From: Julian Seward Date: Thu, 18 Aug 2011 15:08:20 +0000 (+0000) Subject: Add a new simulation hint, --sim-hints=fuse-compatible, which causes X-Git-Tag: svn/VALGRIND_3_7_0~244 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=7bb130f5f32893218fb9a5a7fc5ee795215180b3;p=thirdparty%2Fvalgrind.git Add a new simulation hint, --sim-hints=fuse-compatible, which causes a bunch of file-related syscalls to be handled on the might-block syscall path rather than the fast syscall path. This fixes deadlocks when running some FUSE-specific filesystem codes. Fixes #278057. (Mike Shal, marfey@gmail.com) git-svn-id: svn://svn.valgrind.org/valgrind/trunk@11993 --- diff --git a/coregrind/m_main.c b/coregrind/m_main.c index cc217f40ea..f0134b6a0a 100644 --- a/coregrind/m_main.c +++ b/coregrind/m_main.c @@ -177,7 +177,7 @@ static void usage_NORETURN ( Bool debug_help ) " --vgdb-prefix= prefix for vgdb FIFOs [%s]\n" " --run-libc-freeres=no|yes free up glibc memory at exit on Linux? [yes]\n" " --sim-hints=hint1,hint2,... known hints:\n" -" lax-ioctls, enable-outer [none]\n" +" lax-ioctls, enable-outer, fuse-compatible [none]\n" " --kernel-variant=variant1,variant2,... known variants: bproc [none]\n" " handle non-standard kernel variants\n" " --show-emwarns=no|yes show warnings about emulation limits? [no]\n" diff --git a/coregrind/m_syswrap/priv_types_n_macros.h b/coregrind/m_syswrap/priv_types_n_macros.h index b15d19b541..a7890b26ed 100644 --- a/coregrind/m_syswrap/priv_types_n_macros.h +++ b/coregrind/m_syswrap/priv_types_n_macros.h @@ -345,6 +345,9 @@ static inline UWord getERR ( SyscallStatus* st ) { if (VG_(clo_trace_syscalls)) \ VG_(printf)(format, ## args) +#define FUSE_COMPATIBLE_MAY_BLOCK() \ + if (VG_(strstr)(VG_(clo_sim_hints),"fuse-compatible")) \ + *flags |= SfMayBlock /* Macros used to tell tools about uses of scalar arguments. Note, diff --git a/coregrind/m_syswrap/syswrap-generic.c b/coregrind/m_syswrap/syswrap-generic.c index ec09e50687..87a7c1104f 100644 --- a/coregrind/m_syswrap/syswrap-generic.c +++ b/coregrind/m_syswrap/syswrap-generic.c @@ -2412,6 +2412,7 @@ PRE(sys_sync) PRE(sys_fstatfs) { + FUSE_COMPATIBLE_MAY_BLOCK(); PRINT("sys_fstatfs ( %ld, %#lx )",ARG1,ARG2); PRE_REG_READ2(long, "fstatfs", unsigned int, fd, struct statfs *, buf); @@ -2425,6 +2426,7 @@ POST(sys_fstatfs) PRE(sys_fstatfs64) { + FUSE_COMPATIBLE_MAY_BLOCK(); PRINT("sys_fstatfs64 ( %ld, %llu, %#lx )",ARG1,(ULong)ARG2,ARG3); PRE_REG_READ3(long, "fstatfs64", unsigned int, fd, vki_size_t, size, struct statfs64 *, buf); @@ -2471,6 +2473,7 @@ POST(sys_pread64) PRE(sys_mknod) { + FUSE_COMPATIBLE_MAY_BLOCK(); PRINT("sys_mknod ( %#lx(%s), 0x%lx, 0x%lx )", ARG1, (char*)ARG1, ARG2, ARG3 ); PRE_REG_READ3(long, "mknod", const char *, pathname, int, mode, unsigned, dev); @@ -2849,6 +2852,7 @@ PRE(sys_brk) PRE(sys_chdir) { + FUSE_COMPATIBLE_MAY_BLOCK(); PRINT("sys_chdir ( %#lx(%s) )", ARG1,(char*)ARG1); PRE_REG_READ1(long, "chdir", const char *, path); PRE_MEM_RASCIIZ( "chdir(path)", ARG1 ); @@ -2856,6 +2860,7 @@ PRE(sys_chdir) PRE(sys_chmod) { + FUSE_COMPATIBLE_MAY_BLOCK(); PRINT("sys_chmod ( %#lx(%s), %ld )", ARG1,(char*)ARG1,ARG2); PRE_REG_READ2(long, "chmod", const char *, path, vki_mode_t, mode); PRE_MEM_RASCIIZ( "chmod(path)", ARG1 ); @@ -2863,6 +2868,7 @@ PRE(sys_chmod) PRE(sys_chown) { + FUSE_COMPATIBLE_MAY_BLOCK(); PRINT("sys_chown ( %#lx(%s), 0x%lx, 0x%lx )", ARG1,(char*)ARG1,ARG2,ARG3); PRE_REG_READ3(long, "chown", const char *, path, vki_uid_t, owner, vki_gid_t, group); @@ -2871,6 +2877,7 @@ PRE(sys_chown) PRE(sys_lchown) { + FUSE_COMPATIBLE_MAY_BLOCK(); PRINT("sys_lchown ( %#lx(%s), 0x%lx, 0x%lx )", ARG1,(char*)ARG1,ARG2,ARG3); PRE_REG_READ3(long, "lchown", const char *, path, vki_uid_t, owner, vki_gid_t, group); @@ -2879,6 +2886,7 @@ PRE(sys_lchown) PRE(sys_close) { + FUSE_COMPATIBLE_MAY_BLOCK(); PRINT("sys_close ( %ld )", ARG1); PRE_REG_READ1(long, "close", unsigned int, fd); @@ -2930,12 +2938,14 @@ POST(sys_dup2) PRE(sys_fchdir) { + FUSE_COMPATIBLE_MAY_BLOCK(); PRINT("sys_fchdir ( %ld )", ARG1); PRE_REG_READ1(long, "fchdir", unsigned int, fd); } PRE(sys_fchown) { + FUSE_COMPATIBLE_MAY_BLOCK(); PRINT("sys_fchown ( %ld, %ld, %ld )", ARG1,ARG2,ARG3); PRE_REG_READ3(long, "fchown", unsigned int, fd, vki_uid_t, owner, vki_gid_t, group); @@ -2943,12 +2953,14 @@ PRE(sys_fchown) PRE(sys_fchmod) { + FUSE_COMPATIBLE_MAY_BLOCK(); PRINT("sys_fchmod ( %ld, %ld )", ARG1,ARG2); PRE_REG_READ2(long, "fchmod", unsigned int, fildes, vki_mode_t, mode); } PRE(sys_newfstat) { + FUSE_COMPATIBLE_MAY_BLOCK(); PRINT("sys_newfstat ( %ld, %#lx )", ARG1,ARG2); PRE_REG_READ2(long, "fstat", unsigned int, fd, struct stat *, buf); PRE_MEM_WRITE( "fstat(buf)", ARG2, sizeof(struct vki_stat) ); @@ -3741,6 +3753,7 @@ POST(sys_poll) PRE(sys_readlink) { + FUSE_COMPATIBLE_MAY_BLOCK(); Word saved = SYSNO; PRINT("sys_readlink ( %#lx(%s), %#lx, %llu )", ARG1,(char*)ARG1,ARG2,(ULong)ARG3); @@ -3822,6 +3835,7 @@ POST(sys_readv) PRE(sys_rename) { + FUSE_COMPATIBLE_MAY_BLOCK(); PRINT("sys_rename ( %#lx(%s), %#lx(%s) )", ARG1,(char*)ARG1,ARG2,(char*)ARG2); PRE_REG_READ2(long, "rename", const char *, oldpath, const char *, newpath); PRE_MEM_RASCIIZ( "rename(oldpath)", ARG1 ); @@ -4121,6 +4135,7 @@ PRE(sys_writev) PRE(sys_utimes) { + FUSE_COMPATIBLE_MAY_BLOCK(); PRINT("sys_utimes ( %#lx(%s), %#lx )", ARG1,(char*)ARG1,ARG2); PRE_REG_READ2(long, "utimes", char *, filename, struct timeval *, tvp); PRE_MEM_RASCIIZ( "utimes(filename)", ARG1 ); diff --git a/coregrind/m_syswrap/syswrap-linux.c b/coregrind/m_syswrap/syswrap-linux.c index ac5e8ec74d..1cfd7b78ab 100644 --- a/coregrind/m_syswrap/syswrap-linux.c +++ b/coregrind/m_syswrap/syswrap-linux.c @@ -3267,6 +3267,7 @@ PRE(sys_utimensat) PRE(sys_newfstatat) { + FUSE_COMPATIBLE_MAY_BLOCK(); PRINT("sys_newfstatat ( %ld, %#lx(%s), %#lx )", ARG1,ARG2,(char*)ARG2,ARG3); PRE_REG_READ3(long, "fstatat", int, dfd, char *, file_name, struct stat *, buf); diff --git a/coregrind/m_syswrap/syswrap-x86-linux.c b/coregrind/m_syswrap/syswrap-x86-linux.c index 9888cc6f32..aa7c0b68be 100644 --- a/coregrind/m_syswrap/syswrap-x86-linux.c +++ b/coregrind/m_syswrap/syswrap-x86-linux.c @@ -1404,6 +1404,7 @@ POST(sys_lstat64) PRE(sys_stat64) { + FUSE_COMPATIBLE_MAY_BLOCK(); PRINT("sys_stat64 ( %#lx(%s), %#lx )",ARG1,(char*)ARG1,ARG2); PRE_REG_READ2(long, "stat64", char *, file_name, struct stat64 *, buf); PRE_MEM_RASCIIZ( "stat64(file_name)", ARG1 ); @@ -1417,6 +1418,7 @@ POST(sys_stat64) PRE(sys_fstatat64) { + FUSE_COMPATIBLE_MAY_BLOCK(); PRINT("sys_fstatat64 ( %ld, %#lx(%s), %#lx )",ARG1,ARG2,(char*)ARG2,ARG3); PRE_REG_READ3(long, "fstatat64", int, dfd, char *, file_name, struct stat64 *, buf); diff --git a/docs/xml/manual-core.xml b/docs/xml/manual-core.xml index 1e03d66f4c..76c1ed0c11 100644 --- a/docs/xml/manual-core.xml +++ b/docs/xml/manual-core.xml @@ -1647,6 +1647,15 @@ need to use these. magic needed when the program being run is itself Valgrind. + + Enable special + handling for certain system calls that may block in a FUSE + file-system. This may be necessary when running Valgrind + on a multi-threaded program that uses one thread to manage + a FUSE file-system and another thread to access that + file-system. + + diff --git a/none/tests/cmdline1.stdout.exp b/none/tests/cmdline1.stdout.exp index 4bb0752f7d..5b96d088ca 100644 --- a/none/tests/cmdline1.stdout.exp +++ b/none/tests/cmdline1.stdout.exp @@ -72,7 +72,7 @@ usage: valgrind [options] prog-and-args --vgdb-prefix= prefix for vgdb FIFOs [/tmp/vgdb-pipe] --run-libc-freeres=no|yes free up glibc memory at exit on Linux? [yes] --sim-hints=hint1,hint2,... known hints: - lax-ioctls, enable-outer [none] + lax-ioctls, enable-outer, fuse-compatible [none] --kernel-variant=variant1,variant2,... known variants: bproc [none] handle non-standard kernel variants --show-emwarns=no|yes show warnings about emulation limits? [no] diff --git a/none/tests/cmdline2.stdout.exp b/none/tests/cmdline2.stdout.exp index 056c689084..40cdb0d3ed 100644 --- a/none/tests/cmdline2.stdout.exp +++ b/none/tests/cmdline2.stdout.exp @@ -72,7 +72,7 @@ usage: valgrind [options] prog-and-args --vgdb-prefix= prefix for vgdb FIFOs [/tmp/vgdb-pipe] --run-libc-freeres=no|yes free up glibc memory at exit on Linux? [yes] --sim-hints=hint1,hint2,... known hints: - lax-ioctls, enable-outer [none] + lax-ioctls, enable-outer, fuse-compatible [none] --kernel-variant=variant1,variant2,... known variants: bproc [none] handle non-standard kernel variants --show-emwarns=no|yes show warnings about emulation limits? [no]