When parted commands like print, delete and others along with create command, are run continuously, at some point of time a race has been noticed between the create command and systemd.
The parted create command when tries to sync the partition table by calling "_disk_sync_part_table()" function, it will try to fetch the start and length of the partition. For this, it will try to open the sysfs entry of the partition (for example /sys/block/loop0/loop0p1/start). At the same time, if systemd calls rescan_partitions, then the sysfs entries will disapper as these partitions will be removed and added. Now, since the parted create command is trying to open the same sysfs entry to get the start and length, it will fail when systemd removes the partition and hence the parted command thinks that this is a new partition and will try to add the existing partition again by calling BLKPG_ADD_PARTITION ioctl. At kernel level, the kernel ioctl code will check for the overlap. As the partition was already existing, it will return EBUSY to the userspace. This is causing the parted command to throw the below exception: "Error: Partition(s) 1 on /dev/loop276070 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." This can be fixed by retrying to open the sysfs entry of the partition device with few retries, if the open call fails. Signed-off-by: Gulam Mohamed <gulam.moha...@oracle.com> --- libparted/arch/linux.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/libparted/arch/linux.c b/libparted/arch/linux.c index ccbba8656bc7..375e36cdd5d0 100644 --- a/libparted/arch/linux.c +++ b/libparted/arch/linux.c @@ -2735,6 +2735,12 @@ _sysfs_ull_entry_from_part(PedPartition const* part, const char *entry, { char path[128]; char *part_name = _device_get_part_path (part->disk->dev, part->num); + bool ok = false; + FILE *fp = NULL; + unsigned int sleep_microseconds = 10000; + unsigned int max_sleep_seconds = 1; + unsigned int n_sleep = (max_sleep_seconds + * 1000000 / sleep_microseconds); if (!part_name) return false; @@ -2744,12 +2750,16 @@ _sysfs_ull_entry_from_part(PedPartition const* part, const char *entry, free(part_name); if (r < 0 || r >= sizeof(path)) return false; - - FILE *fp = fopen(path, "r"); + do { + fp = fopen(path, "r"); + if (fp) + break; + usleep (sleep_microseconds); + } while(n_sleep--); if (!fp) return false; - bool ok = fscanf(fp, "%llu", val) == 1; + ok = fscanf(fp, "%llu", val) == 1; fclose(fp); return ok; -- 2.43.5