OmniCube Reference Manualoc_console(3)

oc_console(3)

Library Functions · OmniCube · August 29, 2026

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.

index(), not a regex

zone is compared as a literal substring. Interpolated into an ERE, a . in a zone name would match any character and could select another VM's relay - a root kill(1) aimed at the wrong process.

[s]ocat, not socat

The bracket keeps the awk process from matching its own command line, which contains the pattern.

The surrounding slashes

/zone/ only appears in a path, never in an option value, so a manage_zone.sh command line carrying -z zone does not match itself.

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

0

No relay is running for zone, either because none was found or because all of them exited. The pool can be exported.

1

At least one process survived SIGKILL. An error is logged naming the surviving pids. The caller should treat a following zpool export as likely to fail.

ENVIRONMENT

PFEXEC

Set at source time by utils.sh: empty for root, pfexec otherwise. Used unquoted, so it disappears from the command line entirely when the caller is already privileged. See omnicube_utils(3).

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

<zonepath>/log/vnc.log

The relay's log, and the reason this function exists: an open descriptor on a file inside the pool being exported.

/opt/omnicube/lib/common/utils.sh

Defines both functions.

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).

man3/oc_console.3generated 2026-09-02 05:17 CEST