switch -drive to QemuOpts.
Demo QemuOpts in action ;) Implementing a alternative way to specify the filename should be just a few lines of code now once we decided how the cmd line syntax should look like. Signed-off-by: Gerd Hoffmann <kraxel@redhat.com> Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
This commit is contained in:
parent
e27c88fe9e
commit
9dfd7c7a00
@ -28,19 +28,19 @@
|
|||||||
#include "block_int.h"
|
#include "block_int.h"
|
||||||
#include "sysemu.h"
|
#include "sysemu.h"
|
||||||
|
|
||||||
DriveInfo *add_init_drive(const char *opts)
|
DriveInfo *add_init_drive(const char *optstr)
|
||||||
{
|
{
|
||||||
int fatal_error;
|
int fatal_error;
|
||||||
DriveInfo *dinfo;
|
DriveInfo *dinfo;
|
||||||
DriveOpt *dopt;
|
QemuOpts *opts;
|
||||||
|
|
||||||
dopt = drive_add(NULL, "%s", opts);
|
opts = drive_add(NULL, "%s", optstr);
|
||||||
if (!dopt)
|
if (!opts)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
dinfo = drive_init(dopt, 0, current_machine, &fatal_error);
|
dinfo = drive_init(opts, current_machine, &fatal_error);
|
||||||
if (!dinfo) {
|
if (!dinfo) {
|
||||||
drive_remove(dopt);
|
qemu_opts_del(opts);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
14
sysemu.h
14
sysemu.h
@ -160,12 +160,6 @@ typedef enum {
|
|||||||
|
|
||||||
#define BLOCK_SERIAL_STRLEN 20
|
#define BLOCK_SERIAL_STRLEN 20
|
||||||
|
|
||||||
typedef struct DriveOpt {
|
|
||||||
const char *file;
|
|
||||||
char opt[1024];
|
|
||||||
TAILQ_ENTRY(DriveOpt) next;
|
|
||||||
} DriveOpt;
|
|
||||||
|
|
||||||
typedef struct DriveInfo {
|
typedef struct DriveInfo {
|
||||||
BlockDriverState *bdrv;
|
BlockDriverState *bdrv;
|
||||||
char *id;
|
char *id;
|
||||||
@ -173,7 +167,7 @@ typedef struct DriveInfo {
|
|||||||
BlockInterfaceType type;
|
BlockInterfaceType type;
|
||||||
int bus;
|
int bus;
|
||||||
int unit;
|
int unit;
|
||||||
DriveOpt *opt;
|
QemuOpts *opts;
|
||||||
BlockInterfaceErrorAction onerror;
|
BlockInterfaceErrorAction onerror;
|
||||||
char serial[BLOCK_SERIAL_STRLEN + 1];
|
char serial[BLOCK_SERIAL_STRLEN + 1];
|
||||||
TAILQ_ENTRY(DriveInfo) next;
|
TAILQ_ENTRY(DriveInfo) next;
|
||||||
@ -190,15 +184,13 @@ extern DriveInfo *drive_get(BlockInterfaceType type, int bus, int unit);
|
|||||||
extern DriveInfo *drive_get_by_id(char *id);
|
extern DriveInfo *drive_get_by_id(char *id);
|
||||||
extern int drive_get_max_bus(BlockInterfaceType type);
|
extern int drive_get_max_bus(BlockInterfaceType type);
|
||||||
extern void drive_uninit(BlockDriverState *bdrv);
|
extern void drive_uninit(BlockDriverState *bdrv);
|
||||||
extern void drive_remove(DriveOpt *opt);
|
|
||||||
extern const char *drive_get_serial(BlockDriverState *bdrv);
|
extern const char *drive_get_serial(BlockDriverState *bdrv);
|
||||||
extern BlockInterfaceErrorAction drive_get_onerror(BlockDriverState *bdrv);
|
extern BlockInterfaceErrorAction drive_get_onerror(BlockDriverState *bdrv);
|
||||||
|
|
||||||
BlockDriverState *qdev_init_bdrv(DeviceState *dev, BlockInterfaceType type);
|
BlockDriverState *qdev_init_bdrv(DeviceState *dev, BlockInterfaceType type);
|
||||||
|
|
||||||
extern DriveOpt *drive_add(const char *file, const char *fmt, ...);
|
extern QemuOpts *drive_add(const char *file, const char *fmt, ...);
|
||||||
extern DriveInfo *drive_init(DriveOpt *arg, int snapshot, void *machine,
|
extern DriveInfo *drive_init(QemuOpts *arg, void *machine, int *fatal_error);
|
||||||
int *fatal_error);
|
|
||||||
|
|
||||||
/* acpi */
|
/* acpi */
|
||||||
typedef void (*qemu_system_device_hot_add_t)(int pcibus, int slot, int state);
|
typedef void (*qemu_system_device_hot_add_t)(int pcibus, int slot, int state);
|
||||||
|
308
vl.c
308
vl.c
@ -1800,27 +1800,94 @@ static int bt_parse(const char *opt)
|
|||||||
#define MTD_ALIAS "if=mtd"
|
#define MTD_ALIAS "if=mtd"
|
||||||
#define SD_ALIAS "index=0,if=sd"
|
#define SD_ALIAS "index=0,if=sd"
|
||||||
|
|
||||||
DriveOpt *drive_add(const char *file, const char *fmt, ...)
|
static QemuOptsList drive_opt_list = {
|
||||||
|
.name = "drive",
|
||||||
|
.head = TAILQ_HEAD_INITIALIZER(drive_opt_list.head),
|
||||||
|
.desc = {
|
||||||
|
{
|
||||||
|
.name = "bus",
|
||||||
|
.type = QEMU_OPT_NUMBER,
|
||||||
|
.help = "bus number",
|
||||||
|
},{
|
||||||
|
.name = "unit",
|
||||||
|
.type = QEMU_OPT_NUMBER,
|
||||||
|
.help = "unit number (i.e. lun for scsi)",
|
||||||
|
},{
|
||||||
|
.name = "if",
|
||||||
|
.type = QEMU_OPT_STRING,
|
||||||
|
.help = "interface (ide, scsi, sd, mtd, floppy, pflash, virtio)",
|
||||||
|
},{
|
||||||
|
.name = "index",
|
||||||
|
.type = QEMU_OPT_NUMBER,
|
||||||
|
},{
|
||||||
|
.name = "cyls",
|
||||||
|
.type = QEMU_OPT_NUMBER,
|
||||||
|
.help = "number of cylinders (ide disk geometry)",
|
||||||
|
},{
|
||||||
|
.name = "heads",
|
||||||
|
.type = QEMU_OPT_NUMBER,
|
||||||
|
.help = "number of heads (ide disk geometry)",
|
||||||
|
},{
|
||||||
|
.name = "secs",
|
||||||
|
.type = QEMU_OPT_NUMBER,
|
||||||
|
.help = "number of sectors (ide disk geometry)",
|
||||||
|
},{
|
||||||
|
.name = "trans",
|
||||||
|
.type = QEMU_OPT_STRING,
|
||||||
|
.help = "chs translation (auto, lba. none)",
|
||||||
|
},{
|
||||||
|
.name = "media",
|
||||||
|
.type = QEMU_OPT_STRING,
|
||||||
|
.help = "media type (disk, cdrom)",
|
||||||
|
},{
|
||||||
|
.name = "snapshot",
|
||||||
|
.type = QEMU_OPT_BOOL,
|
||||||
|
},{
|
||||||
|
.name = "file",
|
||||||
|
.type = QEMU_OPT_STRING,
|
||||||
|
.help = "disk image",
|
||||||
|
},{
|
||||||
|
.name = "cache",
|
||||||
|
.type = QEMU_OPT_STRING,
|
||||||
|
.help = "host cache usage (none, writeback, writethrough)",
|
||||||
|
},{
|
||||||
|
.name = "format",
|
||||||
|
.type = QEMU_OPT_STRING,
|
||||||
|
.help = "disk format (raw, qcow2, ...)",
|
||||||
|
},{
|
||||||
|
.name = "serial",
|
||||||
|
.type = QEMU_OPT_STRING,
|
||||||
|
},{
|
||||||
|
.name = "werror",
|
||||||
|
.type = QEMU_OPT_STRING,
|
||||||
|
},{
|
||||||
|
.name = "addr",
|
||||||
|
.type = QEMU_OPT_STRING,
|
||||||
|
.help = "pci address (virtio only)",
|
||||||
|
},
|
||||||
|
{ /* end if list */ }
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
QemuOpts *drive_add(const char *file, const char *fmt, ...)
|
||||||
{
|
{
|
||||||
va_list ap;
|
va_list ap;
|
||||||
DriveOpt *dopt;
|
char optstr[1024];
|
||||||
|
QemuOpts *opts;
|
||||||
|
|
||||||
dopt = qemu_mallocz(sizeof(*dopt));
|
|
||||||
|
|
||||||
dopt->file = file;
|
|
||||||
va_start(ap, fmt);
|
va_start(ap, fmt);
|
||||||
vsnprintf(dopt->opt,
|
vsnprintf(optstr, sizeof(optstr), fmt, ap);
|
||||||
sizeof(dopt->opt), fmt, ap);
|
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
|
|
||||||
TAILQ_INSERT_TAIL(&driveopts, dopt, next);
|
opts = qemu_opts_parse(&drive_opt_list, optstr, NULL);
|
||||||
return dopt;
|
if (!opts) {
|
||||||
}
|
fprintf(stderr, "%s: huh? duplicate? (%s)\n",
|
||||||
|
__FUNCTION__, optstr);
|
||||||
void drive_remove(DriveOpt *dopt)
|
return NULL;
|
||||||
{
|
}
|
||||||
TAILQ_REMOVE(&driveopts, dopt, next);
|
if (file)
|
||||||
qemu_free(dopt);
|
qemu_opt_set(opts, "file", file);
|
||||||
|
return opts;
|
||||||
}
|
}
|
||||||
|
|
||||||
DriveInfo *drive_get(BlockInterfaceType type, int bus, int unit)
|
DriveInfo *drive_get(BlockInterfaceType type, int bus, int unit)
|
||||||
@ -1901,20 +1968,20 @@ void drive_uninit(BlockDriverState *bdrv)
|
|||||||
TAILQ_FOREACH(dinfo, &drives, next) {
|
TAILQ_FOREACH(dinfo, &drives, next) {
|
||||||
if (dinfo->bdrv != bdrv)
|
if (dinfo->bdrv != bdrv)
|
||||||
continue;
|
continue;
|
||||||
drive_remove(dinfo->opt);
|
qemu_opts_del(dinfo->opts);
|
||||||
TAILQ_REMOVE(&drives, dinfo, next);
|
TAILQ_REMOVE(&drives, dinfo, next);
|
||||||
qemu_free(dinfo);
|
qemu_free(dinfo);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DriveInfo *drive_init(DriveOpt *arg, int snapshot, void *opaque,
|
DriveInfo *drive_init(QemuOpts *opts, void *opaque,
|
||||||
int *fatal_error)
|
int *fatal_error)
|
||||||
{
|
{
|
||||||
char buf[128];
|
const char *buf;
|
||||||
char file[1024];
|
const char *file = NULL;
|
||||||
char devname[128];
|
char devname[128];
|
||||||
char serial[21];
|
const char *serial;
|
||||||
const char *mediastr = "";
|
const char *mediastr = "";
|
||||||
BlockInterfaceType type;
|
BlockInterfaceType type;
|
||||||
enum { MEDIA_DISK, MEDIA_CDROM } media;
|
enum { MEDIA_DISK, MEDIA_CDROM } media;
|
||||||
@ -1928,27 +1995,11 @@ DriveInfo *drive_init(DriveOpt *arg, int snapshot, void *opaque,
|
|||||||
int bdrv_flags, onerror;
|
int bdrv_flags, onerror;
|
||||||
const char *devaddr;
|
const char *devaddr;
|
||||||
DriveInfo *dinfo;
|
DriveInfo *dinfo;
|
||||||
char *str = arg->opt;
|
int snapshot = 0;
|
||||||
static const char * const params[] = { "bus", "unit", "if", "index",
|
|
||||||
"cyls", "heads", "secs", "trans",
|
|
||||||
"media", "snapshot", "file",
|
|
||||||
"cache", "format", "serial",
|
|
||||||
"werror", "addr", "id",
|
|
||||||
NULL };
|
|
||||||
*fatal_error = 1;
|
*fatal_error = 1;
|
||||||
|
|
||||||
if (check_params(buf, sizeof(buf), params, str) < 0) {
|
|
||||||
fprintf(stderr, "qemu: unknown parameter '%s' in '%s'\n",
|
|
||||||
buf, str);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
file[0] = 0;
|
|
||||||
cyls = heads = secs = 0;
|
|
||||||
bus_id = 0;
|
|
||||||
unit_id = -1;
|
|
||||||
translation = BIOS_ATA_TRANSLATION_AUTO;
|
translation = BIOS_ATA_TRANSLATION_AUTO;
|
||||||
index = -1;
|
|
||||||
cache = 1;
|
cache = 1;
|
||||||
|
|
||||||
if (machine->use_scsi) {
|
if (machine->use_scsi) {
|
||||||
@ -1963,24 +2014,20 @@ DriveInfo *drive_init(DriveOpt *arg, int snapshot, void *opaque,
|
|||||||
media = MEDIA_DISK;
|
media = MEDIA_DISK;
|
||||||
|
|
||||||
/* extract parameters */
|
/* extract parameters */
|
||||||
|
bus_id = qemu_opt_get_number(opts, "bus", 0);
|
||||||
|
unit_id = qemu_opt_get_number(opts, "unit", -1);
|
||||||
|
index = qemu_opt_get_number(opts, "index", -1);
|
||||||
|
|
||||||
if (get_param_value(buf, sizeof(buf), "bus", str)) {
|
cyls = qemu_opt_get_number(opts, "cyls", 0);
|
||||||
bus_id = strtol(buf, NULL, 0);
|
heads = qemu_opt_get_number(opts, "heads", 0);
|
||||||
if (bus_id < 0) {
|
secs = qemu_opt_get_number(opts, "secs", 0);
|
||||||
fprintf(stderr, "qemu: '%s' invalid bus id\n", str);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (get_param_value(buf, sizeof(buf), "unit", str)) {
|
snapshot = qemu_opt_get_bool(opts, "snapshot", 0);
|
||||||
unit_id = strtol(buf, NULL, 0);
|
|
||||||
if (unit_id < 0) {
|
|
||||||
fprintf(stderr, "qemu: '%s' invalid unit id\n", str);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (get_param_value(buf, sizeof(buf), "if", str)) {
|
file = qemu_opt_get(opts, "file");
|
||||||
|
serial = qemu_opt_get(opts, "serial");
|
||||||
|
|
||||||
|
if ((buf = qemu_opt_get(opts, "if")) != NULL) {
|
||||||
pstrcpy(devname, sizeof(devname), buf);
|
pstrcpy(devname, sizeof(devname), buf);
|
||||||
if (!strcmp(buf, "ide")) {
|
if (!strcmp(buf, "ide")) {
|
||||||
type = IF_IDE;
|
type = IF_IDE;
|
||||||
@ -2007,51 +2054,31 @@ DriveInfo *drive_init(DriveOpt *arg, int snapshot, void *opaque,
|
|||||||
type = IF_XEN;
|
type = IF_XEN;
|
||||||
max_devs = 0;
|
max_devs = 0;
|
||||||
} else {
|
} else {
|
||||||
fprintf(stderr, "qemu: '%s' unsupported bus type '%s'\n", str, buf);
|
fprintf(stderr, "qemu: unsupported bus type '%s'\n", buf);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (get_param_value(buf, sizeof(buf), "index", str)) {
|
|
||||||
index = strtol(buf, NULL, 0);
|
|
||||||
if (index < 0) {
|
|
||||||
fprintf(stderr, "qemu: '%s' invalid index\n", str);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (get_param_value(buf, sizeof(buf), "cyls", str)) {
|
|
||||||
cyls = strtol(buf, NULL, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (get_param_value(buf, sizeof(buf), "heads", str)) {
|
|
||||||
heads = strtol(buf, NULL, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (get_param_value(buf, sizeof(buf), "secs", str)) {
|
|
||||||
secs = strtol(buf, NULL, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cyls || heads || secs) {
|
if (cyls || heads || secs) {
|
||||||
if (cyls < 1 || cyls > 16383) {
|
if (cyls < 1 || cyls > 16383) {
|
||||||
fprintf(stderr, "qemu: '%s' invalid physical cyls number\n", str);
|
fprintf(stderr, "qemu: '%s' invalid physical cyls number\n", buf);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
if (heads < 1 || heads > 16) {
|
if (heads < 1 || heads > 16) {
|
||||||
fprintf(stderr, "qemu: '%s' invalid physical heads number\n", str);
|
fprintf(stderr, "qemu: '%s' invalid physical heads number\n", buf);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
if (secs < 1 || secs > 63) {
|
if (secs < 1 || secs > 63) {
|
||||||
fprintf(stderr, "qemu: '%s' invalid physical secs number\n", str);
|
fprintf(stderr, "qemu: '%s' invalid physical secs number\n", buf);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (get_param_value(buf, sizeof(buf), "trans", str)) {
|
if ((buf = qemu_opt_get(opts, "trans")) != NULL) {
|
||||||
if (!cyls) {
|
if (!cyls) {
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"qemu: '%s' trans must be used with cyls,heads and secs\n",
|
"qemu: '%s' trans must be used with cyls,heads and secs\n",
|
||||||
str);
|
buf);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
if (!strcmp(buf, "none"))
|
if (!strcmp(buf, "none"))
|
||||||
@ -2061,39 +2088,28 @@ DriveInfo *drive_init(DriveOpt *arg, int snapshot, void *opaque,
|
|||||||
else if (!strcmp(buf, "auto"))
|
else if (!strcmp(buf, "auto"))
|
||||||
translation = BIOS_ATA_TRANSLATION_AUTO;
|
translation = BIOS_ATA_TRANSLATION_AUTO;
|
||||||
else {
|
else {
|
||||||
fprintf(stderr, "qemu: '%s' invalid translation type\n", str);
|
fprintf(stderr, "qemu: '%s' invalid translation type\n", buf);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (get_param_value(buf, sizeof(buf), "media", str)) {
|
if ((buf = qemu_opt_get(opts, "media")) != NULL) {
|
||||||
if (!strcmp(buf, "disk")) {
|
if (!strcmp(buf, "disk")) {
|
||||||
media = MEDIA_DISK;
|
media = MEDIA_DISK;
|
||||||
} else if (!strcmp(buf, "cdrom")) {
|
} else if (!strcmp(buf, "cdrom")) {
|
||||||
if (cyls || secs || heads) {
|
if (cyls || secs || heads) {
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"qemu: '%s' invalid physical CHS format\n", str);
|
"qemu: '%s' invalid physical CHS format\n", buf);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
media = MEDIA_CDROM;
|
media = MEDIA_CDROM;
|
||||||
} else {
|
} else {
|
||||||
fprintf(stderr, "qemu: '%s' invalid media\n", str);
|
fprintf(stderr, "qemu: '%s' invalid media\n", buf);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (get_param_value(buf, sizeof(buf), "snapshot", str)) {
|
if ((buf = qemu_opt_get(opts, "cache")) != NULL) {
|
||||||
if (!strcmp(buf, "on"))
|
|
||||||
snapshot = 1;
|
|
||||||
else if (!strcmp(buf, "off"))
|
|
||||||
snapshot = 0;
|
|
||||||
else {
|
|
||||||
fprintf(stderr, "qemu: '%s' invalid snapshot option\n", str);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (get_param_value(buf, sizeof(buf), "cache", str)) {
|
|
||||||
if (!strcmp(buf, "off") || !strcmp(buf, "none"))
|
if (!strcmp(buf, "off") || !strcmp(buf, "none"))
|
||||||
cache = 0;
|
cache = 0;
|
||||||
else if (!strcmp(buf, "writethrough"))
|
else if (!strcmp(buf, "writethrough"))
|
||||||
@ -2106,7 +2122,7 @@ DriveInfo *drive_init(DriveOpt *arg, int snapshot, void *opaque,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (get_param_value(buf, sizeof(buf), "format", str)) {
|
if ((buf = qemu_opt_get(opts, "format")) != NULL) {
|
||||||
if (strcmp(buf, "?") == 0) {
|
if (strcmp(buf, "?") == 0) {
|
||||||
fprintf(stderr, "qemu: Supported formats:");
|
fprintf(stderr, "qemu: Supported formats:");
|
||||||
bdrv_iterate_format(bdrv_format_print, NULL);
|
bdrv_iterate_format(bdrv_format_print, NULL);
|
||||||
@ -2120,16 +2136,8 @@ DriveInfo *drive_init(DriveOpt *arg, int snapshot, void *opaque,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (arg->file == NULL)
|
|
||||||
get_param_value(file, sizeof(file), "file", str);
|
|
||||||
else
|
|
||||||
pstrcpy(file, sizeof(file), arg->file);
|
|
||||||
|
|
||||||
if (!get_param_value(serial, sizeof(serial), "serial", str))
|
|
||||||
memset(serial, 0, sizeof(serial));
|
|
||||||
|
|
||||||
onerror = BLOCK_ERR_STOP_ENOSPC;
|
onerror = BLOCK_ERR_STOP_ENOSPC;
|
||||||
if (get_param_value(buf, sizeof(serial), "werror", str)) {
|
if ((buf = qemu_opt_get(opts, "werror")) != NULL) {
|
||||||
if (type != IF_IDE && type != IF_SCSI && type != IF_VIRTIO) {
|
if (type != IF_IDE && type != IF_SCSI && type != IF_VIRTIO) {
|
||||||
fprintf(stderr, "werror is no supported by this format\n");
|
fprintf(stderr, "werror is no supported by this format\n");
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -2148,13 +2156,11 @@ DriveInfo *drive_init(DriveOpt *arg, int snapshot, void *opaque,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
devaddr = NULL;
|
if ((devaddr = qemu_opt_get(opts, "addr")) != NULL) {
|
||||||
if (get_param_value(buf, sizeof(buf), "addr", str)) {
|
|
||||||
if (type != IF_VIRTIO) {
|
if (type != IF_VIRTIO) {
|
||||||
fprintf(stderr, "addr is not supported by in '%s'\n", str);
|
fprintf(stderr, "addr is not supported\n");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
devaddr = strdup(buf);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* compute bus and unit according index */
|
/* compute bus and unit according index */
|
||||||
@ -2162,7 +2168,7 @@ DriveInfo *drive_init(DriveOpt *arg, int snapshot, void *opaque,
|
|||||||
if (index != -1) {
|
if (index != -1) {
|
||||||
if (bus_id != 0 || unit_id != -1) {
|
if (bus_id != 0 || unit_id != -1) {
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"qemu: '%s' index cannot be used with bus and unit\n", str);
|
"qemu: index cannot be used with bus and unit\n");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
if (max_devs == 0)
|
if (max_devs == 0)
|
||||||
@ -2193,8 +2199,8 @@ DriveInfo *drive_init(DriveOpt *arg, int snapshot, void *opaque,
|
|||||||
/* check unit id */
|
/* check unit id */
|
||||||
|
|
||||||
if (max_devs && unit_id >= max_devs) {
|
if (max_devs && unit_id >= max_devs) {
|
||||||
fprintf(stderr, "qemu: '%s' unit %d too big (max is %d)\n",
|
fprintf(stderr, "qemu: unit %d too big (max is %d)\n",
|
||||||
str, unit_id, max_devs - 1);
|
unit_id, max_devs - 1);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2210,26 +2216,29 @@ DriveInfo *drive_init(DriveOpt *arg, int snapshot, void *opaque,
|
|||||||
/* init */
|
/* init */
|
||||||
|
|
||||||
dinfo = qemu_mallocz(sizeof(*dinfo));
|
dinfo = qemu_mallocz(sizeof(*dinfo));
|
||||||
if (!get_param_value(buf, sizeof(buf), "id", str)) {
|
if ((buf = qemu_opt_get(opts, "id")) != NULL) {
|
||||||
|
dinfo->id = qemu_strdup(buf);
|
||||||
|
} else {
|
||||||
/* no id supplied -> create one */
|
/* no id supplied -> create one */
|
||||||
|
dinfo->id = qemu_mallocz(32);
|
||||||
if (type == IF_IDE || type == IF_SCSI)
|
if (type == IF_IDE || type == IF_SCSI)
|
||||||
mediastr = (media == MEDIA_CDROM) ? "-cd" : "-hd";
|
mediastr = (media == MEDIA_CDROM) ? "-cd" : "-hd";
|
||||||
if (max_devs)
|
if (max_devs)
|
||||||
snprintf(buf, sizeof(buf), "%s%i%s%i",
|
snprintf(dinfo->id, 32, "%s%i%s%i",
|
||||||
devname, bus_id, mediastr, unit_id);
|
devname, bus_id, mediastr, unit_id);
|
||||||
else
|
else
|
||||||
snprintf(buf, sizeof(buf), "%s%s%i",
|
snprintf(dinfo->id, 32, "%s%s%i",
|
||||||
devname, mediastr, unit_id);
|
devname, mediastr, unit_id);
|
||||||
}
|
}
|
||||||
dinfo->id = qemu_strdup(buf);
|
|
||||||
dinfo->bdrv = bdrv_new(dinfo->id);
|
dinfo->bdrv = bdrv_new(dinfo->id);
|
||||||
dinfo->devaddr = devaddr;
|
dinfo->devaddr = devaddr;
|
||||||
dinfo->type = type;
|
dinfo->type = type;
|
||||||
dinfo->bus = bus_id;
|
dinfo->bus = bus_id;
|
||||||
dinfo->unit = unit_id;
|
dinfo->unit = unit_id;
|
||||||
dinfo->onerror = onerror;
|
dinfo->onerror = onerror;
|
||||||
dinfo->opt = arg;
|
dinfo->opts = opts;
|
||||||
strncpy(dinfo->serial, serial, sizeof(serial));
|
if (serial)
|
||||||
|
strncpy(dinfo->serial, serial, sizeof(serial));
|
||||||
TAILQ_INSERT_TAIL(&drives, dinfo, next);
|
TAILQ_INSERT_TAIL(&drives, dinfo, next);
|
||||||
|
|
||||||
switch(type) {
|
switch(type) {
|
||||||
@ -2261,7 +2270,7 @@ DriveInfo *drive_init(DriveOpt *arg, int snapshot, void *opaque,
|
|||||||
case IF_COUNT:
|
case IF_COUNT:
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
if (!file[0]) {
|
if (!file) {
|
||||||
*fatal_error = 0;
|
*fatal_error = 0;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@ -2285,6 +2294,26 @@ DriveInfo *drive_init(DriveOpt *arg, int snapshot, void *opaque,
|
|||||||
return dinfo;
|
return dinfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int drive_init_func(QemuOpts *opts, void *opaque)
|
||||||
|
{
|
||||||
|
QEMUMachine *machine = opaque;
|
||||||
|
int fatal_error = 0;
|
||||||
|
|
||||||
|
if (drive_init(opts, machine, &fatal_error) == NULL) {
|
||||||
|
if (fatal_error)
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int drive_enable_snapshot(QemuOpts *opts, void *opaque)
|
||||||
|
{
|
||||||
|
if (NULL == qemu_opt_get(opts, "snapshot")) {
|
||||||
|
qemu_opt_set(opts, "snapshot", "on");
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
void qemu_register_boot_set(QEMUBootSetHandler *func, void *opaque)
|
void qemu_register_boot_set(QEMUBootSetHandler *func, void *opaque)
|
||||||
{
|
{
|
||||||
boot_set_handler = func;
|
boot_set_handler = func;
|
||||||
@ -4815,7 +4844,7 @@ int main(int argc, char **argv, char **envp)
|
|||||||
int cyls, heads, secs, translation;
|
int cyls, heads, secs, translation;
|
||||||
const char *net_clients[MAX_NET_CLIENTS];
|
const char *net_clients[MAX_NET_CLIENTS];
|
||||||
int nb_net_clients;
|
int nb_net_clients;
|
||||||
DriveOpt *dopt, *hda_opt = NULL;
|
QemuOpts *hda_opts = NULL;
|
||||||
int optind;
|
int optind;
|
||||||
const char *r, *optarg;
|
const char *r, *optarg;
|
||||||
CharDriverState *monitor_hd = NULL;
|
CharDriverState *monitor_hd = NULL;
|
||||||
@ -4923,7 +4952,7 @@ int main(int argc, char **argv, char **envp)
|
|||||||
break;
|
break;
|
||||||
r = argv[optind];
|
r = argv[optind];
|
||||||
if (r[0] != '-') {
|
if (r[0] != '-') {
|
||||||
hda_opt = drive_add(argv[optind++], HD_ALIAS, 0);
|
hda_opts = drive_add(argv[optind++], HD_ALIAS, 0);
|
||||||
} else {
|
} else {
|
||||||
const QEMUOption *popt;
|
const QEMUOption *popt;
|
||||||
|
|
||||||
@ -4987,9 +5016,9 @@ int main(int argc, char **argv, char **envp)
|
|||||||
break;
|
break;
|
||||||
case QEMU_OPTION_hda:
|
case QEMU_OPTION_hda:
|
||||||
if (cyls == 0)
|
if (cyls == 0)
|
||||||
hda_opt = drive_add(optarg, HD_ALIAS, 0);
|
hda_opts = drive_add(optarg, HD_ALIAS, 0);
|
||||||
else
|
else
|
||||||
hda_opt = drive_add(optarg, HD_ALIAS
|
hda_opts = drive_add(optarg, HD_ALIAS
|
||||||
",cyls=%d,heads=%d,secs=%d%s",
|
",cyls=%d,heads=%d,secs=%d%s",
|
||||||
0, cyls, heads, secs,
|
0, cyls, heads, secs,
|
||||||
translation == BIOS_ATA_TRANSLATION_LBA ?
|
translation == BIOS_ATA_TRANSLATION_LBA ?
|
||||||
@ -5051,15 +5080,19 @@ int main(int argc, char **argv, char **envp)
|
|||||||
fprintf(stderr, "qemu: invalid physical CHS format\n");
|
fprintf(stderr, "qemu: invalid physical CHS format\n");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
if (hda_opt != NULL)
|
if (hda_opts != NULL) {
|
||||||
snprintf(hda_opt->opt,
|
char num[16];
|
||||||
sizeof(hda_opt->opt),
|
snprintf(num, sizeof(num), "%d", cyls);
|
||||||
HD_ALIAS ",cyls=%d,heads=%d,secs=%d%s",
|
qemu_opt_set(hda_opts, "cyls", num);
|
||||||
0, cyls, heads, secs,
|
snprintf(num, sizeof(num), "%d", heads);
|
||||||
translation == BIOS_ATA_TRANSLATION_LBA ?
|
qemu_opt_set(hda_opts, "heads", num);
|
||||||
",trans=lba" :
|
snprintf(num, sizeof(num), "%d", secs);
|
||||||
translation == BIOS_ATA_TRANSLATION_NONE ?
|
qemu_opt_set(hda_opts, "secs", num);
|
||||||
",trans=none" : "");
|
if (translation == BIOS_ATA_TRANSLATION_LBA)
|
||||||
|
qemu_opt_set(hda_opts, "trans", "lba");
|
||||||
|
if (translation == BIOS_ATA_TRANSLATION_NONE)
|
||||||
|
qemu_opt_set(hda_opts, "trans", "none");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case QEMU_OPTION_numa:
|
case QEMU_OPTION_numa:
|
||||||
@ -5771,13 +5804,10 @@ int main(int argc, char **argv, char **envp)
|
|||||||
drive_add(NULL, SD_ALIAS);
|
drive_add(NULL, SD_ALIAS);
|
||||||
|
|
||||||
/* open the virtual block devices */
|
/* open the virtual block devices */
|
||||||
|
if (snapshot)
|
||||||
TAILQ_FOREACH(dopt, &driveopts, next) {
|
qemu_opts_foreach(&drive_opt_list, drive_enable_snapshot, NULL, 0);
|
||||||
int fatal_error;
|
if (qemu_opts_foreach(&drive_opt_list, drive_init_func, machine, 1) != 0)
|
||||||
if (drive_init(dopt, snapshot, machine, &fatal_error) == NULL)
|
exit(1);
|
||||||
if (fatal_error)
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
register_savevm("timer", 0, 2, timer_save, timer_load, NULL);
|
register_savevm("timer", 0, 2, timer_save, timer_load, NULL);
|
||||||
register_savevm_live("ram", 0, 3, ram_save_live, NULL, ram_load, NULL);
|
register_savevm_live("ram", 0, 3, ram_save_live, NULL, ram_load, NULL);
|
||||||
|
Loading…
Reference in New Issue
Block a user