]> git.ipfire.org Git - ipfire-2.x.git/blobdiff - src/installer/hw.c
installer: Fix umounting destination
[ipfire-2.x.git] / src / installer / hw.c
index e14a47016e951e9993e867dcb8e082b87bda2cb5..ce9777500d5cbd28ecabdb10082f7fbd04760841 100644 (file)
@@ -24,6 +24,7 @@
 
 #include <assert.h>
 #include <blkid/blkid.h>
+#include <errno.h>
 #include <fcntl.h>
 #include <libudev.h>
 #include <linux/loop.h>
@@ -138,7 +139,16 @@ int hw_mount(const char* source, const char* target, const char* fs, int flags)
 }
 
 int hw_umount(const char* target) {
-       return umount2(target, 0);
+       int r = umount2(target, 0);
+
+       if (r && errno == EBUSY) {
+               // Give it a moment to settle
+               sleep(1);
+
+               r = umount2(target, MNT_FORCE);
+       }
+
+       return r;
 }
 
 static int hw_test_source_medium(const char* path) {
@@ -440,7 +450,7 @@ static int hw_device_has_p_suffix(const struct hw_destination* dest) {
        return 0;
 }
 
-static int hw_calculate_partition_table(struct hw_destination* dest) {
+static int hw_calculate_partition_table(struct hw_destination* dest, int disable_swap) {
        char path[DEV_SIZE];
        int part_idx = 1;
 
@@ -493,9 +503,14 @@ static int hw_calculate_partition_table(struct hw_destination* dest) {
        }
 
        dest->size_boot = hw_boot_size(dest);
-       dest->size_swap = hw_swap_size(dest);
        dest->size_root = hw_root_size(dest);
 
+       // Should we use swap?
+       if (disable_swap)
+               dest->size_swap = 0;
+       else
+               dest->size_swap = hw_swap_size(dest);
+
        // Determine the size of the data partition.
        unsigned long long used_space = dest->size_bootldr + dest->size_boot
                + dest->size_swap + dest->size_root;
@@ -540,7 +555,7 @@ static int hw_calculate_partition_table(struct hw_destination* dest) {
        return 0;
 }
 
-struct hw_destination* hw_make_destination(int part_type, struct hw_disk** disks) {
+struct hw_destination* hw_make_destination(int part_type, struct hw_disk** disks, int disable_swap) {
        struct hw_destination* dest = malloc(sizeof(*dest));
 
        if (part_type == HW_PART_TYPE_NORMAL) {
@@ -560,7 +575,7 @@ struct hw_destination* hw_make_destination(int part_type, struct hw_disk** disks
        // Is this a RAID device?
        dest->is_raid = (part_type > HW_PART_TYPE_NORMAL);
 
-       int r = hw_calculate_partition_table(dest);
+       int r = hw_calculate_partition_table(dest, disable_swap);
        if (r)
                return NULL;
 
@@ -864,36 +879,47 @@ int hw_mount_filesystems(struct hw_destination* dest, const char* prefix) {
 }
 
 int hw_umount_filesystems(struct hw_destination* dest, const char* prefix) {
+       int r;
+       char target[STRING_SIZE];
+
        // Write all buffers to disk before umounting
        hw_sync();
 
        // boot
        if (*dest->part_boot) {
-               hw_umount(dest->part_boot);
+               snprintf(target, sizeof(target), "%s%s", prefix, HW_PATH_BOOT);
+               r = hw_umount(target);
+               if (r)
+                       return -1;
        }
 
        // data
        if (*dest->part_data) {
-               hw_umount(dest->part_data);
+               snprintf(target, sizeof(target), "%s%s", prefix, HW_PATH_DATA);
+               r = hw_umount(target);
+               if (r)
+                       return -1;
        }
 
-       // root
-       hw_umount(dest->part_root);
-
        // swap
        if (*dest->part_swap) {
                swapoff(dest->part_swap);
        }
 
        // misc filesystems
-       char target[STRING_SIZE];
        char** otherfs = other_filesystems;
-
        while (*otherfs) {
                snprintf(target, sizeof(target), "%s%s", prefix, *otherfs++);
-               hw_umount(target);
+               r = hw_umount(target);
+               if (r)
+                       return -1;
        }
 
+       // root
+       r = hw_umount(prefix);
+       if (r)
+               return -1;
+
        return 0;
 }
 
@@ -1007,6 +1033,8 @@ int hw_install_bootloader(struct hw_destination* dest, const char* output) {
                r = system_chroot(output, DESTINATION_MOUNT_PATH, cmd);
        }
 
+       hw_sync();
+
        return r;
 }