sdcard: Add lock/unlock
authorMunkyu Im <munkyu.im@samsung.com>
Fri, 12 Sep 2014 07:53:42 +0000 (16:53 +0900)
committerMunkyu Im <munkyu.im@samsung.com>
Fri, 12 Sep 2014 08:04:47 +0000 (17:04 +0900)
Add file lock to avoid multiple mount/umount.

Change-Id: I583f14e0d7667d722fb84ef86650625bc8789138
Signed-off-by: Munkyu Im <munkyu.im@samsung.com>
tizen/src/ecs/ecs_msg.c
tizen/src/osutil-darwin.c
tizen/src/osutil-linux.c
tizen/src/osutil-win32.c
tizen/src/osutil.h

index 69dcc127f8087dcccb140cf859150d06fc8ae3e5..bc6c21b3ef1bb449fd05ac8bebb7c5e91d02084b 100644 (file)
@@ -79,10 +79,10 @@ MULTI_DEBUG_CHANNEL(qemu, ecs);
 static int guest_connection = 0;
 extern QemuMutex mutex_guest_connection;
 extern QemuMutex mutex_location_data;
-
+static bool is_sdcard_attached = false;
 static char location_data[MAX_INJECTOR_REQ_DATA];
 /*static function define*/
-static void handle_sdcard(char* dataBuf, size_t dataLen);
+static bool handle_sdcard(char* dataBuf, size_t dataLen);
 static char* get_emulator_sdcard_path(void);
 static char *get_old_tizen_sdk_data_path(void);
 
@@ -163,6 +163,46 @@ static bool send_to_single_client(ECS__Master* master, ECS_Client *ccli)
 }
 #endif
 
+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);
+
+    if (status_msg)
+        free(status_msg);
+}
+
 static void send_status_injector_ntf(const char* cmd, int cmdlen, int act, char* on)
 {
     int msglen = 0, datalen = 0;
@@ -295,8 +335,9 @@ bool msgproc_injector_req(ECS_Client* ccli, ECS__InjectorReq* msg)
     if (!strcmp(cmd, MSG_TYPE_SDCARD)) {
         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");
         }
@@ -366,11 +407,11 @@ injector_send:
     }
 
     if(strcmp(cmd, "telephony") == 0) {
-       TRACE("telephony msg >>");
-       ret = send_to_vmodem(route_ij, sndbuf, sndlen);
+        TRACE("telephony msg >>");
+        ret = send_to_vmodem(route_ij, sndbuf, sndlen);
     } else {
-       TRACE("evdi msg >> %s", cmd);
-       ret = send_to_evdi(route_ij, sndbuf, sndlen);
+        TRACE("evdi msg >> %s", cmd);
+        ret = send_to_evdi(route_ij, sndbuf, sndlen);
     }
 
 
