aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVladimir Chtchetkine <vchtchetkine@google.com>2010-10-07 05:40:39 -0700
committerVladimir Chtchetkine <vchtchetkine@google.com>2010-10-08 01:02:22 -0700
commit7746af04f1c7a44253ce49cf7cf1914757faaafe (patch)
tree7a556d8622f4d750c59a38821a625a7ac798fd09
parent4e024bb4f5c8aa8b07459f7fbd65c35122127fd1 (diff)
downloadexternal_qemu-7746af04f1c7a44253ce49cf7cf1914757faaafe.zip
external_qemu-7746af04f1c7a44253ce49cf7cf1914757faaafe.tar.gz
external_qemu-7746af04f1c7a44253ce49cf7cf1914757faaafe.tar.bz2
Make core initialization replying to the UI at the end of initialization.
Also, this CL contains a minor fix to formatting boot options passed to the kernel Change-Id: I267172d82094a0cbbbced2cee7a2990bb7fa3793
-rw-r--r--Makefile.android1
-rw-r--r--android/core-init-utils.c99
-rw-r--r--android/core-init-utils.h41
-rw-r--r--qemu-options.hx6
-rw-r--r--vl-android.c388
5 files changed, 347 insertions, 188 deletions
diff --git a/Makefile.android b/Makefile.android
index 70904f5..49dfd1a 100644
--- a/Makefile.android
+++ b/Makefile.android
@@ -678,6 +678,7 @@ CORE_MISC_SOURCES = vl-android.c \
android/console.c \
android/hw-sensors.c \
android/hw-qemud.c \
+ android/core-init-utils.c \
ifeq ($(HOST_ARCH),x86)
CORE_MISC_SOURCES += i386-dis.c
diff --git a/android/core-init-utils.c b/android/core-init-utils.c
new file mode 100644
index 0000000..97d5f05
--- /dev/null
+++ b/android/core-init-utils.c
@@ -0,0 +1,99 @@
+/* Copyright (C) 2010 The Android Open Source Project
+**
+** This software is licensed under the terms of the GNU General Public
+** License version 2, as published by the Free Software Foundation, and
+** may be copied, distributed, and modified under those terms.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+*/
+
+/*
+ * Contains implementation of routines and that are used in the course
+ * of the emulator's core initialization.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include "qemu-common.h"
+#include "sockets.h"
+#include "android/android.h"
+#include "android/core-init-utils.h"
+#include "android/utils/bufprint.h"
+
+extern char* android_op_ui_port;
+
+/* Sends core initialization status message back to the UI that started this
+ * core process.
+ * Param:
+ * msg - Message to send. On success, message must begin with "ok:", followed
+ * by "port=<console port number>". On initialization failure, message must
+ * begin with "ko:", followed by a string describing the reason of failure.
+ */
+static void
+android_core_send_init_response(const char* msg)
+{
+ int fd;
+ int ui_port;
+
+ if (android_op_ui_port == NULL) {
+ // No socket - no reply.
+ return;
+ }
+
+ ui_port = atoi(android_op_ui_port);
+ if (ui_port >= 0) {
+ // At this point UI always starts the core on the same workstation.
+ fd = socket_loopback_client(ui_port, SOCKET_STREAM);
+ if (fd == -1) {
+ fprintf(stderr, "Unable to create UI socket client for port %s: %s\n",
+ android_op_ui_port, errno_str);
+ return;
+ }
+ socket_send(fd, msg, strlen(msg) + 1);
+ socket_close(fd);
+ } else {
+ fprintf(stderr, "Invalid -ui-port parameter: %s\n", android_op_ui_port);
+ }
+}
+
+void
+android_core_init_completed(void)
+{
+ char msg[32];
+ snprintf(msg, sizeof(msg), "ok:port=%d", android_base_port);
+ android_core_send_init_response(msg);
+}
+
+void
+android_core_init_failure(const char* fmt, ...)
+{
+ va_list args;
+ char msg[4096];
+
+ // Format "ko" message to send back to the UI.
+ snprintf(msg, sizeof(msg), "ko:");
+
+ va_start(args, fmt);
+ vbufprint(msg + strlen(msg), msg + sizeof(msg), fmt, args);
+ va_end(args);
+
+ // Send message back to the UI, print it to the error stdout, and exit the
+ // process.
+ android_core_send_init_response(msg);
+ fprintf(stderr, "%s\n", msg);
+ exit(1);
+}
+
+void
+android_core_init_exit(int exit_status)
+{
+ char msg[32];
+ // Build "ok" message with the exit status, and send it back to the UI.
+ snprintf(msg, sizeof(msg), "ok:status=%d", exit_status);
+ android_core_send_init_response(msg);
+ exit(exit_status);
+}
diff --git a/android/core-init-utils.h b/android/core-init-utils.h
new file mode 100644
index 0000000..2d53288
--- /dev/null
+++ b/android/core-init-utils.h
@@ -0,0 +1,41 @@
+/* Copyright (C) 2010 The Android Open Source Project
+**
+** This software is licensed under the terms of the GNU General Public
+** License version 2, as published by the Free Software Foundation, and
+** may be copied, distributed, and modified under those terms.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+*/
+
+/*
+ * Contains declarations of routines and that are used in the course
+ * of the emulator's core initialization.
+ */
+
+#ifndef QEMU_ANDROID_CORE_INIT_UI_UTILS_H_
+#define QEMU_ANDROID_CORE_INIT_UI_UTILS_H_
+
+/* Formats and sends back to the UI message indicating successful completion
+ * of the core initialization.
+ */
+void android_core_init_completed(void);
+
+/* Builds and sends initialization failure message back to the UI that started
+ * the core. After that exits the process.
+ * Param:
+ * Parameters match those that are passed to sprintf routine to format an
+ * error message for the error that has occured.
+ */
+void android_core_init_failure(const char* fmt, ...);
+
+/* Sends successful initialization completion message back to the UI, and exits
+ * the application.
+ * Param:
+ * exit_status Exit status, that will be passed to the "exit" routine.
+ */
+void android_core_init_exit(int exit_status);
+
+#endif // QEMU_ANDROID_CORE_INIT_UI_UTILS_H_
diff --git a/qemu-options.hx b/qemu-options.hx
index 1203680..44443bc 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -1680,4 +1680,10 @@ DEF("boot-property", HAS_ARG, QEMU_OPTION_boot_property, \
DEF("lcd-density", HAS_ARG, QEMU_OPTION_lcd_density, \
"-lcd-density <density> sets LCD density system property on boot\n")
+DEF("ui-port", HAS_ARG, QEMU_OPTION_ui_port, \
+ "-ui-port <port> socket port to report initialization completion\n")
+
+DEF("ui-settings", HAS_ARG, QEMU_OPTION_ui_settings, \
+ "-ui-settings <string> opaque string containing persitent UI settings\n")
+
#endif
diff --git a/vl-android.c b/vl-android.c
index 13f4dac..a946a35 100644
--- a/vl-android.c
+++ b/vl-android.c
@@ -189,6 +189,7 @@
#include "balloon.h"
#include "android/hw-lcd.h"
#include "android/boot-properties.h"
+#include "android/core-init-utils.h"
#ifdef CONFIG_STANDALONE_CORE
/* Verbose value used by the standalone emulator core (without UI) */
@@ -378,6 +379,16 @@ char* android_op_tcpdump = NULL;
/* -lcd-density option value. */
char* android_op_lcd_density = NULL;
+/* -ui-port option value. This port will be used to report the core
+ * initialization completion.
+ */
+char* android_op_ui_port = NULL;
+
+/* -ui-settings option value. This value will be passed to the UI when new UI
+ * process is attaching to the core.
+ */
+char* android_op_ui_settings = NULL;
+
extern int android_display_width;
extern int android_display_height;
extern int android_display_bpp;
@@ -386,6 +397,26 @@ extern void dprint( const char* format, ... );
#define TFR(expr) do { if ((expr) != -1) break; } while (errno == EINTR)
+/* Reports the core initialization failure to the error stdout and to the UI
+ * socket before exiting the application.
+ * Parameters that are passed to this macro are used to format the error
+ * mesage using sprintf routine.
+ */
+#ifdef CONFIG_ANDROID
+#define PANIC(...) android_core_init_failure(__VA_ARGS__)
+#else
+#define PANIC(...) do { fprintf(stderr, __VA_ARGS__); \
+ exit(1); \
+ } while (0)
+#endif // CONFIG_ANDROID
+
+/* Exits the core during initialization. */
+#ifdef CONFIG_ANDROID
+#define QEMU_EXIT(exit_code) android_core_init_exit(exit_code)
+#else
+#define QEMU_EXIT(exit_code) exit(exit_code)
+#endif // CONFIG_ANDROID
+
/***********************************************************/
/* x86 ISA bus support */
@@ -3279,7 +3310,7 @@ void qemu_help(int exitcode)
#endif
DEFAULT_GDBSTUB_PORT,
"/tmp/qemu.log");
- exit(exitcode);
+ QEMU_EXIT(exitcode);
}
#define HAS_ARG 0x0001
@@ -3406,7 +3437,11 @@ static void select_soundhw (const char *optarg)
printf ("%-11s %s\n", c->name, c->descr);
}
printf ("\n-soundhw all will enable all of the above\n");
- exit (*optarg != '?');
+ if (*optarg != '?') {
+ PANIC("Unknown sound card name: %s", optarg);
+ } else {
+ QEMU_EXIT(0);
+ }
}
else {
size_t l;
@@ -3434,15 +3469,16 @@ static void select_soundhw (const char *optarg)
}
if (!c->name) {
+#ifndef CONFIG_ANDROID
if (l > 80) {
fprintf (stderr,
"Unknown sound card name (too big to show)\n");
- }
- else {
+ } else {
fprintf (stderr, "Unknown sound card name `%.*s'\n",
(int) l, p);
}
- bad_card = 1;
+#endif // !CONFIG_ANDROID
+ bad_card = 1;
}
p += l + (e != NULL);
}
@@ -3471,8 +3507,7 @@ static void select_vgahw (const char *p)
xenfb_enabled = 1;
} else if (!strstart(p, "none", &opts)) {
invalid_vga:
- fprintf(stderr, "Unknown vga type: %s\n", p);
- exit(1);
+ PANIC("Unknown vga type: %s", p);
}
while (*opts) {
const char *nextopt;
@@ -3773,6 +3808,12 @@ int main(int argc, char **argv, char **envp)
char tmp_str[1024];
int dns_count = 0;
+ /* Initialize sockets before anything else, so we can properly report
+ * initialization failures back to the UI. */
+#ifdef _WIN32
+ socket_init();
+#endif
+
init_clocks();
qemu_cache_utils_init(envp);
@@ -3877,9 +3918,8 @@ int main(int argc, char **argv, char **envp)
popt = qemu_options;
for(;;) {
if (!popt->name) {
- fprintf(stderr, "%s: invalid option -- '%s'\n",
- argv[0], r);
- exit(1);
+ PANIC("%s: invalid option -- '%s'",
+ argv[0], r);
}
if (!strcmp(popt->name, r + 1))
break;
@@ -3887,9 +3927,8 @@ int main(int argc, char **argv, char **envp)
}
if (popt->flags & HAS_ARG) {
if (optind >= argc) {
- fprintf(stderr, "%s: option '%s' requires an argument\n",
- argv[0], r);
- exit(1);
+ PANIC("%s: option '%s' requires an argument",
+ argv[0], r);
}
optarg = argv[optind++];
} else {
@@ -3907,7 +3946,12 @@ int main(int argc, char **argv, char **envp)
m->name, m->desc,
m->is_default ? " (default)" : "");
}
- exit(*optarg != '?');
+ if (*optarg != '?') {
+ PANIC("Invalid machine parameter: %s",
+ optarg);
+ } else {
+ QEMU_EXIT(0);
+ }
}
break;
case QEMU_OPTION_cpu:
@@ -3917,7 +3961,7 @@ int main(int argc, char **argv, char **envp)
#if defined(cpu_list)
cpu_list(stdout, &fprintf);
#endif
- exit(0);
+ QEMU_EXIT(0);
} else {
cpu_model = optarg;
}
@@ -3988,8 +4032,7 @@ int main(int argc, char **argv, char **envp)
goto chs_fail;
} else if (*p != '\0') {
chs_fail:
- fprintf(stderr, "qemu: invalid physical CHS format\n");
- exit(1);
+ PANIC("qemu: invalid physical CHS format");
}
if (hda_index != -1)
snprintf(drives_opt[hda_index].opt,
@@ -4004,8 +4047,7 @@ int main(int argc, char **argv, char **envp)
break;
case QEMU_OPTION_numa:
if (nb_numa_nodes >= MAX_NODES) {
- fprintf(stderr, "qemu: too many NUMA nodes\n");
- exit(1);
+ PANIC("qemu: too many NUMA nodes");
}
numa_add(optarg);
break;
@@ -4048,13 +4090,11 @@ int main(int argc, char **argv, char **envp)
* implementation and firmware features.
*/
if (*p < 'a' || *p > 'q') {
- fprintf(stderr, "Invalid boot device '%c'\n", *p);
- exit(1);
+ PANIC("Invalid boot device '%c'", *p);
}
if (boot_devices_bitmap & (1 << (*p - 'a'))) {
- fprintf(stderr,
- "Boot device '%c' was given twice\n",*p);
- exit(1);
+ PANIC(
+ "Boot device '%c' was given twice",*p);
}
boot_devices_bitmap |= 1 << (*p - 'a');
}
@@ -4071,8 +4111,7 @@ int main(int argc, char **argv, char **envp)
#endif
case QEMU_OPTION_net:
if (nb_net_clients >= MAX_NET_CLIENTS) {
- fprintf(stderr, "qemu: too many network clients\n");
- exit(1);
+ PANIC("qemu: too many network clients");
}
net_clients[nb_net_clients] = optarg;
nb_net_clients++;
@@ -4097,15 +4136,14 @@ int main(int argc, char **argv, char **envp)
#endif
case QEMU_OPTION_bt:
if (nb_bt_opts >= MAX_BT_CMDLINE) {
- fprintf(stderr, "qemu: too many bluetooth options\n");
- exit(1);
+ PANIC("qemu: too many bluetooth options");
}
bt_opts[nb_bt_opts++] = optarg;
break;
#ifdef HAS_AUDIO
case QEMU_OPTION_audio_help:
AUD_help ();
- exit (0);
+ QEMU_EXIT(0);
break;
case QEMU_OPTION_soundhw:
select_soundhw (optarg);
@@ -4116,7 +4154,7 @@ int main(int argc, char **argv, char **envp)
break;
case QEMU_OPTION_version:
version();
- exit(0);
+ QEMU_EXIT(0);
break;
case QEMU_OPTION_m: {
uint64_t value;
@@ -4131,8 +4169,7 @@ int main(int argc, char **argv, char **envp)
value <<= 30;
break;
default:
- fprintf(stderr, "qemu: invalid ram size: %s\n", optarg);
- exit(1);
+ PANIC("qemu: invalid ram size: %s", optarg);
}
/* On 32-bit hosts, QEMU is limited by virtual address space */
@@ -4141,12 +4178,10 @@ int main(int argc, char **argv, char **envp)
&& HOST_LONG_BITS == 32
#endif
) {
- fprintf(stderr, "qemu: at most 2047 MB RAM can be simulated\n");
- exit(1);
+ PANIC("qemu: at most 2047 MB RAM can be simulated");
}
if (value != (uint64_t)(ram_addr_t)value) {
- fprintf(stderr, "qemu: ram size too large\n");
- exit(1);
+ PANIC("qemu: ram size too large");
}
ram_size = value;
break;
@@ -4159,10 +4194,10 @@ int main(int argc, char **argv, char **envp)
mask = cpu_str_to_log_mask(optarg);
if (!mask) {
printf("Log items (comma separated):\n");
- for(item = cpu_log_items; item->mask != 0; item++) {
- printf("%-10s %s\n", item->name, item->help);
- }
- exit(1);
+ for(item = cpu_log_items; item->mask != 0; item++) {
+ printf("%-10s %s\n", item->name, item->help);
+ }
+ PANIC("Invalid parameter -d=%s", optarg);
}
cpu_set_log(mask);
}
@@ -4184,8 +4219,7 @@ int main(int argc, char **argv, char **envp)
break;
case QEMU_OPTION_S:
#if 0 /* ANDROID */
- fprintf(stderr, "Sorry, stopped launch is not supported in the Android emulator\n" );
- exit(1);
+ PANIC("Sorry, stopped launch is not supported in the Android emulator" );
#endif
autostart = 0;
break;
@@ -4209,8 +4243,7 @@ int main(int argc, char **argv, char **envp)
w = strtol(p, (char **)&p, 10);
if (w <= 0) {
graphic_error:
- fprintf(stderr, "qemu: invalid resolution or depth\n");
- exit(1);
+ PANIC("qemu: invalid resolution or depth");
}
if (*p != 'x')
goto graphic_error;
@@ -4249,35 +4282,37 @@ int main(int argc, char **argv, char **envp)
break;
case QEMU_OPTION_serial:
if (serial_device_index >= MAX_SERIAL_PORTS) {
- fprintf(stderr, "qemu: too many serial ports\n");
- exit(1);
+ PANIC("qemu: too many serial ports");
}
serial_devices[serial_device_index] = optarg;
serial_device_index++;
break;
case QEMU_OPTION_watchdog:
i = select_watchdog(optarg);
- if (i > 0)
- exit (i == 1 ? 1 : 0);
+ if (i > 0) {
+ if (i == 1) {
+ PANIC("Invalid watchdog parameter: %s",
+ optarg);
+ } else {
+ QEMU_EXIT(0);
+ }
+ }
break;
case QEMU_OPTION_watchdog_action:
if (select_watchdog_action(optarg) == -1) {
- fprintf(stderr, "Unknown -watchdog-action parameter\n");
- exit(1);
+ PANIC("Unknown -watchdog-action parameter");
}
break;
case QEMU_OPTION_virtiocon:
if (virtio_console_index >= MAX_VIRTIO_CONSOLES) {
- fprintf(stderr, "qemu: too many virtio consoles\n");
- exit(1);
+ PANIC("qemu: too many virtio consoles");
}
virtio_consoles[virtio_console_index] = optarg;
virtio_console_index++;
break;
case QEMU_OPTION_parallel:
if (parallel_device_index >= MAX_PARALLEL_PORTS) {
- fprintf(stderr, "qemu: too many parallel ports\n");
- exit(1);
+ PANIC("qemu: too many parallel ports");
}
parallel_devices[parallel_device_index] = optarg;
parallel_device_index++;
@@ -4314,14 +4349,12 @@ int main(int argc, char **argv, char **envp)
break;
case QEMU_OPTION_acpitable:
if(acpi_table_add(optarg) < 0) {
- fprintf(stderr, "Wrong acpi table provided\n");
- exit(1);
+ PANIC("Wrong acpi table provided");
}
break;
case QEMU_OPTION_smbios:
if(smbios_entry_add(optarg) < 0) {
- fprintf(stderr, "Wrong smbios provided\n");
- exit(1);
+ PANIC("Wrong smbios provided");
}
break;
#endif
@@ -4347,8 +4380,7 @@ int main(int argc, char **argv, char **envp)
case QEMU_OPTION_usbdevice:
usb_enabled = 1;
if (usb_devices_index >= MAX_USB_CMDLINE) {
- fprintf(stderr, "Too many USB devices\n");
- exit(1);
+ PANIC("Too many USB devices");
}
usb_devices[usb_devices_index] = optarg;
usb_devices_index++;
@@ -4356,8 +4388,7 @@ int main(int argc, char **argv, char **envp)
case QEMU_OPTION_smp:
smp_cpus = atoi(optarg);
if (smp_cpus < 1) {
- fprintf(stderr, "Invalid number of CPUs\n");
- exit(1);
+ PANIC("Invalid number of CPUs");
}
break;
case QEMU_OPTION_vnc:
@@ -4386,9 +4417,7 @@ int main(int argc, char **argv, char **envp)
break;
case QEMU_OPTION_uuid:
if(qemu_uuid_parse(optarg, qemu_uuid) < 0) {
- fprintf(stderr, "Fail to parse UUID string."
- " Wrong format.\n");
- exit(1);
+ PANIC("Fail to parse UUID string. Wrong format.");
}
break;
#ifndef _WIN32
@@ -4398,8 +4427,7 @@ int main(int argc, char **argv, char **envp)
#endif
case QEMU_OPTION_option_rom:
if (nb_option_roms >= MAX_OPTION_ROMS) {
- fprintf(stderr, "Too many option ROMs\n");
- exit(1);
+ PANIC("Too many option ROMs");
}
option_rom[nb_option_roms] = optarg;
nb_option_roms++;
@@ -4415,8 +4443,7 @@ int main(int argc, char **argv, char **envp)
#if defined(TARGET_SPARC) || defined(TARGET_PPC)
case QEMU_OPTION_prom_env:
if (nb_prom_envs >= MAX_PROM_ENVS) {
- fprintf(stderr, "Too many prom variables\n");
- exit(1);
+ PANIC("Too many prom variables");
}
prom_envs[nb_prom_envs] = optarg;
nb_prom_envs++;
@@ -4460,9 +4487,8 @@ int main(int argc, char **argv, char **envp)
rtc_start_date = mktimegm(&tm);
if (rtc_start_date == -1) {
date_fail:
- fprintf(stderr, "Invalid date format. Valid format are:\n"
- "'now' or '2006-06-17T16:01:21' or '2006-06-17'\n");
- exit(1);
+ PANIC("Invalid date format. Valid format are:\n"
+ "'now' or '2006-06-17T16:01:21' or '2006-06-17'");
}
rtc_date_offset = time(NULL) - rtc_start_date;
}
@@ -4522,9 +4548,8 @@ int main(int argc, char **argv, char **envp)
else if (strcmp(optarg, "on") == 0 && trace_filename)
tracing = 1;
else {
- fprintf(stderr, "Unexpected option to -tracing ('%s')\n",
+ PANIC("Unexpected option to -tracing ('%s')",
optarg);
- exit(1);
}
break;
#if 0
@@ -4631,6 +4656,14 @@ int main(int argc, char **argv, char **envp)
android_op_lcd_density = (char*)optarg;
break;
+ case QEMU_OPTION_ui_port:
+ android_op_ui_port = (char*)optarg;
+ break;
+
+ case QEMU_OPTION_ui_settings:
+ android_op_ui_settings = (char*)optarg;
+ break;
+
#ifdef CONFIG_MEMCHECK
case QEMU_OPTION_android_memcheck:
android_op_memcheck = (char*)optarg;
@@ -4649,14 +4682,13 @@ int main(int argc, char **argv, char **envp)
/* Initialize character map. */
if (android_charmap_setup(op_charmap_file)) {
if (op_charmap_file) {
- fprintf(stderr,
- "Unable to initialize character map from file %s.\n",
+ PANIC(
+ "Unable to initialize character map from file %s.",
op_charmap_file);
} else {
- fprintf(stderr,
- "Unable to initialize default character map.\n");
+ PANIC(
+ "Unable to initialize default character map.");
}
- exit(1);
}
/* If no data_dir is specified then try to find it relative to the
@@ -4674,8 +4706,7 @@ int main(int argc, char **argv, char **envp)
if (android_op_hwini) {
hw_ini = iniFile_newFromFile(android_op_hwini);
if (hw_ini == NULL) {
- fprintf(stderr, "Could not find %s file.\n", android_op_hwini);
- exit(1);
+ PANIC("Could not find %s file.", android_op_hwini);
}
} else {
hw_ini = iniFile_newFromMemory("", 0);
@@ -4701,15 +4732,13 @@ int main(int argc, char **argv, char **envp)
/* Initialize net speed and delays stuff. */
if (android_parse_network_speed(android_op_netspeed) < 0 ) {
- fprintf(stderr, "invalid -netspeed parameter '%s'\n",
+ PANIC("invalid -netspeed parameter '%s'",
android_op_netspeed);
- exit(1);
}
if ( android_parse_network_latency(android_op_netdelay) < 0 ) {
- fprintf(stderr, "invalid -netdelay parameter '%s'\n",
+ PANIC("invalid -netdelay parameter '%s'",
android_op_netdelay);
- exit(1);
}
if (android_op_netfast) {
@@ -4724,8 +4753,7 @@ int main(int argc, char **argv, char **envp)
char* end;
long density = strtol(android_op_lcd_density, &end, 0);
if (end == NULL || *end || density < 0) {
- fprintf(stderr, "option -lcd-density must be a positive integer\n" );
- exit(1);
+ PANIC("option -lcd-density must be a positive integer");
}
hwLcd_setBootProperty(density);
}
@@ -4741,16 +4769,14 @@ int main(int argc, char **argv, char **envp)
if (android_op_radio) {
CharDriverState* cs = qemu_chr_open("radio", android_op_radio, NULL);
if (cs == NULL) {
- fprintf(stderr, "unsupported character device specification: %s\n"
- "used -help-char-devices for list of available formats\n",
+ PANIC("unsupported character device specification: %s\n"
+ "used -help-char-devices for list of available formats",
android_op_radio);
- exit(1);
}
android_qemud_set_channel( ANDROID_QEMUD_GSM, cs);
} else if (android_hw->hw_gsmModem != 0 ) {
if ( android_qemud_get_channel( ANDROID_QEMUD_GSM, &android_modem_cs ) < 0 ) {
- fprintf(stderr, "could not initialize qemud 'gsm' channel");
- exit(1);
+ PANIC("could not initialize qemud 'gsm' channel");
}
}
@@ -4758,29 +4784,25 @@ int main(int argc, char **argv, char **envp)
if (android_op_gps) {
CharDriverState* cs = qemu_chr_open("gps", android_op_gps, NULL);
if (cs == NULL) {
- fprintf(stderr, "unsupported character device specification: %s\n"
- "used -help-char-devices for list of available formats\n",
+ PANIC("unsupported character device specification: %s\n"
+ "used -help-char-devices for list of available formats",
android_op_gps);
- exit(1);
}
android_qemud_set_channel( ANDROID_QEMUD_GPS, cs);
} else if (android_hw->hw_gps != 0) {
if ( android_qemud_get_channel( "gps", &android_gps_cs ) < 0 ) {
- fprintf(stderr, "could not initialize qemud 'gps' channel" );
- exit(1);
+ PANIC("could not initialize qemud 'gps' channel");
}
}
/* Initialize audio. */
if (android_op_audio) {
if (android_op_audio_in || android_op_audio_out) {
- fprintf(stderr, "you can't use -audio with -audio-in or -audio-out\n" );
- exit(1);
+ PANIC("you can't use -audio with -audio-in or -audio-out");
}
if ( !audio_check_backend_name( 0, android_op_audio ) ) {
- fprintf(stderr, "'%s' is not a valid audio output backend. see -help-audio-out\n",
+ PANIC("'%s' is not a valid audio output backend. see -help-audio-out",
android_op_audio);
- exit(1);
}
android_op_audio_out = android_op_audio;
android_op_audio_in = android_op_audio;
@@ -4796,9 +4818,8 @@ int main(int argc, char **argv, char **envp)
if (android_op_audio_in) {
static char env[64]; /* note: putenv needs a static unique string buffer */
if ( !audio_check_backend_name( 1, android_op_audio_in ) ) {
- fprintf(stderr, "'%s' is not a valid audio input backend. see -help-audio-in\n",
+ PANIC("'%s' is not a valid audio input backend. see -help-audio-in",
android_op_audio_in);
- exit(1);
}
bufprint( env, env+sizeof(env), "QEMU_AUDIO_IN_DRV=%s", android_op_audio_in );
putenv( env );
@@ -4810,9 +4831,8 @@ int main(int argc, char **argv, char **envp)
if (android_op_audio_out) {
static char env[64]; /* note: putenv needs a static unique string buffer */
if ( !audio_check_backend_name( 0, android_op_audio_out ) ) {
- fprintf(stderr, "'%s' is not a valid audio output backend. see -help-audio-out\n",
+ PANIC("'%s' is not a valid audio output backend. see -help-audio-out",
android_op_audio_out);
- exit(1);
}
bufprint( env, env+sizeof(env), "QEMU_AUDIO_OUT_DRV=%s", android_op_audio_out );
putenv( env );
@@ -4825,8 +4845,7 @@ int main(int argc, char **argv, char **envp)
char* end;
long delay = strtol(android_op_cpu_delay, &end, 0);
if (end == NULL || *end || delay < 0 || delay > 1000 ) {
- fprintf(stderr, "option -cpu-delay must be an integer between 0 and 1000\n" );
- exit(1);
+ PANIC("option -cpu-delay must be an integer between 0 and 1000" );
}
if (delay > 0)
delay = (1000-delay);
@@ -4868,7 +4887,7 @@ int main(int argc, char **argv, char **envp)
if (dns_count == 0)
dns_count = slirp_get_system_dns_servers();
if (dns_count) {
- snprintf(tmp_str, sizeof(tmp_str), "android.ndns=%d", dns_count);
+ snprintf(tmp_str, sizeof(tmp_str), "ndns=%d", dns_count);
append_param(kernel_cmdline_append, tmp_str, sizeof(kernel_cmdline_append));
}
@@ -4880,18 +4899,16 @@ int main(int argc, char **argv, char **envp)
#if defined(CONFIG_KVM) && defined(CONFIG_KQEMU)
if (kvm_allowed && kqemu_allowed) {
- fprintf(stderr,
- "You can not enable both KVM and kqemu at the same time\n");
- exit(1);
+ PANIC(
+ "You can not enable both KVM and kqemu at the same time");
}
#endif
machine->max_cpus = machine->max_cpus ?: 1; /* Default to UP */
if (smp_cpus > machine->max_cpus) {
- fprintf(stderr, "Number of SMP cpus requested (%d), exceeds max cpus "
- "supported by machine `%s' (%d)\n", smp_cpus, machine->name,
+ PANIC("Number of SMP cpus requested (%d), exceeds max cpus "
+ "supported by machine `%s' (%d)", smp_cpus, machine->name,
machine->max_cpus);
- exit(1);
}
if (display_type == DT_NOGRAPHIC) {
@@ -4907,8 +4924,9 @@ int main(int argc, char **argv, char **envp)
if (daemonize) {
pid_t pid;
- if (pipe(fds) == -1)
- exit(1);
+ if (pipe(fds) == -1) {
+ PANIC("Unable to aquire pidfile");
+ }
pid = fork();
if (pid > 0) {
@@ -4922,23 +4940,26 @@ int main(int argc, char **argv, char **envp)
if (len == -1 && (errno == EINTR))
goto again;
- if (len != 1)
- exit(1);
+ if (len != 1) {
+ PANIC("Error when aquiring pidfile");
+ }
else if (status == 1) {
- fprintf(stderr, "Could not acquire pidfile\n");
- exit(1);
- } else
- exit(0);
- } else if (pid < 0)
- exit(1);
+ PANIC("Could not acquire pidfile");
+ } else {
+ QEMU_EXIT(0);
+ }
+ } else if (pid < 0) {
+ PANIC("Unable to daemonize");
+ }
setsid();
pid = fork();
- if (pid > 0)
- exit(0);
- else if (pid < 0)
- exit(1);
+ if (pid > 0) {
+ QEMU_EXIT(0);
+ } else if (pid < 0) {
+ PANIC("Could not acquire pid file");
+ }
umask(027);
@@ -4954,9 +4975,10 @@ int main(int argc, char **argv, char **envp)
do {
ret = write(fds[1], &status, 1);
} while (ret < 0 && errno == EINTR);
- } else
- fprintf(stderr, "Could not acquire pid file\n");
- exit(1);
+ PANIC("Could not acquire pid file");
+ } else {
+ PANIC("Could not acquire pid file");
+ }
}
#endif
@@ -4965,20 +4987,17 @@ int main(int argc, char **argv, char **envp)
kqemu_allowed = 0;
#endif
if (qemu_init_main_loop()) {
- fprintf(stderr, "qemu_init_main_loop failed\n");
- exit(1);
+ PANIC("qemu_init_main_loop failed");
}
linux_boot = (kernel_filename != NULL);
net_boot = (boot_devices_bitmap >> ('n' - 'a')) & 0xF;
if (!linux_boot && *kernel_cmdline != '\0') {
- fprintf(stderr, "-append only allowed with -kernel option\n");
- exit(1);
+ PANIC("-append only allowed with -kernel option");
}
if (!linux_boot && initrd_filename != NULL) {
- fprintf(stderr, "-initrd only allowed with -kernel option\n");
- exit(1);
+ PANIC("-initrd only allowed with -kernel option");
}
/* boot to floppy or the default cd if no hard disk defined yet */
@@ -4988,15 +5007,10 @@ int main(int argc, char **argv, char **envp)
setvbuf(stdout, NULL, _IOLBF, 0);
if (init_timer_alarm() < 0) {
- fprintf(stderr, "could not initialize alarm timer\n");
- exit(1);
+ PANIC("could not initialize alarm timer");
}
configure_icount(icount_option);
-#ifdef _WIN32
- socket_init();
-#endif
-
/* init network clients */
if (nb_net_clients == 0) {
/* if no clients, we use a default config */
@@ -5007,8 +5021,9 @@ int main(int argc, char **argv, char **envp)
}
for(i = 0;i < nb_net_clients; i++) {
- if (net_client_parse(net_clients[i]) < 0)
- exit(1);
+ if (net_client_parse(net_clients[i]) < 0) {
+ PANIC("Unable to parse net clients");
+ }
}
net_client_check();
@@ -5027,8 +5042,7 @@ int main(int argc, char **argv, char **envp)
filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, buf);
if (filename && get_image_size(filename) > 0) {
if (nb_option_roms >= MAX_OPTION_ROMS) {
- fprintf(stderr, "Too many option ROMs\n");
- exit(1);
+ PANIC("Too many option ROMs");
}
option_rom[nb_option_roms] = qemu_strdup(buf);
nb_option_roms++;
@@ -5040,16 +5054,16 @@ int main(int argc, char **argv, char **envp)
}
}
if (netroms == 0) {
- fprintf(stderr, "No valid PXE rom found for network device\n");
- exit(1);
+ PANIC("No valid PXE rom found for network device");
}
}
#endif
/* init the bluetooth world */
for (i = 0; i < nb_bt_opts; i++)
- if (bt_parse(bt_opts[i]))
- exit(1);
+ if (bt_parse(bt_opts[i])) {
+ PANIC("Unable to parse bluetooth options");
+ }
/* init the memory */
if (ram_size == 0)
@@ -5062,8 +5076,7 @@ int main(int argc, char **argv, char **envp)
kqemu_phys_ram_size = ram_size + 8 * 1024 * 1024 + 4 * 1024 * 1024;
kqemu_phys_ram_base = qemu_vmalloc(kqemu_phys_ram_size);
if (!kqemu_phys_ram_base) {
- fprintf(stderr, "Could not allocate physical memory\n");
- exit(1);
+ PANIC("Could not allocate physical memory");
}
}
#endif
@@ -5091,8 +5104,9 @@ int main(int argc, char **argv, char **envp)
/* open the virtual block devices */
for(i = 0; i < nb_drives_opt; i++)
- if (drive_init(&drives_opt[i], snapshot, machine) == -1)
- exit(1);
+ if (drive_init(&drives_opt[i], snapshot, machine) == -1) {
+ PANIC("Could not open the virtual block devices");
+ }
//register_savevm("timer", 0, 2, timer_save, timer_load, &timers_state);
register_savevm_live("ram", 0, 3, ram_save_live, NULL, ram_load, NULL);
@@ -5164,16 +5178,15 @@ int main(int argc, char **argv, char **envp)
ret = kvm_init(smp_cpus);
if (ret < 0) {
- fprintf(stderr, "failed to initialize KVM\n");
- exit(1);
+ PANIC("failed to initialize KVM");
}
}
if (monitor_device) {
monitor_hd = qemu_chr_open("monitor", monitor_device, NULL);
if (!monitor_hd) {
- fprintf(stderr, "qemu: could not open monitor device '%s'\n", monitor_device);
- exit(1);
+ PANIC("qemu: could not open monitor device '%s'",
+ monitor_device);
}
}
@@ -5184,9 +5197,8 @@ int main(int argc, char **argv, char **envp)
snprintf(label, sizeof(label), "serial%d", i);
serial_hds[i] = qemu_chr_open(label, devname, NULL);
if (!serial_hds[i]) {
- fprintf(stderr, "qemu: could not open serial device '%s'\n",
+ PANIC("qemu: could not open serial device '%s'",
devname);
- exit(1);
}
}
}
@@ -5198,9 +5210,8 @@ int main(int argc, char **argv, char **envp)
snprintf(label, sizeof(label), "parallel%d", i);
parallel_hds[i] = qemu_chr_open(label, devname, NULL);
if (!parallel_hds[i]) {
- fprintf(stderr, "qemu: could not open parallel device '%s'\n",
+ PANIC("qemu: could not open parallel device '%s'",
devname);
- exit(1);
}
}
}
@@ -5212,9 +5223,8 @@ int main(int argc, char **argv, char **envp)
snprintf(label, sizeof(label), "virtcon%d", i);
virtcon_hds[i] = qemu_chr_open(label, devname, NULL);
if (!virtcon_hds[i]) {
- fprintf(stderr, "qemu: could not open virtio console '%s'\n",
+ PANIC("qemu: could not open virtio console '%s'",
devname);
- exit(1);
}
}
}
@@ -5270,8 +5280,7 @@ int main(int argc, char **argv, char **envp)
ret = kvm_sync_vcpus();
if (ret < 0) {
- fprintf(stderr, "failed to initialize vcpus\n");
- exit(1);
+ PANIC("failed to initialize vcpus");
}
}
@@ -5292,7 +5301,8 @@ int main(int argc, char **argv, char **envp)
&android_display_width,
&android_display_height,
&android_display_bpp)) {
- exit(1);
+ PANIC("Unable to parse -android-gui parameter: %s",
+ android_op_gui);
}
android_display_init_from(android_display_width,
android_display_height, 0,
@@ -5306,7 +5316,8 @@ int main(int argc, char **argv, char **envp)
&android_display_width,
&android_display_height,
&android_display_bpp)) {
- exit(1);
+ PANIC("Unable to parse -android-gui parameter: %s",
+ android_op_gui);
}
display_state->surface = qemu_resize_displaysurface(display_state,
android_display_width,
@@ -5346,8 +5357,9 @@ int main(int argc, char **argv, char **envp)
#endif
case DT_VNC:
vnc_display_init(ds);
- if (vnc_display_open(ds, vnc_display) < 0)
- exit(1);
+ if (vnc_display_open(ds, vnc_display) < 0) {
+ PANIC("Unable to initialize VNC display");
+ }
if (show_vnc_port) {
printf("VNC server running on `%s'\n", vnc_display_local_addr(ds));
@@ -5403,9 +5415,8 @@ int main(int argc, char **argv, char **envp)
}
if (gdbstub_dev && gdbserver_start(gdbstub_dev) < 0) {
- fprintf(stderr, "qemu: could not open gdbserver on device '%s'\n",
+ PANIC("qemu: could not open gdbserver on device '%s'",
gdbstub_dev);
- exit(1);
}
if (loadvm)
@@ -5432,49 +5443,45 @@ int main(int argc, char **argv, char **envp)
if (len == -1 && (errno == EINTR))
goto again1;
- if (len != 1)
- exit(1);
+ if (len != 1) {
+ PANIC("Unable to daemonize");
+ }
if (chdir("/")) {
perror("not able to chdir to /");
- exit(1);
+ PANIC("not able to chdir to /");
}
TFR(fd = open("/dev/null", O_RDWR));
if (fd == -1)
- exit(1);
+ PANIC("open(\"/dev/null\") failed: %s", errno_str);
}
if (run_as) {
pwd = getpwnam(run_as);
if (!pwd) {
- fprintf(stderr, "User \"%s\" doesn't exist\n", run_as);
- exit(1);
+ PANIC("User \"%s\" doesn't exist", run_as);
}
}
if (chroot_dir) {
if (chroot(chroot_dir) < 0) {
- fprintf(stderr, "chroot failed\n");
- exit(1);
+ PANIC("chroot failed");
}
if (chdir("/")) {
perror("not able to chdir to /");
- exit(1);
+ PANIC("not able to chdir to /");
}
}
if (run_as) {
if (setgid(pwd->pw_gid) < 0) {
- fprintf(stderr, "Failed to setgid(%d)\n", pwd->pw_gid);
- exit(1);
+ PANIC("Failed to setgid(%d)", pwd->pw_gid);
}
if (setuid(pwd->pw_uid) < 0) {
- fprintf(stderr, "Failed to setuid(%d)\n", pwd->pw_uid);
- exit(1);
+ PANIC("Failed to setuid(%d)", pwd->pw_uid);
}
if (setuid(0) != -1) {
- fprintf(stderr, "Dropping privileges failed\n");
- exit(1);
+ PANIC("Dropping privileges failed");
}
}
@@ -5487,6 +5494,11 @@ int main(int argc, char **argv, char **envp)
}
#endif
+#ifdef CONFIG_ANDROID
+ // This will notify the UI that the core is successfuly initialized
+ android_core_init_completed();
+#endif // CONFIG_ANDROID
+
main_loop();
quit_timers();
net_cleanup();