summaryrefslogtreecommitdiff
path: root/libdm/libdm-common.c
diff options
context:
space:
mode:
authorAlasdair G Kergon <agk@redhat.com>2016-04-28 00:54:27 +0100
committerAlasdair G Kergon <agk@redhat.com>2016-04-28 00:54:27 +0100
commit16019b518e287da19c87eb64229f5c3ca057cb05 (patch)
tree509a161c02b1b2206a6b077e5a21440039e9abe2 /libdm/libdm-common.c
parenta2d2a61339b83de0d48ed6ed15e816773393c6b4 (diff)
downloadlvm2-16019b518e287da19c87eb64229f5c3ca057cb05.tar.gz
libdm: Add dm_udev_wait_immediate.
dm_udev_wait() waits inside the library. dm_udev_wait_immediate allows the caller to do other things if the cookie isn't yet ready to be decremented.
Diffstat (limited to 'libdm/libdm-common.c')
-rw-r--r--libdm/libdm-common.c49
1 files changed, 47 insertions, 2 deletions
diff --git a/libdm/libdm-common.c b/libdm/libdm-common.c
index 2580d94bf..d67d0bb3f 100644
--- a/libdm/libdm-common.c
+++ b/libdm/libdm-common.c
@@ -2082,6 +2082,14 @@ int dm_udev_wait(uint32_t cookie)
return 1;
}
+int dm_udev_wait_immediate(uint32_t cookie, int *ready)
+{
+ update_devs();
+ *ready = 1;
+
+ return 1;
+}
+
#else /* UDEV_SYNC_SUPPORT */
static int _check_semaphore_is_supported(void)
@@ -2506,10 +2514,16 @@ int dm_udev_complete(uint32_t cookie)
return 1;
}
-static int _udev_wait(uint32_t cookie)
+/*
+ * If *nowait is set, return immediately leaving it set if the semaphore
+ * is not ready to be decremented to 0. *nowait is cleared if the wait
+ * succeeds.
+ */
+static int _udev_wait(uint32_t cookie, int *nowait)
{
int semid;
struct sembuf sb = {0, 0, 0};
+ int val;
if (!cookie || !dm_udev_get_sync_support())
return 1;
@@ -2517,6 +2531,21 @@ static int _udev_wait(uint32_t cookie)
if (!_get_cookie_sem(cookie, &semid))
return_0;
+ /* Return immediately if the semaphore value exceeds 1? */
+ if (*nowait) {
+ if ((val = semctl(semid, 0, GETVAL)) < 0) {
+ log_error("semid %d: sem_ctl GETVAL failed for "
+ "cookie 0x%" PRIx32 ": %s",
+ semid, cookie, strerror(errno));
+ return 0;
+ }
+
+ if (val > 1)
+ return 1;
+
+ *nowait = 0;
+ }
+
if (!_udev_notify_sem_dec(cookie, semid)) {
log_error("Failed to set a proper state for notification "
"semaphore identified by cookie value %" PRIu32 " (0x%x) "
@@ -2548,11 +2577,27 @@ repeat_wait:
int dm_udev_wait(uint32_t cookie)
{
- int r = _udev_wait(cookie);
+ int nowait = 0;
+ int r = _udev_wait(cookie, &nowait);
update_devs();
return r;
}
+int dm_udev_wait_immediate(uint32_t cookie, int *ready)
+{
+ int nowait = 1;
+ int r = _udev_wait(cookie, &nowait);
+
+ if (r && nowait) {
+ *ready = 0;
+ return 1;
+ }
+
+ update_devs();
+ *ready = 1;
+
+ return r;
+}
#endif /* UDEV_SYNC_SUPPORT */