@@ -729,7 +770,7 @@ static bool injector_req_handle(const char* cat, type_action action)
 {
     /*SD CARD msg process*/
     if (!strcmp(cat, MSG_TYPE_SDCARD)) {
-       return false;
+        return false;
 
     } else if (!strcmp(cat, "suspend")) {
         ecs_suspend_lock_state(ecs_get_suspend_state());
@@ -912,19 +953,56 @@ bool send_nfc_ntf(struct nfc_msg_info* msg)
     return true;
 }
 
-static void handle_sdcard(char* dataBuf, size_t dataLen)
+static bool handle_sdcard(char* dataBuf, size_t dataLen)
 {
-
+    int err_no = 0;
     char ret = 0;
-
-    if (dataBuf != NULL){
+    INFO("handle_sdcard() data: %s\n", dataBuf);
+    if (dataBuf != NULL) {
         ret = dataBuf[0];
 
         if (ret == '0' ) {
             /* umount sdcard */
             //mloop_evcmd_usbdisk(NULL);
-            mloop_evcmd_sdcard(NULL);
-        } else if (ret == '1') {
+            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));
+                    INFO("sdcard path: [%s]\n", sdcard_img_path);
+
+                    /*if using strndup than free string*/
+                    if (pLinechange != NULL && sdcard_img_name!= NULL) {
+                        free(sdcard_img_name);
+                    }
+                }
+                g_free(sdcard_path);
+
+            }
+            err_no = remove_sdcard_lock_os(sdcard_img_path);
+            INFO("umount err_no: %d\n", err_no);
+            if (errno == 0 && is_sdcard_attached) {
+                mloop_evcmd_sdcard(NULL);
+                is_sdcard_attached = false;
+            } 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;
+            }
+        }
+        else if (ret == '1') {
             /* mount sdcard */
             char sdcard_img_path[256];
             char* sdcard_path = NULL;
@@ -936,7 +1014,7 @@ static void handle_sdcard(char* dataBuf, size_t dataLen)
 
                 /* emulator_sdcard_img_path + sdcard img name */
                 char* sdcard_img_name = dataBuf+2;
-                if(dataLen > 3 && sdcard_img_name != NULL){
+                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);
@@ -946,10 +1024,15 @@ static void handle_sdcard(char* dataBuf, size_t dataLen)
                     TRACE("sdcard path: [%s]\n", sdcard_img_path);
 
                     //mloop_evcmd_usbdisk(sdcard_img_path);
-                    mloop_evcmd_sdcard(sdcard_img_path);
-
+                    if (make_sdcard_lock_os(sdcard_img_path) && !is_sdcard_attached) {
+                        mloop_evcmd_sdcard(sdcard_img_path);
+                        is_sdcard_attached = true;
+                    } else {
+                        send_gen_injector_ntf(MSG_TYPE_SDCARD, 6, 11, 5, NULL);
+                        return ERR_LCK;
+                    }
                     /*if using strndup than free string*/
-                    if(pLinechange != NULL && sdcard_img_name!= NULL){
+                    if (pLinechange != NULL && sdcard_img_name!= NULL) {
                         free(sdcard_img_name);
                     }
 
@@ -959,15 +1042,16 @@ static void handle_sdcard(char* dataBuf, size_t dataLen)
             } else {
                 ERR("failed to get sdcard path!!\n");
             }
-        } else if(ret == '2'){
+        } else if (ret == '2') {
             TRACE("sdcard status 2 bypass\n" );
-        }else {
+        } else {
             ERR("!!! unknown command : %c\n", ret);
         }
 
-    }else{
+    } else {
         ERR("!!! unknown data : %c\n", ret);
     }
+    return ERR_SUCCESS;
 }
 
 static char* get_emulator_sdcard_path(void)
index 76736198159f7fe93a2b924b74af59e19886dc00..d5edfe5c78638115c4b06e13b615a3b2547eefbb 100644 (file)
@@ -390,3 +390,72 @@ void get_host_proxy_os(char *http_proxy, char *https_proxy, char *ftp_proxy, cha
         }
     }
 }
+
+static int fd_isopen(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);
+}
+
+bool make_sdcard_lock_os(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_isopen(fd) == -1)
+    {
+        perror("file is lock ");
+        return false;
+    }
+    INFO("Get file lock: %s\n", lock_file);
+    return true;
+
+}
+
+int remove_sdcard_lock_os(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 ");
+        return ERR_UNLCK;
+    }
+    unlink(lock_file);
+    INFO("unlock success: %s\n", lock_file);
+    return ERR_SUCCESS;
+}
+
index c6b3e67c2c8410881818214db8be7bd4a3501c5c..e00fcecd21aba220fad7d3537ff5d0ffbeea039e 100644 (file)
@@ -45,7 +45,6 @@
 #ifndef CONFIG_LINUX
 #error
 #endif
-
 #include <string.h>
 #include <unistd.h>
 #include <sys/shm.h>
@@ -150,6 +149,74 @@ void make_vm_lock_os(void)
     }
 }
 
