Statistics
| Branch: | Revision:

root / blockdev.c @ 2292ddae

History | View | Annotate | Download (20 kB)

1
/*
2
 * QEMU host block devices
3
 *
4
 * Copyright (c) 2003-2008 Fabrice Bellard
5
 *
6
 * This work is licensed under the terms of the GNU GPL, version 2 or
7
 * later.  See the COPYING file in the top-level directory.
8
 */
9

    
10
#include "block.h"
11
#include "blockdev.h"
12
#include "monitor.h"
13
#include "qerror.h"
14
#include "qemu-option.h"
15
#include "qemu-config.h"
16
#include "sysemu.h"
17
#include "hw/qdev.h"
18
#include "block_int.h"
19

    
20
static QTAILQ_HEAD(drivelist, DriveInfo) drives = QTAILQ_HEAD_INITIALIZER(drives);
21

    
22
static const char *const if_name[IF_COUNT] = {
23
    [IF_NONE] = "none",
24
    [IF_IDE] = "ide",
25
    [IF_SCSI] = "scsi",
26
    [IF_FLOPPY] = "floppy",
27
    [IF_PFLASH] = "pflash",
28
    [IF_MTD] = "mtd",
29
    [IF_SD] = "sd",
30
    [IF_VIRTIO] = "virtio",
31
    [IF_XEN] = "xen",
32
};
33

    
34
static const int if_max_devs[IF_COUNT] = {
35
    /*
36
     * Do not change these numbers!  They govern how drive option
37
     * index maps to unit and bus.  That mapping is ABI.
38
     *
39
     * All controllers used to imlement if=T drives need to support
40
     * if_max_devs[T] units, for any T with if_max_devs[T] != 0.
41
     * Otherwise, some index values map to "impossible" bus, unit
42
     * values.
43
     *
44
     * For instance, if you change [IF_SCSI] to 255, -drive
45
     * if=scsi,index=12 no longer means bus=1,unit=5, but
46
     * bus=0,unit=12.  With an lsi53c895a controller (7 units max),
47
     * the drive can't be set up.  Regression.
48
     */
49
    [IF_IDE] = 2,
50
    [IF_SCSI] = 7,
51
};
52

    
53
/*
54
 * We automatically delete the drive when a device using it gets
55
 * unplugged.  Questionable feature, but we can't just drop it.
56
 * Device models call blockdev_mark_auto_del() to schedule the
57
 * automatic deletion, and generic qdev code calls blockdev_auto_del()
58
 * when deletion is actually safe.
59
 */
60
void blockdev_mark_auto_del(BlockDriverState *bs)
61
{
62
    DriveInfo *dinfo = drive_get_by_blockdev(bs);
63

    
64
    if (dinfo) {
65
        dinfo->auto_del = 1;
66
    }
67
}
68

    
69
void blockdev_auto_del(BlockDriverState *bs)
70
{
71
    DriveInfo *dinfo = drive_get_by_blockdev(bs);
72

    
73
    if (dinfo && dinfo->auto_del) {
74
        drive_uninit(dinfo);
75
    }
76
}
77

    
78
QemuOpts *drive_def(const char *optstr)
79
{
80
    return qemu_opts_parse(qemu_find_opts("drive"), optstr, 0);
81
}
82

    
83
QemuOpts *drive_add(BlockInterfaceType type, int index, const char *file,
84
                    const char *fmt, ...)
