Patchworkβ [oe] problem building uclibc + udev

login
register
about
Submitter Cliff Brake
Date 2009-08-29 20:38:56
Message ID <f96d234e0908291338i2fe06f6fkfc52b57cccd28fe6@mail.gmail.com>
Download mbox | patch
Permalink /patch/1008/
State New
Headers show

Comments

Cliff Brake - 2009-08-29 20:38:56
On Tue, Aug 25, 2009 at 10:03 PM, Khem Raj<raj.khem@gmail.com> wrote:
> On (25/08/09 17:11), Cliff Brake wrote:
>> I'm running into the following issue building udev:
>>
>> NOTE: Running task 606 of 631 (ID: 8,
>> /build/oe/oe-testing/openembedded/recipes/udev/udev_141.bb,
>> do_compile)
>> ERROR: function do_compile failed
>> ERROR: log data follows
>> (/build/oe/oe-testing/build/angstrom-2008.1/tmp/work/armv7a-angstrom-linux-uclibcgnueabi/udev-141-r11/temp/log.do_compile.14745)
>> | NOTE: make -j 5
>> | make  all-recursive
>> | make[1]: Entering directory
>> `/build/oe/oe-testing/build/angstrom-2008.1/tmp/work/armv7a-angstrom-linux-uclibcgnueabi/udev-141-r11/udev-141'
>> | Making all in udev
>> | make[2]: Entering directory
>> `/build/oe/oe-testing/build/angstrom-2008.1/tmp/work/armv7a-angstrom-linux-uclibcgnueabi/udev-141-r11/udev-141/udev'
>> | Making all in lib
>> | make[3]: Entering directory
>> `/build/oe/oe-testing/build/angstrom-2008.1/tmp/work/armv7a-angstrom-linux-uclibcgnueabi/udev-141-r11/udev-141/udev/lib'
>> | make[3]: Nothing to be done for `all'.
>> | make[3]: Leaving directory
>> `/build/oe/oe-testing/build/angstrom-2008.1/tmp/work/armv7a-angstrom-linux-uclibcgnueabi/udev-141-r11/udev-141/udev/lib'
>> | make[3]: Entering directory
>> `/build/oe/oe-testing/build/angstrom-2008.1/tmp/work/armv7a-angstrom-linux-uclibcgnueabi/udev-141-r11/udev-141/udev'
>> | /bin/sh ../arm-angstrom-linux-uclibcgnueabi-libtool --tag=CC
>> --mode=link arm-angstrom-linux-uclibcgnueabi-gcc -march=armv7-a
>> -mtune=cortex-a8 -mfpu=neon -mfloat-abi=softfp
>> -isystem/build/oe/oe-testing/build/angstrom-2008.1/tmp/staging/armv7a-angstrom-linux-uclibcgnueabi/usr/include
>> -fexpensive-optimizations -fomit-frame-pointer -frename-registers -O2
>> -ggdb3 -Wl,--as-needed
>> -L/build/oe/oe-testing/build/angstrom-2008.1/tmp/staging/armv7a-angstrom-linux-uclibcgnueabi/usr/lib
>> -Wl,-rpath-link,/build/oe/oe-testing/build/angstrom-2008.1/tmp/staging/armv7a-angstrom-linux-uclibcgnueabi/usr/lib
>> -Wl,-O1 -Wl,--hash-style=gnu -o udevd udev-event.o udev-watch.o
>> udev-node.o udev-rules.o udev-util.o libudev.o libudev-list.o
>> libudev-util.o libudev-device.o libudev-device-db-write.o
>> libudev-monitor.o libudev-enumerate.o libudev-queue.o libudev-ctrl.o
>> udevd.o
>> | arm-angstrom-linux-uclibcgnueabi-libtool: link:
>> arm-angstrom-linux-uclibcgnueabi-gcc -march=armv7-a -mtune=cortex-a8
>> -mfpu=neon -mfloat-abi=softfp
>> -isystem/build/oe/oe-testing/build/angstrom-2008.1/tmp/staging/armv7a-angstrom-linux-uclibcgnueabi/usr/include
>> -fexpensive-optimizations -fomit-frame-pointer -frename-registers -O2
>> -ggdb3 -Wl,--as-needed -Wl,-rpath-link
>> -Wl,/build/oe/oe-testing/build/angstrom-2008.1/tmp/staging/armv7a-angstrom-linux-uclibcgnueabi/usr/lib
>> -Wl,-O1 -Wl,--hash-style=gnu -o udevd udev-event.o udev-watch.o
>> udev-node.o udev-rules.o udev-util.o libudev.o libudev-list.o
>> libudev-util.o libudev-device.o libudev-device-db-write.o
>> libudev-monitor.o libudev-enumerate.o libudev-queue.o libudev-ctrl.o
>> udevd.o  -L/build/oe/oe-testing/build/angstrom-2008.1/tmp/staging/armv7a-angstrom-linux-uclibcgnueabi/usr/lib
>> | udevd.o: In function `main':
>> | /build/oe/oe-testing/build/angstrom-2008.1/tmp/work/armv7a-angstrom-linux-uclibcgnueabi/udev-141-r11/udev-141/udev/udevd.c:978:
>> undefined reference to `ppoll'
>> | collect2: ld returned 1 exit status
>> | make[3]: *** [udevd] Error 1
>> | make[3]: Leaving directory
>> `/build/oe/oe-testing/build/angstrom-2008.1/tmp/work/armv7a-angstrom-linux-uclibcgnueabi/udev-141-r11/udev-141/udev'
>> | make[2]: *** [all-recursive] Error 1
>> | make[2]: Leaving directory
>> `/build/oe/oe-testing/build/angstrom-2008.1/tmp/work/armv7a-angstrom-linux-uclibcgnueabi/udev-141-r11/udev-141/udev'
>> | make[1]: *** [all-recursive] Error 1
>> | make[1]: Leaving directory
>> `/build/oe/oe-testing/build/angstrom-2008.1/tmp/work/armv7a-angstrom-linux-uclibcgnueabi/udev-141-r11/udev-141'
>> | make: *** [all] Error 2
>> | FATAL: oe_runmake failed
>>
>> It appears that uclibc is being built without ppoll as the headers
>> don't have it.  The beagleboard kernel is patched
>> (http://cgit.openembedded.org/cgit.cgi/openembedded/commit/?id=1f0d91e152f16fbd40bb2fb3c44a30d774d4dede)
>> to include ppoll, and the headers are modified as such:
>>
>> cbrake@happy:/build/oe/oe-testing/build/angstrom-2008.1/tmp/staging$
>> searchc ppoll
>> ./armv7a-angstrom-linux-uclibcgnueabi/usr/include/asm/unistd.h:
>>                          /* 336 for ppoll */
>> ./beagleboard-angstrom-linux-gnueabi/kernel/arch/arm/include/asm/unistd.h:#define
>> __NR_ppoll                    (__NR_SYSCALL_BASE+336)
>> ./beagleboard-angstrom-linux-gnueabi/kernel/include/linux/syscalls.h:asmlinkage
>> long sys_ppoll(struct pollfd __user *, unsigned int,
>> ./beagleboard-angstrom-linux-gnueabi/kernel/include/asm-arm/unistd.h:#define
>> __NR_ppoll                 (__NR_SYSCALL_BASE+336)
>> ./armv7a-angstrom-linux-gnueabi/usr/include/asm/unistd.h:
>>                          /* 336 for ppoll */
>> ./armv7a-angstrom-linux-gnueabi/usr/include/sys/poll.h:extern int
>> ppoll (struct pollfd *__fds, nfds_t __nfds,
>>
>> However, the headers are only modified in the kernel include
>> directory.  I suspect uclibc is getting unistd.h from the usr/include
>> directory which does not have __NR_ppoll defined.  What is the best
>> way to fix this.  I suspect we need to tell uclibc to look at the
>> kernel headers?
>
> it already does look into kernel headers to configure its system calls.
> All you need is to wireup this syscall in kernel and also in
> linux-libc-headers. IOW Port
> http://www.spinics.net/lists/arm-kernel/msg38114.html to both above
> places.

There are several solutions to this problem:

1) patch the kernel and linux-libc-headers with the attached patch
files (2.6.29 kernel, and 2.6.23 headers)
2) use the micro-base-image which uses mdev instead of udev.

Unfortunately, the linux-libc-headers patch is probably not distro
friendly as it modifies a non-machine specific package.  So there does
not seem to be a clear path forward.

Cliff
Phil Blundell - 2009-08-30 15:01:03
On Sat, 2009-08-29 at 16:38 -0400, Cliff Brake wrote:
> There are several solutions to this problem:
> 
> 1) patch the kernel and linux-libc-headers with the attached patch
> files (2.6.29 kernel, and 2.6.23 headers)
> 2) use the micro-base-image which uses mdev instead of udev.
> 
> Unfortunately, the linux-libc-headers patch is probably not distro
> friendly as it modifies a non-machine specific package.  So there does
> not seem to be a clear path forward.

I think the only real way ahead with the ppoll thing is to get that
patch landed in the upstream kernel (if it isn't there already) and then
rev all the appropriate packages to include the fix.

Or, given that the syscall numbers were already reserved anyway and
hence unlikely to collide with anything else, it should be safe enough
to just apply those patches in OE.  It doesn't matter that the
linux-libc-headers package is used on multiple machines: if somebody
builds against the patched linux-libc-headers and then tries to run on
an unpatched kernel, ppoll() will just return -ENOSYS which is the same
thing it would have done anyway.

p.

Patch

From 8a7643b09856f4f661403dcedbe0455b3cbeeea9 Mon Sep 17 00:00:00 2001
From: Steven Newbury <s_j_newbury@yahoo.co.uk>
Date: Fri, 22 May 2009 14:25:40 +0200
Subject: [PATCH] implement TIF_RESTORE_SIGMASK support and enable the related
 syscalls:

pselect6
ppoll
epoll_pwait

Based on http://www.spinics.net/lists/arm-kernel/msg38114.html
---
 arch/arm/include/asm/thread_info.h |    2 +
 arch/arm/include/asm/unistd.h      |    7 ++-
 arch/arm/kernel/calls.S            |    6 +-
 arch/arm/kernel/signal.c           |   90 +++++++++++++++---------------------
 4 files changed, 46 insertions(+), 59 deletions(-)

diff --git a/arch/arm/include/asm/thread_info.h b/arch/arm/include/asm/thread_info.h
index 4f88482..2cf0917 100644
--- a/arch/arm/include/asm/thread_info.h
+++ b/arch/arm/include/asm/thread_info.h
@@ -136,6 +136,7 @@  extern void vfp_sync_state(struct thread_info *thread);
 #define TIF_SIGPENDING		0
 #define TIF_NEED_RESCHED	1
 #define TIF_SYSCALL_TRACE	8
+#define TIF_RESTORE_SIGMASK	9       /* restore signal mask in do_signal */
 #define TIF_POLLING_NRFLAG	16
 #define TIF_USING_IWMMXT	17
 #define TIF_MEMDIE		18
@@ -144,6 +145,7 @@  extern void vfp_sync_state(struct thread_info *thread);
 #define _TIF_SIGPENDING		(1 << TIF_SIGPENDING)
 #define _TIF_NEED_RESCHED	(1 << TIF_NEED_RESCHED)
 #define _TIF_SYSCALL_TRACE	(1 << TIF_SYSCALL_TRACE)
+#define _TIF_RESTORE_SIGMASK	(1 << TIF_RESTORE_SIGMASK)
 #define _TIF_POLLING_NRFLAG	(1 << TIF_POLLING_NRFLAG)
 #define _TIF_USING_IWMMXT	(1 << TIF_USING_IWMMXT)
 #define _TIF_FREEZE		(1 << TIF_FREEZE)
diff --git a/arch/arm/include/asm/unistd.h b/arch/arm/include/asm/unistd.h
index 94cc58e..cd1eaa0 100644
--- a/arch/arm/include/asm/unistd.h
+++ b/arch/arm/include/asm/unistd.h
@@ -360,8 +360,8 @@ 
 #define __NR_readlinkat			(__NR_SYSCALL_BASE+332)
 #define __NR_fchmodat			(__NR_SYSCALL_BASE+333)
 #define __NR_faccessat			(__NR_SYSCALL_BASE+334)
-					/* 335 for pselect6 */
-					/* 336 for ppoll */
+#define __NR_pselect6			(__NR_SYSCALL_BASE+335)
+#define __NR_ppoll			(__NR_SYSCALL_BASE+336)
 #define __NR_unshare			(__NR_SYSCALL_BASE+337)
 #define __NR_set_robust_list		(__NR_SYSCALL_BASE+338)
 #define __NR_get_robust_list		(__NR_SYSCALL_BASE+339)
@@ -372,7 +372,7 @@ 
 #define __NR_vmsplice			(__NR_SYSCALL_BASE+343)
 #define __NR_move_pages			(__NR_SYSCALL_BASE+344)
 #define __NR_getcpu			(__NR_SYSCALL_BASE+345)
-					/* 346 for epoll_pwait */
+#define __NR_epoll_pwait		(__NR_SYSCALL_BASE+346)
 #define __NR_kexec_load			(__NR_SYSCALL_BASE+347)
 #define __NR_utimensat			(__NR_SYSCALL_BASE+348)
 #define __NR_signalfd			(__NR_SYSCALL_BASE+349)
@@ -430,6 +430,7 @@ 
 #define __ARCH_WANT_SYS_SIGPENDING
 #define __ARCH_WANT_SYS_SIGPROCMASK
 #define __ARCH_WANT_SYS_RT_SIGACTION
+#define __ARCH_WANT_SYS_RT_SIGSUSPEND
 
 #if !defined(CONFIG_AEABI) || defined(CONFIG_OABI_COMPAT)
 #define __ARCH_WANT_SYS_TIME
diff --git a/arch/arm/kernel/calls.S b/arch/arm/kernel/calls.S
index 1680e9e..534000d 100644
--- a/arch/arm/kernel/calls.S
+++ b/arch/arm/kernel/calls.S
@@ -344,8 +344,8 @@ 
 		CALL(sys_readlinkat)
 		CALL(sys_fchmodat)
 		CALL(sys_faccessat)
-/* 335 */	CALL(sys_ni_syscall)		/* eventually pselect6 */
-		CALL(sys_ni_syscall)		/* eventually ppoll */
+/* 335 */	CALL(sys_pselect6)
+		CALL(sys_ppoll)
 		CALL(sys_unshare)
 		CALL(sys_set_robust_list)
 		CALL(sys_get_robust_list)
@@ -355,7 +355,7 @@ 
 		CALL(sys_vmsplice)
 		CALL(sys_move_pages)
 /* 345 */	CALL(sys_getcpu)
-		CALL(sys_ni_syscall)		/* eventually epoll_pwait */
+		CALL(sys_epoll_pwait)
 		CALL(sys_kexec_load)
 		CALL(sys_utimensat)
 		CALL(sys_signalfd)
diff --git a/arch/arm/kernel/signal.c b/arch/arm/kernel/signal.c
index 80b8b5c..7645048 100644
--- a/arch/arm/kernel/signal.c
+++ b/arch/arm/kernel/signal.c
@@ -47,57 +47,23 @@  const unsigned long sigreturn_codes[7] = {
 	MOV_R7_NR_RT_SIGRETURN, SWI_SYS_RT_SIGRETURN, SWI_THUMB_RT_SIGRETURN,
 };
 
-static int do_signal(sigset_t *oldset, struct pt_regs * regs, int syscall);
+static void do_signal(struct pt_regs * regs, int syscall);
 
 /*
  * atomically swap in the new signal mask, and wait for a signal.
  */
-asmlinkage int sys_sigsuspend(int restart, unsigned long oldmask, old_sigset_t mask, struct pt_regs *regs)
+asmlinkage int sys_sigsuspend(int restart, unsigned long oldmask, old_sigset_t mask)
 {
-	sigset_t saveset;
-
 	mask &= _BLOCKABLE;
 	spin_lock_irq(&current->sighand->siglock);
-	saveset = current->blocked;
+	current->saved_sigmask = current->blocked;
 	siginitset(&current->blocked, mask);
 	recalc_sigpending();
 	spin_unlock_irq(&current->sighand->siglock);
-	regs->ARM_r0 = -EINTR;
-
-	while (1) {
-		current->state = TASK_INTERRUPTIBLE;
-		schedule();
-		if (do_signal(&saveset, regs, 0))
-			return regs->ARM_r0;
-	}
-}
-
-asmlinkage int
-sys_rt_sigsuspend(sigset_t __user *unewset, size_t sigsetsize, struct pt_regs *regs)
-{
-	sigset_t saveset, newset;
-
-	/* XXX: Don't preclude handling different sized sigset_t's. */
-	if (sigsetsize != sizeof(sigset_t))
-		return -EINVAL;
-
-	if (copy_from_user(&newset, unewset, sizeof(newset)))
-		return -EFAULT;
-	sigdelsetmask(&newset, ~_BLOCKABLE);
-
-	spin_lock_irq(&current->sighand->siglock);
-	saveset = current->blocked;
-	current->blocked = newset;
-	recalc_sigpending();
-	spin_unlock_irq(&current->sighand->siglock);
-	regs->ARM_r0 = -EINTR;
-
-	while (1) {
-		current->state = TASK_INTERRUPTIBLE;
-		schedule();
-		if (do_signal(&saveset, regs, 0))
-			return regs->ARM_r0;
-	}
+	current->state = TASK_INTERRUPTIBLE;
+	schedule();
+	set_thread_flag(TIF_RESTORE_SIGMASK);
+	return -ERESTARTNOHAND;
 }
 
 asmlinkage int 
@@ -290,7 +256,7 @@  asmlinkage int sys_sigreturn(struct pt_regs *regs)
 
 badframe:
 	force_sig(SIGSEGV, current);
-	return 0;
+	return -EFAULT;
 }
 
 asmlinkage int sys_rt_sigreturn(struct pt_regs *regs)
@@ -325,7 +291,7 @@  asmlinkage int sys_rt_sigreturn(struct pt_regs *regs)
 
 badframe:
 	force_sig(SIGSEGV, current);
-	return 0;
+	return -EFAULT;
 }
 
 static int
@@ -541,7 +507,7 @@  static inline void restart_syscall(struct pt_regs *regs)
 /*
  * OK, we're invoking a handler
  */	
-static void
+static int
 handle_signal(unsigned long sig, struct k_sigaction *ka,
 	      siginfo_t *info, sigset_t *oldset,
 	      struct pt_regs * regs, int syscall)
@@ -592,7 +558,7 @@  handle_signal(unsigned long sig, struct k_sigaction *ka,
 
 	if (ret != 0) {
 		force_sigsegv(sig, tsk);
-		return;
+		return ret;
 	}
 
 	/*
@@ -606,6 +572,7 @@  handle_signal(unsigned long sig, struct k_sigaction *ka,
 	recalc_sigpending();
 	spin_unlock_irq(&tsk->sighand->siglock);
 
+	return ret;
 }
 
 /*
@@ -617,11 +584,12 @@  handle_signal(unsigned long sig, struct k_sigaction *ka,
  * the kernel can handle, and then we build all the user-level signal handling
  * stack-frames in one go after that.
  */
-static int do_signal(sigset_t *oldset, struct pt_regs *regs, int syscall)
+static void do_signal(struct pt_regs *regs, int syscall)
 {
 	struct k_sigaction ka;
 	siginfo_t info;
 	int signr;
+	sigset_t *oldset;
 
 	/*
 	 * We want the common case to go fast, which
@@ -630,18 +598,29 @@  static int do_signal(sigset_t *oldset, struct pt_regs *regs, int syscall)
 	 * if so.
 	 */
 	if (!user_mode(regs))
-		return 0;
+		return;
 
 	if (try_to_freeze())
 		goto no_signal;
 
 	single_step_clear(current);
 
+	if (test_thread_flag(TIF_RESTORE_SIGMASK))
+		oldset = &current->saved_sigmask;
+	else
+		oldset = &current->blocked;
+
 	signr = get_signal_to_deliver(&info, &ka, regs, NULL);
 	if (signr > 0) {
-		handle_signal(signr, &ka, &info, oldset, regs, syscall);
+		if (handle_signal(signr, &ka, &info, oldset, regs, syscall) == 0) {
+			/* a signal was successfully delivered; the saved
+			 * sigmask will have been stored in the signal frame,
+			 * and will be restored by sigreturn, so we can simply
+			 * clear the TIF_RESTORE_SIGMASK flag */
+			clear_thread_flag(TIF_RESTORE_SIGMASK);
+		}
 		single_step_set(current);
-		return 1;
+		return;
 	}
 
  no_signal:
@@ -665,7 +644,7 @@  static int do_signal(sigset_t *oldset, struct pt_regs *regs, int syscall)
 				usp = (u32 __user *)regs->ARM_sp;
 
 				/*
-				 * Either we supports OABI only, or we have
+				 * Either we support OABI only, or we have
 				 * EABI with the OABI compat layer enabled.
 				 * In the later case we don't know if user
 				 * space is EABI or not, and if not we must
@@ -695,12 +674,17 @@  static int do_signal(sigset_t *oldset, struct pt_regs *regs, int syscall)
 		}
 	}
 	single_step_set(current);
-	return 0;
+        /* if there's no signal to deliver, we just put the saved sigmask
+           back. */
+		if (test_thread_flag(TIF_RESTORE_SIGMASK)) {
+			clear_thread_flag(TIF_RESTORE_SIGMASK);
+			sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL);
+		}
 }
 
 asmlinkage void
 do_notify_resume(struct pt_regs *regs, unsigned int thread_flags, int syscall)
 {
-	if (thread_flags & _TIF_SIGPENDING)
-		do_signal(&current->blocked, regs, syscall);
+	if (thread_flags & (_TIF_SIGPENDING|_TIF_RESTORE_SIGMASK))
+		do_signal(regs, syscall);
 }
-- 
1.6.2.4