diff options
author | Ralph Boehme <slow@samba.org> | 2016-07-21 16:53:15 +0200 |
---|---|---|
committer | Stefan Metzmacher <metze@samba.org> | 2016-07-28 05:00:18 +0200 |
commit | 9c1cd31c0f931b99d79638fbef5e46f01788f3ca (patch) | |
tree | 6bfdb9877c112bcf326db94c56d551e7e4100b85 /source3 | |
parent | ed81e51cc1633cecfef05b84c0595418db8a384b (diff) | |
download | samba-9c1cd31c0f931b99d79638fbef5e46f01788f3ca.tar.gz |
s3/lib: add smbd_cleanupd.tdb
This will be used between cleanupd and smbd for passing information
about exitted smbd childs.
Bug: https://bugzilla.samba.org/show_bug.cgi?id=12022
Signed-off-by: Ralph Boehme <slow@samba.org>
Reviewed-by: Volker Lendecke <vl@samba.org>
Diffstat (limited to 'source3')
-rw-r--r-- | source3/lib/cleanupdb.c | 170 | ||||
-rw-r--r-- | source3/lib/cleanupdb.h | 30 | ||||
-rwxr-xr-x | source3/wscript_build | 3 |
3 files changed, 202 insertions, 1 deletions
diff --git a/source3/lib/cleanupdb.c b/source3/lib/cleanupdb.c new file mode 100644 index 00000000000..8832abe27d6 --- /dev/null +++ b/source3/lib/cleanupdb.c @@ -0,0 +1,170 @@ +/* + Unix SMB/CIFS implementation. + Implementation of reliable cleanup events + Copyright (C) Ralph Boehme 2016 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +#include "cleanupdb.h" + +struct cleanup_key { + pid_t pid; +}; + +struct cleanup_rec { + /* Storing the pid here as well saves a few lines of code */ + pid_t pid; + bool unclean; +}; + +static struct tdb_wrap *cleanup_db(void) +{ + static struct tdb_wrap *db; + char *db_path = NULL; + int tdbflags = TDB_INCOMPATIBLE_HASH | TDB_CLEAR_IF_FIRST | + TDB_MUTEX_LOCKING; + + if (db != NULL) { + return db; + } + + db_path = lock_path("smbd_cleanupd.tdb"); + if (db_path == NULL) { + return NULL; + } + + db = tdb_wrap_open(NULL, db_path, 0, tdbflags, + O_CREAT | O_RDWR, 0644); + if (db == NULL) { + DBG_ERR("Failed to open smbd_cleanupd.tdb\n"); + } + + TALLOC_FREE(db_path); + return db; +} + +bool cleanupdb_store_child(const pid_t pid, const bool unclean) +{ + struct tdb_wrap *db; + struct cleanup_key key = { .pid = pid }; + struct cleanup_rec rec = { .pid = pid, .unclean = unclean }; + TDB_DATA tdbkey = { .dptr = (uint8_t *)&key, .dsize = sizeof(key) }; + TDB_DATA tdbdata = { .dptr = (uint8_t *)&key, .dsize = sizeof(rec) }; + int result; + + db = cleanup_db(); + if (db == NULL) { + return false; + } + + result = tdb_store(db->tdb, tdbkey, tdbdata, TDB_REPLACE); + if (result != 0) { + DBG_ERR("tdb_store failed for pid %d\n", (int)pid); + return false; + } + + return true; +} + +bool cleanupdb_delete_child(const pid_t pid) +{ + struct tdb_wrap *db; + struct cleanup_key key = { .pid = pid }; + TDB_DATA tdbkey = { .dptr = (uint8_t *)&key, .dsize = sizeof(key) }; + int result; + + db = cleanup_db(); + if (db == NULL) { + return false; + } + + result = tdb_delete(db->tdb, tdbkey); + if (result != 0) { + DBG_ERR("tdb_delete failed for pid %d\n", (int)pid); + return false; + } + + return true; +} + +static bool cleanup_rec_parse(TDB_DATA tdbdata, + struct cleanup_rec *cleanup_rec) +{ + if (tdbdata.dsize != sizeof(struct cleanup_rec)) { + DBG_ERR("Found invalid value length %d in cleanup.tdb\n", + (int)tdbdata.dsize); + return false; + } + + memcpy(cleanup_rec, tdbdata.dptr, sizeof(struct cleanup_rec)); + + return true; +} + +struct cleanup_read_state { + int (*fn)(const pid_t pid, const bool cleanup, void *private_data); + void *private_data; +}; + +static int cleanup_traverse_fn(struct tdb_context *tdb, + TDB_DATA key, TDB_DATA value, + void *private_data) +{ + struct cleanup_read_state *state = + (struct cleanup_read_state *)private_data; + struct cleanup_rec rec; + bool ok; + int result; + + ok = cleanup_rec_parse(value, &rec); + if (!ok) { + return -1; + } + + result = state->fn(rec.pid, rec.unclean, state->private_data); + if (result != 0) { + return -1; + } + + return 0; +} + +int cleanupdb_traverse_read(int (*fn)(const pid_t pid, + const bool cleanup, + void *private_data), + void *private_data) +{ + struct tdb_wrap *db; + struct cleanup_read_state state; + int result; + + db = cleanup_db(); + if (db == NULL) { + return -1; + } + + state = (struct cleanup_read_state) { + .fn = fn, + .private_data = private_data + }; + + result = tdb_traverse_read(db->tdb, cleanup_traverse_fn, &state); + if (result < 0) { + DBG_ERR("tdb_traverse_read failed\n"); + return -1; + } + + return result; +} diff --git a/source3/lib/cleanupdb.h b/source3/lib/cleanupdb.h new file mode 100644 index 00000000000..71dd6955168 --- /dev/null +++ b/source3/lib/cleanupdb.h @@ -0,0 +1,30 @@ +/* + Unix SMB/CIFS implementation. + Implementation of reliable cleanup events + Copyright (C) Ralph Boehme 2016 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +#include "includes.h" +#include "system/filesys.h" +#include "util_tdb.h" +#include "lib/tdb_wrap/tdb_wrap.h" + +bool cleanupdb_store_child(const pid_t pid, const bool unclean); +bool cleanupdb_delete_child(const pid_t pid); +int cleanupdb_traverse_read(int (*fn)(const pid_t pid, + const bool cleanup, + void *private_data), + void *private_data); diff --git a/source3/wscript_build b/source3/wscript_build index b9a2ee60275..edf921c05df 100755 --- a/source3/wscript_build +++ b/source3/wscript_build @@ -345,7 +345,8 @@ bld.SAMBA3_SUBSYSTEM('samba3core', lib/tevent_wait.c lib/idmap_cache.c lib/util_ea.c - lib/background.c''', + lib/background.c + lib/cleanupdb.c''', deps=''' samba3util LIBTSOCKET |