Dynamically find mmcblk number and remove memory leak
authorHyunbin Lee <hyunbin.lee@samsung.com>
Thu, 11 Jul 2013 05:36:55 +0000 (14:36 +0900)
committerHyunbin Lee <hyunbin.lee@samsung.com>
Wed, 14 Aug 2013 06:19:18 +0000 (15:19 +0900)
Change-Id: Ia09d1dd9a5a4711ffa145288edaa0155bdb115a0
Signed-off-by: Hyunbin Lee <hyunbin.lee@samsung.com>
inc/FIo_MmcStorageManagerService.h
src/FApp_ContextManager.cpp
src/FIo_MmcStorageManagerService.cpp

index 3bc70c9..6d18e02 100644 (file)
@@ -33,7 +33,7 @@
 
 #include <FBaseObject.h>
 #include <FBaseString.h>
-#include <FBaseColLinkedList.h>
+#include <FBaseColHashMap.h>
 #include <FAppTypes.h>
 
 #include <FApp_ContextManager.h>
@@ -79,10 +79,13 @@ private:
 
        static result CreateExternalDirectories(const char srcPath[][_MAX_PATH_LENGTH], const char destPath[][_MAX_PATH_LENGTH]);
 
+       static int GetMmcblockNumber(void);
+
+private:
        static _MmcStorageManagerService* __pMmcStorageManagerService;
        _IMmcStorageManagerServiceListener* __pStub;
        _AppList __appList;
-       Tizen::Base::Collection::LinkedList* __pVirtualRootList;
+       Tizen::Base::Collection::HashMap* __pVirtualRootList;
        friend class Tizen::App::_ContextManager;
 };
 
