diff --git a/libdm/libdm-common.c b/libdm/libdm-common.c index 40b366b..0b03106 100644 --- a/libdm/libdm-common.c +++ b/libdm/libdm-common.c @@ -59,6 +59,7 @@ union semun #endif #endif +#define UDEV_SEM_TIMEOUT 300 static char _dm_dir[PATH_MAX] = DEV_DIR DM_DIR; static char _sysfs_dir[PATH_MAX] = "/sys/"; static char _path0[PATH_MAX]; /* path buffer, safe 4kB on stack */ @@ -2611,6 +2612,9 @@ static int _udev_wait(uint32_t cookie, int *nowait) int semid; struct sembuf sb = {0, 0, 0}; int val; + struct timespec timeout; + timeout.tv_sec = UDEV_SEM_TIMEOUT; + timeout.tv_nsec = 0; if (!cookie || !dm_udev_get_sync_support()) return 1; @@ -2646,7 +2650,7 @@ static int _udev_wait(uint32_t cookie, int *nowait) cookie, semid); repeat_wait: - if (semop(semid, &sb, 1) < 0) { + if (semtimedop(semid, &sb, 1,&timeout) < 0) { if (errno == EINTR) goto repeat_wait; else if (errno == EIDRM) diff --git a/tools/dmsetup.c b/tools/dmsetup.c index 3cdf862..af70a02 100644 --- a/tools/dmsetup.c +++ b/tools/dmsetup.c @@ -1131,6 +1131,7 @@ out: static int _create_one_device(const char *name, const char *file) { int r = 0; + int udev_wait_r = 1; struct dm_task *dmt; uint32_t cookie = 0; uint16_t udev_flags = 0; @@ -1203,13 +1204,16 @@ static int _create_one_device(const char *name, const char *file) out: if (!_udev_cookie) - (void) dm_udev_wait(cookie); + udev_wait_r = dm_udev_wait(cookie); if (r && _switches[VERBOSE_ARG]) r = _display_info(dmt); dm_task_destroy(dmt); + if(!udev_wait_r) + return 0; + return r; } @@ -1430,6 +1434,7 @@ static int _create(CMD_ARGS) static int _do_rename(const char *name, const char *new_name, const char *new_uuid) { int r = 0; + int udev_wait_r = 1; struct dm_task *dmt; uint32_t cookie = 0; uint16_t udev_flags = 0; @@ -1474,10 +1479,13 @@ static int _do_rename(const char *name, const char *new_name, const char *new_uu out: if (!_udev_cookie) - (void) dm_udev_wait(cookie); + udev_wait_r = dm_udev_wait(cookie); dm_task_destroy(dmt); + if (!udev_wait_r) + return 0; + return r; } @@ -1997,6 +2005,7 @@ static int _simple(int task, const char *name, uint32_t event_nr, int display) int udev_wait_flag = task == DM_DEVICE_RESUME || task == DM_DEVICE_REMOVE; int r = 0; + int udev_wait_r = 1; struct dm_task *dmt; @@ -2056,13 +2065,16 @@ static int _simple(int task, const char *name, uint32_t event_nr, int display) out: if (!_udev_cookie && udev_wait_flag) - (void) dm_udev_wait(cookie); + udev_wait_r = dm_udev_wait(cookie); if (r && display && _switches[VERBOSE_ARG]) r = _display_info(dmt); dm_task_destroy(dmt); + if(!udev_wait_r) + return 0; + return r; }