sdcard: Allow only one attach for the same sdcard image 85/29185/6
authorMunkyu Im <munkyu.im@samsung.com>
Wed, 22 Oct 2014 09:45:38 +0000 (18:45 +0900)
committerMunkyu Im <munkyu.im@samsung.com>
Fri, 24 Oct 2014 05:11:17 +0000 (14:11 +0900)
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 <munkyu.im@samsung.com>
tizen/src/ecs/ecs_msg_injector.c
tizen/src/util/osutil-darwin.c
tizen/src/util/osutil-linux.c
tizen/src/util/osutil-win32.c
tizen/src/util/osutil.c
tizen/src/util/osutil.h

index 6f7f6e78b81e423a85e914966abd369e75010f23..1d20de1ccc94e99f1b47b40318256f14defec420 100644 (file)
@@ -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)
index 56913ae436fcda35c2bedc8b644f39ff5a4c5e29..9c86f1efb5d5d9885764da41f5fe104374b301df 100644 (file)
@@ -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);
+}
index a6884396e69736cf64e55a5d5ab75dc011dc164d..c4139f60b7e5b29fb8f4d261dbffe29dffdbd9fd 100644 (file)
@@ -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);
+}
index eea34dc945362f60f244695ed21f8621f6041428..bd07447651fe48d9482f086c880dbd72015ef77c 100644 (file)
@@ -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;
+
+}
index 3bcaf20193729de4fd6fcabf3c4074e16db52d99..d0780e9a297800efa7f3e86da2974a0e68590af9 100644 (file)
@@ -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
index 64835742284a247a641c8e56bdde7bd9c2c75ec2..2997a78bebec969418ee631cc48469969c95e883 100644 (file)
 #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);