Attached is a patch that I created to make HVM virtual cdroms behave
more like their physical counterparts.
Problem: When cd media is ejected, and worse, replaced, the guest is
not made aware until the you enter the qemu monitor and type 'change
<device> <name>'. This 'change' command must also be done for each
guest that has access to the media, i.e., has the 'cdrom =' line its
config file. When a guest is not made aware of media changes then the
guest continues on the assumption that all is well returns previously
cached data for media not present, or worse, reads non-cached from the
new media believing that it is still the previous media.
Recognizing that the patch is large I will spend a moment explaining
the theory of operations. The objective was to get each guest to be
aware of media ejects and inerts regardless from which domain the event
occurred, including Dom0.
The foundation for this work is the creation of a very small amount of
memory shared between all guests. This shared memory contains a list of
shared removable media devices, as defined by the 'cdrom=' line that may
exist is each guest's config file. There is one entry in this shared
memory for each unique device name. Accompanying the device name is
media instance number. This instance number is incremented each time
media is ejected from any guest.
The current value of the instance number is stored in the
BlockDriverState structure when a guest is initialized. This instance
number kept by the guest is compared against the value in the shared
memory in the TEST_UNIT_READY routine and the cdrom read routine found
in qemu's ide.c. If the values are not equal then is is assumed that
the media has been ejected by another guest and a ASC_MEDIA_CHANGED
error is returned to each quest's routine that is polling for removable
media device status. If polling is not employed by the guest then the
media changed notification will occur on the next IO request and the
guest OS will respond appropriately.
In addition to comparing the guest's media instance number against the
value in shared memory the TEST_UNIT_READY routine checks the
accessibility of the media. It does so by opening the the device with
the O_NONBLOCK flag, clearing the flag with fcntl() and checking the
value returned by a read() from the device. Using O_NONBLOCK prevents
the automatic draw-in of the cd tray should it be ejected. If the guest
believes that the media should be present then TEST_UNIT_READY returns
ok, otherwise, it reports MEDIA_CHANGED and then MEDIA_NOT_PRESENT for
all following TEST_UNIT_READY until it determined that media is once
again present. This is determined by TEST_UNIT_READY when it believes
that media is not present and the open() and read() succeed.
When it is discovered that media has become present then qemu responds
essentially as if qemu's 'change' command had been entered at the qemu's
monitor screen. The device is opened and made available to the quest.
The guest's media polling routines discover the new media and respond
appropriately. Having the TEST_UNIT_READY check the media also allows
the guests to respond properly when media is ejected manually or from
This implementation is stateless meaning that there is nothing to
cleanup when a domain terminates, nicely or otherwise. The shared
memory is not created until there is at least one guest and is removed
when the last guest terminates, providing it did so nicely. Even if the
memory should not be freed when the last domain terminates, it is not
much memory and is never reallocated but simply reused by the next
It was suggested that xenstore be used in place of the shared memory.
After considering this it was decided to stay with the shared memory
approach because of the frequency at which the memory was accessed and
by the fact that it is not data that is managed or even interesting.
Also, there is no measurable difference in cd IO performance with this
implementation, nor any visible signs, i.e., no spinning up, lights
blinking, trays unexpectedly moving, etc.
This implementation does nothing to protect against simultaneous writes
to shared media. It is recognized that in the future there will need to
be a comprehensive solution for the management of shared removable
devices of all types. This patch simply satisfies the expectation that
when media is present, or not, each guest responds appropriately.
This patch applies to change set 10162.
Signed off by Ross Maxfield <rmaxfiel@xxxxxxxxxx>
Description: Binary data
Xen-devel mailing list