[SCM] CTDB repository - branch master updated - ctdb-2.0-59-g746168d

Amitay Isaacs amitay at samba.org
Tue Jan 8 20:43:10 MST 2013


The branch, master has been updated
       via  746168df2e691058e601016110fae818c6a265c3 (commit)
       via  45d439a1ab093b420c27b1502ef109021833c7af (commit)
       via  efaac27a9ed52ed0f436c7e194013fd06e8b02b3 (commit)
       via  ca6e7eccc90f2869c220231666bf284798342bce (commit)
       via  d23adec89b69e7c6f96c8e1417ef4ca4c9edc57e (commit)
       via  9a70a4d23d00f6cb996c061ba3dfb7c47b4f6a4f (commit)
      from  735ec99b99c7bb579851ce8293011aaf1dcc552a (commit)

http://gitweb.samba.org/?p=ctdb.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit 746168df2e691058e601016110fae818c6a265c3
Author: Amitay Isaacs <amitay at gmail.com>
Date:   Tue Dec 4 15:05:44 2012 +1100

    daemon: On shutdown, destroy timed events that check if recoverd is active
    
    When CTDB is shutting down, recovery daemon is stopped, but the
    event that checks if recovery daemon is still alive is not destroyed.
    So recovery master is restarted during shutdown if CTDB daemon takes
    longer to shutdown.
    
    There are two processes that check if recovery daemon is working.
    
    1. ctdb_check_recd() - which checks every 30 seconds if the recovery
       daemon process exists.
    
    2. ctdb_recd_ping_timeout() - which is triggered when recovery daemon
       fails to ping CTDB daemon.
    
    Both the events are periodic and need to be destroyed when shutting down.
    
    Signed-off-by: Amitay Isaacs <amitay at gmail.com>

commit 45d439a1ab093b420c27b1502ef109021833c7af
Author: Amitay Isaacs <amitay at gmail.com>
Date:   Tue Dec 18 12:52:39 2012 +1100

    tests: Add a test for recovery of persistent databases
    
    Ensure that RSN based recovery and __db_sequence_number__ based recovery
    methods for persistent databases work correctly.  They should not cause
    corruption of the database.
    
    Signed-off-by: Amitay Isaacs <amitay at gmail.com>

commit efaac27a9ed52ed0f436c7e194013fd06e8b02b3
Author: Amitay Isaacs <amitay at gmail.com>
Date:   Wed Dec 19 15:14:42 2012 +1100

    tools/ctdb: Add setdbseqnum command to set __db_sequence_number__
    
    Signed-off-by: Amitay Isaacs <amitay at gmail.com>

commit ca6e7eccc90f2869c220231666bf284798342bce
Author: Amitay Isaacs <amitay at gmail.com>
Date:   Wed Dec 19 14:43:26 2012 +1100

    tools/ctdb: Re-factor code to check if db exists given name or id
    
    Most of the commands related to database operations can now use the
    common code (db_exists()) to refer to database with either name or id.
    
    In addition to return db_id for db_name, the function returns all the
    flags set for the database.
    
    Signed-off-by: Amitay Isaacs <amitay at gmail.com>

commit d23adec89b69e7c6f96c8e1417ef4ca4c9edc57e
Author: Amitay Isaacs <amitay at gmail.com>
Date:   Mon Dec 17 14:46:14 2012 +1100

    tools/ctdb: Add pdelete command to delete a record from persistent database
    
    Signed-off-by: Amitay Isaacs <amitay at gmail.com>

commit 9a70a4d23d00f6cb996c061ba3dfb7c47b4f6a4f
Author: Amitay Isaacs <amitay at gmail.com>
Date:   Tue Dec 4 14:58:30 2012 +1100

    daemon: Update the comment and remove redundant check in ctdb_start_transport()
    
    ctdb_start_transport() is called just before "setup" event, when CTDB
    is ready to process the requests. "startup" event happens much later
    after a successful recovery.
    
    Transport method ctdb->methods is successfully initialized before
    ctdb_start_transport() is called.  No need to check again.
    
    Signed-off-by: Amitay Isaacs <amitay at gmail.com>

-----------------------------------------------------------------------

