Do private mount temporarily for OSP-compatible applications 82/14082/1
authorHyunbin Lee <hyunbin.lee@samsung.com>
Wed, 27 Nov 2013 10:09:44 +0000 (19:09 +0900)
committerHyunbin Lee <hyunbin.lee@samsung.com>
Mon, 23 Dec 2013 06:45:42 +0000 (15:45 +0900)
Change-Id: I9ddc95edcb9c17575c5c0abe9c23d540c533ca50
Signed-off-by: Hyunbin Lee <hyunbin.lee@samsung.com>
inc/FIo_MmcStorageManagerService.h
src/FIo_MmcStorageManagerService.cpp

index 6d18e02..8f3576e 100644 (file)
@@ -81,6 +81,10 @@ private:
 
        static int GetMmcblockNumber(void);
 
+       static result FindDeviceNode(const char *pPath, char* pBuf, int bufLen);
+
+       static result ChangeMountMode(unsigned long mountFlags);
+
 private:
        static _MmcStorageManagerService* __pMmcStorageManagerService;
        _IMmcStorageManagerServiceListener* __pStub;
index 82f3511..4ea9407 100644 (file)
  * @brief      This is the implementation for the _MmcStorageManagerService class.
  */
 
+#include <stdio.h>
 #include <unistd.h>
 #include <sys/mount.h>
 #include <sys/types.h>
 #include <dirent.h>
 #include <sys/stat.h>
 #include <fcntl.h>
+#include <mntent.h>
 #include <errno.h>
 #include <unique_ptr.h>
 #include <sysman_managed.h>
