Accepting request 30480 from home:puzel:branches:Base:System

Copy from home:puzel:branches:Base:System/parted via accept of submit request 30480 revision 2.
Request was accepted with message:

OBS-URL: https://build.opensuse.org/request/show/30480
OBS-URL: https://build.opensuse.org/package/show/Base:System/parted?expand=0&rev=14
This commit is contained in:
Petr Uzel 2010-01-26 09:03:05 +00:00 committed by Git OBS Bridge
parent e373e82ffd
commit 1f7315e780
7 changed files with 252 additions and 3 deletions

View File

@ -0,0 +1,61 @@
From ad25892bb995f61b0ddf801ed1f74e0b1e7390ce Mon Sep 17 00:00:00 2001
From: Hans de Goede <hdegoede@redhat.com>
Date: Thu, 27 Aug 2009 20:16:09 +0200
Subject: [PATCH] parted: avoid unnecessary open/close on commit, and thus udev activity
* libparted/disk.c (ped_disk_commit): Open/close the underlying file
descriptor in this function, so that callees, ped_disk_commit_to_dev
and ped_disk_commit_to_os do not each perform open/close syscalls.
This saves an open/close pair, and thus avoids unneeded udev
activity on Linux.
Before this change, when calling commit() on a ped_disk, the
following would happen:
open /dev/sda
write partition table
close /dev/sda
open /dev/sda
ioctl (BLKRRPART)
close /dev/sda
This is rather inefficient, and causes 2 udev change events to be fired
for /dev/sda (+ the change events from the BLKRRPART), causing all kind
of scanning (blkid & friends) twice.
This patch fixes things to only open the device once.
---
libparted/disk.c | 20 ++++++++++++++++++--
1 files changed, 18 insertions(+), 2 deletions(-)
Index: parted-1.9.0/libparted/disk.c
===================================================================
--- parted-1.9.0.orig/libparted/disk.c 2009-12-03 15:09:44.000000000 +0100
+++ parted-1.9.0/libparted/disk.c 2009-12-03 15:10:13.000000000 +0100
@@ -489,9 +489,25 @@ error:
int
ped_disk_commit (PedDisk* disk)
{
+ /* Open the device here, so that the underlying fd is not closed
+ between commit_to_dev and commit_to_os (closing causes unwanted
+ udev events to be sent under Linux). */
+ if (!ped_device_open (disk->dev))
+ goto error;
+
if (!ped_disk_commit_to_dev (disk))
+ goto error_close_dev;
+
+ if (!ped_disk_commit_to_os (disk))
+ goto error_close_dev;
+
+ ped_device_close (disk->dev);
+ return 1;
+
+error_close_dev:
+ ped_device_close (disk->dev);
+error:
return 0;
- return ped_disk_commit_to_os (disk);
}
/**

View File

@ -0,0 +1,96 @@
From 2a6936fab4d4499a4b812dd330d3db50549029e0 Mon Sep 17 00:00:00 2001
From: Hans de Goede <hdegoede@redhat.com>
Date: Fri, 28 Aug 2009 17:05:55 +0200
Subject: [PATCH] linux-commit: do not unnecessarily open partition device nodes
After patching parted with my do-not-use-BLKPG patch, I started
to get EBUSY errors on commit_to_os. Note this is not caused
by the do-not-use-BLKPG patch, this was already happening, but
parted was silently ignoring the errors (and the kernel was
not notified of the changes, which is bad). The error now
actually gets reported.
The problem turns out to be in libparted/arch/linux.c's
_flush_cache function, which walks all the partitions of the
disk and does BLKFLSBUF calls on them. This causes the following:
commit_to_os -> device_open -> fd = open /dev/sda ->
_flush_cache -> for each /dev/sda# open, ioctl, close
-> ioctl(fd, BLKRRPART) -> EBUSY
What is happening here is that the:
for each /dev/sda# open, ioctl, close
Is causing udev change events for all the /dev/sda#
nodes, which causes udev to call blkid on all these nodes
(on systems which use DeviceKit), so blkid has /dev/sda# nodes
open while BLKRRPART gets called on /dev/sda -> EBUSY.
I've checked with two independend storage subsystem kernel
developers, and /dev/sda and /dev/sda#, guarantee cache coherency
now-a-days. So there is no need to do this for 2.6, which also
eliminates the need to call _flush_cache() on device open at all.
* libparted/arch/linux.c (_have_kern26): New function.
(_flush_cache): For linux kernels 2.6 and newer, don't flush
partition devices.
(linux_open): Skip _flush_cache on newer kernels here, too.
---
libparted/arch/linux.c | 25 ++++++++++++++++++++++---
1 files changed, 22 insertions(+), 3 deletions(-)
Index: parted-1.9.0/libparted/arch/linux.c
===================================================================
--- parted-1.9.0.orig/libparted/arch/linux.c 2009-12-03 17:04:44.000000000 +0100
+++ parted-1.9.0/libparted/arch/linux.c 2009-12-03 17:05:06.000000000 +0100
@@ -601,6 +601,19 @@ _have_devfs ()
return have_devfs = S_ISCHR(sb.st_mode) ? 1 : 0;
}
+static int
+_have_kern26 ()
+{
+ static int have_kern26 = -1;
+ int kver;
+
+ if (have_kern26 != -1)
+ return have_kern26;
+
+ kver = _get_linux_version();
+ return have_kern26 = kver >= KERNEL_VERSION (2,6,0) ? 1 : 0;
+}
+
static void
_device_set_sector_size (PedDevice* dev)
{
@@ -1374,8 +1387,8 @@ linux_is_busy (PedDevice* dev)
return 0;
}
-/* we need to flush the master device, and all the partition devices,
- * because there is no coherency between the caches.
+/* we need to flush the master device, and with kernel < 2.6 all the partition
+ * devices, because there is no coherency between the caches with old kernels.
* We should only flush unmounted partition devices, because:
* - there is never a need to flush them (we're not doing IO there)
* - flushing a device that is mounted causes unnecessary IO, and can
@@ -1393,6 +1406,10 @@ _flush_cache (PedDevice* dev)
ioctl (arch_specific->fd, BLKFLSBUF);
+ /* With linux-2.6.0 and newer, we're done. */
+ if (_have_kern26())
+ return;
+
for (i = 1; i < 16; i++) {
char* name;
int fd;
@@ -1449,6 +1466,8 @@ retry:
dev->read_only = 0;
}
+ /* With kernels < 2.6 flush cache for cache coherence issues */
+ if (!_have_kern26())
_flush_cache (dev);
return 1;

