}
static int hw_calculate_partition_table(struct hw_destination* dest) {
+ char path[DEV_SIZE];
+ int part_idx = 1;
+
+ snprintf(path, sizeof(path), "%s%s", dest->path, (dest->is_raid) ? "p" : "");
+ dest->part_boot_idx = 0;
+
// Determine the size of the target block device
if (dest->is_raid) {
dest->size = (dest->disk1->size >= dest->disk2->size) ?
dest->size = dest->disk1->size;
}
+ // Determine partition table
+ dest->part_table = HW_PART_TABLE_MSDOS;
+
+ // Disks over 2TB need to use GPT
+ if (dest->size >= MB2BYTES(2047 * 1024))
+ dest->part_table = HW_PART_TABLE_GPT;
+
+ // We also use GPT on raid disks by default
+ else if (dest->is_raid)
+ dest->part_table = HW_PART_TABLE_GPT;
+
+ // When using GPT, GRUB2 needs a little bit of space to put
+ // itself in.
+ if (dest->part_table = HW_PART_TABLE_GPT) {
+ snprintf(dest->part_bootldr, sizeof(dest->part_bootldr),
+ "%s%d", path, part_idx);
+
+ dest->size_bootldr = MB2BYTES(4);
+
+ dest->part_boot_idx = part_idx++;
+ } else {
+ *dest->part_bootldr = '\0';
+ dest->size_bootldr = 0;
+ }
+
dest->size_boot = hw_boot_size(dest);
dest->size_swap = hw_swap_size(dest);
dest->size_root = hw_root_size(dest);
// Determine the size of the data partition.
- unsigned long long used_space = dest->size_boot + dest->size_swap + dest->size_root;
+ unsigned long long used_space = dest->size_bootldr + dest->size_boot
+ + dest->size_swap + dest->size_root;
// Disk is way too small
if (used_space >= dest->size)
}
// Set partition names
- char path[DEV_SIZE];
- int part_idx = 1;
-
- snprintf(path, sizeof(path), "%s%s", dest->path, (dest->is_raid) ? "p" : "");
-
if (dest->size_boot > 0) {
- dest->part_boot_idx = part_idx;
+ if (dest->part_boot_idx == 0)
+ dest->part_boot_idx = part_idx;
snprintf(dest->part_boot, sizeof(dest->part_boot), "%s%d", path, part_idx++);
} else
*dest->part_swap = '\0';
// There is always a root partition
- if (!*dest->part_boot)
+ if (dest->part_boot_idx == 0)
dest->part_boot_idx = part_idx;
snprintf(dest->part_root, sizeof(dest->part_root), "%s%d", path, part_idx++);
else
*dest->part_data = '\0';
- // Determine partition table
- dest->part_table = HW_PART_TABLE_MSDOS;
-
- // Disks over 2TB need to use GPT
- if (dest->size >= MB2BYTES(2047 * 1024))
- dest->part_table = HW_PART_TABLE_GPT;
-
- // We also use GPT on raid disks by default
- else if (dest->is_raid)
- dest->part_table = HW_PART_TABLE_GPT;
-
return 0;
}
unsigned long long part_start = 1 * 1024 * 1024; // 1MB
+ if (*dest->part_bootldr) {
+ asprintf(&cmd, "%s mkpart %s ext2 %lluMB %lluMB", cmd,
+ (dest->part_table == HW_PART_TABLE_GPT) ? "BOOTLDR" : "primary",
+ BYTES2MB(part_start), BYTES2MB(part_start + dest->size_bootldr));
+
+ part_start += dest->size_bootldr;
+ }
+
if (*dest->part_boot) {
asprintf(&cmd, "%s mkpart %s ext2 %lluMB %lluMB", cmd,
(dest->part_table == HW_PART_TABLE_GPT) ? "BOOT" : "primary",
asprintf(&cmd, "%s set %d boot on", cmd, dest->part_boot_idx);
} else if (dest->part_table == HW_PART_TABLE_GPT) {
+ if (*dest->part_bootldr) {
+ asprintf(&cmd, "%s set %d bios_grub on", cmd, dest->part_boot_idx);
+ }
asprintf(&cmd, "%s disk_set pmbr_boot on", cmd);
}
while (counter-- > 0) {
sleep(1);
+ if (*dest->part_bootldr && (access(dest->part_bootldr, R_OK) != 0))
+ continue;
+
if (*dest->part_boot && (access(dest->part_boot, R_OK) != 0))
continue;
char cmd_grub[STRING_SIZE];
snprintf(cmd_grub, sizeof(cmd_grub), "/usr/sbin/grub-install --no-floppy --recheck");
- if (dest->is_raid) {
+ if (dest->is_raid && (dest->part_table == HW_PART_TABLE_MSDOS)) {
snprintf(cmd, sizeof(cmd), "%s %s", cmd_grub, dest->disk1->path);
r = system_chroot(DESTINATION_MOUNT_PATH, cmd);
if (r)
}
fprintf(flog, "Destination drive: %s\n", destination->path);
- fprintf(flog, " boot: %s (%lluMB)\n", destination->part_boot, BYTES2MB(destination->size_boot));
- fprintf(flog, " swap: %s (%lluMB)\n", destination->part_swap, BYTES2MB(destination->size_swap));
- fprintf(flog, " root: %s (%lluMB)\n", destination->part_root, BYTES2MB(destination->size_root));
- fprintf(flog, " data: %s (%lluMB)\n", destination->part_data, BYTES2MB(destination->size_data));
+ fprintf(flog, " bootldr: %s (%lluMB)\n", destination->part_bootldr, BYTES2MB(destination->size_bootldr));
+ fprintf(flog, " boot : %s (%lluMB)\n", destination->part_boot, BYTES2MB(destination->size_boot));
+ fprintf(flog, " swap : %s (%lluMB)\n", destination->part_swap, BYTES2MB(destination->size_swap));
+ fprintf(flog, " root : %s (%lluMB)\n", destination->part_root, BYTES2MB(destination->size_root));
+ fprintf(flog, " data : %s (%lluMB)\n", destination->part_data, BYTES2MB(destination->size_data));
// Warn the user if there is not enough space to create a swap partition
if (!unattended && !*destination->part_swap) {