Three new flags for pkill/pgrep.
Pawel Jakub Dawidek
pjd at FreeBSD.org
Fri Mar 11 11:14:49 PST 2005
Hi.
I'm attaching patches (directly from perforce) which implements three
new flags:
-F pidfile Restrict matches to process which pid is stored in
pidfile file.
-i Ignore case distinctions in both the process table and
the supplied pattern.
-j jid Restrict matches to processes inside jails with a jail ID in
the comma-separated list jid. The value zero is taken to
mean any jail ID.
The '-F' option will allow for more safe kill `cat /var/run/daemon.pid`,
because one can call it as: pkill -F /var/run/sshd.pid sshd, so if pid
from the file not belongs to sshd daemon, it won't be killed.
The '-i' flag was obtained from Jonathan Perkin's patch posted on NetBSD
mailing list.
The '-j' option is simlar to Solaris' '-z' option (for Solaris zones).
In addition, there is a patch which allows to print process jail ID
from ps(1).
--
Pawel Jakub Dawidek http://www.wheel.pl
pjd at FreeBSD.org http://www.FreeBSD.org
FreeBSD committer Am I Evil? Yes, I Am!
-------------- next part --------------
http://perforce.freebsd.org/chv.cgi?CH=72889
Change 72889 by pjd at pjd_anger on 2005/03/11 12:15:59
Sort options properly.
Affected files ...
.. //depot/user/pjd/pkill/usr.bin/pkill/pkill.1#2 edit
Differences ...
==== //depot/user/pjd/pkill/usr.bin/pkill/pkill.1#2 (text+ko) ====
@@ -87,16 +87,16 @@
Restrict matches to processes with a real group ID in the comma-separated
list
.Ar gid .
-.It Fl P Ar ppid
-Restrict matches to processes with a parent process ID in the
-comma-separated list
-.Ar ppid .
.It Fl M Ar core
Extract values associated with the name list from the specified core
instead of the currently running system.
.It Fl N Ar system
Extract the name list from the specified system instead of the default,
which is the kernel image the system has booted from.
+.It Fl P Ar ppid
+Restrict matches to processes with a parent process ID in the
+comma-separated list
+.Ar ppid .
.It Fl U Ar uid
Restrict matches to processes with a real user ID in the comma-separated
list
-------------- next part --------------
http://perforce.freebsd.org/chv.cgi?CH=72890
Change 72890 by pjd at pjd_anger on 2005/03/11 12:16:51
Add '-F' options which allows to specify file which contains
process' PID.
Affected files ...
.. //depot/user/pjd/pkill/usr.bin/pkill/pkill.1#3 edit
.. //depot/user/pjd/pkill/usr.bin/pkill/pkill.c#2 edit
Differences ...
==== //depot/user/pjd/pkill/usr.bin/pkill/pkill.1#3 (text+ko) ====
@@ -45,6 +45,7 @@
.Sh SYNOPSIS
.Nm pgrep
.Op Fl flnvx
+.Op Fl F Ar pidfile
.Op Fl G Ar gid
.Op Fl M Ar core
.Op Fl N Ar system
@@ -59,6 +60,7 @@
.Nm pkill
.Op Fl Ar signal
.Op Fl fnvx
+.Op Fl F Ar pidfile
.Op Fl G Ar gid
.Op Fl M Ar core
.Op Fl N Ar system
@@ -82,7 +84,11 @@
processes that match the criteria given on the command line.
.Pp
The following options are available:
-.Bl -tag -width ".Fl d Ar delim"
+.Bl -tag -width ".Fl F Ar pidfile"
+.It Fl F Ar pidfile
+Restrict matches to process which pid is stored in
+.Ar pidfile
+file.
.It Fl G Ar gid
Restrict matches to processes with a real group ID in the comma-separated
list
==== //depot/user/pjd/pkill/usr.bin/pkill/pkill.c#2 (text+ko) ====
@@ -69,6 +69,9 @@
#define STATUS_BADUSAGE 2
#define STATUS_ERROR 3
+#define MIN_PID 5
+#define MAX_PID 99999
+
/* Check for system-processes which should always be ignored. */
#define IS_KERNPROC(kp) ((kp)->ki_flag & P_KTHREAD)
@@ -115,6 +118,7 @@
void killact(struct kinfo_proc *);
void grepact(struct kinfo_proc *);
void makelist(struct listhead *, enum listtype, char *);
+int takepid(const char *);
int
main(int argc, char **argv)
@@ -124,7 +128,7 @@
char buf[_POSIX2_LINE_MAX], *mstr, **pargv, *p, *q;
const char *execf, *coref;
int debug_opt;
- int i, ch, bestidx, rv, criteria;
+ int i, ch, bestidx, rv, criteria, pidfromfile;
size_t jsz;
void (*action)(struct kinfo_proc *);
struct kinfo_proc *kp;
@@ -166,13 +170,18 @@
criteria = 0;
debug_opt = 0;
+ pidfromfile = -1;
execf = coref = _PATH_DEVNULL;
- while ((ch = getopt(argc, argv, "DG:M:N:P:U:d:fg:lns:t:u:vx")) != -1)
+ while ((ch = getopt(argc, argv, "DF:G:M:N:P:U:d:fg:lns:t:u:vx")) != -1)
switch (ch) {
case 'D':
debug_opt++;
break;
+ case 'F':
+ pidfromfile = takepid(optarg);
+ criteria = 1;
+ break;
case 'G':
makelist(&rgidlist, LT_GROUP, optarg);
criteria = 1;
@@ -330,6 +339,11 @@
if (IS_KERNPROC(kp) != 0)
continue;
+ if (pidfromfile >= 0 && kp->ki_pid != pidfromfile) {
+ selected[i] = 0;
+ continue;
+ }
+
SLIST_FOREACH(li, &ruidlist, li_chain)
if (kp->ki_ruid == (uid_t)li->li_number)
break;
@@ -578,3 +592,33 @@
if (empty)
usage();
}
+
+int
+takepid(const char *pidfile)
+{
+ char *endp, line[BUFSIZ];
+ FILE *fh;
+ long rval;
+
+ fh = fopen(pidfile, "r");
+ if (fh == NULL)
+ err(STATUS_ERROR, "can't open pid file `%s'", pidfile);
+
+ if (fgets(line, sizeof(line), fh) == NULL) {
+ if (feof(fh)) {
+ (void)fclose(fh);
+ errx(STATUS_ERROR, "pid file `%s' is empty", pidfile);
+ }
+ (void)fclose(fh);
+ err(STATUS_ERROR, "can't read from pid file `%s'", pidfile);
+ }
+ (void)fclose(fh);
+
+ errno = 0;
+ rval = strtol(line, &endp, 10);
+ if (*endp != '\0' && !isspace(*endp))
+ errx(STATUS_ERROR, "invalid pid in file `%s'", pidfile);
+ else if (rval < MIN_PID || rval > MAX_PID)
+ errx(STATUS_ERROR, "invalid pid in file `%s'", pidfile);
+ return (rval);
+}
-------------- next part --------------
http://perforce.freebsd.org/chv.cgi?CH=72891
Change 72891 by pjd at pjd_anger on 2005/03/11 12:31:09
Document '-F' option in usage.
Affected files ...
.. //depot/user/pjd/pkill/usr.bin/pkill/pkill.c#3 edit
Differences ...
==== //depot/user/pjd/pkill/usr.bin/pkill/pkill.c#3 (text+ko) ====
@@ -464,7 +464,7 @@
ustr = "[-signal] [-fnvx]";
fprintf(stderr,
- "usage: %s %s [-G gid] [-M core] [-N system]\n"
+ "usage: %s %s [-F pidfile] [-G gid] [-M core] [-N system]\n"
" [-P ppid] [-U uid] [-g pgrp] [-s sid] [-t tty]\n"
" [-u euid] pattern ...\n", getprogname(), ustr);
-------------- next part --------------
http://perforce.freebsd.org/chv.cgi?CH=72892
Change 72892 by pjd at pjd_anger on 2005/03/11 12:33:34
Implement '-i' option which allows to ignore case distinctions in
both the process table and the supplied pattern.
Obtained from: Jonathan Perkin <jonathan at perkin.org.uk>
Affected files ...
.. //depot/user/pjd/pkill/usr.bin/pkill/pkill.1#4 edit
.. //depot/user/pjd/pkill/usr.bin/pkill/pkill.c#4 edit
Differences ...
==== //depot/user/pjd/pkill/usr.bin/pkill/pkill.1#4 (text+ko) ====
@@ -44,7 +44,7 @@
.Nd find or signal processes by name
.Sh SYNOPSIS
.Nm pgrep
-.Op Fl flnvx
+.Op Fl filnvx
.Op Fl F Ar pidfile
.Op Fl G Ar gid
.Op Fl M Ar core
@@ -59,7 +59,7 @@
.Ar pattern ...
.Nm pkill
.Op Fl Ar signal
-.Op Fl fnvx
+.Op Fl finvx
.Op Fl F Ar pidfile
.Op Fl G Ar gid
.Op Fl M Ar core
@@ -125,6 +125,8 @@
or
.Nm pkill
command.
+.It Fl i
+Ignore case distinctions in both the process table and the supplied pattern.
.It Fl l
Long output.
Print the process name in addition to the process ID for each matching
==== //depot/user/pjd/pkill/usr.bin/pkill/pkill.c#4 (text+ko) ====
@@ -102,6 +102,7 @@
int longfmt;
int matchargs;
int fullmatch;
+int cflags = REG_EXTENDED;
kvm_t *kd;
pid_t mypid;
@@ -173,7 +174,7 @@
pidfromfile = -1;
execf = coref = _PATH_DEVNULL;
- while ((ch = getopt(argc, argv, "DF:G:M:N:P:U:d:fg:lns:t:u:vx")) != -1)
+ while ((ch = getopt(argc, argv, "DF:G:M:N:P:U:d:fg:ilns:t:u:vx")) != -1)
switch (ch) {
case 'D':
debug_opt++;
@@ -212,6 +213,9 @@
makelist(&pgrplist, LT_PGRP, optarg);
criteria = 1;
break;
+ case 'i':
+ cflags |= REG_ICASE;
+ break;
case 'l':
if (!pgrep)
usage();
@@ -280,7 +284,7 @@
* Refine the selection.
*/
for (; *argv != NULL; argv++) {
- if ((rv = regcomp(®, *argv, REG_EXTENDED)) != 0) {
+ if ((rv = regcomp(®, *argv, cflags)) != 0) {
regerror(rv, ®, buf, sizeof(buf));
errx(STATUS_BADUSAGE, "bad expression: %s", buf);
}
@@ -459,7 +463,7 @@
const char *ustr;
if (pgrep)
- ustr = "[-flnvx] [-d delim]";
+ ustr = "[-filnvx] [-d delim]";
else
ustr = "[-signal] [-fnvx]";
-------------- next part --------------
http://perforce.freebsd.org/chv.cgi?CH=72918
Change 72918 by pjd at pjd_anger on 2005/03/11 18:47:26
Add missing '-i' flag.
Affected files ...
.. //depot/user/pjd/pkill/usr.bin/pkill/pkill.c#5 edit
Differences ...
==== //depot/user/pjd/pkill/usr.bin/pkill/pkill.c#5 (text+ko) ====
@@ -465,7 +465,7 @@
if (pgrep)
ustr = "[-filnvx] [-d delim]";
else
- ustr = "[-signal] [-fnvx]";
+ ustr = "[-signal] [-finvx]";
fprintf(stderr,
"usage: %s %s [-F pidfile] [-G gid] [-M core] [-N system]\n"
-------------- next part --------------
http://perforce.freebsd.org/chv.cgi?CH=72906
Change 72906 by pjd at pjd_anger on 2005/03/11 16:26:07
Made structure prison visible from userland if _WANT_PRISON is
specified.
Affected files ...
.. //depot/user/pjd/pkill/sys/sys/jail.h#2 edit
Differences ...
==== //depot/user/pjd/pkill/sys/sys/jail.h#2 (text+ko) ====
@@ -46,6 +46,7 @@
#ifdef MALLOC_DECLARE
MALLOC_DECLARE(M_PRISON);
#endif
+#endif /* _KERNEL */
/*
* This structure describes a prison. It is pointed to by all struct
@@ -59,6 +60,7 @@
* required to read
* (d) set only during destruction of jail, no mutex needed
*/
+#if defined(_KERNEL) || defined(_WANT_PRISON)
struct prison {
LIST_ENTRY(prison) pr_list; /* (a) all prisons */
int pr_id; /* (c) prison id */
@@ -72,7 +74,9 @@
struct task pr_task; /* (d) destroy task */
struct mtx pr_mtx;
};
+#endif /* _KERNEL || _WANT_PRISON */
+#ifdef _KERNEL
/*
* Sysctl-set variables that determine global jail policy
*
@@ -105,5 +109,5 @@
int prison_ip(struct ucred *cred, int flag, u_int32_t *ip);
void prison_remote_ip(struct ucred *cred, int flags, u_int32_t *ip);
-#endif /* !_KERNEL */
+#endif /* _KERNEL */
#endif /* !_SYS_JAIL_H_ */
-------------- next part --------------
http://perforce.freebsd.org/chv.cgi?CH=72916
Change 72916 by pjd at pjd_anger on 2005/03/11 18:38:09
Add ki_jid field which contains process' jail ID.
If asking process is closed in jail, put 0 into this field for all
processes.
Teach kvm(3) how to handle prison structure.
Size of kinfo_proc structure verified on: i386, amd64, ia64, sparc64, alpha
Affected files ...
.. //depot/user/pjd/pkill/lib/libkvm/kvm_proc.c#2 edit
.. //depot/user/pjd/pkill/sys/kern/kern_proc.c#2 edit
.. //depot/user/pjd/pkill/sys/sys/user.h#2 edit
Differences ...
==== //depot/user/pjd/pkill/lib/libkvm/kvm_proc.c#2 (text+ko) ====
@@ -54,6 +54,12 @@
#include <sys/param.h>
#define _WANT_UCRED /* make ucred.h give us 'struct ucred' */
#include <sys/ucred.h>
+#include <sys/queue.h>
+#include <sys/_lock.h>
+#include <sys/_mutex.h>
+#include <sys/_task.h>
+#define _WANT_PRISON /* make jail.h give us 'struct prison' */
+#include <sys/jail.h>
#include <sys/user.h>
#include <sys/proc.h>
#include <sys/exec.h>
@@ -105,6 +111,7 @@
struct sigacts sigacts;
struct pstats pstats;
struct ucred ucred;
+ struct prison pr;
struct thread mtd;
/*struct kse mke;*/
struct ksegrp mkg;
@@ -159,6 +166,15 @@
bcopy(ucred.cr_groups, kp->ki_groups,
NGROUPS * sizeof(gid_t));
kp->ki_uid = ucred.cr_uid;
+ if (ucred.cr_prison != NULL) {
+ if (KREAD(kd, (u_long)ucred.cr_prison, &pr)) {
+ _kvm_err(kd, kd->program,
+ "can't read prison at %x",
+ ucred.cr_prison);
+ return (-1);
+ }
+ kp->ki_jid = pr.pr_id;
+ }
}
switch(what & ~KERN_PROC_INC_THREAD) {
==== //depot/user/pjd/pkill/sys/kern/kern_proc.c#2 (text+ko) ====
@@ -612,6 +612,7 @@
struct tty *tp;
struct session *sp;
struct timeval tv;
+ struct ucred *cred;
struct sigacts *ps;
p = td->td_proc;
@@ -632,19 +633,28 @@
#endif
kp->ki_fd = p->p_fd;
kp->ki_vmspace = p->p_vmspace;
- if (p->p_ucred) {
- kp->ki_uid = p->p_ucred->cr_uid;
- kp->ki_ruid = p->p_ucred->cr_ruid;
- kp->ki_svuid = p->p_ucred->cr_svuid;
+ kp->ki_flag = p->p_flag;
+ cred = p->p_ucred;
+ if (cred) {
+ kp->ki_uid = cred->cr_uid;
+ kp->ki_ruid = cred->cr_ruid;
+ kp->ki_svuid = cred->cr_svuid;
/* XXX bde doesn't like KI_NGROUPS */
- kp->ki_ngroups = min(p->p_ucred->cr_ngroups, KI_NGROUPS);
- bcopy(p->p_ucred->cr_groups, kp->ki_groups,
+ kp->ki_ngroups = min(cred->cr_ngroups, KI_NGROUPS);
+ bcopy(cred->cr_groups, kp->ki_groups,
kp->ki_ngroups * sizeof(gid_t));
- kp->ki_rgid = p->p_ucred->cr_rgid;
- kp->ki_svgid = p->p_ucred->cr_svgid;
+ kp->ki_rgid = cred->cr_rgid;
+ kp->ki_svgid = cred->cr_svgid;
+ /* If jailed(cred), emulate the old P_JAILED flag. */
+ if (jailed(cred)) {
+ kp->ki_flag |= P_JAILED;
+ /* If inside a jail, use 0 as a jail ID. */
+ if (!jailed(td->td_ucred))
+ kp->ki_jid = cred->cr_prison->pr_id;
+ }
}
- if (p->p_sigacts) {
- ps = p->p_sigacts;
+ ps = p->p_sigacts;
+ if (ps) {
mtx_lock(&ps->ps_mtx);
kp->ki_sigignore = ps->ps_sigignore;
kp->ki_sigcatch = ps->ps_sigcatch;
@@ -752,7 +762,6 @@
kp->ki_childtime = kp->ki_childstime;
timevaladd(&kp->ki_childtime, &kp->ki_childutime);
}
- sp = NULL;
tp = NULL;
if (p->p_pgrp) {
kp->ki_pgid = p->p_pgrp->pg_id;
@@ -791,10 +800,6 @@
kp->ki_sigmask = td->td_sigmask;
kp->ki_xstat = p->p_xstat;
kp->ki_acflag = p->p_acflag;
- kp->ki_flag = p->p_flag;
- /* If jailed(p->p_ucred), emulate the old P_JAILED flag. */
- if (jailed(p->p_ucred))
- kp->ki_flag |= P_JAILED;
kp->ki_lock = p->p_lock;
if (p->p_pptr)
kp->ki_ppid = p->p_pptr->p_pid;
==== //depot/user/pjd/pkill/sys/sys/user.h#2 (text+ko) ====
@@ -74,7 +74,7 @@
* end of kinfo_proc. It may need to be overridden on a platform-specific
* basis as new fields are added.
*/
-#define KI_NSPARE 16
+#define KI_NSPARE 15
#ifdef __alpha__
#define KINFO_PROC_SIZE 912
@@ -84,7 +84,7 @@
#endif
#ifdef __arm__
#undef KI_NSPARE /* Fewer spare longs on this arch */
-#define KI_NSPARE 15
+#define KI_NSPARE 14
#define KINFO_PROC_SIZE 648
#endif
#ifdef __ia64__
@@ -92,7 +92,7 @@
#endif
#ifdef __i386__
#undef KI_NSPARE /* Fewer spare longs on this arch */
-#define KI_NSPARE 15
+#define KI_NSPARE 14
#define KINFO_PROC_SIZE 648
#endif
#ifdef __powerpc__
@@ -187,6 +187,7 @@
lwpid_t ki_tid; /* XXXKSE thread id */
int ki_numthreads; /* XXXKSE number of threads in total */
void *ki_udata; /* User convenience pointer */
+ int ki_jid; /* Process jail ID */
long ki_spare[KI_NSPARE]; /* spare room for later growth */
};
void fill_kinfo_proc(struct proc *, struct kinfo_proc *);
-------------- next part --------------
http://perforce.freebsd.org/chv.cgi?CH=72919
Change 72919 by pjd at pjd_anger on 2005/03/11 18:48:57
Add '-j' flag which allows to match processes based on their jail ID.
Affected files ...
.. //depot/user/pjd/pkill/usr.bin/pkill/pkill.1#5 edit
.. //depot/user/pjd/pkill/usr.bin/pkill/pkill.c#6 edit
Differences ...
==== //depot/user/pjd/pkill/usr.bin/pkill/pkill.1#5 (text+ko) ====
@@ -53,6 +53,7 @@
.Op Fl U Ar uid
.Op Fl d Ar delim
.Op Fl g Ar pgrp
+.Op Fl j Ar jid
.Op Fl s Ar sid
.Op Fl t Ar tty
.Op Fl u Ar euid
@@ -67,6 +68,7 @@
.Op Fl P Ar ppid
.Op Fl U Ar uid
.Op Fl g Ar pgrp
+.Op Fl j Ar jid
.Op Fl s Ar sid
.Op Fl t Ar tty
.Op Fl u Ar euid
@@ -127,6 +129,11 @@
command.
.It Fl i
Ignore case distinctions in both the process table and the supplied pattern.
+.It Fl j Ar jid
+Restrict matches to processes inside jails with a jail ID in the comma-separated
+list
+.Ar jid .
+The value zero is taken to mean any jail ID.
.It Fl l
Long output.
Print the process name in addition to the process ID for each matching
==== //depot/user/pjd/pkill/usr.bin/pkill/pkill.c#6 (text+ko) ====
@@ -113,6 +113,7 @@
struct listhead ppidlist = SLIST_HEAD_INITIALIZER(list);
struct listhead tdevlist = SLIST_HEAD_INITIALIZER(list);
struct listhead sidlist = SLIST_HEAD_INITIALIZER(list);
+struct listhead jidlist = SLIST_HEAD_INITIALIZER(list);
int main(int, char **);
void usage(void);
@@ -174,7 +175,7 @@
pidfromfile = -1;
execf = coref = _PATH_DEVNULL;
- while ((ch = getopt(argc, argv, "DF:G:M:N:P:U:d:fg:ilns:t:u:vx")) != -1)
+ while ((ch = getopt(argc, argv, "DF:G:M:N:P:U:d:fg:ij:lns:t:u:vx")) != -1)
switch (ch) {
case 'D':
debug_opt++;
@@ -216,6 +217,10 @@
case 'i':
cflags |= REG_ICASE;
break;
+ case 'j':
+ makelist(&jidlist, LT_GENERIC, optarg);
+ criteria = 1;
+ break;
case 'l':
if (!pgrep)
usage();
@@ -408,6 +413,19 @@
continue;
}
+ SLIST_FOREACH(li, &jidlist, li_chain) {
+ if (kp->ki_jid > 0) {
+ if (li->li_number == 0)
+ break;
+ if (kp->ki_jid == (int)li->li_number)
+ break;
+ }
+ }
+ if (SLIST_FIRST(&jidlist) != NULL && li == NULL) {
+ selected[i] = 0;
+ continue;
+ }
+
if (argc == 0)
selected[i] = 1;
}
@@ -469,8 +487,9 @@
fprintf(stderr,
"usage: %s %s [-F pidfile] [-G gid] [-M core] [-N system]\n"
- " [-P ppid] [-U uid] [-g pgrp] [-s sid] [-t tty]\n"
- " [-u euid] pattern ...\n", getprogname(), ustr);
+ " [-P ppid] [-U uid] [-g pgrp] [-j jid] [-s sid]\n"
+ " [-t tty] [-u euid] pattern ...\n", getprogname(),
+ ustr);
exit(STATUS_ERROR);
}
-------------- next part --------------
http://perforce.freebsd.org/chv.cgi?CH=72920
Change 72920 by pjd at pjd_anger on 2005/03/11 18:50:31
Allow to display process' jail ID.
Affected files ...
.. //depot/user/pjd/pkill/bin/ps/keyword.c#2 edit
.. //depot/user/pjd/pkill/bin/ps/ps.1#2 edit
Differences ...
==== //depot/user/pjd/pkill/bin/ps/keyword.c#2 (text+ko) ====
@@ -95,6 +95,7 @@
{"inblk", "INBLK", NULL, USER, rvar, NULL, 4, ROFF(ru_inblock), LONG,
"ld", 0},
{"inblock", "", "inblk", 0, NULL, NULL, 0, 0, CHAR, NULL, 0},
+ {"jid", "JID", NULL, 0, kvar, NULL, 6, KOFF(ki_jid), INT, "d", 0},
{"jobc", "JOBC", NULL, 0, kvar, NULL, 4, KOFF(ki_jobc), SHORT, "d",
0},
{"ktrace", "KTRACE", NULL, 0, kvar, NULL, 8, KOFF(ki_traceflag), INT,
==== //depot/user/pjd/pkill/bin/ps/ps.1#2 (text+ko) ====
@@ -471,6 +471,8 @@
.It Cm inblk
total blocks read (alias
.Cm inblock )
+.It Cm jid
+jail ID
.It Cm jobc
job control count
.It Cm ktrace
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 187 bytes
Desc: not available
Url : http://lists.freebsd.org/pipermail/freebsd-current/attachments/20050311/15b71976/attachment.bin
More information about the freebsd-current
mailing list