77 lines
2.6 KiB
Diff
77 lines
2.6 KiB
Diff
From 66ceb82b6d51707a74174dfb7a74b943ea571a43 Mon Sep 17 00:00:00 2001
|
|
From: Vratislav Podzimek <vpodzime@redhat.com>
|
|
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 <vpodzime@redhat.com>
|
|
---
|
|
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 <stdlib.h>
|
|
#include <math.h>
|
|
#include <inttypes.h>
|
|
+#include <unistd.h>
|
|
+#include <sys/file.h>
|
|
#include <utils.h>
|
|
|
|
#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
|
|
|