Skip to content

Commit

Permalink
OS-1395 kernel should not kill a GZ process preventing zone shutdown …
Browse files Browse the repository at this point in the history
…if process is not a shell or child of a shell
  • Loading branch information
jjelinek committed Jul 18, 2012
1 parent 7d858a1 commit 6406848
Show file tree
Hide file tree
Showing 3 changed files with 93 additions and 54 deletions.
49 changes: 31 additions & 18 deletions overlay/generic/usr/lib/brand/joyent-minimal/statechange
Original file line number Diff line number Diff line change
Expand Up @@ -497,7 +497,7 @@ cleanup_net()
done
}

kill_gz_sockholder()
id_gz_sockholder()
{
echo "searching for GZ process holding socket $1"
logger -p daemon.err "zone $ZONENAME " \
Expand All @@ -512,28 +512,41 @@ kill_gz_sockholder()
[ -z "$pid" ] && return
echo "killing GZ process $pid holding socket $1"
logger -p daemon.err "zone $ZONENAME " \
"killing GZ process $pid holding socket $1"
kill -9 $pid
echo "Error: GZ process $pid holding socket $1 blocking shutdown"
logger -p daemon.err "Error: zone $ZONENAME:" \
"GZ process $pid holding socket $1 blocking shutdown"
}
# zonadmd unable to unmount the given path, try to cleanup so unmount can
# succeed.
cleanup_mount()
{
echo "attempting to cleanup mount $1"
logger -p daemon.err "zone $ZONENAME " \
"attempting to cleanup mount $1"
logger -p daemon.err "zone $ZONENAME attempting to cleanup mount $1"
cnt=`fuser -c $1 2>/dev/null | wc -w`
if [ $cnt -gt 0 ]; then
echo "trying to kill GZ processes under $1"
logger -p daemon.err "zone $ZONENAME " \
"trying to kill GZ processes under $1"
fuser -ck $1
fnd_procs=0
for i in `fuser -c $1 2>/dev/null`
do
fnd_procs=1
pty=`ps -otty -p $i | \
nawk '{if ($1 != "TT" && $1 != "?") print $0}'`
if [ -n "$pty" ]; then
echo "shell process $i blocking zone" \
"$ZONENAME shutdown, killing the process" | wall
echo "killing GZ user shell $i under $1"
logger -p daemon.err "zone $ZONENAME:" \
"killing GZ user shell $i under $1"
kill -9 $i
else
echo "Error: GZ process $i under $1 blocking shutdown"
logger -p daemon.err "Error: zone $ZONENAME:" \
"GZ process $i under $1 blocking shutdown"
fi
done
if [ $fnd_procs -eq 1 ]; then
# Exit out to give the zoneadmd umount a chance to suceed now.
# Zoneadmd will give us another shot if it still can't umount.
sleep 1
Expand All @@ -545,20 +558,20 @@ cleanup_mount()
# zone's root. For example, a zone with its root at /zones/foo/root and
# an open socket as /zones/foo/root/var/run/x will show up in a pfiles
# search as /var/run/x. This is a problem since we have no way to
# narrow down which process to kill.
# narrow down which process is the culprit.
#
# Because the socket doesn't have enough information for us to tie to
# the specific GZ process, we hardcode to kill things we know will open
# the specific GZ process, we hardcode to id things we know will open
# sockets into the zone:
# /var/run/smartdc/metadata.sock
# /var/run/.smartdc-amon.sock
ZVR=$ZONEPATH/root/var/run
[ -S $ZVR/smartdc/metadata.sock ] &&
kill_gz_sockholder /var/run/smartdc/metadata.sock
id_gz_sockholder /var/run/smartdc/metadata.sock
[ -S $ZVR/.smartdc-amon.sock ] &&
kill_gz_sockholder /var/run/.smartdc-amon.sock
id_gz_sockholder /var/run/.smartdc-amon.sock
}
#
Expand Down
49 changes: 31 additions & 18 deletions overlay/generic/usr/lib/brand/joyent/statechange
Original file line number Diff line number Diff line change
Expand Up @@ -497,7 +497,7 @@ cleanup_net()
done
}

