723 lines
23 KiB
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);
|
|
- }
|
|
- }
|
|
}
|
|
}
|
|
|