#ifdef CONFIG_SECCOMP
#include "sysemu/seccomp.h"
-#endif
-
-#if defined(CONFIG_VDE)
-#include <libvdeplug.h>
+#include "sys/prctl.h"
#endif
#ifdef CONFIG_SDL
int win2k_install_hack = 0;
int singlestep = 0;
int smp_cpus = 1;
-int max_cpus = 1;
+unsigned int max_cpus = 1;
int smp_cores = 1;
int smp_threads = 1;
int acpi_enabled = 1;
.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 */ }
},
};
{ RUN_STATE_PAUSED, RUN_STATE_RUNNING },
{ RUN_STATE_PAUSED, RUN_STATE_FINISH_MIGRATE },
+ { RUN_STATE_PAUSED, RUN_STATE_POSTMIGRATE },
{ RUN_STATE_PAUSED, RUN_STATE_PRELAUNCH },
{ RUN_STATE_PAUSED, RUN_STATE_COLO},
{ RUN_STATE_PRELAUNCH, RUN_STATE_INMIGRATE },
{ RUN_STATE_FINISH_MIGRATE, RUN_STATE_RUNNING },
+ { RUN_STATE_FINISH_MIGRATE, RUN_STATE_PAUSED },
{ RUN_STATE_FINISH_MIGRATE, RUN_STATE_POSTMIGRATE },
{ RUN_STATE_FINISH_MIGRATE, RUN_STATE_PRELAUNCH },
{ RUN_STATE_FINISH_MIGRATE, RUN_STATE_COLO},
bool runstate_store(char *str, size_t size)
{
- const char *state = RunState_lookup[current_run_state];
+ const char *state = RunState_str(current_run_state);
size_t len = strlen(state) + 1;
if (len > size) {
if (!runstate_valid_transitions[current_run_state][new_state]) {
error_report("invalid runstate transition: '%s' -> '%s'",
- RunState_lookup[current_run_state],
- RunState_lookup[new_state]);
+ RunState_str(current_run_state),
+ RunState_str(new_state));
abort();
}
trace_runstate_set(new_state);
struct bt_scatternet_s *vlan = qemu_find_bt_vlan(vlan_id);
if (!vlan->slave)
- error_report("warning: adding a VHCI to an empty scatternet %i",
- vlan_id);
+ warn_report("adding a VHCI to an empty scatternet %i",
+ vlan_id);
bt_vhci_init(bt_new_hci(vlan));
}
vlan = qemu_find_bt_vlan(vlan_id);
if (!vlan->slave)
- error_report("warning: adding a slave device to an empty scatternet %i",
- vlan_id);
+ warn_report("adding a slave device to an empty scatternet %i",
+ vlan_id);
if (!strcmp(devname, "keyboard"))
return bt_keyboard_init(vlan);
static int parse_sandbox(void *opaque, QemuOpts *opts, Error **errp)
{
- /* FIXME: change this to true for 1.3 */
if (qemu_opt_get_bool(opts, "enable", false)) {
#ifdef CONFIG_SECCOMP
- if (seccomp_start() < 0) {
+ 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;
"ctrl-alt-n switch to virtual console 'n'\n"
"ctrl-alt toggle mouse and keyboard grab\n"
"\n"
- "When using -nographic, press 'ctrl-a h' to get some help.\n");
+ "When using -nographic, press 'ctrl-a h' to get some help.\n"
+ "\n"
+ QEMU_HELP_BOTTOM "\n");
exit(exitcode);
}
return NULL;
}
+static void qemu_add_data_dir(const char *path)
+{
+ int i;
+
+ if (path == NULL) {
+ return;
+ }
+ if (data_dir_idx == ARRAY_SIZE(data_dir)) {
+ return;
+ }
+ for (i = 0; i < data_dir_idx; i++) {
+ if (strcmp(data_dir[i], path) == 0) {
+ return; /* duplicate */
+ }
+ }
+ data_dir[data_dir_idx++] = path;
+}
+
static inline bool nonempty_str(const char *str)
{
return str && *str;
return -1;
}
if (strncmp(name, "opt/", 4) != 0) {
- error_report("warning: externally provided fw_cfg item names "
- "should be prefixed with \"opt/\"");
+ warn_report("externally provided fw_cfg item names "
+ "should be prefixed with \"opt/\"");
}
if (nonempty_str(str)) {
size = strlen(str); /* NUL terminator NOT included in fw_cfg blob */
{
Error *local_err = NULL;
- qemu_chr_new_from_opts(opts, &local_err);
- if (local_err) {
- error_report_err(local_err);
- return -1;
+ if (!qemu_chr_new_from_opts(opts, &local_err)) {
+ if (local_err) {
+ error_report_err(local_err);
+ return -1;
+ }
+ exit(0);
}
return 0;
}
*/
static bool object_create_initial(const char *type)
{
- if (g_str_equal(type, "rng-egd")) {
+ if (g_str_equal(type, "rng-egd") ||
+ g_str_has_prefix(type, "pr-manager-")) {
return false;
}
const char *qtest_log = NULL;
const char *pid_file = NULL;
const char *incoming = NULL;
- bool defconfig = true;
bool userconfig = true;
bool nographic = false;
DisplayType display_type = DT_DEFAULT;
Error *main_loop_err = NULL;
Error *err = NULL;
bool list_data_dirs = false;
+ char **dirs;
typedef struct BlockdevOptions_queue {
BlockdevOptions *bdo;
Location loc;
popt = lookup_opt(argc, argv, &optarg, &optind);
switch (popt->index) {
case QEMU_OPTION_nodefconfig:
- defconfig = false;
- break;
case QEMU_OPTION_nouserconfig:
userconfig = false;
break;
}
}
- if (defconfig && userconfig) {
+ if (userconfig) {
if (qemu_read_default_config_file() < 0) {
exit(1);
}
case QEMU_OPTION_L:
if (is_help_option(optarg)) {
list_data_dirs = true;
- } else if (data_dir_idx < ARRAY_SIZE(data_dir)) {
- data_dir[data_dir_idx++] = optarg;
+ } else {
+ qemu_add_data_dir(optarg);
}
break;
case QEMU_OPTION_bios:
case QEMU_OPTION_virtfs: {
QemuOpts *fsdev;
QemuOpts *device;
- const char *writeout, *sock_fd, *socket;
+ const char *writeout, *sock_fd, *socket, *path, *security_model;
olist = qemu_find_opts("virtfs");
if (!olist) {
}
qemu_opt_set(fsdev, "fsdriver",
qemu_opt_get(opts, "fsdriver"), &error_abort);
- qemu_opt_set(fsdev, "path", qemu_opt_get(opts, "path"),
- &error_abort);
- qemu_opt_set(fsdev, "security_model",
- qemu_opt_get(opts, "security_model"),
- &error_abort);
+ path = qemu_opt_get(opts, "path");
+ if (path) {
+ qemu_opt_set(fsdev, "path", path, &error_abort);
+ }
+ security_model = qemu_opt_get(opts, "security_model");
+ if (security_model) {
+ qemu_opt_set(fsdev, "security_model", security_model,
+ &error_abort);
+ }
socket = qemu_opt_get(opts, "socket");
if (socket) {
qemu_opt_set(fsdev, "socket", socket, &error_abort);
qemu_opts_parse_noisily(olist, "accel=tcg", false);
break;
case QEMU_OPTION_no_kvm_pit: {
- error_report("warning: ignoring deprecated option");
+ warn_report("ignoring deprecated option");
break;
}
case QEMU_OPTION_no_kvm_pit_reinjection: {
.value = "discard",
};
- error_report("warning: deprecated, replaced by "
- "-global kvm-pit.lost_tick_policy=discard");
+ warn_report("deprecated, replaced by "
+ "-global kvm-pit.lost_tick_policy=discard");
qdev_prop_register_global(&kvm_pit_lost_tick_policy);
break;
}
}
break;
case QEMU_OPTION_tdf:
- error_report("warning: ignoring deprecated option");
+ warn_report("ignoring deprecated option");
break;
case QEMU_OPTION_name:
opts = qemu_opts_parse_noisily(qemu_find_opts("name"),
configure_rtc(opts);
break;
case QEMU_OPTION_tb_size:
- tcg_tb_size = strtol(optarg, NULL, 0);
- if (tcg_tb_size < 0) {
- tcg_tb_size = 0;
+#ifndef CONFIG_TCG
+ error_report("TCG is disabled");
+ exit(1);
+#endif
+ if (qemu_strtoul(optarg, NULL, 0, &tcg_tb_size) < 0) {
+ error_report("Invalid argument to -tb-size");
+ exit(1);
}
break;
case QEMU_OPTION_icount:
*
* "-global migration.only-migratable=true"
*/
- migration_only_migratable_set();
+ qemu_global_option("migration.only-migratable=true");
break;
case QEMU_OPTION_nodefaults:
has_defaults = 0;
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));
qemu_set_log(0);
}
- /* If no data_dir is specified then try to find it relative to the
- executable path. */
- if (data_dir_idx < ARRAY_SIZE(data_dir)) {
- data_dir[data_dir_idx] = os_find_datadir();
- if (data_dir[data_dir_idx] != NULL) {
- data_dir_idx++;
- }
- }
- /* If all else fails use the install path specified when building. */
- if (data_dir_idx < ARRAY_SIZE(data_dir)) {
- data_dir[data_dir_idx++] = CONFIG_QEMU_DATADIR;
+ /* add configured firmware directories */
+ dirs = g_strsplit(CONFIG_QEMU_FIRMWAREPATH, G_SEARCHPATH_SEPARATOR_S, 0);
+ for (i = 0; dirs[i] != NULL; i++) {
+ qemu_add_data_dir(dirs[i]);
}
+ /* try to find datadir relative to the executable path */
+ qemu_add_data_dir(os_find_datadir());
+
+ /* add the datadir specified when building */
+ qemu_add_data_dir(CONFIG_QEMU_DATADIR);
+
/* -L help lists the data directories and exits. */
if (list_data_dirs) {
for (i = 0; i < data_dir_idx; i++) {
machine_class->max_cpus = machine_class->max_cpus ?: 1; /* Default to UP */
if (max_cpus > machine_class->max_cpus) {
- error_report("Number of SMP CPUs requested (%d) exceeds max CPUs "
- "supported by machine '%s' (%d)", max_cpus,
+ error_report("Invalid SMP CPUs %d. The max CPUs "
+ "supported by machine '%s' is %d", max_cpus,
machine_class->name, machine_class->max_cpus);
exit(1);
}
configure_accelerator(current_machine);
+ /*
+ * Register all the global properties, including accel properties,
+ * machine properties, and user-specified ones.
+ */
+ register_global_properties(current_machine);
+
+ /*
+ * Migration object can only be created after global properties
+ * are applied correctly.
+ */
+ migration_object_init();
+
if (qtest_chrdev) {
qtest_init(qtest_chrdev, qtest_log, &error_fatal);
}
qemu_opts_del(icount_opts);
}
- qemu_tcg_configure(accel_opts, &error_fatal);
+ if (tcg_enabled()) {
+ qemu_tcg_configure(accel_opts, &error_fatal);
+ }
if (default_net) {
QemuOptsList *net = qemu_find_opts("net");
exit(1);
}
-#ifdef CONFIG_TPM
if (tpm_init() < 0) {
exit(1);
}
-#endif
/* init the bluetooth world */
if (foreach_device_config(DEV_BT, bt_parse))
exit (i == 1 ? 1 : 0);
}
- /*
- * Register all the global properties, including accel properties,
- * machine properties, and user-specified ones.
- */
- register_global_properties(current_machine);
-
- /*
- * Migration object can only be created after global properties
- * are applied correctly.
- */
- migration_object_init();
-
/* This checkpoint is required by replay to separate prior clock
reading from the other reads, because timer polling functions query
clock values from the log. */
current_machine->boot_order = boot_order;
current_machine->cpu_model = cpu_model;
+
+ /* parse features once if machine provides default cpu_type */
+ if (machine_class->default_cpu_type) {
+ current_machine->cpu_type = machine_class->default_cpu_type;
+ if (cpu_model) {
+ current_machine->cpu_type =
+ cpu_parse_cpu_model(machine_class->default_cpu_type, cpu_model);
+ }
+ }
+
machine_run_board_init(current_machine);
realtime_init();
replay_disable_events();
iothread_stop_all();
- bdrv_close_all();
pause_all_vcpus();
+ bdrv_close_all();
res_free();
/* vhost-user must be cleaned up before chardevs. */
+ tpm_cleanup();
net_cleanup();
audio_cleanup();
monitor_cleanup();
qemu_chr_cleanup();
+ user_creatable_cleanup();
/* TODO: unref root container, check all devices are ok */
return 0;