All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [7118] linux-user: prefer glibc over direct syscalls
@ 2009-04-15 16:12 Aurelien Jarno
  2009-04-15 19:21 ` Stefan Weil
                   ` (3 more replies)
  0 siblings, 4 replies; 11+ messages in thread
From: Aurelien Jarno @ 2009-04-15 16:12 UTC (permalink / raw)
  To: qemu-devel

Revision: 7118
          http://svn.sv.gnu.org/viewvc/?view=rev&root=qemu&revision=7118
Author:   aurel32
Date:     2009-04-15 16:12:13 +0000 (Wed, 15 Apr 2009)
Log Message:
-----------
linux-user: prefer glibc over direct syscalls

The openat/*at syscalls are incredibly common with modern coreutils,
calling them directly via syscalls breaks for example fakeroot. Use
glibc stubs whenever directly available and provide old syscall
calling for people still using older libc.

Patch originally from Mika Westerberg, Adapted to
apply to current trunk and cleaned up by Riku Voipio.

Signed-off-by: Riku Voipio <riku.voipio@iki.fi>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>

Modified Paths:
--------------
    trunk/configure
    trunk/linux-user/syscall.c

Modified: trunk/configure
===================================================================
--- trunk/configure	2009-04-15 16:12:06 UTC (rev 7117)
+++ trunk/configure	2009-04-15 16:12:13 UTC (rev 7118)
@@ -1156,6 +1156,53 @@
   fi
 fi
 
+#
+# Check for xxxat() functions when we are building linux-user
+# emulator.  This is done because older glibc versions don't
+# have syscall stubs for these implemented.
+#
+atfile=no
+if [ "$linux_user" = "yes" ] ; then
+  cat > $TMPC << EOF
+#define _ATFILE_SOURCE
+#include <sys/types.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+int
+main(void)
+{
+	/* try to unlink nonexisting file */
+	return (unlinkat(AT_FDCWD, "nonexistent_file", 0));
+}
+EOF
+  if $cc $ARCH_CFLAGS -o $TMPE $TMPC 2> /dev/null ; then
+    atfile=yes
+  fi
+fi
+
+# Check for initofy functions when we are building linux-user
+# emulator.  This is done because older glibc versions don't
+# have syscall stubs for these implemented.  In that case we
+# don't provide them even if kernel supports them.
+#
+inotify=no
+if [ "$linux_user" = "yes" ] ; then
+  cat > $TMPC << EOF
+#include <sys/inotify.h>
+
+int
+main(void)
+{
+	/* try to start inotify */
+	return inotify_init(void);
+}
+EOF
+  if $cc $ARCH_CFLAGS -o $TMPE $TMPC 2> /dev/null ; then
+    inotify=yes
+  fi
+fi
+
 # Check if tools are available to build documentation.
 if [ -x "`which texi2html 2>/dev/null`" ] && \
    [ -x "`which pod2man 2>/dev/null`" ]; then
@@ -1544,6 +1591,12 @@
   echo "CONFIG_CURSES=yes" >> $config_mak
   echo "CURSES_LIBS=-lcurses" >> $config_mak
 fi
+if test "$atfile" = "yes" ; then
+  echo "#define CONFIG_ATFILE 1" >> $config_h
+fi
+if test "$inotify" = "yes" ; then
+  echo "#define CONFIG_INOTIFY 1" >> $config_h
+fi
 if test "$brlapi" = "yes" ; then
   echo "CONFIG_BRLAPI=yes" >> $config_mak
   echo "#define CONFIG_BRLAPI 1" >> $config_h

Modified: trunk/linux-user/syscall.c
===================================================================
--- trunk/linux-user/syscall.c	2009-04-15 16:12:06 UTC (rev 7117)
+++ trunk/linux-user/syscall.c	2009-04-15 16:12:13 UTC (rev 7118)
@@ -53,6 +53,7 @@
 #include <sys/statfs.h>
 #include <utime.h>
 #include <sys/sysinfo.h>
+#include <sys/utsname.h>
 //#include <sys/user.h>
 #include <netinet/ip.h>
 #include <netinet/tcp.h>
@@ -200,7 +201,229 @@
     return -ENOSYS;
 }
 #endif
