From 9463583b614f290041b93e9d4b459b4c064d6333 Mon Sep 17 00:00:00 2001 From: Vratislav Podzimek Date: Mon, 24 Oct 2016 12:20:55 +0200 Subject: [PATCH] New version - Prevent issues between libparted and udev (vpodzime) --- libblockdev.spec | 7 +++- parted_udev_issues.patch | 76 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 82 insertions(+), 1 deletion(-) create mode 100644 parted_udev_issues.patch diff --git a/libblockdev.spec b/libblockdev.spec index a04f8a4..75fc84f 100644 --- a/libblockdev.spec +++ b/libblockdev.spec @@ -1,6 +1,6 @@ Name: libblockdev Version: 1.9 -Release: 5%{?dist} +Release: 6%{?dist} Summary: A library for low-level manipulation with block devices License: LGPLv2+ URL: https://github.com/rhinstaller/libblockdev @@ -13,6 +13,7 @@ Patch3: mdadm_examine_export.patch Patch4: mdadm_examine_uuid.patch Patch5: mdadm_fw_raid_device.patch Patch6: obj_path_signatures.patch +Patch7: parted_udev_issues.patch BuildRequires: glib2-devel BuildRequires: gobject-introspection-devel @@ -390,6 +391,7 @@ A meta-package that pulls all the libblockdev plugins as dependencies. %patch4 -p1 %patch5 -p1 %patch6 -p1 +%patch7 -p1 %build %configure @@ -587,6 +589,9 @@ find %{buildroot} -type f -name "*.la" | xargs %{__rm} %files plugins-all %changelog +* Mon Oct 24 2016 Vratislav Podzimek - 1.9-6 +- Prevent issues between libparted and udev (vpodzime) + * Mon Oct 10 2016 Vratislav Podzimek - 1.9-5 - Make sure all object paths are passed and extracted as such (vpodzime) Resolves: rhbz#1374973 diff --git a/parted_udev_issues.patch b/parted_udev_issues.patch new file mode 100644 index 0000000..63ed34a --- /dev/null +++ b/parted_udev_issues.patch @@ -0,0 +1,76 @@ +From 66ceb82b6d51707a74174dfb7a74b943ea571a43 Mon Sep 17 00:00:00 2001 +From: Vratislav Podzimek +Date: Thu, 20 Oct 2016 15:43:23 +0200 +Subject: [PATCH] Prevent issues between libparted and udev + +libparted does committing of a new partition table to disk in two steps: + +1. committing (writing and flushing) to disk and +2. telling OS about the partitions. + +However, that means that if things go wrong, udev may step in between the above +steps and trigger events when the block device file is closed (from being opened +RW) that could lead to a failure of the second step because some other process +may open the block device file in the reaction to the event. + +In order to prevent such issues we need to acquire an exclusive lock on the +block device file, which prevents udev from triggering events, for the time we +let libparted perform the two operations above. + +(cherry picked from commit 0a65466154994759cbec15ce984b751b073a891f) +Signed-off-by: Vratislav Podzimek +--- + src/plugins/part.c | 15 +++++++++++++++ + 1 file changed, 15 insertions(+) + +diff --git a/src/plugins/part.c b/src/plugins/part.c +index 4634ef8..d5239e3 100644 +--- a/src/plugins/part.c ++++ b/src/plugins/part.c +@@ -23,6 +23,8 @@ + #include + #include + #include ++#include ++#include + #include + + #include "part.h" +@@ -150,11 +152,22 @@ static const gchar *table_type_str[BD_PART_TABLE_UNDEF] = {"msdos", "gpt"}; + + static gboolean disk_commit (PedDisk *disk, gchar *path, GError **error) { + gint ret = 0; ++ gint dev_fd = 0; ++ ++ /* XXX: try to grab an exclusive lock for the device so that udev doesn't ++ trigger events for it in between the two operations we need to perform ++ (see below) */ ++ dev_fd = open (disk->dev->path, O_RDONLY|O_CLOEXEC); ++ if (dev_fd >= 0) ++ /* if this fails, we can do no better anyway, so just ignore the return ++ value */ ++ flock (dev_fd, LOCK_EX); + + ret = ped_disk_commit_to_dev (disk); + if (ret == 0) { + set_parted_error (error, BD_PART_ERROR_FAIL); + g_prefix_error (error, "Failed to commit changes to device '%s'", path); ++ close (dev_fd); + return FALSE; + } + +@@ -162,9 +175,11 @@ static gboolean disk_commit (PedDisk *disk, gchar *path, GError **error) { + if (ret == 0) { + set_parted_error (error, BD_PART_ERROR_FAIL); + g_prefix_error (error, "Failed to inform OS about changes on the '%s' device", path); ++ close (dev_fd); + return FALSE; + } + ++ close (dev_fd); + return TRUE; + } + +-- +2.7.4 +