When aug_save fails, the /augeas metadata tree is now searched to find a
possible reason for the failure and an error is raised containing the file
path, Augeas error code (pointing to the action that failed) and the message if
supplied (from strerror).

A failure to unlink a file now results in a message such as:

  error: unspecified error
  error: aug_save failed on /etc/sysconfig/network-scripts/ifcfg-em1:
  unlink_orig (Permission denied)

Multiple failures aren't reported in detail, but will be printed if debug is
enabled.
---
 src/drv_debian.c  | 16 ++++------------
 src/drv_redhat.c  | 19 ++++---------------
 src/drv_suse.c    | 14 ++++----------
 src/dutil_linux.c | 40 ++++++++++++++++++++++++++++++++++++++++
 src/dutil_linux.h |  3 +++
 5 files changed, 55 insertions(+), 37 deletions(-)

diff --git a/src/drv_debian.c b/src/drv_debian.c
index 440b233..bf05bd4 100644
--- a/src/drv_debian.c
+++ b/src/drv_debian.c
@@ -912,8 +912,6 @@ struct netcf_if *drv_define(struct netcf *ncf, const char 
*xml_str) {
     struct netcf_if *result = NULL;
     xmlDocPtr ncf_xml = NULL, aug_xml = NULL;
     char *name = NULL;
-    int r;
-    struct augeas *aug = get_augeas(ncf);
 
     ERR_BAIL(ncf);
 
@@ -941,12 +939,8 @@ struct netcf_if *drv_define(struct netcf *ncf, const char 
*xml_str) {
     bond_setup(ncf, name, true);
     ERR_BAIL(ncf);
 
-    r = aug_save(aug);
-    if (r < 0 && NCF_DEBUG(ncf)) {
-        fprintf(stderr, "Errors from aug_save:\n");
-        aug_print(aug, stderr, "/augeas//error");
-    }
-    ERR_THROW(r < 0, ncf, EOTHER, "aug_save failed");
+    if (aug_save_assert(ncf) < 0)
+        goto error;
 
     result = make_netcf_if(ncf, name);
     ERR_BAIL(ncf);
@@ -961,9 +955,7 @@ struct netcf_if *drv_define(struct netcf *ncf, const char 
*xml_str) {
 }
 
 int drv_undefine(struct netcf_if *nif) {
-    struct augeas *aug = NULL;
     struct netcf *ncf = nif->ncf;
-    int r;
 
     aug = get_augeas(ncf);
     ERR_BAIL(ncf);
@@ -974,8 +966,8 @@ int drv_undefine(struct netcf_if *nif) {
     rm_interface(ncf, nif->name);
     ERR_BAIL(ncf);
 
-    r = aug_save(aug);
-    ERR_COND_BAIL(r < 0, ncf, EOTHER);
+    if (aug_save_assert(ncf) < 0)
+        goto error;
 
     return 0;
  error:
diff --git a/src/drv_redhat.c b/src/drv_redhat.c
index 898601d..d000164 100644
--- a/src/drv_redhat.c
+++ b/src/drv_redhat.c
@@ -865,8 +865,6 @@ struct netcf_if *drv_define(struct netcf *ncf, const char 
*xml_str) {
     xmlDocPtr ncf_xml = NULL, aug_xml = NULL;
     char *name = NULL;
     struct netcf_if *result = NULL;
-    int r;
-    struct augeas *aug = get_augeas(ncf);
 
     ERR_BAIL(ncf);
 
@@ -894,12 +892,8 @@ struct netcf_if *drv_define(struct netcf *ncf, const char 
*xml_str) {
     bond_setup(ncf, name, true);
     ERR_BAIL(ncf);
 
-    r = aug_save(aug);
-    if (r < 0 && NCF_DEBUG(ncf)) {
-        fprintf(stderr, "Errors from aug_save:\n");
-        aug_print(aug, stderr, "/augeas//error");
-    }
-    ERR_THROW(r < 0, ncf, EOTHER, "aug_save failed");
+    if (aug_save_assert(ncf) < 0)
+        goto error;
 
     result = make_netcf_if(ncf, name);
     ERR_BAIL(ncf);
@@ -914,12 +908,7 @@ struct netcf_if *drv_define(struct netcf *ncf, const char 
*xml_str) {
 }
 
 int drv_undefine(struct netcf_if *nif) {
-    struct augeas *aug = NULL;
     struct netcf *ncf = nif->ncf;
-    int r;
-
-    aug = get_augeas(ncf);
-    ERR_BAIL(ncf);
 
     bond_setup(ncf, nif->name, false);
     ERR_BAIL(ncf);
@@ -927,8 +916,8 @@ int drv_undefine(struct netcf_if *nif) {
     rm_interface(ncf, nif->name);
     ERR_BAIL(ncf);
 
-    r = aug_save(aug);
-    ERR_COND_BAIL(r < 0, ncf, EOTHER);
+    if (aug_save_assert(ncf) < 0)
+        goto error;
 
     return 0;
  error:
diff --git a/src/drv_suse.c b/src/drv_suse.c
index b677c88..e5944ef 100644
--- a/src/drv_suse.c
+++ b/src/drv_suse.c
@@ -1007,8 +1007,6 @@ struct netcf_if *drv_define(struct netcf *ncf, const char 
*xml_str) {
     xmlDocPtr ncf_xml = NULL, aug_xml = NULL;
     char *name = NULL;
     struct netcf_if *result = NULL;
-    int r;
-    struct augeas *aug = get_augeas(ncf);
 
     ERR_BAIL(ncf);
 
@@ -1036,12 +1034,8 @@ struct netcf_if *drv_define(struct netcf *ncf, const 
char *xml_str) {
     bond_setup(ncf, name, true);
     ERR_BAIL(ncf);
 
-    r = aug_save(aug);
-    if (r < 0 && NCF_DEBUG(ncf)) {
-        fprintf(stderr, "Errors from aug_save:\n");
-        aug_print(aug, stderr, "/augeas//error");
-    }
-    ERR_THROW(r < 0, ncf, EOTHER, "aug_save failed");
+    if (aug_save_assert(ncf) < 0)
+        goto error;
 
     result = make_netcf_if(ncf, name);
     ERR_BAIL(ncf);
@@ -1069,8 +1063,8 @@ int drv_undefine(struct netcf_if *nif) {
     rm_interface(ncf, nif->name);
     ERR_BAIL(ncf);
 
-    r = aug_save(aug);
-    ERR_COND_BAIL(r < 0, ncf, EOTHER);
+    if (aug_save_assert(ncf) < 0)
+        goto error;
 
     return 0;
  error:
diff --git a/src/dutil_linux.c b/src/dutil_linux.c
index d2bbef4..651da2e 100644
--- a/src/dutil_linux.c
+++ b/src/dutil_linux.c
@@ -215,6 +215,46 @@ struct augeas *get_augeas(struct netcf *ncf) {
     return NULL;
 }
 
+int aug_save_assert(struct netcf *ncf) {
+    int r = -1;
+    const char *err, *errmsg, *path = "unknown";
+    struct augeas *aug = get_augeas(ncf);
+
+    ERR_BAIL(ncf);
+
+    r = aug_save(aug);
+    if (r >= 0)
+        goto done;
+
+    if (NCF_DEBUG(ncf)) {
+        fprintf(stderr, "Errors from aug_save:\n");
+        aug_print(aug, stderr, "/augeas//error");
+    }
+
+    if (aug_get(aug, "/augeas//error", &err) == 1) {
+        if (aug_get(aug, "/augeas//error/../path", &path) == 1) {
+            /* strip /files prefix */
+            if (path != NULL && *path != '\0')
+                path = strchrnul(path + 1, '/');
+        }
+        if (aug_get(aug, "/augeas//error/message", &errmsg) == 1) {
+            report_error(ncf, NETCF_EOTHER, "aug_save failed on %s: %s (%s)",
+                         path, err, errmsg);
+        } else {
+            report_error(ncf, NETCF_EOTHER, "aug_save failed on %s: %s",
+                         path, err);
+        }
+    } else if (aug_match(aug, "/augeas//error", NULL) > 1) {
+        report_error(ncf, NETCF_EOTHER, "aug_save failed: multiple failures");
+    } else {
+        report_error(ncf, NETCF_EOTHER, "aug_save failed: unknown failure");
+    }
+
+ error:
+ done:
+    return r;
+}
+
 ATTRIBUTE_FORMAT(printf, 4, 5)
 int defnode(struct netcf *ncf, const char *name, const char *value,
                    const char *format, ...) {
diff --git a/src/dutil_linux.h b/src/dutil_linux.h
index 64fe64f..f63cc5a 100644
--- a/src/dutil_linux.h
+++ b/src/dutil_linux.h
@@ -69,6 +69,9 @@ int remove_augeas_xfm_table(struct netcf *ncf,
 /* Get or create the augeas instance from NCF */
 struct augeas *get_augeas(struct netcf *ncf);
 
+/* Save changes in augeas and raise error with message on failure */
+int aug_save_assert(struct netcf *ncf);
+
 /* Define a node inside the augeas tree */
 ATTRIBUTE_FORMAT(printf, 4, 5)
 int defnode(struct netcf *ncf, const char *name, const char *value,
-- 
1.9.3

_______________________________________________
netcf-devel mailing list
netcf-devel@lists.fedorahosted.org
https://lists.fedorahosted.org/mailman/listinfo/netcf-devel

Reply via email to