Terminating qvm process instances and guests
The method you use in your vdev to terminate a qvm process instance and a guest depends on the status of the guest.
A vdev can expect a VDEV_CTRL_GUEST_STARTING callback from the
qvm process when it starts the guest it is hosting, so you
can use this callback to determine which method you use to terminate the guest (see
the earlier Overview
section).
For additional information about terminating qvm process instances
and guests, see Handling
a qvm termination
in the User's Guide
QNX Hypervisor: Protection Features
chapter.
Guest hasn't started: qvm_logf() and qvm_fatal()
If the guest hasn't started and the vdev encounters a condition that requires it to take action to prevent the guest from starting (i.e., a QVM_OUTAL_FATAL or QVM_OUTAL_INTERNAL error from the qvm process), the vdev should call qvm_logf() or qvm_fatal() to output the error message and terminate the qvm process.
Of the two functions, qvm_logf() is the more flexible. You can use
it to output various types of messages: information, debug, warning, etc. (see
Definitions in outpipe.h
in the Virtual Device Developer's
API reference). Most calls to this function cause it to print output to
the output pipes defined in the VM configuration, then return and continue.
The following snippet is from the trace vdev described in the next
chapter:
case VDEV_CTRL_GUEST_CONFIGURED:
/* The guest is now fully configured. It is now safe to create
* any threads that are needed by the vdev.
*/
qvm_logf(QVM_OUTI_QVM, "%s: GUEST_CONFIGURED", __func__);
Notice that the qvm_logf() function's first argument is QVM_OUTI_QVM, which specifies information-level output from the qvm process.
The same call to qvm_logf() with QVM_OUTF_QVM,
which includes QVM_OUTAL_FATAL (see Definitions in outpipe.h
),
as the first argument would deliver the output message and cause the
qvm process to terminate.
Since qvm_logf() is designed to return, using it to handle fatal errors will cause difficulities with static code analysis: the analysis will require some code to handle the return; if you put code to handle the return, it will be dead code.
You can use the qvm_fatal() function to avoid the problem created
when you call qvm_logf() in response to a fatal error.
This function behaves like qvm_logf(), but doesn't return;
its prototype in qvm/outpipe.h is marked with
__attribute__((noreturn)) so that static code analysis tools
know that the function never returns.
For more information about the qvm_logf() and
qvm_fatal() functions and how to use them, see the
Virtual Device Developer's API Reference
outpipe.h
chapter.
Guest has started: guest_terminate()
If the qvm process has already started the guest; that is, if your
vdev has received a VDEV_CTRL_GUEST_STARTING callback from the
qvm process, then you must use
guest_terminate() to terminate the guest, followed by the
hosting qvm process (see guest_terminate() in the Virtual Device
Developer's API Reference
guest.h
chapter).
The following code snippet is from the wdog_bite() function called
by the watchdog vdevs described in the Advanced Topics
chapter of this guide:
case WDOG_ACTION_TERMINATE:
qvm_logf(QVM_OUTE_QVM, "%s: terminating", str);
guest_terminate(wds->ws_vdev->v_gsp, GTC_WATCHDOG);
break;
For more information about wdog_bite(), see the Virtual
Device Developer's API Reference
wdog.h
chapter.