View File

@ -0,0 +1,19 @@
---
libparted/arch/linux.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
Index: parted-1.9.0/libparted/arch/linux.c
===================================================================
--- parted-1.9.0.orig/libparted/arch/linux.c 2009-12-11 12:04:43.000000000 +0100
+++ parted-1.9.0/libparted/arch/linux.c 2009-12-11 12:10:22.000000000 +0100
@@ -2224,7 +2224,9 @@ _blkpg_part_command (PedDevice* dev, str
ioctl_arg.datalen = sizeof (struct blkpg_partition);
ioctl_arg.data = (void*) part;
- return ioctl (arch_specific->fd, BLKPG, &ioctl_arg) == 0;
+ int ret = (ioctl (arch_specific->fd, BLKPG, &ioctl_arg) == 0);
+ system("/sbin/udevadm settle");
+ return ret;
}
static int

View File

@ -1,3 +1,16 @@
-------------------------------------------------------------------
Mon Jan 25 15:54:17 UTC 2010 - puzel@novell.com
- use-ext-range.patch (bnc#567652)
-------------------------------------------------------------------
Thu Dec 3 14:10:59 UTC 2009 - puzel@novell.com
- avoid-unnecessary-open-close.patch,
do-not-unnecessarily-open-part-dev.patch,
fix-race-call-udevadm-settle.patch,
retry-blkpg-ioctl.patch (bnc#539521)
-------------------------------------------------------------------
Wed Oct 7 14:12:15 UTC 2009 - puzel@novell.com

View File

@ -26,11 +26,12 @@ BuildRequires: readline-devel
BuildRequires: libsepol-devel
BuildRequires: libselinux-devel
%define aclocaldir /usr/share/aclocal
License: GPL v3 or later
License: GPLv3+
Group: System/Filesystems
Requires: /sbin/udevadm
Summary: GNU partitioner
Version: 1.9.0
Release: 2
Release: 3
Source0: %{name}-%{version}.tar.bz2
Patch0: always-resize-part.dif
Patch1: parted-type.patch
@ -53,6 +54,16 @@ Patch15: fix-dm-partition-name.patch
Patch16: fix-tests.sh
#PATCH-FEATURE-OPENSUSE do-not-create-dm-nodes.patch bnc#501773 petr.uzel@suse.cz
Patch17: do-not-create-dm-nodes.patch
#PATCH-FIX-UPSTREAM avoid-unnecessary-open-close.patch bnc#539521 petr.uzel@suse.cz
Patch18: avoid-unnecessary-open-close.patch
#PATCH-FIX-UPSTREAM do-not-unnecessarily-open-part-dev.patch bnc#539521 petr.uzel@suse.cz
Patch19: do-not-unnecessarily-open-part-dev.patch
#PATCH-FIX-UPSTREAM fix-race-call-udevadm-settle.patch bnc#539521 petr.uzel@suse.cz
Patch20: fix-race-call-udevadm-settle.patch
#PATCH-FIX-UPSTREAM retry-blkpg-ioctl.patch bnc#539521 petr.uzel@suse.cz
Patch21: retry-blkpg-ioctl.patch
#PATCH-FIX-UPSTREAM use-ext-range.patch bnc#567652 petr.uzel@suse.cz
Patch22: use-ext-range.patch
BuildRoot: %{_tmppath}/%{name}-%{version}-build
Url: http://www.gnu.org/software/parted/
PreReq: %install_info_prereq
@ -70,7 +81,7 @@ Authors:
Andrew Clausen <clausen@gnu.org>
%package devel
License: GPL v2 or later
License: GPLv2+
Summary: Parted Include Files and Libraries necessary for Development
Group: Development/Libraries/C and C++
Requires: e2fsprogs-devel parted = %version device-mapper-devel libreiserfs-devel
@ -113,6 +124,11 @@ Authors:
%patch15 -p1
%patch16 -p1
%patch17 -p1
%patch18 -p1
%patch19 -p1
%patch20 -p1
%patch21 -p1
%patch22 -p1
%build
AUTOPOINT=true autoreconf --force --install

22
retry-blkpg-ioctl.patch Normal file
View File

@ -0,0 +1,22 @@
Index: parted-1.9.0/libparted/arch/linux.c
===================================================================
--- parted-1.9.0.orig/libparted/arch/linux.c 2010-01-25 16:24:54.000000000 +0100
+++ parted-1.9.0/libparted/arch/linux.c 2010-01-25 16:26:35.000000000 +0100
@@ -2360,8 +2360,17 @@ _disk_sync_part_table (PedDisk* disk)
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++) {

22
use-ext-range.patch Normal file
View File

@ -0,0 +1,22 @@
Index: parted-1.9.0/libparted/arch/linux.c
===================================================================
--- parted-1.9.0.orig/libparted/arch/linux.c 2010-01-25 16:32:09.000000000 +0100
+++ parted-1.9.0/libparted/arch/linux.c 2010-01-25 16:33:18.000000000 +0100
@@ -2296,7 +2296,7 @@ _blkpg_remove_partition (PedDisk* disk,
/*
* 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
+ * If we don't find this value in /sys/block/DEV/ext_range, we will use our own
* value.
*/
static unsigned int
@@ -2307,7 +2307,7 @@ _device_get_partition_range(PedDevice* d
FILE* fp;
bool ok;
- r = snprintf(path, sizeof(path), "/sys/block/%s/range",
+ r = snprintf(path, sizeof(path), "/sys/block/%s/ext_range",
last_component(dev->path));
if(r < 0 || r >= sizeof(path))
return MAX_NUM_PARTS;