added a hook to reopen all tdb's after the server fork
authorAndrew Tridgell <tridge@samba.org>
Wed, 19 Sep 2001 05:43:15 +0000 (05:43 +0000)
committerAndrew Tridgell <tridge@samba.org>
Wed, 19 Sep 2001 05:43:15 +0000 (05:43 +0000)
this prevents the fd seek pointer problem
(This used to be commit f49518e497deeb46292456c3650769d50ec2a955)

source3/smbd/server.c
source3/tdb/tdb.c
source3/tdb/tdb.h

index 1dfff6cafa13d9fc6c24e75aa75f3dc7620b1804..27fd8e30154a08ac591dbe7d76ce6ec449d00e43 100644 (file)
@@ -309,6 +309,9 @@ max can be %d\n",
                                   done correctly in the process.  */
                                reset_globals_after_fork();
 
+                               /* tdb needs special fork handling */
+                               tdb_reopen_all();
+
                                return True; 
                        }
                        /* The parent doesn't need this socket */
index bb58950948971c71a758b02ee561f6bfa7483e4e..3a5b66bbc785b1332a267f13310a5ec862866d94 100644 (file)
@@ -611,31 +611,24 @@ static int expand_file(TDB_CONTEXT *tdb, tdb_off size, tdb_off addition)
 #else
        char b = 0;
 
-#ifdef HAVE_PWRITE
-       if (pwrite(tdb->fd,  &b, 1, (size+addition) - 1) != 1) {
-#else
        if (lseek(tdb->fd, (size+addition) - 1, SEEK_SET) != (size+addition) - 1 || 
            write(tdb->fd, &b, 1) != 1) {
-#endif
                TDB_LOG((tdb, 0, "expand_file to %d failed (%s)\n", 
                           size+addition, strerror(errno)));
                return -1;
        }
 #endif
 
-       /* now fill the file with something. This ensures that the file isn't sparse, which would be
-          very bad if we ran out of disk. This must be done with write, not via mmap */
+       /* now fill the file with something. This ensures that the
+          file isn't sparse, which would be very bad if we ran out of
+          disk. This must be done with write, not via mmap */
        memset(buf, 0x42, sizeof(buf));
        while (addition) {
                int n = addition>sizeof(buf)?sizeof(buf):addition;
-#ifdef HAVE_PWRITE
-               int ret = pwrite(tdb->fd, buf, n, size);
-#else
                int ret;
                if (lseek(tdb->fd, size, SEEK_SET) != size)
                        return -1;
                ret = write(tdb->fd, buf, n);
-#endif
                if (ret != n) {
                        TDB_LOG((tdb, 0, "expand_file write of %d failed (%s)\n", 
                                   n, strerror(errno)));
@@ -1369,6 +1362,7 @@ TDB_CONTEXT *tdb_open(char *name, int hash_size, int tdb_flags,
        tdb.map_ptr = NULL;
        tdb.lockedkeys = NULL;
        tdb.flags = tdb_flags;
+       tdb.open_flags = open_flags;
 
        if ((open_flags & O_ACCMODE) == O_WRONLY)
                goto fail;
@@ -1605,3 +1599,47 @@ void tdb_logging_function(TDB_CONTEXT *tdb, void (*fn)(TDB_CONTEXT *, int , cons
 {
        tdb->log_fn = fn;
 }
+
+
+/* reopen a tdb - this is used after a fork to ensure that we have an independent
+   seek pointer from our parent and to re-establish locks */
+int tdb_reopen(TDB_CONTEXT *tdb)
+{
+       struct stat st;
+
+       tdb_munmap(tdb);
+       close(tdb->fd);
+       tdb->fd = open(tdb->name, tdb->open_flags & ~(O_CREAT|O_TRUNC), 0);
+       if (tdb->fd == -1) {
+               TDB_LOG((tdb, 0, "tdb_reopen: open failed (%s)\n", strerror(errno)));
+               goto fail;
+       }
+       fstat(tdb->fd, &st);
+       if (st.st_ino != tdb->inode || st.st_dev != tdb->device) {
+               TDB_LOG((tdb, 0, "tdb_reopen: file dev/inode has changed!\n"));
+               goto fail;
+       }
+       tdb_mmap(tdb);
+       if (tdb_brlock(tdb, ACTIVE_LOCK, F_RDLCK, F_SETLKW, 0) == -1) {
+               TDB_LOG((tdb, 0, "tdb_reopen: failed to obtain active lock\n"));
+               goto fail;
+       }
+
+       return 0;
+
+fail:
+       tdb_close(tdb);
+       return -1;
+}
+
+/* reopen all tdb's */
+int tdb_reopen_all(void)
+{
+       TDB_CONTEXT *tdb;
+
+       for (tdb=tdbs; tdb; tdb = tdb->next) {
+               if (tdb_reopen(tdb) != 0) return -1;
+       }
+
+       return 0;
+}
index cc37825e7811fa539487062f5b5b919f781f12df..4efe263ee85ce53e9ccafe343e3edbc6694c49a6 100644 (file)
@@ -95,6 +95,7 @@ typedef struct tdb_context {
        dev_t device;   /* uniquely identifies this tdb */
        ino_t inode;    /* uniquely identifies this tdb */
        void (*log_fn)(struct tdb_context *tdb, int level, const char *, ...); /* logging function */
+       int open_flags; /* flags used in the open - needed by reopen */
 } TDB_CONTEXT;
 
 typedef int (*tdb_traverse_func)(TDB_CONTEXT *, TDB_DATA, TDB_DATA, void *);