From: sungmin ha Date: Tue, 30 Sep 2014 08:22:53 +0000 (+0900) Subject: web-viewer: added init and shutdown logic of nodejs and websocket X-Git-Tag: Tizen_Studio_1.3_Release_p2.3.1~228^2^2~7 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=231ecf610f13f4ca7da541c4f771165e30076aae;p=sdk%2Femulator%2Fqemu.git web-viewer: added init and shutdown logic of nodejs and websocket Change-Id: Ib9c9f99be49f6e40f51cb16506adc9d61bb66f1a Signed-off-by: sungmin ha --- diff --git a/tizen/src/emul_state.c b/tizen/src/emul_state.c index 02bdca72f6..0f47b12fd6 100644 --- a/tizen/src/emul_state.c +++ b/tizen/src/emul_state.c @@ -46,12 +46,17 @@ static EmulatorConfigInfo _emul_info = {0,}; static EmulatorConfigState _emul_state; /* misc */ +char remote_bin_path[PATH_MAX] = { 0, }; char bin_path[PATH_MAX] = { 0, }; #ifdef SUPPORT_LEGACY_ARGS // for compatibility char log_path[PATH_MAX] = { 0, }; #endif +const char *get_remote_bin_path(void) +{ + return remote_bin_path; +} const char *get_bin_path(void) { @@ -188,6 +193,12 @@ void set_emul_vm_base_port(int port) _emul_info.ecs_port = port + 3; _emul_info.serial_port = port + 4; _emul_info.spice_port = port + 5; + _emul_info.websocket_port = port + 6; +} + +int get_emul_websocket_port(void) +{ + return _emul_info.websocket_port; } int get_emul_spice_port(void) diff --git a/tizen/src/emul_state.h b/tizen/src/emul_state.h index 9e59d5bbb0..5c9d599651 100644 --- a/tizen/src/emul_state.h +++ b/tizen/src/emul_state.h @@ -96,6 +96,7 @@ typedef struct EmulatorConfigInfo { int device_serial_number; int ecs_port; int spice_port; + int websocket_port; char *vm_name; /* add here */ int serial_port; @@ -112,11 +113,13 @@ typedef struct EmulatorConfigState { } EmulatorConfigState; /* misc */ +extern char remote_bin_path[]; extern char bin_path[]; #ifdef SUPPORT_LEGACY_ARGS extern char log_path[]; #endif +char const *get_remote_bin_path(void); char const *get_bin_path(void); char const *get_log_path(void); @@ -151,6 +154,7 @@ int get_device_serial_number(void); int get_emul_ecs_port(void); int get_emul_serial_port(void); int get_emul_spice_port(void); +int get_emul_websocket_port(void); int get_emulator_condition(void); short get_emul_rotation(void); diff --git a/tizen/src/emulator.c b/tizen/src/emulator.c index 73a2544a8f..a66de955bf 100644 --- a/tizen/src/emulator.c +++ b/tizen/src/emulator.c @@ -206,6 +206,10 @@ static void prepare_basic_features(gchar * const kernel_cmdline) set_base_port(); +#if defined(CONFIG_SPICE) && defined(CONFIG_LINUX) + clean_websocket_port(SIGKILL); +#endif + check_vm_lock(); make_vm_lock(); diff --git a/tizen/src/util/osutil-linux.c b/tizen/src/util/osutil-linux.c index 53c5882276..a6884396e6 100644 --- a/tizen/src/util/osutil-linux.c +++ b/tizen/src/util/osutil-linux.c @@ -53,6 +53,9 @@ #include #include #include +#ifdef CONFIG_SPICE +#include +#endif MULTI_DEBUG_CHANNEL(emulator, osutil); @@ -173,6 +176,11 @@ void set_bin_path_os(char const *const exec_argv) g_strlcpy(bin_path, link_path, strlen(link_path) - strlen(file_name) + 1); g_strlcat(bin_path, "/", PATH_MAX); + +#ifdef CONFIG_SPICE + g_strlcpy(remote_bin_path, link_path, strlen(link_path) - strlen(file_name) - 2); + g_strlcat(remote_bin_path, "remote/bin/", PATH_MAX); +#endif } int get_number_of_processors(void) @@ -445,3 +453,209 @@ void get_host_proxy_os(char *http_proxy, char *https_proxy, char *ftp_proxy, cha } pclose(output); } + +#ifdef CONFIG_SPICE +#define PID_MAX_COUNT 256 +const char *execution_file_websocket = "websockify.py"; +const char *execution_file_node = "node"; +const char *node_proc_name = "emulator-x86-web"; + +void get_process_id(char const *process_name, char *first_param, int *pid, int *pscount) +{ + char cmdline[2048], dir_name[255]; + int total_len = 0, current_len = 0; + struct dirent *dir_entry_p; + DIR *dir_p; + FILE *fp; + char *mptr; + + dir_p = opendir("/proc/"); + while (NULL != (dir_entry_p = readdir(dir_p))) { + /* Checking for numbered directories */ + if (strspn(dir_entry_p->d_name, "0123456789") == strlen(dir_entry_p->d_name)) { + strcpy(dir_name, "/proc/"); + strcat(dir_name, dir_entry_p->d_name); + strcat(dir_name, "/cmdline"); + + fp = fopen(dir_name, "rb"); + if (fp == NULL) { + continue; + } + + total_len = 0; + memset(cmdline, 0, sizeof(cmdline)); + while (!feof(fp)) { + cmdline[total_len++] = fgetc(fp); + } + + fclose(fp); + current_len = strlen(cmdline); + mptr = cmdline; + do { + if (strstr(mptr, process_name) != NULL) { + if (!first_param || strstr(&cmdline[current_len + 1], first_param) != NULL) { + if (sizeof(pid) < *pscount + 1) { + WARN("PID array size is not enough.\n"); + return; + } + pid[*pscount] = atoi(dir_entry_p->d_name); + INFO("get_process_id(%s %s) :Found. id = %d\n", process_name, first_param, pid[*pscount]); + (*pscount)++; + } + break; + } + + mptr = &cmdline[current_len + 1]; + current_len += strlen(mptr) + 1; + } while (current_len < total_len); + } + } + + closedir(dir_p); + if (*pscount == 0) { + INFO("get_process_id(%s %s) : id = 0 (could not find process)\n", process_name, first_param); + } +} + +void execute_websocket(int port) +{ + char const *remote_bin_dir = get_remote_bin_path(); + char const *relative_path = "../websocket/"; + char websocket_path[strlen(remote_bin_dir) + strlen(execution_file_websocket) + strlen(relative_path) + 1]; + int ret = -1; + char local_port[32]; + char websocket_port[16]; + + memset(websocket_port, 0, sizeof(websocket_port)); + sprintf(websocket_port, "%d", port); + + memset(local_port, 0, sizeof(local_port)); + sprintf(local_port, "localhost:%d", get_emul_spice_port()); + + memset(websocket_path, 0, sizeof(websocket_path)); + sprintf(websocket_path, "%s%s%s", remote_bin_dir, relative_path, execution_file_websocket); + + INFO("Exec [%s %s %s]\n", websocket_path, websocket_port, local_port); + + ret = execl(websocket_path, execution_file_websocket, websocket_port, local_port, (char *)0); + if (ret == 127) { + WARN("Can't execute websocket.\n"); + } else if (ret == -1) { + WARN("Fork error!\n"); + } +} + +void execute_nodejs(void) +{ + char const *remote_bin_dir = get_remote_bin_path(); + char const *relative_path = "../web-viewer/bin/emul"; + char webviewer_script[strlen(remote_bin_dir) + strlen(relative_path) + 1]; + char nodejs_path[strlen(remote_bin_dir) + strlen(execution_file_node) + 1]; + int ret = -1; + + memset(webviewer_script, 0, sizeof(webviewer_script)); + sprintf(webviewer_script, "%s%s", remote_bin_dir, relative_path); + + memset(nodejs_path, 0, sizeof(nodejs_path)); + sprintf(nodejs_path, "%s%s", remote_bin_dir, execution_file_node); + + INFO("Exec [%s %s]\n", nodejs_path, webviewer_script); + + ret = execl(nodejs_path, execution_file_node, webviewer_script, (char *)0); + if (ret == 127) { + WARN("Can't execute node server.\n"); + } else if (ret == -1) { + WARN("Fork error!\n"); + } +} + +void clean_websocket_port(int signal) +{ + char websocket_port[16]; + memset(websocket_port, 0, sizeof(websocket_port)); + sprintf(websocket_port, "%d", get_emul_websocket_port()); + + int pscount = 0, i = 0; + int pid[PID_MAX_COUNT]; + + memset(pid, 0, PID_MAX_COUNT); + get_process_id(execution_file_websocket, websocket_port, pid, &pscount); + if (pscount > 0) { + for (i = 0; i < pscount; i++) { + INFO("Will be killed PID: %d\n", pid[i]); + kill(pid[i], signal); + } + } +} + +static void websocket_notify_exit(Notifier *notifier, void *data) +{ + clean_websocket_port(SIGTERM); +} + +static void nodejs_notify_exit(Notifier *notifier, void *data) +{ + int pscount = 0, i = 0; + int pid[PID_MAX_COUNT]; + + memset(pid, 0, sizeof(pid)); + get_process_id("spicevmc", NULL, pid, &pscount); + if (pscount == 1) { + INFO("Detected the last spice emulator.\n"); + pid[0] = 0; + pscount = 0; + get_process_id(node_proc_name, NULL, pid, &pscount); + for (i = 0; i < pscount; i++) { + INFO("Will be killed %s, PID: %d\n", node_proc_name, pid[i]); + kill(pid[i], SIGTERM); + } + } +} + +static Notifier websocket_exit = { .notify = websocket_notify_exit }; +static Notifier nodejs_exit = { .notify = nodejs_notify_exit }; + +void websocket_init(void) +{ + int pscount = 0; + char websocket_port[16]; + int pid[PID_MAX_COUNT]; + + memset(websocket_port, 0, sizeof(websocket_port)); + sprintf(websocket_port, "%d", get_emul_websocket_port()); + + memset(pid, 0, sizeof(pid)); + get_process_id(execution_file_websocket, websocket_port, pid, &pscount); + emulator_add_exit_notifier(&websocket_exit); + + if (pscount == 0) { + int pid = fork(); + if (pid == 0) { + setsid(); + execute_websocket(get_emul_websocket_port()); + } + } else { + INFO("Aleady running websokify %s localhost:%d\n", websocket_port, get_emul_spice_port()); + } +} + +void nodejs_init(void) +{ + int pscount = 0; + int pid[PID_MAX_COUNT]; + + memset(pid, 0, sizeof(pid)); + get_process_id(node_proc_name, NULL, pid, &pscount); + emulator_add_exit_notifier(&nodejs_exit); + + if (pscount == 0) { + int pid = fork(); + if (pid == 0) { + setsid(); + execute_nodejs(); + } + } else { + INFO("Aleady running node server.\n"); + } +} +#endif diff --git a/tizen/src/util/osutil.h b/tizen/src/util/osutil.h index f8858237a2..6483574228 100644 --- a/tizen/src/util/osutil.h +++ b/tizen/src/util/osutil.h @@ -74,6 +74,15 @@ void download_url(char *); size_t write_data(void *, size_t, size_t, FILE *); void remove_string(char *, char *, const char *); +#if defined(CONFIG_SPICE) && defined(CONFIG_LINUX) +void get_process_id(char const *process_name, char *first_param, int *pid, int *pscount); +void execute_websocket(int port); +void execute_nodejs(void); +void clean_websocket_port(int signal); +void nodejs_init(void); +void websocket_init(void); +#endif + static inline int get_timeofday(char *buf, size_t size) { qemu_timeval tv; diff --git a/vl.c b/vl.c index 228b817bb6..99b6614780 100644 --- a/vl.c +++ b/vl.c @@ -150,6 +150,10 @@ extern int enable_spice; static const char *yagl_backend = NULL; static int enable_vigs = 0; static char *vigs_backend = NULL; +#if defined(CONFIG_SPICE) && defined(CONFIG_LINUX) +extern void websocket_init(void); +extern void nodejs_init(void); +#endif #endif static const char *data_dir[16]; @@ -4370,6 +4374,10 @@ int main(int argc, char **argv, char **envp) qemu_mutex_lock_iothread(); #ifdef CONFIG_SPICE +#if defined(CONFIG_MARU) && defined(CONFIG_LINUX) + nodejs_init(); +#endif + /* spice needs the timers to be initialized by this point */ qemu_spice_init(); #endif @@ -4636,6 +4644,9 @@ int main(int argc, char **argv, char **envp) #ifdef CONFIG_SPICE if (using_spice) { qemu_spice_display_init(); +#if defined(CONFIG_MARU) && defined(CONFIG_LINUX) + websocket_init(); +#endif } #endif