[augeas-devel] [PATCH] Transparent save of cross-device links

David Lutterkort lutter at redhat.com
Fri Sep 4 00:05:24 UTC 2009


When saving to a file, we first write to a file with extension .augnew and
then rename that file to the actual file. This fails when the original is a
symlink to a file on another device.

We now write the .augnew file next to the canonicalized original file to
avoid that headache. There are still situations where the rename fails,
e.g. when the original file is bindmounted - in that situation, we have to
copy.
---
 src/transform.c |   38 ++++++++++++++++++++++++--------------
 1 files changed, 24 insertions(+), 14 deletions(-)

diff --git a/src/transform.c b/src/transform.c
index 933edb4..a9e60dc 100644
--- a/src/transform.c
+++ b/src/transform.c
@@ -737,11 +737,6 @@ int transform_save(struct augeas *aug, struct tree *xfm,
         goto done;
     }
 
-    if (asprintf(&augnew, "%s%s" EXT_AUGNEW, aug->root, filename) == -1) {
-        augnew = NULL;
-        goto done;
-    }
-
     if (access(augorig, R_OK) == 0) {
         text = read_file(augorig);
     } else {
@@ -755,15 +750,6 @@ int transform_save(struct augeas *aug, struct tree *xfm,
 
     text = append_newline(text, strlen(text));
 
-    // FIXME: We might have to create intermediary directories
-    // to be able to write augnew, but we have no idea what permissions
-    // etc. they should get. Just the process default ?
-    fp = fopen(augnew, "w");
-    if (fp == NULL) {
-        err_status = "open_augnew";
-        goto done;
-    }
-
     augorig_canon = canonicalize_file_name(augorig);
     augorig_exists = 1;
     if (augorig_canon == NULL) {
@@ -775,6 +761,30 @@ int transform_save(struct augeas *aug, struct tree *xfm,
             goto done;
         }
     }
+
+    /* Figure out where to put the .augnew file. If we need to rename it
+       later on, put it next to augorig_canon */
+    if (aug->flags & AUG_SAVE_NEWFILE) {
+        if (xasprintf(&augnew, "%s" EXT_AUGNEW, augorig) < 0) {
+            err_status = "augnew_oom";
+            goto done;
+        }
+    } else {
+        if (xasprintf(&augnew, "%s" EXT_AUGNEW, augorig_canon) < 0) {
+            err_status = "augnew_oom";
+            goto done;
+        }
+    }
+
+    // FIXME: We might have to create intermediate directories
+    // to be able to write augnew, but we have no idea what permissions
+    // etc. they should get. Just the process default ?
+    fp = fopen(augnew, "w");
+    if (fp == NULL) {
+        err_status = "open_augnew";
+        goto done;
+    }
+
     if (augorig_exists) {
         if (transfer_file_attrs(augorig_canon, augnew, &err_status) != 0) {
             err_status = "xfer_attrs";
-- 
1.6.2.5




More information about the augeas-devel mailing list