]> git.ipfire.org Git - people/stevee/ipfire-2.x.git/commitdiff
installer: Add code to create a BTRFS subvolume layout.
authorStefan Schantl <stefan.schantl@ipfire.org>
Sun, 25 Feb 2024 18:34:38 +0000 (19:34 +0100)
committerStefan Schantl <stefan.schantl@ipfire.org>
Sun, 25 Feb 2024 18:34:38 +0000 (19:34 +0100)
Signed-off-by: Stefan Schantl <stefan.schantl@ipfire.org>
src/installer/hw.c
src/installer/hw.h

index 81be874716915de93a3a78a7da2bf325366babef..420feaca734aeb84d28facafe62c16ccdba577c5 100644 (file)
 
 #include "hw.h"
 
+// Array which contains the subvolumes which will be created when installing
+// IPFire on a BTRFS.
+const char* btrfs_subvolumes[7][2] = {
+       {"@root" ,"/"},
+       {"@snapshots", "/.snapshots"},
+       {"@home", "/home"},
+       {"@cache", "/var/cache"},
+       {"@lib", "/var/lib"},
+       {"@logs", "/var/log"},
+       {"@mails", "/var/mail"}
+};
+
+#define LEN(arr) ((int) (sizeof (arr) / sizeof (arr)[0]))
+
 static int system_chroot(const char* output, const char* path, const char* cmd) {
        char chroot_cmd[STRING_SIZE];
 
@@ -805,6 +819,7 @@ int hw_create_partitions(struct hw_destination* dest, const char* output) {
 
 static int hw_format_filesystem(const char* path, int fs, const char* output) {
        char cmd[STRING_SIZE] = "\0";
+       int r;
 
        // Swap
        if (fs == HW_FS_SWAP) {
@@ -824,7 +839,9 @@ static int hw_format_filesystem(const char* path, int fs, const char* output) {
 
        // BTRFS
        } else if (fs == HW_FS_BTRFS) {
-               snprintf(cmd, sizeof(cmd), "/usr/bin/mkfs.btrfs -L rootfs -f %s", path);
+               r = hw_create_btrfs_layout(path, output);
+
+               return r;
 
        // FAT32
        } else if (fs == HW_FS_FAT32) {
@@ -833,7 +850,7 @@ static int hw_format_filesystem(const char* path, int fs, const char* output) {
 
        assert(*cmd);
 
-       int r = mysystem(output, cmd);
+       r = mysystem(output, cmd);
 
        return r;
 }
@@ -870,6 +887,43 @@ int hw_create_filesystems(struct hw_destination* dest, const char* output) {
        return 0;
 }
 
+int hw_create_btrfs_layout(const char* path, const char* output) {
+       char cmd[STRING_SIZE];
+       char subvolume[STRING_SIZE];
+
+       // Create the main BTRFS.
+       snprintf(cmd, sizeof(cmd), "/usr/bin/mkfs.btrfs -L IPFire -f %s", path);
+       int r = mysystem(output, cmd);
+
+       if (r)
+               return r;
+
+       // We need to mount the FS in order to create any subvolumes.
+       r = hw_mount(path, DESTINATION_MOUNT_PATH, "btrfs", 0);
+
+       if (r)
+               return r;
+
+       // Loop through the array of subvolumes to create.
+       for ( int i = 0; i < LEN(btrfs_subvolumes); i++ ) {
+               snprintf(subvolume, sizeof(subvolume), "%s", btrfs_subvolumes[i][0]);
+
+               // Call function to create the subvolume
+               r = hw_create_btrfs_subvolume(output, subvolume);
+
+               if (r)
+                       return r;
+       }
+
+       // Umount the main BTRFS after subvolume creation.
+       r = hw_umount(path, 0);
+
+       if (r)
+               return r;
+
+       return 0;
+}
+
 int hw_mount_filesystems(struct hw_destination* dest, const char* prefix) {
        char target[STRING_SIZE];
 
@@ -1219,3 +1273,15 @@ int hw_restore_backup(const char* output, const char* backup_path, const char* d
 
        return 0;
 }
+
+int hw_create_btrfs_subvolume(const char* output, const char* subvolume) {
+       char command [STRING_SIZE];
+       snprintf(command, sizeof(command), "/usr/bin/btrfs subvolume create  %s/%s", DESTINATION_MOUNT_PATH, subvolume);
+
+       int r = mysystem(output, command);
+
+       if (r)
+               return -1;
+
+       return 0;
+}
index e5ee65a6d2a7f706aa3d982c2dea6f26daec673b..2de73a3be824fa9ad8b7e2775f1a2573ea28c7f3 100644 (file)
@@ -104,6 +104,8 @@ struct hw_destination {
        unsigned long long size_root;
 };
 
+extern const char* btrfs_subvolumes[][2];
+
 struct hw* hw_init();
 void hw_free(struct hw* hw);
 
@@ -143,4 +145,7 @@ int hw_start_networking(const char* output);
 
 void hw_sync();
 
+int hw_create_btrfs_layout(const char* output, const char* subvolume);
+int hw_create_btrfs_subvolume(const char* output, const char* subvolume);
+
 #endif /* HEADER_HW_H */