+static int fd_isopen(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);
+}
+
+bool make_sdcard_lock_os(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_isopen(fd) == -1)
+    {
+        perror("file is lock ");
+        return false;
+    }
+    INFO("Get file lock: %s\n", lock_file);
+    return true;
+
+}
+
+int remove_sdcard_lock_os(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 ");
+        return ERR_UNLCK;
+    }
+    unlink(lock_file);
+    INFO("unlock success: %s\n", lock_file);
+    return ERR_SUCCESS;
+}
+
 void set_bin_path_os(gchar * exec_argv)
 {
     gchar link_path[PATH_MAX] = { 0, };
index 9403c2678a96b5bad8a254c4c01493555863f010..28997fdf9b917328a5afc6b510be43df8962aa99 100644 (file)
@@ -54,8 +54,9 @@ MULTI_DEBUG_CHANNEL (emulator, osutil);
 static qemu_timeval tv = { 0, 0 };
 static time_t ti;
 static char buf_time[64];
-
 extern char tizen_target_img_path[];
+HANDLE g_hFile;
+static char g_sdcard[256] = {0,};
 
 static const char *pactempfile = ".autoproxy";
 
@@ -282,7 +283,7 @@ void get_host_proxy_os(char *http_proxy, char *https_proxy, char *ftp_proxy, cha
     if (nRet != ERROR_SUCCESS) {
         ERR("Failed to open registry from %s\n",
                 "Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings");
-        return 0;
+        return;
     }
     //check auto proxy key exists
     lRet = RegQueryValueEx(hKey, "AutoConfigURL", 0, NULL, NULL, &dwLength);
@@ -302,7 +303,7 @@ void get_host_proxy_os(char *http_proxy, char *https_proxy, char *ftp_proxy, cha
             if (lRet == ERROR_SUCCESS && dwLength != 0) {
                 get_auto_proxy(url, http_proxy, https_proxy, ftp_proxy, socks_proxy);
                 RegCloseKey(hKey);
-                return 0;
+                return;
             }
         }
     }
@@ -312,13 +313,13 @@ void get_host_proxy_os(char *http_proxy, char *https_proxy, char *ftp_proxy, cha
         ERR(stderr, "Failed to query value from %s\n",
                 "Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings\\ProxyEnable");
         RegCloseKey(hKey);
-        return 0;
+        return;
     }
     proxyenable = (BYTE*)malloc(dwLength);
     if (proxyenable == NULL) {
         ERR( "Failed to allocate a buffer\n");
         RegCloseKey(hKey);
-        return 0;
+        return;
     }
 
     lRet = RegQueryValueEx(hKey, "ProxyEnable", 0, NULL, proxyenable, &dwLength);
@@ -327,12 +328,12 @@ void get_host_proxy_os(char *http_proxy, char *https_proxy, char *ftp_proxy, cha
         ERR("Failed to query value from %s\n",
                 "Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings\\ProxyEnable");
         RegCloseKey(hKey);
-        return 0;
+        return;
     }
     if (*(char*)proxyenable == 0) {
         free(proxyenable);
         RegCloseKey(hKey);
-        return 0;
+        return;
     }
 
     dwLength = 0;
@@ -341,14 +342,14 @@ void get_host_proxy_os(char *http_proxy, char *https_proxy, char *ftp_proxy, cha
         ERR("Failed to query value from from %s\n",
                 "Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings");
         RegCloseKey(hKey);
-        return 0;
+        return;
     }
 
     proxyserver = (BYTE*)malloc(dwLength);
     if (proxyserver == NULL) {
         ERR( "Failed to allocate a buffer\n");
         RegCloseKey(hKey);
-        return 0;
+        return;
     }
 
     memset(proxyserver, 0x00, dwLength);
@@ -358,7 +359,7 @@ void get_host_proxy_os(char *http_proxy, char *https_proxy, char *ftp_proxy, cha
         ERR( "Failed to query value from from %s\n",
                 "Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings");
         RegCloseKey(hKey);
-        return 0;
+        return;
     }
 
     if((char*)proxyserver != NULL) {
@@ -394,7 +395,90 @@ void get_host_proxy_os(char *http_proxy, char *https_proxy, char *ftp_proxy, cha
     }
     else {
         INFO("proxy is null\n");
-        return 0;
+        return;
     }
     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;
+    }
+       g_hFile = hFile;
+       strncpy(g_sdcard, sdcard, strlen(sdcard));
+    INFO("Get file lock: %s\n", lock_file);
+    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");
+            CloseHandle(g_hFile);
+            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);
+    CloseHandle(g_hFile);
+    INFO("unlock success: %s\n", lock_file);
+    return ERR_SUCCESS;
+
+}
+
+
index 80f34fa925982484324a00f74bf0400c7d645a16..27721e306b0a4b80247e062d9f1b518386d815b4 100644 (file)
 #define GCONFTOOL 0
 #define GSETTINGS 1
 
-extern const char *pac_tempfile; 
+#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);
+bool make_sdcard_lock_os(char *sdcard);
+int remove_sdcard_lock_os(char *sdcard);
 
 void set_bin_path_os(gchar *);