85
{
86
    va_list ap;
87
    char optstr[1024];
88
    QemuOpts *opts;
89
    char buf[32];
90

    
91
    va_start(ap, fmt);
92
    vsnprintf(optstr, sizeof(optstr), fmt, ap);
93
    va_end(ap);
94

    
95
    opts = drive_def(optstr);
96
    if (!opts) {
97
        return NULL;
98
    }
99
    if (type != IF_DEFAULT) {
100
        qemu_opt_set(opts, "if", if_name[type]);
101
    }
102
    if (index >= 0) {
103
        snprintf(buf, sizeof(buf), "%d", index);
104
        qemu_opt_set(opts, "index", buf);
105
    }
106
    if (file)
107
        qemu_opt_set(opts, "file", file);
108
    return opts;
109
}
110

    
111
DriveInfo *drive_get(BlockInterfaceType type, int bus, int unit)
112
{
113
    DriveInfo *dinfo;
114

    
115
    /* seek interface, bus and unit */
116

    
117
    QTAILQ_FOREACH(dinfo, &drives, next) {
118
        if (dinfo->type == type &&
119
            dinfo->bus == bus &&
120
            dinfo->unit == unit)
121
            return dinfo;
122
    }
123

    
124
    return NULL;
125
}
126

    
127
int drive_get_max_bus(BlockInterfaceType type)
128
{
129
    int max_bus;
130
    DriveInfo *dinfo;
131

    
132
    max_bus = -1;
133
    QTAILQ_FOREACH(dinfo, &drives, next) {
134
        if(dinfo->type == type &&
135
           dinfo->bus > max_bus)
136
            max_bus = dinfo->bus;
137
    }
138
    return max_bus;
139
}
140

    
141
/* Get a block device.  This should only be used for single-drive devices
142
   (e.g. SD/Floppy/MTD).  Multi-disk devices (scsi/ide) should use the
143
   appropriate bus.  */