@@ -206,6 +208,7 @@ _MmcStorageManagerService::MmcEventVconfCallback(keynode_t* node, void* userData
        char srcPath[_MAX_EXT_SRC_DIR_COUNT][_MAX_PATH_LENGTH];
        char destPath[_MAX_EXT_DEST_DIR_COUNT][_MAX_PATH_LENGTH];
        bool compat = false;
+       result r = E_SUCCESS;
 
        SysLog(NID_IO, "MMC event occurs.");
 
@@ -213,7 +216,6 @@ _MmcStorageManagerService::MmcEventVconfCallback(keynode_t* node, void* userData
        {
                int value = 0;
                int res = vconf_get_int(VCONFKEY_SYSMAN_MMC_STATUS, &value);
-               result r = E_SUCCESS;
 
                _MmcStorageManagerService* pMmcMgr = static_cast< _MmcStorageManagerService* >(userData);
                _AppList::const_iterator iter;
@@ -268,6 +270,9 @@ _MmcStorageManagerService::MmcEventVconfCallback(keynode_t* node, void* userData
                                                        SysTryReturnVoidResult(NID_IO, !IsFailed(r), E_SYSTEM, "[%s] Failed to create external directories.",
                                                                        GetErrorMessage(r));
 
+                                                       r = ChangeMountMode(MS_PRIVATE);
+                                                       SysTryCatch(NID_IO, !IsFailed(r), , E_SYSTEM, "[E_SYSTEM] Changing to private mount mode is failed.");
+
                                                        for (int i = 1; i < _MAX_EXT_DIR_MOUNT_COUNT; ++i)
                                                        {
                                                                if (i == 1)
@@ -290,12 +295,15 @@ _MmcStorageManagerService::MmcEventVconfCallback(keynode_t* node, void* userData
                                                                {
                                                                        SysLog(NID_IO, "srcPath[%d]: %s, destPath[%d]: %s", i, srcPath[i], i, destPath[i]);
 
-                                                                       res = mount(srcPath[i], destPath[i], null, MS_BIND, null);
+                                                                       res = mount(srcPath[i], destPath[i], null, MS_BIND | MS_PRIVATE, null);
                                                                        SysTryCatch(NID_IO, res == 0, , E_SYSTEM, "[E_SYSTEM] Failed to mount (%s, %s), errno: %d (%s)",
                                                                                        srcPath[i], destPath[i], errno, strerror(errno));
                                                                }
                                                        }
 
+                                                       r = ChangeMountMode(MS_SHARED);
+                                                       SysTryCatch(NID_IO, !IsFailed(r), , E_SYSTEM, "[E_SYSTEM] Changing to shared mount mode is failed.");
+
                                                        r = _MmcStorageManagerService::CreateFlag(mountFlag);
                                                        SysTryCatch(NID_IO, !IsFailed(r), , E_SYSTEM, "[%s] Failed to create mount flag (%s)",
                                                                        GetErrorMessage(r), mountFlag);
@@ -382,6 +390,9 @@ _MmcStorageManagerService::MmcEventVconfCallback(keynode_t* node, void* userData
                                        if (access(pAppRootPath.get(), F_OK) == 0)
                                        {
                                                // /opt/storage/sdcard -> {app-root}/virtual-root/opt/storage/sdcard
+
+                                               r = ChangeMountMode(MS_PRIVATE);
+                                               SysTryCatch(NID_IO, !IsFailed(r), , E_SYSTEM, "[E_SYSTEM] Changing to private mount mode is failed.");
 #ifdef _OSP_EMUL_
                                                int mmcblkNum = GetMmcblockNumber();
                                                SysTryLog(NID_IO, mmcblkNum >= 0, "Failed to get mmcblk number");
@@ -392,10 +403,12 @@ _MmcStorageManagerService::MmcEventVconfCallback(keynode_t* node, void* userData
                                                res = mount("/dev/mmcblk1p1", pDestPath.get(), "vfat", 0,
                                                                "uid=0,gid=0,dmask=0000,fmask=0111,iocharset=iso8859-1,utf8,shortname=mixed,smackfsroot=*,smackfsdef=*");
 #endif
-
                                                SysTryReturnVoidResult(NID_IO, res == 0, E_SYSTEM, "[E_SYSTEM] Failed to mount (%s), errno: %d (%s)",
                                                                pDestPath.get(), errno, strerror(errno));
 
+                                               r = ChangeMountMode(MS_SHARED);
+                                               SysTryCatch(NID_IO, !IsFailed(r), , E_SYSTEM, "[E_SYSTEM] Changing to shared mount mode is failed.");
+
                                                SysLog(NID_IO, "mount() succeeded");
                                        }
                                }
@@ -427,11 +440,18 @@ CATCH:
        {
                for (int i = _MAX_EXT_DIR_MOUNT_COUNT; i >= 0; --i)
                {
-                       int res = umount2(destPath[i], MNT_DETACH);
-                       SysTryLog(NID_IO, res == 0 || errno == EINVAL || errno == ENOENT,
+                       int ret = umount2(destPath[i], MNT_DETACH);
+                       SysTryLog(NID_IO, ret == 0 || errno == EINVAL || errno == ENOENT,
                                        "[E_SYSTEM] Failed to unmount (%s), errno: %d (%s)", destPath[i], errno, strerror(errno));
                }
        }
+
+       r = ChangeMountMode(MS_SHARED);
+       if (IsFailed(r))
+       {
+               SysLogException(NID_IO, E_SYSTEM, "[E_SYSTEM] Restoring mount mode is failed.");
+       }
+
        return;
 }
 
@@ -561,5 +581,70 @@ _MmcStorageManagerService::GetMmcblockNumber(void)
        return mmcblkNum;
 }
 
+result
+_MmcStorageManagerService::FindDeviceNode(const char *pPath, char* pBuf, int bufLen)
+{
+       const char table[] = "/etc/mtab";
+       struct mntent ent;
+       bool found = false;
+
+       SysTryReturnResult(NID_IO, strlen(pPath) < PATH_MAX, E_INVALID_ARG,
+                       "The specified pPath (%s) is too long. length: %d", pPath, strlen(pPath));
+
+       FILE* pFile = setmntent(table, "r");
+       SysTryReturnResult(NID_IO, pFile != null, E_SYSTEM, "Calling setmntent() with %s failed.", table);
+
+       while (getmntent_r(pFile, &ent, pBuf, bufLen))
+       {
+               //SysLog(NID_IO, "path: %s, device node: %s", ent.mnt_dir, pBuf);
+               if (strncmp(ent.mnt_dir, pPath, strlen(pPath)) == 0)
+               {
+                       found = true;
+                       break;
+               }
+       }
+
+       endmntent(pFile);
+
+       SysTryReturnResult(NID_IO, found == true, E_OBJ_NOT_FOUND, "Device node does not exist. path: %s", pPath);
+
+       return E_SUCCESS;
+}
+
+result
+_MmcStorageManagerService::ChangeMountMode(unsigned long mountFlags)
+{
+       char devNode[PATH_MAX] = { 0, };
+       static const char dir[][32] =
+       {
+               { "/opt/storage/sdcard" }
+       };
+
+       for (int i = 0; i < sizeof(dir)/32; ++i)
+       {
+               //SysLog(NID_IO, "dir: %s", dir[i]);
+               result r = FindDeviceNode(dir[i], devNode, PATH_MAX - 1);
+               if (r == E_SUCCESS)
+               {
+                       int ret = mount(devNode, dir[i], NULL, mountFlags, NULL);
+                       SysTryReturnResult(NID_IO, ret == 0, E_SYSTEM, "Changing mount mode failed. ret: %d, errno: %d (%s)",
+                                       ret, errno, strerror(errno));
+               }
+               else if (r == E_OBJ_NOT_FOUND)
+               {
+                       continue;
+               }
+               else
+               {
+                       SysLogException(NID_IO, E_SYSTEM, "[E_SYSTEM] Finding device node failed.");
+                       return E_SYSTEM;
+               }
+
+               memset(devNode, '\0', PATH_MAX);
+       }
+
+       return E_SUCCESS;
+}
+
 }} // Tizen::Io