Summary of changes:
 include/ctdb_private.h               |    1 +
 server/ctdb_daemon.c                 |    7 +-
 server/ctdb_recover.c                |    8 +-
 server/ctdb_recoverd.c               |   13 +-
 tests/simple/76_ctdb_pdb_recovery.sh |  119 +++++++++
 tools/ctdb.c                         |  469 +++++++++++++++++++---------------
 6 files changed, 395 insertions(+), 222 deletions(-)
 create mode 100755 tests/simple/76_ctdb_pdb_recovery.sh


Changeset truncated at 500 lines:

diff --git a/include/ctdb_private.h b/include/ctdb_private.h
index 152af64..fb54195 100644
--- a/include/ctdb_private.h
+++ b/include/ctdb_private.h
@@ -508,6 +508,7 @@ struct ctdb_context {
 	bool valgrinding;
 	uint32_t event_script_timeouts; /* counting how many consecutive times an eventscript has timedout */
 	uint32_t *recd_ping_count;
+	TALLOC_CTX *recd_ctx; /* a context used to track recoverd monitoring events */
 	TALLOC_CTX *release_ips_ctx; /* a context used to automatically drop all IPs if we fail to recover the node */
 
 	TALLOC_CTX *event_script_ctx;
diff --git a/server/ctdb_daemon.c b/server/ctdb_daemon.c
index 623e623..fdfd5de 100644
--- a/server/ctdb_daemon.c
+++ b/server/ctdb_daemon.c
@@ -70,14 +70,9 @@ static void ctdb_start_time_tickd(struct ctdb_context *ctdb)
 }
 
 
