Login
[x]
Log in using an account from:
Fedora Account System
Red Hat Associate
Red Hat Customer
Or login using a Red Hat Bugzilla account
Forgot Password
Login:
Hide Forgot
Create an Account
Red Hat Bugzilla – Attachment 583438 Details for
Bug 820473
RUNNING PARTED IN PARALLEL ON DIFFERENT DISKS MAY FAIL UNDER LOAD
[?]
New
Simple Search
Advanced Search
My Links
Browse
Requests
Reports
Current State
Search
Tabular reports
Graphical reports
Duplicates
Other Reports
User Changes
Plotly Reports
Bug Status
Bug Severity
Non-Defaults
|
Product Dashboard
Help
Page Help!
Bug Writing Guidelines
What's new
Browser Support Policy
5.0.4.rh83 Release notes
FAQ
Guides index
User guide
Web Services
Contact
Legal
This site requires JavaScript to be enabled to function correctly, please enable it.
[patch]
patch for fixe the bug.
0001-libparted-reenable-use-of-BLKPG-ioctls.patch (text/plain), 8.86 KB, created by
Luan Jianhai
on 2012-05-10 05:45:57 UTC
(
hide
)
Description:
patch for fixe the bug.
Filename:
MIME Type:
Creator:
Luan Jianhai
Created:
2012-05-10 05:45:57 UTC
Size:
8.86 KB
patch
obsolete
>From 0e04d17386274fc218a9e6f9ae17d75510e632a3 Mon Sep 17 00:00:00 2001 >From: Phillip Susi <psusi@cfl.rr.com> >Date: Tue, 30 Mar 2010 15:04:43 -0400 >Subject: [PATCH] libparted: reenable use of BLKPG ioctls > >This patch effectively reverses commit 1d8f9bec which removed the code >using the new BLKPG ioctls instead of the old BLKRRPART ioctl to update >the in-kernel partition table. The reason for this is because BLKRRPART >fails if any partition on the disk is in use, but the BLKPG ioctls allow >you to manipulate the other partitions on the disk without requiring a >reboot. Also BLKRRPART requires that the kernel understand the >partition table on the disk, which may not always be the case. >--- > libparted/arch/linux.c | 208 +++++++++++++++++++++++++++++++++++++++++++++++- > 1 files changed, 205 insertions(+), 3 deletions(-) > >diff --git a/libparted/arch/linux.c b/libparted/arch/linux.c >index d7ec2e4..65043d3 100644 >--- a/libparted/arch/linux.c >+++ b/libparted/arch/linux.c >@@ -19,7 +19,7 @@ > > #include <config.h> > #include <arch/linux.h> >- >+#include <linux/blkpg.h> > #include <parted/parted.h> > #include <parted/debug.h> > #if defined __s390__ || defined __s390x__ >@@ -2305,6 +2305,182 @@ linux_partition_is_busy (const PedPartition* part) > return 0; > } > >+static int >+_blkpg_part_command (PedDevice* dev, struct blkpg_partition* part, int op) >+{ >+ LinuxSpecific* arch_specific = LINUX_SPECIFIC (dev); >+ struct blkpg_ioctl_arg ioctl_arg; >+ >+ ioctl_arg.op = op; >+ ioctl_arg.flags = 0; >+ ioctl_arg.datalen = sizeof (struct blkpg_partition); >+ ioctl_arg.data = (void*) part; >+ >+ return ioctl (arch_specific->fd, BLKPG, &ioctl_arg) == 0; >+} >+ >+static int >+_blkpg_add_partition (PedDisk* disk, const PedPartition *part) >+{ >+ struct blkpg_partition linux_part; >+ const char* vol_name; >+ char* dev_name; >+ >+ PED_ASSERT(disk != NULL, return 0); >+ PED_ASSERT(disk->dev->sector_size % PED_SECTOR_SIZE_DEFAULT == 0, >+ return 0); >+ >+ if (!_has_partitions (disk)) >+ return 0; >+ >+ if (ped_disk_type_check_feature (disk->type, >+ PED_DISK_TYPE_PARTITION_NAME)) >+ vol_name = ped_partition_get_name (part); >+ else >+ vol_name = NULL; >+ >+ 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) >+ linux_part.length = part->geom.length == 1 ? 512 : 1024; >+ else >+ linux_part.length = part->geom.length * disk->dev->sector_size; >+ linux_part.pno = part->num; >+ strncpy (linux_part.devname, dev_name, BLKPG_DEVNAMELTH); >+ if (vol_name) >+ strncpy (linux_part.volname, vol_name, BLKPG_VOLNAMELTH); >+ >+ free (dev_name); >+ >+ if (!_blkpg_part_command (disk->dev, &linux_part, >+ BLKPG_ADD_PARTITION)) { >+ return ped_exception_throw ( >+ PED_EXCEPTION_ERROR, >+ PED_EXCEPTION_IGNORE_CANCEL, >+ _("Error informing the kernel about modifications to " >+ "partition %s -- %s. This means Linux won't know " >+ "about any changes you made to %s until you reboot " >+ "-- so you shouldn't mount it or use it in any way " >+ "before rebooting."), >+ linux_part.devname, >+ strerror (errno), >+ linux_part.devname) >+ == PED_EXCEPTION_IGNORE; >+ } >+ >+ return 1; >+} >+ >+static int >+_blkpg_remove_partition (PedDisk* disk, int n) >+{ >+ struct blkpg_partition linux_part; >+ >+ if (!_has_partitions (disk)) >+ return 0; >+ >+ memset (&linux_part, 0, sizeof (linux_part)); >+ linux_part.pno = n; >+ return _blkpg_part_command (disk->dev, &linux_part, >+ BLKPG_DEL_PARTITION); >+} >+ >+/* >+ * The number of partitions that a device can have depends on the kernel. >+ * If we don't find this value in /sys/block/DEV/range, we will use our own >+ * value. >+ */ >+static unsigned int >+_device_get_partition_range(PedDevice* dev) >+{ >+ int range, r; >+ char path[128]; >+ FILE* fp; >+ bool ok; >+ >+ r = snprintf(path, sizeof(path), "/sys/block/%s/range", >+ last_component(dev->path)); >+ if(r < 0 || r >= sizeof(path)) >+ return MAX_NUM_PARTS; >+ >+ fp = fopen(path, "r"); >+ if(!fp) >+ return MAX_NUM_PARTS; >+ >+ ok = fscanf(fp, "%d", &range) == 1; >+ fclose(fp); >+ >+ /* (range <= 0) is none sense.*/ >+ return ok && range > 0 ? range : MAX_NUM_PARTS; >+} >+ >+/* >+ * 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. >+ * >+ * 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, return 0); >+ PED_ASSERT(disk->dev != NULL, return 0); >+ int lpn; >+ >+ /* lpn = largest partition number. */ >+ if(ped_disk_get_max_supported_partition_count(disk, &lpn)) >+ lpn = PED_MIN(lpn, _device_get_partition_range(disk->dev)); >+ else >+ lpn = _device_get_partition_range(disk->dev); >+ >+ /* Its not possible to support largest_partnum < 0. >+ * largest_partnum == 0 would mean does not support partitions. >+ * */ >+ if(lpn < 0) >+ return 0; >+ >+ int *rets = ped_malloc(sizeof(int) * lpn); >+ int *errnums = ped_malloc(sizeof(int) * lpn); >+ int ret = 1; >+ int i; >+ >+ for (i = 1; i <= lpn; i++) { >+ 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); >+ if (part) { >+ /* busy... so we won't (can't!) disturb ;) Prolly >+ * doesn't matter anyway, because users shouldn't be >+ * changing mounted partitions anyway... >+ */ >+ if (!rets[i - 1] && errnums[i - 1] == EBUSY) >+ continue; >+ >+ /* add the (possibly modified or new) partition */ >+ if (!_blkpg_add_partition (disk, part)) >+ ret = 0; >+ } >+ } >+ >+ free (rets); >+ free (errnums); >+ return ret; >+} >+ > #ifdef ENABLE_DEVICE_MAPPER > static int > _dm_remove_map_name(char *name) >@@ -2543,16 +2719,42 @@ _kernel_reread_part_table (PedDevice* dev) > } > > static int >+_have_blkpg () >+{ >+ static int have_blkpg = -1; >+ int kver; >+ >+ if (have_blkpg != -1) >+ return have_blkpg; >+ >+ kver = _get_linux_version(); >+ return have_blkpg = kver >= KERNEL_VERSION (2,4,0) ? 1 : 0; >+} >+ >+static int > linux_disk_commit (PedDisk* disk) > { >- if (!_has_partitions (disk)) >- return 1; >+ if (!_has_partitions (disk)) >+ return 1; > > #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) { >+ /* The ioctl() command BLKPG_ADD_PARTITION does not notify >+ * the devfs system; consequently, /proc/partitions will not >+ * be up to date, and the proper links in /dev are not >+ * created. Therefore, if using DevFS, we must get the kernel >+ * to re-read and grok the partition table. >+ */ >+ /* Work around kernel dasd problem so we really do BLKRRPART */ >+ if (disk->dev->type != PED_DEVICE_DASD && >+ _have_blkpg () ) { >+ if (_disk_sync_part_table (disk)) >+ return 1; >+ } >+ > return _kernel_reread_part_table (disk->dev); > } > >-- >1.7.6.5 >
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 820473
: 583438