2 Unix SMB/CIFS implementation.
3 Implementation of reliable cleanup events
4 Copyright (C) Ralph Boehme 2016
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>.
21 #include "system/filesys.h"
22 #include "lib/tdb_wrap/tdb_wrap.h"
23 #include "lib/util/talloc_stack.h"
24 #include "lib/util/debug.h"
25 #include "source3/lib/cleanupdb.h"
26 #include "source3/lib/util_path.h"
36 static struct tdb_wrap
*cleanup_db(void)
38 static struct tdb_wrap
*db
;
40 int tdbflags
= TDB_INCOMPATIBLE_HASH
| TDB_CLEAR_IF_FIRST
|
47 db_path
= lock_path(talloc_tos(), "smbd_cleanupd.tdb");
48 if (db_path
== NULL
) {
52 db
= tdb_wrap_open(NULL
, db_path
, 0, tdbflags
,
53 O_CREAT
| O_RDWR
, 0644);
55 DBG_ERR("Failed to open smbd_cleanupd.tdb\n");
62 bool cleanupdb_store_child(const pid_t pid
, const bool unclean
)
65 struct cleanup_key key
= { .pid
= pid
};
66 struct cleanup_rec rec
= { .unclean
= unclean
};
67 TDB_DATA tdbkey
= { .dptr
= (uint8_t *)&key
, .dsize
= sizeof(key
) };
68 TDB_DATA tdbdata
= { .dptr
= (uint8_t *)&rec
, .dsize
= sizeof(rec
) };
76 result
= tdb_store(db
->tdb
, tdbkey
, tdbdata
, TDB_REPLACE
);
78 DBG_ERR("tdb_store failed for pid %d\n", (int)pid
);
85 bool cleanupdb_delete_child(const pid_t pid
)
88 struct cleanup_key key
= { .pid
= pid
};
89 TDB_DATA tdbkey
= { .dptr
= (uint8_t *)&key
, .dsize
= sizeof(key
) };
97 result
= tdb_delete(db
->tdb
, tdbkey
);
99 DBG_ERR("tdb_delete failed for pid %d\n", (int)pid
);
106 struct cleanup_read_state
{
107 int (*fn
)(const pid_t pid
, const bool cleanup
, void *private_data
);
111 static int cleanup_traverse_fn(struct tdb_context
*tdb
,
112 TDB_DATA key
, TDB_DATA value
,
115 struct cleanup_read_state
*state
=
116 (struct cleanup_read_state
*)private_data
;
117 struct cleanup_key ckey
;
118 struct cleanup_rec rec
;
121 if (key
.dsize
!= sizeof(struct cleanup_key
)) {
122 DBG_ERR("Found invalid key length %zu in cleanup.tdb\n",
126 memcpy(&ckey
, key
.dptr
, sizeof(struct cleanup_key
));
128 if (value
.dsize
!= sizeof(struct cleanup_rec
)) {
129 DBG_ERR("Found invalid value length %zu in cleanup.tdb\n",
133 memcpy(&rec
, value
.dptr
, sizeof(struct cleanup_rec
));
135 result
= state
->fn(ckey
.pid
, rec
.unclean
, state
->private_data
);
143 int cleanupdb_traverse_read(int (*fn
)(const pid_t pid
,
149 struct cleanup_read_state state
;
157 state
= (struct cleanup_read_state
) {
159 .private_data
= private_data
162 result
= tdb_traverse_read(db
->tdb
, cleanup_traverse_fn
, &state
);
164 DBG_ERR("tdb_traverse_read failed\n");