NAME
oc_console, kill_zone_console, _zone_console_pids - stop a zone's VNC console relay before its pool is exported
SYNOPSIS
amp;. /opt/omnicube/lib/common/utils.sh
kill_zone_console zone
_zone_console_pids zone
DESCRIPTION
activate_zone_vnc.sh(1) publishes a VM's graphical console by starting a socat(1) relay under pfexec(1), and tells it to write its own log to <zonepath>/log/vnc.log amp;. That log file lives inside the zone's pool, and socat holds it open for the whole life of the relay. A zpool export of that pool therefore fails with "pool is busy" while the relay is running, which is why every code path that stops a zone has to call kill_zone_console first.
kill_zone_console finds the relay processes for zone, sends them SIGTERM, and then waits for them to disappear from the process table - up to five seconds, checked once a second. If any are left it escalates to SIGKILL, waits one more second and looks again. The wait is the point: a fire-and-forget kill(1) returns before the file descriptors are closed and races the zpool export that follows it.
Both the parent relay and every in-flight child are matched and signalled. socat is started with fork, so each accepted connection is served by a child that inherited the log file descriptor; killing only the parent would leave the pool busy.
Matching
_zone_console_pids is the single definition of what counts as "this zone's relay":
ps -eaf | awk -v z="/${zone}/" '/[s]ocat/ && index($0, z) {print $2}'
Three details of that line are deliberate.
The match is against ps(1) output, and illumos reports pr_psargs truncated to 80 characters. For a TLS relay the trailing UNIX-CONNECT: address is well past that cutoff, so what is actually found is the -lf<zonepath>/log/vnc.log argument near the front of the command line. Every valid zonepath contains /zone/, whichever layout the site uses - /zones/zone or the OmniCube standard /zones/zone/root - so the match holds either way. activate_zone_vnc.sh(1) places its logging options before the listen address for exactly this reason; moving them after it would make every relay invisible to this function.
RETURN VALUES
ENVIRONMENT
EXAMPLES
Example 1: before exporting a pool
kill_zone_console "${zone}" \\
|| warning "console relay for ${zone} could not be stopped; the export may fail"
zpool export ${zone}
Example 2: testing whether a console is published
if [[ -n $(_zone_console_pids "${zone}") ]]; then
printf "VM %s vnc already setup\\n" "${zone}"
fi
FILES
NOTES
Callers are activate_zone_vnc.sh(1), which uses _zone_console_pids as its duplicate-relay guard; manage_zone.sh(8), in both relocate and send_async, before the zone's datasets leave the node; and the zone-mgt SMF method's stop_zone, which covers every other way a zone is stopped - a plain svcadm disable, and a node shutdown.
Because stop_zone calls it, a relay no longer survives a stop/start cycle of its zone. It used to, by accident: the parent only touches the guest's UNIX socket when a new connection arrives, so it would reconnect to the socket the zone recreated on boot. Consoles must be re-activated with activate_zone_vnc.sh(1) after a zone restart. A relocate is different: there manage_zone.sh(8) records that a console was published before it calls this function, and re-publishes it on the target once the zone is running there.
SEE ALSO
activate_zone_vnc.sh(1), manage_zone.sh(8), omnicube_utils(3), oc_log(3), oc_validate(3), socat(1), omnicube(7).