tdb_chainlock_with_timeout_internal error
Jeremy Allison
jra at samba.org
Mon Nov 5 19:46:56 GMT 2007
On Wed, Jun 27, 2007 at 09:27:22AM -0400, Eddie Chen wrote:
> Has anyone seen this error before?
>
> Jun 26 11:00:55 bb02f79 smbd[4788]: [2007/06/26 11:00:55, 0] lib/util_tdb.c:tdb_chainlock_with_timeout_internal(84)
> Jun 26 11:00:55 bb02f79 smbd[4788]: tdb_chainlock_with_timeout_internal: alarm (10) timed out for key NADC20 in tdb /etc/samba/secrets.tdb
>
> Whenever this happens, the number of smbd processes increased exponentially, and given a few hours, it reached around 17000 smbd processes, and caused the system to hang.
>
> Someone please help.
Please try this patch (should apply cleanly
to 3.0.26).
Jeremy.
-------------- next part --------------
diff --git a/source/lib/replace/libreplace.m4 b/source/lib/replace/libreplace.m4
index e9b19b7..1fdd778 100644
--- a/source/lib/replace/libreplace.m4
+++ b/source/lib/replace/libreplace.m4
@@ -94,7 +94,7 @@ fi
AC_CHECK_HEADERS(sys/syslog.h syslog.h)
-AC_CHECK_HEADERS(sys/time.h time.h)
+AC_CHECK_HEADERS(sys/time.h time.h signal.h)
AC_CHECK_HEADERS(stdarg.h vararg.h)
AC_CHECK_HEADERS(sys/socket.h netinet/in.h netdb.h arpa/inet.h)
AC_CHECK_HEADERS(netinet/ip.h netinet/tcp.h netinet/in_systm.h netinet/in_ip.h)
diff --git a/source/lib/replace/replace.h b/source/lib/replace/replace.h
index b96356a..d5aaf1a 100644
--- a/source/lib/replace/replace.h
+++ b/source/lib/replace/replace.h
@@ -79,6 +79,20 @@
#include <stddef.h>
#endif
+#ifdef HAVE_SIGNAL_H
+#include <signal.h>
+#endif
+
+#if defined(HAVE_VOLATILE)
+#define VOLATILE volatile
+#else
+#define VOLATILE
+#endif
+
+#if !defined(HAVE_SIG_ATOMIC_T_TYPE)
+typedef int sig_atomic_t;
+#endif
+
/**
this is a warning hack. The idea is to use this everywhere that we
get the "discarding const" warning from gcc. That doesn't actually
diff --git a/source/lib/util_tdb.c b/source/lib/util_tdb.c
index a1b5bf5..48e34e0 100644
--- a/source/lib/util_tdb.c
+++ b/source/lib/util_tdb.c
@@ -68,6 +68,7 @@ static int tdb_chainlock_with_timeout_internal( TDB_CONTEXT *tdb, TDB_DATA key,
if (timeout) {
CatchSignal(SIGALRM, SIGNAL_CAST gotalarm_sig);
+ tdb_setalarm_sigptr(tdb, &gotalarm);
alarm(timeout);
}
@@ -78,6 +79,7 @@ static int tdb_chainlock_with_timeout_internal( TDB_CONTEXT *tdb, TDB_DATA key,
if (timeout) {
alarm(0);
+ tdb_setalarm_sigptr(tdb, NULL);
CatchSignal(SIGALRM, SIGNAL_CAST SIG_IGN);
if (gotalarm) {
DEBUG(0,("tdb_chainlock_with_timeout_internal: alarm (%u) timed out for key %s in tdb %s\n",
diff --git a/source/tdb/common/lock.c b/source/tdb/common/lock.c
index 8a96437..25e975f 100644
--- a/source/tdb/common/lock.c
+++ b/source/tdb/common/lock.c
@@ -28,6 +28,11 @@
#include "tdb_private.h"
+void tdb_setalarm_sigptr(struct tdb_context *tdb, VOLATILE sig_atomic_t *ptr)
+{
+ tdb->interrupt_sig_ptr = ptr;
+}
+
/* a byte range locking function - return 0 on success
this functions locks/unlocks 1 byte at the specified offset.
@@ -59,6 +64,13 @@ int tdb_brlock(struct tdb_context *tdb, tdb_off_t offset,
do {
ret = fcntl(tdb->fd,lck_type,&fl);
+
+ /* Check for a sigalarm break. */
+ if (ret == -1 && errno == EINTR &&
+ tdb->interrupt_sig_ptr &&
+ *tdb->interrupt_sig_ptr) {
+ break;
+ }
} while (ret == -1 && errno == EINTR);
if (ret == -1) {
diff --git a/source/tdb/common/tdb_private.h b/source/tdb/common/tdb_private.h
index 10bc6da..ade5164 100644
--- a/source/tdb/common/tdb_private.h
+++ b/source/tdb/common/tdb_private.h
@@ -170,6 +170,7 @@ struct tdb_context {
struct tdb_transaction *transaction;
int page_size;
int max_dead_records;
+ VOLATILE sig_atomic_t *interrupt_sig_ptr;
};
diff --git a/source/tdb/include/tdb.h b/source/tdb/include/tdb.h
index 51bf709..363005b 100644
--- a/source/tdb/include/tdb.h
+++ b/source/tdb/include/tdb.h
@@ -138,6 +138,8 @@ int tdb_chainunlock(struct tdb_context *tdb, TDB_DATA key);
int tdb_chainlock_read(struct tdb_context *tdb, TDB_DATA key);
int tdb_chainunlock_read(struct tdb_context *tdb, TDB_DATA key);
+void tdb_setalarm_sigptr(struct tdb_context *tdb, VOLATILE sig_atomic_t *sigptr);
+
/* Debug functions. Not used in production. */
void tdb_dump_all(struct tdb_context *tdb);
int tdb_printfreelist(struct tdb_context *tdb);
More information about the samba-technical
mailing list