aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile.android1
-rw-r--r--android/cmdline-options.h4
-rw-r--r--android/help.c12
-rw-r--r--android/main.c143
-rw-r--r--iolooper-select.c6
5 files changed, 163 insertions, 3 deletions
diff --git a/Makefile.android b/Makefile.android
index 1d82197..97bfafb 100644
--- a/Makefile.android
+++ b/Makefile.android
@@ -1187,6 +1187,7 @@ VL_SOURCES := framebuffer.c \
qemu-timer-ui.c \
vl-android-ui.c \
console-ui.c \
+ iolooper-select.c \
# Add common system libraries
#
diff --git a/android/cmdline-options.h b/android/cmdline-options.h
index da8f375..1ae3121 100644
--- a/android/cmdline-options.h
+++ b/android/cmdline-options.h
@@ -152,6 +152,10 @@ OPT_PARAM( nand_limits, "<nlimits>", "enforce NAND/Flash read/write thresholds"
OPT_PARAM( memcheck, "<flags>", "enable memory access checking" )
#endif // CONFIG_MEMCHECK
+#ifdef CONFIG_STANDALONE_UI
+OPT_PARAM( list_cores, "<host>", "list running core process" )
+#endif // CONFIG_STANDALONE_UI
+
#undef CFG_FLAG
#undef CFG_PARAM
#undef OPT_FLAG
diff --git a/android/help.c b/android/help.c
index f589b3e..2103b00 100644
--- a/android/help.c
+++ b/android/help.c
@@ -1010,6 +1010,18 @@ help_memcheck(stralloc_t* out)
}
#endif // CONFIG_MEMCHECK
+#ifdef CONFIG_STANDALONE_UI
+static void
+help_list_cores(stralloc_t* out)
+{
+ PRINTF(
+ " use '-list-cores localhost to list emulator core processes running on this machine.\n"
+ " use '-list-cores host_name, or IP address to list emulator core processes running on\n"
+ " a remote machine.\n"
+ );
+}
+#endif // CONFIG_STANDALONE_UI
+
static void
help_show_kernel(stralloc_t* out)
{
diff --git a/android/main.c b/android/main.c
index 6b3bea6..ffdd821 100644
--- a/android/main.c
+++ b/android/main.c
@@ -62,6 +62,7 @@
#include "android/snapshot.h"
#include "framebuffer.h"
+#include "iolooper.h"
AndroidRotation android_framebuffer_rotation;
@@ -734,6 +735,137 @@ _adjustPartitionSize( const char* description,
return convertMBToBytes(imageMB);
}
+#ifdef CONFIG_STANDALONE_UI
+
+// Base console port
+#define CORE_BASE_PORT 5554
+
+// Maximum number of core porocesses running simultaneously on a machine.
+#define MAX_CORE_PROCS 16
+
+// Socket timeout in millisec (set to half a second)
+#define CORE_PORT_TIMEOUT_MS 500
+
+/* Checks if emulator core runs at the end of the given socket.
+ * Param:
+ * sockaddr Socket address addressing emulator's console.
+ * Return:
+ * 0 in case that core has been found for the socket, or -1 otherwise.
+ */
+static int
+check_for_running_core(SockAddress* sockaddr)
+{
+ IoLooper* looper = iolooper_new();
+ int connect_status;
+ char buf[512];
+ int ret = -1;
+
+ int fd = socket_create_inet(SOCKET_STREAM);
+ if (fd < 0) {
+ return -1;
+ }
+
+ socket_set_xreuseaddr(fd);
+ socket_set_nonblock(fd);
+ connect_status = socket_connect(fd, sockaddr);
+ if (connect_status < 0 && errno == EINPROGRESS) {
+ // Wait till connection occurs.
+ iolooper_add_write(looper, fd);
+ connect_status = iolooper_wait(looper, CORE_PORT_TIMEOUT_MS);
+ if (connect_status > 0) {
+ iolooper_del_write(looper, fd);
+ } else {
+ connect_status = -1;
+ }
+ }
+ if (connect_status >= 0) {
+ iolooper_add_read(looper, fd);
+ // Read the handshake message from the core's console.
+ if (iolooper_wait(looper, CORE_PORT_TIMEOUT_MS) > 0 &&
+ iolooper_is_read(looper, fd)) {
+ int read_bytes = read(fd, buf, sizeof(buf));
+ // Check for the console handshake.
+ if (read_bytes > 15 && !strncmp(buf, "Android Console", 15)) {
+ ret = 0;
+ }
+ }
+ }
+
+ socket_close( fd );
+ iolooper_free(looper);
+ return ret;
+}
+
+/* List emulator core processes running on the given machine.
+ * This routine is called from main() if -list-cores parameter is set in the
+ * command line.
+ * Param:
+ * host Value passed with -list-core parameter. Must be either "localhost", or
+ * an IP address of a machine where core processes must be enumerated.
+ */
+static void
+list_running_cores(const char* host)
+{
+ int iter;
+ int port_iter;
+ int found_cores = 0;
+
+ // Convert host name into socket address list.
+ SockAddress** sockaddr_list = sock_address_list_create(host, NULL, 0);
+ if (sockaddr_list == NULL) {
+ derror("Unable to resolve hostname %s: %s\n", host, errno_str);
+ return;
+ }
+
+ /* Since core's console is not a UNIX socket, lets make sure that UNIX
+ * socket is not the only family in the list. */
+ for (iter = 0; sockaddr_list[iter] != NULL; iter++) {
+ if (sock_address_get_family(sockaddr_list[iter]) != SOCKET_UNIX) {
+ break;
+ }
+ }
+ if (sockaddr_list[iter] == NULL) {
+ derror("Unix socket is an invalid parameter for -list-cores option.\n");
+ sock_address_list_free(sockaddr_list);
+ return;
+ }
+
+ /* List running core processes. To enum core processes we will loop
+ * through socket ports 5554-5584, where we assume that successful
+ * conection to a socket means that there is a core process running
+ * at the other end of that socket. In order to make sure that it's
+ * emulator console at the other end of that socket, we will read from
+ * the socket, expecting "Android Console" string at the beginning of
+ * the data read from the socket. */
+ for (port_iter = 0; port_iter < MAX_CORE_PROCS; port_iter++) {
+ int port_num = CORE_BASE_PORT + port_iter * 2;
+ for (iter = 0; sockaddr_list[iter] != NULL; iter++) {
+ if (sock_address_get_family(sockaddr_list[iter]) == SOCKET_UNIX) {
+ continue;
+ }
+ sock_address_set_port(sockaddr_list[iter], port_num);
+ if (!check_for_running_core(sockaddr_list[iter])) {
+ // This is a core process at the other end of the socket.
+ found_cores++;
+ if (found_cores == 1) {
+ fprintf(stdout, "Running emulator core processes:\n");
+ }
+ fprintf(stdout, "Emulator console port %d\n", port_num);
+ }
+ // Go through this loop just once, for a non-Unix socket address.
+ break;
+ }
+ }
+
+ sock_address_list_free(sockaddr_list);
+
+ if (!found_cores) {
+ fprintf(stdout, "There were no running emulator core processes found on %s.\n",
+ host);
+ }
+}
+#endif // CONFIG_STANDALONE_UI
+
int main(int argc, char **argv)
{
char tmp[MAX_PATH];
@@ -820,6 +952,17 @@ int main(int argc, char **argv)
exit(1);
}
+#ifdef CONFIG_STANDALONE_UI
+ // Lets see if user just wants to list core process.
+ if (opts->list_cores) {
+ fprintf(stdout, "Enumerating running core processes.\n"
+ "This make take up to %d seconds...\n\n",
+ (MAX_CORE_PROCS * CORE_PORT_TIMEOUT_MS) / 1000 + 1);
+ list_running_cores(opts->list_cores);
+ exit(0);
+ }
+#endif // CONFIG_STANDALONE_UI
+
if (android_charmap_setup(opts->charmap)) {
exit(1);
}
diff --git a/iolooper-select.c b/iolooper-select.c
index f5aecbd..000fa5d 100644
--- a/iolooper-select.c
+++ b/iolooper-select.c
@@ -21,7 +21,7 @@ struct IoLooper {
IoLooper*
iolooper_new(void)
{
- IoLooper* iol = qemu_malloc(sizeof(*iol));
+ IoLooper* iol = malloc(sizeof(*iol));
iolooper_reset(iol);
return iol;
}
@@ -29,7 +29,7 @@ iolooper_new(void)
void
iolooper_free( IoLooper* iol )
{
- qemu_free(iol);
+ free(iol);
}
void
@@ -110,7 +110,7 @@ iolooper_del_write( IoLooper* iol, int fd )
{
if (fd >= 0) {
iolooper_del_fd(iol, fd);
- FD_CLR(fd, iol->reads);
+ FD_CLR(fd, iol->writes);
}
}