LCOV - code coverage report
Current view: top level - source3/lib - cleanupdb.c (source / functions) Hit Total Coverage
Test: coverage report for abartlet/fix-coverage dd10fb34 Lines: 21 61 34.4 %
Date: 2021-09-23 10:06:22 Functions: 2 5 40.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 "cleanupdb.h"
      21             : 
      22             : struct cleanup_key {
      23             :         pid_t pid;
      24             : };
      25             : 
      26             : struct cleanup_rec {
      27             :         bool unclean;
      28             : };
      29             : 
      30       23494 : static struct tdb_wrap *cleanup_db(void)
      31             : {
      32             :         static struct tdb_wrap *db;
      33       23494 :         char *db_path = NULL;
      34       23494 :         int tdbflags = TDB_INCOMPATIBLE_HASH | TDB_CLEAR_IF_FIRST |
      35             :                 TDB_MUTEX_LOCKING;
      36             : 
      37       23494 :         if (db != NULL) {
      38       22919 :                 return db;
      39             :         }
      40             : 
      41          51 :         db_path = lock_path(talloc_tos(), "smbd_cleanupd.tdb");
      42          51 :         if (db_path == NULL) {
      43           0 :                 return NULL;
      44             :         }
      45             : 
      46          51 :         db = tdb_wrap_open(NULL, db_path, 0, tdbflags,
      47             :                            O_CREAT | O_RDWR, 0644);
      48          51 :         if (db == NULL) {
      49           0 :                 DBG_ERR("Failed to open smbd_cleanupd.tdb\n");
      50             :         }
      51             : 
      52          51 :         TALLOC_FREE(db_path);
      53          51 :         return db;
      54             : }
      55             : 
      56       23494 : bool cleanupdb_store_child(const pid_t pid, const bool unclean)
      57             : {
      58             :         struct tdb_wrap *db;
      59       23494 :         struct cleanup_key key = { .pid = pid };
      60       23494 :         struct cleanup_rec rec = { .unclean = unclean };
      61       23494 :         TDB_DATA tdbkey = { .dptr = (uint8_t *)&key, .dsize = sizeof(key) };
      62       23494 :         TDB_DATA tdbdata = { .dptr = (uint8_t *)&rec, .dsize = sizeof(rec) };
      63             :         int result;
      64             : 
      65       23494 :         db = cleanup_db();
      66       23494 :         if (db == NULL) {
      67           0 :                 return false;
      68             :         }
      69             : 
      70       23494 :         result = tdb_store(db->tdb, tdbkey, tdbdata, TDB_REPLACE);
      71       23494 :         if (result != 0) {
      72           0 :                 DBG_ERR("tdb_store failed for pid %d\n", (int)pid);
      73           0 :                 return false;
      74             :         }
      75             : 
      76       22968 :         return true;
      77             : }
      78             : 
      79           0 : bool cleanupdb_delete_child(const pid_t pid)
      80             : {
      81             :         struct tdb_wrap *db;
      82           0 :         struct cleanup_key key = { .pid = pid };
      83           0 :         TDB_DATA tdbkey = { .dptr = (uint8_t *)&key, .dsize = sizeof(key) };
      84             :         int result;
      85             : 
      86           0 :         db = cleanup_db();
      87           0 :         if (db == NULL) {
      88           0 :                 return false;
      89             :         }
      90             : 
      91           0 :         result = tdb_delete(db->tdb, tdbkey);
      92           0 :         if (result != 0) {
      93           0 :                 DBG_ERR("tdb_delete failed for pid %d\n", (int)pid);
      94           0 :                 return false;
      95             :         }
      96             : 
      97           0 :         return true;
      98             : }
      99             : 
     100             : struct cleanup_read_state {
     101             :         int (*fn)(const pid_t pid, const bool cleanup, void *private_data);
     102             :         void *private_data;
     103             : };
     104             : 
     105           0 : static int cleanup_traverse_fn(struct tdb_context *tdb,
     106             :                                TDB_DATA key, TDB_DATA value,
     107             :                                void *private_data)
     108             : {
     109           0 :         struct cleanup_read_state *state =
     110             :                 (struct cleanup_read_state *)private_data;
     111             :         struct cleanup_key ckey;
     112             :         struct cleanup_rec rec;
     113             :         int result;
     114             : 
     115           0 :         if (key.dsize != sizeof(struct cleanup_key)) {
     116           0 :                 DBG_ERR("Found invalid key length %zu in cleanup.tdb\n",
     117             :                         key.dsize);
     118           0 :                 return -1;
     119             :         }
     120           0 :         memcpy(&ckey, key.dptr, sizeof(struct cleanup_key));
     121             : 
     122           0 :         if (value.dsize != sizeof(struct cleanup_rec)) {
     123           0 :                 DBG_ERR("Found invalid value length %zu in cleanup.tdb\n",
     124             :                         value.dsize);
     125           0 :                 return -1;
     126             :         }
     127           0 :         memcpy(&rec, value.dptr, sizeof(struct cleanup_rec));
     128             : 
     129           0 :         result = state->fn(ckey.pid, rec.unclean, state->private_data);
     130           0 :         if (result != 0) {
     131           0 :                 return -1;
     132             :         }
     133             : 
     134           0 :         return 0;
     135             : }
     136             : 
     137           0 : int cleanupdb_traverse_read(int (*fn)(const pid_t pid,
     138             :                                       const bool cleanup,
     139             :                                       void *private_data),
     140             :                             void *private_data)
     141             : {
     142             :         struct tdb_wrap *db;
     143             :         struct cleanup_read_state state;
     144             :         int result;
     145             : 
     146           0 :         db = cleanup_db();
     147           0 :         if (db == NULL) {
     148           0 :                 return -1;
     149             :         }
     150             : 
     151           0 :         state = (struct cleanup_read_state) {
     152             :                 .fn = fn,
     153             :                 .private_data = private_data
     154             :         };
     155             : 
     156           0 :         result = tdb_traverse_read(db->tdb, cleanup_traverse_fn, &state);
     157           0 :         if (result < 0) {
     158           0 :                 DBG_ERR("tdb_traverse_read failed\n");
     159           0 :                 return -1;
     160             :         }
     161             : 
     162           0 :         return result;
     163             : }

Generated by: LCOV version 1.13