Hello community,

here is the log from the commit of package psmisc for openSUSE:Factory
checked in at Fri Oct 7 17:07:37 CEST 2011.



--------
--- openSUSE:Factory/psmisc/psmisc.changes      2011-10-05 17:47:29.000000000 
+0200
+++ /mounts/work_src_done/STABLE/psmisc/psmisc.changes  2011-10-07 
16:12:00.000000000 +0200
@@ -1,0 +2,6 @@
+Fri Oct  7 14:08:31 UTC 2011 - [email protected]
+
+- Make main fuser process more robust against broken pipe and check
+  for helper process within a SIGCHLD handler
+
+-------------------------------------------------------------------

calling whatdependson for head-i586


++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ psmisc-22.15-timeout.patch ++++++
--- /var/tmp/diff_new_pack.8QpXDu/_old  2011-10-07 17:07:34.000000000 +0200
+++ /var/tmp/diff_new_pack.8QpXDu/_new  2011-10-07 17:07:34.000000000 +0200
@@ -117,10 +117,10 @@
  /*
   * Use /proc/self/mountinfo of modern linux system to determine
 diff --git a/src/timeout.c b/src/timeout.c
-index e69de29..3b582a3 100644
+index e69de29..e79774b 100644
 --- a/src/timeout.c
 +++ b/src/timeout.c
-@@ -0,0 +1,215 @@
+@@ -0,0 +1,260 @@
 +/*
 + * timout.c   Advanced timeout handling for file system calls
 + *            to avoid deadlocks on remote file shares.
@@ -138,9 +138,16 @@
 + */
 +
 +#ifndef _GNU_SOURCE
-+#define _GNU_SOURCE
++# define _GNU_SOURCE
 +#endif
 +
++#ifndef USE_SOCKETPAIR
++# define USE_SOCKETPAIR               1
++#endif
++
++#ifdef _FEATURES_H
++# error Include local config.h before any system header file
++#endif
 +#include "config.h"           /* For _FILE_OFFSET_BITS */
 +
 +#include <errno.h>
@@ -153,10 +160,24 @@
 +#include <sys/types.h>
 +#include <sys/select.h>
 +#include <sys/stat.h>
++
 +#include <unistd.h>
++#if USE_SOCKETPAIR
++# include <sys/socket.h>
++# include <netdb.h>
++# include <netinet/in.h>
++#  ifndef SHUT_RD
++#   define SHUT_RD    0
++# endif
++# ifndef SHUT_WR
++#  define SHUT_WR     1
++# endif
++# undef pipe
++# define pipe(v)      (((socketpair(AF_UNIX,SOCK_STREAM,0,v) < 0) || \
++                      (shutdown((v)[1],SHUT_RD) < 0) || 
(shutdown((v)[0],SHUT_WR) < 0)) ? -1 : 0)
++#endif
 +#include <wait.h>
 +
-+#include <stdio.h>
 +#include "timeout.h"
 +
 +#if !defined(__STDC_VERSION__) || (__STDC_VERSION__ < 199901L)
@@ -186,16 +207,14 @@
 +/*
 + * The structure used for communication between the processes
 + */
-+
 +typedef struct _handle {
-+      size_t len;
 +      int errcode;
 +      struct stat argument;
 +      stat_t function;
++      size_t len;
++      char path[0];
 +} attribute((packed)) handle_t;
 +
-+static volatile handle_t handle;
-+
 +/*
 + * Using a forked process for doing e.g. stat(2) system call as this
 + * allows us to send e.g. SIGKILL to this process if it hangs in `D'
@@ -205,44 +224,72 @@
 +
 +static volatile pid_t active;
 +static int pipes[4] = {-1, -1, -1, -1};
++static char buf[PATH_MAX + sizeof(handle_t) + 1];
++
++static void sigchild(int sig attribute((unused)))
++{
++      pid_t pid = waitpid(active, NULL, WNOHANG|WUNTRACED);
++      if (pid <= 0)
++              return;
++      if (errno == ECHILD)
++              return;
++      active = 0;
++}
 +
 +static void attribute((constructor)) start(void)
 +{
 +      sigset_t sigset, oldset;
-+      char path[PATH_MAX];
-+      handle_t handle;
++      struct sigaction act;
 +      ssize_t in;
 +
++      if (pipes[1] >= 0) close(pipes[1]);
++      if (pipes[2] >= 0) close(pipes[2]);
++
 +      if (pipe(&pipes[0]))
 +              goto error;
 +      if (pipe(&pipes[2]))
 +              goto error;
++
++      memset(&act, 0, sizeof(act));
++      sigemptyset(&act.sa_mask);
++      act.sa_flags = SA_RESTART;
++      act.sa_handler = sigchild;
++      sigaction(SIGCHLD, &act, 0);
++
 +      if ((active = fork()) < 0)
 +              goto error;
++
 +      if (active) {
 +              close(pipes[0]);
 +              close(pipes[3]);
 +              pipes[0] = pipes[3] = -1;
 +              return;
 +      }
++
 +      sigemptyset(&sigset);
 +      sigaddset(&sigset, SIGALRM);
 +      sigprocmask(SIG_BLOCK, &sigset, &oldset);
 +
++      act.sa_handler = SIG_DFL;
++      sigaction(SIGCHLD, &act, 0);
++
 +      close(pipes[1]);
 +      close(pipes[2]);
-+      dup2(pipes[0], 0);
-+      dup2(pipes[3], 1);
++      dup2(pipes[0], STDIN_FILENO);
++      dup2(pipes[3], STDOUT_FILENO);
 +      close(pipes[0]);
 +      close(pipes[3]);
 +      pipes[1] = pipes[2] = -1;
 +      pipes[0] = pipes[3] = -1;
 +
-+      while ((in = read(0, &handle, sizeof(handle_t))) == sizeof(handle_t) &&
-+             (in = read(0, path, handle.len)) == handle.len) {
-+              if (handle.function(path, &handle.argument) < 0)
-+                      handle.errcode = errno;
-+              write(1, &handle.errcode, 
sizeof(handle.errcode)+sizeof(handle.argument));
++      {
++              handle_t *restrict handle = (void*)&buf[0];
++
++              while ((in = read(STDIN_FILENO, handle, sizeof(buf))) > 
sizeof(handle_t)) {
++                      if (handle->function(handle->path, &handle->argument) < 
0)
++                                      handle->errcode = errno;
++                      write(STDOUT_FILENO, &handle->errcode, 
sizeof(handle->errcode)+sizeof(handle->argument));
++              }
 +      }
 +      sigprocmask(SIG_SETMASK, &oldset, NULL);
 +      exit(0);
@@ -255,15 +302,12 @@
 +
 +static void /* attribute((destructor)) */ stop(void)
 +{
-+      if (active <= 0)
-+              return;
-+      if (waitpid(active, NULL, WNOHANG) == 0)
++      if (active && waitpid(active, NULL, WNOHANG|WUNTRACED) == 0)
 +              kill(active, SIGKILL);
-+      active = 0;
 +}
 +
 +static sigjmp_buf jenv;
