From 31ab97cfe0233191a73a1dd9cb7cd193451491da Mon Sep 17 00:00:00 2001 From: "Brian C. Lane" Date: Fri, 11 Aug 2017 08:37:11 -0700 Subject: [PATCH 46/48] libparted: Backport partition resize code This adds _blkpg_resize_partition, _dm_resize_partition, and adjust the current code to support it. Changes are somewhat extensive, since they also touch _disk_sync_part_table. This is based on code from commit f09ca967a0bc443b869a6fad5b5ffe8e95c3fe9a Related: rhbz#1423357 --- libparted/arch/linux.c | 673 +++++++++++++++++++++++++++++-------------------- 1 file changed, 403 insertions(+), 270 deletions(-) diff --git a/libparted/arch/linux.c b/libparted/arch/linux.c index fa329f4..6e78faf 100644 --- a/libparted/arch/linux.c +++ b/libparted/arch/linux.c @@ -288,6 +288,7 @@ struct blkdev_ioctl_param { static char* _device_get_part_path (PedDevice* dev, int num); static int _partition_is_mounted_by_path (const char* path); +static unsigned int _device_get_partition_range(PedDevice const* dev); static int _device_open (PedDevice* dev, int flags); static int _device_open_ro (PedDevice* dev); static int _device_close (PedDevice* dev); @@ -446,6 +447,17 @@ _is_blkext_major (int major) #ifdef ENABLE_DEVICE_MAPPER static int +_dm_task_run_wait (struct dm_task *task, uint32_t cookie) +{ + int rc = 0; + + rc = dm_task_run (task); + dm_udev_wait (cookie); + + return rc; +} + +static int _is_dm_major (int major) { return _major_type_in_devices (major, "device-mapper"); @@ -1521,6 +1533,7 @@ _flush_cache (PedDevice* dev) { LinuxSpecific* arch_specific = LINUX_SPECIFIC (dev); int i; + int lpn = _device_get_partition_range(dev); if (dev->read_only) return; @@ -1532,7 +1545,7 @@ _flush_cache (PedDevice* dev) if (_have_kern26()) return; - for (i = 1; i < 16; i++) { + for (i = 1; i < lpn; i++) { char* name; int fd; @@ -2268,28 +2281,63 @@ zasprintf (const char *format, ...) return r < 0 ? NULL : resultp; } +#ifdef ENABLE_DEVICE_MAPPER +static char * +dm_canonical_path (PedDevice const *dev) +{ + LinuxSpecific const *arch_specific = LINUX_SPECIFIC (dev); + + /* Get map name from devicemapper */ + struct dm_task *task = dm_task_create (DM_DEVICE_INFO); + if (!task) + goto err; + if (!dm_task_set_major_minor (task, arch_specific->major, + arch_specific->minor, 0)) + goto err; + if (!dm_task_run(task)) + goto err; + char *dev_name = zasprintf ("/dev/mapper/%s", dm_task_get_name (task)); + if (dev_name == NULL) + goto err; + dm_task_destroy (task); + return dev_name; +err: + return NULL; +} +#endif + static char* _device_get_part_path (PedDevice *dev, int num) { - size_t path_len = strlen (dev->path); - + char *devpath; + size_t path_len; char *result; +#ifdef ENABLE_DEVICE_MAPPER + devpath = (dev->type == PED_DEVICE_DM + ? dm_canonical_path (dev) : dev->path); +#else + devpath = dev->path; +#endif + path_len = strlen (devpath); /* Check for devfs-style /disc => /partN transformation unconditionally; the system might be using udev with devfs rules, and if not the test is harmless. */ - if (5 < path_len && !strcmp (dev->path + path_len - 5, "/disc")) { + if (5 < path_len && !strcmp (devpath + path_len - 5, "/disc")) { /* replace /disc with /part%d */ result = zasprintf ("%.*s/part%d", - (int) (path_len - 5), dev->path, num); + (int) (path_len - 5), devpath, num); } else { char const *p = (dev->type == PED_DEVICE_DAC960 || dev->type == PED_DEVICE_CPQARRAY || dev->type == PED_DEVICE_ATARAID || isdigit (dev->path[path_len - 1]) ? "p" : ""); - result = zasprintf ("%s%s%d", dev->path, p, num); + result = zasprintf ("%s%s%d", devpath, p, num); } - +#ifdef ENABLE_DEVICE_MAPPER + if (dev->type == PED_DEVICE_DM) + free (devpath); +#endif return result; } @@ -2438,6 +2486,62 @@ _blkpg_add_partition (PedDisk* disk, const PedPartition *part) if (!_blkpg_part_command (disk->dev, &linux_part, BLKPG_ADD_PARTITION)) { + return 0; + } + + return 1; +} + +static int +_blkpg_remove_partition (PedDisk* disk, int n) +{ + struct blkpg_partition linux_part; + + memset (&linux_part, 0, sizeof (linux_part)); + linux_part.pno = n; + return _blkpg_part_command (disk->dev, &linux_part, + BLKPG_DEL_PARTITION); +} + +#ifdef BLKPG_RESIZE_PARTITION +static int _blkpg_resize_partition (PedDisk* disk, const PedPartition *part) +{ + struct blkpg_partition linux_part; + char* dev_name; + + PED_ASSERT(disk != NULL); + PED_ASSERT(disk->dev->sector_size % PED_SECTOR_SIZE_DEFAULT == 0); + + dev_name = _device_get_part_path (disk->dev, part->num); + if (!dev_name) + return 0; + memset (&linux_part, 0, sizeof (linux_part)); + linux_part.start = part->geom.start * disk->dev->sector_size; + /* see fs/partitions/msdos.c:msdos_partition(): "leave room for LILO" */ + if (part->type & PED_PARTITION_EXTENDED) { + if (disk->dev->sector_size == 512) { + linux_part.length = 2; + PedPartition *walk; + /* if the second sector is claimed by a logical partition, + then there's just no room for lilo, so don't try to use it */ + for (walk = part->part_list; walk; walk = walk->next) { + if (walk->geom.start == part->geom.start+1) + linux_part.length = 1; + } + } else { + linux_part.length = 1; + } + linux_part.length *= disk->dev->sector_size; + } + else + linux_part.length = part->geom.length * disk->dev->sector_size; + linux_part.pno = part->num; + strncpy (linux_part.devname, dev_name, BLKPG_DEVNAMELTH); + + free (dev_name); + + if (!_blkpg_part_command (disk->dev, &linux_part, + BLKPG_RESIZE_PARTITION)) { return ped_exception_throw ( PED_EXCEPTION_ERROR, PED_EXCEPTION_IGNORE_CANCEL, @@ -2454,17 +2558,7 @@ _blkpg_add_partition (PedDisk* disk, const PedPartition *part) return 1; } - -static int -_blkpg_remove_partition (PedDisk* disk, int n) -{ - struct blkpg_partition linux_part; - - memset (&linux_part, 0, sizeof (linux_part)); - linux_part.pno = n; - return _blkpg_part_command (disk->dev, &linux_part, - BLKPG_DEL_PARTITION); -} +#endif /* Read the integer from /sys/block/DEV_BASE/ENTRY and set *VAL to that value, where DEV_BASE is the last component of DEV->path. @@ -2586,6 +2680,8 @@ static unsigned int _device_get_partition_range(PedDevice const* dev) { int range; + if (dev->type == PED_DEVICE_DM) + return MAX_NUM_PARTS; bool ok = _sysfs_int_entry_from_dev(dev, "ext_range", &range); if (!ok) @@ -2594,264 +2690,78 @@ _device_get_partition_range(PedDevice const* dev) return range > 1 ? range : 0; } -/* - * Sync the partition table in two step process: - * 1. Remove all of the partitions from the kernel's tables, but do not attempt - * removal of any partition for which the corresponding ioctl call fails. - * 2. Add all the partitions that we hold in disk, throwing a warning - * if we cannot because step 1 failed to remove it and it is not being - * added back with the same start and length. - * - * To achieve this two step process we must calculate the minimum number of - * maximum possible partitions between what linux supports and what the label - * type supports. EX: - * - * number=MIN(max_parts_supported_in_linux,max_parts_supported_in_msdos_tables) - */ -static int -_disk_sync_part_table (PedDisk* disk) -{ - PED_ASSERT(disk != NULL); - PED_ASSERT(disk->dev != NULL); - int lpn; - - unsigned int part_range = _device_get_partition_range(disk->dev); - - /* lpn = largest partition number. */ - if (ped_disk_get_max_supported_partition_count(disk, &lpn)) - lpn = PED_MIN(lpn, part_range); - else - lpn = part_range; - - /* Its not possible to support largest_partnum < 0. - * largest_partnum == 0 would mean does not support partitions. - * */ - if (lpn < 1) - return 0; - int ret = 0; - int *ok = calloc (lpn, sizeof *ok); - if (!ok) - return 0; - int *errnums = ped_malloc(sizeof(int) * lpn); - if (!errnums) - goto cleanup; - - /* Attempt to remove each and every partition, retrying for - up to max_sleep_seconds upon any failure due to EBUSY. */ - unsigned int sleep_microseconds = 10000; - unsigned int max_sleep_seconds = 1; - unsigned int n_sleep = (max_sleep_seconds - * 1000000 / sleep_microseconds); - int i; - for (i = 0; i < n_sleep; i++) { - if (i) - usleep (sleep_microseconds); - bool busy = false; - int j; - for (j = 0; j < lpn; j++) { - if (!ok[j]) { - ok[j] = _blkpg_remove_partition (disk, j + 1); - errnums[j] = errno; - if (!ok[j] && errnums[j] == EBUSY) - busy = true; - } - } - if (!busy) - break; - } - - for (i = 1; i <= lpn; i++) { - PedPartition *part = ped_disk_get_partition (disk, i); - if (part) { - if (!ok[i - 1] && errnums[i - 1] == EBUSY) { - unsigned long long length; - unsigned long long start; - /* get start and length of existing partition */ - if (!_kernel_get_partition_start_and_length(part, - &start, &length)) - goto cleanup; - if (start == part->geom.start - && length == part->geom.length) - ok[i - 1] = 1; - /* If the new partition is unchanged and the - existing one was not removed because it was - in use, then reset the error flag and do not - try to add it since it is already there. */ - continue; - } - - /* add the (possibly modified or new) partition */ - if (!_blkpg_add_partition (disk, part)) { - ped_exception_throw ( - PED_EXCEPTION_ERROR, - PED_EXCEPTION_RETRY_CANCEL, - _("Failed to add partition %d (%s)"), - i, strerror (errno)); - goto cleanup; - } - } - } - - char *bad_part_list = NULL; - /* now warn about any errors */ - for (i = 1; i <= lpn; i++) { - if (ok[i - 1] || errnums[i - 1] == ENXIO) - continue; - if (bad_part_list == NULL) { - bad_part_list = malloc (lpn * 5); - if (!bad_part_list) - goto cleanup; - bad_part_list[0] = 0; - } - sprintf (bad_part_list + strlen (bad_part_list), "%d, ", i); - } - if (bad_part_list == NULL) - ret = 1; - else { - bad_part_list[strlen (bad_part_list) - 2] = 0; - if (ped_exception_throw ( - PED_EXCEPTION_ERROR, - PED_EXCEPTION_IGNORE_CANCEL, - _("Partition(s) %s on %s have been written, but we have " - "been unable to inform the kernel of the change, " - "probably because it/they are in use. As a result, " - "the old partition(s) will remain in use. You " - "should reboot now before making further changes."), - bad_part_list, disk->dev->path) == PED_EXCEPTION_IGNORE) - ret = 1; - free (bad_part_list); - } - cleanup: - free (errnums); - free (ok); - return ret; -} - #ifdef ENABLE_DEVICE_MAPPER static int -_dm_remove_map_name(char *name) +_dm_remove_partition(PedDisk* disk, int partno) { - struct dm_task *task = NULL; int rc = 0; uint32_t cookie = 0; + char *part_name = _device_get_part_path (disk->dev, partno); - task = dm_task_create(DM_DEVICE_REMOVE); + int fd = open (part_name, O_RDONLY | O_EXCL); + if (fd == -1) { + if (errno == ENOENT) + errno = ENXIO; /* nothing to remove, device already doesn't exist */ + goto err; + } + close (fd); + struct dm_task *task = dm_task_create(DM_DEVICE_REMOVE); if (!task) - return 1; - - dm_task_set_name (task, name); - if (!dm_task_set_cookie(task, &cookie, 0)) - goto err; - - rc = dm_task_run(task); - dm_udev_wait(cookie); + goto err; + dm_task_set_name (task, part_name); + if (!dm_task_set_cookie (task, &cookie, 0)) + goto err; + rc = _dm_task_run_wait (task, cookie); dm_task_update_nodes(); -err: dm_task_destroy(task); - if (!rc) - return 1; - - return 0; +err: + free (part_name); + return rc; } -static int -_dm_is_part (struct dm_info *this, char *name) +static bool +_dm_get_partition_start_and_length(PedPartition const *part, + unsigned long long *start, + unsigned long long *length) { struct dm_task* task = NULL; - struct dm_info* info = alloca(sizeof *info); - struct dm_deps* deps = NULL; int rc = 0; - unsigned int i; - task = dm_task_create(DM_DEVICE_DEPS); - if (!task) + if (!(task = dm_task_create(DM_DEVICE_TABLE))) return 0; - - dm_task_set_name(task, name); - if (!dm_task_run(task)) + char *path = _device_get_part_path (part->disk->dev, part->num); + PED_ASSERT(path); + /* libdevmapper likes to complain on stderr instead of quietly + returning ENOENT or ENXIO, so try to stat first */ + struct stat st; + if (stat(path, &st)) goto err; - - memset(info, '\0', sizeof *info); - dm_task_get_info(task, info); - if (!info->exists) + dm_task_set_name(task, path); + if (!dm_task_run(task)) goto err; - deps = dm_task_get_deps(task); - if (!deps) + int major, minor; + char *params; + char *target_type; + dm_get_next_target(task, NULL, (uint64_t *)start, (uint64_t *)length, &target_type, ¶ms); + if (sscanf (params, "%d:%d %Ld", &major, &minor, start) != 3) goto err; + rc = 1; - for (i = 0; i < deps->count; i++) { - unsigned int ma = major(deps->device[i]), - mi = minor(deps->device[i]); - - if (ma == this->major && mi == this->minor) - rc = 1; - } - + /* device-mapper uses 512b units, make sure we return length and start in terms of the device's + * sector size. + */ + *start /= (part->disk->dev->sector_size / PED_SECTOR_SIZE_DEFAULT); + *length /= (part->disk->dev->sector_size / PED_SECTOR_SIZE_DEFAULT); err: + free (path); dm_task_destroy(task); return rc; } -static int -_dm_remove_parts (PedDevice* dev) -{ - struct dm_task* task = NULL; - struct dm_info* info = alloca(sizeof *info); - struct dm_names* names = NULL; - unsigned int next = 0; - int rc; - LinuxSpecific* arch_specific = LINUX_SPECIFIC (dev); - - task = dm_task_create(DM_DEVICE_LIST); - if (!task) - goto err; - - if (!dm_task_set_major_minor (task, arch_specific->major, - arch_specific->minor, 0)) - goto err; - - if (!dm_task_run(task)) - goto err; - - memset(info, '\0', sizeof *info); - dm_task_get_info(task, info); - if (!info->exists) - goto err; - - names = dm_task_get_names(task); - if (!names) - goto err; - - rc = 0; - do { - names = (void *) ((char *) names + next); - - if (_dm_is_part(info, names->name)) - rc += _dm_remove_map_name(names->name); - - next = names->next; - } while (next); - - dm_task_update_nodes(); - dm_task_destroy(task); - task = NULL; - - if (!rc) - return 1; -err: - if (task) - dm_task_destroy(task); - ped_exception_throw (PED_EXCEPTION_WARNING, PED_EXCEPTION_IGNORE, - _("parted was unable to re-read the partition " - "table on %s (%s). This means Linux won't know " - "anything about the modifications you made. "), - dev->path, strerror (errno)); - return 0; -} static int -_dm_add_partition (PedDisk* disk, PedPartition* part) +_dm_add_partition (PedDisk* disk, const PedPartition* part) { char* vol_name = NULL; const char* dev_name = NULL; @@ -2908,9 +2818,8 @@ _dm_add_partition (PedDisk* disk, PedPartition* part) "linear", params); if (!dm_task_set_cookie(task, &cookie, 0)) goto err; - if (dm_task_run (task)) { + if (_dm_task_run_wait (task, cookie)) { //printf("0 %ld linear %s\n", part->geom.length, params); - dm_udev_wait(cookie); dm_task_update_nodes(); dm_task_destroy(task); free(params); @@ -2918,8 +2827,7 @@ _dm_add_partition (PedDisk* disk, PedPartition* part) free(vol_name); return 1; } else { - dm_udev_wait(cookie); - _dm_remove_map_name(vol_name); + _dm_remove_partition (disk, part->num); } err: dm_task_update_nodes(); @@ -2932,30 +2840,259 @@ err: } static int -_dm_reread_part_table (PedDisk* disk) +_dm_resize_partition (PedDisk* disk, const PedPartition* part) { - int largest_partnum = ped_disk_get_last_partition_num (disk); - int rc = 1; - int i; + LinuxSpecific* arch_specific = LINUX_SPECIFIC (disk->dev); + char* params = NULL; + char* vol_name = NULL; + const char* dev_name = NULL; + uint32_t cookie = 0; + int rc = 0; - sync(); - if (!_dm_remove_parts(disk->dev)) - rc = 0; + /* Get map name from devicemapper */ + struct dm_task *task = dm_task_create (DM_DEVICE_INFO); + if (!task) + goto err; - for (i = 1; i <= largest_partnum; i++) { - PedPartition* part; + if (!dm_task_set_major_minor (task, arch_specific->major, + arch_specific->minor, 0)) + goto err; - part = ped_disk_get_partition (disk, i); - if (!part) - continue; + if (!dm_task_run(task)) + goto err; + + dev_name = dm_task_get_name (task); + size_t name_len = strlen (dev_name); + vol_name = zasprintf ("%s%s%d", + dev_name, + isdigit (dev_name[name_len - 1]) ? "p" : "", + part->num); + if (vol_name == NULL) + goto err; + + /* Caution: dm_task_destroy frees dev_name. */ + dm_task_destroy (task); + task = NULL; + + /* device-mapper uses 512b units, not the device's sector size */ + if ( ! (params = zasprintf ("%d:%d %lld", arch_specific->major, + arch_specific->minor, + part->geom.start * (disk->dev->sector_size / PED_SECTOR_SIZE_DEFAULT)))) + goto err; + + task = dm_task_create (DM_DEVICE_RELOAD); + if (!task) + goto err; - if (!_dm_add_partition (disk, part)) - rc = 0; + dm_task_set_name (task, vol_name); + /* device-mapper uses 512b units, not the device's sector size */ + dm_task_add_target (task, 0, part->geom.length * (disk->dev->sector_size / PED_SECTOR_SIZE_DEFAULT), + "linear", params); + /* NOTE: DM_DEVICE_RELOAD doesn't generate udev events, so no cookie is needed (it will freeze). + * DM_DEVICE_RESUME does, so get a cookie and synchronize with udev. + */ + if (dm_task_run (task)) { + dm_task_destroy (task); + task = dm_task_create (DM_DEVICE_RESUME); + if (!task) + goto err; + dm_task_set_name (task, vol_name); + if (!dm_task_set_cookie (task, &cookie, 0)) + goto err; + if (_dm_task_run_wait (task, cookie)) { + rc = 1; + } } +err: + dm_task_update_nodes(); + if (task) + dm_task_destroy (task); + free (params); + free (vol_name); return rc; } + #endif +/* + * Sync the partition table in two step process: + * 1. Remove all of the partitions from the kernel's tables, but do not attempt + * removal of any partition for which the corresponding ioctl call fails. + * 2. Add all the partitions that we hold in disk, throwing a warning + * if we cannot because step 1 failed to remove it and it is not being + * added back with the same start and length. + * + * To achieve this two step process we must calculate the minimum number of + * maximum possible partitions between what linux supports and what the label + * type supports. EX: + * + * number=MIN(max_parts_supported_in_linux,max_parts_supported_in_msdos_tables) + */ +static int +_disk_sync_part_table (PedDisk* disk) +{ + PED_ASSERT(disk != NULL); + PED_ASSERT(disk->dev != NULL); + int lpn, lpn2; + unsigned int part_range = _device_get_partition_range(disk->dev); + int (*add_partition)(PedDisk* disk, const PedPartition *part); + int (*resize_partition)(PedDisk* disk, const PedPartition *part); + int (*remove_partition)(PedDisk* disk, int partno); + bool (*get_partition_start_and_length)(PedPartition const *part, + unsigned long long *start, + unsigned long long *length); + + +#ifdef ENABLE_DEVICE_MAPPER + if (disk->dev->type == PED_DEVICE_DM) { + add_partition = _dm_add_partition; + remove_partition = _dm_remove_partition; + resize_partition = _dm_resize_partition; + get_partition_start_and_length = _dm_get_partition_start_and_length; + } else +#endif + { + add_partition = _blkpg_add_partition; + remove_partition = _blkpg_remove_partition; +#ifdef BLKPG_RESIZE_PARTITION + resize_partition = _blkpg_resize_partition; +#else + resize_partition = NULL; +#endif + get_partition_start_and_length = _kernel_get_partition_start_and_length; + } + + /* lpn = largest partition number. + * for remove pass, use greater of device or label limit */ + if (ped_disk_get_max_supported_partition_count(disk, &lpn)) + lpn = PED_MAX(lpn, part_range); + else + lpn = part_range; + /* for add pass, use lesser of device or label limit */ + if (ped_disk_get_max_supported_partition_count(disk, &lpn2)) + lpn2 = PED_MIN(lpn2, part_range); + else + lpn2 = part_range; + /* Its not possible to support largest_partnum < 0. + * largest_partnum == 0 would mean does not support partitions. + * */ + if (lpn < 1) + return 0; + int ret = 0; + int *ok = calloc (lpn, sizeof *ok); + if (!ok) + return 0; + int *errnums = ped_malloc(sizeof(int) * lpn); + if (!errnums) + goto cleanup; + + int i; + /* remove old partitions first */ + for (i = 1; i <= lpn; i++) { + PedPartition *part = ped_disk_get_partition (disk, i); + if (part) { + unsigned long long length; + unsigned long long start; + /* get start and length of existing partition */ + if (get_partition_start_and_length(part, + &start, &length) + && start == part->geom.start + && (length == part->geom.length + || (resize_partition && part->num < lpn2))) + { + /* partition is unchanged, or will be resized so nothing to do */ + ok[i - 1] = 1; + continue; + } + } + /* Attempt to remove the partition, retrying for + up to max_sleep_seconds upon any failure due to EBUSY. */ + unsigned int sleep_microseconds = 10000; + unsigned int max_sleep_seconds = 1; + unsigned int n_sleep = (max_sleep_seconds + * 1000000 / sleep_microseconds); + do { + ok[i - 1] = remove_partition (disk, i); + errnums[i - 1] = errno; + if (ok[i - 1] || errnums[i - 1] != EBUSY) + break; + usleep (sleep_microseconds); + } while (n_sleep--); + if (!ok[i - 1] && errnums[i - 1] == ENXIO) + ok[i - 1] = 1; /* it already doesn't exist */ + } + lpn = lpn2; + /* don't actually add partitions for loop */ + if (strcmp (disk->type->name, "loop") == 0) + lpn = 0; + for (i = 1; i <= lpn; i++) { + PedPartition *part = ped_disk_get_partition (disk, i); + if (!part) + continue; + unsigned long long length; + unsigned long long start; + /* get start and length of existing partition */ + if (get_partition_start_and_length(part, + &start, &length) + && start == part->geom.start) + { + if (length == part->geom.length) { + ok[i - 1] = 1; + /* partition is unchanged, so nothing to do */ + continue; + } + if (resize_partition + && start == part->geom.start) + { + /* try to resize */ + if (resize_partition (disk, part)) { + ok[i - 1] = 1; + continue; + } + } + } + /* add the (possibly modified or new) partition */ + if (!add_partition (disk, part)) { + ok[i - 1] = 0; + errnums[i - 1] = errno; + } + } + + char *bad_part_list = NULL; + /* now warn about any errors */ + for (i = 1; i <= lpn; i++) { + if (ok[i - 1] || errnums[i - 1] == ENXIO) + continue; + if (bad_part_list == NULL) { + bad_part_list = malloc (lpn * 5); + if (!bad_part_list) + goto cleanup; + bad_part_list[0] = 0; + } + sprintf (bad_part_list + strlen (bad_part_list), "%d, ", i); + } + if (bad_part_list == NULL) + ret = 1; + else { + bad_part_list[strlen (bad_part_list) - 2] = 0; + if (ped_exception_throw ( + PED_EXCEPTION_ERROR, + PED_EXCEPTION_IGNORE_CANCEL, + _("Partition(s) %s on %s have been written, but we have " + "been unable to inform the kernel of the change, " + "probably because it/they are in use. As a result, " + "the old partition(s) will remain in use. You " + "should reboot now before making further changes."), + bad_part_list, disk->dev->path) == PED_EXCEPTION_IGNORE) + ret = 1; + free (bad_part_list); + } + cleanup: + free (errnums); + free (ok); + return ret; +} + static int _have_blkpg () { @@ -2973,10 +3110,6 @@ _have_blkpg () static int linux_disk_commit (PedDisk* disk) { -#ifdef ENABLE_DEVICE_MAPPER - if (disk->dev->type == PED_DEVICE_DM) - return _dm_reread_part_table (disk); -#endif if (disk->dev->type != PED_DEVICE_FILE) { /* We now require BLKPG support. If this assertion fails, -- 2.9.4