summary refs log tree commit diff stats
path: root/vl.c
diff options
context:
space:
mode:
authorMarkus Armbruster <armbru@redhat.com>2011-01-28 11:21:46 +0100
committerKevin Wolf <kwolf@redhat.com>2011-01-31 11:59:24 +0100
commit319ae529b8d55ea60b1036809aaab2130048d0e1 (patch)
tree3740e9a82f9de67de48abb76a8c35bd855f818b5 /vl.c
parent5645b0f4f2185437d8df03810ce9c102cc4c90db (diff)
downloadfocaccia-qemu-319ae529b8d55ea60b1036809aaab2130048d0e1.tar.gz
focaccia-qemu-319ae529b8d55ea60b1036809aaab2130048d0e1.zip
blockdev: Fix drive_add for drives without media
Watch this:

    (qemu) drive_add 0 if=none
    (qemu) info block
    none0: type=hd removable=0 [not inserted]
    (qemu) drive_del none0
    Segmentation fault (core dumped)

add_init_drive() is confused about drive_init()'s failure modes, and
cleans up when it shouldn't.  This leaves the DriveInfo with member
opts dangling.  drive_del attempts to free it, and dies.

drive_init() behaves as follows:

* If it created a drive with media, it returns its DriveInfo.

* If it created a drive without media, it clears *fatal_error and
  returns NULL.

* If it couldn't create a drive, it sets *fatal_error and returns
  NULL.

Of its three callers:

* drive_init_func() is correct.

* usb_msd_init() assumes drive_init() failed when it returns NULL.
  This is correct only because it always passes option "file", and
  "drive without media" can't happen then.

* add_init_drive() assumes drive_init() failed when it returns NULL.
  This is incorrect.

Clean up drive_init() to return NULL on failure and only on failure.
Drop its parameter fatal_error.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Diffstat (limited to 'vl.c')
-rw-r--r--vl.c9
1 files changed, 2 insertions, 7 deletions
diff --git a/vl.c b/vl.c
index f86724f83a..ce5708bbbd 100644
--- a/vl.c
+++ b/vl.c
@@ -631,13 +631,8 @@ static int bt_parse(const char *opt)
 static int drive_init_func(QemuOpts *opts, void *opaque)
 {
     int *use_scsi = opaque;
-    int fatal_error = 0;
 
-    if (drive_init(opts, *use_scsi, &fatal_error) == NULL) {
-        if (fatal_error)
-            return 1;
-    }
-    return 0;
+    return drive_init(opts, *use_scsi) == NULL;
 }
 
 static int drive_enable_snapshot(QemuOpts *opts, void *opaque)
@@ -666,7 +661,7 @@ static void default_drive(int enable, int snapshot, int use_scsi,
     if (snapshot) {
         drive_enable_snapshot(opts, NULL);
     }
-    if (drive_init_func(opts, &use_scsi)) {
+    if (!drive_init(opts, use_scsi)) {
         exit(1);
     }
 }