-_syscall1(int,sys_uname,struct new_utsname *,buf)
+#if TARGET_ABI_BITS == 32
+_syscall3(int, sys_getdents, uint, fd, struct linux_dirent *, dirp, uint, count);
+#endif
+#if defined(TARGET_NR_getdents64) && defined(__NR_getdents64)
+_syscall3(int, sys_getdents64, uint, fd, struct linux_dirent64 *, dirp, uint, count);
+#endif
+_syscall2(int, sys_getpriority, int, which, int, who);
+#if !defined (__x86_64__)
+_syscall5(int, _llseek,  uint,  fd, ulong, hi, ulong, lo,
+          loff_t *, res, uint, wh);
+#endif
+_syscall3(int,sys_rt_sigqueueinfo,int,pid,int,sig,siginfo_t *,uinfo)
+_syscall3(int,sys_syslog,int,type,char*,bufp,int,len)
+#if defined(TARGET_NR_tgkill) && defined(__NR_tgkill)
+_syscall3(int,sys_tgkill,int,tgid,int,pid,int,sig)
+#endif
+#if defined(TARGET_NR_tkill) && defined(__NR_tkill)
+_syscall2(int,sys_tkill,int,tid,int,sig)
+#endif
+#ifdef __NR_exit_group
+_syscall1(int,exit_group,int,error_code)
+#endif
+#if defined(TARGET_NR_set_tid_address) && defined(__NR_set_tid_address)
+_syscall1(int,set_tid_address,int *,tidptr)
+#endif
+#if defined(USE_NPTL)
+#if defined(TARGET_NR_futex) && defined(__NR_futex)
+_syscall6(int,sys_futex,int *,uaddr,int,op,int,val,
+          const struct timespec *,timeout,int *,uaddr2,int,val3)
+#endif
+#endif
+
+static bitmask_transtbl fcntl_flags_tbl[] = {
+  { TARGET_O_ACCMODE,   TARGET_O_WRONLY,    O_ACCMODE,   O_WRONLY,    },
+  { TARGET_O_ACCMODE,   TARGET_O_RDWR,      O_ACCMODE,   O_RDWR,      },
+  { TARGET_O_CREAT,     TARGET_O_CREAT,     O_CREAT,     O_CREAT,     },
+  { TARGET_O_EXCL,      TARGET_O_EXCL,      O_EXCL,      O_EXCL,      },
+  { TARGET_O_NOCTTY,    TARGET_O_NOCTTY,    O_NOCTTY,    O_NOCTTY,    },
+  { TARGET_O_TRUNC,     TARGET_O_TRUNC,     O_TRUNC,     O_TRUNC,     },
+  { TARGET_O_APPEND,    TARGET_O_APPEND,    O_APPEND,    O_APPEND,    },
+  { TARGET_O_NONBLOCK,  TARGET_O_NONBLOCK,  O_NONBLOCK,  O_NONBLOCK,  },
+  { TARGET_O_SYNC,      TARGET_O_SYNC,      O_SYNC,      O_SYNC,      },
+  { TARGET_FASYNC,      TARGET_FASYNC,      FASYNC,      FASYNC,      },
+  { TARGET_O_DIRECTORY, TARGET_O_DIRECTORY, O_DIRECTORY, O_DIRECTORY, },
+  { TARGET_O_NOFOLLOW,  TARGET_O_NOFOLLOW,  O_NOFOLLOW,  O_NOFOLLOW,  },
+  { TARGET_O_LARGEFILE, TARGET_O_LARGEFILE, O_LARGEFILE, O_LARGEFILE, },
+#if defined(O_DIRECT)
+  { TARGET_O_DIRECT,    TARGET_O_DIRECT,    O_DIRECT,    O_DIRECT,    },
+#endif
+  { 0, 0, 0, 0 }
+};
+
+#define COPY_UTSNAME_FIELD(dest, src) \
+  do { \
+      /* __NEW_UTS_LEN doesn't include terminating null */ \
+      (void) strncpy((dest), (src), __NEW_UTS_LEN); \
+      (dest)[__NEW_UTS_LEN] = '\0'; \
+  } while (0)
+
+static int sys_uname(struct new_utsname *buf)
+{
+  struct utsname uts_buf;
+
+  if (uname(&uts_buf) < 0)
+      return (-1);
+
+  /*
+   * Just in case these have some differences, we
+   * translate utsname to new_utsname (which is the
+   * struct linux kernel uses).
+   */
+
+  bzero(buf, sizeof (*buf));
+  COPY_UTSNAME_FIELD(buf->sysname, uts_buf.sysname);
+  COPY_UTSNAME_FIELD(buf->nodename, uts_buf.nodename);
+  COPY_UTSNAME_FIELD(buf->release, uts_buf.release);
+  COPY_UTSNAME_FIELD(buf->version, uts_buf.version);
+  COPY_UTSNAME_FIELD(buf->machine, uts_buf.machine);
+#ifdef _GNU_SOURCE
+  COPY_UTSNAME_FIELD(buf->domainname, uts_buf.domainname);
+#endif
+  return (0);
+
+#undef COPY_UTSNAME_FIELD
+}
+
+static int sys_getcwd1(char *buf, size_t size)
+{
+  if (getcwd(buf, size) == NULL) {
+      /* getcwd() sets errno */
+      return (-1);
+  }
+  return (0);
+}
+
+#ifdef CONFIG_ATFILE
+/*
+ * Host system seems to have atfile syscall stubs available.  We
+ * now enable them one by one as specified by target syscall_nr.h.
+ */
+
+#ifdef TARGET_NR_faccessat
+static int sys_faccessat(int dirfd, const char *pathname, int mode, int flags)
+{
+  return (faccessat(dirfd, pathname, mode, flags));
+}
+#endif
+#ifdef TARGET_NR_fchmodat
+static int sys_fchmodat(int dirfd, const char *pathname, mode_t mode, int flags)
+{
+  return (fchmodat(dirfd, pathname, mode, flags));
+}
+#endif
+#ifdef TARGET_NR_fchownat
+static int sys_fchownat(int dirfd, const char *pathname, uid_t owner,
+    gid_t group, int flags)
+{
+  return (fchownat(dirfd, pathname, owner, group, flags));
+}
+#endif
+#ifdef __NR_fstatat64
+static int sys_fstatat64(int dirfd, const char *pathname, struct stat *buf,
+    int flags)
+{
+  return (fstatat(dirfd, pathname, buf, flags));
+}
+#endif
+#ifdef __NR_newfstatat
+static int sys_newfstatat(int dirfd, const char *pathname, struct stat *buf,
+    int flags)
+{
+  return (fstatat(dirfd, pathname, buf, flags));
+}
+#endif
+#ifdef TARGET_NR_futimesat
+static int sys_futimesat(int dirfd, const char *pathname,
+    const struct timeval times[2])
+{
+  return (futimesat(dirfd, pathname, times));
+}
+#endif
+#ifdef TARGET_NR_linkat
+static int sys_linkat(int olddirfd, const char *oldpath,
+    int newdirfd, const char *newpath, int flags)
+{
+  return (linkat(olddirfd, oldpath, newdirfd, newpath, flags));
+}
+#endif
+#ifdef TARGET_NR_mkdirat
+static int sys_mkdirat(int dirfd, const char *pathname, mode_t mode)
+{
+  return (mkdirat(dirfd, pathname, mode));
+}
+#endif
+#ifdef TARGET_NR_mknodat
+static int sys_mknodat(int dirfd, const char *pathname, mode_t mode,
+    dev_t dev)
+{
+  return (mknodat(dirfd, pathname, mode, dev));
+}
+#endif
+#ifdef TARGET_NR_openat
+static int sys_openat(int dirfd, const char *pathname, int flags, ...)
+{
+  /*
+   * open(2) has extra parameter 'mode' when called with
+   * flag O_CREAT.
+   */
+  if ((flags & O_CREAT) != 0) {
+      va_list ap;
+      mode_t mode;
+
+      /*
+       * Get the 'mode' parameter and translate it to
+       * host bits.
+       */
+      va_start(ap, flags);
+      mode = va_arg(ap, mode_t);
+      mode = target_to_host_bitmask(mode, fcntl_flags_tbl);
+      va_end(ap);
+
+      return (openat(dirfd, pathname, flags, mode));
+  }
+  return (openat(dirfd, pathname, flags));
+}
+#endif
+#ifdef TARGET_NR_readlinkat
+static int sys_readlinkat(int dirfd, const char *pathname, char *buf, size_t bufsiz)
+{
+  return (readlinkat(dirfd, pathname, buf, bufsiz));
+}
+#endif
+#ifdef TARGET_NR_renameat
+static int sys_renameat(int olddirfd, const char *oldpath,
+    int newdirfd, const char *newpath)
+{
+  return (renameat(olddirfd, oldpath, newdirfd, newpath));
+}
+#endif
+#ifdef TARGET_NR_symlinkat
+static int sys_symlinkat(const char *oldpath, int newdirfd, const char *newpath)
+{
+  return (symlinkat(oldpath, newdirfd, newpath));
+}
+#endif
+#ifdef TARGET_NR_unlinkat
+static int sys_unlinkat(int dirfd, const char *pathname, int flags)
+{
+  return (unlinkat(dirfd, pathname, flags));
+}
+#endif
+#ifdef TARGET_NR_utimensat
+static int sys_utimensat(int dirfd, const char *pathname,
+    const struct timespec times[2], int flags)
+{
+  return (utimensat(dirfd, pathname, times, flags));
+}
+#endif
+#else /* !CONFIG_ATFILE */
+
+/*
+ * Try direct syscalls instead
+ */
 #if defined(TARGET_NR_faccessat) && defined(__NR_faccessat)
 _syscall4(int,sys_faccessat,int,dirfd,const char *,pathname,int,mode,int,flags)
 #endif
