Lifecycle of a vdev
Below is an overview of the lifecycle of a vdev, from initialization to termination.
For examples of source code that look after each stage of a vdev's lifecycle, see the
next chapter: The Basics: vdev trace
.
Overview
The lifecycle of a vdev can be divided into two stages:
- Startup — the vdev parses its options, defines itself and registers with the qvm framework in which it will run
- Running — the vdev runs and does whatever it is designed to do; generally, this involves performing some task and reading and writing to memory to communicate with the guest
The figure below presents the lifecycle of a vdev. Notice the Startup/Running demarcation, identified by the VDEV_CTRL_GUEST_CONFIGURED callback.
Determining when startup is complete
When you write a vdev, you must include code to identify the demarcation between your vdev's startup stage and its running stage, because some functions may be called only during the startup stage, when the qvm process instance is assembling the VM, including the vdevs. Others may be called only after the startup stage has completed, when the system is running.
When the qvm process is completing the vdev and VM configuration, it will issue callbacks that your vdev can use to identify when the startup stage ends and the running stage has begun:
- VDEV_CTRL_OPTIONS_END
- The qvm process has finished parsing your vdev's options. It may not have completed configuring the VM, however: it may still have other vdevs and VM components to configure.
- VDEV_CTRL_ASSIGN
- All user-specified options have been processed. The vdev must now check if the loc and intr options have been specified; if they haven't been specified, and the vdev will use them, the vdev must specify them for itself.
- VDEV_CTRL_GUEST_CONFIGURED
- The qvm process has finished configuring the VM for the guest system. It is safe to create threads, and to call functions that should only be used after startup is complete (e.g., vdev_path()).
- VDEV_CTRL_GUEST_STARTING
- The qvm process is about to start the guest. This callback marks the point at which the qvm process is about to change the state of the vCPU thread that will start the guest.
Protecting your vdev in a multi-threaded environment
When a qvm process instance is in its startup stage (i.e.,
assembling and configuring a VM), it is single-threaded: it runs with only a
main thread executing code. This means that your vdev can skip
some tasks that are required after the VM is ready and the guest has started
executing. For example, your vdev doesn't need to call
gasp_lock() and gasp_unlock() around other
calls to gasp_*() functions (see Guest memory regions
and the Virtual Device Developer's API Reference
gasp.h
chapter).
When the guest starts executing, it requires at least one vCPU, which adds a vCPU thread, so the qvm process instance must run at least two threads: the main thread and the vCPU thread. This means that your vdev is running in a multi-threaded environment and must use lock functions such as gasp_lock() to ensure that no other entity in your VM (e.g., another vdev) interferes with your vdev's resources.
