qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-devel] [PATCH 09/10] Prefer glibc over direct syscalls


From: Aurelien Jarno
Subject: Re: [Qemu-devel] [PATCH 09/10] Prefer glibc over direct syscalls
Date: Wed, 15 Apr 2009 18:14:38 +0200
User-agent: Mutt/1.5.18 (2008-05-17)

On Sun, Apr 05, 2009 at 11:59:25PM +0300, address@hidden wrote:
> From: Riku Voipio <address@hidden>
> 
> 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 <address@hidden>
> ---
>  configure            |   53 +++++++++
>  linux-user/syscall.c |  314 
> ++++++++++++++++++++++++++++++++++++++++----------
>  2 files changed, 306 insertions(+), 61 deletions(-)

Thanks, applied.

> diff --git a/configure b/configure
> index fa77937..8955c83 100755
> --- a/configure
> +++ b/configure
> @@ -1115,6 +1115,53 @@ EOF
>    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
> @@ -1494,6 +1541,12 @@ if test "$curses" = "yes" ; then
>    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
> diff --git a/linux-user/syscall.c b/linux-user/syscall.c
> index 110cba0..52e9ff5 100644
> --- a/linux-user/syscall.c
> +++ b/linux-user/syscall.c
> @@ -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 @@ static int gettid(void) {
>      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 @@ _syscall4(int,sys_fstatat64,int,dirfd,const char 
> *,pathname,
>  _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);
> -#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);
> +#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_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 @@ _syscall3(int,sys_mkdirat,int,dirfd,const char 
> *,pathname,mode_t,mode)
>  _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_readlinkat,int,dirfd,const char 
> *,pathname,
>  _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,21 +482,36 @@ _syscall3(int,sys_unlinkat,int,dirfd,const char 
> *,pathname,int,flags)
>  _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)
> -#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
> +static int sys_inotify_rm_watch(int fd, int32_t wd)
> +{
> +  return (inotify_rm_watch(fd,pathname, wd));
> +}
>  #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);
> @@ -2837,26 +3049,6 @@ static bitmask_transtbl mmap_flags_tbl[] = {
>       { 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 */
> -- 
> 1.6.2.1
> 
> 
> 
> 

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




reply via email to

[Prev in Thread] Current Thread [Next in Thread]