This patch provides three new public API functions that allow
reverting the network configuration back to a previous "known good"
state. The three new functions are:

  ncf_change_begin() - save a snapshot of current network config
  ncf_change_rollback() - revert to the config previously saved
  ncf_change_commit() - delete the saved snapshot, making the new
                        config permanent

If the system is rebooted after ncf_change_begin() is called, but
prior to calling ncf_change_commit(), the network config will be
automatically reverted to the saved state during the boot process.

The functionality is provided by the the script netcf-transaction,
which was added in the previous patch.

This initial version only updates the config files during a
rollback. It doesn't attempt to ifdown interfaces that are being
removed, ifup interfaces that are being added, or ifdown/ifup
interfaces that have been changed. That will be in an upcoming patch.
---
 configure.ac          |    2 +-
 src/drv_initscripts.c |   43 +++++++++++++++++++++++++++++++++
 src/internal.h        |    4 +++
 src/ncftool.c         |   63 +++++++++++++++++++++++++++++++++++++++++++++++++
 src/netcf.c           |   21 ++++++++++++++++
 src/netcf.h           |   22 +++++++++++++++++
 src/netcf_public.syms |    7 +++++
 7 files changed, 161 insertions(+), 1 deletions(-)

diff --git a/configure.ac b/configure.ac
index f62097b..abc7a13 100644
--- a/configure.ac
+++ b/configure.ac
@@ -6,7 +6,7 @@ AM_CONFIG_HEADER([config.h])
 AM_INIT_AUTOMAKE([-Wno-portability 1.11 color-tests parallel-tests])
 AM_SILENT_RULES([yes]) # make --enable-silent-rules the default.
 
-AC_SUBST([LIBNETCF_VERSION_INFO], [4:3:3])
+AC_SUBST([LIBNETCF_VERSION_INFO], [5:0:4])
 
 AC_GNU_SOURCE
 
diff --git a/src/drv_initscripts.c b/src/drv_initscripts.c
index b2f16d5..39a8070 100644
--- a/src/drv_initscripts.c
+++ b/src/drv_initscripts.c
@@ -1070,6 +1070,49 @@ int drv_if_down(struct netcf_if *nif) {
     return result;
 }
 
+/* Functions to take a snapshot of network config (change_begin), and
+ * later either revert to that config (change_rollback), or make the
+ * new config permanent (change_commit).
+ */
+int
+drv_change_begin(struct netcf *ncf ATTRIBUTE_UNUSED,
+                 unsigned int flags ATTRIBUTE_UNUSED)
+{
+    int result = -1;
+
+    run1(ncf, NETCF_TRANSACTION, "change-begin");
+    ERR_BAIL(ncf);
+    result = 0;
+error:
+    return result;
+}
+
+int
+drv_change_rollback(struct netcf *ncf ATTRIBUTE_UNUSED,
+                    unsigned int flags ATTRIBUTE_UNUSED)
+{
+    int result = -1;
+
+    run1(ncf, NETCF_TRANSACTION, "change-rollback");
+    ERR_BAIL(ncf);
+    result = 0;
+error:
+    return result;
+}
+
+int
+drv_change_commit(struct netcf *ncf ATTRIBUTE_UNUSED,
+                  unsigned int flags ATTRIBUTE_UNUSED)
+{
+    int result = -1;
+
+    run1(ncf, NETCF_TRANSACTION, "change-commit");
+    ERR_BAIL(ncf);
+    result = 0;
+error:
+    return result;
+}
+
 /*
  * Test interface
  */
