This flag is available for msdos and sun disklabels (for sun labels
it only controls the aligning of the end of the partition) */
PED_DISK_CYLINDER_ALIGNMENT=1,
+ /* This flag controls whether the boot flag of a GPT PMBR is set */
+ PED_DISK_GPT_PMBR_BOOT=2,
};
#define PED_DISK_FIRST_FLAG PED_DISK_CYLINDER_ALIGNMENT
-#define PED_DISK_LAST_FLAG PED_DISK_CYLINDER_ALIGNMENT
+#define PED_DISK_LAST_FLAG PED_DISK_GPT_PMBR_BOOT
/**
* Partition types
switch (flag) {
case PED_DISK_CYLINDER_ALIGNMENT:
return N_("cylinder_alignment");
-
+ case PED_DISK_GPT_PMBR_BOOT:
+ return N_("pmbr_boot");
default:
ped_exception_throw (
PED_EXCEPTION_BUG,
PedGeometry data_area;
int entry_count;
efi_guid_t uuid;
+ int pmbr_boot;
};
/* uses libparted's disk_specific field in PedPartition, to store our info */
gpt_disk_data->entry_count = GPT_DEFAULT_PARTITION_ENTRIES;
uuid_generate ((unsigned char *) &gpt_disk_data->uuid);
swap_uuid_and_efi_guid ((unsigned char *) (&gpt_disk_data->uuid));
+ gpt_disk_data->pmbr_boot = 0;
return disk;
error_free_disk:
*primary_gpt = NULL;
*backup_gpt = NULL;
PedDevice const *dev = disk->dev;
+ GPTDiskData *gpt_disk_data = disk->disk_specific;
+ LegacyMBR_t *mbr;
+
+ if (!ptt_read_sector (dev, 0, (void *)&mbr))
+ return 1;
+
+ if (mbr->PartitionRecord[0].BootIndicator == 0x80)
+ gpt_disk_data->pmbr_boot = 1;
+ free (mbr);
void *s1;
if (!ptt_read_sector (dev, 1, &s1))
#ifndef DISCOVER_ONLY
/* Write the protective MBR (to keep DOS happy) */
static int
-_write_pmbr (PedDevice *dev)
+_write_pmbr (PedDevice *dev, bool pmbr_boot)
{
/* The UEFI spec is not clear about what to do with the following
elements of the Protective MBR (pmbr): BootCode (0-440B),
pmbr->PartitionRecord[0].SizeInLBA = PED_CPU_TO_LE32 (0xFFFFFFFF);
else
pmbr->PartitionRecord[0].SizeInLBA = PED_CPU_TO_LE32 (dev->length - 1UL);
+ if (pmbr_boot)
+ pmbr->PartitionRecord[0].BootIndicator = 0x80;
int write_ok = ped_device_write (dev, pmbr, GPT_PMBR_LBA,
GPT_PMBR_SECTORS);
ptes_crc = efi_crc32 (ptes, ptes_bytes);
/* Write protective MBR */
- if (!_write_pmbr (disk->dev))
+ if (!_write_pmbr (disk->dev, gpt_disk_data->pmbr_boot))
goto error_free_ptes;
/* Write PTH and PTEs */
}
static int
+gpt_disk_set_flag (PedDisk *disk, PedDiskFlag flag, int state)
+{
+ GPTDiskData *gpt_disk_data = disk->disk_specific;
+ switch (flag)
+ {
+ case PED_DISK_GPT_PMBR_BOOT:
+ gpt_disk_data->pmbr_boot = state;
+ return 1;
+ default:
+ return 0;
+ }
+}
+
+static int
+gpt_disk_is_flag_available(const PedDisk *disk, PedDiskFlag flag)
+{
+ switch (flag)
+ {
+ case PED_DISK_GPT_PMBR_BOOT:
+ return 1;
+ default:
+ return 0;
+ }
+}
+
+static int
+gpt_disk_get_flag (const PedDisk *disk, PedDiskFlag flag)
+{
+ GPTDiskData *gpt_disk_data = disk->disk_specific;
+ switch (flag)
+ {
+ case PED_DISK_GPT_PMBR_BOOT:
+ return gpt_disk_data->pmbr_boot;
+ break;
+ default:
+ return 0;
+ }
+}
+
+static int
gpt_partition_set_flag (PedPartition *part, PedPartitionFlag flag, int state)
{
GPTPartitionData *gpt_part_data;
partition_set_name: gpt_partition_set_name,
partition_get_name: gpt_partition_get_name,
+ disk_set_flag: gpt_disk_set_flag,
+ disk_get_flag: gpt_disk_get_flag,
+ disk_is_flag_available: gpt_disk_is_flag_available,
PT_op_function_initializers (gpt)
};
}
static int
+do_disk_set (PedDevice** dev)
+{
+ PedDisk* disk;
+ PedDiskFlag flag;
+ int state;
+
+ disk = ped_disk_new (*dev);
+ if (!disk)
+ goto error;
+
+ if (!command_line_get_disk_flag (_("Flag to Invert?"), disk, &flag))
+ goto error_destroy_disk;
+ state = (ped_disk_get_flag (disk, flag) == 0 ? 1 : 0);
+
+ if (!is_toggle_mode) {
+ if (!command_line_get_state (_("New state?"), &state))
+ goto error_destroy_disk;
+ }
+
+ if (!ped_disk_set_flag (disk, flag, state))
+ goto error_destroy_disk;
+ if (!ped_disk_commit (disk))
+ goto error_destroy_disk;
+ ped_disk_destroy (disk);
+
+ if ((*dev)->type != PED_DEVICE_FILE)
+ disk_is_modified = 1;
+
+ return 1;
+
+error_destroy_disk:
+ ped_disk_destroy (disk);
+error:
+ return 0;
+}
+
+static int
do_set (PedDevice** dev)
{
PedDisk* disk;
}
static int
+do_disk_toggle (PedDevice **dev)
+{
+ int result;
+
+ is_toggle_mode = 1;
+ result = do_disk_set (dev);
+ is_toggle_mode = 0;
+
+ return result;
+}
+
+static int
do_toggle (PedDevice **dev)
{
int result;
str_list_create (_(device_msg), NULL), 1));
command_register (commands, command_create (
+ str_list_create_unique ("disk_set", _("disk_set"), NULL),
+ do_disk_set,
+ str_list_create (
+_("disk_set FLAG STATE change the FLAG on selected device"),
+NULL),
+ str_list_create (flag_msg, _(state_msg), NULL), 1));
+
+command_register (commands, command_create (
+ str_list_create_unique ("disk_toggle", _("disk_toggle"), NULL),
+ do_disk_toggle,
+ str_list_create (
+_("disk_toggle [FLAG] toggle the state of FLAG on "
+"selected device"),
+NULL),
+ str_list_create (flag_msg, NULL), 1));
+
+command_register (commands, command_create (
str_list_create_unique ("set", _("set"), NULL),
do_set,
str_list_create (
}
int
+command_line_get_disk_flag (const char* prompt, const PedDisk* disk,
+ PedDiskFlag* flag)
+{
+ StrList* opts = NULL;
+ PedPartitionFlag walk = 0;
+ char* flag_name;
+
+ while ( (walk = ped_disk_flag_next (walk)) ) {
+ if (ped_disk_is_flag_available (disk, walk)) {
+ const char* walk_name;
+
+ walk_name = ped_disk_flag_get_name (walk);
+ opts = str_list_append (opts, walk_name);
+ opts = str_list_append_unique (opts, _(walk_name));
+ }
+ }
+
+ flag_name = command_line_get_word (prompt, NULL, opts, 1);
+ str_list_destroy (opts);
+
+ if (flag_name) {
+ *flag = ped_disk_flag_get_by_name (flag_name);
+ free (flag_name);
+ return 1;
+ } else
+ return 0;
+}
+
+int
command_line_get_part_flag (const char* prompt, const PedPartition* part,
PedPartitionFlag* flag)
{
const PedFileSystemType*(* value));
extern int command_line_get_disk_type (const char* prompt,
const PedDiskType*(* value));
+extern int command_line_get_disk_flag (const char* prompt,
+ const PedDisk* disk,
+ PedDiskFlag* flag);
extern int command_line_get_part_flag (const char* prompt,
const PedPartition* part,
PedPartitionFlag* flag);