Handling a qvm termination

You can register to be informed if a qvm process instance terminates, so you can take appropriate action in response to the termination.

See Shutting down guests in the Booting and Shutting Down chapter for more information about shutting down guests.

Controlled termination

You can write a minimalist vdev that can initiate appropriate actions when its qvm process instance is about to terminate; for example, because its guest has shut down or become unresponsive. The samples below are from a fictitious vdev qvmterm that includes only a control function, which registers to receive a callback only if its qvm process instance terminates.

The vdev's control function is implemented as follows:
qvmterm_control(vdev_t *vdp, unsigned const ctrl, const char *const arg) {
  struct term_state *state = vdp->v_device;
  
  switch (ctrl) {
  
    case VDEV_CTRL_TERMINATE:
    // The qvm is terminating.
    // Do any cleanup necessary for the vdev: end any worker threads
    // it created, close its connections to backend drivers, etc.
    // In this example, one worker thread was created by this vdev from
    // the vdev_thread_create() function when the guest was configured
    // (VDEV_CTRL_GUEST_CONFIGURED message block).
    // End the thread.
    pthread_cancel(state->thread);
    pthread_join(state->thread, NULL);
    break;
  }

The sample code here is written in C. We recommend using C but if you do use other languages to write code that handles VDEV_CTRL_TERMINATE, then you must consider how language-specific mechanisms can affect the vdev behavior during qvm shutdown. For information about which particular mechanisms you should consider, see the heading What language will I use to implement the vdev? in the Designing a vdev section in the Virtual Device Developer's Guide.

The vdev populates its factory structure (qvmterm_factory) with the control function but nothing else:
qvmterm_register(void) {
  static struct vdev_factory qvmterm_factory = {
    .next = NULL, // patched
    .control = qvmterm_control,
    .vread = NULL,
    .vwrite = NULL,
    .option_list = NULL,
    .name = NULL, // patched
    .factory_flags = VFF_NONE,
    .acc_sizes = 1u << 1,
    // Make sure we have local data space for our internal structure
    .extra_space = sizeof(struct qvmterm_state),
  };
  vdev_register_factory(&qvmterm_factory, QVM_VDEV_ABI);
}

For general information about designing and writing vdevs, refer to the first chapter of the Virtual Device Developer's Guide and the Virtual Device Developer's API Reference. You can find vdev source code samples in the QNX Hypervisor GitLab Repository at https://gitlab.com/qnx/hypervisor.

qvm crash

To manage an urgent qvm process instance termination in response to an unknown state, you can run a hypervisor host process outside the qvm that handles the termination. This process includes code to perform the system cleanup and hardware shutdown tasks that would be looked after in the VDEV_CTRL_TERMINATE message block in the fictional vdev qvmterm described above.

For a list of qvm exit codes, see qvm process exit codes in the Monitoring and Troubleshooting chapter.

Page updated: