summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Tridgell <tridge@samba.org>2004-10-29 07:29:26 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 13:05:00 -0500
commitdbf03959244c392073281c10badd2095397ad2f2 (patch)
tree427e9fb6143cd2a2b66b6804a8c5339272115e47
parent0caeda53d37740d18b38e6d37d0ecef8c6336820 (diff)
downloadsamba-dbf03959244c392073281c10badd2095397ad2f2.tar.gz
samba-dbf03959244c392073281c10badd2095397ad2f2.tar.bz2
samba-dbf03959244c392073281c10badd2095397ad2f2.zip
r3357: removed the need to use TDB_CLEAR_IF_FIRST in Samba4.
We found a few months ago that TDB_CLEAR_IF_FIRST is extremely inefficient for large numbers of connections, due to a fundamental limitation in the way posix byte range locking is implemented. Rather than the nasty workaround we had for Samba3, we now have a single "cleanup tmp files" function that runs when smbd starts. That deletes the tmp tdbs, so TDB_CLEAR_IF_FIRST is not needed at all. (This used to be commit ffa285bc783c775a2d53a58fb691ca339e6c76ae)
-rw-r--r--source4/lib/util.c15
-rw-r--r--source4/libcli/unexpected.c2
-rw-r--r--source4/ntvfs/common/brlock.c2
-rw-r--r--source4/ntvfs/common/opendb.c2
-rw-r--r--source4/smbd/rewrite.c16
-rw-r--r--source4/smbd/service.c30
6 files changed, 46 insertions, 21 deletions
diff --git a/source4/lib/util.c b/source4/lib/util.c
index d7c5661f7d..8b27bf070c 100644
--- a/source4/lib/util.c
+++ b/source4/lib/util.c
@@ -705,15 +705,18 @@ char *name_to_fqdn(TALLOC_CTX *mem_ctx, const char *name)
char *lock_path(TALLOC_CTX* mem_ctx, const char *name)
{
- char *fname;
+ char *fname, *dname;
- fname = talloc_strdup(mem_ctx, lp_lockdir());
- trim_string(fname,"","/");
+ dname = talloc_strdup(mem_ctx, lp_lockdir());
+ trim_string(dname,"","/");
- if (!directory_exist(fname,NULL))
- mkdir(fname,0755);
+ if (!directory_exist(dname,NULL)) {
+ mkdir(dname,0755);
+ }
- fname = talloc_asprintf(mem_ctx, "%s/%s", fname, name);
+ fname = talloc_asprintf(mem_ctx, "%s/%s", dname, name);
+
+ talloc_free(dname);
return fname;
}
diff --git a/source4/libcli/unexpected.c b/source4/libcli/unexpected.c
index e109c9d5bf..19a02bdeb8 100644
--- a/source4/libcli/unexpected.c
+++ b/source4/libcli/unexpected.c
@@ -50,7 +50,7 @@ void unexpected_packet(struct packet_struct *p)
mem_ctx = talloc_init("receive_unexpected");
if (!mem_ctx) return;
tdbd = tdb_wrap_open(NULL, lock_path(mem_ctx, "unexpected.tdb"), 0,
- TDB_CLEAR_IF_FIRST|TDB_DEFAULT,
+ TDB_DEFAULT,
O_RDWR | O_CREAT, 0644);
talloc_destroy(mem_ctx);
if (!tdbd) {
diff --git a/source4/ntvfs/common/brlock.c b/source4/ntvfs/common/brlock.c
index b43f0705a5..0f6af3e971 100644
--- a/source4/ntvfs/common/brlock.c
+++ b/source4/ntvfs/common/brlock.c
@@ -84,7 +84,7 @@ struct brl_context *brl_init(TALLOC_CTX *mem_ctx, servid_t server, uint16_t tid,
path = lock_path(brl, "brlock.tdb");
brl->w = tdb_wrap_open(brl, path, 0,
- TDB_DEFAULT|TDB_CLEAR_IF_FIRST,
+ TDB_DEFAULT,
O_RDWR|O_CREAT, 0600);
talloc_free(path);
if (brl->w == NULL) {
diff --git a/source4/ntvfs/common/opendb.c b/source4/ntvfs/common/opendb.c
index d8ca4c999d..a66549b764 100644
--- a/source4/ntvfs/common/opendb.c
+++ b/source4/ntvfs/common/opendb.c
@@ -88,7 +88,7 @@ struct odb_context *odb_init(TALLOC_CTX *mem_ctx, servid_t server, uint16_t tid,
path = lock_path(odb, "openfiles.tdb");
odb->w = tdb_wrap_open(odb, path, 0,
- TDB_DEFAULT|TDB_CLEAR_IF_FIRST,
+ TDB_DEFAULT,
O_RDWR|O_CREAT, 0600);
talloc_free(path);
if (odb->w == NULL) {
diff --git a/source4/smbd/rewrite.c b/source4/smbd/rewrite.c
index 035532a01f..ff311c6680 100644
--- a/source4/smbd/rewrite.c
+++ b/source4/smbd/rewrite.c
@@ -19,18 +19,12 @@ BOOL share_access_check(struct smbsrv_request *req, struct smbsrv_tcon *tcon, in
{ return True; }
/*
- * initialize an smb process
+ * initialize an smb process. Guaranteed to be called only once per
+ * smbd instance (so it can assume it is starting from scratch, and
+ * delete temporary files etc)
*/
void smbd_process_init(void)
{
- TALLOC_CTX *mem_ctx;
-
- mem_ctx = talloc_init("smbd_process_init talloc");
- if (!mem_ctx) {
- DEBUG(0,("smbd_process_init: ERROR: No memory\n"));
- exit(1);
- }
-
/* possibly reload the services file. */
reload_services(NULL, True);
@@ -39,9 +33,7 @@ void smbd_process_init(void)
DEBUG(2,("Changed root to %s\n", lp_rootdir()));
}
- /* Start old-style secrets subsystem */
-
- talloc_destroy(mem_ctx);
+ service_cleanup_tmp_files();
}
void init_subsystems(void)
diff --git a/source4/smbd/service.c b/source4/smbd/service.c
index ca5f5e7531..33c0d5fcbd 100644
--- a/source4/smbd/service.c
+++ b/source4/smbd/service.c
@@ -349,3 +349,33 @@ void service_close_listening_sockets(struct server_context *srv_ctx)
}
}
}
+
+
+/*
+ cleanup temporary files. This is the new alternative to
+ TDB_CLEAR_IF_FIRST. Unfortunately TDB_CLEAR_IF_FIRST is not
+ efficient on unix systems due to the lack of scaling of the byte
+ range locking system. So instead of putting the burden on tdb to
+ cleanup tmp files, this function deletes them. You need to expand
+ the list here as appropriate.
+*/
+void service_cleanup_tmp_files(void)
+{
+ const char *list[] = {
+ "openfiles.tdb",
+ "brlock.tdb",
+ "unexpected.tdb"};
+ int i;
+ for (i=0;i<ARRAY_SIZE(list);i++) {
+ char *path = lock_path(NULL, list[i]);
+ int ret;
+ ret = unlink(path);
+ if (ret == -1 &&
+ errno != ENOENT &&
+ errno != ENOTDIR) {
+ DEBUG(0,("Failed to cleanup '%s'\n", path));
+ smb_panic("unable to cleanup temporary files\n");
+ }
+ talloc_free(path);
+ }
+}