Fix and extend the -j option to pkill/pgrep WRT the jail

wildcard specifications.  Earlier the only wildcard syntax
was "-j 0" for "any jail".  There were at least
two shortcomings in it:  First, jail ID 0 was abused; it
meant "no jail" in other utils, e.g., ps(1).  Second, it
was impossible to match processed not in jail, which could
be useful to rc.d developers.  Therefore a new syntax is
introduced: "-j any" means any jail while "-j none" means
out of jail.  The old syntax is preserved for compatibility,
but now it's deprecated because it's limited and confusing.

Update the respective regression tests.  While I'm here,
make the tests more complex but sensitive:  Start several
processes, some in jail and some out of jail, so we can
detect that only the right processes are killed by pkill
or matched by pgrep.

Reviewed by:	gad, pjd
MFC after:	1 week
This commit is contained in:
yar 2006-11-23 11:55:17 +00:00
parent 75d7b09c83
commit af6cce5172
4 changed files with 131 additions and 44 deletions

View File

@ -3,43 +3,73 @@
base=`basename $0`
echo "1..2"
echo "1..3"
name="pgrep -j <jid>"
if [ `id -u` -eq 0 ]; then
sleep=`mktemp /tmp/$base.XXXXXX` || exit 1
ln -sf /bin/sleep $sleep
jail / temp 127.0.0.1 $sleep 5 &
sleep 0.3
jail / $base-1 127.0.0.1 $sleep 5 &
chpid=$!
jid=`jls | egrep '127\.0\.0\.1.*temp.*\/' | awk '{print $1}'`
jail / $base-2 127.0.0.1 $sleep 5 &
chpid2=$!
$sleep 5 &
chpid3=$!
sleep 0.5
jid=`jls | awk "/127\\.0\\.0\\.1.*${base}-1/ {print \$1}"`
pid=`pgrep -f -j $jid $sleep`
if [ "$pid" = "$chpid" ]; then
echo "ok 1 - $name"
else
echo "not ok 1 - $name"
fi
kill $chpid
kill $chpid $chpid2 $chpid3
rm -f $sleep
else
echo "ok 1 - $name # skip Test needs uid 0."
fi
name="pgrep -j 0"
name="pgrep -j any"
if [ `id -u` -eq 0 ]; then
sleep=`mktemp /tmp/$base.XXXXXX` || exit 1
ln -sf /bin/sleep $sleep
jail / temp 127.0.0.1 $sleep 5 &
sleep 0.3
jail / $base-1 127.0.0.1 $sleep 5 &
chpid=$!
pid=`pgrep -f -j 0 $sleep`
if [ "$pid" = "$chpid" ]; then
jail / $base-2 127.0.0.1 $sleep 5 &
chpid2=$!
$sleep 5 &
chpid3=$!
sleep 0.5
pids=`pgrep -f -j any $sleep | sort`
refpids=`{ echo $chpid; echo $chpid2; } | sort`
if [ "$pids" = "$refpids" ]; then
echo "ok 2 - $name"
else
echo "not ok 2 - $name"
fi
kill $chpid
kill $chpid $chpid2 $chpid3
rm -f $sleep
else
echo "ok 2 - $name # skip Test needs uid 0."
fi
name="pgrep -j none"
if [ `id -u` -eq 0 ]; then
sleep=`mktemp /tmp/$base.XXXXXX` || exit 1
ln -sf /bin/sleep $sleep
$sleep 5 &
chpid=$!
jail / $base 127.0.0.1 $sleep 5 &
chpid2=$!
sleep 0.5
pid=`pgrep -f -j none $sleep`
if [ "$pid" = "$chpid" ]; then
echo "ok 3 - $name"
else
echo "not ok 3 - $name"
fi
kill $chpid $chpid2
rm -f $sleep
else
echo "ok 3 - $name # skip Test needs uid 0."
fi

View File

