Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
openSUSE:Evergreen:11.2:Test
parted
retry-blkpg-ioctl-and-improve-error-handling.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File retry-blkpg-ioctl-and-improve-error-handling.patch of Package parted
--- libparted/arch/linux.c | 88 +++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 81 insertions(+), 7 deletions(-) Index: parted-1.9.0/libparted/arch/linux.c =================================================================== --- parted-1.9.0.orig/libparted/arch/linux.c 2010-04-12 09:33:46.000000000 +0200 +++ parted-1.9.0/libparted/arch/linux.c 2010-04-12 09:51:13.000000000 +0200 @@ -2110,7 +2110,9 @@ _device_get_part_path (PedDevice* dev, i /* replace /disc with /path%d */ strcpy (result, dev->path); snprintf (result + path_len - 5, 16, "/part%d", num); - } else if (dev->type == PED_DEVICE_DAC960 + } else if (!strncmp (dev->path, "/dev/md", 7 )) + snprintf (result, result_len, "%sp%d", dev->path, num); + else if (dev->type == PED_DEVICE_DAC960 || dev->type == PED_DEVICE_CPQARRAY || dev->type == PED_DEVICE_ATARAID || dev->type == PED_DEVICE_DM @@ -2352,15 +2354,28 @@ _disk_sync_part_table (PedDisk* disk) if(lpn < 0) return 0; + int ret = 0; int *rets = ped_malloc(sizeof(int) * lpn); + if (!rets) + return 0; int *errnums = ped_malloc(sizeof(int) * lpn); - int ret = 1; + if (!errnums) + goto free_rets; int i; for (i = 1; i <= lpn; i++) { + /* try to BLKPG_REMOVE the partition + * retry once more after short sleep if EBUSY + */ + rets[i - 1] = _blkpg_remove_partition (disk, i); + errnums[i - 1] = errno; + + if ( !rets[i - 1] && errnums[i - 1] == EBUSY ) { + sleep(1); rets[i - 1] = _blkpg_remove_partition (disk, i); errnums[i - 1] = errno; } + } for (i = 1; i <= lpn; i++) { const PedPartition *part = ped_disk_get_partition (disk, i); @@ -2369,17 +2384,76 @@ _disk_sync_part_table (PedDisk* disk) * doesn't matter anyway, because users shouldn't be * changing mounted partitions anyway... */ - if (!rets[i - 1] && errnums[i - 1] == EBUSY) + if (!rets[i - 1] && errnums[i - 1] == EBUSY) { + struct hd_geometry geom; + int fd; + unsigned long long length = 0; + /* get start and length of existing partition */ + char *dev_name = _device_get_part_path (disk->dev, i); + if (!dev_name) + goto free_errnums; + fd = open (dev_name, O_RDONLY); + free (dev_name); + if (fd == -1 || + ioctl (fd, HDIO_GETGEO, &geom) || + ioctl (fd, BLKGETSIZE64, &length)) { + if( fd != -1 ) + close (fd); + /* continue with error flag set */ continue; + } + length /= disk->dev->sector_size; + close (fd); + if (geom.start == part->geom.start && + length == part->geom.length) + rets[i - 1] = 1; + /* if the new partition is unchanged and the exiting + * one was not removed because it was in use, then + * reset the error flag and skip adding it + * since it is already there + */ + continue; + } + if (!_blkpg_add_partition (disk, part)) { + ped_exception_throw ( + PED_EXCEPTION_ERROR, + PED_EXCEPTION_RETRY_CANCEL, + _("Failed to add partition %i (%s)"), + i, strerror (errno)); + goto free_errnums; + } - /* add the (possibly modified or new) partition */ - if (!_blkpg_add_partition (disk, part)) - ret = 0; } } - free (rets); + char *parts = ped_malloc (lpn * 5); + if (!parts) + goto free_errnums; + parts[0] = 0; + /* now warn about any errors */ + for (i = 1; i <= lpn; i++) + if (!rets[i - 1] && errnums[i - 1] == EBUSY) + sprintf (parts + strlen (parts), "%i, ", i); + if (parts[0]) { + parts[strlen (parts) - 2] = 0; + ped_exception_throw ( + PED_EXCEPTION_WARNING, + PED_EXCEPTION_IGNORE, + _("Parted could not inform the kernel about eventual changes to " + "partitions(s) %s on %s. This most likely means that the partition(s) " + "is/are in use and parted could not determine whether the partition(s) " + "have changed. As a result, the old partition(s) will remain in use until " + "after reboot. If you know the partition(s) listed above have not changed, " + "you can ignore this warning. Otherwise, you should reboot now before making " + "further changes."), + parts, disk->dev->path); + } + free (parts); + ret = 1; +free_errnums: free (errnums); +free_rets: + free (rets); return ret; }
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor