]> git.ipfire.org Git - thirdparty/systemd.git/blobdiff - src/shared/machine-image.c
tree-wide: use mfree more
[thirdparty/systemd.git] / src / shared / machine-image.c
index d2f1c4a40c7d17f6fbff6e50b57bbf4a516d59c9..060f8d50c716b85615fe3b46b806957f392d7922 100644 (file)
@@ -62,8 +62,7 @@ Image *image_unref(Image *i) {
 
         free(i->name);
         free(i->path);
-        free(i);
-        return NULL;
+        return mfree(i);
 }
 
 static char **image_settings_path(Image *image) {
@@ -401,8 +400,7 @@ int image_remove(Image *i) {
 
         assert(i);
 
-        if (path_equal(i->path, "/") ||
-            path_startswith(i->path, "/usr"))
+        if (IMAGE_IS_VENDOR(i) || IMAGE_IS_HOST(i))
                 return -EROFS;
 
         settings = image_settings_path(i);
@@ -424,7 +422,7 @@ int image_remove(Image *i) {
 
         case IMAGE_DIRECTORY:
                 /* Allow deletion of read-only directories */
-                (void) chattr_path(i->path, false, FS_IMMUTABLE_FL);
+                (void) chattr_path(i->path, 0, FS_IMMUTABLE_FL);
                 r = rm_rf(i->path, REMOVE_ROOT|REMOVE_PHYSICAL|REMOVE_SUBVOLUME);
                 if (r < 0)
                         return r;
@@ -474,8 +472,7 @@ int image_rename(Image *i, const char *new_name) {
         if (!image_name_is_valid(new_name))
                 return -EINVAL;
 
-        if (path_equal(i->path, "/") ||
-            path_startswith(i->path, "/usr"))
+        if (IMAGE_IS_VENDOR(i) || IMAGE_IS_HOST(i))
                 return -EROFS;
 
         settings = image_settings_path(i);
@@ -489,7 +486,7 @@ int image_rename(Image *i, const char *new_name) {
 
         /* Make sure nobody takes the new name, between the time we
          * checked it is currently unused in all search paths, and the
-         * time we take possesion of it */
+         * time we take possession of it */
         r = image_name_lock(new_name, LOCK_EX|LOCK_NB, &name_lock);
         if (r < 0)
                 return r;
@@ -507,7 +504,7 @@ int image_rename(Image *i, const char *new_name) {
                 (void) read_attr_path(i->path, &file_attr);
 
                 if (file_attr & FS_IMMUTABLE_FL)
-                        (void) chattr_path(i->path, false, FS_IMMUTABLE_FL);
+                        (void) chattr_path(i->path, 0, FS_IMMUTABLE_FL);
 
                 /* fall through */
 
@@ -540,7 +537,7 @@ int image_rename(Image *i, const char *new_name) {
 
         /* Restore the immutable bit, if it was set before */
         if (file_attr & FS_IMMUTABLE_FL)
-                (void) chattr_path(new_path, true, FS_IMMUTABLE_FL);
+                (void) chattr_path(new_path, FS_IMMUTABLE_FL, FS_IMMUTABLE_FL);
 
         free(i->path);
         i->path = new_path;
@@ -590,7 +587,7 @@ int image_clone(Image *i, const char *new_name, bool read_only) {
 
         /* Make sure nobody takes the new name, between the time we
          * checked it is currently unused in all search paths, and the
-         * time we take possesion of it */
+         * time we take possession of it */
         r = image_name_lock(new_name, LOCK_EX|LOCK_NB, &name_lock);
         if (r < 0)
                 return r;
@@ -605,13 +602,21 @@ int image_clone(Image *i, const char *new_name, bool read_only) {
 
         case IMAGE_SUBVOLUME:
         case IMAGE_DIRECTORY:
+                /* If we can we'll always try to create a new btrfs subvolume here, even if the source is a plain
+                 * directory.*/
+
                 new_path = strjoina("/var/lib/machines/", new_name);
 
                 r = btrfs_subvol_snapshot(i->path, new_path, (read_only ? BTRFS_SNAPSHOT_READ_ONLY : 0) | BTRFS_SNAPSHOT_FALLBACK_COPY | BTRFS_SNAPSHOT_RECURSIVE | BTRFS_SNAPSHOT_QUOTA);
+                if (r == -EOPNOTSUPP) {
+                        /* No btrfs snapshots supported, create a normal directory then. */
 
-                /* Enable "subtree" quotas for the copy, if we didn't
-                 * copy any quota from the source. */
-                (void) btrfs_subvol_auto_qgroup(i->path, 0, true);
+                        r = copy_directory(i->path, new_path, false);
+                        if (r >= 0)
+                                (void) chattr_path(new_path, read_only ? FS_IMMUTABLE_FL : 0, FS_IMMUTABLE_FL);
+                } else if (r >= 0)
+                        /* Enable "subtree" quotas for the copy, if we didn't copy any quota from the source. */
+                        (void) btrfs_subvol_auto_qgroup(new_path, 0, true);
 
                 break;
 
@@ -642,8 +647,7 @@ int image_read_only(Image *i, bool b) {
         int r;
         assert(i);
 
-        if (path_equal(i->path, "/") ||
-            path_startswith(i->path, "/usr"))
+        if (IMAGE_IS_VENDOR(i) || IMAGE_IS_HOST(i))
                 return -EROFS;
 
         /* Make sure we don't interfere with a running nspawn */
@@ -673,7 +677,7 @@ int image_read_only(Image *i, bool b) {
                    a read-only subvolume, but at least something, and
                    we can read the value back.*/
 
-                r = chattr_path(i->path, b, FS_IMMUTABLE_FL);
+                r = chattr_path(i->path, b ? FS_IMMUTABLE_FL : 0, FS_IMMUTABLE_FL);
                 if (r < 0)
                         return r;
 
@@ -751,8 +755,7 @@ int image_path_lock(const char *path, int operation, LockFile *global, LockFile
 int image_set_limit(Image *i, uint64_t referenced_max) {
         assert(i);
 
-        if (path_equal(i->path, "/") ||
-            path_startswith(i->path, "/usr"))
+        if (IMAGE_IS_VENDOR(i) || IMAGE_IS_HOST(i))
                 return -EROFS;
 
         if (i->type != IMAGE_SUBVOLUME)