@@ -221,21 +444,14 @@
 _syscall3(int,sys_futimesat,int,dirfd,const char *,pathname,
          const struct timeval *,times)
 #endif
-_syscall2(int,sys_getcwd1,char *,buf,size_t,size)
-#if TARGET_ABI_BITS == 32
-_syscall3(int, sys_getdents, uint, fd, struct linux_dirent *, dirp, uint, count);
+#if (defined(TARGET_NR_newfstatat) || defined(TARGET_NR_fstatat64) ) && \
+        defined(__NR_newfstatat)
+_syscall4(int,sys_newfstatat,int,dirfd,const char *,pathname,
+          struct stat *,buf,int,flags)
 #endif
-#if defined(TARGET_NR_getdents64) && defined(__NR_getdents64)
-_syscall3(int, sys_getdents64, uint, fd, struct linux_dirent64 *, dirp, uint, count);
-#endif
-_syscall2(int, sys_getpriority, int, which, int, who);
-#if !defined (__x86_64__)
-_syscall5(int, _llseek,  uint,  fd, ulong, hi, ulong, lo,
-          loff_t *, res, uint, wh);
-#endif
 #if defined(TARGET_NR_linkat) && defined(__NR_linkat)
 _syscall5(int,sys_linkat,int,olddirfd,const char *,oldpath,
-	  int,newdirfd,const char *,newpath,int,flags)
+      int,newdirfd,const char *,newpath,int,flags)
 #endif
 #if defined(TARGET_NR_mkdirat) && defined(__NR_mkdirat)
 _syscall3(int,sys_mkdirat,int,dirfd,const char *,pathname,mode_t,mode)
@@ -244,11 +460,6 @@
 _syscall4(int,sys_mknodat,int,dirfd,const char *,pathname,
           mode_t,mode,dev_t,dev)
 #endif
-#if (defined(TARGET_NR_newfstatat) || defined(TARGET_NR_fstatat64) ) && \
-        defined(__NR_newfstatat)
-_syscall4(int,sys_newfstatat,int,dirfd,const char *,pathname,
-          struct stat *,buf,int,flags)
-#endif
 #if defined(TARGET_NR_openat) && defined(__NR_openat)
 _syscall4(int,sys_openat,int,dirfd,const char *,pathname,int,flags,mode_t,mode)
 #endif
@@ -260,24 +471,10 @@
 _syscall4(int,sys_renameat,int,olddirfd,const char *,oldpath,
           int,newdirfd,const char *,newpath)
 #endif
-_syscall3(int,sys_rt_sigqueueinfo,int,pid,int,sig,siginfo_t *,uinfo)
 #if defined(TARGET_NR_symlinkat) && defined(__NR_symlinkat)
 _syscall3(int,sys_symlinkat,const char *,oldpath,
           int,newdirfd,const char *,newpath)
 #endif
-_syscall3(int,sys_syslog,int,type,char*,bufp,int,len)
-#if defined(TARGET_NR_tgkill) && defined(__NR_tgkill)
-_syscall3(int,sys_tgkill,int,tgid,int,pid,int,sig)
-#endif
-#if defined(TARGET_NR_tkill) && defined(__NR_tkill)
-_syscall2(int,sys_tkill,int,tid,int,sig)
-#endif
-#ifdef __NR_exit_group
-_syscall1(int,exit_group,int,error_code)
-#endif
-#if defined(TARGET_NR_set_tid_address) && defined(__NR_set_tid_address)
-_syscall1(int,set_tid_address,int *,tidptr)
-#endif
 #if defined(TARGET_NR_unlinkat) && defined(__NR_unlinkat)
 _syscall3(int,sys_unlinkat,int,dirfd,const char *,pathname,int,flags)
 #endif
