#include "qemu-option.h"
#include "qemu-config.h"
#include "qemu-objects.h"
+#ifdef CONFIG_LINUX
+#include "fsdev/qemu-fsdev.h"
+#endif
#include "disas.h"
opts = qemu_opts_parse(&qemu_drive_opts, optstr, 0);
if (!opts) {
- fprintf(stderr, "%s: huh? duplicate? (%s)\n",
- __FUNCTION__, optstr);
return NULL;
}
if (file)
QEMUMachine *machine = opaque;
int max_devs;
int index;
- int cache;
- int aio = 0;
int ro = 0;
- int bdrv_flags;
+ int bdrv_flags = 0;
int on_read_error, on_write_error;
const char *devaddr;
DriveInfo *dinfo;
*fatal_error = 1;
translation = BIOS_ATA_TRANSLATION_AUTO;
- cache = 1;
if (machine && machine->use_scsi) {
type = IF_SCSI;
}
if ((buf = qemu_opt_get(opts, "cache")) != NULL) {
- if (!strcmp(buf, "off") || !strcmp(buf, "none"))
- cache = 0;
- else if (!strcmp(buf, "writethrough"))
- cache = 1;
- else if (!strcmp(buf, "writeback"))
- cache = 2;
- else {
+ if (!strcmp(buf, "off") || !strcmp(buf, "none")) {
+ bdrv_flags |= BDRV_O_NOCACHE;
+ } else if (!strcmp(buf, "writeback")) {
+ bdrv_flags |= BDRV_O_CACHE_WB;
+ } else if (!strcmp(buf, "writethrough")) {
+ /* this is the default */
+ } else {
fprintf(stderr, "qemu: invalid cache option\n");
return NULL;
}
#ifdef CONFIG_LINUX_AIO
if ((buf = qemu_opt_get(opts, "aio")) != NULL) {
- if (!strcmp(buf, "threads"))
- aio = 0;
- else if (!strcmp(buf, "native"))
- aio = 1;
- else {
+ if (!strcmp(buf, "native")) {
+ bdrv_flags |= BDRV_O_NATIVE_AIO;
+ } else if (!strcmp(buf, "threads")) {
+ /* this is the default */
+ } else {
fprintf(stderr, "qemu: invalid aio option\n");
return NULL;
}
*fatal_error = 0;
return NULL;
}
- bdrv_flags = 0;
if (snapshot) {
- bdrv_flags |= BDRV_O_SNAPSHOT;
- cache = 2; /* always use write-back with snapshot */
- }
- if (cache == 0) /* no caching */
- bdrv_flags |= BDRV_O_NOCACHE;
- else if (cache == 2) /* write-back */
- bdrv_flags |= BDRV_O_CACHE_WB;
-
- if (aio == 1) {
- bdrv_flags |= BDRV_O_NATIVE_AIO;
- } else {
- bdrv_flags &= ~BDRV_O_NATIVE_AIO;
+ /* always use write-back with snapshot */
+ bdrv_flags &= ~BDRV_O_CACHE_MASK;
+ bdrv_flags |= (BDRV_O_SNAPSHOT|BDRV_O_CACHE_WB);
}
if (media == MEDIA_CDROM) {
bdrv_flags |= ro ? 0 : BDRV_O_RDWR;
- if (bdrv_open2(dinfo->bdrv, file, bdrv_flags, drv) < 0) {
+ if (bdrv_open(dinfo->bdrv, file, bdrv_flags, drv) < 0) {
fprintf(stderr, "qemu: could not open disk image %s: %s\n",
file, strerror(errno));
return NULL;
static void restore_boot_devices(void *opaque)
{
char *standard_boot_devices = opaque;
+ static int first = 1;
+
+ /* Restore boot order and remove ourselves after the first boot */
+ if (first) {
+ first = 0;
+ return;
+ }
qemu_boot_set(standard_boot_devices);
vm_running = 1;
vm_state_notify(1, 0);
resume_all_vcpus();
+ monitor_protocol_event(QEVENT_RESUME, NULL);
}
}
static int powerdown_requested;
int debug_requested;
int vmstop_requested;
+static int exit_requested;
int qemu_shutdown_requested(void)
{
return r;
}
+int qemu_exit_requested(void)
+{
+ /* just return it, we'll exit() anyway */
+ return exit_requested;
+}
+
static int qemu_debug_requested(void)
{
int r = debug_requested;
qemu_notify_event();
}
+void qemu_system_exit_request(void)
+{
+ exit_requested = 1;
+ qemu_notify_event();
+}
+
#ifdef _WIN32
static void host_main_loop_wait(int *timeout)
{
return 0;
if (debug_requested)
return 0;
+ if (exit_requested)
+ return 0;
return 1;
}
if ((r = qemu_vmstop_requested())) {
vm_stop(r);
}
+ if (qemu_exit_requested()) {
+ exit(0);
+ }
}
pause_all_vcpus();
}
static void version(void)
{
- printf("QEMU PC emulator version " QEMU_VERSION QEMU_PKGVERSION ", Copyright (c) 2003-2008 Fabrice Bellard\n");
+ printf("QEMU emulator version " QEMU_VERSION QEMU_PKGVERSION ", Copyright (c) 2003-2008 Fabrice Bellard\n");
}
static void help(int exitcode)
version();
printf("usage: %s [options] [disk_image]\n"
"\n"
- "'disk_image' is a raw hard image image for IDE hard disk 0\n"
+ "'disk_image' is a raw hard disk image for IDE hard disk 0\n"
"\n"
"%s\n"
"During emulation, the following keys are useful:\n"
return 0;
}
+#ifdef CONFIG_LINUX
+static int fsdev_init_func(QemuOpts *opts, void *opaque)
+{
+ int ret;
+ ret = qemu_fsdev_add(opts);
+
+ return ret;
+}
+#endif
+
static int mon_init_func(QemuOpts *opts, void *opaque)
{
CharDriverState *chr;
if (strstart(optarg, "chardev:", &p)) {
snprintf(label, sizeof(label), "%s", p);
} else {
- if (monitor_device_index) {
- snprintf(label, sizeof(label), "monitor%d",
- monitor_device_index);
- } else {
- snprintf(label, sizeof(label), "monitor");
+ snprintf(label, sizeof(label), "compat_monitor%d",
+ monitor_device_index);
+ if (monitor_device_index == 0) {
def = 1;
}
opts = qemu_chr_parse_compat(label, optarg);
}
if (defconfig) {
- const char *fname;
- FILE *fp;
+ int ret;
- fname = CONFIG_QEMU_CONFDIR "/qemu.conf";
- fp = fopen(fname, "r");
- if (fp) {
- if (qemu_config_parse(fp, fname) != 0) {
- exit(1);
- }
- fclose(fp);
+ ret = qemu_read_config_file(CONFIG_QEMU_CONFDIR "/qemu.conf");
+ if (ret == -EINVAL) {
+ exit(1);
}
- fname = arch_config_name;
- fp = fopen(fname, "r");
- if (fp) {
- if (qemu_config_parse(fp, fname) != 0) {
- exit(1);
- }
- fclose(fp);
+ ret = qemu_read_config_file(arch_config_name);
+ if (ret == -EINVAL) {
+ exit(1);
}
}
cpudef_init();
case QEMU_OPTION_cpu:
/* hw initialization will check this */
if (*optarg == '?') {
-/* XXX: implement xxx_cpu_list for targets that still miss it */
-#if defined(cpu_list_id)
- cpu_list_id(stdout, &fprintf, optarg);
-#elif defined(cpu_list)
- cpu_list(stdout, &fprintf); /* deprecated */
-#endif
+ list_cpus(stdout, &fprintf, optarg);
exit(0);
} else {
cpu_model = optarg;
case QEMU_OPTION_mon:
opts = qemu_opts_parse(&qemu_mon_opts, optarg, 1);
if (!opts) {
- fprintf(stderr, "parse error: %s\n", optarg);
exit(1);
}
default_monitor = 0;
break;
case QEMU_OPTION_chardev:
opts = qemu_opts_parse(&qemu_chardev_opts, optarg, 1);
+ if (!opts) {
+ exit(1);
+ }
+ break;
+#ifdef CONFIG_LINUX
+ case QEMU_OPTION_fsdev:
+ opts = qemu_opts_parse(&qemu_fsdev_opts, optarg, 1);
+ if (!opts) {
+ fprintf(stderr, "parse error: %s\n", optarg);
+ exit(1);
+ }
+ break;
+ case QEMU_OPTION_virtfs: {
+ char *arg_fsdev = NULL;
+ char *arg_9p = NULL;
+ int len = 0;
+
+ opts = qemu_opts_parse(&qemu_virtfs_opts, optarg, 1);
if (!opts) {
fprintf(stderr, "parse error: %s\n", optarg);
exit(1);
}
+
+ len = strlen(",id=,path=");
+ len += strlen(qemu_opt_get(opts, "fstype"));
+ len += strlen(qemu_opt_get(opts, "mount_tag"));
+ len += strlen(qemu_opt_get(opts, "path"));
+ arg_fsdev = qemu_malloc((len + 1) * sizeof(*arg_fsdev));
+
+ if (!arg_fsdev) {
+ fprintf(stderr, "No memory to parse -fsdev for %s\n",
+ optarg);
+ exit(1);
+ }
+
+ sprintf(arg_fsdev, "%s,id=%s,path=%s",
+ qemu_opt_get(opts, "fstype"),
+ qemu_opt_get(opts, "mount_tag"),
+ qemu_opt_get(opts, "path"));
+
+ len = strlen("virtio-9p-pci,fsdev=,mount_tag=");
+ len += 2*strlen(qemu_opt_get(opts, "mount_tag"));
+ arg_9p = qemu_malloc((len + 1) * sizeof(*arg_9p));
+
+ if (!arg_9p) {
+ fprintf(stderr, "No memory to parse -device for %s\n",
+ optarg);
+ exit(1);
+ }
+
+ sprintf(arg_9p, "virtio-9p-pci,fsdev=%s,mount_tag=%s",
+ qemu_opt_get(opts, "mount_tag"),
+ qemu_opt_get(opts, "mount_tag"));
+
+ if (!qemu_opts_parse(&qemu_fsdev_opts, arg_fsdev, 1)) {
+ fprintf(stderr, "parse error [fsdev]: %s\n", optarg);
+ exit(1);
+ }
+
+ if (!qemu_opts_parse(&qemu_device_opts, arg_9p, 1)) {
+ fprintf(stderr, "parse error [device]: %s\n", optarg);
+ exit(1);
+ }
+
+ qemu_free(arg_fsdev);
+ qemu_free(arg_9p);
break;
+ }
+#endif
case QEMU_OPTION_serial:
add_device_config(DEV_SERIAL, optarg);
default_serial = 0;
do_smbios_option(optarg);
break;
case QEMU_OPTION_enable_kvm:
- if (!(kvm_available())) {
- printf("Option %s not supported for this target\n", popt->name);
- exit(1);
- }
kvm_allowed = 1;
break;
case QEMU_OPTION_usb:
case QEMU_OPTION_rtc:
opts = qemu_opts_parse(&qemu_rtc_opts, optarg, 0);
if (!opts) {
- fprintf(stderr, "parse error: %s\n", optarg);
exit(1);
}
configure_rtc(opts);
break;
case QEMU_OPTION_readconfig:
{
- FILE *fp;
- fp = fopen(optarg, "r");
- if (fp == NULL) {
- fprintf(stderr, "open %s: %s\n", optarg, strerror(errno));
- exit(1);
- }
- if (qemu_config_parse(fp, optarg) != 0) {
+ int ret = qemu_read_config_file(optarg);
+ if (ret < 0) {
+ fprintf(stderr, "read config %s: %s\n", optarg,
+ strerror(-ret));
exit(1);
}
- fclose(fp);
break;
}
case QEMU_OPTION_writeconfig:
if (default_vga)
vga_interface_type = VGA_CIRRUS;
+ socket_init();
+
if (qemu_opts_foreach(&qemu_chardev_opts, chardev_init_func, NULL, 1) != 0)
exit(1);
+#ifdef CONFIG_LINUX
+ if (qemu_opts_foreach(&qemu_fsdev_opts, fsdev_init_func, NULL, 1) != 0) {
+ exit(1);
+ }
+#endif
#ifndef _WIN32
if (daemonize) {
exit(1);
}
- if (kvm_enabled()) {
- int ret;
-
- ret = kvm_init(smp_cpus);
+ if (kvm_allowed) {
+ int ret = kvm_init(smp_cpus);
if (ret < 0) {
- fprintf(stderr, "failed to initialize KVM\n");
+ if (!kvm_available()) {
+ printf("KVM not supported for this target\n");
+ } else {
+ fprintf(stderr, "failed to initialize KVM: %s\n", strerror(-ret));
+ }
exit(1);
}
}
}
configure_icount(icount_option);
- socket_init();
-
if (net_init_clients() < 0) {
exit(1);
}
}
}
+ if (qemu_opts_foreach(&qemu_mon_opts, mon_init_func, NULL, 1) != 0) {
+ exit(1);
+ }
+
if (foreach_device_config(DEV_SERIAL, serial_parse) < 0)
exit(1);
if (foreach_device_config(DEV_PARALLEL, parallel_parse) < 0)
text_consoles_set_display(ds);
- if (qemu_opts_foreach(&qemu_mon_opts, mon_init_func, NULL, 1) != 0)
- exit(1);
-
if (gdbstub_dev && gdbserver_start(gdbstub_dev) < 0) {
fprintf(stderr, "qemu: could not open gdbserver on device '%s'\n",
gdbstub_dev);