*/
#include "qemu/osdep.h"
+#include "qemu/units.h"
#include "qapi/error.h"
#include "qemu-version.h"
#include "qemu/cutils.h"
#include "qemu/help_option.h"
#include "qemu/uuid.h"
-
-#ifdef CONFIG_SECCOMP
-#include <sys/prctl.h>
#include "sysemu/seccomp.h"
-#endif
#ifdef CONFIG_SDL
#if defined(__APPLE__) || defined(main)
#include "ui/qemu-spice.h"
#include "qapi/string-input-visitor.h"
#include "qapi/opts-visitor.h"
+#include "qapi/clone-visitor.h"
#include "qom/object_interfaces.h"
#include "exec/semihost.h"
#include "crypto/init.h"
#include "sysemu/replay.h"
#include "qapi/qapi-events-run-state.h"
#include "qapi/qapi-visit-block-core.h"
+#include "qapi/qapi-visit-ui.h"
#include "qapi/qapi-commands-block-core.h"
#include "qapi/qapi-commands-misc.h"
#include "qapi/qapi-commands-run-state.h"
#include "sysemu/iothread.h"
#define MAX_VIRTIO_CONSOLES 1
-#define MAX_SCLP_CONSOLES 1
static const char *data_dir[16];
static int data_dir_idx;
const char *mem_path = NULL;
int mem_prealloc = 0; /* force preallocation of physical target memory */
bool enable_mlock = false;
+bool enable_cpu_pm = false;
int nb_nics;
NICInfo nd_table[MAX_NICS];
int autostart;
int vga_interface_type = VGA_NONE;
static DisplayOptions dpy;
int no_frame;
-static int num_serial_hds = 0;
-static Chardev **serial_hds = NULL;
+static int num_serial_hds;
+static Chardev **serial_hds;
Chardev *parallel_hds[MAX_PARALLEL_PORTS];
Chardev *virtcon_hds[MAX_VIRTIO_CONSOLES];
-Chardev *sclp_hds[MAX_SCLP_CONSOLES];
int win2k_install_hack = 0;
int singlestep = 0;
int smp_cpus;
static int default_serial = 1;
static int default_parallel = 1;
static int default_virtcon = 1;
-static int default_sclp = 1;
static int default_monitor = 1;
static int default_floppy = 1;
static int default_cdrom = 1;
},
};
-static QemuOptsList qemu_sandbox_opts = {
- .name = "sandbox",
- .implied_opt_name = "enable",
- .head = QTAILQ_HEAD_INITIALIZER(qemu_sandbox_opts.head),
- .desc = {
- {
- .name = "enable",
- .type = QEMU_OPT_BOOL,
- },
- {
- .name = "obsolete",
- .type = QEMU_OPT_STRING,
- },
- {
- .name = "elevateprivileges",
- .type = QEMU_OPT_STRING,
- },
- {
- .name = "spawn",
- .type = QEMU_OPT_STRING,
- },
- {
- .name = "resourcecontrol",
- .type = QEMU_OPT_STRING,
- },
- { /* end of list */ }
- },
-};
-
static QemuOptsList qemu_option_rom_opts = {
.name = "option-rom",
.implied_opt_name = "romfile",
},
};
+static QemuOptsList qemu_overcommit_opts = {
+ .name = "overcommit",
+ .head = QTAILQ_HEAD_INITIALIZER(qemu_overcommit_opts.head),
+ .desc = {
+ {
+ .name = "mem-lock",
+ .type = QEMU_OPT_BOOL,
+ },
+ {
+ .name = "cpu-pm",
+ .type = QEMU_OPT_BOOL,
+ },
+ { /* end of list */ }
+ },
+};
+
static QemuOptsList qemu_msg_opts = {
.name = "msg",
.head = QTAILQ_HEAD_INITIALIZER(qemu_msg_opts.head),
/***********************************************************/
/* QEMU state */
-static RunState current_run_state = RUN_STATE_PRELAUNCH;
+static RunState current_run_state = RUN_STATE_PRECONFIG;
/* We use RUN_STATE__MAX but any invalid value will do */
static RunState vmstop_requested = RUN_STATE__MAX;
static const RunStateTransition runstate_transitions_def[] = {
/* from -> to */
+ { RUN_STATE_PRECONFIG, RUN_STATE_PRELAUNCH },
+ /* Early switch to inmigrate state to allow -incoming CLI option work
+ * as it used to. TODO: delay actual switching to inmigrate state to
+ * the point after machine is built and remove this hack.
+ */
+ { RUN_STATE_PRECONFIG, RUN_STATE_INMIGRATE },
+
{ RUN_STATE_DEBUG, RUN_STATE_RUNNING },
{ RUN_STATE_DEBUG, RUN_STATE_FINISH_MIGRATE },
{ RUN_STATE_DEBUG, RUN_STATE_PRELAUNCH },
return seconds - qemu_time();
}
-static void configure_rtc_date_offset(const char *startdate, int legacy)
+static void configure_rtc_date_offset(const char *startdate)
{
time_t rtc_start_date;
struct tm tm;
- if (!strcmp(startdate, "now") && legacy) {
- rtc_date_offset = -1;
+ if (sscanf(startdate, "%d-%d-%dT%d:%d:%d", &tm.tm_year, &tm.tm_mon,
+ &tm.tm_mday, &tm.tm_hour, &tm.tm_min, &tm.tm_sec) == 6) {
+ /* OK */
+ } else if (sscanf(startdate, "%d-%d-%d",
+ &tm.tm_year, &tm.tm_mon, &tm.tm_mday) == 3) {
+ tm.tm_hour = 0;
+ tm.tm_min = 0;
+ tm.tm_sec = 0;
} else {
- if (sscanf(startdate, "%d-%d-%dT%d:%d:%d",
- &tm.tm_year,
- &tm.tm_mon,
- &tm.tm_mday,
- &tm.tm_hour,
- &tm.tm_min,
- &tm.tm_sec) == 6) {
- /* OK */
- } else if (sscanf(startdate, "%d-%d-%d",
- &tm.tm_year,
- &tm.tm_mon,
- &tm.tm_mday) == 3) {
- tm.tm_hour = 0;
- tm.tm_min = 0;
- tm.tm_sec = 0;
- } else {
- goto date_fail;
- }
- tm.tm_year -= 1900;
- tm.tm_mon--;
- rtc_start_date = mktimegm(&tm);
- if (rtc_start_date == -1) {
- date_fail:
- error_report("invalid date format");
- error_printf("valid formats: "
- "'2006-06-17T16:01:21' or '2006-06-17'\n");
- exit(1);
- }
- rtc_date_offset = qemu_time() - rtc_start_date;
+ goto date_fail;
+ }
+ tm.tm_year -= 1900;
+ tm.tm_mon--;
+ rtc_start_date = mktimegm(&tm);
+ if (rtc_start_date == -1) {
+ date_fail:
+ error_report("invalid date format");
+ error_printf("valid formats: "
+ "'2006-06-17T16:01:21' or '2006-06-17'\n");
+ exit(1);
}
+ rtc_date_offset = qemu_time() - rtc_start_date;
}
static void configure_rtc(QemuOpts *opts)
"-rtc base=localtime");
replay_add_blocker(blocker);
} else {
- configure_rtc_date_offset(value, 0);
+ configure_rtc_date_offset(value);
}
}
value = qemu_opt_get(opts, "clock");
return 1;
}
-static int parse_sandbox(void *opaque, QemuOpts *opts, Error **errp)
-{
- if (qemu_opt_get_bool(opts, "enable", false)) {
-#ifdef CONFIG_SECCOMP
- uint32_t seccomp_opts = QEMU_SECCOMP_SET_DEFAULT
- | QEMU_SECCOMP_SET_OBSOLETE;
- const char *value = NULL;
-
- value = qemu_opt_get(opts, "obsolete");
- if (value) {
- if (g_str_equal(value, "allow")) {
- seccomp_opts &= ~QEMU_SECCOMP_SET_OBSOLETE;
- } else if (g_str_equal(value, "deny")) {
- /* this is the default option, this if is here
- * to provide a little bit of consistency for
- * the command line */
- } else {
- error_report("invalid argument for obsolete");
- return -1;
- }
- }
-
- value = qemu_opt_get(opts, "elevateprivileges");
- if (value) {
- if (g_str_equal(value, "deny")) {
- seccomp_opts |= QEMU_SECCOMP_SET_PRIVILEGED;
- } else if (g_str_equal(value, "children")) {
- seccomp_opts |= QEMU_SECCOMP_SET_PRIVILEGED;
-
- /* calling prctl directly because we're
- * not sure if host has CAP_SYS_ADMIN set*/
- if (prctl(PR_SET_NO_NEW_PRIVS, 1)) {
- error_report("failed to set no_new_privs "
- "aborting");
- return -1;
- }
- } else if (g_str_equal(value, "allow")) {
- /* default value */
- } else {
- error_report("invalid argument for elevateprivileges");
- return -1;
- }
- }
-
- value = qemu_opt_get(opts, "spawn");
- if (value) {
- if (g_str_equal(value, "deny")) {
- seccomp_opts |= QEMU_SECCOMP_SET_SPAWN;
- } else if (g_str_equal(value, "allow")) {
- /* default value */
- } else {
- error_report("invalid argument for spawn");
- return -1;
- }
- }
-
- value = qemu_opt_get(opts, "resourcecontrol");
- if (value) {
- if (g_str_equal(value, "deny")) {
- seccomp_opts |= QEMU_SECCOMP_SET_RESOURCECTL;
- } else if (g_str_equal(value, "allow")) {
- /* default value */
- } else {
- error_report("invalid argument for resourcecontrol");
- return -1;
- }
- }
-
- if (seccomp_start(seccomp_opts) < 0) {
- error_report("failed to install seccomp syscall filter "
- "in the kernel");
- return -1;
- }
-#else
- error_report("seccomp support is disabled");
- return -1;
-#endif
- }
-
- return 0;
-}
-
static int parse_name(void *opaque, QemuOpts *opts, Error **errp)
{
const char *proc_name;
static int powerdown_requested;
static int debug_requested;
static int suspend_requested;
+static bool preconfig_exit_requested = true;
static WakeupReason wakeup_reason;
static NotifierList powerdown_notifiers =
NOTIFIER_LIST_INITIALIZER(powerdown_notifiers);
return r;
}
+void qemu_exit_preconfig_request(void)
+{
+ preconfig_exit_requested = true;
+}
+
/*
* Reset the VM. Issue an event unless @reason is SHUTDOWN_CAUSE_NONE.
*/
} else {
qemu_devices_reset();
}
- if (reason) {
- qapi_event_send_reset(shutdown_caused_by_guest(reason),
- &error_abort);
+ if (reason != SHUTDOWN_CAUSE_SUBSYSTEM_RESET) {
+ qapi_event_send_reset(shutdown_caused_by_guest(reason));
}
cpu_synchronize_all_post_reset();
}
current_cpu->crash_occurred = true;
}
qapi_event_send_guest_panicked(GUEST_PANIC_ACTION_PAUSE,
- !!info, info, &error_abort);
+ !!info, info);
vm_stop(RUN_STATE_GUEST_PANICKED);
if (!no_shutdown) {
qapi_event_send_guest_panicked(GUEST_PANIC_ACTION_POWEROFF,
- !!info, info, &error_abort);
+ !!info, info);
qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_PANIC);
}
void qemu_system_reset_request(ShutdownCause reason)
{
- if (no_reboot) {
+ if (no_reboot && reason != SHUTDOWN_CAUSE_SUBSYSTEM_RESET) {
shutdown_requested = reason;
} else {
reset_requested = reason;
pause_all_vcpus();
notifier_list_notify(&suspend_notifiers, NULL);
runstate_set(RUN_STATE_SUSPENDED);
- qapi_event_send_suspend(&error_abort);
+ qapi_event_send_suspend();
}
void qemu_system_suspend_request(void)
static void qemu_system_powerdown(void)
{
- qapi_event_send_powerdown(&error_abort);
+ qapi_event_send_powerdown();
notifier_list_notify(&powerdown_notifiers, NULL);
}
RunState r;
ShutdownCause request;
+ if (preconfig_exit_requested) {
+ if (runstate_check(RUN_STATE_PRECONFIG)) {
+ runstate_set(RUN_STATE_PRELAUNCH);
+ }
+ preconfig_exit_requested = false;
+ return true;
+ }
if (qemu_debug_requested()) {
vm_stop(RUN_STATE_DEBUG);
}
request = qemu_shutdown_requested();
if (request) {
qemu_kill_report();
- qapi_event_send_shutdown(shutdown_caused_by_guest(request),
- &error_abort);
+ qapi_event_send_shutdown(shutdown_caused_by_guest(request));
if (no_shutdown) {
vm_stop(RUN_STATE_SHUTDOWN);
} else {
notifier_list_notify(&wakeup_notifiers, &wakeup_reason);
wakeup_reason = QEMU_WAKEUP_REASON_NONE;
resume_all_vcpus();
- qapi_event_send_wakeup(&error_abort);
+ qapi_event_send_wakeup();
}
if (qemu_powerdown_requested()) {
qemu_system_powerdown();
#ifdef CONFIG_PROFILER
int64_t ti;
#endif
- do {
+ while (!main_loop_should_exit()) {
#ifdef CONFIG_PROFILER
ti = profile_getclock();
#endif
#ifdef CONFIG_PROFILER
dev_time += profile_getclock() - ti;
#endif
- } while (!main_loop_should_exit());
+ }
}
static void version(void)
}
}
+static void parse_display_qapi(const char *optarg)
+{
+ Error *err = NULL;
+ DisplayOptions *opts;
+ Visitor *v;
+
+ v = qobject_input_visitor_new_str(optarg, "type", &err);
+ if (!v) {
+ error_report_err(err);
+ exit(1);
+ }
+
+ visit_type_DisplayOptions(v, NULL, &opts, &error_fatal);
+ QAPI_CLONE_MEMBERS(DisplayOptions, &dpy, opts);
+
+ qapi_free_DisplayOptions(opts);
+ visit_free(v);
+}
+
static void parse_display(const char *p)
{
const char *opts;
if (strstart(p, "sdl", &opts)) {
+ /*
+ * sdl DisplayType needs hand-crafted parser instead of
+ * parse_display_qapi() due to some options not in
+ * DisplayOptions, specifically:
+ * - frame
+ * Already deprecated.
+ * - ctrl_grab + alt_grab
+ * Not clear yet what happens to them long-term. Should
+ * replaced by something better or deprecated and dropped.
+ */
dpy.type = DISPLAY_TYPE_SDL;
while (*opts) {
const char *nextopt;
dpy.has_gl = true;
if (strstart(opts, "on", &nextopt)) {
dpy.gl = DISPLAYGL_MODE_ON;
+ } else if (strstart(opts, "core", &nextopt)) {
+ dpy.gl = DISPLAYGL_MODE_CORE;
+ } else if (strstart(opts, "es", &nextopt)) {
+ dpy.gl = DISPLAYGL_MODE_ES;
} else if (strstart(opts, "off", &nextopt)) {
dpy.gl = DISPLAYGL_MODE_OFF;
} else {
opts = nextopt;
}
} else if (strstart(p, "vnc", &opts)) {
+ /*
+ * vnc isn't a (local) DisplayType but a protocol for remote
+ * display access.
+ */
if (*opts == '=') {
vnc_parse(opts + 1, &error_fatal);
} else {
error_report("VNC requires a display argument vnc=<display>");
exit(1);
}
- } else if (strstart(p, "egl-headless", &opts)) {
- dpy.type = DISPLAY_TYPE_EGL_HEADLESS;
- } else if (strstart(p, "curses", &opts)) {
- dpy.type = DISPLAY_TYPE_CURSES;
- } else if (strstart(p, "gtk", &opts)) {
- dpy.type = DISPLAY_TYPE_GTK;
- while (*opts) {
- const char *nextopt;
-
- if (strstart(opts, ",grab_on_hover=", &nextopt)) {
- opts = nextopt;
- dpy.u.gtk.has_grab_on_hover = true;
- if (strstart(opts, "on", &nextopt)) {
- dpy.u.gtk.grab_on_hover = true;
- } else if (strstart(opts, "off", &nextopt)) {
- dpy.u.gtk.grab_on_hover = false;
- } else {
- goto invalid_gtk_args;
- }
- } else if (strstart(opts, ",gl=", &nextopt)) {
- opts = nextopt;
- dpy.has_gl = true;
- if (strstart(opts, "on", &nextopt)) {
- dpy.gl = DISPLAYGL_MODE_ON;
- } else if (strstart(opts, "off", &nextopt)) {
- dpy.gl = DISPLAYGL_MODE_OFF;
- } else {
- goto invalid_gtk_args;
- }
- } else {
- invalid_gtk_args:
- error_report("invalid GTK option string");
- exit(1);
- }
- opts = nextopt;
- }
- } else if (strstart(p, "none", &opts)) {
- dpy.type = DISPLAY_TYPE_NONE;
} else {
- error_report("unknown display type");
- exit(1);
- }
-}
-
-static int balloon_parse(const char *arg)
-{
- QemuOpts *opts;
-
- warn_report("This option is deprecated. "
- "Use '--device virtio-balloon' to enable the balloon device.");
-
- if (strcmp(arg, "none") == 0) {
- return 0;
- }
-
- if (!strncmp(arg, "virtio", 6)) {
- if (arg[6] == ',') {
- /* have params -> parse them */
- opts = qemu_opts_parse_noisily(qemu_find_opts("device"), arg + 7,
- false);
- if (!opts)
- return -1;
- } else {
- /* create empty opts */
- opts = qemu_opts_create(qemu_find_opts("device"), NULL, 0,
- &error_abort);
- }
- qemu_opt_set(opts, "driver", "virtio-balloon", &error_abort);
- return 0;
+ parse_display_qapi(p);
}
-
- return -1;
}
char *qemu_find_file(int type, const char *name)
} else {
snprintf(label, sizeof(label), "compat_monitor%d",
monitor_device_index);
- opts = qemu_chr_parse_compat(label, optarg);
+ opts = qemu_chr_parse_compat(label, optarg, true);
if (!opts) {
error_report("parse error: %s", optarg);
exit(1);
snprintf(label, sizeof(label), "serial%d", index);
serial_hds = g_renew(Chardev *, serial_hds, index + 1);
- serial_hds[index] = qemu_chr_new(label, devname);
+ serial_hds[index] = qemu_chr_new_mux_mon(label, devname);
if (!serial_hds[index]) {
error_report("could not connect serial device"
" to character backend '%s'", devname);
exit(1);
}
snprintf(label, sizeof(label), "parallel%d", index);
- parallel_hds[index] = qemu_chr_new(label, devname);
+ parallel_hds[index] = qemu_chr_new_mux_mon(label, devname);
if (!parallel_hds[index]) {
error_report("could not connect parallel device"
" to character backend '%s'", devname);
qemu_opt_set(dev_opts, "driver", "virtconsole", &error_abort);
snprintf(label, sizeof(label), "virtcon%d", index);
- virtcon_hds[index] = qemu_chr_new(label, devname);
+ virtcon_hds[index] = qemu_chr_new_mux_mon(label, devname);
if (!virtcon_hds[index]) {
error_report("could not connect virtio console"
" to character backend '%s'", devname);
return 0;
}
-static int sclp_parse(const char *devname)
-{
- QemuOptsList *device = qemu_find_opts("device");
- static int index = 0;
- char label[32];
- QemuOpts *dev_opts;
-
- if (strcmp(devname, "none") == 0) {
- return 0;
- }
- if (index == MAX_SCLP_CONSOLES) {
- error_report("too many sclp consoles");
- exit(1);
- }
-
- assert(arch_type == QEMU_ARCH_S390X);
-
- dev_opts = qemu_opts_create(device, NULL, 0, NULL);
- qemu_opt_set(dev_opts, "driver", "sclpconsole", &error_abort);
-
- snprintf(label, sizeof(label), "sclpcon%d", index);
- sclp_hds[index] = qemu_chr_new(label, devname);
- if (!sclp_hds[index]) {
- error_report("could not connect sclp console"
- " to character backend '%s'", devname);
- return -1;
- }
- qemu_opt_set(dev_opts, "chardev", label, &error_abort);
-
- index++;
- return 0;
-}
-
static int debugcon_parse(const char *devname)
{
QemuOpts *opts;
- if (!qemu_chr_new("debugcon", devname)) {
+ if (!qemu_chr_new_mux_mon("debugcon", devname)) {
exit(1);
}
opts = qemu_opts_create(qemu_find_opts("device"), "debugcon", 1, NULL);
if (mc->alias) {
printf("%-20s %s (alias of %s)\n", mc->alias, mc->desc, mc->name);
}
- printf("%-20s %s%s\n", mc->name, mc->desc,
- mc->is_default ? " (default)" : "");
+ printf("%-20s %s%s%s\n", mc->name, mc->desc,
+ mc->is_default ? " (default)" : "",
+ mc->deprecation_reason ? " (deprecated)" : "");
}
}
notifier_list_notify(&exit_notifiers, NULL);
}
+static const char *pid_file;
+static Notifier qemu_unlink_pidfile_notifier;
+
+static void qemu_unlink_pidfile(Notifier *n, void *data)
+{
+ if (pid_file) {
+ unlink(pid_file);
+ }
+}
+
bool machine_init_done;
void qemu_add_machine_init_done_notifier(Notifier *notify)
* cannot be created here, as it depends on the chardev
* already existing.
*/
-static bool object_create_initial(const char *type)
+static bool object_create_initial(const char *type, QemuOpts *opts)
{
+ ObjectClass *klass;
+
+ if (is_help_option(type)) {
+ GSList *l, *list;
+
+ printf("List of user creatable objects:\n");
+ list = object_class_get_list_sorted(TYPE_USER_CREATABLE, false);
+ for (l = list; l != NULL; l = l->next) {
+ ObjectClass *oc = OBJECT_CLASS(l->data);
+ printf("%s\n", object_class_get_name(oc));
+ }
+ g_slist_free(list);
+ exit(0);
+ }
+
+ klass = object_class_by_name(type);
+ if (klass && qemu_opt_has_help_opt(opts)) {
+ ObjectPropertyIterator iter;
+ ObjectProperty *prop;
+ GPtrArray *array = g_ptr_array_new();
+ int i;
+
+ object_class_property_iter_init(&iter, klass);
+ while ((prop = object_property_iter_next(&iter))) {
+ GString *str;
+
+ if (!prop->set) {
+ continue;
+ }
+
+ str = g_string_new(NULL);
+ g_string_append_printf(str, "%s.%s=%s", type,
+ prop->name, prop->type);
+ if (prop->description) {
+ g_string_append_printf(str, " - %s", prop->description);
+ }
+ g_ptr_array_add(array, g_string_free(str, false));
+ }
+ g_ptr_array_sort(array, (GCompareFunc)qemu_pstrcmp0);
+ for (i = 0; i < array->len; i++) {
+ printf("%s\n", (char *)array->pdata[i]);
+ }
+ g_ptr_array_set_free_func(array, g_free);
+ g_ptr_array_free(array, true);
+ exit(0);
+ }
+
if (g_str_equal(type, "rng-egd") ||
g_str_has_prefix(type, "pr-manager-")) {
return false;
* The remainder of object creation happens after the
* creation of chardev, fsdev, net clients and device data types.
*/
-static bool object_create_delayed(const char *type)
+static bool object_create_delayed(const char *type, QemuOpts *opts)
{
- return !object_create_initial(type);
+ return !object_create_initial(type, opts);
}
{
uint64_t sz;
const char *mem_str;
- const char *maxmem_str, *slots_str;
const ram_addr_t default_ram_size = mc->default_ram_size;
QemuOpts *opts = qemu_find_opts_singleton("memory");
Location loc;
if (g_ascii_isdigit(mem_str[strlen(mem_str) - 1])) {
uint64_t overflow_check = sz;
- sz <<= 20;
- if ((sz >> 20) != overflow_check) {
+ sz *= MiB;
+ if (sz / MiB != overflow_check) {
error_report("too large 'size' option value");
exit(EXIT_FAILURE);
}
qemu_opt_set_number(opts, "size", ram_size, &error_abort);
*maxram_size = ram_size;
- maxmem_str = qemu_opt_get(opts, "maxmem");
- slots_str = qemu_opt_get(opts, "slots");
- if (maxmem_str && slots_str) {
+ if (qemu_opt_get(opts, "maxmem")) {
uint64_t slots;
sz = qemu_opt_get_size(opts, "maxmem", 0);
"the initial memory size (0x" RAM_ADDR_FMT ")",
sz, ram_size);
exit(EXIT_FAILURE);
- } else if (sz > ram_size) {
- if (!slots) {
- error_report("invalid value of -m option: maxmem was "
- "specified, but no hotplug slots were specified");
- exit(EXIT_FAILURE);
- }
- } else if (slots) {
+ } else if (slots && sz == ram_size) {
error_report("invalid value of -m option maxmem: "
"memory slots were specified but maximum memory size "
"(0x%" PRIx64 ") is equal to the initial memory size "
*maxram_size = sz;
*ram_slots = slots;
- } else if ((!maxmem_str && slots_str) ||
- (maxmem_str && !slots_str)) {
- error_report("invalid -m option value: missing "
- "'%s' option", slots_str ? "maxmem" : "slots");
+ } else if (qemu_opt_get(opts, "slots")) {
+ error_report("invalid -m option value: missing 'maxmem' option");
exit(EXIT_FAILURE);
}
const char *vga_model = NULL;
const char *qtest_chrdev = NULL;
const char *qtest_log = NULL;
- const char *pid_file = NULL;
const char *incoming = NULL;
bool userconfig = true;
bool nographic = false;
qemu_add_opts(&qemu_mem_opts);
qemu_add_opts(&qemu_smp_opts);
qemu_add_opts(&qemu_boot_opts);
- qemu_add_opts(&qemu_sandbox_opts);
qemu_add_opts(&qemu_add_fd_opts);
qemu_add_opts(&qemu_object_opts);
qemu_add_opts(&qemu_tpmdev_opts);
qemu_add_opts(&qemu_realtime_opts);
+ qemu_add_opts(&qemu_overcommit_opts);
qemu_add_opts(&qemu_msg_opts);
qemu_add_opts(&qemu_name_opts);
qemu_add_opts(&qemu_numa_opts);
runstate_init();
postcopy_infrastructure_init();
+ monitor_init_globals();
if (qcrypto_init(&err) < 0) {
error_reportf_err(err, "cannot initialize crypto: ");
popt = lookup_opt(argc, argv, &optarg, &optind);
switch (popt->index) {
- case QEMU_OPTION_nodefconfig:
case QEMU_OPTION_nouserconfig:
userconfig = false;
break;
exit(1);
}
switch(popt->index) {
- case QEMU_OPTION_no_kvm_irqchip: {
- olist = qemu_find_opts("machine");
- qemu_opts_parse_noisily(olist, "kernel_irqchip=off", false);
- break;
- }
case QEMU_OPTION_cpu:
/* hw initialization will check this */
cpu_model = optarg;
exit(1);
}
break;
-#endif
-#ifdef CONFIG_SLIRP
- case QEMU_OPTION_tftp:
- error_report("The -tftp option is deprecated. "
- "Please use '-netdev user,tftp=...' instead.");
- legacy_tftp_prefix = optarg;
- break;
- case QEMU_OPTION_bootp:
- error_report("The -bootp option is deprecated. "
- "Please use '-netdev user,bootfile=...' instead.");
- legacy_bootp_filename = optarg;
- break;
- case QEMU_OPTION_redir:
- error_report("The -redir option is deprecated. "
- "Please use '-netdev user,hostfwd=...' instead.");
- if (net_slirp_redir(optarg) < 0)
- exit(1);
- break;
#endif
case QEMU_OPTION_bt:
add_device_config(DEV_BT, optarg);
case QEMU_OPTION_k:
keyboard_layout = optarg;
break;
- case QEMU_OPTION_localtime:
- rtc_utc = 0;
- warn_report("This option is deprecated, "
- "use '-rtc base=localtime' instead.");
- break;
case QEMU_OPTION_vga:
vga_model = optarg;
default_vga = 0;
}
break;
case QEMU_OPTION_virtiocon:
+ warn_report("This option is deprecated, "
+ "use '-device virtconsole' instead");
add_device_config(DEV_VIRTCON, optarg);
default_virtcon = 0;
if (strncmp(optarg, "mon:", 4) == 0) {
case QEMU_OPTION_win2k_hack:
win2k_install_hack = 1;
break;
- case QEMU_OPTION_rtc_td_hack: {
- static GlobalProperty slew_lost_ticks = {
- .driver = "mc146818rtc",
- .property = "lost_tick_policy",
- .value = "slew",
- };
-
- qdev_prop_register_global(&slew_lost_ticks);
- warn_report("This option is deprecated, "
- "use '-rtc driftfix=slew' instead.");
- break;
- }
case QEMU_OPTION_acpitable:
opts = qemu_opts_parse_noisily(qemu_find_opts("acpi"),
optarg, true);
exit(1);
}
break;
+ case QEMU_OPTION_preconfig:
+ preconfig_exit_requested = false;
+ break;
case QEMU_OPTION_enable_kvm:
olist = qemu_find_opts("machine");
qemu_opts_parse_noisily(olist, "accel=kvm", false);
break;
case QEMU_OPTION_enable_hax:
+ warn_report("Option is deprecated, use '-accel hax' instead");
olist = qemu_find_opts("machine");
qemu_opts_parse_noisily(olist, "accel=hax", false);
break;
olist = qemu_find_opts("machine");
qemu_opts_parse_noisily(olist, "accel=tcg", false);
break;
- case QEMU_OPTION_no_kvm_pit_reinjection: {
- static GlobalProperty kvm_pit_lost_tick_policy = {
- .driver = "kvm-pit",
- .property = "lost_tick_policy",
- .value = "discard",
- };
-
- warn_report("deprecated, replaced by "
- "-global kvm-pit.lost_tick_policy=discard");
- qdev_prop_register_global(&kvm_pit_lost_tick_policy);
- break;
- }
case QEMU_OPTION_accel:
accel_opts = qemu_opts_parse_noisily(qemu_find_opts("accel"),
optarg, true);
case QEMU_OPTION_no_hpet:
no_hpet = 1;
break;
- case QEMU_OPTION_balloon:
- if (balloon_parse(optarg) < 0) {
- error_report("unknown -balloon argument %s", optarg);
- exit(1);
- }
- break;
case QEMU_OPTION_no_reboot:
no_reboot = 1;
break;
/* Clock options no longer exist. Keep this option for
* backward compatibility.
*/
- break;
- case QEMU_OPTION_startdate:
- warn_report("This option is deprecated, use '-rtc base=' instead.");
- configure_rtc_date_offset(optarg, 1);
+ warn_report("This option is ignored and will be removed soon");
break;
case QEMU_OPTION_rtc:
opts = qemu_opts_parse_noisily(qemu_find_opts("rtc"), optarg,
qtest_log = optarg;
break;
case QEMU_OPTION_sandbox:
+#ifdef CONFIG_SECCOMP
opts = qemu_opts_parse_noisily(qemu_find_opts("sandbox"),
optarg, true);
if (!opts) {
exit(1);
}
+#else
+ error_report("-sandbox support is not enabled "
+ "in this QEMU binary");
+ exit(1);
+#endif
break;
case QEMU_OPTION_add_fd:
#ifndef _WIN32
if (!opts) {
exit(1);
}
- enable_mlock = qemu_opt_get_bool(opts, "mlock", true);
+ /* Don't override the -overcommit option if set */
+ enable_mlock = enable_mlock ||
+ qemu_opt_get_bool(opts, "mlock", true);
+ break;
+ case QEMU_OPTION_overcommit:
+ opts = qemu_opts_parse_noisily(qemu_find_opts("overcommit"),
+ optarg, false);
+ if (!opts) {
+ exit(1);
+ }
+ /* Don't override the -realtime option if set */
+ enable_mlock = enable_mlock ||
+ qemu_opt_get_bool(opts, "mem-lock", false);
+ enable_cpu_pm = qemu_opt_get_bool(opts, "cpu-pm", false);
break;
case QEMU_OPTION_msg:
opts = qemu_opts_parse_noisily(qemu_find_opts("msg"), optarg,
exit(1);
}
break;
+ case QEMU_OPTION_enable_sync_profile:
+ qsp_enable();
+ break;
+ case QEMU_OPTION_nouserconfig:
+ /* Nothing to be parsed here. Especially, do not error out below. */
+ break;
default:
- os_parse_cmd_args(popt->index, optarg);
+ if (os_parse_cmd_args(popt->index, optarg)) {
+ error_report("Option not supported in this build");
+ exit(1);
+ }
}
}
}
replay_configure(icount_opts);
+ if (incoming && !preconfig_exit_requested) {
+ error_report("'preconfig' and 'incoming' options are "
+ "mutually exclusive");
+ exit(EXIT_FAILURE);
+ }
+
machine_class = select_machine();
set_memory_options(&ram_slots, &maxram_size, machine_class);
os_daemonize();
rcu_disable_atfork();
- if (pid_file && qemu_create_pidfile(pid_file) != 0) {
- error_report("could not acquire pid file: %s", strerror(errno));
+ if (pid_file && !qemu_write_pidfile(pid_file, &err)) {
+ error_reportf_err(err, "cannot create PID file: ");
exit(1);
}
+ qemu_unlink_pidfile_notifier.notify = qemu_unlink_pidfile;
+ qemu_add_exit_notifier(&qemu_unlink_pidfile_notifier);
+
if (qemu_init_main_loop(&main_loop_err)) {
error_report_err(main_loop_err);
exit(1);
}
- if (qemu_opts_foreach(qemu_find_opts("sandbox"),
- parse_sandbox, NULL, NULL)) {
+#ifdef CONFIG_SECCOMP
+ olist = qemu_find_opts_err("sandbox", NULL);
+ if (olist && qemu_opts_foreach(olist, parse_sandbox, NULL, NULL)) {
exit(1);
}
+#endif
if (qemu_opts_foreach(qemu_find_opts("name"),
parse_name, NULL, NULL)) {
if (!has_defaults || !machine_class->use_virtcon) {
default_virtcon = 0;
}
- if (!has_defaults || !machine_class->use_sclp) {
- default_sclp = 0;
- }
if (!has_defaults || machine_class->no_floppy) {
default_floppy = 0;
}
}
if (is_daemonized()) {
+ if (!preconfig_exit_requested) {
+ error_report("'preconfig' and 'daemonize' options are "
+ "mutually exclusive");
+ exit(EXIT_FAILURE);
+ }
+
/* According to documentation and historically, -nographic redirects
* serial port, parallel port and monitor to stdio, which does not work
* with -daemonize. We can redirect these to null instead, but since
add_device_config(DEV_SERIAL, "mon:stdio");
} else if (default_virtcon && default_monitor) {
add_device_config(DEV_VIRTCON, "mon:stdio");
- } else if (default_sclp && default_monitor) {
- add_device_config(DEV_SCLP, "mon:stdio");
} else {
if (default_serial)
add_device_config(DEV_SERIAL, "stdio");
if (default_virtcon)
add_device_config(DEV_VIRTCON, "stdio");
- if (default_sclp) {
- add_device_config(DEV_SCLP, "stdio");
- }
if (default_monitor)
monitor_parse("stdio", "readline", false);
}
monitor_parse("vc:80Cx24C", "readline", false);
if (default_virtcon)
add_device_config(DEV_VIRTCON, "vc:80Cx24C");
- if (default_sclp) {
- add_device_config(DEV_SCLP, "vc:80Cx24C");
- }
}
#if defined(CONFIG_VNC)
configure_accelerator(current_machine);
+ if (!qtest_enabled() && machine_class->deprecation_reason) {
+ error_report("Machine type '%s' is deprecated: %s",
+ machine_class->name, machine_class->deprecation_reason);
+ }
+
/*
* Register all the global properties, including accel properties,
* machine properties, and user-specified ones.
default_drive(default_floppy, snapshot, IF_FLOPPY, 0, FD_OPTS);
default_drive(default_sdcard, snapshot, IF_SD, 0, SD_OPTS);
- /*
- * Note: qtest_enabled() (which is used in monitor_qapi_event_init())
- * depends on configure_accelerator() above.
- */
- monitor_init_globals();
-
if (qemu_opts_foreach(qemu_find_opts("mon"),
mon_init_func, NULL, NULL)) {
exit(1);
exit(1);
if (foreach_device_config(DEV_VIRTCON, virtcon_parse) < 0)
exit(1);
- if (foreach_device_config(DEV_SCLP, sclp_parse) < 0) {
- exit(1);
- }
if (foreach_device_config(DEV_DEBUGCON, debugcon_parse) < 0)
exit(1);
}
parse_numa_opts(current_machine);
+ /* do monitor/qmp handling at preconfig state if requested */
+ main_loop();
+
+ /* from here on runstate is RUN_STATE_PRELAUNCH */
machine_run_board_init(current_machine);
realtime_init();
* (2) CONFIG_SLIRP not set, in which case the implicit "-net nic"
* sets up a nic that isn't connected to anything.
*/
- if (!default_net) {
+ if (!default_net && (!qtest_enabled() || has_defaults)) {
net_check_clients();
}
-
if (boot_once) {
qemu_boot_set(boot_once, &error_fatal);
qemu_register_reset(restore_boot_order, g_strdup(boot_order));
replay_checkpoint(CHECKPOINT_RESET);
qemu_system_reset(SHUTDOWN_CAUSE_NONE);
register_global_state();
- if (replay_mode != REPLAY_MODE_NONE) {
- replay_vmstate_init();
- } else if (loadvm) {
+ if (loadvm) {
Error *local_err = NULL;
if (load_snapshot(loadvm, &local_err) < 0) {
error_report_err(local_err);
autostart = 0;
+ exit(1);
}
}
+ if (replay_mode != REPLAY_MODE_NONE) {
+ replay_vmstate_init();
+ }
qdev_prop_check_globals();
if (vmstate_dump_file) {
vm_start();
}
+ accel_setup_post(current_machine);
os_setup_post();
main_loop();
/* No more vcpu or device emulation activity beyond this point */
vm_shutdown();
+ job_cancel_sync_all();
bdrv_close_all();
res_free();