NULL
};
-static int system_chroot(const char* path, const char* cmd) {
+static int system_chroot(const char* output, const char* path, const char* cmd) {
char chroot_cmd[STRING_SIZE];
snprintf(chroot_cmd, sizeof(chroot_cmd), "/usr/sbin/chroot %s %s", path, cmd);
- return mysystem(chroot_cmd);
+ return mysystem(output, chroot_cmd);
}
struct hw* hw_init() {
return bytes_written;
}
-int hw_create_partitions(struct hw_destination* dest) {
+static int try_open(const char* path) {
+ FILE* f = fopen(path, "r");
+ if (f) {
+ fclose(f);
+ return 0;
+ }
+
+ return -1;
+}
+
+int hw_create_partitions(struct hw_destination* dest, const char* output) {
// Before we write a new partition table to the disk, we will erase
// the first couple of megabytes at the beginning of the device to
// get rid of all left other things like bootloaders and partition tables.
asprintf(&cmd, "%s disk_set pmbr_boot on", cmd);
}
- r = mysystem(cmd);
+ r = mysystem(output, cmd);
// Wait until the system re-read the partition table
if (r == 0) {
while (counter-- > 0) {
sleep(1);
- if (*dest->part_bootldr && (access(dest->part_bootldr, R_OK) != 0))
+ if (*dest->part_bootldr && (try_open(dest->part_bootldr) != 0))
continue;
- if (*dest->part_boot && (access(dest->part_boot, R_OK) != 0))
+ if (*dest->part_boot && (try_open(dest->part_boot) != 0))
continue;
- if (*dest->part_swap && (access(dest->part_swap, R_OK) != 0))
+ if (*dest->part_swap && (try_open(dest->part_swap) != 0))
continue;
- if (*dest->part_root && (access(dest->part_root, R_OK) != 0))
+ if (*dest->part_root && (try_open(dest->part_root) != 0))
continue;
- if (*dest->part_data && (access(dest->part_data, R_OK) != 0))
+ if (*dest->part_data && (try_open(dest->part_data) != 0))
continue;
// All partitions do exist, exiting the loop.
return r;
}
-static int hw_format_filesystem(const char* path, int fs) {
+static int hw_format_filesystem(const char* path, int fs, const char* output) {
char cmd[STRING_SIZE] = "\0";
// Swap
assert(*cmd);
- int r = mysystem(cmd);
+ int r = mysystem(output, cmd);
return r;
}
-int hw_create_filesystems(struct hw_destination* dest) {
+int hw_create_filesystems(struct hw_destination* dest, const char* output) {
int r;
// boot
if (*dest->part_boot) {
- r = hw_format_filesystem(dest->part_boot, dest->filesystem);
+ r = hw_format_filesystem(dest->part_boot, dest->filesystem, output);
if (r)
return r;
}
// swap
if (*dest->part_swap) {
- r = hw_format_filesystem(dest->part_swap, HW_FS_SWAP);
+ r = hw_format_filesystem(dest->part_swap, HW_FS_SWAP, output);
if (r)
return r;
}
// root
- r = hw_format_filesystem(dest->part_root, dest->filesystem);
+ r = hw_format_filesystem(dest->part_root, dest->filesystem, output);
if (r)
return r;
// data
if (*dest->part_data) {
- r = hw_format_filesystem(dest->part_data, dest->filesystem);
+ r = hw_format_filesystem(dest->part_data, dest->filesystem, output);
if (r)
return r;
}
}
int hw_umount_filesystems(struct hw_destination* dest, const char* prefix) {
+ // Write all buffers to disk before umounting
+ hw_sync();
+
// boot
if (*dest->part_boot) {
hw_umount(dest->part_boot);
return 0;
}
-int hw_setup_raid(struct hw_destination* dest) {
+static int hw_destroy_raid_superblocks(const struct hw_destination* dest, const char* output) {
+ char cmd[STRING_SIZE];
+
+ hw_stop_all_raid_arrays(output);
+ hw_stop_all_raid_arrays(output);
+
+ if (dest->disk1) {
+ snprintf(cmd, sizeof(cmd), "/sbin/mdadm --zero-superblock %s", dest->disk1->path);
+ mysystem(output, cmd);
+ }
+
+ if (dest->disk2) {
+ snprintf(cmd, sizeof(cmd), "/sbin/mdadm --zero-superblock %s", dest->disk2->path);
+ mysystem(output, cmd);
+ }
+
+ return 0;
+}
+
+int hw_setup_raid(struct hw_destination* dest, const char* output) {
char* cmd = NULL;
int r;
assert(dest->is_raid);
+ // Stop all RAID arrays that might be around (again).
+ // It seems that there is some sort of race-condition with udev re-enabling
+ // the raid arrays and therefore locking the disks.
+ r = hw_destroy_raid_superblocks(dest, output);
+
asprintf(&cmd, "echo \"y\" | /sbin/mdadm --create --verbose --metadata=%s --auto=mdp %s",
RAID_METADATA, dest->path);
return r;
}
- r = mysystem(cmd);
+ r = mysystem(output, cmd);
free(cmd);
// Wait a moment until the device has been properly brought up
// If the raid device has not yet been properly brought up,
// opening it will fail with the message: Device or resource busy
// Hence we will wait a bit until it becomes usable.
- FILE* f = fopen(dest->path, "r");
- if (f) {
- fclose(f);
+ if (try_open(dest->path) == 0)
break;
- }
}
}
return r;
}
-int hw_stop_all_raid_arrays() {
- return mysystem("/sbin/mdadm --stop --scan");
+int hw_stop_all_raid_arrays(const char* output) {
+ return mysystem(output, "/sbin/mdadm --stop --scan --verbose");
}
-int hw_install_bootloader(struct hw_destination* dest) {
+int hw_install_bootloader(struct hw_destination* dest, const char* output) {
char cmd[STRING_SIZE];
int r;
// Generate configuration file
snprintf(cmd, sizeof(cmd), "/usr/sbin/grub-mkconfig -o /boot/grub/grub.cfg");
- r = system_chroot(DESTINATION_MOUNT_PATH, cmd);
+ r = system_chroot(output, DESTINATION_MOUNT_PATH, cmd);
if (r)
return r;
if (dest->is_raid) {
snprintf(cmd, sizeof(cmd), "%s %s", cmd_grub, dest->disk1->path);
- r = system_chroot(DESTINATION_MOUNT_PATH, cmd);
+ r = system_chroot(output, DESTINATION_MOUNT_PATH, cmd);
if (r)
return r;
snprintf(cmd, sizeof(cmd), "%s %s", cmd_grub, dest->disk2->path);
- r = system_chroot(DESTINATION_MOUNT_PATH, cmd);
+ r = system_chroot(output, DESTINATION_MOUNT_PATH, cmd);
} else {
snprintf(cmd, sizeof(cmd), "%s %s", cmd_grub, dest->path);
- r = system_chroot(DESTINATION_MOUNT_PATH, cmd);
+ r = system_chroot(output, DESTINATION_MOUNT_PATH, cmd);
}
return r;