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

For additional information about terminating qvm process instances and guests, see Handling a qvm termination in the QNX Hypervisor for Safety 2.0 User's Guide “QNX Hypervisor for Safety” chapter.

Guest hasn't started: qvm_outf() and qvm_outff()

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_outf() or qvm_outff() to output the error message and terminate the qvm process.

Of the two functions, qvm_outf() 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_outf(QVM_OUTI_QVM, "%s: GUEST_CONFIGURED", __func__);

Notice that the qvm_outf() function's first argument is QVM_OUTI_QVM, which specifies information-level output from the qvm process.

The same call to qvm_outf() 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_outf() 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_outff() function to avoid the catch 22 created when you call qvm_outf() in response to a fatal error. This function behaves like qvm_outf(), 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_outf() and qvm_outff() 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 the Advanced Topics chapter of this guide:

case WDOG_ACTION_TERMINATE:
	qvm_outf(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.