Author: tridge Date: 2004-10-29 07:29:26 +0000 (Fri, 29 Oct 2004) New Revision: 3357
WebSVN: http://websvn.samba.org/cgi-bin/viewcvs.cgi?view=rev&root=samba&rev=3357 Log: 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. Modified: branches/SAMBA_4_0/source/lib/util.c branches/SAMBA_4_0/source/libcli/unexpected.c branches/SAMBA_4_0/source/ntvfs/common/brlock.c branches/SAMBA_4_0/source/ntvfs/common/opendb.c branches/SAMBA_4_0/source/smbd/rewrite.c branches/SAMBA_4_0/source/smbd/service.c Changeset: Modified: branches/SAMBA_4_0/source/lib/util.c =================================================================== --- branches/SAMBA_4_0/source/lib/util.c 2004-10-29 07:00:14 UTC (rev 3356) +++ branches/SAMBA_4_0/source/lib/util.c 2004-10-29 07:29:26 UTC (rev 3357) @@ -705,16 +705,19 @@ 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; } Modified: branches/SAMBA_4_0/source/libcli/unexpected.c =================================================================== --- branches/SAMBA_4_0/source/libcli/unexpected.c 2004-10-29 07:00:14 UTC (rev 3356) +++ branches/SAMBA_4_0/source/libcli/unexpected.c 2004-10-29 07:29:26 UTC (rev 3357) @@ -50,7 +50,7 @@ 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) { Modified: branches/SAMBA_4_0/source/ntvfs/common/brlock.c =================================================================== --- branches/SAMBA_4_0/source/ntvfs/common/brlock.c 2004-10-29 07:00:14 UTC (rev 3356) +++ branches/SAMBA_4_0/source/ntvfs/common/brlock.c 2004-10-29 07:29:26 UTC (rev 3357) @@ -84,7 +84,7 @@ 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) { Modified: branches/SAMBA_4_0/source/ntvfs/common/opendb.c =================================================================== --- branches/SAMBA_4_0/source/ntvfs/common/opendb.c 2004-10-29 07:00:14 UTC (rev 3356) +++ branches/SAMBA_4_0/source/ntvfs/common/opendb.c 2004-10-29 07:29:26 UTC (rev 3357) @@ -88,7 +88,7 @@ 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) { Modified: branches/SAMBA_4_0/source/smbd/rewrite.c =================================================================== --- branches/SAMBA_4_0/source/smbd/rewrite.c 2004-10-29 07:00:14 UTC (rev 3356) +++ branches/SAMBA_4_0/source/smbd/rewrite.c 2004-10-29 07:29:26 UTC (rev 3357) @@ -19,18 +19,12 @@ { 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 @@ 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) Modified: branches/SAMBA_4_0/source/smbd/service.c =================================================================== --- branches/SAMBA_4_0/source/smbd/service.c 2004-10-29 07:00:14 UTC (rev 3356) +++ branches/SAMBA_4_0/source/smbd/service.c 2004-10-29 07:29:26 UTC (rev 3357) @@ -349,3 +349,33 @@ } } } + + +/* + 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); + } +}