@@ -285,22 +482,37 @@
 _syscall4(int,sys_utimensat,int,dirfd,const char *,pathname,
           const struct timespec *,tsp,int,flags)
 #endif
+
+#endif /* CONFIG_ATFILE */
+
+#ifdef CONFIG_INOTIFY
+
 #if defined(TARGET_NR_inotify_init) && defined(__NR_inotify_init)
-_syscall0(int,sys_inotify_init)
+static int sys_inotify_init(void)
+{
+  return (inotify_init());
+}
 #endif
 #if defined(TARGET_NR_inotify_add_watch) && defined(__NR_inotify_add_watch)
-_syscall3(int,sys_inotify_add_watch,int,fd,const char *,pathname,uint32_t,mask)
+static int sys_inotify_add_watch(int fd,const char *pathname, int32_t mask)
+{
+  return (inotify_add_watch(fd, pathname, mask));
+}
 #endif
 #if defined(TARGET_NR_inotify_rm_watch) && defined(__NR_inotify_rm_watch)
-_syscall2(int,sys_inotify_rm_watch,int,fd,uint32_t,wd)
+static int sys_inotify_rm_watch(int fd, int32_t wd)
+{
+  return (inotify_rm_watch(fd,pathname, wd));
+}
 #endif
-#if defined(USE_NPTL)
-#if defined(TARGET_NR_futex) && defined(__NR_futex)
-_syscall6(int,sys_futex,int *,uaddr,int,op,int,val,
-          const struct timespec *,timeout,int *,uaddr2,int,val3)
-#endif
-#endif
+#else
+/* Userspace can usually survive runtime without inotify */
+#undef TARGET_NR_inotify_init
+#undef TARGET_NR_inotify_add_watch
+#undef TARGET_NR_inotify_rm_watch
+#endif /* CONFIG_INOTIFY  */
 
+
 extern int personality(int);
 extern int flock(int, int);
 extern int setfsuid(int);
@@ -2580,26 +2792,6 @@
 	{ 0, 0, 0, 0 }
 };
 
-static bitmask_transtbl fcntl_flags_tbl[] = {
-	{ TARGET_O_ACCMODE,   TARGET_O_WRONLY,    O_ACCMODE,   O_WRONLY,    },
-	{ TARGET_O_ACCMODE,   TARGET_O_RDWR,      O_ACCMODE,   O_RDWR,      },
-	{ TARGET_O_CREAT,     TARGET_O_CREAT,     O_CREAT,     O_CREAT,     },
-	{ TARGET_O_EXCL,      TARGET_O_EXCL,      O_EXCL,      O_EXCL,      },
-	{ TARGET_O_NOCTTY,    TARGET_O_NOCTTY,    O_NOCTTY,    O_NOCTTY,    },
-	{ TARGET_O_TRUNC,     TARGET_O_TRUNC,     O_TRUNC,     O_TRUNC,     },
-	{ TARGET_O_APPEND,    TARGET_O_APPEND,    O_APPEND,    O_APPEND,    },
-	{ TARGET_O_NONBLOCK,  TARGET_O_NONBLOCK,  O_NONBLOCK,  O_NONBLOCK,  },
-	{ TARGET_O_SYNC,      TARGET_O_SYNC,      O_SYNC,      O_SYNC,      },
-	{ TARGET_FASYNC,      TARGET_FASYNC,      FASYNC,      FASYNC,      },
-	{ TARGET_O_DIRECTORY, TARGET_O_DIRECTORY, O_DIRECTORY, O_DIRECTORY, },
-	{ TARGET_O_NOFOLLOW,  TARGET_O_NOFOLLOW,  O_NOFOLLOW,  O_NOFOLLOW,  },
-	{ TARGET_O_LARGEFILE, TARGET_O_LARGEFILE, O_LARGEFILE, O_LARGEFILE, },
-#if defined(O_DIRECT)
-	{ TARGET_O_DIRECT,    TARGET_O_DIRECT,    O_DIRECT,    O_DIRECT,    },
-#endif
-	{ 0, 0, 0, 0 }
-};
-
 #if defined(TARGET_I386)
 
 /* NOTE: there is really one LDT for all the threads */

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [Qemu-devel] [7118] linux-user: prefer glibc over direct syscalls
  2009-04-15 16:12 [Qemu-devel] [7118] linux-user: prefer glibc over direct syscalls Aurelien Jarno
@ 2009-04-15 19:21 ` Stefan Weil
  2009-04-15 19:48   ` Aurelien Jarno
  2009-04-16 15:25 ` Laurent Desnogues
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 11+ messages in thread
From: Stefan Weil @ 2009-04-15 19:21 UTC (permalink / raw)
  To: qemu-devel; +Cc: Aurelien Jarno

Aurelien Jarno schrieb:
> Revision: 7118
>           http://svn.sv.gnu.org/viewvc/?view=rev&root=qemu&revision=7118
> Author:   aurel32
> Date:     2009-04-15 16:12:13 +0000 (Wed, 15 Apr 2009)
> Log Message:
> -----------
> linux-user: prefer glibc over direct syscalls
> ...
> +
> +# Check for initofy functions when we are building linux-user
>   

initofy => inotify?

> +# emulator.  This is done because older glibc versions don't
> +# have syscall stubs for these implemented.  In that case we
> +# don't provide them even if kernel supports them.
> +#
> +inotify=no
> +if [ "$linux_user" = "yes" ] ; then
> +  cat > $TMPC << EOF
> +#include <sys/inotify.h>
> +
> +int
> +main(void)
> +{
> +	/* try to start inotify */
> +	return inotify_init(void);
> +}
> +EOF
>   

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [Qemu-devel] [7118] linux-user: prefer glibc over direct syscalls
  2009-04-15 19:21 ` Stefan Weil
