Blob Blame History Raw
From 1edbfcdb4a973120048b5c04e0eb92b05ad3cbd2 Mon Sep 17 00:00:00 2001
From: Vratislav Podzimek <vpodzime@redhat.com>
Date: Wed, 26 Oct 2016 16:13:58 +0200
Subject: [PATCH] Open the device file as RDWR when committing parts

We block udev from generating events for the device while we are between
committing changes to disk and informing kernel about the changes. If we close
the file descriptor later, no udev changes are generated either unless we open
is as RDWR. Here's the difference:

RDONLY:
  # udevadm monitor
  monitor will print the received events for:
  UDEV - the event which udev sends out after rule processing
  KERNEL - the kernel uevent

  KERNEL[68221.911864] change   /devices/virtual/block/loop0 (block)
  KERNEL[68221.913442] change   /devices/virtual/block/loop0 (block)
  KERNEL[68221.913794] add      /devices/virtual/block/loop0/loop0p1 (block)
  KERNEL[68221.915019] change   /devices/virtual/block/loop0 (block)
  KERNEL[68221.915217] change   /devices/virtual/block/loop0/loop0p1 (block)
  UDEV  [68221.941293] change   /devices/virtual/block/loop0 (block)
  UDEV  [68221.954214] change   /devices/virtual/block/loop0/loop0p1 (block)

RDWR:
  # udevadm monitor
  monitor will print the received events for:
  UDEV - the event which udev sends out after rule processing
  KERNEL - the kernel uevent

  KERNEL[68161.533114] change   /devices/virtual/block/loop0 (block)
  KERNEL[68161.533165] change   /devices/virtual/block/loop0 (block)
  UDEV  [68161.533219] change   /devices/virtual/block/loop0 (block)
  KERNEL[68161.533262] add      /devices/virtual/block/loop0/loop0p1 (block)
  KERNEL[68161.533292] change   /devices/virtual/block/loop0 (block)
  KERNEL[68161.533326] change   /devices/virtual/block/loop0/loop0p1 (block)
  UDEV  [68161.539255] add      /devices/virtual/block/loop0/loop0p1 (block)
  UDEV  [68161.560215] change   /devices/virtual/block/loop0 (block)
  UDEV  [68161.572345] change   /devices/virtual/block/loop0/loop0p1 (block)

As seen above, there's no 'add' udev event in case we open the device file as
RDONLY.

(cherry picked from commit 44fdb3953eb05ff4f43a576f15d508928dca3eb7)
Signed-off-by: Vratislav Podzimek <vpodzime@redhat.com>
---
 src/plugins/part.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/src/plugins/part.c b/src/plugins/part.c
index d5239e3..0f8e678 100644
--- a/src/plugins/part.c
+++ b/src/plugins/part.c
@@ -157,7 +157,7 @@ static gboolean disk_commit (PedDisk *disk, gchar *path, GError **error) {
     /* 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);
+    dev_fd = open (disk->dev->path, O_RDWR|O_CLOEXEC);
     if (dev_fd >= 0)
         /* if this fails, we can do no better anyway, so just ignore the return
            value */
@@ -167,6 +167,7 @@ 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 commit changes to device '%s'", path);
+        flock (dev_fd, LOCK_UN);
         close (dev_fd);
         return FALSE;
     }
@@ -175,10 +176,12 @@ 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);
+        flock (dev_fd, LOCK_UN);
         close (dev_fd);
         return FALSE;
     }
 
+    flock (dev_fd, LOCK_UN);
     close (dev_fd);
     return TRUE;
 }
-- 
2.7.4