144
DriveInfo *drive_get_next(BlockInterfaceType type)
145
{
146
    static int next_block_unit[IF_COUNT];
147

    
148
    return drive_get(type, 0, next_block_unit[type]++);
149
}
150

    
151
DriveInfo *drive_get_by_blockdev(BlockDriverState *bs)
152
{
153
    DriveInfo *dinfo;
154

    
155
    QTAILQ_FOREACH(dinfo, &drives, next) {
156
        if (dinfo->bdrv == bs) {
157
            return dinfo;
158
        }
159
    }
160
    return NULL;
161
}
162

    
163
static void bdrv_format_print(void *opaque, const char *name)
164
{
165
    error_printf(" %s", name);
166
}
167

    
168
void drive_uninit(DriveInfo *dinfo)
169
{
170
    qemu_opts_del(dinfo->opts);
171
    bdrv_delete(dinfo->bdrv);
172
    QTAILQ_REMOVE(&drives, dinfo, next);
173
    qemu_free(dinfo);
174
}
175

    
176
static int parse_block_error_action(const char *buf, int is_read)
177
{
178
    if (!strcmp(buf, "ignore")) {
179
        return BLOCK_ERR_IGNORE;
180
    } else if (!is_read && !strcmp(buf, "enospc")) {
181
        return BLOCK_ERR_STOP_ENOSPC;
182
    } else if (!strcmp(buf, "stop")) {
183
        return BLOCK_ERR_STOP_ANY;
184
    } else if (!strcmp(buf, "report")) {
185
        return BLOCK_ERR_REPORT;
186
    } else {
187
        error_report("'%s' invalid %s error action",
188
                     buf, is_read ? "read" : "write");
189
        return -1;
190
    }
191
}
192

    
193
DriveInfo *drive_init(QemuOpts *opts, int default_to_scsi, int *fatal_error)
194
{
195
    const char *buf;
196
    const char *file = NULL;
197
    char devname[128];
198
    const char *serial;
199
    const char *mediastr = "";
200
    BlockInterfaceType type;
201
    enum { MEDIA_DISK, MEDIA_CDROM } media;
202
    int bus_id, unit_id;
203
    int cyls, heads, secs, translation;
204
    BlockDriver *drv = NULL;
205
    int max_devs;
206
    int index;
207
    int ro = 0;
208
    int bdrv_flags = 0;
209
    int on_read_error, on_write_error;
210
    const char *devaddr;
211
    DriveInfo *dinfo;
212
    int snapshot = 0;
213
    int ret;
214

    
215
    *fatal_error = 1;
216

    
217
    translation = BIOS_ATA_TRANSLATION_AUTO;
218

    
219
    if (default_to_scsi) {
220
        type = IF_SCSI;
221
        pstrcpy(devname, sizeof(devname), "scsi");
222
    } else {
223
        type = IF_IDE;
224
        pstrcpy(devname, sizeof(devname), "ide");
225
    }
226
    media = MEDIA_DISK;
227

    
228
    /* extract parameters */
229
    bus_id  = qemu_opt_get_number(opts, "bus", 0);
230
    unit_id = qemu_opt_get_number(opts, "unit", -1);
231
    index   = qemu_opt_get_number(opts, "index", -1);
232

    
233
    cyls  = qemu_opt_get_number(opts, "cyls", 0);
234
    heads = qemu_opt_get_number(opts, "heads", 0);
235
    secs  = qemu_opt_get_number(opts, "secs", 0);
236

    
237
    snapshot = qemu_opt_get_bool(opts, "snapshot", 0);
238
    ro = qemu_opt_get_bool(opts, "readonly", 0);
239

    
240
    file = qemu_opt_get(opts, "file");
241
    serial = qemu_opt_get(opts, "serial");
242

    
243
    if ((buf = qemu_opt_get(opts, "if")) != NULL) {
244
        pstrcpy(devname, sizeof(devname), buf);
245
        for (type = 0; type < IF_COUNT && strcmp(buf, if_name[type]); type++)
246
            ;
247
        if (type == IF_COUNT) {
248
            error_report("unsupported bus type '%s'", buf);
249
            return NULL;
250
        }
251
    }
252
    max_devs = if_max_devs[type];
253

    
254
    if (cyls || heads || secs) {
255
        if (cyls < 1 || (type == IF_IDE && cyls > 16383)) {
256
            error_report("invalid physical cyls number");
257
            return NULL;
258
        }
259
        if (heads < 1 || (type == IF_IDE && heads > 16)) {
260
            error_report("invalid physical heads number");
261
            return NULL;
262
        }
263
        if (secs < 1 || (type == IF_IDE && secs > 63)) {
264
            error_report("invalid physical secs number");
265
            return NULL;
266
        }
267
    }
268

    
269
    if ((buf = qemu_opt_get(opts, "trans")) != NULL) {
270
        if (!cyls) {
271
            error_report("'%s' trans must be used with cyls,heads and secs",
272
                         buf);
273
            return NULL;
274
        }
275
        if (!strcmp(buf, "none"))
276
            translation = BIOS_ATA_TRANSLATION_NONE;
277
        else if (!strcmp(buf, "lba"))
278
            translation = BIOS_ATA_TRANSLATION_LBA;
279
        else if (!strcmp(buf, "auto"))
280
            translation = BIOS_ATA_TRANSLATION_AUTO;
281
        else {
282
            error_report("'%s' invalid translation type", buf);
283
            return NULL;
284
        }
285
    }
286

    
287
    if ((buf = qemu_opt_get(opts, "media")) != NULL) {
288
        if (!strcmp(buf, "disk")) {
289
            media = MEDIA_DISK;
290
        } else if (!strcmp(buf, "cdrom")) {
291
            if (cyls || secs || heads) {
292
                error_report("'%s' invalid physical CHS format", buf);
293
                return NULL;
294
            }
295
            media = MEDIA_CDROM;
296
        } else {
297
            error_report("'%s' invalid media", buf);
298
            return NULL;
299
        }
300
    }
301

    
302
    if ((buf = qemu_opt_get(opts, "cache")) != NULL) {
303
        if (!strcmp(buf, "off") || !strcmp(buf, "none")) {
304
            bdrv_flags |= BDRV_O_NOCACHE;
305
        } else if (!strcmp(buf, "writeback")) {
306
            bdrv_flags |= BDRV_O_CACHE_WB;
307
        } else if (!strcmp(buf, "unsafe")) {
308
            bdrv_flags |= BDRV_O_CACHE_WB;
309
            bdrv_flags |= BDRV_O_NO_FLUSH;
310
        } else if (!strcmp(buf, "writethrough")) {
311
            /* this is the default */
312
        } else {
313
           error_report("invalid cache option");
314
           return NULL;
315
        }
316
    }
317

    
318
#ifdef CONFIG_LINUX_AIO
319
    if ((buf = qemu_opt_get(opts, "aio")) != NULL) {
320
        if (!strcmp(buf, "native")) {
321
            bdrv_flags |= BDRV_O_NATIVE_AIO;
322
        } else if (!strcmp(buf, "threads")) {
323
            /* this is the default */
324
        } else {
325
           error_report("invalid aio option");
326
           return NULL;
327
        }
328
    }
329
#endif
330

    
331
    if ((buf = qemu_opt_get(opts, "format")) != NULL) {
332
       if (strcmp(buf, "?") == 0) {
333
           error_printf("Supported formats:");
334
           bdrv_iterate_format(bdrv_format_print, NULL);
335
           error_printf("\n");
336
           return NULL;
337
        }
338
        drv = bdrv_find_whitelisted_format(buf);
339
        if (!drv) {
340
            error_report("'%s' invalid format", buf);
341
            return NULL;
342
        }
343
    }
344

    
345
    on_write_error = BLOCK_ERR_STOP_ENOSPC;
346
    if ((buf = qemu_opt_get(opts, "werror")) != NULL) {
347
        if (type != IF_IDE && type != IF_SCSI && type != IF_VIRTIO && type != IF_NONE) {
348
            error_report("werror is not supported by this bus type");
349
            return NULL;
350
        }
351

    
352
        on_write_error = parse_block_error_action(buf, 0);
353
        if (on_write_error < 0) {
354
            return NULL;
355
        }
356
    }
357

    
358
    on_read_error = BLOCK_ERR_REPORT;
359
    if ((buf = qemu_opt_get(opts, "rerror")) != NULL) {
360
        if (type != IF_IDE && type != IF_VIRTIO && type != IF_SCSI && type != IF_NONE) {
361
            error_report("rerror is not supported by this bus type");
362
            return NULL;
363
        }
364

    
365
        on_read_error = parse_block_error_action(buf, 1);
366
        if (on_read_error < 0) {
367
            return NULL;
368
        }
369
    }
370

    
371
    if ((devaddr = qemu_opt_get(opts, "addr")) != NULL) {
372
        if (type != IF_VIRTIO) {
373
            error_report("addr is not supported by this bus type");
374
            return NULL;
375
        }
376
    }
377

    
378
    /* compute bus and unit according index */
379

    
380
    if (index != -1) {
381
        if (bus_id != 0 || unit_id != -1) {
382
            error_report("index cannot be used with bus and unit");
383
            return NULL;
384
        }
385
        if (max_devs == 0)
386
        {
387
            unit_id = index;
388
            bus_id = 0;
389
        } else {
390
            unit_id = index % max_devs;
391
            bus_id = index / max_devs;
392
        }
393
    }
394

    
395
    /* if user doesn't specify a unit_id,
396
     * try to find the first free
397
     */
398

    
399
    if (unit_id == -1) {
400
       unit_id = 0;
401
       while (drive_get(type, bus_id, unit_id) != NULL) {
402
           unit_id++;
403
           if (max_devs && unit_id >= max_devs) {
404
               unit_id -= max_devs;
405
               bus_id++;
406
           }
407
       }
408
    }
409

    
410
    /* check unit id */
411

    
412
    if (max_devs && unit_id >= max_devs) {
413
        error_report("unit %d too big (max is %d)",
414
                     unit_id, max_devs - 1);
415
        return NULL;
416
    }
417

    
418
    /*
419
     * ignore multiple definitions
420
     */
421

    
422
    if (drive_get(type, bus_id, unit_id) != NULL) {
423
        *fatal_error = 0;
424
        return NULL;
425
    }
426

    
427
    /* init */
428

    
429
    dinfo = qemu_mallocz(sizeof(*dinfo));
430
    if ((buf = qemu_opts_id(opts)) != NULL) {
431
        dinfo->id = qemu_strdup(buf);
432
    } else {
433
        /* no id supplied -> create one */
434
        dinfo->id = qemu_mallocz(32);
435
        if (type == IF_IDE || type == IF_SCSI)
436
            mediastr = (media == MEDIA_CDROM) ? "-cd" : "-hd";
437
        if (max_devs)
438
            snprintf(dinfo->id, 32, "%s%i%s%i",
439
                     devname, bus_id, mediastr, unit_id);
440
        else
441
            snprintf(dinfo->id, 32, "%s%s%i",
442
                     devname, mediastr, unit_id);
443
    }
444
    dinfo->bdrv = bdrv_new(dinfo->id);
445
    dinfo->devaddr = devaddr;
446
    dinfo->type = type;
447
    dinfo->bus = bus_id;
448
    dinfo->unit = unit_id;
449
    dinfo->opts = opts;
450
    if (serial)
451
        strncpy(dinfo->serial, serial, sizeof(dinfo->serial) - 1);
452
    QTAILQ_INSERT_TAIL(&drives, dinfo, next);
453

    
454
    bdrv_set_on_error(dinfo->bdrv, on_read_error, on_write_error);
455

    
456
    switch(type) {
457
    case IF_IDE:
458
    case IF_SCSI:
459
    case IF_XEN:
460
    case IF_NONE:
461
        switch(media) {
462
        case MEDIA_DISK:
463
            if (cyls != 0) {
464
                bdrv_set_geometry_hint(dinfo->bdrv, cyls, heads, secs);
465
                bdrv_set_translation_hint(dinfo->bdrv, translation);
466
            }
467
            break;
468
        case MEDIA_CDROM:
469
            bdrv_set_type_hint(dinfo->bdrv, BDRV_TYPE_CDROM);
470
            break;
471
        }
472
        break;
473
    case IF_SD:
474
        /* FIXME: This isn't really a floppy, but it's a reasonable
475
           approximation.  */
476
    case IF_FLOPPY:
477
        bdrv_set_type_hint(dinfo->bdrv, BDRV_TYPE_FLOPPY);
478
        break;
479
    case IF_PFLASH:
480
    case IF_MTD:
481
        break;
482
    case IF_VIRTIO:
483
        /* add virtio block device */
484
        opts = qemu_opts_create(qemu_find_opts("device"), NULL, 0);
485
        qemu_opt_set(opts, "driver", "virtio-blk-pci");
486
        qemu_opt_set(opts, "drive", dinfo->id);
487
        if (devaddr)
488
            qemu_opt_set(opts, "addr", devaddr);
489
        break;
490
    default:
491
        abort();
492
    }
493
    if (!file || !*file) {
494
        *fatal_error = 0;
495
        return NULL;
496
    }
497
    if (snapshot) {
498
        /* always use cache=unsafe with snapshot */
499
        bdrv_flags &= ~BDRV_O_CACHE_MASK;
500
        bdrv_flags |= (BDRV_O_SNAPSHOT|BDRV_O_CACHE_WB|BDRV_O_NO_FLUSH);
501
    }
502

    
503
    if (media == MEDIA_CDROM) {
504
        /* CDROM is fine for any interface, don't check.  */
505
        ro = 1;
506
    } else if (ro == 1) {
507
        if (type != IF_SCSI && type != IF_VIRTIO && type != IF_FLOPPY && type != IF_NONE) {
508
            error_report("readonly not supported by this bus type");
509
            return NULL;
510
        }
511
    }
512

    
513
    bdrv_flags |= ro ? 0 : BDRV_O_RDWR;
514

    
515
    ret = bdrv_open(dinfo->bdrv, file, bdrv_flags, drv);
516
    if (ret < 0) {
517
        error_report("could not open disk image %s: %s",
518
                     file, strerror(-ret));
519
        return NULL;
520
    }
521

    
522
    if (bdrv_key_required(dinfo->bdrv))
523
        autostart = 0;
524
    *fatal_error = 0;
525
    return dinfo;
526
}
527

    
528
void do_commit(Monitor *mon, const QDict *qdict)
529
{
530
    const char *device = qdict_get_str(qdict, "device");
531
    BlockDriverState *bs;
532

    
533
    if (!strcmp(device, "all")) {
534
        bdrv_commit_all();
535
    } else {
536
        bs = bdrv_find(device);
537
        if (!bs) {
538
            qerror_report(QERR_DEVICE_NOT_FOUND, device);
539
            return;
540
        }
541
        bdrv_commit(bs);
542
    }
543
}
544

    
545
int do_snapshot_blkdev(Monitor *mon, const QDict *qdict, QObject **ret_data)
546
{
547
    const char *device = qdict_get_str(qdict, "device");
548
    const char *filename = qdict_get_try_str(qdict, "snapshot_file");
549
    const char *format = qdict_get_try_str(qdict, "format");
550
    BlockDriverState *bs;
551
    BlockDriver *drv, *proto_drv;
552
    int ret = 0;
553
    int flags;
554

    
555
    if (!filename) {
556
        qerror_report(QERR_MISSING_PARAMETER, "snapshot_file");
557
        ret = -1;
558
        goto out;
559
    }
560

    
561
    bs = bdrv_find(device);
562
    if (!bs) {
563
        qerror_report(QERR_DEVICE_NOT_FOUND, device);
564
        ret = -1;
565
        goto out;
566
    }
567

    
568
    if (!format) {
569
        format = "qcow2";
570
    }
571

    
572
    drv = bdrv_find_format(format);
573
    if (!drv) {
574
        qerror_report(QERR_INVALID_BLOCK_FORMAT, format);
575
        ret = -1;
576
        goto out;
577
    }
578

    
579
    proto_drv = bdrv_find_protocol(filename);
580
    if (!proto_drv) {
581
        qerror_report(QERR_INVALID_BLOCK_FORMAT, format);
582
        ret = -1;
583
        goto out;
584
    }
585

    
586
    ret = bdrv_img_create(filename, format, bs->filename,
587
                          bs->drv->format_name, NULL, -1, bs->open_flags);
588
    if (ret) {
589
        goto out;
590
    }
591

    
592
    qemu_aio_flush();
593
    bdrv_flush(bs);
594

    
595
    flags = bs->open_flags;
596
    bdrv_close(bs);
597
    ret = bdrv_open(bs, filename, flags, drv);
598
    /*
599
     * If reopening the image file we just created fails, we really
600
     * are in trouble :(
601
     */
602
    if (ret != 0) {
603
        abort();
604
    }
605
out:
606
    if (ret) {
607
        ret = -1;
608
    }
609

    
610
    return ret;
611
}
612

    
613
static int eject_device(Monitor *mon, BlockDriverState *bs, int force)
614
{
615
    if (!force) {
616
        if (!bdrv_is_removable(bs)) {
617
            qerror_report(QERR_DEVICE_NOT_REMOVABLE,
618
                           bdrv_get_device_name(bs));
619
            return -1;
620
        }
621
        if (bdrv_is_locked(bs)) {
622
            qerror_report(QERR_DEVICE_LOCKED, bdrv_get_device_name(bs));
623
            return -1;
624
        }
625
    }
626
    bdrv_close(bs);
627
    return 0;
628
}
629

    
630
int do_eject(Monitor *mon, const QDict *qdict, QObject **ret_data)
631
{
632
    BlockDriverState *bs;
633
    int force = qdict_get_try_bool(qdict, "force", 0);
634
    const char *filename = qdict_get_str(qdict, "device");
635

    
636
    bs = bdrv_find(filename);
637
    if (!bs) {
638
        qerror_report(QERR_DEVICE_NOT_FOUND, filename);
639
        return -1;
640
    }
641
    return eject_device(mon, bs, force);
642
}
643

    
644
int do_block_set_passwd(Monitor *mon, const QDict *qdict,
645
                        QObject **ret_data)