@ 2009-04-15 19:48   ` Aurelien Jarno
  0 siblings, 0 replies; 11+ messages in thread
From: Aurelien Jarno @ 2009-04-15 19:48 UTC (permalink / raw)
  To: Stefan Weil; +Cc: qemu-devel

On Wed, Apr 15, 2009 at 09:21:00PM +0200, Stefan Weil wrote:
> Aurelien Jarno schrieb:
> > Revision: 7118
> >           http://svn.sv.gnu.org/viewvc/?view=rev&root=qemu&revision=7118
> > Author:   aurel32
> > Date:     2009-04-15 16:12:13 +0000 (Wed, 15 Apr 2009)
> > Log Message:
> > -----------
> > linux-user: prefer glibc over direct syscalls
> > ...
> > +
> > +# Check for initofy functions when we are building linux-user
> >   
> 
> initofy => inotify?
> 

Thanks, fixed.

-- 
Aurelien Jarno	                        GPG: 1024D/F1BCDB73
aurelien@aurel32.net                 http://www.aurel32.net

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [Qemu-devel] [7118] linux-user: prefer glibc over direct syscalls
  2009-04-15 16:12 [Qemu-devel] [7118] linux-user: prefer glibc over direct syscalls Aurelien Jarno
  2009-04-15 19:21 ` Stefan Weil
@ 2009-04-16 15:25 ` Laurent Desnogues
  2009-04-16 16:47   ` Riku Voipio
  2009-04-17  0:16 ` Paul Brook
  2009-04-21  7:56 ` Laurent Desnogues
  3 siblings, 1 reply; 11+ messages in thread
From: Laurent Desnogues @ 2009-04-16 15:25 UTC (permalink / raw)
  To: qemu-devel

