From 146ee5c274d301613e1dfea88528d8127cba0909 Mon Sep 17 00:00:00 2001 From: "munkyu.im" Date: Wed, 7 Mar 2012 14:18:28 +0900 Subject: [PATCH] [Title]add sdb [Type] [Module] [Priority] [CQ#] [Redmine#] [Problem] [Cause] [Solution] [TestCase] --- Makefile.target | 1 + sdb.c | 351 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ sdb.h | 112 ++++++++++++++++++ tizen/src/ui | 2 +- 4 files changed, 465 insertions(+), 1 deletion(-) create mode 100644 sdb.c create mode 100644 sdb.h diff --git a/Makefile.target b/Makefile.target index 9a29741..dad29d4 100755 --- a/Makefile.target +++ b/Makefile.target @@ -202,6 +202,7 @@ obj-$(CONFIG_VIRTIO) += virtio.o virtio-blk.o virtio-balloon.o virtio-net.o virt obj-y += vhost_net.o obj-$(CONFIG_VHOST_NET) += vhost.o obj-$(CONFIG_REALLY_VIRTFS) += 9pfs/virtio-9p-device.o +obj-y += sdb.o obj-$(CONFIG_KVM) += kvm.o kvm-all.o obj-$(CONFIG_NO_KVM) += kvm-stub.o obj-y += memory.o diff --git a/sdb.c b/sdb.c new file mode 100644 index 0000000..ecfe59b --- /dev/null +++ b/sdb.c @@ -0,0 +1,351 @@ +/* Copyright (C) 2006-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. +*/ + + +#ifdef _WIN32 +#include +#include +#include +#else /* !_WIN32 */ +#include +#include +#include +#include +#include +#endif /* !_WIN32 */ + +#include "net/slirp.h" +#include "qemu_socket.h" +#include "sdb.h" +#include "nbd.h" +#include "tizen/src/debug_ch.h" + +//DEFAULT_DEBUG_CHANNEL(qemu); +MULTI_DEBUG_CHANNEL(qemu, sdb); + +/* QSOCKET_CALL is used to deal with the fact that EINTR happens pretty + * easily in QEMU since we use SIGALRM to implement periodic timers + */ + +#ifdef _WIN32 +# define QSOCKET_CALL(_ret,_cmd) \ + do { _ret = (_cmd); } while ( _ret < 0 && WSAGetLastError() == WSAEINTR ) +#else +# define QSOCKET_CALL(_ret,_cmd) \ + do { \ + errno = 0; \ + do { _ret = (_cmd); } while ( _ret < 0 && errno == EINTR ); \ + } while (0); +#endif + +#ifdef _WIN32 + +#include + +static int winsock_error; + +#define WINSOCK_ERRORS_LIST \ + EE(WSA_INVALID_HANDLE,EINVAL,"invalid handle") \ +EE(WSA_NOT_ENOUGH_MEMORY,ENOMEM,"not enough memory") \ +EE(WSA_INVALID_PARAMETER,EINVAL,"invalid parameter") \ +EE(WSAEINTR,EINTR,"interrupted function call") \ +EE(WSAEALREADY,EALREADY,"operation already in progress") \ +EE(WSAEBADF,EBADF,"bad file descriptor") \ +EE(WSAEACCES,EACCES,"permission denied") \ +EE(WSAEFAULT,EFAULT,"bad address") \ +EE(WSAEINVAL,EINVAL,"invalid argument") \ +EE(WSAEMFILE,EMFILE,"too many opened files") \ +EE(WSAEWOULDBLOCK,EWOULDBLOCK,"resource temporarily unavailable") \ +EE(WSAEINPROGRESS,EINPROGRESS,"operation now in progress") \ +EE(WSAEALREADY,EAGAIN,"operation already in progress") \ +EE(WSAENOTSOCK,EBADF,"socket operation not on socket") \ +EE(WSAEDESTADDRREQ,EDESTADDRREQ,"destination address required") \ +EE(WSAEMSGSIZE,EMSGSIZE,"message too long") \ +EE(WSAEPROTOTYPE,EPROTOTYPE,"wrong protocol type for socket") \ +EE(WSAENOPROTOOPT,ENOPROTOOPT,"bad protocol option") \ +EE(WSAEADDRINUSE,EADDRINUSE,"address already in use") \ +EE(WSAEADDRNOTAVAIL,EADDRNOTAVAIL,"cannot assign requested address") \ +EE(WSAENETDOWN,ENETDOWN,"network is down") \ +EE(WSAENETUNREACH,ENETUNREACH,"network unreachable") \ +EE(WSAENETRESET,ENETRESET,"network dropped connection on reset") \ +EE(WSAECONNABORTED,ECONNABORTED,"software caused connection abort") \ +EE(WSAECONNRESET,ECONNRESET,"connection reset by peer") \ +EE(WSAENOBUFS,ENOBUFS,"no buffer space available") \ +EE(WSAEISCONN,EISCONN,"socket is already connected") \ +EE(WSAENOTCONN,ENOTCONN,"socket is not connected") \ +EE(WSAESHUTDOWN,ESHUTDOWN,"cannot send after socket shutdown") \ +EE(WSAETOOMANYREFS,ETOOMANYREFS,"too many references") \ +EE(WSAETIMEDOUT,ETIMEDOUT,"connection timed out") \ +EE(WSAECONNREFUSED,ECONNREFUSED,"connection refused") \ +EE(WSAELOOP,ELOOP,"cannot translate name") \ +EE(WSAENAMETOOLONG,ENAMETOOLONG,"name too long") \ +EE(WSAEHOSTDOWN,EHOSTDOWN,"host is down") \ +EE(WSAEHOSTUNREACH,EHOSTUNREACH,"no route to host") \ + +typedef struct { + int winsock; + int unix; + const char* string; +} WinsockError; + +static const WinsockError _winsock_errors[] = { +#define EE(w,u,s) { w, u, s }, + WINSOCK_ERRORS_LIST +#undef EE + { -1, -1, NULL } +}; + +/* this function reads the latest winsock error code and updates + * errno to a matching value. It also returns the new value of + * errno. + */ +static int _fix_errno( void ) +{ + const WinsockError* werr = _winsock_errors; + int unix = EINVAL; /* generic error code */ + + winsock_error = WSAGetLastError(); + + for ( ; werr->string != NULL; werr++ ) { + if (werr->winsock == winsock_error) { + unix = werr->unix; + break; + } + } + errno = unix; + return -1; +} + +#else +static int _fix_errno( void ) +{ + return -1; +} + +#endif + +#define SOCKET_CALL(cmd) \ + int ret; \ +QSOCKET_CALL(ret, (cmd)); \ +if (ret < 0) \ +return _fix_errno(); \ +return ret; \ + +int socket_send(int fd, const void* buf, int buflen) +{ + SOCKET_CALL(send(fd, buf, buflen, 0)) +} + +#ifdef _WIN32 + + 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 + + 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; +} + +static int check_port_bind_listen(u_int port) +{ + struct sockaddr_in addr; + int s, opt = 1; + int ret = -1; + socklen_t addrlen = sizeof(addr); + memset(&addr, 0, addrlen); + + addr.sin_family = AF_INET; + addr.sin_addr.s_addr = INADDR_ANY; + addr.sin_port = htons(port); + + if (((s = qemu_socket(AF_INET,SOCK_STREAM,0)) < 0) || + (bind(s,(struct sockaddr *)&addr, sizeof(addr)) < 0) || + (setsockopt(s,SOL_SOCKET,SO_REUSEADDR,(char *)&opt,sizeof(int)) < 0) || + (listen(s,1) < 0)) { + + /* fail */ + ret = -1; + ERR( "port(%d) listen fail \n", port); + }else{ + /*fsucess*/ + ret = 1; + INFO( "port(%d) listen ok \n", port); + } + +#ifdef _WIN32 + closesocket(s); +#else + close(s); +#endif + + return ret; +} + +int get_sdb_base_port(void) +{ + int tries = 10; + int success = 0; + u_int port = 26100; + + if(tizen_base_port == 0){ + + for ( ; tries > 0; tries--, port += 10 ) { + if(check_port_bind_listen(port+1) < 0 ) + continue; + + success = 1; + break; + } + + if (!success) { + ERR( "it seems too many emulator instances are running on this machine. Aborting\n" ); + exit(1); + } + + tizen_base_port = port; + INFO( "sdb port is %d \n", tizen_base_port); + } + + return tizen_base_port; +} + +void sdb_setup(void) +{ + int tries = 10; + const char *base_port = "26100"; + int success = 0; + int s; + int port; + uint32_t guest_ip; + const char *p; + char buf[64] = {0,}; + + inet_strtoip("10.0.2.16", &guest_ip); + + port = strtol(base_port, (char **)&p, 0); + + for ( ; tries > 0; tries--, port += 10 ) { + // redir form [tcp:26100:10.0.2.16:26101] + sprintf(buf, "tcp:%d:10.0.2.16:26101", port+1); + if(net_slirp_redir((char*)buf) < 0) + continue; + + // fprintf(stdout,"SDBD established on port %d\n", port+1); + success = 1; + break; + } + + INFO("redirect [%s] success\n", buf); + if (!success) { + ERR( "it seems too many emulator instances are running on this machine. Aborting\n" ); + exit(1); + } + + if( tizen_base_port != port ){ + ERR( "sdb port is miss match. Aborting\n" ); + exit(1); + } + + /* Save base port. */ + tizen_base_port = port; + INFO( "Port(%d/tcp) listen for SDB \n", tizen_base_port + 1); + + /* for sensort */ + sprintf(buf, "tcp:%d:10.0.2.16:3577", get_sdb_base_port() + SDB_TCP_EMULD_INDEX ); + if(net_slirp_redir((char*)buf) < 0){ + ERR( "redirect [%s] fail \n", buf); + }else{ + INFO("redirect [%s] success\n", buf); + } + + /* send a simple message to the SDB host server to tell it we just started. + * it should be listening on port 26099. if we can't reach it, don't bother + */ + do + { + char tmp[32] = {0}; + + s = tcp_socket_outgoing("127.0.0.1", SDB_HOST_PORT); + if (s < 0) { + INFO("can't create socket to talk to the SDB server \n"); + INFO("This emulator will be scaned by the SDB server \n"); + break; + } + + /* length is hex: 0x13 = 19 */ + sprintf(tmp,"0013host:emulator:%d",port+1); + socket_send(s, tmp, 30); + + } + while (0); + + if (s >= 0) + socket_close(s); +} diff --git a/sdb.h b/sdb.h new file mode 100644 index 0000000..c4ec1fb --- /dev/null +++ b/sdb.h @@ -0,0 +1,112 @@ +/* Copyright (C) 2006-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. +*/ + +#include +#include +#include + +#define SDB_HOST_PORT 26099 + +#ifdef _WIN32 +# ifndef EINTR +# define EINTR 10004 +# endif +# ifndef EAGAIN +# define EAGAIN 10035 +# endif +# ifndef EWOULDBLOCK +# define EWOULDBLOCK EAGAIN +# endif +# ifndef EINPROGRESS +# define EINPROGRESS 10036 +# endif +# ifndef EALREADY +# define EALREADY 10037 +# endif +# ifndef EDESTADDRREQ +# define EDESTADDRREQ 10039 +# endif +# ifndef EMSGSIZE +# define EMSGSIZE 10040 +# endif +# ifndef EPROTOTYPE +# define EPROTOTYPE 10041 +# endif +# ifndef ENOPROTOOPT +# define ENOPROTOOPT 10042 +# endif +# ifndef EAFNOSUPPORT +# define EAFNOSUPPORT 10047 +# endif +# ifndef EADDRINUSE +# define EADDRINUSE 10048 +# endif +# ifndef EADDRNOTAVAIL +# define EADDRNOTAVAIL 10049 +# endif +# ifndef ENETDOWN +# define ENETDOWN 10050 +# endif +# ifndef ENETUNREACH +# define ENETUNREACH 10051 +# endif +# ifndef ENETRESET +# define ENETRESET 10052 +# endif +# ifndef ECONNABORTED +# define ECONNABORTED 10053 +# endif +# ifndef ECONNRESET +# define ECONNRESET 10054 +# endif +# ifndef ENOBUFS +# define ENOBUFS 10055 +# endif +# ifndef EISCONN +# define EISCONN 10056 +# endif +# ifndef ENOTCONN +# define ENOTCONN 10057 +# endif +# ifndef ESHUTDOWN +# define ESHUTDOWN 10058 +# endif +# ifndef ETOOMANYREFS +# define ETOOMANYREFS 10059 +# endif +# ifndef ETIMEDOUT +# define ETIMEDOUT 10060 +# endif +# ifndef ECONNREFUSED +# define ECONNREFUSED 10061 +# endif +# ifndef ELOOP +# define ELOOP 10062 +# endif +# ifndef EHOSTDOWN +# define EHOSTDOWN 10064 +# endif +# ifndef EHOSTUNREACH +# define EHOSTUNREACH 10065 +# endif +#endif /* _WIN32 */ + +#define SDB_TCP_EMULD_INDEX 3 /* emulator daemon port */ +#define SDB_TCP_OPENGL_INDEX 4 /* opengl server port */ + +#define SDB_UDP_SENSOR_INDEX 3 /* sensor server port */ +extern int tizen_base_port; +void sdb_setup(void); +int get_sdb_base_port(void); +int inet_strtoip(const char* str, uint32_t *ip); +int socket_send(int fd, const void* buf, int buflen); +void socket_close(int fd); diff --git a/tizen/src/ui b/tizen/src/ui index 79c0092..a3a66ec 160000 --- a/tizen/src/ui +++ b/tizen/src/ui @@ -1 +1 @@ -Subproject commit 79c009238dd60dfdb70f9da0e47d18a77cd66675 +Subproject commit a3a66ec0b2cf218e640fc79a2adc092371406b5f -- 2.7.4