-+static void sigalarm(int sig attribute((unused)))
++static void sigjump(int sig attribute((unused)))
 +{
 +      siglongjmp(jenv, 1);
 +}
@@ -271,61 +315,62 @@
 +/*
 + * External routine
 + */
-+
 +int timeout(stat_t function, const char *path, struct stat *restrict 
argument, time_t seconds)
 +{
-+      struct sigaction old_act, new_act;
++      handle_t *restrict handle = (void*)&buf[0];
++      struct sigaction alrm_act, pipe_act, new_act;
 +      sigset_t sigset, oldset;
 +
-+      if (active <= 0) {      /* Oops, last one failed therefore clear status 
and restart */
-+              int status;
-+              waitpid(-1, &status, WNOHANG);
++      if (active <= 0)        /* Oops, last one failed therefore clear status 
and restart */
 +              start();
-+      }
 +
-+      handle.len = strlen(path) + 1;
-+      if (handle.len >= PATH_MAX) {
++      handle->len = strlen(path) + 1;
++      if (handle->len >= PATH_MAX) {
 +              errno = ENAMETOOLONG;
 +              goto error;
 +      }
-+      handle.errcode = 0;
-+      handle.argument = *argument;
-+      handle.function = function;
++      handle->errcode = 0;
++      handle->argument = *argument;
++      handle->function = function;
++      strcpy(handle->path, path);
 +
 +      sigemptyset(&sigset);
 +      sigaddset(&sigset, SIGALRM);
++      sigaddset(&sigset, SIGPIPE);
 +      sigprocmask(SIG_UNBLOCK, &sigset, &oldset);
 +
 +      memset(&new_act, 0, sizeof(new_act));
 +      sigemptyset(&new_act.sa_mask);
 +      new_act.sa_flags = SA_RESETHAND;
-+      new_act.sa_handler = sigalarm;
 +
 +      if (sigsetjmp(jenv, 1))
 +              goto timed;
 +
-+      sigaction(SIGALRM, &new_act, &old_act);
++      new_act.sa_handler = sigjump;
++      sigaction(SIGALRM, &new_act, &alrm_act);
++      sigaction(SIGPIPE, &new_act, &pipe_act);
 +      alarm(seconds);
 +
-+      write(pipes[1], &handle, sizeof(handle_t));
-+      write(pipes[1], path, handle.len);
-+      sched_yield();
-+      read(pipes[2], &handle.errcode, 
sizeof(handle.errcode)+sizeof(handle.argument));
++      write(pipes[1], handle, sizeof(handle_t)+handle->len);
++      read(pipes[2], &handle->errcode, 
sizeof(handle->errcode)+sizeof(handle->argument));
 +
 +      alarm(0);
-+      sigaction(SIGALRM, &old_act, NULL);
++      sigaction(SIGPIPE, &pipe_act, NULL);
++      sigaction(SIGALRM, &alrm_act, NULL);
 +
-+      if (handle.errcode) {
-+              errno = handle.errcode;
++      if (handle->errcode) {
++              errno = handle->errcode;
 +              goto error;
 +      }
 +
-+      *argument = handle.argument;
++      *argument = handle->argument;
 +      sigprocmask(SIG_SETMASK, &oldset, NULL);
 +
 +      return 0;
 +timed:
 +      (void) alarm(0);
++      sigaction(SIGPIPE, &pipe_act, NULL);
++      sigaction(SIGALRM, &alrm_act, NULL);
 +      sigprocmask(SIG_SETMASK, &oldset, NULL);
 +      stop();
 +      errno = ETIMEDOUT;
@@ -337,7 +382,7 @@
 + * End of timeout.c
 + */
 diff --git a/src/timeout.h b/src/timeout.h
-index e69de29..50dd135 100644
+index e69de29..546c13b 100644
 --- a/src/timeout.h
 +++ b/src/timeout.h
 @@ -0,0 +1,36 @@

continue with "q"...



Remember to have fun...

-- 
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to