kill_gz_sockholder()
id_gz_sockholder()
{
echo "searching for GZ process holding socket $1"
logger -p daemon.err "zone $ZONENAME " \
Expand All @@ -512,28 +512,41 @@ kill_gz_sockholder()
[ -z "$pid" ] && return
echo "killing GZ process $pid holding socket $1"
logger -p daemon.err "zone $ZONENAME " \
"killing GZ process $pid holding socket $1"
kill -9 $pid
echo "Error: GZ process $pid holding socket $1 blocking shutdown"
logger -p daemon.err "Error: zone $ZONENAME:" \
"GZ process $pid holding socket $1 blocking shutdown"
}
# zonadmd unable to unmount the given path, try to cleanup so unmount can
# succeed.
cleanup_mount()
{
echo "attempting to cleanup mount $1"
logger -p daemon.err "zone $ZONENAME " \
"attempting to cleanup mount $1"
logger -p daemon.err "zone $ZONENAME attempting to cleanup mount $1"
cnt=`fuser -c $1 2>/dev/null | wc -w`
if [ $cnt -gt 0 ]; then
echo "trying to kill GZ processes under $1"
logger -p daemon.err "zone $ZONENAME " \
"trying to kill GZ processes under $1"
fuser -ck $1
fnd_procs=0
for i in `fuser -c $1 2>/dev/null`
do
fnd_procs=1
pty=`ps -otty -p $i | \
nawk '{if ($1 != "TT" && $1 != "?") print $0}'`
if [ -n "$pty" ]; then
echo "shell process $i blocking zone" \
"$ZONENAME shutdown, killing the process" | wall
echo "killing GZ user shell $i under $1"
logger -p daemon.err "zone $ZONENAME:" \
"killing GZ user shell $i under $1"
kill -9 $i
else
echo "Error: GZ process $i under $1 blocking shutdown"
logger -p daemon.err "Error: zone $ZONENAME:" \
"GZ process $i under $1 blocking shutdown"
fi
done
if [ $fnd_procs -eq 1 ]; then
# Exit out to give the zoneadmd umount a chance to suceed now.
# Zoneadmd will give us another shot if it still can't umount.
sleep 1
Expand All @@ -545,20 +558,20 @@ cleanup_mount()
# zone's root. For example, a zone with its root at /zones/foo/root and
# an open socket as /zones/foo/root/var/run/x will show up in a pfiles
# search as /var/run/x. This is a problem since we have no way to
# narrow down which process to kill.
# narrow down which process is the culprit.
#
# Because the socket doesn't have enough information for us to tie to
# the specific GZ process, we hardcode to kill things we know will open
# the specific GZ process, we hardcode to id things we know will open
# sockets into the zone:
# /var/run/smartdc/metadata.sock
# /var/run/.smartdc-amon.sock
ZVR=$ZONEPATH/root/var/run
[ -S $ZVR/smartdc/metadata.sock ] &&
kill_gz_sockholder /var/run/smartdc/metadata.sock
id_gz_sockholder /var/run/smartdc/metadata.sock
[ -S $ZVR/.smartdc-amon.sock ] &&
kill_gz_sockholder /var/run/.smartdc-amon.sock
id_gz_sockholder /var/run/.smartdc-amon.sock
}
#
Expand Down
49 changes: 31 additions & 18 deletions overlay/generic/usr/lib/brand/kvm/statechange
Original file line number Diff line number Diff line change
Expand Up @@ -418,7 +418,7 @@ cleanup_net()
done
}

kill_gz_sockholder()
id_gz_sockholder()
{
echo "searching for GZ process holding socket $1"
logger -p daemon.err "zone $ZONENAME " \
Expand All @@ -433,28 +433,41 @@ kill_gz_sockholder()
[ -z "$pid" ] && return
echo "killing GZ process $pid holding socket $1"
logger -p daemon.err "zone $ZONENAME " \
"killing GZ process $pid holding socket $1"
kill -9 $pid
echo "Error: GZ process $pid holding socket $1 blocking shutdown"
logger -p daemon.err "Error: zone $ZONENAME:" \
"GZ process $pid holding socket $1 blocking shutdown"
}
# zonadmd unable to unmount the given path, try to cleanup so unmount can
# succeed.
cleanup_mount()
{
echo "attempting to cleanup mount $1"
logger -p daemon.err "zone $ZONENAME " \
"attempting to cleanup mount $1"
logger -p daemon.err "zone $ZONENAME attempting to cleanup mount $1"
cnt=`fuser -c $1 2>/dev/null | wc -w`
if [ $cnt -gt 0 ]; then
echo "trying to kill GZ processes under $1"
logger -p daemon.err "zone $ZONENAME " \
"trying to kill GZ processes under $1"
fuser -ck $1
fnd_procs=0
for i in `fuser -c $1 2>/dev/null`
do
fnd_procs=1
pty=`ps -otty -p $i | \
nawk '{if ($1 != "TT" && $1 != "?") print $0}'`
if [ -n "$pty" ]; then
echo "shell process $i blocking zone" \
"$ZONENAME shutdown, killing the process" | wall
echo "killing GZ user shell $i under $1"
logger -p daemon.err "zone $ZONENAME:" \
"killing GZ user shell $i under $1"
kill -9 $i
else
echo "Error: GZ process $i under $1 blocking shutdown"
logger -p daemon.err "Error: zone $ZONENAME:" \
"GZ process $i under $1 blocking shutdown"
fi
done
if [ $fnd_procs -eq 1 ]; then
# Exit out to give the zoneadmd umount a chance to suceed now.
# Zoneadmd will give us another shot if it still can't umount.
sleep 1
Expand All @@ -466,20 +479,20 @@ cleanup_mount()
# zone's root. For example, a zone with its root at /zones/foo/root and
# an open socket as /zones/foo/root/var/run/x will show up in a pfiles
# search as /var/run/x. This is a problem since we have no way to
# narrow down which process to kill.
# narrow down which process is the culprit.
#
# Because the socket doesn't have enough information for us to tie to
# the specific GZ process, we hardcode to kill things we know will open
# the specific GZ process, we hardcode to id things we know will open
# sockets into the zone:
# /var/run/smartdc/metadata.sock
# /var/run/.smartdc-amon.sock
ZVR=$ZONEPATH/root/var/run
[ -S $ZVR/smartdc/metadata.sock ] &&
kill_gz_sockholder /var/run/smartdc/metadata.sock
id_gz_sockholder /var/run/smartdc/metadata.sock
[ -S $ZVR/.smartdc-amon.sock ] &&
kill_gz_sockholder /var/run/.smartdc-amon.sock
id_gz_sockholder /var/run/.smartdc-amon.sock
}
#
Expand Down

0 comments on commit 6406848

Please sign in to comment.