@ -3,47 +3,69 @@
base=`basename $0`
echo "1..2"
echo "1..3"
name="pkill -j <jid>"
if [ `id -u` -eq 0 ]; then
sleep=`mktemp /tmp/$base.XXXXXX` || exit 1
ln -sf /bin/sleep $sleep
jail / temp 127.0.0.1 $sleep 5 &
sleep 0.3
jid=`jls | egrep '127\.0\.0\.1.*temp.*\/' | awk '{print $1}'`
pkill -f -j $jid $sleep
ec=$?
case $ec in
0)
jail / $base-1 127.0.0.1 $sleep 5 &
chpid=$!
jail / $base-2 127.0.0.1 $sleep 5 &
chpid2=$!
$sleep 5 &
chpid3=$!
sleep 0.5
jid=`jls | awk "/127\\.0\\.0\\.1.*${base}-1/ {print \$1}"`
if pkill -f -j $jid $sleep && sleep 0.5 &&
! kill $chpid && kill $chpid2 $chpid3; then
echo "ok 1 - $name"
;;
*)
else
echo "not ok 1 - $name"
;;
esac
fi 2>/dev/null
rm -f $sleep
else
echo "ok 1 - $name # skip Test needs uid 0."
fi
name="pkill -j 0"
name="pkill -j any"
if [ `id -u` -eq 0 ]; then
sleep=`mktemp /tmp/$base.XXXXXX` || exit 1
ln -sf /bin/sleep $sleep
jail / temp 127.0.0.1 $sleep 5 &
sleep 0.3
pkill -f -j 0 $sleep
ec=$?
case $ec in
0)
jail / $base-1 127.0.0.1 $sleep 5 &
chpid=$!
jail / $base-2 127.0.0.1 $sleep 5 &
chpid2=$!
$sleep 5 &
chpid3=$!
sleep 0.5
if pkill -f -j any $sleep && sleep 0.5 &&
! kill $chpid && ! kill $chpid2 && kill $chpid3; then
echo "ok 2 - $name"
;;
*)
else
echo "not ok 2 - $name"
;;
esac
fi 2>/dev/null
rm -f $sleep
else
echo "ok 1 - $name # skip Test needs uid 0."
echo "ok 2 - $name # skip Test needs uid 0."
fi
name="pkill -j none"
if [ `id -u` -eq 0 ]; then
sleep=`mktemp /tmp/$base.XXXXXX` || exit 1
ln -sf /bin/sleep $sleep
$sleep 5 &
chpid=$!
jail / $base 127.0.0.1 $sleep 5 &
chpid2=$!
sleep 0.5
if pkill -f -j none $sleep && sleep 0.5 &&
! kill $chpid && kill $chpid2; then
echo "ok 3 - $name"
else
echo "not ok 3 - $name"
fi 2>/dev/null
rm -f $sleep
else
echo "ok 3 - $name # skip Test needs uid 0."
fi

View File

@ -36,7 +36,7 @@
.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
.\" POSSIBILITY OF SUCH DAMAGE.
.\"
.Dd November 16, 2005
.Dd November 23, 2006
.Dt PKILL 1
.Os
.Sh NAME
@ -146,7 +146,12 @@ Ignore case distinctions in both the process table and the supplied pattern.
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.
The value
.Dq Li any
matches processes in any jail.
The value
.Dq Li none
matches processes not in jail.
.It Fl l
Long output.
Print the process name in addition to the process ID for each matching
@ -240,6 +245,18 @@ Invalid options were specified on the command line.
.It 3
An internal error occurred.
.El
.Sh COMPATIBILITY
Historically the option
.Dq Fl j Li 0
means any jail, although in other utilities such as
.Xr ps 1
jail ID
.Li 0
has the opposite meaning, not in jail.
Therefore
.Dq Fl j Li 0
is deprecated, and its use is discouraged in favor of
.Dq Fl j Li any .
.Sh SEE ALSO
.Xr kill 1 ,
.Xr killall 1 ,

View File

@ -84,6 +84,7 @@ enum listtype {
LT_GROUP,
LT_TTY,
LT_PGRP,
LT_JID,
LT_SID
};
@ -235,7 +236,7 @@ main(int argc, char **argv)
cflags |= REG_ICASE;
break;
case 'j':
makelist(&jidlist, LT_GENERIC, optarg);
makelist(&jidlist, LT_JID, optarg);
criteria = 1;
break;
case 'l':
@ -451,12 +452,12 @@ main(int argc, char **argv)
}
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;
}
/* A particular jail ID, including 0 (not in jail) */
if (kp->ki_jid == (int)li->li_number)
break;
/* Any jail */
if (kp->ki_jid > 0 && li->li_number == -1)
break;
}
if (SLIST_FIRST(&jidlist) != NULL && li == NULL) {
selected[i] = 0;
@ -636,6 +637,14 @@ makelist(struct listhead *head, enum listtype type, char *src)
if (li->li_number == 0)
li->li_number = getsid(mypid);
break;
case LT_JID:
if (li->li_number < 0)
errx(STATUS_BADUSAGE,
"Negative jail ID `%s'", sp);
/* For compatibility with old -j */
if (li->li_number == 0)
li->li_number = -1; /* any jail */
break;
case LT_TTY:
usage();
/* NOTREACHED */
@ -683,6 +692,15 @@ makelist(struct listhead *head, enum listtype type, char *src)
li->li_number = st.st_rdev;
break;
case LT_JID:
if (strcmp(sp, "none") == 0)
li->li_number = 0;
else if (strcmp(sp, "any") == 0)
li->li_number = -1;
else if (*ep != '\0')
errx(STATUS_BADUSAGE,
"Invalid jail ID `%s'", sp);
break;
default:
usage();
}