-/* called when the "startup" event script has finished */
+/* called when CTDB is ready to process requests */
 static void ctdb_start_transport(struct ctdb_context *ctdb)
 {
-	if (ctdb->methods == NULL) {
-		DEBUG(DEBUG_ALERT,(__location__ " startup event finished but transport is DOWN.\n"));
-		ctdb_fatal(ctdb, "transport is not initialized but startup completed");
-	}
-
 	/* start the transport running */
 	if (ctdb->methods->start(ctdb) != 0) {
 		DEBUG(DEBUG_ALERT,("transport failed to start!\n"));
diff --git a/server/ctdb_recover.c b/server/ctdb_recover.c
index 719352a..32c87bb 100644
--- a/server/ctdb_recover.c
+++ b/server/ctdb_recover.c
@@ -1162,6 +1162,10 @@ int32_t ctdb_control_get_capabilities(struct ctdb_context *ctdb, TDB_DATA *outda
 	return 0;	
 }
 
+/* The recovery daemon will ping us at regular intervals.
+   If we havent been pinged for a while we assume the recovery
+   daemon is inoperable and we restart.
+*/
 static void ctdb_recd_ping_timeout(struct event_context *ev, struct timed_event *te, struct timeval t, void *p)
 {
 	struct ctdb_context *ctdb = talloc_get_type(p, struct ctdb_context);
@@ -1183,10 +1187,6 @@ static void ctdb_recd_ping_timeout(struct event_context *ev, struct timed_event
 	ctdb_start_recoverd(ctdb);
 }
 
-/* The recovery daemon will ping us at regular intervals.
-   If we havent been pinged for a while we assume the recovery
-   daemon is inoperable and we shut down.
-*/
 int32_t ctdb_control_recd_ping(struct ctdb_context *ctdb)
 {
 	talloc_free(ctdb->recd_ping_count);
diff --git a/server/ctdb_recoverd.c b/server/ctdb_recoverd.c
index d50e84e..5f83044 100644
--- a/server/ctdb_recoverd.c
+++ b/server/ctdb_recoverd.c
@@ -4018,10 +4018,14 @@ int ctdb_start_recoverd(struct ctdb_context *ctdb)
 	if (ctdb->recoverd_pid == -1) {
 		return -1;
 	}
-	
+
 	if (ctdb->recoverd_pid != 0) {
+		talloc_free(ctdb->recd_ctx);
+		ctdb->recd_ctx = talloc_new(ctdb);
+		CTDB_NO_MEMORY(ctdb, ctdb->recd_ctx);
+
 		close(fd[0]);
-		event_add_timed(ctdb->ev, ctdb, 
+		event_add_timed(ctdb->ev, ctdb->recd_ctx,
 				timeval_current_ofs(30, 0),
 				ctdb_check_recd, ctdb);
 		return 0;
@@ -4039,7 +4043,7 @@ int ctdb_start_recoverd(struct ctdb_context *ctdb)
 	DEBUG(DEBUG_DEBUG, (__location__ " Created PIPE FD:%d to recovery daemon\n", fd[0]));
 
 	fde = event_add_fd(ctdb->ev, ctdb, fd[0], EVENT_FD_READ,
-		     ctdb_recoverd_parent, &fd[0]);	
+		     ctdb_recoverd_parent, &fd[0]);
 	tevent_fd_set_auto_close(fde);
 
 	/* set up a handler to pick up sigchld */
@@ -4069,6 +4073,9 @@ void ctdb_stop_recoverd(struct ctdb_context *ctdb)
 
 	DEBUG(DEBUG_NOTICE,("Shutting down recovery daemon\n"));
 	ctdb_kill(ctdb, ctdb->recoverd_pid, SIGTERM);
+
+	TALLOC_FREE(ctdb->recd_ctx);
+	TALLOC_FREE(ctdb->recd_ping_count);
 }
 
 static void ctdb_restart_recd(struct event_context *ev, struct timed_event *te, 
diff --git a/tests/simple/76_ctdb_pdb_recovery.sh b/tests/simple/76_ctdb_pdb_recovery.sh
new file mode 100755
index 0000000..2f21fdd
--- /dev/null
+++ b/tests/simple/76_ctdb_pdb_recovery.sh
@@ -0,0 +1,119 @@
+#!/bin/bash
+
+test_info()
+{
+    cat <<EOF
+The recovery process based on RSN for persistent databases is defective.
+For persistent databases sequence number based recovery method should be
+used. This test checks for the defect in the RSN based recovery method
+for persistent databases and confirms that the same issue is not observed
+when using sequence number based recovery method.
+
+Steps:
+
+1. Create a persistent database
+2. Add a record and update it few times. Set the sequence number to 5
+3. Delete the record
+4. Turn off one of the nodes
+5. Add a record with same key. Set the sequence number to 10
+6. Turn on the stopped node
+
+Expected results:
+
+* Check that the record is deleted (RSN based recovery) and record is
+  present (sequence number based recovery)
+
+EOF
+}
+
+. "${TEST_SCRIPTS_DIR}/integration.bash"
+
+ctdb_test_init "$@"
+
+set -e
+
+cluster_is_healthy
+
+# Reset configuration
+ctdb_restart_when_done
+
+do_test()
+{
+# Wipe Test database
+echo "wipe test database"
+try_command_on_node -q 0 $CTDB_TEST_WRAPPER ctdb wipedb $TESTDB
+
+# Add a record   key=test1 data=value1
+# and update values
+for value in value1 value2 value3 value4 value5 ; do
+	echo "store key(test1) data($value)"
+	try_command_on_node -q 0 "(echo -ne $value > /tmp/test_data)"
+	try_command_on_node -q 0 $CTDB_TEST_WRAPPER ctdb pstore $TESTDB test1 /tmp/test_data
+done
+
+# Update sequence number on all the nodes
+echo "set __db_sequence_number__ to 5"
+try_command_on_node -q 0 $CTDB_TEST_WRAPPER ctdb setdbseqnum $TESTDB 5
+
+# Delete record
+echo "delete key(test1)"
+try_command_on_node -q 0 $CTDB_TEST_WRAPPER ctdb pdelete $TESTDB test1
+
+# Stop a node
+echo "stop node 1"
+try_command_on_node -q 1 $CTDB_TEST_WRAPPER ctdb stop
+
+wait_until_node_has_status 1 stopped
+
+# Add a record   key=test1 data=value2
+echo "store key(test1) data(newvalue1)"
+try_command_on_node -q 0 "(echo -ne newvalue1 > /tmp/test_data)"
+try_command_on_node -q 0 $CTDB_TEST_WRAPPER ctdb pstore $TESTDB test1 /tmp/test_data
+
+echo "set __db_sequence_number__ to 6"
+try_command_on_node -q 0 $CTDB_TEST_WRAPPER ctdb setdbseqnum $TESTDB 6
+
+# Continue node
+echo "contine node 1"
+try_command_on_node -q 1 $CTDB_TEST_WRAPPER ctdb continue
+
+wait_until_node_has_status 1 notstopped
+
+}
+
+#
+# Main test
+#
+TESTDB="persistent_test.tdb"
+
+stauts=0
+
+# Create a temporary persistent database to test with
+echo "create persistent test database $TESTDB"
+try_command_on_node -q 0 $CTDB_TEST_WRAPPER ctdb attach $TESTDB persistent
+
+# Set RecoverPDBBySeqNum = 0
+echo "set RecoverPDBBySeqNum to 0"
+try_command_on_node -q all $CTDB_TEST_WRAPPER ctdb setvar RecoverPDBBySeqNum 0
+
+do_test
+if try_command_on_node 0 $CTDB_TEST_WRAPPER ctdb pfetch $TESTDB test1 ; then
+	echo "GOOD: Record was not deleted (recovery by RSN worked)"
+else
+	echo "BAD: Record was not deleted"
+	status=1
+fi
+
+# Set RecoverPDBBySeqNum = 1
+echo "set RecoverPDBBySeqNum to 1"
+try_command_on_node -q all $CTDB_TEST_WRAPPER ctdb setvar RecoverPDBBySeqNum 1
+
+do_test
+if try_command_on_node 0 $CTDB_TEST_WRAPPER ctdb pfetch $TESTDB test1 ; then
+	echo "GOOD: Record was not deleted (recovery by sequnce number worked)"
+else
+	echo "BAD: Record was deleted"
+	status=1
+fi
+
+exit $status
diff --git a/tools/ctdb.c b/tools/ctdb.c
index a974fb2..678b555 100644
--- a/tools/ctdb.c
+++ b/tools/ctdb.c
@@ -241,30 +241,57 @@ static bool parse_nodestring(struct ctdb_context *ctdb,
 /*
  check if a database exists
 */
-static int db_exists(struct ctdb_context *ctdb, const char *db_name, bool *persistent)
+static bool db_exists(struct ctdb_context *ctdb, const char *dbarg, uint32_t *dbid, uint8_t *flags)
 {
 	int i, ret;
 	struct ctdb_dbid_map *dbmap=NULL;
+	bool dbid_given = false, found = false;
+	uint32_t id;
+	TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
 
-	ret = ctdb_ctrl_getdbmap(ctdb, TIMELIMIT(), options.pnn, ctdb, &dbmap);
+	ret = ctdb_ctrl_getdbmap(ctdb, TIMELIMIT(), options.pnn, tmp_ctx, &dbmap);
 	if (ret != 0) {
 		DEBUG(DEBUG_ERR, ("Unable to get dbids from node %u\n", options.pnn));
-		return -1;
+		goto fail;
 	}
 
-	for(i=0;i<dbmap->num;i++){
-		const char *name;
+	if (strncmp(dbarg, "0x", 2) == 0) {
+		id = strtoul(dbarg, NULL, 0);
+		dbid_given = true;
+	}
 
-		ctdb_ctrl_getdbname(ctdb, TIMELIMIT(), options.pnn, dbmap->dbs[i].dbid, ctdb, &name);
-		if (!strcmp(name, db_name)) {
-			if (persistent) {
-				*persistent = dbmap->dbs[i].flags & CTDB_DB_FLAGS_PERSISTENT;
+	for(i=0; i<dbmap->num; i++) {
+		if (dbid_given) {
+			if (id == dbmap->dbs[i].dbid) {
+				found = true;
+				break;
+			}
+		} else {
+			const char *name;
+			ret = ctdb_ctrl_getdbname(ctdb, TIMELIMIT(), options.pnn, dbmap->dbs[i].dbid, tmp_ctx, &name);
+			if (ret != 0) {
+				DEBUG(DEBUG_ERR, ("Unable to get dbname from dbid %u\n", dbmap->dbs[i].dbid));
+				goto fail;
+			}
+
+			if (strcmp(name, dbarg) == 0) {
+				id = dbmap->dbs[i].dbid;
+				found = true;
+				break;
 			}
-			return 0;
 		}
 	}
 
-	return -1;
+	if (found) {
+		if (dbid) *dbid = id;
+		if (flags) *flags = dbmap->dbs[i].flags;
+	} else {
+		DEBUG(DEBUG_ERR,("No database matching '%s' found\n", dbarg));
+	}
+
+fail:
+	talloc_free(tmp_ctx);
+	return found;
 }
 
 /*
@@ -575,35 +602,18 @@ static int control_dbstatistics(struct ctdb_context *ctdb, int argc, const char
 {
 	TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
 	struct ctdb_db_statistics *dbstat;
-	struct ctdb_dbid_map *dbmap=NULL;
-	int i, ret;
+	int i;
+	uint32_t db_id;
 
 	if (argc < 1) {
 		usage();
 	}
 
-	ret = ctdb_ctrl_getdbmap(ctdb, TIMELIMIT(), options.pnn, tmp_ctx, &dbmap);
-	if (ret != 0) {
-		DEBUG(DEBUG_ERR, ("Unable to get dbids from node %u\n", options.pnn));
-		return ret;
-	}
-	for(i=0;i<dbmap->num;i++){
-		const char *name;
-
-		ctdb_ctrl_getdbname(ctdb, TIMELIMIT(), options.pnn, dbmap->dbs[i].dbid, tmp_ctx, &name);
-		if(!strcmp(argv[0], name)){
-			talloc_free(discard_const(name));
-			break;
-		}
-		talloc_free(discard_const(name));
-	}
-	if (i == dbmap->num) {
-		DEBUG(DEBUG_ERR,("No database with name '%s' found\n", argv[0]));
-		talloc_free(tmp_ctx);
+	if (!db_exists(ctdb, argv[0], &db_id, NULL)) {
 		return -1;
 	}
 
-	if (!ctdb_getdbstat(ctdb_connection, options.pnn, dbmap->dbs[i].dbid, &dbstat)) {
+	if (!ctdb_getdbstat(ctdb_connection, options.pnn, db_id, &dbstat)) {
 		DEBUG(DEBUG_ERR,("Failed to read db statistics from node\n"));
 		talloc_free(tmp_ctx);
 		return -1;
@@ -3401,8 +3411,8 @@ static int control_catdb(struct ctdb_context *ctdb, int argc, const char **argv)
 	const char *db_name;
 	struct ctdb_db_context *ctdb_db;
 	int ret;
-	bool persistent;
 	struct ctdb_dump_db_context c;
+	uint8_t flags;
 
 	if (argc < 1) {
 		usage();
@@ -3410,14 +3420,11 @@ static int control_catdb(struct ctdb_context *ctdb, int argc, const char **argv)
 
 	db_name = argv[0];
 
-
-	if (db_exists(ctdb, db_name, &persistent)) {
-		DEBUG(DEBUG_ERR,("Database '%s' does not exist\n", db_name));
+	if (!db_exists(ctdb, db_name, NULL, &flags)) {
 		return -1;
 	}
 
-	ctdb_db = ctdb_attach(ctdb, TIMELIMIT(), db_name, persistent, 0);
-
+	ctdb_db = ctdb_attach(ctdb, TIMELIMIT(), db_name, flags & CTDB_DB_FLAGS_PERSISTENT, 0);
 	if (ctdb_db == NULL) {
 		DEBUG(DEBUG_ERR,("Unable to attach to database '%s'\n", db_name));
 		return -1;
@@ -3487,7 +3494,7 @@ static int control_cattdb(struct ctdb_context *ctdb, int argc, const char **argv
 	const char *db_name;
 	struct ctdb_db_context *ctdb_db;
 	struct cattdb_data d;
-	bool persistent;
+	uint8_t flags;
 
 	if (argc < 1) {
 		usage();
@@ -3495,14 +3502,11 @@ static int control_cattdb(struct ctdb_context *ctdb, int argc, const char **argv
 
 	db_name = argv[0];
 
-
-	if (db_exists(ctdb, db_name, &persistent)) {
-		DEBUG(DEBUG_ERR,("Database '%s' does not exist\n", db_name));
+	if (!db_exists(ctdb, db_name, NULL, &flags)) {
 		return -1;
 	}
 
-	ctdb_db = ctdb_attach(ctdb, TIMELIMIT(), db_name, persistent, 0);
-
+	ctdb_db = ctdb_attach(ctdb, TIMELIMIT(), db_name, flags & CTDB_DB_FLAGS_PERSISTENT, 0);
 	if (ctdb_db == NULL) {
 		DEBUG(DEBUG_ERR,("Unable to attach to database '%s'\n", db_name));
 		return -1;
@@ -3531,7 +3535,7 @@ static int control_readkey(struct ctdb_context *ctdb, int argc, const char **arg
 	struct ctdb_record_handle *h;
 	TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
 	TDB_DATA key, data;
-	bool persistent;
+	uint8_t flags;
 
 	if (argc < 2) {
 		usage();
@@ -3539,13 +3543,11 @@ static int control_readkey(struct ctdb_context *ctdb, int argc, const char **arg
 
 	db_name = argv[0];
 
-	if (db_exists(ctdb, db_name, &persistent)) {
-		DEBUG(DEBUG_ERR,("Database '%s' does not exist\n", db_name));
+	if (!db_exists(ctdb, db_name, NULL, &flags)) {
 		return -1;
 	}
 
-	ctdb_db = ctdb_attach(ctdb, TIMELIMIT(), db_name, persistent, 0);
-
+	ctdb_db = ctdb_attach(ctdb, TIMELIMIT(), db_name, flags & CTDB_DB_FLAGS_PERSISTENT, 0);
 	if (ctdb_db == NULL) {
 		DEBUG(DEBUG_ERR,("Unable to attach to database '%s'\n", db_name));
 		return -1;
@@ -3579,7 +3581,7 @@ static int control_writekey(struct ctdb_context *ctdb, int argc, const char **ar
 	struct ctdb_record_handle *h;
 	TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
 	TDB_DATA key, data;
-	bool persistent;
+	uint8_t flags;
 
 	if (argc < 3) {
 		usage();
@@ -3587,13 +3589,11 @@ static int control_writekey(struct ctdb_context *ctdb, int argc, const char **ar
 
 	db_name = argv[0];
 
-	if (db_exists(ctdb, db_name, &persistent)) {
-		DEBUG(DEBUG_ERR,("Database '%s' does not exist\n", db_name));
+	if (!db_exists(ctdb, db_name, NULL, &flags)) {
 		return -1;
 	}
 
-	ctdb_db = ctdb_attach(ctdb, TIMELIMIT(), db_name, persistent, 0);
-
+	ctdb_db = ctdb_attach(ctdb, TIMELIMIT(), db_name, flags & CTDB_DB_FLAGS_PERSISTENT, 0);
 	if (ctdb_db == NULL) {
 		DEBUG(DEBUG_ERR,("Unable to attach to database '%s'\n", db_name));
 		return -1;
@@ -3635,6 +3635,7 @@ static int control_pfetch(struct ctdb_context *ctdb, int argc, const char **argv
 	TDB_DATA key, data;
 	int fd, ret;
 	bool persistent;
+	uint8_t flags;
 
 	if (argc < 2) {
 		talloc_free(tmp_ctx);
@@ -3643,13 +3644,12 @@ static int control_pfetch(struct ctdb_context *ctdb, int argc, const char **argv
 
 	db_name = argv[0];
 
-
-	if (db_exists(ctdb, db_name, &persistent)) {
-		DEBUG(DEBUG_ERR,("Database '%s' does not exist\n", db_name));
+	if (!db_exists(ctdb, db_name, NULL, &flags)) {
 		talloc_free(tmp_ctx);
 		return -1;
 	}
 
+	persistent = flags & CTDB_DB_FLAGS_PERSISTENT;
 	if (!persistent) {
 		DEBUG(DEBUG_ERR,("Database '%s' is not persistent\n", db_name));
 		talloc_free(tmp_ctx);
@@ -3657,7 +3657,6 @@ static int control_pfetch(struct ctdb_context *ctdb, int argc, const char **argv
 	}
 
 	ctdb_db = ctdb_attach(ctdb, TIMELIMIT(), db_name, persistent, 0);
-
 	if (ctdb_db == NULL) {
 		DEBUG(DEBUG_ERR,("Unable to attach to database '%s'\n", db_name));
 		talloc_free(tmp_ctx);
@@ -3934,6 +3933,73 @@ static int control_pstore(struct ctdb_context *ctdb, int argc, const char **argv
 }
 
 /*
+ * delete a record from a persistent database
+ */
+static int control_pdelete(struct ctdb_context *ctdb, int argc, const char **argv)
+{
+	const char *db_name;
+	struct ctdb_db_context *ctdb_db;
+	TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
+	struct ctdb_transaction_handle *h;
+	TDB_DATA key;
+	int ret;
+	bool persistent;
+	uint8_t flags;
+
+	if (argc < 2) {
+		talloc_free(tmp_ctx);
+		usage();
+	}
+
+	db_name = argv[0];
+
+	if (!db_exists(ctdb, db_name, NULL, &flags)) {
+		talloc_free(tmp_ctx);
+		return -1;
+	}
+


-- 
CTDB repository


More information about the samba-cvs mailing list