Author: arekm Date: Wed Mar 21 17:13:49 2012 GMT Module: packages Tag: HEAD ---- Log message: - rel 2; add timeout patch (from upstream); add fakerootpid patch that makes pstree work from user on kernel with hidepid feature
---- Files affected: packages/psmisc: psmisc.spec (1.108 -> 1.109) , psmisc-fakerootpid.patch (NONE -> 1.1) (NEW), psmisc-timeout.patch (NONE -> 1.1) (NEW) ---- Diffs: ================================================================ Index: packages/psmisc/psmisc.spec diff -u packages/psmisc/psmisc.spec:1.108 packages/psmisc/psmisc.spec:1.109 --- packages/psmisc/psmisc.spec:1.108 Wed Mar 21 15:52:42 2012 +++ packages/psmisc/psmisc.spec Wed Mar 21 18:13:44 2012 @@ -15,7 +15,7 @@ Summary(uk.UTF-8): Утиліти роботи з процесами Name: psmisc Version: 22.16 -Release: 1 +Release: 2 License: GPL v2+ Group: Applications/System Source0: http://downloads.sourceforge.net/psmisc/%{name}-%{version}.tar.gz @@ -23,6 +23,8 @@ Source1: http://www.mif.pg.gda.pl/homepages/ankry/man-PLD/%{name}-non-english-man-pages.tar.bz2 # Source1-md5: 9add7665e440bbd6b0b4f9293ba8b86d Patch0: %{name}-pl.po-update.patch +Patch1: %{name}-timeout.patch +Patch2: %{name}-fakerootpid.patch URL: http://psmisc.sourceforge.net/ BuildRequires: autoconf >= 2.68 BuildRequires: automake >= 1:1.10 @@ -89,6 +91,8 @@ %prep %setup -q %patch0 -p1 +%patch1 -p1 +%patch2 -p1 %build %{__gettextize} @@ -145,6 +149,9 @@ All persons listed below can be reached at <cvs_login>@pld-linux.org $Log$ +Revision 1.109 2012/03/21 17:13:44 arekm +- rel 2; add timeout patch (from upstream); add fakerootpid patch that makes pstree work from user on kernel with hidepid feature + Revision 1.108 2012/03/21 14:52:42 arekm - use timeout on stat calls ================================================================ Index: packages/psmisc/psmisc-fakerootpid.patch diff -u /dev/null packages/psmisc/psmisc-fakerootpid.patch:1.1 --- /dev/null Wed Mar 21 18:13:49 2012 +++ packages/psmisc/psmisc-fakerootpid.patch Wed Mar 21 18:13:44 2012 @@ -0,0 +1,30 @@ +diff -urN psmisc-22.16.org/src/pstree.c psmisc-22.16/src/pstree.c +--- psmisc-22.16.org/src/pstree.c 2012-02-20 00:07:14.000000000 +0100 ++++ psmisc-22.16/src/pstree.c 2012-03-21 18:07:44.000000000 +0100 +@@ -363,12 +363,25 @@ + ppid = 0; + if (isthread) + this->flags |= PFLAG_THREAD; +- if (!(parent = find_proc(ppid))) ++ if (!(parent = find_proc(ppid))) { ++ PROC *root; + #ifdef WITH_SELINUX + parent = new_proc("?", ppid, 0, scontext); + #else /*WITH_SELINUX */ + parent = new_proc("?", ppid, 0); + #endif /*WITH_SELINUX */ ++ /* When using kernel 3.3 with hidepid feature enabled on /proc ++ * then we need fake root pid */ ++ if (!(root = find_proc(1))) { ++#ifdef WITH_SELINUX ++ root = new_proc("?", 1, 0, scontext); ++#else /*WITH_SELINUX */ ++ root = new_proc("?", 1, 0); ++#endif ++ } ++ add_child(root, parent); ++ parent->parent = root; ++ } + add_child(parent, this); + this->parent = parent; + } ================================================================ Index: packages/psmisc/psmisc-timeout.patch diff -u /dev/null packages/psmisc/psmisc-timeout.patch:1.1 --- /dev/null Wed Mar 21 18:13:50 2012 +++ packages/psmisc/psmisc-timeout.patch Wed Mar 21 18:13:44 2012 @@ -0,0 +1,396 @@ +commit 54033e94bb8e038655f3241524da5616cb344435 +Author: Werner Fink <[email protected]> +Date: Tue Mar 13 14:49:52 2012 +0100 + + Add timeout.c/timeout.h for static background process for doing the stat system calls + + Signed-off-by: Werner Fink <[email protected]> + +diff --git a/src/timeout.c b/src/timeout.c +new file mode 100644 +index 0000000..1fe0354 +--- /dev/null ++++ b/src/timeout.c +@@ -0,0 +1,267 @@ ++/* ++ * timout.c Advanced timeout handling for file system calls ++ * to avoid deadlocks on remote file shares. ++ * ++ * Version: 0.1 07-Sep-2011 Fink ++ * ++ * Copyright 2011 Werner Fink, 2011 SUSE LINUX Products GmbH, Germany. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * Author: Werner Fink <[email protected]>, 2011 ++ */ ++ ++#ifndef _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> ++#include <pthread.h> ++#include <setjmp.h> ++#include <signal.h> ++#include <stdlib.h> ++#include <string.h> ++#include <sys/time.h> ++#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 "timeout.h" ++ ++#if !defined(__STDC_VERSION__) || (__STDC_VERSION__ < 199901L) ++# ifndef destructor ++# define destructor __destructor__ ++# endif ++# ifndef constructor ++# define constructor __constructor__ ++# endif ++# ifndef packed ++# define packed __packed__ ++# endif ++# ifndef inline ++# define inline __inline__ ++# endif ++# ifndef unused ++# define unused __unused__ ++# endif ++# ifndef volatile ++# define volatile __volatile__ ++# endif ++#endif ++#ifndef attribute ++# define attribute(attr) __attribute__(attr) ++#endif ++ ++#if defined __GNUC__ ++# undef strcpy ++# define strcpy(d,s) __builtin_strcpy((d),(s)) /* Without boundary check please */ ++#endif ++ ++/* ++ * The structure used for communication between the processes ++ */ ++typedef struct _handle { ++ int errcode; ++ struct stat argument; ++ stat_t function; ++ size_t len; ++ char path[0]; ++} attribute((packed)) handle_t; ++ ++/* ++ * 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' ++ * state on a file share due a stalled NFS server. This does not work ++ * with (p)threads as SIGKILL would kill all threads including main. ++ */ ++ ++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; ++ 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], STDIN_FILENO); ++ dup2(pipes[3], STDOUT_FILENO); ++ close(pipes[0]); ++ close(pipes[3]); ++ pipes[1] = pipes[2] = -1; ++ pipes[0] = pipes[3] = -1; ++ ++ { ++ 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)); ++ memset(handle, 0, sizeof(handle_t)); ++ } ++ } ++ sigprocmask(SIG_SETMASK, &oldset, NULL); ++ exit(0); ++error: ++ if (pipes[0] >= 0) close(pipes[0]); ++ if (pipes[1] >= 0) close(pipes[1]); ++ if (pipes[2] >= 0) close(pipes[2]); ++ if (pipes[3] >= 0) close(pipes[3]); ++} ++ ++static void /* attribute((destructor)) */ stop(void) ++{ ++ if (active && waitpid(active, NULL, WNOHANG|WUNTRACED) == 0) ++ kill(active, SIGKILL); ++} ++ ++static sigjmp_buf jenv; ++static void sigjump(int sig attribute((unused))) ++{ ++ siglongjmp(jenv, 1); ++} ++ ++/* ++ * External routine ++ */ ++int timeout(stat_t function, const char *path, struct stat *restrict argument, time_t seconds) ++{ ++ 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 */ ++ start(); ++ ++ memset(handle, 0, sizeof(handle_t)); ++ handle->len = strlen(path) + 1; ++ if (handle->len >= PATH_MAX) { ++ errno = ENAMETOOLONG; ++ goto error; ++ } ++ 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; ++ ++ if (sigsetjmp(jenv, 1)) ++ goto timed; ++ ++ 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)+handle->len); ++ read(pipes[2], &handle->errcode, sizeof(handle->errcode)+sizeof(handle->argument)); ++ ++ alarm(0); ++ sigaction(SIGPIPE, &pipe_act, NULL); ++ sigaction(SIGALRM, &alrm_act, NULL); ++ ++ if (handle->errcode) { ++ errno = handle->errcode; ++ goto error; ++ } ++ ++ *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; ++error: ++ return -1; ++} ++ ++/* ++ * End of timeout.c ++ */ +diff --git a/src/timeout.h b/src/timeout.h +new file mode 100644 +index 0000000..546c13b +--- /dev/null ++++ b/src/timeout.h +@@ -0,0 +1,36 @@ ++/* ++ * timout.h Advanced timeout handling for file system calls ++ * to avoid deadlocks on remote file shares. ++ * ++ * Version: 0.1 07-Sep-2011 Fink ++ * ++ * Copyright 2011 Werner Fink, 2011 SUSE LINUX Products GmbH, Germany. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * Author: Werner Fink <[email protected]>, 2011 ++ */ ++ ++#ifndef _TIMEOUT_H ++#define _TIMEOUT_H ++ ++#include "config.h" /* For _FILE_OFFSET_BITS */ ++ ++#include <sys/types.h> ++#include <sys/stat.h> ++#include <time.h> ++#include <limits.h> ++ ++#if !defined(__STDC_VERSION__) || (__STDC_VERSION__ < 199901L) ++# ifndef restrict ++# define restrict __restrict__ ++# endif ++#endif ++ ++typedef int (*stat_t)(const char *, struct stat *restrict); ++extern int timeout(stat_t, const char *, struct stat *restrict, time_t); ++ ++#endif +commit 378eea8bd5db4ed8244ce1a3f416137f131acdd5 +Author: Werner Fink <[email protected]> +Date: Tue Mar 13 16:15:43 2012 +0100 + + Use --enable-timeout-stat as well as --enable-timeout-stat=static + for a static background process which does the final stat system calls + + Signed-off-by: Werner Fink <[email protected]> + +diff --git a/configure.ac b/configure.ac +index 0615f5f..9265d82 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -30,12 +30,16 @@ AC_SUBST([SELINUX_LIB]) + # Call fork before all stat calls to stop hanging on NFS mounts + AC_SUBST([WITH_TIMEOUT_STAT]) + AC_ARG_ENABLE([timeout_stat], +- [AS_HELP_STRING([--enable-timeout-stat], [Use a timeout on stat calls])], ++ [AS_HELP_STRING([--enable-timeout-stat], [Use a timeout on stat calls (optional with argument "static" for a static background process)])], + [enable_timeout_stat=$enableval], + [enable_timeout_stat="no"]) + if test "$enable_timeout_stat" = "yes"; then + AC_DEFINE([WITH_TIMEOUT_STAT], [1], [Use timeout on stat calls]) + fi ++if test "$enable_timeout_stat" = "static"; then ++ AC_DEFINE([WITH_TIMEOUT_STAT], [2], [Use timeout on stat calls]) ++fi ++AM_CONDITIONAL([WANT_TIMEOUT_STAT], [test "$enable_timeout_stat" = "static"]) + + # Enable hardened compile and link flags + AC_ARG_ENABLE([harden_flags], +diff --git a/src/Makefile.am b/src/Makefile.am +index d511f24..a28af7d 100644 +--- a/src/Makefile.am ++++ b/src/Makefile.am +@@ -24,6 +24,9 @@ if WANT_PEEKFD_MIPS + endif + + fuser_SOURCES = fuser.c comm.h signals.c signals.h i18n.h fuser.h lists.h ++if WANT_TIMEOUT_STAT ++ fuser_SOURCES += timeout.c timeout.h ++endif + + fuser_LDADD = @LIBINTL@ + +diff --git a/src/fuser.c b/src/fuser.c +index e4081eb..09548ff 100644 +--- a/src/fuser.c ++++ b/src/fuser.c +@@ -111,9 +111,13 @@ static dev_t device(const char *path); + #endif + static char *expandpath(const char *path); + +-typedef int (*stat_t)(const char*, struct stat*); + #ifdef WITH_TIMEOUT_STAT ++# if (WITH_TIMEOUT_STAT == 2) ++# include "timeout.h" ++# else ++typedef int (*stat_t)(const char*, struct stat*); + static int timeout(stat_t func, const char *path, struct stat *buf, unsigned int seconds); ++# endif + #else + #define timeout(func,path,buf,dummy) (func)((path),(buf)) + #endif /* WITH_TIMEOUT_STAT */ +@@ -1783,7 +1787,7 @@ scan_swaps(struct names *names_head, struct inode_list *ino_head, + * Execute stat(2) system call with timeout to avoid deadlock + * on network based file systems. + */ +-#ifdef HAVE_TIMEOUT_STAT ++#if defined(WITH_TIMEOUT_STAT) && (WITH_TIMEOUT_STAT == 1) + + static sigjmp_buf jenv; + ================================================================ ---- CVS-web: http://cvs.pld-linux.org/packages/psmisc/psmisc.spec?r1=1.108&r2=1.109 _______________________________________________ pld-cvs-commit mailing list [email protected] http://lists.pld-linux.org/mailman/listinfo/pld-cvs-commit