646
{
647
    BlockDriverState *bs;
648
    int err;
649

    
650
    bs = bdrv_find(qdict_get_str(qdict, "device"));
651
    if (!bs) {
652
        qerror_report(QERR_DEVICE_NOT_FOUND, qdict_get_str(qdict, "device"));
653
        return -1;
654
    }
655

    
656
    err = bdrv_set_key(bs, qdict_get_str(qdict, "password"));
657
    if (err == -EINVAL) {
658
        qerror_report(QERR_DEVICE_NOT_ENCRYPTED, bdrv_get_device_name(bs));
659
        return -1;
660
    } else if (err < 0) {
661
        qerror_report(QERR_INVALID_PASSWORD);
662
        return -1;
663
    }
664

    
665
    return 0;
666
}
667

    
668
int do_change_block(Monitor *mon, const char *device,
669
                    const char *filename, const char *fmt)
670
{
671
    BlockDriverState *bs;
672
    BlockDriver *drv = NULL;
673
    int bdrv_flags;
674

    
675
    bs = bdrv_find(device);
676
    if (!bs) {
677
        qerror_report(QERR_DEVICE_NOT_FOUND, device);
678
        return -1;
679
    }
680
    if (fmt) {
681
        drv = bdrv_find_whitelisted_format(fmt);
682
        if (!drv) {
683
            qerror_report(QERR_INVALID_BLOCK_FORMAT, fmt);
684
            return -1;
685
        }
686
    }
687
    if (eject_device(mon, bs, 0) < 0) {
688
        return -1;
689
    }
690
    bdrv_flags = bdrv_is_read_only(bs) ? 0 : BDRV_O_RDWR;
691
    bdrv_flags |= bdrv_is_snapshot(bs) ? BDRV_O_SNAPSHOT : 0;
692
    if (bdrv_open(bs, filename, bdrv_flags, drv) < 0) {
693
        qerror_report(QERR_OPEN_FILE_FAILED, filename);
694
        return -1;
695
    }
696
    return monitor_read_bdrv_key_start(mon, bs, NULL, NULL);
697
}
698

    
699
int do_drive_del(Monitor *mon, const QDict *qdict, QObject **ret_data)
700
{
701
    const char *id = qdict_get_str(qdict, "id");
702
    BlockDriverState *bs;
703
    BlockDriverState **ptr;
704
    Property *prop;
705

    
706
    bs = bdrv_find(id);
707
    if (!bs) {
708
        qerror_report(QERR_DEVICE_NOT_FOUND, id);
709
        return -1;
710
    }
711

    
712
    /* quiesce block driver; prevent further io */
713
    qemu_aio_flush();
714
    bdrv_flush(bs);
715
    bdrv_close(bs);
716

    
717
    /* clean up guest state from pointing to host resource by
718
     * finding and removing DeviceState "drive" property */
719
    if (bs->peer) {
720
        for (prop = bs->peer->info->props; prop && prop->name; prop++) {
721
            if (prop->info->type == PROP_TYPE_DRIVE) {
722
                ptr = qdev_get_prop_ptr(bs->peer, prop);
723
                if (*ptr == bs) {
724
                    bdrv_detach(bs, bs->peer);
725
                    *ptr = NULL;
726
                    break;
727
                }
728
            }
729
        }
730
    }
731

    
732
    /* clean up host side */
733
    drive_uninit(drive_get_by_blockdev(bs));
734

    
735
    return 0;
736
}
737

    
738
/*
739
 * XXX: replace the QERR_UNDEFINED_ERROR errors with real values once the
740
 * existing QERR_ macro mess is cleaned up.  A good example for better
741
 * error reports can be found in the qemu-img resize code.
742
 */
743
int do_block_resize(Monitor *mon, const QDict *qdict, QObject **ret_data)
744
{
745
    const char *device = qdict_get_str(qdict, "device");
746
    int64_t size = qdict_get_int(qdict, "size");
747
    BlockDriverState *bs;
748

    
749
    bs = bdrv_find(device);
750
    if (!bs) {
751
        qerror_report(QERR_DEVICE_NOT_FOUND, device);
752
        return -1;
753
    }
754

    
755
    if (size < 0) {
756
        qerror_report(QERR_UNDEFINED_ERROR);
757
        return -1;
758
    }
759

    
760
    if (bdrv_truncate(bs, size)) {
761
        qerror_report(QERR_UNDEFINED_ERROR);
762
        return -1;
763
    }
764

    
765
    return 0;
766
}