From b401efe5d232be657a1d469f0a7eb3561186e26e Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 20 Sep 2023 11:18:02 +0200 Subject: [PATCH 1/2] time-util: use clock_nanosleep() rather than nanosleep() nanosleep() is kinda broken since it sleeps in the CLOCK_REALTIME clock, i.e. is subject to time changes. Let's use clock_nanosleep() instead with CLOCK_MONOTONIC, which is really the only thing that makes sense. --- src/basic/time-util.h | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/basic/time-util.h b/src/basic/time-util.h index b648a3b59e..73ba8b9544 100644 --- a/src/basic/time-util.h +++ b/src/basic/time-util.h @@ -214,10 +214,13 @@ static inline usec_t usec_sub_signed(usec_t timestamp, int64_t delta) { static inline int usleep_safe(usec_t usec) { /* usleep() takes useconds_t that is (typically?) uint32_t. Also, usleep() may only support the - * range [0, 1000000]. See usleep(3). Let's override usleep() with nanosleep(). */ + * range [0, 1000000]. See usleep(3). Let's override usleep() with clock_nanosleep(). + * + * ⚠️ Note we are not using plain nanosleep() here, since that operates on CLOCK_REALTIME, not + * CLOCK_MONOTONIC! */ // FIXME: use RET_NERRNO() macro here. Currently, this header cannot include errno-util.h. - return nanosleep(TIMESPEC_STORE(usec), NULL) < 0 ? -errno : 0; + return clock_nanosleep(CLOCK_MONOTONIC, 0, TIMESPEC_STORE(usec), NULL) < 0 ? -errno : 0; } /* The last second we can format is 31. Dec 9999, 1s before midnight, because otherwise we'd enter 5 digit From 8fcacaf0464a9a45fded4392e4f9ac31896d77c3 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 20 Sep 2023 11:18:59 +0200 Subject: [PATCH 2/2] scsi_serial: convert from nanosleep() to usleep_safe() --- src/udev/scsi_id/scsi_serial.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/udev/scsi_id/scsi_serial.c b/src/udev/scsi_id/scsi_serial.c index a271b1786c..aed6082620 100644 --- a/src/udev/scsi_id/scsi_serial.c +++ b/src/udev/scsi_id/scsi_serial.c @@ -793,14 +793,11 @@ int scsi_get_serial(struct scsi_id_device *dev_scsi, const char *devname, memzero(dev_scsi->serial, len); for (cnt = 20; cnt > 0; cnt--) { - struct timespec duration; - fd = open(devname, O_RDONLY | O_NONBLOCK | O_CLOEXEC | O_NOCTTY); if (fd >= 0 || errno != EBUSY) break; - duration.tv_sec = 0; - duration.tv_nsec = (200 * 1000 * 1000) + (random_u32() % 100 * 1000 * 1000); - nanosleep(&duration, NULL); + + usleep_safe(200U*USEC_PER_MSEC + random_u64_range(100U*USEC_PER_MSEC)); } if (fd < 0) return 1;