diff --git a/src/internal.h b/src/internal.h
index b7fa5f2..78494e9 100644
--- a/src/internal.h
+++ b/src/internal.h
@@ -182,6 +182,10 @@ int drv_lookup_by_mac_string(struct netcf *, const char 
*mac,
 char *drv_xml_desc(struct netcf_if *);
 char *drv_xml_state(struct netcf_if *);
 int drv_if_status(struct netcf_if *nif, unsigned int *flags);
+int drv_change_begin(struct netcf *ncf, unsigned int flags);
+int drv_change_rollback(struct netcf *ncf, unsigned int flags);
+int drv_change_commit(struct netcf *ncf, unsigned int flags);
+
 const char *drv_mac_string(struct netcf_if *nif);
 struct netcf_if *drv_define(struct netcf *ncf, const char *xml);
 int drv_undefine(struct netcf_if *nif);
diff --git a/src/ncftool.c b/src/ncftool.c
index f86b62c..b202e17 100644
--- a/src/ncftool.c
+++ b/src/ncftool.c
@@ -412,6 +412,66 @@ static const struct command_def cmd_undefine_def = {
     .help = "remove the configuration of an interface"
 };
 
+static int cmd_change_begin(ATTRIBUTE_UNUSED const struct command *cmd)
+{
+    if (ncf_change_begin(ncf, 0) < 0)
+        return CMD_RES_ERR;
+    printf("config change transaction started\n");
+    return CMD_RES_OK;
+}
+
+static const struct command_opt_def cmd_change_begin_opts[] = {
+    CMD_OPT_DEF_LAST
+};
+
+static const struct command_def cmd_change_begin_def = {
+    .name = "change-begin",
+    .opts = cmd_change_begin_opts,
+    .handler = cmd_change_begin,
+    .synopsis = "mark the beginning of a set of revertable network config 
changes",
+    .help = "marks the beginning of a set of revertable network config 
changes",
+};
+
+static int cmd_change_commit(ATTRIBUTE_UNUSED const struct command *cmd)
+{
+    if (ncf_change_commit(ncf, 0) < 0)
+        return CMD_RES_ERR;
+    printf("config change transaction committed\n");
+    return CMD_RES_OK;
+}
+
+static const struct command_opt_def cmd_change_commit_opts[] = {
+    CMD_OPT_DEF_LAST
+};
+
+static const struct command_def cmd_change_commit_def = {
+    .name = "change-commit",
+    .opts = cmd_change_commit_opts,
+    .handler = cmd_change_commit,
+    .synopsis = "commit the pending network config changes",
+    .help = "commits (makes permanent) of a set of network config changes",
+};
+
+static int cmd_change_rollback(ATTRIBUTE_UNUSED const struct command *cmd)
+{
+    if (ncf_change_rollback(ncf, 0) < 0)
+        return CMD_RES_ERR;
+    printf("config change transaction rolled back\n");
+    return CMD_RES_OK;
+}
+
+static const struct command_opt_def cmd_change_rollback_opts[] = {
+    CMD_OPT_DEF_LAST
+};
+
+static const struct command_def cmd_change_rollback_def = {
+    .name = "change-rollback",
+    .opts = cmd_change_rollback_opts,
+    .handler = cmd_change_rollback,
+    .synopsis = "rollback (revert) a set of network config changes",
+    .help = "rollback (revert) a set of network config changes",
+};
+
 static int cmd_help(const struct command *cmd) {
     const char *name = param_value(cmd, "command");
     if (name == NULL) {
@@ -616,6 +676,9 @@ static const struct command_def const *commands[] = {
     &cmd_undefine_def,
     &cmd_if_up_def,
     &cmd_if_down_def,
+    &cmd_change_begin_def,
+    &cmd_change_commit_def,
+    &cmd_change_rollback_def,
     &cmd_help_def,
     &cmd_quit_def,
     &cmd_def_last
diff --git a/src/netcf.c b/src/netcf.c
index 9440ed0..34994bb 100644
--- a/src/netcf.c
+++ b/src/netcf.c
@@ -196,6 +196,27 @@ int ncf_if_status(struct netcf_if *nif, unsigned int 
*flags) {
     return drv_if_status(nif, flags);
 }
 
+int
+ncf_change_begin(struct netcf *ncf, unsigned int flags)
+{
+    API_ENTRY(ncf);
+    return drv_change_begin(ncf, flags);
+}
+
+int
+ncf_change_rollback(struct netcf *ncf, unsigned int flags)
+{
+    API_ENTRY(ncf);
+    return drv_change_rollback(ncf, flags);
+}
+
+int
+ncf_change_commit(struct netcf *ncf, unsigned int flags)
+{
+    API_ENTRY(ncf);
+    return drv_change_commit(ncf, flags);
+}
+
 /* Release any resources used by this NETCF_IF; the pointer is invalid
  * after this call
  */
diff --git a/src/netcf.h b/src/netcf.h
index bf5e4e2..e507b97 100644
--- a/src/netcf.h
+++ b/src/netcf.h
@@ -169,6 +169,28 @@ char *ncf_if_xml_state(struct netcf_if *);
  */
 int ncf_if_status(struct netcf_if *nif, unsigned int *flags);
 
+/* Mark the beginning of a sequence of revertable changes to the
+ * network interface config by saving a snapshot of all relevant
+ * config information.
+ * Returns 0 on success, -1 on failure
+ */
+int ncf_change_begin(struct netcf *ncf, unsigned int flags); 
+
+/* Revert to the previously snapshotted (with ncf_change_begin)
+ * network config, effectively undoing the changes.
+ * Returns 0 on success, -1 on failure
+ */
+int ncf_change_rollback(struct netcf *ncf, unsigned int flags); 
+
+/* Commit the changes made to network config since ncf_change_begin
+ * was called (usually by simply deleting the snapshot that was saved,
+ * as well as bringing down any interfaces that will not be present in
+ * the restored config, and bouncing interfaces that still exist, but
+ * have changed their config.)
+ * Returns 0 on success, -1 on failure
+ */
+int ncf_change_commit(struct netcf *ncf, unsigned int flags); 
+
 /* Release any resources used by this NETCF_IF; the pointer is invalid
  * after this call
  */
diff --git a/src/netcf_public.syms b/src/netcf_public.syms
index 9180614..e0e034a 100644
--- a/src/netcf_public.syms
+++ b/src/netcf_public.syms
@@ -28,3 +28,10 @@ NETCF_1.3.0 {
     global:
       ncf_if_status;
 } NETCF_1.2.0;
+
+NETCF_1.4.0 {
+    global:
+      ncf_change_begin;
+      ncf_change_commit;
+      ncf_change_rollback;
+} NETCF_1.3.0;
-- 
1.7.3.4

_______________________________________________
netcf-devel mailing list
[email protected]
https://fedorahosted.org/mailman/listinfo/netcf-devel

Reply via email to