aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPeter Seebach <peter.seebach@windriver.com>2013-02-26 21:31:18 -0600
committerPeter Seebach <peter.seebach@windriver.com>2013-02-26 21:32:50 -0600
commit0db033145b47dfa76f57316eb9a03b157f3a0631 (patch)
tree0164f69aa0ad7af1fdd0b57709e4eb4c76153b76
parentbe1131e2ee2178bcc50ba04916fea527059f6aa0 (diff)
downloadpseudo-PSEUDO_1_5.tar.gz
pseudo-PSEUDO_1_5.tar.bz2
pseudo-PSEUDO_1_5.zip
PSEUDO_ALLOW_FSYNC: Allow fsync()pseudo-1.5PSEUDO_1_5
Some filesystems have buggy semantics where stat(2) will return incorrect sizes for files for a while after some changes, sometimes, unless they've been fsync'd. We still want to disable fsync most of the time, but enabling it for specific programs can be useful. Signed-off-by: Peter Seebach <peter.seebach@windriver.com>
-rw-r--r--ChangeLog.txt3
-rw-r--r--Makefile.in2
-rwxr-xr-xmakewrappers3
-rw-r--r--pseudo.h1
-rw-r--r--pseudo_client.c20
-rw-r--r--pseudo_util.c1
6 files changed, 28 insertions, 2 deletions
diff --git a/ChangeLog.txt b/ChangeLog.txt
index 6ed5706..6a1c3a8 100644
--- a/ChangeLog.txt
+++ b/ChangeLog.txt
@@ -1,5 +1,8 @@
2013-02-26:
* (seebs) When built -DNDEBUG, completely drop pseudo_debug calls.
+ * (seebs) Add PSEUDO_ALLOW_FSYNC to allow temporary re-enabling of
+ fsync to work around filesystem bugs.
+ * (seebs) call that 1.5.1.
2013-02-17:
* (seebs) Fix uninitialized variable in unlink, fix force-fsync for
diff --git a/Makefile.in b/Makefile.in
index 8046bda..21324f9 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -29,7 +29,7 @@ BITS=@BITS@
ARCH_FLAGS=@ARCH_FLAGS@
MARK64=@MARK64@
RPATH=@RPATH@
-VERSION=1.5
+VERSION=1.5.1
LIB=@LIB@
BIN=bin
diff --git a/makewrappers b/makewrappers
index 8af65f1..e87cc56 100755
--- a/makewrappers
+++ b/makewrappers
@@ -305,7 +305,8 @@ class Function:
if self.async_skip:
return """/* This function is not called if pseudo is configured --enable-force-async */
#ifdef PSEUDO_FORCE_ASYNC
- return %s;
+ if (!pseudo_allow_fsync)
+ return %s;
#endif
""" % self.async_skip
else:
diff --git a/pseudo.h b/pseudo.h
index ca2baa9..56760a4 100644
--- a/pseudo.h
+++ b/pseudo.h
@@ -35,6 +35,7 @@ extern void pseudo_debug_verbose(void);
extern void pseudo_debug_terse(void);
extern int pseudo_util_debug_fd;
extern int pseudo_disabled;
+extern int pseudo_allow_fsync;
#ifndef NDEBUG
extern int pseudo_debug_real(int, char *, ...) __attribute__ ((format (printf, 2, 3)));
#define pseudo_debug pseudo_debug_real
diff --git a/pseudo_client.c b/pseudo_client.c
index f58ce4c..a3e40f6 100644
--- a/pseudo_client.c
+++ b/pseudo_client.c
@@ -68,6 +68,7 @@ size_t pseudo_chroot_len = 0;
char *pseudo_cwd_rel = NULL;
/* used for PSEUDO_DISABLED */
int pseudo_disabled = 0;
+int pseudo_allow_fsync = 0;
static int pseudo_local_only = 0;
static char **fd_paths = NULL;
@@ -163,6 +164,25 @@ pseudo_init_client(void) {
pseudo_set_value("PSEUDO_DISABLED", "0");
}
+ /* ALLOW_FSYNC is here because some crazy hosts will otherwise
+ * report incorrect values for st_size/st_blocks. I can sort of
+ * understand st_blocks, but bogus values for st_size? Not cool,
+ * dudes, not cool.
+ */
+ env = getenv("PSEUDO_ALLOW_FSYNC");
+ if (!env) {
+ env = pseudo_get_value("PSEUDO_ALLOW_FSYNC");
+ } else {
+ pseudo_set_value("PSEUDO_ALLOW_FSYNC", env);
+ }
+ if (env) {
+ pseudo_allow_fsync = 1;
+ pseudo_diag("pseudo_allow_fsync: %s => 1\n", env);
+ } else {
+ pseudo_allow_fsync = 0;
+ pseudo_diag("pseudo_allow_fsync: null => 0\n");
+ }
+
/* in child processes, PSEUDO_UNLOAD may become set to
* some truthy value, in which case we're being asked to
* remove pseudo from the LD_PRELOAD. We need to make sure
diff --git a/pseudo_util.c b/pseudo_util.c
index ca2f0a4..8d0969e 100644
--- a/pseudo_util.c
+++ b/pseudo_util.c
@@ -65,6 +65,7 @@ static struct pseudo_variables pseudo_env[] = {
{ "PSEUDO_NOSYMLINKEXP", 19, NULL },
{ "PSEUDO_DISABLED", 15, NULL },
{ "PSEUDO_UNLOAD", 13, NULL },
+ { "PSEUDO_ALLOW_FSYNC", 18, NULL },
{ NULL, 0, NULL } /* Magic terminator */
};