diff options
author | Munkyu Im <munkyu.im@samsung.com> | 2017-09-17 14:42:24 +0900 |
---|---|---|
committer | Munkyu Im <munkyu.im@samsung.com> | 2017-09-17 19:18:14 +0900 |
commit | 4a241901bc06ff35c2a60225f03856fd30398f1f (patch) | |
tree | dc33b75590d629864f7d562565d967bc5310bdda | |
parent | ddee021a2f36bd58d1f596ea0f90add099a44144 (diff) | |
download | qemu-4a241901bc06ff35c2a60225f03856fd30398f1f.tar.gz qemu-4a241901bc06ff35c2a60225f03856fd30398f1f.tar.bz2 qemu-4a241901bc06ff35c2a60225f03856fd30398f1f.zip |
net: arrange base port management
This commit apply the port management of latest version.
fix error that multiple emulators connect to the same port.
qemu_socket() turns on SOCK_CLOEXEC option.
Remove unused functions.
Change-Id: Id0a9c92a24f9e364bf56ca784a5d9fd847ec5f11
Signed-off-by: Munkyu Im <munkyu.im@samsung.com>
-rw-r--r-- | tizen/src/ecs/ecs.c | 67 | ||||
-rw-r--r-- | tizen/src/emulator.c | 7 | ||||
-rw-r--r-- | tizen/src/util/sdb.c | 202 | ||||
-rw-r--r-- | tizen/src/util/sdb.h | 22 |
4 files changed, 82 insertions, 216 deletions
diff --git a/tizen/src/ecs/ecs.c b/tizen/src/ecs/ecs.c index 65722175f5..f1426472d8 100644 --- a/tizen/src/ecs/ecs.c +++ b/tizen/src/ecs/ecs.c @@ -633,68 +633,17 @@ static int ecs_loop(ECS_State *cs) #endif -static int ecs_socket_listen(int port) -{ - struct sockaddr_in addr; - int slisten = -1; - int ret = -1; - - addr.sin_family = AF_INET; - addr.sin_port = htons(port); - - ret = inet_aton(HOST_LISTEN_ADDR, &addr.sin_addr); - if (ret == 0) { - ERR("inet_aton failure\n"); - return -1; - } - - slisten = qemu_socket(PF_INET, SOCK_STREAM, 0); - if (slisten < 0) { - ERR("socket creation failed.\n"); - return slisten; - } +static int socket_initialize(ECS_State *cs) { + LOG_INFO("Listen fd is %d\n", emul_vm_base_socket); + g_assert(emul_vm_base_socket >= 0); - ret = socket_set_fast_reuse(slisten); - if (ret != 0) { - ERR("It cannot be reach here.\n"); - closesocket(slisten); - return -1; - } - - if (bind(slisten, (struct sockaddr *)&addr, sizeof(addr)) < 0) { - ERR("bind failed : %d\n", errno); - closesocket(slisten); - return -1; - } - - if (listen(slisten,1) != 0) { - ERR("listen failed : %d\n", errno); - closesocket(slisten); - return -1; - } - - return slisten; -} - -static int socket_initialize(ECS_State *cs, int port) { - int fd = -1; - - fd = ecs_socket_listen(port); - if (fd < 0) { - return -1; - } - - INFO("Listen fd is %d\n", fd); - - qemu_set_nonblock(fd); - - cs->listen_fd = fd; + cs->listen_fd = emul_vm_base_socket; #ifdef CONFIG_LINUX epoll_init(cs); #else FD_ZERO(&cs->reads); - FD_SET(fd, &cs->reads); + FD_SET(cs->listen_fd, &cs->reads); #endif make_keep_alive_msg(); @@ -711,7 +660,6 @@ static void* ecs_initialize(void* args) { int ret = 1; ECS_State *cs = NULL; Monitor* mon = NULL; - int port = 0; INFO("ecs starts initializing.\n"); @@ -725,10 +673,7 @@ static void* ecs_initialize(void* args) { } cs->listen_fd = -1; - - port = get_emul_ecs_port(); - - ret = socket_initialize(cs, port); + ret = socket_initialize(cs); if (ret < 0) { ERR("Socket initialization is failed.\n"); ecs_close(cs); diff --git a/tizen/src/emulator.c b/tizen/src/emulator.c index aa397c673e..e140d69019 100644 --- a/tizen/src/emulator.c +++ b/tizen/src/emulator.c @@ -188,13 +188,10 @@ static void prepare_basic_features(gchar * const kernel_cmdline) socks_proxy[PROXY_BUFFER_LEN] = { 0, }, dns[PROXY_BUFFER_LEN] = { 0, }; - set_base_port(); - #if defined(CONFIG_SPICE) && defined(CONFIG_LINUX) clean_websocket_port(SIGKILL); #endif - get_host_proxy(http_proxy, https_proxy, ftp_proxy, socks_proxy); /* using "DNS" provided by default QEMU */ g_strlcpy(dns, DEFAULT_QEMU_DNS_IP, strlen(DEFAULT_QEMU_DNS_IP) + 1); @@ -272,6 +269,8 @@ const char *prepare_maru(const gchar * const kernel_cmdline) /* Prepare basic features */ LOG_INFO("Prepare_basic_features\n"); + init_sdb_and_vm_base_port(); + prepare_basic_features(maru_kernel_cmdline); /* Prepare GL acceleration */ @@ -289,8 +288,6 @@ void prepare_maru_after_device_init(void) { maru_device_hotplug_init(); start_ecs(); - start_sdb_noti_server(get_device_serial_number() + SDB_UDP_SENSOR_INDEX); - sdb_setup(); } #if defined(CONFIG_SDL) || defined(CONFIG_USE_SHM) diff --git a/tizen/src/util/sdb.c b/tizen/src/util/sdb.c index 9dbc775973..f4f72272cb 100644 --- a/tizen/src/util/sdb.c +++ b/tizen/src/util/sdb.c @@ -46,179 +46,97 @@ MULTI_DEBUG_CHANNEL(qemu, sdb); -#ifdef _WIN32 -#include "qemu/main-loop.h" - -static void socket_close_handler( void* _fd ) -{ - int fd = (int)_fd; - int ret; - char buff[64]; - - /* we want to drain the read side of the socket before closing it */ - do { - ret = recv( fd, buff, sizeof(buff), 0 ); - } while (ret < 0 && WSAGetLastError() == WSAEINTR); - - if (ret < 0 && WSAGetLastError() == EWOULDBLOCK) - return; - - qemu_set_fd_handler( fd, NULL, NULL, NULL ); - closesocket( fd ); -} - -void socket_close( int fd ) -{ - int old_errno = errno; - - shutdown( fd, SD_BOTH ); - /* we want to drain the socket before closing it */ - qemu_set_fd_handler( fd, socket_close_handler, NULL, (void*)fd ); - - errno = old_errno; -} - -#else /* !_WIN32 */ - -#include <unistd.h> +#define BUF_SIZE 64 -void socket_close( int fd ) -{ - int old_errno = errno; - - shutdown( fd, SHUT_RDWR ); - close( fd ); - - errno = old_errno; -} - -#endif /* !_WIN32 */ - -int inet_strtoip(const char* str, uint32_t *ip) -{ - int comp[4]; - - if (sscanf(str, "%d.%d.%d.%d", &comp[0], &comp[1], &comp[2], &comp[3]) != 4) - return -1; - - if ((unsigned)comp[0] >= 256 || - (unsigned)comp[1] >= 256 || - (unsigned)comp[2] >= 256 || - (unsigned)comp[3] >= 256) - return -1; - - *ip = (uint32_t)((comp[0] << 24) | (comp[1] << 16) | - (comp[2] << 8) | comp[3]); - return 0; -} +int emul_vm_base_socket; int check_port_bind_listen(uint32_t port) { struct sockaddr_in addr; - int s = 0; int ret = -1; - socklen_t addrlen = sizeof(addr); - memset(&addr, 0, addrlen); - addr.sin_family = AF_INET; - addr.sin_addr.s_addr = htonl(INADDR_ANY); addr.sin_port = htons(port); + addr.sin_addr.s_addr = INADDR_ANY; - s = qemu_socket(AF_INET, SOCK_STREAM, 0); - if (s < 0) { - INFO("failed to create a socket\n"); + ret = qemu_socket(PF_INET, SOCK_STREAM, 0); + if (ret < 0) { + LOG_SEVERE("socket creation failed.\n"); return -1; } -#ifndef _WIN32 - int opt = 1; - ret = setsockopt(s, SOL_SOCKET, SO_REUSEADDR, - (char *)&opt, sizeof(int)); - if (ret < 0) { - INFO("setsockopt failure\n"); - close(s); + qemu_set_nonblock(ret); + + if (socket_set_fast_reuse(ret) != 0) { + LOG_SEVERE("It cannot be reach here.\n"); + closesocket(ret); return -1; } -#endif - if ((bind(s, (struct sockaddr *)&addr, sizeof(addr)) < 0) || - (listen(s, 1) < 0)) { - /* failure */ - ret = -1; - INFO("port(%d) listen failure\n", port); - } else { - /* success */ - ret = 1; - INFO("port(%d) listen success\n", port); + if (bind(ret, (struct sockaddr *)&addr, sizeof(addr)) != 0) { + LOG_INFO("bind failed for port: %d, errno: %d\n", port, errno); + closesocket(ret); + return -1; } -#ifdef _WIN32 - closesocket(s); -#else - close(s); -#endif + if (listen(ret, 1) != 0) { + LOG_SEVERE("listen failed :%s-%d\n", strerror(errno), errno); + closesocket(ret); + return -1; + } return ret; } -#define ECS_INDEX 3 -void set_base_port(void) +static int prepare_network_port(uint32_t base_port) { - int tries = 10; - int success = 0; - uint32_t port = 26100; - int base_port; - - base_port = get_emul_vm_base_port(); - - if(base_port == 0){ - - for ( ; tries > 0; tries--, port += 10 ) { - if (check_port_bind_listen(port + ECS_INDEX) < 0) - continue; + int ret = -1; + char buf[64] = {0,}; + if ((ret = check_port_bind_listen(base_port + ECS_TCP_INDEX)) < 0) { + LOG_INFO("TCP port %"PRIu32" is aleady occupied.\n", + base_port + ECS_TCP_INDEX); - success = 1; - break; - } + return -1; + } - if (!success) { - INFO( "it seems too many emulator instances are running on this machine. Aborting\n" ); - exit(1); - } + g_assert(ret >= 0); - base_port = port; - INFO( "sdb port is %d\n", base_port); + sprintf(buf, "tcp:%d::26101", base_port + SDB_TCP_INDEX); + if (net_slirp_redir((char*)buf) < 0) { + LOG_WARNING("failed to redirect rule %s", buf); + return -1; } + // save ecs socket fd as global variable + // FIXME: should not use global variable. + emul_vm_base_socket = ret; - set_emul_vm_base_port(base_port); + return ret; } -void sdb_setup(void) -{ - int tries = 10; - int success = 0; - char buf[64] = {0,}; - int number; +static void start_sdb_noti_server(int server_port); - number = get_device_serial_number(); +void init_sdb_and_vm_base_port(void) +{ + uint32_t port = -1; - for ( ; tries > 0; tries--, number += 10 ) { - sprintf(buf, "tcp:%d::26101", number); - if(net_slirp_redir((char*)buf) < 0) + for (port = START_VM_BASE_PORT ; port < END_VM_BASE_PORT; port += 10) { + if (prepare_network_port(port) < 0) { continue; + } - INFO( "SDBD established on port %d\n", number); - success = 1; break; } - INFO("redirect [%s] success\n", buf); - if (!success) { - INFO( "it seems too many emulator instances are running on this machine. Aborting\n" ); + if (port >= END_VM_BASE_PORT) { + error_report("It seems too many emulator instances are " + "running on this machine. Aborting."); exit(1); } + LOG_INFO("Emulator base port is %"PRIu32".\n", port); + + start_sdb_noti_server(port + SDB_UDP_NOTI_PORT_INDEX); + start_sdb_noti_server(port + SDB_UDP_SENSOR_INDEX); - INFO( "Port(%d/tcp) listen for SDB\n", number); + set_emul_vm_base_port(port); } /* @@ -266,10 +184,10 @@ static void send_to_sdb_client(SDB_Client* client, int state) struct sockaddr_in sock_addr; int s, slen = sizeof(sock_addr); int serial_len = 0; - char buf [64]; + char buf[BUF_SIZE]; - if ((s = socket(AF_INET, SOCK_STREAM, 0)) == -1){ - INFO("socket creation error! %d\n", errno); + if ((s = qemu_socket(AF_INET, SOCK_STREAM, 0)) == -1){ + LOG_INFO("socket creation error! %d\n", errno); return; } @@ -280,9 +198,9 @@ static void send_to_sdb_client(SDB_Client* client, int state) sock_addr.sin_addr = (client->addr).sin_addr; if (connect(s, (struct sockaddr*)&sock_addr, slen) == -1) { - INFO("connect error! remove this client.\n"); + LOG_INFO("connect error! remove this client.\n"); remove_sdb_client(client); - close(s); + closesocket(s); return; } @@ -293,15 +211,15 @@ static void send_to_sdb_client(SDB_Client* client, int state) // send message "[4 digit message length]host:sync:emulator-26101:[0|1]" sprintf(buf, "%04xhost:sync:%s:%01d", (serial_len + 12), client->serial, state); - INFO("send %s to client %s\n", buf, inet_ntoa(client->addr.sin_addr)); + LOG_INFO("send %s to client %s\n", buf, inet_ntoa(client->addr.sin_addr)); if (send(s, buf, sizeof(buf), 0) == -1) { - INFO("send error! remove this client.\n"); + LOG_INFO("send error! remove this client.\n"); remove_sdb_client(client); } - close(s); + closesocket(s); } void notify_all_sdb_clients(int state) diff --git a/tizen/src/util/sdb.h b/tizen/src/util/sdb.h index 7be0ee3914..bfa9bbf33d 100644 --- a/tizen/src/util/sdb.h +++ b/tizen/src/util/sdb.h @@ -48,18 +48,24 @@ #define SDB_HOST_PORT 26099 -#define SDB_TCP_EMULD_INDEX 2 /* emulator daemon port */ -#define SDB_TCP_OPENGL_INDEX 3 /* opengl server port */ -#define SDB_UDP_SENSOR_INDEX 2 /* sensor server port */ +#define START_VM_BASE_PORT 26100 +#define END_VM_BASE_PORT 26200 -void sdb_setup(void); -void set_base_port(void); -int inet_strtoip(const char* str, uint32_t *ip); +#define SDB_TCP_INDEX 1 +#define GDB_TCP_INDEX 2 +#define ECS_TCP_INDEX 3 +#define SPICE_TCP_INDEX 3 +#define SDB_UDP_SENSOR_INDEX 2 +#define SDB_UDP_NOTI_PORT_INDEX 3 + +#define SDB_GUEST_PORT (START_VM_BASE_PORT + SDB_TCP_INDEX) +#define GDB_GUEST_PORT (START_VM_BASE_PORT + GDB_TCP_INDEX) + +void init_sdb_and_vm_base_port(void); int socket_send(int fd, const void* buf, int buflen); void socket_close(int fd); int check_port_bind_listen(uint32_t port); - -void start_sdb_noti_server(int server_port); +extern int emul_vm_base_socket; #define STATE_RUNNING 0 #define STATE_SUSPEND 1 |