index 6ca6c09..8aa8626 100755 (executable)
@@ -198,7 +198,7 @@ _ContextManager::Register(const PackageId& pkgId, const String& executableName,
        if (GetLastResult() == E_SUCCESS && virtualRoot == true)
        {
                _MmcStorageManagerService* pMmcMgr = _MmcStorageManagerService::GetInstance();
-               pMmcMgr->__pVirtualRootList->Add(new (std::nothrow) String(appRoot));
+               pMmcMgr->__pVirtualRootList->Add(new (std::nothrow) String(pkgId), new (std::nothrow) String(appRoot));
                SysLog(NID_APP, "Virtual root application (%ls) is registered.", pkgId.GetPointer());
        }
 
index 7c8d664..10659ca 100644 (file)
@@ -22,6 +22,7 @@
 #include <unistd.h>
 #include <sys/mount.h>
 #include <sys/types.h>
+#include <dirent.h>
 #include <sys/stat.h>
 #include <fcntl.h>
 #include <errno.h>
@@ -29,6 +30,7 @@
 #include <sysman_managed.h>
 #include <vconf.h>
 
+#include <FBaseInteger.h>
 #include <FIoFile.h>
 #include <FIoDirectory.h>
 #include <FIoMmcStorageManager.h>
@@ -123,7 +125,8 @@ _MmcStorageManagerService::_MmcStorageManagerService(void)
        : __pStub(null)
        , __pVirtualRootList(null)
 {
-       __pVirtualRootList = new (std::nothrow) LinkedList(SingleObjectDeleter);
+       __pVirtualRootList = new (std::nothrow) HashMap(SingleObjectDeleter);
+       __pVirtualRootList->Construct();
 }
 
 _MmcStorageManagerService::~_MmcStorageManagerService(void)
@@ -270,7 +273,11 @@ _MmcStorageManagerService::MmcEventVconfCallback(keynode_t* node, void* userData
                                                                {
                                                                        SysLog(NID_IO, "destPath[%d]: %s", i, destPath[i]);
 #ifdef _OSP_EMUL_
-                                                                       res = mount("/dev/mmcblk0", destPath[i], "ext4", 0, "");
+                                                                       int mmcblkNum = GetMmcblockNumber();
+                                                                       SysTryLog(NID_IO, mmcblkNum >= 0, "Failed to get mmcblk number");
+                                                                       char devPath[_MAX_PATH_LENGTH] = { 0, };
+                                                                       sprintf(devPath, "/dev/mmcblk%d", mmcblkNum);
+                                                                       res = mount(devPath, destPath[i], "ext4", 0, "");
 #else
                                                                        res = mount("/dev/mmcblk1p1", destPath[i], "vfat", 0,
                                                                                        "uid=0,gid=0,dmask=0000,fmask=0111,iocharset=iso8859-1,utf8,shortname=mixed,smackfsroot=*,smackfsdef=*");
@@ -336,11 +343,12 @@ _MmcStorageManagerService::MmcEventVconfCallback(keynode_t* node, void* userData
                }
 
                // Checks virtual root application
-               IEnumerator* pEnum = pMmcMgr->__pVirtualRootList->GetEnumeratorN();
+               IMapEnumerator* pEnum = pMmcMgr->__pVirtualRootList->GetMapEnumeratorN();
                while (pEnum->MoveNext() == E_SUCCESS)
                {
                        compat = false;
-                       const String* pAppRoot = static_cast< String* >(pEnum->GetCurrent());
+                       const String* pPkgId = static_cast< String* >(pEnum->GetKey());
+                       const String* pAppRoot = static_cast< String* >(pEnum->GetValue());
                        if (pAppRoot != null)
                        {
                                std::unique_ptr< char[] > pAppRootPath(_StringConverter::CopyToCharArrayN(*pAppRoot));
@@ -352,49 +360,28 @@ _MmcStorageManagerService::MmcEventVconfCallback(keynode_t* node, void* userData
                                std::unique_ptr< char[] > pDestPath(_StringConverter::CopyToCharArrayN(destPath));
                                SysTryReturnVoidResult(NID_IO, pDestPath != null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
 
-                               char* pPkgId = strrchr(pAppRootPath.get(), '/');
-                               char mountFlag[_MAX_PATH_LENGTH] = { 0, };
-                               sprintf(mountFlag, "%s/%s", _EXTERNAL_MOUNT_FLAG, ++pPkgId);
-
                                if (value == 1)
                                {
                                        SysLog(NID_IO, "MMC mount event for virtual root application.");
 
-                                       res = access(mountFlag, F_OK);
-                                       if (res == -1 && errno == ENOENT)
+                                       if (access(pAppRootPath.get(), F_OK) == 0)
                                        {
-                                               if (access(pAppRootPath.get(), F_OK) == 0)
-                                               {
-                                                       // /opt/storage/sdcard -> {app-root}/virtual-root/opt/storage/sdcard
+                                               // /opt/storage/sdcard -> {app-root}/virtual-root/opt/storage/sdcard
 #ifdef _OSP_EMUL_
-                                                       res = mount("/dev/mmcblk0", pDestPath.get(), "ext4", 0, "");
+                                               int mmcblkNum = GetMmcblockNumber();
+                                               SysTryLog(NID_IO, mmcblkNum >= 0, "Failed to get mmcblk number");
+                                               char devPath[_MAX_PATH_LENGTH] = { 0, };
+                                               sprintf(devPath, "/dev/mmcblk%d", mmcblkNum);
+                                               res = mount(devPath, pDestPath.get(), "ext4", 0, "");
 #else
-                                                       res = mount("/dev/mmcblk1p1", pDestPath.get(), "vfat", 0,
-                                                                       "uid=0,gid=0,dmask=0000,fmask=0111,iocharset=iso8859-1,utf8,shortname=mixed,smackfsroot=*,smackfsdef=*");
+                                               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));
+                                               SysTryReturnVoidResult(NID_IO, res == 0, E_SYSTEM, "[E_SYSTEM] Failed to mount (%s), errno: %d (%s)",
+                                                               pDestPath.get(), errno, strerror(errno));
 
-                                                       r = _MmcStorageManagerService::CreateFlag(mountFlag);
-                                                       if (IsFailed(r))
-                                                       {
-                                                               SysLogException(NID_IO, E_SYSTEM, "[%s] Failed to create mount flag (%s)",
-                                                                               GetErrorMessage(r), mountFlag);
-                                                               res = umount2(pDestPath.get(), MNT_DETACH);
-                                                       }
-                                                       SysLog(NID_IO, "mount() succeeded, mount flag: %s", mountFlag);
-                                               }
-                                       }
-                                       else if (res == -1)
-                                       {
-                                               SysLogException(NID_IO, E_SYSTEM, "[E_SYSTEM] Failed to access mount flag (%s), errno: %d (%s)",
-                                                               mountFlag, errno, strerror(errno));
-                                               return;
-                                       }
-                                       else
-                                       {
-                                               SysLog(NID_IO, "mount() was already done.");
+                                               SysLog(NID_IO, "mount() succeeded");
                                        }
                                }
                                else
@@ -405,22 +392,16 @@ _MmcStorageManagerService::MmcEventVconfCallback(keynode_t* node, void* userData
                                        SysTryLog(NID_IO, res == 0 || errno == EINVAL || errno == ENOENT,
                                                        "[E_SYSTEM] Failed to unmount (%s), errno: %d (%s)", pDestPath.get(), errno, strerror(errno));
 
-                                       if (access(mountFlag, F_OK) == 0)
-                                       {
-                                               res = unlink(mountFlag);
-                                               SysTryReturnVoidResult(NID_IO, res == 0, E_SYSTEM, "[E_SYSTEM] Failed to remove mount flag (%s), errno: %d (%s)",
-                                                               mountFlag, errno, strerror(errno));
-                                       }
-
                                        if (access(pAppRootPath.get(), F_OK) != 0 && errno == ENOENT)
                                        {
-                                               pMmcMgr->__pVirtualRootList->Remove(*pAppRoot);
+                                               pMmcMgr->__pVirtualRootList->Remove(*pPkgId);
                                                SysLog(NID_IO, "Virtual root application is unregistered.");
                                        }
-                                       SysLog(NID_IO, "unmount() succeeded, mount flag: %s", mountFlag);
+                                       SysLog(NID_IO, "unmount() succeeded");
                                }
                        }
                }
+               delete pEnum;
 
                res = vconf_set_int(VCONFKEY_APPSERVICE_MMC_STATUS, value);
        }
@@ -493,5 +474,77 @@ _MmcStorageManagerService::CreateExternalDirectories(const char srcPath[][_MAX_P
        return E_SUCCESS;
 }
 
+int
+_MmcStorageManagerService::GetMmcblockNumber(void)
+{
+       DIR* pDir = opendir("/sys/block");
+       SysTryReturn(NID_IO, pDir != null, -1, E_SYSTEM, "[E_SYSTEM] Failed to open /sys/block, errno: %d (%s)",
+                       errno, strerror(errno));
+
+       int mmcblkNum = -1;
+       struct dirent* pDirEntry;
+       while ((pDirEntry = readdir(pDir)) != null)
+       {
+               char entryPath[PATH_MAX] = { 0, };
+               sprintf(entryPath, "/sys/block/%s", pDirEntry->d_name);
+
+               struct stat stat;
+               memset(&stat, 0, sizeof(struct stat));
+
+               if (lstat(entryPath, &stat) < 0)
+               {
+                       continue;
+               }
+               if (S_ISDIR(stat.st_mode) || S_ISLNK(stat.st_mode))
+               {
+                       if (strncmp(".", pDirEntry->d_name, 1) == 0 || strncmp("..", pDirEntry->d_name, 2) == 0)
+                       {
+                               continue;
+                       }
+                       if (strncmp("mmcblk", pDirEntry->d_name, 6) == 0)
+                       {
+                               char buf[_MAX_PATH_LENGTH];
+                               snprintf(buf, _MAX_PATH_LENGTH, "/sys/block/%s/device/type", pDirEntry->d_name);
+
+                               int fd = open(buf, O_RDONLY);
+                               if (fd == -1)
+                               {
+                                       SysLog(NID_IO, "Failed to open device type, errno: %d (%s)", errno, strerror(errno));
+                                       continue;
+                               }
+
+                               int readBytes = read(fd, buf, 10);
+                               close(fd);
+                               if (readBytes < 0)
+                               {
+                                       SysLog(NID_IO, "Failed to read device type, errno: %d (%s)", errno, strerror(errno));
+                                       continue;
+                               }
+                               buf[readBytes] = '\0';
+
+                               if (strncmp("SD", buf, 2) == 0)
+                               {
+                                       char* num = strndup((pDirEntry->d_name) + 6, 1);
+                                       if (num == null)
+                                       {
+                                               SysLogException(NID_IO, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
+                                               closedir(pDir);
+                                               return -1;
+                                       }
+
+                                       mmcblkNum = atoi(num);
+                                       free(num);
+
+                                       SysLog(NID_IO, "mmcblk number is %d", mmcblkNum);
+                                       break;
+                               }
+                       }
+               }
+       }
+
+       closedir(pDir);
+       return mmcblkNum;
+}
+
 }} // Tizen::Io