From: Munkyu Im Date: Wed, 22 Oct 2014 09:45:38 +0000 (+0900) Subject: sdcard: Allow only one attach for the same sdcard image X-Git-Tag: Tizen_Studio_1.3_Release_p2.3.2~629^2~30^2 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=9a99b3f67e5b15814c0df4a4ae83d055641bd1d3;p=sdk%2Femulator%2Fqemu.git sdcard: Allow only one attach for the same sdcard image Implemented file locking when attach/detach sdcard. During one user attach a image, other user cannot attach it. Change-Id: I6f0a971c8114048412583acc3daec0f7ac6dc965 Signed-off-by: Munkyu Im --- diff --git a/tizen/src/ecs/ecs_msg_injector.c b/tizen/src/ecs/ecs_msg_injector.c index 6f7f6e78b8..1d20de1ccc 100644 --- a/tizen/src/ecs/ecs_msg_injector.c +++ b/tizen/src/ecs/ecs_msg_injector.c @@ -38,6 +38,7 @@ #include "emul_state.h" #include "ecs.h" #include "debug_ch.h" +#include "util/osutil.h" MULTI_DEBUG_CHANNEL(qemu, ecs); @@ -46,6 +47,44 @@ static int guest_connection = 0; extern QemuMutex mutex_location_data; static char location_data[MAX_INJECTOR_REQ_DATA]; +static void send_gen_injector_ntf(const char* cmd, int cmdlen, int grp, int act, char* on) +{ + int msglen = 0, datalen = 0; + type_length length = 0; + type_group group = grp; + type_action action = act; + + if (cmd == NULL || cmdlen > 10) + return; + + if (on == NULL) { + msglen = 14; + } else { + datalen = strlen(on); + length = (unsigned short)datalen; + + msglen = datalen + 15; + } + + char* status_msg = (char*) malloc(msglen); + if(!status_msg) + return; + + memset(status_msg, 0, msglen); + + memcpy(status_msg, cmd, cmdlen); + memcpy(status_msg + 10, &length, sizeof(unsigned short)); + memcpy(status_msg + 12, &group, sizeof(unsigned char)); + memcpy(status_msg + 13, &action, sizeof(unsigned char)); + + if (on != NULL) { + memcpy(status_msg + 14, on, datalen); + } + + send_injector_ntf(status_msg, msglen); + + free(status_msg); +} static void msgproc_injector_ans(ECS_Client* ccli, const char* category, bool succeed) { @@ -291,9 +330,36 @@ char *get_tizen_sdk_data_path(void) return get_old_tizen_sdk_data_path(); } -static void handle_sdcard(char* dataBuf, size_t dataLen) -{ +static char* get_sdcard_img_path(char* sdcard_img_name, size_t dataLen) { + char* sdcard_img_path = NULL; + char* sdcard_path = NULL; + if (sdcard_img_name == NULL || dataLen < 3) { + return NULL; + } + dataLen = dataLen - 3; + if (sdcard_img_name[dataLen] == '\n') { + sdcard_img_name[dataLen] = '\0'; + TRACE("sdcard_img_name: %s\n", sdcard_img_name); + } else { + ERR("wrong sdcard message!\n"); + return NULL; + } + sdcard_path = get_emulator_sdcard_path(); + if (sdcard_path != NULL) { + sdcard_img_path = g_malloc(DEFAULTBUFLEN); + g_strlcpy(sdcard_img_path, sdcard_path, DEFAULTBUFLEN); + g_strlcat(sdcard_img_path, sdcard_img_name, DEFAULTBUFLEN); + TRACE("sdcard img path: [%s] length: %d\n", sdcard_img_path, strlen(sdcard_img_path)); + g_free(sdcard_path); + return sdcard_img_path; + } + return NULL; +} + +static int handle_sdcard(char* dataBuf, size_t dataLen) +{ + int err_no = 0; char ret = 0; if (dataBuf != NULL){ @@ -301,57 +367,48 @@ static void handle_sdcard(char* dataBuf, size_t dataLen) if (ret == '0' ) { /* umount sdcard */ - do_hotplug(DETACH_SDCARD, NULL, 0); + char* sdcard_img_path = get_sdcard_img_path(dataBuf + 2, dataLen); + err_no = remove_sdcard_lock_os(sdcard_img_path); + if (errno == 0 && is_sdcard_attached()) { + do_hotplug(DETACH_SDCARD, NULL, 0); + } else { + ERR("failed to umount: %s\n", sdcard_img_path); + send_gen_injector_ntf(MSG_TYPE_SDCARD, 6, 11, err_no, NULL); + return err_no; + } + g_free(sdcard_img_path); } else if (ret == '1') { /* mount sdcard */ - char sdcard_img_path[256]; - char* sdcard_path = NULL; - - sdcard_path = get_emulator_sdcard_path(); - if (sdcard_path) { - g_strlcpy(sdcard_img_path, sdcard_path, - sizeof(sdcard_img_path)); - - /* emulator_sdcard_img_path + sdcard img name */ - char* sdcard_img_name = dataBuf+2; - if(dataLen > 3 && sdcard_img_name != NULL){ - char* pLinechange = strchr(sdcard_img_name, '\n'); - if(pLinechange != NULL){ - sdcard_img_name = g_strndup(sdcard_img_name, pLinechange - sdcard_img_name); - } - - g_strlcat(sdcard_img_path, sdcard_img_name, sizeof(sdcard_img_path)); - TRACE("sdcard path: [%s]\n", sdcard_img_path); - - do_hotplug(ATTACH_SDCARD, sdcard_img_path, strlen(sdcard_img_path) + 1); - - /*if using strndup than free string*/ - if(pLinechange != NULL && sdcard_img_name!= NULL){ - free(sdcard_img_name); - } - - } - - g_free(sdcard_path); + char* sdcard_img_path = get_sdcard_img_path(dataBuf + 2, dataLen); + if ( !is_sdcard_attached() && make_sdcard_lock_os(sdcard_img_path)) { + do_hotplug(ATTACH_SDCARD, sdcard_img_path, strlen(sdcard_img_path) + 1); + send_gen_injector_ntf(MSG_TYPE_SDCARD, 6, 11, 0, NULL); } else { - ERR("failed to get sdcard path!!\n"); + send_gen_injector_ntf(MSG_TYPE_SDCARD, 6, 11, 5, NULL); + return ERR_LCK; } - } else if(ret == '2'){ - TRACE("sdcard status 2 bypass" ); - }else { + g_free(sdcard_img_path); + + } else if (ret == '2') { + TRACE("sdcard status 2 bypass\n" ); + } else { ERR("!!! unknown command : %c\n", ret); + return ret; } - - }else{ + } else { ERR("!!! unknown data : %c\n", ret); + return ret; } + return ERR_SUCCESS; } static bool injector_req_sdcard(ECS_Client* ccli, ECS__InjectorReq* msg, char *cmd) { if (msg->has_data) { TRACE("msg(%zu) : %s\n", msg->data.len, msg->data.data); - handle_sdcard((char*) msg->data.data, msg->data.len); + if (handle_sdcard((char*) msg->data.data, msg->data.len) > 0) { + return false; + } } else { ERR("has no msg\n"); } @@ -397,8 +454,7 @@ static void send_status_injector_ntf(const char* cmd, int cmdlen, int act, char* send_injector_ntf(status_msg, msglen); - if (status_msg) - free(status_msg); + free(status_msg); } static bool injector_req_sensor(ECS_Client* ccli, ECS__InjectorReq* msg, char *cmd) diff --git a/tizen/src/util/osutil-darwin.c b/tizen/src/util/osutil-darwin.c index 56913ae436..9c86f1efb5 100644 --- a/tizen/src/util/osutil-darwin.c +++ b/tizen/src/util/osutil-darwin.c @@ -381,3 +381,13 @@ void get_host_proxy_os(char *http_proxy, char *https_proxy, char *ftp_proxy, cha } } } + +bool make_sdcard_lock_os(char *sdcard) +{ + return make_sdcard_lock_posix(sdcard); +} + +int remove_sdcard_lock_os(char *sdcard) +{ + return remove_sdcard_lock_posix(sdcard); +} diff --git a/tizen/src/util/osutil-linux.c b/tizen/src/util/osutil-linux.c index a6884396e6..c4139f60b7 100644 --- a/tizen/src/util/osutil-linux.c +++ b/tizen/src/util/osutil-linux.c @@ -659,3 +659,14 @@ void nodejs_init(void) } } #endif + +bool make_sdcard_lock_os(char *sdcard) +{ + return make_sdcard_lock_posix(sdcard); +} + + +int remove_sdcard_lock_os(char *sdcard) +{ + return remove_sdcard_lock_posix(sdcard); +} diff --git a/tizen/src/util/osutil-win32.c b/tizen/src/util/osutil-win32.c index eea34dc945..bd07447651 100644 --- a/tizen/src/util/osutil-win32.c +++ b/tizen/src/util/osutil-win32.c @@ -55,6 +55,8 @@ static HANDLE g_hMapFile; static char *g_pBuf; extern char tizen_target_img_path[]; +static char g_sdcard[256] = {0,}; +static sdcard_info info; static const char *pactempfile = ".autoproxy"; @@ -387,3 +389,89 @@ void get_host_proxy_os(char *http_proxy, char *https_proxy, char *ftp_proxy, cha free(proxyserver); RegCloseKey(hKey); } + +bool make_sdcard_lock_os(char *sdcard) +{ + char *lock_file = g_strdup_printf("%s.lck", sdcard); + + HANDLE hFile = CreateFile(lock_file, GENERIC_READ, + 0, + NULL, + CREATE_ALWAYS, + FILE_ATTRIBUTE_NORMAL, + NULL); + + if (hFile == INVALID_HANDLE_VALUE) { + ERR("file open error : (%d)\n", GetLastError()); + if(GetLastError() == 32) { + if(strcmp(g_sdcard, sdcard) == 0) { + INFO("try to mount same sdcard!\n"); + } + return false; + } + return true; + } + INFO("Get file lock: %s\n", lock_file); + strncpy(g_sdcard, sdcard, strlen(sdcard)); + info.handle = hFile; + return true; + +} + +int remove_sdcard_lock_os(char *sdcard) +{ + char *lock_file = g_strdup_printf("%s.lck", sdcard); + HANDLE hFile2; + BOOL fSuccess; + hFile2 = CreateFile(lock_file, GENERIC_READ, + 0, + NULL, + OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL, + NULL); + + if (hFile2 == INVALID_HANDLE_VALUE) { + ERR("CreateFile() error : (%d)\n", GetLastError()); + if (GetLastError() == 32) { + if (strncmp(g_sdcard, sdcard, strlen(sdcard)) != 0) { + INFO("not same sdcard!!!\n"); + return ERR_UNLCK; + } + + INFO("return ERR_SUCCESS\n"); + g_sdcard[0] = '\0'; + fSuccess = DeleteFile(lock_file); + if (!fSuccess) { + // Handle the error. + ERR("DeleteFile failed (%d)\n", GetLastError()); + return ERR_UNLCK; + } + return ERR_SUCCESS; + } + return ERR_NOENT; + } + + hFile2 = CreateFile(lock_file, GENERIC_READ, + 0, + NULL, + CREATE_ALWAYS, + FILE_ATTRIBUTE_NORMAL, + NULL); + + if (hFile2 == INVALID_HANDLE_VALUE) { + ERR("CreateFile() error : (%d)\n", GetLastError()); + return ERR_UNLCK; + } + CloseHandle(hFile2); + fSuccess = DeleteFile(lock_file); + if (!fSuccess) { + // Handle the error. + ERR("DeleteFile failed (%d)\n", GetLastError()); + return ERR_UNLCK; + } + INFO("unlock success: %s\n", lock_file); + CloseHandle(info.handle); + + return ERR_SUCCESS; + +} diff --git a/tizen/src/util/osutil.c b/tizen/src/util/osutil.c index 3bcaf20193..d0780e9a29 100644 --- a/tizen/src/util/osutil.c +++ b/tizen/src/util/osutil.c @@ -43,6 +43,7 @@ MULTI_DEBUG_CHANNEL(emulator, osutil); +static sdcard_info info; const char *pac_tempfile = ".autoproxy"; inline size_t write_data(void *ptr, size_t size, size_t nmemb, FILE *stream) @@ -96,3 +97,83 @@ inline void remove_string(char *src, char *dst, const char *toremove) dst[j] = '\0'; } + +#ifndef CONFIG_WIN32 +static int fd_lock(int fd) +{ + struct flock lock; + + lock.l_type = F_WRLCK; + lock.l_start = 0; + lock.l_whence = SEEK_SET; + lock.l_len = 0; + lock.l_pid = getpid(); + + return fcntl(fd, F_SETLK, &lock); +} + +static int fd_unlock(int fd) +{ + struct flock lock; + + lock.l_type = F_UNLCK; + lock.l_start = 0; + lock.l_whence = SEEK_SET; + lock.l_len = 0; + + return fcntl(fd, F_SETLK, &lock); +} + +inline bool make_sdcard_lock_posix(char *sdcard) +{ + char *lock_file = g_strdup_printf("%s.lck", sdcard); + int fd = open(lock_file, O_CREAT|O_RDWR, 0666); + if (fd == -1) + { + perror("file open error : "); + return false; + } + if (fd_lock(fd) == -1) + { + perror("file is lock "); + close(fd); + return false; + } + info.fd = fd; + INFO("Get file lock: %s\n", lock_file); + return true; +} + +inline int remove_sdcard_lock_posix(char *sdcard) +{ + errno = 0; + char *lock_file = g_strdup_printf("%s.lck", sdcard); + int fd = open(lock_file, O_RDWR, 0666); + if (fd == -1) + { + perror("file open error : "); + if(errno == ENOENT) { + return ERR_NOENT; + } + return ERR_UNLCK; + } + + if (fd_unlock(fd) == -1) + { + perror("file unlock error "); + close(fd); + return ERR_UNLCK; + } + + if (unlink(lock_file) < 0) { + perror("unlink error "); + close(fd); + return ERR_UNLCK; + } + + INFO("unlock success: %s\n", lock_file); + close(fd); + close(info.fd); + return ERR_SUCCESS; +} +#endif diff --git a/tizen/src/util/osutil.h b/tizen/src/util/osutil.h index 6483574228..2997a78beb 100644 --- a/tizen/src/util/osutil.h +++ b/tizen/src/util/osutil.h @@ -58,13 +58,35 @@ #define GCONFTOOL 0 #define GSETTINGS 1 +#define ERR_SUCCESS 0 +#define ERR_UNLCK 4 +#define ERR_LCK 5 +#define ERR_NOENT 6 + extern const char *pac_tempfile; void check_vm_lock_os(void); void make_vm_lock_os(void); void remove_vm_lock_os(void); +bool make_sdcard_lock_os(char *sdcard); +int remove_sdcard_lock_os(char *sdcard); void set_bin_path_os(char const *const); +typedef struct sdcard_info +{ +#ifndef CONFIG_WIN32 + int fd; +#else + HANDLE handle; +#endif + char* lock_file; /* reserved for future use */ +}sdcard_info; + + +#ifndef CONFIG_WIN32 +bool make_sdcard_lock_posix(char *sdcard); +int remove_sdcard_lock_posix(char *sdcard); +#endif void print_system_info_os(void);