xen/xen-removable.diff

723 lines
23 KiB
Diff

Index: xen-unstable/tools/ioemu/block.c
===================================================================
--- xen-unstable.orig/tools/ioemu/block.c
+++ xen-unstable/tools/ioemu/block.c
@@ -332,6 +332,8 @@ int bdrv_open2(BlockDriverState *bs, con
goto fail;
}
+ shdev_set_media_instance(bs);
+
bs->inserted = 1;
/* call the change callback */
@@ -356,6 +358,7 @@ void bdrv_close(BlockDriverState *bs)
bs->opaque = NULL;
bs->drv = NULL;
bs->inserted = 0;
+ bs->media_instance = 0;
/* call the change callback */
if (bs->change_cb)
@@ -601,6 +604,15 @@ BlockDriverState *bdrv_find(const char *
return NULL;
}
+BlockDriverState *bdrv_find_bs(int (*it)(BlockDriverState *, void *), void *opaque)
+{
+ BlockDriverState *bs;
+
+ for (bs = bdrv_first; bs != NULL && !it(bs, opaque); bs = bs->next);
+
+ return( bs );
+}
+
void bdrv_iterate(void (*it)(void *opaque, const char *name), void *opaque)
{
BlockDriverState *bs;
Index: xen-unstable/tools/ioemu/block_int.h
===================================================================
--- xen-unstable.orig/tools/ioemu/block_int.h
+++ xen-unstable/tools/ioemu/block_int.h
@@ -51,6 +51,8 @@ struct BlockDriverState {
int removable; /* if true, the media can be removed */
int locked; /* if true, the media cannot temporarily be ejected */
int encrypted; /* if true, the media is encrypted */
+ int media_instance;
+ int shdev_el;
/* event callback when inserting/removing */
void (*change_cb)(void *opaque);
void *change_opaque;
Index: xen-unstable/tools/ioemu/hw/ide.c
===================================================================
--- xen-unstable.orig/tools/ioemu/hw/ide.c
+++ xen-unstable/tools/ioemu/hw/ide.c
@@ -23,6 +23,9 @@
*/
#include "vl.h"
#include <pthread.h>
+#include <sys/ioctl.h>
+#include <scsi/scsi.h>
+#include <scsi/sg.h>
/* debug IDE devices */
//#define DEBUG_IDE
@@ -278,6 +281,7 @@
#define ASC_ILLEGAL_OPCODE 0x20
#define ASC_LOGICAL_BLOCK_OOR 0x21
#define ASC_INV_FIELD_IN_CMD_PACKET 0x24
+#define ASC_MEDIA_CHANGED 0x28
#define ASC_MEDIUM_NOT_PRESENT 0x3a
#define ASC_SAVING_PARAMETERS_NOT_SUPPORTED 0x39
@@ -294,6 +298,7 @@ typedef void EndTransferFunc(struct IDES
typedef struct IDEState {
/* ide config */
int is_cdrom;
+ int media_changed;
int cylinders, heads, sectors;
int64_t nb_sectors;
int mult_sectors;
@@ -1141,6 +1146,51 @@ static void ide_atapi_cmd_read(IDEState
}
}
+static int cd_media_inserted(IDEState *s)
+{
+ int inserted = 0;
+
+ if (s->bs->removable) {
+ int h = open(s->bs->filename, O_NONBLOCK, O_RDONLY);
+
+ if (h >= 0) {
+ struct stat statbuf;
+ if (fstat(h, &statbuf) == 0 && S_ISREG(statbuf.st_mode)) {
+ inserted = 1;
+ } else {
+ int status;
+ sg_io_hdr_t io_hdr;
+ unsigned char test_unit_ready_cmd[6] = {TEST_UNIT_READY, 0, 0, 0, 0, 0};
+ unsigned char inqBuff[2];
+ unsigned char sb[32];
+
+ memset(&io_hdr, 0, sizeof(sg_io_hdr_t));
+ io_hdr.interface_id = 'S';
+ io_hdr.cmd_len = 6;
+ io_hdr.mx_sb_len = sizeof(sb);
+ io_hdr.dxfer_direction = SG_DXFER_NONE;
+ io_hdr.dxfer_len = 0;
+ io_hdr.dxferp = inqBuff;
+ io_hdr.sbp = (unsigned char *) sb;
+ io_hdr.timeout = 2000;
+ io_hdr.cmdp = test_unit_ready_cmd;
+
+ sb[0] = 0xFF;
+
+ status = ioctl(h, SG_IO, (void *)&io_hdr);
+
+ if ( (status == 0) && (sb[0] == 0xFF))
+ inserted = 1;
+ }
+
+ close(h);
+ }
+ } else
+ inserted = 1;
+
+ return inserted;
+}
+
static void ide_atapi_cmd(IDEState *s)
{
const uint8_t *packet;
@@ -1162,11 +1212,25 @@ static void ide_atapi_cmd(IDEState *s)
switch(s->io_buffer[0]) {
case GPCMD_TEST_UNIT_READY:
if (bdrv_is_inserted(s->bs)) {
- ide_atapi_cmd_ok(s);
+ if (s->media_changed) {
+ s->media_changed = 0;
+ ide_atapi_cmd_error(s, SENSE_UNIT_ATTENTION, ASC_MEDIA_CHANGED);
+ }
+ else {
+ if (!cd_media_inserted(s) || shdev_media_check(s->bs)) {
+ bdrv_close(s->bs);
+ ide_atapi_cmd_error(s, SENSE_NOT_READY, ASC_MEDIUM_NOT_PRESENT);
+ }
+ else
+ ide_atapi_cmd_ok(s);
+ }
} else {
ide_atapi_cmd_error(s, SENSE_NOT_READY,
ASC_MEDIUM_NOT_PRESENT);
- xenstore_check_new_media_present(1000);
+// xenstore_check_new_media_present(1000);
+ if (cd_media_inserted(s)) {
+ do_insert_request();
+ }
}
break;
case GPCMD_MODE_SENSE_10:
@@ -1298,6 +1362,13 @@ static void ide_atapi_cmd(IDEState *s)
ASC_MEDIUM_NOT_PRESENT);
break;
}
+
+ if (shdev_media_check(s->bs)) {
+ bdrv_close(s->bs);
+ ide_atapi_cmd_error(s, SENSE_NOT_READY, ASC_MEDIUM_NOT_PRESENT);
+ break;
+ }
+
nb_sectors = (packet[6] << 16) | (packet[7] << 8) | packet[8];
lba = ube32_to_cpu(packet + 2);
if (nb_sectors == 0) {
@@ -1355,7 +1426,7 @@ static void ide_atapi_cmd(IDEState *s)
if (eject && !start) {
/* eject the disk */
- bdrv_close(s->bs);
+ do_eject(1, s->bs->device_name);
}
ide_atapi_cmd_ok(s);
}
@@ -1382,6 +1453,13 @@ static void ide_atapi_cmd(IDEState *s)
ASC_MEDIUM_NOT_PRESENT);
break;
}
+
+ if (shdev_media_check(s->bs)) {
+ bdrv_close(s->bs);
+ ide_atapi_cmd_error(s, SENSE_NOT_READY, ASC_MEDIUM_NOT_PRESENT);
+ break;
+ }
+
max_len = ube16_to_cpu(packet + 7);
format = packet[9] >> 6;
msf = (packet[1] >> 1) & 1;
@@ -1454,9 +1532,9 @@ static void cdrom_change_cb(void *opaque
IDEState *s = opaque;
int64_t nb_sectors;
- /* XXX: send interrupt too */
bdrv_get_geometry(s->bs, &nb_sectors);
s->nb_sectors = nb_sectors;
+ s->media_changed = 1;
}
static void ide_cmd_lba48_transform(IDEState *s, int lba48)
@@ -1756,6 +1834,7 @@ static void ide_ioport_write(void *opaqu
ide_set_signature(s);
s->status = 0x00; /* NOTE: READY is _not_ set */
s->error = 0x01;
+ s->media_changed = 0;
break;
case WIN_PACKETCMD:
if (!s->is_cdrom)
Index: xen-unstable/tools/ioemu/monitor.c
===================================================================
--- xen-unstable.orig/tools/ioemu/monitor.c
+++ xen-unstable/tools/ioemu/monitor.c
@@ -24,6 +24,7 @@
#include "vl.h"
#include "disas.h"
#include <dirent.h>
+#include <sys/shm.h>
#include "block_int.h"
//#define DEBUG
@@ -340,7 +341,44 @@ void do_eject(int force, const char *fil
term_printf("device not found\n");
return;
}
- eject_device(bs, force);
+
+ if (eject_device(bs, force) == 0) {
+ char cmd[strlen(bs->filename) + 16];
+ shdev_eject_notice(bs);
+ sprintf(cmd, "eject %s", bs->filename);
+ system(cmd);
+ }
+}
+
+void do_insert(const char *device)
+{
+ BlockDriverState *bs;
+
+ bs = bdrv_find(device);
+
+ if (!bs) {
+ term_printf("'%s' not found\n", device);
+ return;
+ }
+
+ if (!bs->removable) {
+ term_printf("'%s' is not removable\n", device);
+ return;
+ }
+
+ if (bs->inserted) {
+ term_printf("'%s' is already inserted\n", device);
+ return;
+ }
+
+ bdrv_open(bs, bs->filename, 0);
+}
+
+static int find_bs_by_type(BlockDriverState *bs, void *opaque)
+{
+ int *type = (int *)opaque;
+
+ return( (bs->type == *type) );
}
void do_change(const char *device, const char *filename)
@@ -356,7 +394,8 @@ void do_change(const char *device, const
}
if (eject_device(bs, 0) < 0)
return;
- bdrv_open(bs, filename, 0);
+ pstrcpy(bs->filename, sizeof(bs->filename), filename);
+ do_insert(bs->device_name);
if (bdrv_is_encrypted(bs)) {
term_printf("%s is encrypted.\n", device);
for(i = 0; i < 3; i++) {
@@ -368,6 +407,19 @@ void do_change(const char *device, const
}
}
+void do_insert_request()
+{
+ BlockDriverState *bs = NULL;
+ int type = BDRV_TYPE_CDROM;
+
+ bs = bdrv_find_bs(find_bs_by_type, &type);
+
+ if (bs)
+ do_change(bs->device_name, bs->filename);
+ else
+ term_printf("Did not find cdrom bs.\n");
+}
+
static void do_screen_dump(const char *filename)
{
vga_hw_screen_dump(filename);
Index: xen-unstable/tools/ioemu/sdl.c
===================================================================
--- xen-unstable.orig/tools/ioemu/sdl.c
+++ xen-unstable/tools/ioemu/sdl.c
@@ -544,7 +544,7 @@ void sdl_display_init(DisplayState *ds,
#ifndef _WIN32
/* NOTE: we still want Ctrl-C to work, so we undo the SDL redirections */
signal(SIGINT, SIG_DFL);
- signal(SIGQUIT, SIG_DFL);
+// signal(SIGQUIT, SIG_DFL);
#endif
ds->dpy_update = sdl_update;
Index: xen-unstable/tools/ioemu/vl.h
===================================================================
--- xen-unstable.orig/tools/ioemu/vl.h
+++ xen-unstable/tools/ioemu/vl.h
@@ -180,6 +180,8 @@ extern int smp_cpus;
#define BIOS_SIZE ((256 + 64) * 1024)
#endif
+#define CDROM_DISK_POSITION 2
+
/* keyboard/mouse support */
#define MOUSE_EVENT_LBUTTON 0x01
@@ -561,6 +563,7 @@ void bdrv_set_change_cb(BlockDriverState
void (*change_cb)(void *opaque), void *opaque);
void bdrv_get_format(BlockDriverState *bs, char *buf, int buf_size);
void bdrv_info(void);
+BlockDriverState *bdrv_find_bs(int (*it)(BlockDriverState *bs, void *opaque), void *opaque);
BlockDriverState *bdrv_find(const char *name);
void bdrv_iterate(void (*it)(void *opaque, const char *name), void *opaque);
int bdrv_is_encrypted(BlockDriverState *bs);
@@ -1180,6 +1183,15 @@ pflash_t *pflash_register (target_ulong
#endif /* defined(QEMU_TOOL) */
+/* shdev.h */
+
+int shdev_init(void);
+int shdev_report_device(BlockDriverState *bs, const char *name);
+void shdev_set_media_instance(BlockDriverState *bs);
+void shdev_eject_notice(BlockDriverState *bs);
+inline int shdev_media_check(BlockDriverState *bs);
+void do_info_shdev(void);
+
/* monitor.c */
void monitor_init(CharDriverState *hd, int show_banner);
void term_puts(const char *str);
@@ -1189,6 +1201,7 @@ void term_flush(void);
void term_print_help(void);
void monitor_readline(const char *prompt, int is_password,
char *buf, int buf_size);
+void do_insert_request(void);
void do_eject(int force, const char *filename);
void do_change(const char *device, const char *filename);
Index: xen-unstable/tools/ioemu/shdev.c
===================================================================
--- /dev/null
+++ xen-unstable/tools/ioemu/shdev.c
@@ -0,0 +1,138 @@
+/*
+ * Managment for Devices Shared Across Guests
+ *
+ * Copyright (c) 2006 Novell, Inc.
+ *
+ * - Author: Ross Maxfield (ross.maxfield@novell.com)
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "vl.h"
+#include "block_int.h"
+#include <sys/shm.h>
+
+#define MAX_SHARED_DEVS 4
+#define SHDEV_NAME_LEN 128
+#define SHARED_DEVS_SIGNATURE "ShRdDeVs"
+#define QEMU_KEY_PATH "/etc/xen"
+
+typedef struct SharedDevice {
+ char name[SHDEV_NAME_LEN];
+ int media_instance;
+} SharedDevice;
+
+typedef struct SharedDevices {
+ char signature[sizeof(SHARED_DEVS_SIGNATURE)];
+ SharedDevice device[MAX_SHARED_DEVS];
+} SharedDevices;
+
+SharedDevices *shdevs;
+
+int shdev_init()
+{
+ key_t shm_key;
+ int shm_id;
+
+ /* Alloc/Get shared device memory */
+ shm_key = ftok(QEMU_KEY_PATH, 'X');
+
+ if (((shm_id = shmget(shm_key,
+ sizeof(SharedDevices),
+ IPC_CREAT|IPC_EXCL|0660)) != -1)
+ && ((shdevs = shmat(shm_id, 0, 0)) != (void *)-1)) {
+ memcpy(&shdevs->signature, SHARED_DEVS_SIGNATURE,
+ sizeof(SHARED_DEVS_SIGNATURE));
+ }
+ else
+ if (errno == EEXIST)
+ {
+ if (((shm_id = shmget(shm_key, sizeof(SharedDevices), 0)) == -1)
+ || ((shdevs = shmat(shm_id, 0, 0)) == (void *)-1)
+ || (memcmp(shdevs->signature, SHARED_DEVS_SIGNATURE,
+ sizeof(SHARED_DEVS_SIGNATURE)) != 0)) {
+ shdevs = NULL;
+ fprintf(stderr, "Could not setup support for shared devices.\n");
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+void shdev_set_media_instance(BlockDriverState *bs)
+{
+ bs->media_instance = shdevs->device[bs->shdev_el].media_instance;
+}
+
+void shdev_eject_notice(BlockDriverState *bs)
+{
+ shdevs->device[bs->shdev_el].media_instance++;
+}
+
+inline int shdev_media_check(BlockDriverState *bs)
+{
+ return(!(bs->media_instance == shdevs->device[bs->shdev_el].media_instance));
+}
+
+int shdev_report_device(BlockDriverState *bs, const char *name)
+{
+ int i;
+
+ for (i = 0;
+ (i < MAX_SHARED_DEVS) && strcmp(shdevs->device[i].name, name);
+ i++);
+
+ if (i == MAX_SHARED_DEVS) {
+ for (i = 0;
+ (i < MAX_SHARED_DEVS) && (shdevs->device[i].name[0] != '\0');
+ i++);
+
+ if (i < MAX_SHARED_DEVS) {
+ pstrcpy(shdevs->device[i].name, SHDEV_NAME_LEN, name);
+ shdevs->device[i].media_instance = 0;
+ }
+ else {
+ fprintf(stderr, "%s exceeds maximum of %d shared devices.\n",
+ name, MAX_SHARED_DEVS );
+ return -1;
+ }
+ }
+
+ bs->media_instance = shdevs->device[i].media_instance;
+ bs->shdev_el = i;
+
+ return 0;
+}
+
+void do_info_shdev(void)
+{
+ int i;
+
+ /* Can this device be made availble to this domain? */
+ for (i = 0; i < MAX_SHARED_DEVS; i++) {
+ if (shdevs->device[i].name[0] != '\0') {
+ term_printf("'%s' [%d]\n",
+ shdevs->device[i].name,
+ shdevs->device[i].media_instance);
+ }
+ }
+}
+
+
Index: xen-unstable/tools/ioemu/Makefile.target
===================================================================
--- xen-unstable.orig/tools/ioemu/Makefile.target
+++ xen-unstable/tools/ioemu/Makefile.target
@@ -307,7 +307,7 @@ ifeq ($(ARCH),alpha)
endif
# must use static linking to avoid leaving stuff in virtual address space
-VL_OBJS=vl.o osdep.o block.o readline.o monitor.o pci.o console.o
+VL_OBJS=vl.o osdep.o block.o shdev.o readline.o monitor.o pci.o console.o
VL_OBJS+=block-cow.o block-qcow.o aes.o block-vmdk.o block-cloop.o block-dmg.o block-bochs.o block-vpc.o block-vvfat.o
ifdef CONFIG_WIN32
VL_OBJS+=tap-win32.o
Index: xen-unstable/tools/ioemu/vl.c
===================================================================
--- xen-unstable.orig/tools/ioemu/vl.c
+++ xen-unstable/tools/ioemu/vl.c
@@ -5843,6 +5843,8 @@ int main(int argc, char **argv)
int usb_devices_index;
unsigned long nr_pages, tmp_nr_pages, shared_page_nr;
xen_pfn_t *page_array;
+ int dev_type;
+ char buf[64];
extern void *shared_page;
extern void *buffered_io_page;
@@ -5073,7 +5073,7 @@ int main(int argc, char **argv)
#ifdef CONFIG_GDBSTUB
int use_gdbstub, gdbstub_port;
#endif
- int i, has_cdrom;
+ int i, has_cdrom = 0;
int snapshot, linux_boot;
CPUState *env;
const char *initrd_filename;
@@ -5094,6 +5094,8 @@ int main(int argc, char **argv)
const char *loadvm = NULL;
unsigned long nr_pages, extra_pages, ram_pages, *page_array;
xc_dominfo_t info;
+ int dev_type;
+ char buf[64];
extern void *shared_page;
extern void *shared_vram;
extern void *buffered_io_page;
@@ -5122,7 +5124,6 @@ int main(int argc, char **argv)
vncconnect=NULL;
kernel_filename = NULL;
kernel_cmdline = "";
- has_cdrom = 1;
cyls = heads = secs = 0;
pstrcpy(monitor_device, sizeof(monitor_device), "vc");
@@ -5185,12 +5186,6 @@ int main(int argc, char **argv)
case QEMU_OPTION_initrd:
initrd_filename = optarg;
break;
- case QEMU_OPTION_hda:
- hd_filename[0] = optarg;
- break;
- case QEMU_OPTION_hdb:
- hd_filename[1] = optarg;
- break;
case QEMU_OPTION_snapshot:
snapshot = 1;
break;
@@ -5263,15 +5258,56 @@ int main(int argc, char **argv)
}
}
break;
+ case QEMU_OPTION_hda:
+ if (hd_filename[0]) {
+ fprintf(stderr,
+ "qemu: virtual device 'hd%c' already defined as %s\n",
+ 'a',
+ hd_filename[0] );
+ break;
+ }
+ hd_filename[0] = optarg;
+ break;
+ case QEMU_OPTION_hdb:
+ if (hd_filename[1]) {
+ fprintf(stderr,
+ "qemu: virtual device 'hd%c' already defined as %s\n",
+ 'b',
+ hd_filename[1] );
+ break;
+ }
+ hd_filename[1] = optarg;
+ break;
case QEMU_OPTION_hdc:
+ if (hd_filename[2]) {
+ fprintf(stderr,
+ "qemu: virtual device 'hd%c' already defined as %s\n",
+ 'c',
+ hd_filename[2] );
+ break;
+ }
hd_filename[2] = optarg;
- has_cdrom = 0;
break;
case QEMU_OPTION_hdd:
+ if (hd_filename[3]) {
+ fprintf(stderr,
+ "qemu: virtual device 'hd%c' already defined as %s\n",
+ 'd',
+ hd_filename[3] );
+ break;
+ }
hd_filename[3] = optarg;
break;
case QEMU_OPTION_cdrom:
- hd_filename[2] = optarg;
+ if (hd_filename[CDROM_DISK_POSITION]) {
+ fprintf(stderr,
+ "qemu: virtual device 'hd%c' for cdrom "
+ "is already defined as %s\n",
+ 'a' + CDROM_DISK_POSITION,
+ hd_filename[CDROM_DISK_POSITION] );
+ break;
+ }
+ hd_filename[CDROM_DISK_POSITION] = optarg;
has_cdrom = 1;
break;
case QEMU_OPTION_boot:
@@ -5487,7 +5523,7 @@ int main(int argc, char **argv)
linux_boot = (kernel_filename != NULL);
if ( !linux_boot && hd_filename[0] == '\0' &&
- hd_filename[2] == '\0' && fd_filename[0] == '\0' )
+ hd_filename[CDROM_DISK_POSITION] == '\0' && fd_filename[0] == '\0' )
help();
/* boot to cd by default if no hard disk */
@@ -5668,59 +5704,55 @@ int main(int argc, char **argv)
fprintf(logfile, "shared page at pfn:%lx, mfn: %lx\n", (nr_pages-1),
(page_array[nr_pages - 1]));
- /* we always create the cdrom drive, even if no disk is there */
bdrv_init();
- if (has_cdrom) {
- int fd;
- if ( (fd = open(hd_filename[2], O_RDONLY | O_BINARY)) < 0) {
- hd_filename[2]=NULL;
- bs_table[2]=NULL;
- fprintf(logfile, "Could not open CD %s.\n", hd_filename[i]);
- }
- else {
- close(fd);
- bs_table[2] = bdrv_new("cdrom");
- bdrv_set_type_hint(bs_table[2], BDRV_TYPE_CDROM);
- }
- }
+
+ shdev_init();
/* open the virtual block devices */
for(i = 0; i < MAX_DISKS; i++) {
if (hd_filename[i]) {
- if (!bs_table[i]) {
- char buf[64];
+ if ((i == CDROM_DISK_POSITION) && has_cdrom) {
+ snprintf(buf, sizeof(buf), "cdrom");
+ dev_type = BDRV_TYPE_CDROM;
+ }
+ else {
snprintf(buf, sizeof(buf), "hd%c", i + 'a');
- bs_table[i] = bdrv_new(buf);
+ dev_type = BDRV_TYPE_HD;
}
+
+ bs_table[i] = bdrv_new(buf);
+
+ bdrv_set_type_hint(bs_table[i], dev_type);
+
+ if (bs_table[i]->removable)
+ shdev_report_device(bs_table[i], hd_filename[i]);
+
if (bdrv_open(bs_table[i], hd_filename[i], snapshot) < 0) {
+ if (bs_table[i]->removable)
+ continue;
+
fprintf(stderr, "qemu: could not open hard disk image '%s'\n",
hd_filename[i]);
exit(1);
}
+
if (i == 0 && cyls != 0)
bdrv_set_geometry_hint(bs_table[i], cyls, heads, secs);
}
}
- /* we always create at least one floppy disk */
- fd_table[0] = bdrv_new("fda");
- bdrv_set_type_hint(fd_table[0], BDRV_TYPE_FLOPPY);
-
for(i = 0; i < MAX_FD; i++) {
if (fd_filename[i]) {
if (!fd_table[i]) {
- char buf[64];
snprintf(buf, sizeof(buf), "fd%c", i + 'a');
fd_table[i] = bdrv_new(buf);
bdrv_set_type_hint(fd_table[i], BDRV_TYPE_FLOPPY);
+ shdev_report_device(fd_table[i], fd_filename[i]);
}
- if (fd_filename[i] != '\0') {
- if (bdrv_open(fd_table[i], fd_filename[i], snapshot) < 0) {
- fprintf(stderr, "qemu: could not open floppy disk image '%s'\n",
+
+ if (bdrv_open(fd_table[i], fd_filename[i], snapshot) < 0)
+ fprintf(stderr, "qemu: could not open floppy disk '%s'\n",
fd_filename[i]);
- exit(1);
- }
- }
}
}