[augeas-devel] augeas: master - Transparent save of cross-device links

David Lutterkort lutter at fedoraproject.org
Fri Sep 4 17:56:22 UTC 2009


Gitweb:        http://git.fedorahosted.org/git/augeas.git?p=augeas.git;a=commitdiff;h=c0234fc97a7cd7eb5e44d59f96c0adf66a711f8f
Commit:        c0234fc97a7cd7eb5e44d59f96c0adf66a711f8f
Parent:        1e6776618ac43135bd3e64c7d4107a73feac55de
Author:        David Lutterkort <lutter at redhat.com>
AuthorDate:    Thu Sep 3 16:42:25 2009 -0700
Committer:     David Lutterkort <lutter at redhat.com>
CommitterDate: Thu Sep 3 17:01:27 2009 -0700

Transparent save of cross-device links

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";




More information about the augeas-devel mailing list