Simple way to backup CDB from a subscriber

If you are using CDB as your candidate and running datastores (no external DB) and want to create a backup of CDB triggered when a certain part of the configuration has changed, a simple and efficient way to do so is to take a CDB backup in the commit phase of a transaction.

You can then reinitiate CDB from the CDB backup when/if necessary. This way, each time you have a good configuration in the commit phase, you save a backup of the full configuration. (instead of for example saving the old configuration in the validation phase which is not so efficient).

Quick demo below of a CDB backup application that just add a “backup CDB in commit phase” command to the existing confd_cmd tool to demonstrate:

$ diff -u $CONFD_DIR/src/confd/tools/confd_cmd.c confd_cmd.c
--- $CONFD_DIR/src/confd/tools/confd_cmd.c	2016-04-01 17:29:54.000000000 +0200
+++ confd_cmd.c	2016-04-17 13:32:55.000000000 +0200
@@ -1077,6 +1077,40 @@
     }
 }
 
+/* Backup in commit phase */
+static void do_subwait_backup(char *argv[]) /* <path> <path to cdb> <tar file to backup CDB to> [prio] [loop] */
+{
+    int id, n, i, prio, loop, subids[1];
+
+    if (argv[3]) {
+        prio = atoi(argv[3]);
+    } else {
+        prio = 10;
+    }
+    if (argv[3] && argv[4]) {
+        loop = atoi(argv[4]);
+        if (loop == 0) loop = 1;
+    } else {
+        loop = 1;
+    }
+
+    OK(common_subscribe(cs, prio, 0, &id, argv[0]));
+    OK(cdb_subscribe_done(cs));
+    printf("SUBSCRIBED TO %s\n", argv[0]);
+    for (i=0; i<loop; i++) {
+        char tmpbuf[BUFSIZ];
+        OK(cdb_read_subscription_socket(cs, subids, &n));
+        printf("COMMIT\n");
+	sprintf(tmpbuf, "tar cf %s  %s/A.cdb %s/C.cdb; gzip -f %s", argv[2], argv[1], argv[1], argv[2]);
+	system(tmpbuf);
+        common_sync_subscription_socket(cs, CDB_DONE_PRIORITY);
+        printf("DONE\n");
+    }
+
+}
+
+
+
 /* Wait for a path to change */
 static void do_subwait_citer(char *argv[]) /* <path> [prio] [loop] */
 {
@@ -2021,6 +2055,13 @@
         "and run cdb_diff_iterate() when notified"
     },
     {
+        "subwait_backup", {NULL}, do_subwait_backup, -3,
+        CMD_CDB|CMD_CDB_SUB,
+        "<path> <CDB path> <tar file to backup CDB to> [priority] [loop]",
+        “subscribe to <path> "
+        "and take a CDB backup when notified"
+    },
+    {
         "subwait_cli_iter", {NULL}, do_subwait_citer, -1,
         CMD_CDB|CMD_CDB_SUB|CMD_WANT_SCHEMA,
         “<path> [priority] [loop]", NULL

Terminal window:’

$ ./confd_cmd -d -d -c "subwait_backup /dhcp ./confd-cdb ./cdb-backup.tar"
subwait_backup "/dhcp" "./confd-cdb" "./cdb-backup.tar"
TRACE Connected (cdb) to ConfD
TRACE CDB_SUBSCRIBE /contexts --> CONFD_OK
TRACE CDB_SUBSCRIBE_DONE  --> CONFD_OK
SUBSCRIBED TO /dhcp
TRACE CDB_SUBSCRIPTION_EVENT --> 6      <--- Something in the /dhcp configuration changed and we now take a full CDB backup from the subscriber.
COMMIT
TRACE CDB_SYNC_SUB CDB_DONE_PRIORITY --> CONFD_OK
DONE