[Pkg-samba-maint] Bug#759008: libtdb1: FTBFS on hurd-i386
Samuel Thibault
sthibault at debian.org
Sun Mar 1 21:37:44 UTC 2015
Hello,
With the current hurd libc and tdb built with the attached patches,
making it use whole-file locking on platforms which don't support record
locking, tdb works fine, ./bin/tdbtorture -n 10 says "OK", it takes
3m to complete, which is not so bad compared to the 30s it takes with
proper record locking in Linux.
Again, we are fine with a slow tdb: we don't target supporting samba
servers or such, we just want to have tdb basically working, instead
of manually removing it as a dependency from various packages, only to
have to put that back when we have record locking working properly (that
looks like unnecessary work to me). Samba is currently a blocker for
various packages, including mplayer, vlc, kde runtime, etc.
Samuel
-------------- next part --------------
Index: tdb-1.3.0/common/lock.c
===================================================================
--- tdb-1.3.0.orig/common/lock.c
+++ tdb-1.3.0/common/lock.c
@@ -47,10 +47,28 @@ static int fcntl_lock(struct tdb_context
}
#endif
+#ifndef HAVE_FCNTL_LOCK_PARTIAL
+ /* Some platforms (like GNU/Hurd) only support whole file locking */
+ if (rw) {
+ if (tdb->nwr++)
+ /* Alread WR-locked */
+ return 0;
+ } else {
+ if (tdb->nrd++ || tdb->nwr)
+ /* Alread RD or WR-locked */
+ return 0;
+ }
+#endif
+
fl.l_type = rw;
fl.l_whence = SEEK_SET;
+#ifdef HAVE_FCNTL_LOCK_PARTIAL
fl.l_start = off;
fl.l_len = len;
+#else
+ fl.l_start = 0;
+ fl.l_len = 0;
+#endif
fl.l_pid = 0;
cmd = waitflag ? F_SETLKW : F_SETLK;
@@ -128,10 +146,37 @@ static int fcntl_unlock(struct tdb_conte
}
#endif
+#ifndef HAVE_FCNTL_LOCK_PARTIAL
+ /* Some platforms (like GNU/Hurd) only support whole file locking */
+ if (rw)
+ if (--tdb->nwr)
+ /* Still WR-locked */
+ return 0;
+ else if (tdb->nrd)
+ /* Still RD-locked, downgrade to RD */
+ fl.l_type = F_RDLCK;
+ else
+ /* Not locked any more */
+ fl.l_type = F_UNLCK;
+ else
+ if (--tdb->nrd || tdb->nwr)
+ /* Still RD or WR-locked */
+ return 0;
+ else
+ /* Not locked any more */
+ fl.l_type = F_UNLCK;
+#else
fl.l_type = F_UNLCK;
+#endif
+
fl.l_whence = SEEK_SET;
+#ifdef HAVE_FCNTL_LOCK_PARTIAL
fl.l_start = off;
fl.l_len = len;
+#else
+ fl.l_start = 0;
+ fl.l_len = 0;
+#endif
fl.l_pid = 0;
return fcntl(tdb->fd, F_SETLKW, &fl);
Index: tdb-1.3.0/lib/replace/wscript
===================================================================
--- tdb-1.3.0.orig/lib/replace/wscript
+++ tdb-1.3.0/lib/replace/wscript
@@ -134,6 +134,23 @@ struct foo bar = { .y = 'X', .x = 1 };
addmain=False,
msg='Checking for O_DIRECT flag to open(2)')
+ if conf.CHECK_HEADERS('fcntl.h'):
+ conf.CHECK_CODE('''
+ #include <fcntl.h>
+ int main (void) { int fd = open("/dev/null", O_RDWR);
+ struct flock fl;
+ fl.l_type = F_WRLCK;
+ fl.l_whence = SEEK_SET;
+ fl.l_start = fl.l_len = 100;
+ fl.l_pid = 0;
+ return fcntl(fd, F_SETLK, &fl); }
+ ''',
+ define='HAVE_FCNTL_LOCK_PARTIAL',
+ addmain=False,
+ execute=True,
+ msg='Checking for partial locking support using fcntl(2)')
+
+
conf.CHECK_TYPES('"long long" intptr_t uintptr_t ptrdiff_t comparison_fn_t')
conf.CHECK_TYPE('_Bool', define='HAVE__Bool')
conf.CHECK_TYPE('bool', define='HAVE_BOOL')
Index: tdb-1.3.0/test/run-die-during-transaction.c
===================================================================
--- tdb-1.3.0.orig/test/run-die-during-transaction.c
+++ tdb-1.3.0/test/run-die-during-transaction.c
@@ -218,6 +218,9 @@ int main(int argc, char *argv[])
struct agent *agent;
int i;
+#ifndef HAVE_FCNTL_LOCK_PARTIAL
+ skip(1, "No partial locking support");
+#else
plan_tests(12);
unlock_callback = maybe_die;
@@ -227,6 +230,6 @@ int main(int argc, char *argv[])
diag("Testing %s after death", operation_name(ops[i]));
ok1(test_death(ops[i], agent));
}
-
+#endif
return exit_status();
}
Index: tdb-1.3.0/test/run-no-lock-during-traverse.c
===================================================================
--- tdb-1.3.0.orig/test/run-no-lock-during-traverse.c
+++ tdb-1.3.0/test/run-no-lock-during-traverse.c
@@ -77,6 +77,9 @@ int main(int argc, char *argv[])
struct tdb_context *tdb;
int errors = 0;
+#ifndef HAVE_FCNTL_LOCK_PARTIAL
+ skip(1, "No partial locking support");
+#else
plan_tests(41);
tdb = tdb_open_ex("run-no-lock-during-traverse.tdb",
1024, TDB_CLEAR_IF_FIRST, O_CREAT|O_TRUNC|O_RDWR,
@@ -109,6 +112,7 @@ int main(int argc, char *argv[])
ok1(tdb_unlockall(tdb) == 0);
ok1(tdb_close(tdb) == 0);
+#endif
return exit_status();
}
Index: tdb-1.3.0/test/run-nested-traverse.c
===================================================================
--- tdb-1.3.0.orig/test/run-nested-traverse.c
+++ tdb-1.3.0/test/run-nested-traverse.c
@@ -61,6 +61,9 @@ int main(int argc, char *argv[])
struct tdb_context *tdb;
TDB_DATA key, data;
+#ifndef HAVE_FCNTL_LOCK_PARTIAL
+ skip(1, "No partial locking support");
+#else
plan_tests(17);
agent = prepare_external_agent();
@@ -83,6 +86,7 @@ int main(int argc, char *argv[])
tdb_traverse(tdb, traverse1, NULL);
tdb_traverse_read(tdb, traverse1, NULL);
tdb_close(tdb);
+#endif
return exit_status();
}
Index: tdb-1.3.0/test/run-open-during-transaction.c
===================================================================
--- tdb-1.3.0.orig/test/run-open-during-transaction.c
+++ tdb-1.3.0/test/run-open-during-transaction.c
@@ -148,6 +148,9 @@ int main(int argc, char *argv[])
struct tdb_context *tdb;
TDB_DATA key, data;
+#ifndef HAVE_FCNTL_LOCK_PARTIAL
+ skip(1, "No partial locking support");
+#else
plan_tests(20);
agent = prepare_external_agent();
@@ -177,6 +180,7 @@ int main(int argc, char *argv[])
opened = false;
tdb_close(tdb);
}
+#endif
return exit_status();
}
Index: tdb-1.3.0/test/run-marklock-deadlock.c
===================================================================
--- tdb-1.3.0.orig/test/run-marklock-deadlock.c
+++ tdb-1.3.0/test/run-marklock-deadlock.c
@@ -255,6 +255,9 @@ int main(int argc, char *argv[])
int ret;
bool mutex_support;
+#ifndef HAVE_FCNTL_LOCK_PARTIAL
+ skip(1, "No partial locking support");
+#else
mutex_support = tdb_runtime_check_for_robust_mutexes();
ret = do_tests("marklock-deadlock-fcntl.tdb",
@@ -273,6 +276,7 @@ int main(int argc, char *argv[])
TDB_MUTEX_LOCKING |
TDB_INCOMPATIBLE_HASH);
ok(ret == 0, "marklock-deadlock-mutex.tdb tests should succeed");
+#endif
return exit_status();
}
Index: tdb-1.3.0/common/tdb_private.h
===================================================================
--- tdb-1.3.0.orig/common/tdb_private.h
+++ tdb-1.3.0/common/tdb_private.h
@@ -201,6 +201,10 @@ struct tdb_context {
char *name; /* the name of the database */
void *map_ptr; /* where it is currently mapped */
int fd; /* open file descriptor for the database */
+#ifndef HAVE_FCNTL_LOCK_PARTIAL
+ int nrd; /* number of RD locks */
+ int nwr; /* number of WR locks */
+#endif
tdb_len_t map_size; /* how much space has been mapped */
int read_only; /* opened read-only */
int traverse_read; /* read-only traversal */
Index: tdb-1.3.0/common/open.c
===================================================================
--- tdb-1.3.0.orig/common/open.c
+++ tdb-1.3.0/common/open.c
@@ -328,6 +328,10 @@ _PUBLIC_ struct tdb_context *tdb_open_ex
#ifdef TDB_TRACE
tdb->tracefd = -1;
#endif
+#ifndef HAVE_FCNTL_LOCK_PARTIAL
+ tdb->nrd = 0;
+ tdb->nwr = 0;
+#endif
tdb->name = NULL;
tdb->map_ptr = NULL;
tdb->flags = tdb_flags;
--- tdb-1.3.0.orig/test/run-traverse-in-transaction.c 2014-11-25 23:47:30.000000000 +0000
+++ tdb-1.3.0/test/run-traverse-in-transaction.c 2014-11-25 23:47:45.000000000 +0000
@@ -46,6 +46,9 @@
struct tdb_context *tdb;
TDB_DATA key, data;
+#ifndef HAVE_FCNTL_LOCK_PARTIAL
+ skip(1, "No partial locking support");
+#else
plan_tests(13);
agent = prepare_external_agent();
@@ -82,6 +85,7 @@
== SUCCESS);
tdb_close(tdb);
+#endif
return exit_status();
}
-------------- next part --------------
Index: tdb-1.3.0/common/transaction.c
===================================================================
--- tdb-1.3.0.orig/common/transaction.c
+++ tdb-1.3.0/common/transaction.c
@@ -554,7 +554,7 @@ static int transaction_sync(struct tdb_c
TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction: fsync failed\n"));
return -1;
}
-#ifdef HAVE_MMAP
+#if defined(HAVE_MMAP) && defined(HAVE_MSYNC)
if (tdb->map_ptr) {
tdb_off_t moffset = offset & ~(tdb->page_size-1);
if (msync(moffset + (char *)tdb->map_ptr,
Index: tdb-1.3.0/lib/replace/wscript
===================================================================
--- tdb-1.3.0.orig/lib/replace/wscript
+++ tdb-1.3.0/lib/replace/wscript
@@ -310,7 +310,7 @@ struct foo bar = { .y = 'X', .x = 1 };
conf.CHECK_FUNCS('if_nametoindex strerror_r')
conf.CHECK_FUNCS('getdirentries getdents syslog')
conf.CHECK_FUNCS('gai_strerror get_current_dir_name')
- conf.CHECK_FUNCS('timegm getifaddrs freeifaddrs mmap setgroups syscall setsid')
+ conf.CHECK_FUNCS('timegm getifaddrs freeifaddrs mmap msync setgroups syscall setsid')
conf.CHECK_FUNCS('getgrent_r getgrgid_r getgrnam_r getgrouplist getpagesize')
conf.CHECK_FUNCS('getpwent_r getpwnam_r getpwuid_r epoll_create')
Index: tdb-1.3.0/test/run-transaction-expand.c
===================================================================
--- tdb-1.3.0.orig/test/run-transaction-expand.c
+++ tdb-1.3.0/test/run-transaction-expand.c
@@ -9,7 +9,7 @@ static inline int fake_fsync(int fd)
}
#define fsync fake_fsync
-#ifdef MS_SYNC
+#ifdef HAVE_MSYNC
static inline int fake_msync(void *addr, size_t length, int flags)
{
sync_counts++;
Index: tdb-1.3.0/common/io.c
===================================================================
--- tdb-1.3.0.orig/common/io.c
+++ tdb-1.3.0/common/io.c
@@ -295,7 +295,7 @@ int tdb_munmap(struct tdb_context *tdb)
if (tdb->flags & TDB_INTERNAL)
return 0;
-#ifdef HAVE_MMAP
+#if defined(HAVE_MMAP) && defined(HAVE_MSYNC)
if (tdb->map_ptr) {
int ret;
@@ -308,6 +308,7 @@ int tdb_munmap(struct tdb_context *tdb)
return 0;
}
+#ifdef HAVE_MSYNC
/* If mmap isn't coherent, *everyone* must always mmap. */
static bool should_mmap(const struct tdb_context *tdb)
{
@@ -317,13 +318,14 @@ static bool should_mmap(const struct tdb
return !(tdb->flags & TDB_NOMMAP);
#endif
}
+#endif
int tdb_mmap(struct tdb_context *tdb)
{
if (tdb->flags & TDB_INTERNAL)
return 0;
-#ifdef HAVE_MMAP
+#if defined(HAVE_MMAP) && defined(HAVE_MSYNC)
if (should_mmap(tdb)) {
tdb->map_ptr = mmap(NULL, tdb->map_size,
PROT_READ|(tdb->read_only? 0:PROT_WRITE),
More information about the Pkg-samba-maint
mailing list