[Libguestfs] [PATCH nbdkit] freebsd: In nbdkit_nanosleep, fallback to calling nanosleep(2).

Richard W.M. Jones rjones at redhat.com
Wed Aug 28 16:14:28 UTC 2019


Rather than failing to compile on platforms which lack POLLRDHUP such
as FreeBSD, simply fallback to the old method of sleeping.

This leaves the porting suggestions as a comment in case someone wants
to implement a better solution for particular platforms.
---
 server/public.c | 38 ++++++++++++++++++++++++--------------
 1 file changed, 24 insertions(+), 14 deletions(-)

diff --git a/server/public.c b/server/public.c
index a992df1..630de9b 100644
--- a/server/public.c
+++ b/server/public.c
@@ -304,6 +304,16 @@ nbdkit_realpath (const char *path)
 int
 nbdkit_nanosleep (unsigned sec, unsigned nsec)
 {
+  struct timespec ts;
+
+  if (sec >= INT_MAX - nsec / 1000000000) {
+    nbdkit_error ("sleep request is too long");
+    errno = EINVAL;
+    return -1;
+  }
+  ts.tv_sec = sec + nsec / 1000000000;
+  ts.tv_nsec = nsec % 1000000000;
+
 #if defined HAVE_PPOLL && defined POLLRDHUP
   /* End the sleep early if any of these happen:
    * - nbdkit has received a signal to shut down the server
@@ -311,7 +321,6 @@ nbdkit_nanosleep (unsigned sec, unsigned nsec)
    *   NBD_CMD_DISC or a problem with the connection
    * - the input socket detects POLLRDHUP/POLLHUP/POLLERR
    */
-  struct timespec ts;
   struct connection *conn = threadlocal_get_conn ();
   struct pollfd fds[] = {
     [0].fd = quit_fd,
@@ -323,14 +332,6 @@ nbdkit_nanosleep (unsigned sec, unsigned nsec)
   };
   sigset_t all;
 
-  if (sec >= INT_MAX - nsec / 1000000000) {
-    nbdkit_error ("sleep request is too long");
-    errno = EINVAL;
-    return -1;
-  }
-  ts.tv_sec = sec + nsec / 1000000000;
-  ts.tv_nsec = nsec % 1000000000;
-
   /* Block all signals to this thread during the poll, so we don't
    * have to worry about EINTR
    */
@@ -354,9 +355,13 @@ nbdkit_nanosleep (unsigned sec, unsigned nsec)
   nbdkit_error ("aborting sleep to shut down");
   errno = ESHUTDOWN;
   return -1;
+
 #else
-# error "Please port this to your platform"
-  /* Porting ideas, in order of preference:
+  /* The fallback path simply calls ordinary nanosleep, and will
+   * cause long delays on server shutdown.
+   *
+   * If however you want to port this to your platform, then
+   * porting ideas, in order of preference:
    * - POSIX requires pselect; it's a bit clunkier to set up than poll,
    *   but the same ability to atomically mask all signals and operate
    *   on struct timespec makes it similar to the preferred ppoll interface
@@ -364,8 +369,13 @@ nbdkit_nanosleep (unsigned sec, unsigned nsec)
    *   a recalculation of the timeout to still reach the end time (masking
    *   signals in that case is not safe, as it is a non-atomic race)
    */
-  nbdkit_error ("nbdkit_nanosleep not yet ported to systems without ppoll");
-  errno = ENOSYS;
-  return -1;
+  int r;
+
+  r = nanosleep (&ts, NULL);
+  if (r == -1 && errno != EINTR && errno != EAGAIN) {
+    nbdkit_error ("nanosleep: %m");
+    return -1;
+  }
+  return 0;
 #endif
 }
-- 
2.22.0




More information about the Libguestfs mailing list