about summary refs log tree commit diff
diff options
context:
space:
mode:
authorLaurent Bercot <ska-skaware@skarnet.org>2022-08-09 13:31:25 +0000
committerLaurent Bercot <ska-skaware@skarnet.org>2022-08-09 13:32:14 +0000
commite35bc72c6f8214dbcb9105bb0268aaa86b602e9e (patch)
treee78dfbc34971d607246a7d30a079afac5b454ee0
parent90496e3409f8c2686b2082a33e2a386cb1727969 (diff)
downloadmdevd-e35bc72c6f8214dbcb9105bb0268aaa86b602e9e.tar.gz
mdevd-e35bc72c6f8214dbcb9105bb0268aaa86b602e9e.tar.xz
mdevd-e35bc72c6f8214dbcb9105bb0268aaa86b602e9e.zip
Adjust rebc output buffer according to kbufsz; refactor rebc call
Signed-off-by: Laurent Bercot <ska@appnovation.com>
-rw-r--r--NEWS1
-rw-r--r--src/mdevd/mdevd.c38
2 files changed, 21 insertions, 18 deletions
diff --git a/NEWS b/NEWS
index f382c60..555f329 100644
--- a/NEWS
+++ b/NEWS
@@ -3,6 +3,7 @@ Changelog for mdevd.
 In 0.1.6.0
 ----------
 
+ - Bugfixes.
  - mdevd-coldplug can now be synchronous with the -O option.
 
 
diff --git a/src/mdevd/mdevd.c b/src/mdevd/mdevd.c
index 1a3c9d2..5559225 100644
--- a/src/mdevd/mdevd.c
+++ b/src/mdevd/mdevd.c
@@ -179,18 +179,22 @@ static int makesubdirs (char *path)
   return 1 ;
 }
 
-
-static inline int rebc_init (unsigned int groups)
+static inline int rebc_init (unsigned int groups, unsigned int kbufsz)
 {
   struct sockaddr_nl nl = { .nl_family = AF_NETLINK, .nl_pad = 0, .nl_groups = groups & ~1U, .nl_pid = 0 } ;
   int fd = socket_internal(AF_NETLINK, SOCK_DGRAM, NETLINK_KOBJECT_UEVENT, O_CLOEXEC) ;
   if (fd == -1) return -1 ;
-  if (connect(fd, (struct sockaddr *)&nl, sizeof nl) == -1)
+  if (connect(fd, (struct sockaddr *)&nl, sizeof nl) == -1) goto err ;
+  if (setsockopt(fd, SOL_SOCKET, SO_SNDBUFFORCE, &kbufsz, sizeof(unsigned int)) < 0)
   {
-    fd_close(fd) ;
-    return -1 ;
+    if (errno != EPERM
+     || setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &kbufsz, sizeof(unsigned int)) < 0) goto err ;
   }
   return fd ;
+
+ err:
+  fd_close(fd) ;
+  return -1 ;
 }
 
 
@@ -867,7 +871,7 @@ static inline int handle_event (int fd, struct uevent_s *event, scriptelem const
   return on_event(event, script, scriptlen, storage, envmatch, ud) ;
 }
 
-static int output_event (unsigned int outputfd, struct uevent_s *event)
+static inline int output_event (unsigned int outputfd, struct uevent_s *event)
 {
   static char const c = 0 ;
   struct iovec v[2] = { { .iov_base = event->buf, .iov_len = event->len }, { .iov_base = (char *)&c, .iov_len = 1 } } ;
@@ -882,7 +886,7 @@ static int output_event (unsigned int outputfd, struct uevent_s *event)
   return 1 ;
 }
 
-static void rebc_event (int fd, struct uevent_s const *event)
+static inline void rebc_event (int fd, struct uevent_s const *event)
 {
   if (fd_send(fd, event->buf, event->len, 0) == -1)
     strerr_warnwu1sys("rebroadcast uevent") ;
@@ -955,7 +959,7 @@ int main (int argc, char const *const *argv)
   if (x[1].fd < 0) strerr_diefu1sys(111, "init netlink") ;
   if (rebc)
   {
-    int fd = rebc_init(rebc) ;
+    int fd = rebc_init(rebc, kbufsz) ;
     if (fd == -1) strerr_diefu2sys(111, "init netlink", " rebroadcast socket") ;
     rebc = fd ;
   }
@@ -1018,19 +1022,17 @@ int main (int argc, char const *const *argv)
 
       while (ud.pid || cont == 2)
       {
+        int done = 0 ;
         if (iopause_stamp(x, 1 + (!ud.pid && cont == 2), 0, 0) < 0) strerr_diefu1sys(111, "iopause") ;
         if (x[0].revents & IOPAUSE_READ)
-          if (handle_signals(&event, script, scriptlen, storage, envmatch, &ud))
-          {
-            if (outputfd && !output_event(outputfd, &event)) outputfd = 0 ;
-            if (rebc) rebc_event(rebc, &event) ;
-          }
+          done |= handle_signals(&event, script, scriptlen, storage, envmatch, &ud) ;
         if (!ud.pid && cont == 2 && x[1].revents & IOPAUSE_READ)
-          if (handle_event(x[1].fd, &event, script, scriptlen, storage, envmatch, &ud))
-          {
-            if (outputfd && !output_event(outputfd, &event)) outputfd = 0 ;
-            if (rebc) rebc_event(rebc, &event) ;
-          }
+          done |= handle_event(x[1].fd, &event, script, scriptlen, storage, envmatch, &ud) ;
+        if (done)
+        {
+          if (outputfd && !output_event(outputfd, &event)) outputfd = 0 ;
+          if (rebc) rebc_event(rebc, &event) ;
+        }
       }
 
       script_free(script, scriptlen, envmatch, envmatchlen) ;