On Wed, Apr 15, 2009 at 6:12 PM, Aurelien Jarno <aurelien@aurel32.net> wrote:
> Revision: 7118
>          http://svn.sv.gnu.org/viewvc/?view=rev&root=qemu&revision=7118
> Author:   aurel32
> Date:     2009-04-15 16:12:13 +0000 (Wed, 15 Apr 2009)
> Log Message:
> -----------
> linux-user: prefer glibc over direct syscalls
>
> The openat/*at syscalls are incredibly common with modern coreutils,
> calling them directly via syscalls breaks for example fakeroot. Use
> glibc stubs whenever directly available and provide old syscall
> calling for people still using older libc.
>
> Patch originally from Mika Westerberg, Adapted to
> apply to current trunk and cleaned up by Riku Voipio.
>
> Signed-off-by: Riku Voipio <riku.voipio@iki.fi>
> Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
>
> Modified Paths:
> --------------
>    trunk/configure
>    trunk/linux-user/syscall.c
[...]
> Modified: trunk/linux-user/syscall.c
> ===================================================================
> --- trunk/linux-user/syscall.c  2009-04-15 16:12:06 UTC (rev 7117)
> +++ trunk/linux-user/syscall.c  2009-04-15 16:12:13 UTC (rev 7118)
[...]
> @@ -285,22 +482,37 @@
>  _syscall4(int,sys_utimensat,int,dirfd,const char *,pathname,
>           const struct timespec *,tsp,int,flags)
>  #endif
> +
> +#endif /* CONFIG_ATFILE */
> +
> +#ifdef CONFIG_INOTIFY
> +
>  #if defined(TARGET_NR_inotify_init) && defined(__NR_inotify_init)
> -_syscall0(int,sys_inotify_init)
> +static int sys_inotify_init(void)
> +{
> +  return (inotify_init());
> +}
>  #endif
>  #if defined(TARGET_NR_inotify_add_watch) && defined(__NR_inotify_add_watch)
> -_syscall3(int,sys_inotify_add_watch,int,fd,const char *,pathname,uint32_t,mask)
> +static int sys_inotify_add_watch(int fd,const char *pathname, int32_t mask)
> +{
> +  return (inotify_add_watch(fd, pathname, mask));
> +}
>  #endif
>  #if defined(TARGET_NR_inotify_rm_watch) && defined(__NR_inotify_rm_watch)
> -_syscall2(int,sys_inotify_rm_watch,int,fd,uint32_t,wd)
> +static int sys_inotify_rm_watch(int fd, int32_t wd)
> +{
> +  return (inotify_rm_watch(fd,pathname, wd));

Isn't pathname spurious?


Laurent

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [Qemu-devel] [7118] linux-user: prefer glibc over direct syscalls
  2009-04-16 15:25 ` Laurent Desnogues
@ 2009-04-16 16:47   ` Riku Voipio
  2009-04-17 13:51     ` Aurelien Jarno
  0 siblings, 1 reply; 11+ messages in thread
From: Riku Voipio @ 2009-04-16 16:47 UTC (permalink / raw)
  To: qemu-devel

On Thu, Apr 16, 2009 at 05:25:25PM +0200, Laurent Desnogues wrote:
> >  #if defined(TARGET_NR_inotify_rm_watch) && defined(__NR_inotify_rm_watch)
> > -_syscall2(int,sys_inotify_rm_watch,int,fd,uint32_t,wd)
> > +static int sys_inotify_rm_watch(int fd, int32_t wd)
> > +{
> > +  return (inotify_rm_watch(fd,pathname, wd));

> Isn't pathname spurious?

It is broken. Try this.

>From 448cfe737b614ec44a8c4a9a4d8c2542c3eac165 Mon Sep 17 00:00:00 2001
From: Riku Voipio <riku.voipio@iki.fi>
Date: Thu, 16 Apr 2009 19:38:14 +0300
Subject: linux-user: fix inotify syscalls

Configure test was broken, so the breakage of the #ifdef'd
code was not noticed.

Signed-off-by: Riku Voipio <riku.voipio@iki.fi>
---
 configure            |    2 +-
 linux-user/syscall.c |    3 ++-
 2 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/configure b/configure
index 5b705a0..251d271 100755
--- a/configure
+++ b/configure
@@ -1200,7 +1200,7 @@ int
 main(void)
 {
 	/* try to start inotify */
-	return inotify_init(void);
+	return inotify_init();
 }
 EOF
   if $cc $ARCH_CFLAGS -o $TMPE $TMPC 2> /dev/null ; then
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 898f58c..c94efe6 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -480,6 +480,7 @@ _syscall4(int,sys_utimensat,int,dirfd,const char *,pathname,
 #endif /* CONFIG_ATFILE */
 
 #ifdef CONFIG_INOTIFY
+#include <sys/inotify.h>
 
 #if defined(TARGET_NR_inotify_init) && defined(__NR_inotify_init)
 static int sys_inotify_init(void)
@@ -496,7 +497,7 @@ static int sys_inotify_add_watch(int fd,const char *pathname, int32_t mask)
 #if defined(TARGET_NR_inotify_rm_watch) && defined(__NR_inotify_rm_watch)
 static int sys_inotify_rm_watch(int fd, int32_t wd)
 {
-  return (inotify_rm_watch(fd,pathname, wd));
+  return (inotify_rm_watch(fd, wd));
 }
 #endif
 #else
-- 
1.6.2.1


-- 
"rm -rf" only sounds scary if you don't have backups

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* Re: [Qemu-devel] [7118] linux-user: prefer glibc over direct syscalls
  2009-04-15 16:12 [Qemu-devel] [7118] linux-user: prefer glibc over direct syscalls Aurelien Jarno
  2009-04-15 19:21 ` Stefan Weil
  2009-04-16 15:25 ` Laurent Desnogues
@ 2009-04-17  0:16 ` Paul Brook
  2009-04-17  8:03   ` Riku Voipio
  2009-04-21  7:56 ` Laurent Desnogues
  3 siblings, 1 reply; 11+ messages in thread
From: Paul Brook @ 2009-04-17  0:16 UTC (permalink / raw)
  To: qemu-devel; +Cc: Aurelien Jarno

On Wednesday 15 April 2009, Aurelien Jarno wrote:
> +# Check for xxxat() functions when we are building linux-user
> +# emulator.
> +if [ "$linux_user" = "yes" ] ; then

This is wrong. $linux_user only indicates whether the linux usermode targets 
are built by default. It can be overridden by --target-list.

Paul

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [Qemu-devel] [7118] linux-user: prefer glibc over direct syscalls
  2009-04-17  0:16 ` Paul Brook
@ 2009-04-17  8:03   ` Riku Voipio
  0 siblings, 0 replies; 11+ messages in thread
From: Riku Voipio @ 2009-04-17  8:03 UTC (permalink / raw)
  To: qemu-devel

On Fri, Apr 17, 2009 at 01:16:28AM +0100, Paul Brook wrote:
> On Wednesday 15 April 2009, Aurelien Jarno wrote:
> > +# Check for xxxat() functions when we are building linux-user
> > +# emulator.
> > +if [ "$linux_user" = "yes" ] ; then

> This is wrong. $linux_user only indicates whether the linux usermode targets 
> are built by default. It can be overridden by --target-list.

linux_user is default yes linux host and is only removed with --disable-linux-user.
So, to expose this wrongness one would have to configure with
 --disable-linux-user --target-list="foo-linux-user"

I guess we can still drop the $linux_user test and run it anyway, same way
tests only needed for system-qemu (gnutls, sasl..) are run even when
configuring for a linux-user targets build.

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [Qemu-devel] [7118] linux-user: prefer glibc over direct syscalls
  2009-04-16 16:47   ` Riku Voipio
@ 2009-04-17 13:51     ` Aurelien Jarno
  0 siblings, 0 replies; 11+ messages in thread
From: Aurelien Jarno @ 2009-04-17 13:51 UTC (permalink / raw)
  To: Riku Voipio; +Cc: qemu-devel

On Thu, Apr 16, 2009 at 07:47:57PM +0300, Riku Voipio wrote:
> On Thu, Apr 16, 2009 at 05:25:25PM +0200, Laurent Desnogues wrote:
> > >  #if defined(TARGET_NR_inotify_rm_watch) && defined(__NR_inotify_rm_watch)
> > > -_syscall2(int,sys_inotify_rm_watch,int,fd,uint32_t,wd)
> > > +static int sys_inotify_rm_watch(int fd, int32_t wd)
> > > +{
> > > +  return (inotify_rm_watch(fd,pathname, wd));
> 
> > Isn't pathname spurious?
> 
> It is broken. Try this.

Thanks, applied.

> From 448cfe737b614ec44a8c4a9a4d8c2542c3eac165 Mon Sep 17 00:00:00 2001
> From: Riku Voipio <riku.voipio@iki.fi>
> Date: Thu, 16 Apr 2009 19:38:14 +0300
> Subject: linux-user: fix inotify syscalls
> 
> Configure test was broken, so the breakage of the #ifdef'd
> code was not noticed.
> 
> Signed-off-by: Riku Voipio <riku.voipio@iki.fi>
> ---
>  configure            |    2 +-
>  linux-user/syscall.c |    3 ++-
>  2 files changed, 3 insertions(+), 2 deletions(-)
> 
> diff --git a/configure b/configure
> index 5b705a0..251d271 100755
> --- a/configure
> +++ b/configure
> @@ -1200,7 +1200,7 @@ int
>  main(void)
>  {
>  	/* try to start inotify */
> -	return inotify_init(void);
> +	return inotify_init();
>  }
>  EOF
>    if $cc $ARCH_CFLAGS -o $TMPE $TMPC 2> /dev/null ; then
> diff --git a/linux-user/syscall.c b/linux-user/syscall.c
> index 898f58c..c94efe6 100644
> --- a/linux-user/syscall.c
> +++ b/linux-user/syscall.c
> @@ -480,6 +480,7 @@ _syscall4(int,sys_utimensat,int,dirfd,const char *,pathname,
>  #endif /* CONFIG_ATFILE */
>  
>  #ifdef CONFIG_INOTIFY
> +#include <sys/inotify.h>
>  
>  #if defined(TARGET_NR_inotify_init) && defined(__NR_inotify_init)
>  static int sys_inotify_init(void)
> @@ -496,7 +497,7 @@ static int sys_inotify_add_watch(int fd,const char *pathname, int32_t mask)
>  #if defined(TARGET_NR_inotify_rm_watch) && defined(__NR_inotify_rm_watch)
>  static int sys_inotify_rm_watch(int fd, int32_t wd)
>  {
> -  return (inotify_rm_watch(fd,pathname, wd));
> +  return (inotify_rm_watch(fd, wd));
>  }
>  #endif
>  #else
> -- 
> 1.6.2.1
> 
> 
> -- 
> "rm -rf" only sounds scary if you don't have backups
> 
> 
> 

-- 
Aurelien Jarno	                        GPG: 1024D/F1BCDB73
aurelien@aurel32.net                 http://www.aurel32.net

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [Qemu-devel] [7118] linux-user: prefer glibc over direct syscalls
  2009-04-15 16:12 [Qemu-devel] [7118] linux-user: prefer glibc over direct syscalls Aurelien Jarno
                   ` (2 preceding siblings ...)
  2009-04-17  0:16 ` Paul Brook
@ 2009-04-21  7:56 ` Laurent Desnogues
  2009-04-21  8:36   ` Arnaud Patard
  3 siblings, 1 reply; 11+ messages in thread
From: Laurent Desnogues @ 2009-04-21  7:56 UTC (permalink / raw)
  To: qemu-devel

On Wed, Apr 15, 2009 at 6:12 PM, Aurelien Jarno <aurelien@aurel32.net> wrote:
> Revision: 7118
>          http://svn.sv.gnu.org/viewvc/?view=rev&root=qemu&revision=7118
> Author:   aurel32
> Date:     2009-04-15 16:12:13 +0000 (Wed, 15 Apr 2009)
> Log Message:
> -----------
> linux-user: prefer glibc over direct syscalls
>
> The openat/*at syscalls are incredibly common with modern coreutils,
> calling them directly via syscalls breaks for example fakeroot. Use
> glibc stubs whenever directly available and provide old syscall
> calling for people still using older libc.
>
> Patch originally from Mika Westerberg, Adapted to
> apply to current trunk and cleaned up by Riku Voipio.
>
> Signed-off-by: Riku Voipio <riku.voipio@iki.fi>
> Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
>
> Modified Paths:
> --------------
>    trunk/configure
>    trunk/linux-user/syscall.c
[...]
> +int
> +main(void)
> +{
> +       /* try to unlink nonexisting file */
> +       return (unlinkat(AT_FDCWD, "nonexistent_file", 0));
> +}
> +EOF
> +  if $cc $ARCH_CFLAGS -o $TMPE $TMPC 2> /dev/null ; then
> +    atfile=yes
> +  fi
> +fi
[...]
> Modified: trunk/linux-user/syscall.c
> ===================================================================
> --- trunk/linux-user/syscall.c  2009-04-15 16:12:06 UTC (rev 7117)
> +++ trunk/linux-user/syscall.c  2009-04-15 16:12:13 UTC (rev 7118)
[...]
> +#ifdef CONFIG_ATFILE
> +/*
> + * Host system seems to have atfile syscall stubs available.  We
> + * now enable them one by one as specified by target syscall_nr.h.
> + */
> +
> +#ifdef TARGET_NR_faccessat
> +static int sys_faccessat(int dirfd, const char *pathname, int mode, int flags)
> +{
> +  return (faccessat(dirfd, pathname, mode, flags));
> +}
> +#endif
> +#ifdef TARGET_NR_fchmodat
> +static int sys_fchmodat(int dirfd, const char *pathname, mode_t mode, int flags)
> +{
> +  return (fchmodat(dirfd, pathname, mode, flags));
> +}
> +#endif
> +#ifdef TARGET_NR_fchownat
> +static int sys_fchownat(int dirfd, const char *pathname, uid_t owner,
> +    gid_t group, int flags)
> +{
> +  return (fchownat(dirfd, pathname, owner, group, flags));
> +}
> +#endif
> +#ifdef __NR_fstatat64
> +static int sys_fstatat64(int dirfd, const char *pathname, struct stat *buf,
> +    int flags)
> +{
> +  return (fstatat(dirfd, pathname, buf, flags));
> +}
> +#endif
> +#ifdef __NR_newfstatat
> +static int sys_newfstatat(int dirfd, const char *pathname, struct stat *buf,
> +    int flags)
> +{
> +  return (fstatat(dirfd, pathname, buf, flags));
> +}
> +#endif
> +#ifdef TARGET_NR_futimesat
> +static int sys_futimesat(int dirfd, const char *pathname,
> +    const struct timeval times[2])
> +{
> +  return (futimesat(dirfd, pathname, times));
> +}
> +#endif
> +#ifdef TARGET_NR_linkat
> +static int sys_linkat(int olddirfd, const char *oldpath,
> +    int newdirfd, const char *newpath, int flags)
> +{
> +  return (linkat(olddirfd, oldpath, newdirfd, newpath, flags));
> +}
> +#endif
> +#ifdef TARGET_NR_mkdirat
> +static int sys_mkdirat(int dirfd, const char *pathname, mode_t mode)
> +{
> +  return (mkdirat(dirfd, pathname, mode));
> +}
> +#endif
> +#ifdef TARGET_NR_mknodat
> +static int sys_mknodat(int dirfd, const char *pathname, mode_t mode,
> +    dev_t dev)
> +{
> +  return (mknodat(dirfd, pathname, mode, dev));
> +}
> +#endif
> +#ifdef TARGET_NR_openat
> +static int sys_openat(int dirfd, const char *pathname, int flags, ...)
> +{
> +  /*
> +   * open(2) has extra parameter 'mode' when called with
> +   * flag O_CREAT.
> +   */
> +  if ((flags & O_CREAT) != 0) {
> +      va_list ap;
> +      mode_t mode;
> +
> +      /*
> +       * Get the 'mode' parameter and translate it to
> +       * host bits.
> +       */
> +      va_start(ap, flags);
> +      mode = va_arg(ap, mode_t);
> +      mode = target_to_host_bitmask(mode, fcntl_flags_tbl);
> +      va_end(ap);
> +
> +      return (openat(dirfd, pathname, flags, mode));
> +  }
> +  return (openat(dirfd, pathname, flags));
> +}
> +#endif
> +#ifdef TARGET_NR_readlinkat
> +static int sys_readlinkat(int dirfd, const char *pathname, char *buf, size_t bufsiz)
> +{
> +  return (readlinkat(dirfd, pathname, buf, bufsiz));
> +}
> +#endif
> +#ifdef TARGET_NR_renameat
> +static int sys_renameat(int olddirfd, const char *oldpath,
> +    int newdirfd, const char *newpath)
> +{
> +  return (renameat(olddirfd, oldpath, newdirfd, newpath));
> +}
> +#endif
> +#ifdef TARGET_NR_symlinkat
> +static int sys_symlinkat(const char *oldpath, int newdirfd, const char *newpath)
> +{
> +  return (symlinkat(oldpath, newdirfd, newpath));
> +}
> +#endif
> +#ifdef TARGET_NR_unlinkat
> +static int sys_unlinkat(int dirfd, const char *pathname, int flags)
> +{
> +  return (unlinkat(dirfd, pathname, flags));
> +}
> +#endif
> +#ifdef TARGET_NR_utimensat
> +static int sys_utimensat(int dirfd, const char *pathname,
> +    const struct timespec times[2], int flags)
> +{
> +  return (utimensat(dirfd, pathname, times, flags));
> +}
> +#endif

Just to point that my system has all *at functions except for utimensat.
This breaks compilation.  Shouldn't all *at functions be tested in the
configure script?

For the record I am running CentOS 5.3 x86_64.


Laurent

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [Qemu-devel] [7118] linux-user: prefer glibc over direct syscalls
  2009-04-21  8:36   ` Arnaud Patard
@ 2009-04-21  8:35     ` Laurent Desnogues
  0 siblings, 0 replies; 11+ messages in thread
From: Laurent Desnogues @ 2009-04-21  8:35 UTC (permalink / raw)
  To: Arnaud Patard; +Cc: qemu-devel

On Tue, Apr 21, 2009 at 10:36 AM, Arnaud Patard
<arnaud.patard@rtp-net.org> wrote:
>
> This utimensat change is broken, I've sent a patch to revert to the
> syscall interface. As a side effect, it'll bring back the check :
>
> #if defined(TARGET_NR_utimensat) && defined(__NR_utimensat)
>
> It will likely solve your trouble. Lets hope the patch will be merged :)

Yes, that fixes it. Thanks.

>>
>> For the record I am running CentOS 5.3 x86_64.
>
> hmm... glibc older than 2.6 or kernel older than 2.6.22 ?

Indeed: glibc 2.5 and kernel 2.6.18.


Laurent

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [Qemu-devel] [7118] linux-user: prefer glibc over direct syscalls
  2009-04-21  7:56 ` Laurent Desnogues
@ 2009-04-21  8:36   ` Arnaud Patard
  2009-04-21  8:35     ` Laurent Desnogues
  0 siblings, 1 reply; 11+ messages in thread
From: Arnaud Patard @ 2009-04-21  8:36 UTC (permalink / raw)
  To: Laurent Desnogues; +Cc: qemu-devel

Laurent Desnogues <laurent.desnogues@gmail.com> writes:

Hi,

>> +#ifdef TARGET_NR_utimensat
>> +static int sys_utimensat(int dirfd, const char *pathname,
>> +    const struct timespec times[2], int flags)
>> +{
>> +  return (utimensat(dirfd, pathname, times, flags));
>> +}
>> +#endif
>
> Just to point that my system has all *at functions except for utimensat.
> This breaks compilation.  Shouldn't all *at functions be tested in the
> configure script?

This utimensat change is broken, I've sent a patch to revert to the
syscall interface. As a side effect, it'll bring back the check :

#if defined(TARGET_NR_utimensat) && defined(__NR_utimensat)

It will likely solve your trouble. Lets hope the patch will be merged :)

>
> For the record I am running CentOS 5.3 x86_64.

hmm... glibc older than 2.6 or kernel older than 2.6.22 ?

Arnaud

^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2009-04-21  8:35 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-04-15 16:12 [Qemu-devel] [7118] linux-user: prefer glibc over direct syscalls Aurelien Jarno
2009-04-15 19:21 ` Stefan Weil
2009-04-15 19:48   ` Aurelien Jarno
2009-04-16 15:25 ` Laurent Desnogues
2009-04-16 16:47   ` Riku Voipio
2009-04-17 13:51     ` Aurelien Jarno
2009-04-17  0:16 ` Paul Brook
2009-04-17  8:03   ` Riku Voipio
2009-04-21  7:56 ` Laurent Desnogues
2009-04-21  8:36   ` Arnaud Patard
2009-04-21  8:35     ` Laurent Desnogues

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.