Skip to content
  • Markus Armbruster's avatar
    block: Keep DriveInfo alive until BlockDriverState dies · 3ae59580
    Markus Armbruster authored
    If the BDS's refcnt > 0, drive_del() destroys the DriveInfo, but not
    the BDS.  This can happen in three places:
    
    * Device model destruction during unplug: blockdev_auto_del()
    
    * Xen IDE unplug: pci_piix3_xen_ide_unplug()
    
    * drive_del command when no device model is attached: do_drive_del()
    
    The other callers of drive_del are on error paths where refcnt == 1.
    
    If the user somehow manages to plug in a device model using a BDS that
    has gone through drive_del(), the legacy configuration passed in
    DriveInfo doesn't reach the device model, and automatic deletion on
    unplug doesn't work.  Worse, some device models such as scsi-disk
    crash when DriveInfo doesn't exist.
    
    This is theoretical; I didn't research an actual reproducer. The problem
    was introduced when we replaced DriveInfo reference counting by BDS
    reference counting in commit a94a3fac..fa510ebf
    
    .
    
    Fix by keeping DriveInfo alive until its BDS dies.
    
    This affects qemu_drive_opts: now you can't reuse the same ID for new
    drive options until the BDS dies.  Before, you could, but since the
    code always attempts to create a BDS with the same ID next, the
    enclosing operation "create a new drive" failed anyway.  Different
    error path, same result.
    
    Unfortunately, the fix involves use of blockdev.c stuff from block.c,
    which is a layering violation.  Fortunately, my forthcoming
    BlockBackend work will get rid of it again.
    
    Signed-off-by: default avatarMarkus Armbruster <armbru@redhat.com>
    Reviewed-by: default avatarMax Reitz <mreitz@redhat.com>
    Reviewed-by: default avatarBenoît Canet <benoit.canet@nodalink.com>
    Signed-off-by: default avatarKevin Wolf <kwolf@redhat.com>
    3ae59580