LCOV - code coverage report
Current view: top level - source3/lib - cleanupdb.c (source / functions) Hit Total Coverage
Test: coverage report for master 2f515e9b Lines: 0 72 0.0 %
Date: 2024-04-21 15:09:00 Functions: 0 5 0.0 %

          Line data    Source code
       1             : /*
       2             :    Unix SMB/CIFS implementation.
       3             :    Implementation of reliable cleanup events
       4             :    Copyright (C) Ralph Boehme 2016
       5             : 
       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.
      10             : 
      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.
      15             : 
      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/>.
      18             : */
      19             : 
      20             : #include "replace.h"
      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"
      27             : 
      28             : struct cleanup_key {
      29             :         pid_t pid;
      30             : };
      31             : 
      32             : struct cleanup_rec {
      33             :         bool unclean;
      34             : };
      35             : 
      36           0 : static struct tdb_wrap *cleanup_db(void)
      37             : {
      38           0 :         static struct tdb_wrap *db;
      39           0 :         char *db_path = NULL;
      40           0 :         int tdbflags = TDB_INCOMPATIBLE_HASH | TDB_CLEAR_IF_FIRST |
      41             :                 TDB_MUTEX_LOCKING;
      42             : 
      43           0 :         if (db != NULL) {
      44           0 :                 return db;
      45             :         }
      46             : 
      47           0 :         db_path = lock_path(talloc_tos(), "smbd_cleanupd.tdb");
      48           0 :         if (db_path == NULL) {
      49           0 :                 return NULL;
      50             :         }
      51             : 
      52           0 :         db = tdb_wrap_open(NULL, db_path, 0, tdbflags,
      53             :                            O_CREAT | O_RDWR, 0644);
      54           0 :         if (db == NULL) {
      55           0 :                 DBG_ERR("Failed to open smbd_cleanupd.tdb\n");
      56             :         }
      57             : 
      58           0 :         TALLOC_FREE(db_path);
      59           0 :         return db;
      60             : }
      61             : 
      62           0 : bool cleanupdb_store_child(const pid_t pid, const bool unclean)
      63             : {
      64           0 :         struct tdb_wrap *db;
      65           0 :         struct cleanup_key key = { .pid = pid };
      66           0 :         struct cleanup_rec rec = { .unclean = unclean };
      67           0 :         TDB_DATA tdbkey = { .dptr = (uint8_t *)&key, .dsize = sizeof(key) };
      68           0 :         TDB_DATA tdbdata = { .dptr = (uint8_t *)&rec, .dsize = sizeof(rec) };
      69           0 :         int result;
      70             : 
      71           0 :         db = cleanup_db();
      72           0 :         if (db == NULL) {
      73           0 :                 return false;
      74             :         }
      75             : 
      76           0 :         result = tdb_store(db->tdb, tdbkey, tdbdata, TDB_REPLACE);
      77           0 :         if (result != 0) {
      78           0 :                 DBG_ERR("tdb_store failed for pid %d\n", (int)pid);
      79           0 :                 return false;
      80             :         }
      81             : 
      82           0 :         return true;
      83             : }
      84             : 
      85           0 : bool cleanupdb_delete_child(const pid_t pid)
      86             : {
      87           0 :         struct tdb_wrap *db;
      88           0 :         struct cleanup_key key = { .pid = pid };
      89           0 :         TDB_DATA tdbkey = { .dptr = (uint8_t *)&key, .dsize = sizeof(key) };
      90           0 :         int result;
      91             : 
      92           0 :         db = cleanup_db();
      93           0 :         if (db == NULL) {
      94           0 :                 return false;
      95             :         }
      96             : 
      97           0 :         result = tdb_delete(db->tdb, tdbkey);
      98           0 :         if (result != 0) {
      99           0 :                 DBG_ERR("tdb_delete failed for pid %d\n", (int)pid);
     100           0 :                 return false;
     101             :         }
     102             : 
     103           0 :         return true;
     104             : }
     105             : 
     106             : struct cleanup_read_state {
     107             :         int (*fn)(const pid_t pid, const bool cleanup, void *private_data);
     108             :         void *private_data;
     109             : };
     110             : 
     111           0 : static int cleanup_traverse_fn(struct tdb_context *tdb,
     112             :                                TDB_DATA key, TDB_DATA value,
     113             :                                void *private_data)
     114             : {
     115           0 :         struct cleanup_read_state *state =
     116             :                 (struct cleanup_read_state *)private_data;
     117           0 :         struct cleanup_key ckey;
     118           0 :         struct cleanup_rec rec;
     119           0 :         int result;
     120             : 
     121           0 :         if (key.dsize != sizeof(struct cleanup_key)) {
     122           0 :                 DBG_ERR("Found invalid key length %zu in cleanup.tdb\n",
     123             :                         key.dsize);
     124           0 :                 return -1;
     125             :         }
     126           0 :         memcpy(&ckey, key.dptr, sizeof(struct cleanup_key));
     127             : 
     128           0 :         if (value.dsize != sizeof(struct cleanup_rec)) {
     129           0 :                 DBG_ERR("Found invalid value length %zu in cleanup.tdb\n",
     130             :                         value.dsize);
     131           0 :                 return -1;
     132             :         }
     133           0 :         memcpy(&rec, value.dptr, sizeof(struct cleanup_rec));
     134             : 
     135           0 :         result = state->fn(ckey.pid, rec.unclean, state->private_data);
     136           0 :         if (result != 0) {
     137           0 :                 return -1;
     138             :         }
     139             : 
     140           0 :         return 0;
     141             : }
     142             : 
     143           0 : int cleanupdb_traverse_read(int (*fn)(const pid_t pid,
     144             :                                       const bool cleanup,
     145             :                                       void *private_data),
     146             :                             void *private_data)
     147             : {
     148           0 :         struct tdb_wrap *db;
     149           0 :         struct cleanup_read_state state;
     150           0 :         int result;
     151             : 
     152           0 :         db = cleanup_db();
     153           0 :         if (db == NULL) {
     154           0 :                 return -1;
     155             :         }
     156             : 
     157           0 :         state = (struct cleanup_read_state) {
     158             :                 .fn = fn,
     159             :                 .private_data = private_data
     160             :         };
     161             : 
     162           0 :         result = tdb_traverse_read(db->tdb, cleanup_traverse_fn, &state);
     163           0 :         if (result < 0) {
     164           0 :                 DBG_ERR("tdb_traverse_read failed\n");
     165           0 :                 return -1;
     166             :         }
     167             : 
     168           0 :         return result;
     169             : }

Generated by: LCOV version 1.14