separate main handling routine and file system dependent codes 40/14740/2
authorKrzysztof Sasiak <k.sasiak@samsung.com>
Wed, 17 Jul 2013 10:24:57 +0000 (19:24 +0900)
committerKrzysztof Sasiak <k.sasiak@samsung.com>
Mon, 13 Jan 2014 11:02:27 +0000 (12:02 +0100)
Change-Id: I2b626119f70f037f7008f81b82b84f7d1f8c31a1
Signed-off-by: Krzysztof Sasiak <k.sasiak@samsung.com>
CMakeLists.txt
src/mmc/ext4.c [new file with mode: 0644]
src/mmc/mmc-handler.c
src/mmc/mmc-handler.h [new file with mode: 0644]
src/mmc/vfat.c [new file with mode: 0644]

index 3e01631..146bd18 100755 (executable)
@@ -29,6 +29,8 @@ SET(SRCS
        src/core/edbus-handler.c
        src/cpu/cpu-handler.c
        src/mmc/mmc-handler.c
+       src/mmc/ext4.c
+       src/mmc/vfat.c
        src/power/power-handler.c
        src/proc/lowmem-handler.c
        src/proc/pmon-handler.c
diff --git a/src/mmc/ext4.c b/src/mmc/ext4.c
new file mode 100644 (file)
index 0000000..5522661
--- /dev/null
@@ -0,0 +1,134 @@
+/*
+ * deviced
+ *
+ * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "mmc-handler.h"
+
+#define FS_EXT4_SMACK_LABEL "mmc-smack-label "MMC_MOUNT_POINT
+
+static const char *ext4_arg[] = {
+       "/sbin/mkfs.ext4",
+       NULL, NULL,
+};
+
+static const char *ext4_check_arg[] = {
+       "/sbin/fsck.ext4",
+       "-f", "-y", NULL, NULL,
+};
+
+static struct fs_check fs_ext4_type = {
+       FS_TYPE_EXT4,
+       "ext4",
+       0x438,
+       2,
+       {0x53, 0xef},
+};
+
+static int mmc_popup_pid;
+
+static int mmc_check_smack(void)
+{
+       system(FS_EXT4_SMACK_LABEL);
+       vconf_set_int(VCONFKEY_SYSMAN_MMC_STATUS, VCONFKEY_SYSMAN_MMC_MOUNTED);
+       vconf_set_int(VCONFKEY_SYSMAN_MMC_MOUNT, VCONFKEY_SYSMAN_MMC_MOUNT_COMPLETED);
+       if (mmc_popup_pid > 0) {
+               PRT_TRACE_ERR("will be killed mmc-popup(%d)", mmc_popup_pid);
+               kill(mmc_popup_pid, SIGTERM);
+       }
+       return 0;
+}
+
+static int check_smack_popup(void)
+{
+       bundle *b = NULL;
+       int ret = -1;
+       int val = -1;
+
+       b = bundle_create();
+       bundle_add(b, "_SYSPOPUP_CONTENT_", "checksmack");
+       ret = vconf_get_int(VCONFKEY_STARTER_SEQUENCE, &val);
+       if (val == 1 || ret != 0) {
+               if ((mmc_popup_pid = syspopup_launch("mmc-syspopup", b)) < 0) {
+                       PRT_TRACE_EM("popup launch failed\n");
+               }
+       }
+       bundle_free(b);
+
+       mmc_check_smack();
+       return 0;
+}
+
+static int ext4_init(void *data)
+{
+       int fd, ret;
+       int argc;
+       char buf[BUF_LEN];
+       char *path = (char *)data;
+
+       argc = ARRAY_SIZE(ext4_check_arg);
+       ext4_check_arg[argc - 2] = path;
+
+       if ((fd = open(path, O_RDONLY)) < 0) {
+               PRT_TRACE_ERR("can't open the '%s': %s", path, strerror(errno));
+               return -EINVAL;
+       }
+       /* check fs type with magic code */
+       lseek(fd, fs_ext4_type.offset, SEEK_SET);
+       ret = read(fd, buf, 2);
+       PRT_TRACE("mmc search magic : 0x%2x, 0x%2x", buf[0],buf[1]);
+       if (!memcmp(buf, fs_ext4_type.magic, fs_ext4_type.magic_sz)) {
+               PRT_TRACE("mmc type : %s", fs_ext4_type.name);
+               close(fd);
+
+               return fs_ext4_type.type;
+       }
+       close(fd);
+       return -EINVAL;
+}
+
+static const char **ext4_check(void)
+{
+       return ext4_check_arg;
+}
+
+static int ext4_mount(int smack, void *data)
+{
+       PRT_TRACE_ERR("ext4_mount");
+       if (mount_fs((char *)data, "ext4", NULL) != 0)
+               return errno;
+       if (smack) {
+               if (check_smack_popup() != 0)
+                       return -1;
+       }
+       return smack;
+}
+
+static const char **ext4_format(void *data)
+{
+       int argc;
+       char *path = (char *)data;
+       argc = ARRAY_SIZE(ext4_arg);
+       ext4_arg[argc - 2] = path;
+       return ext4_arg;
+}
+
+const struct mmc_filesystem_ops ext4_ops = {
+       .init = ext4_init,
+       .check = ext4_check,
+       .mount = ext4_mount,
+       .format = ext4_format,
+};
index 115cf03..e866621 100644 (file)
 #include "core/log.h"
 #include "core/common.h"
 #include "core/devices.h"
+#include "mmc-handler.h"
 
 #define VCONFKEY_INTERNAL_PRIVATE_MMC_ID       "db/private/sysman/mmc_device_id"
 
 #define PREDEF_MOUNT_MMC               "mountmmc"
 #define PREDEF_UNMOUNT_MMC             "unmountmmc"
 #define PREDEF_FORMAT_MMC              "formatmmc"
-#define PREDEF_CHECK_SMACK_MMC         "checksmackmmc"
-
-#define MMC_MOUNT_POINT                        "/opt/storage/sdcard"
 
+#define MMC_PARENT_PATH        "/opt/storage"
 #define MMC_DEV                        "/dev/mmcblk"
-#define MOVINAND_DEV           "/dev/mmcblk0p1"
-#define FORMAT_MMC             PREFIX"/sbin/mkfs.vfat "
-#define FORMAT_MOVINAND                PREFIX"/bin/movi_format.sh"
-
-#define FS_VFAT_NAME "mkdosfs"
-#define FS_VFAT_MOUNT_OPT  "uid=0,gid=0,dmask=0000,fmask=0111,iocharset=iso8859-1,utf8,shortname=mixed"
-#define FS_VFAT_CHECKER "/sbin/fsck.vfat"
-#define FS_EXT4_CHECKER "/sbin/fsck.ext4"
-#define FS_VFAT_CHECK_PARAM "-a %s"
-#define FS_EXT4_CHECK_PARAM "-f -y %s"
-#define FS_EXT4_SMACK_LABEL "mmc-smack-label "MMC_MOUNT_POINT
 
 #define SMACKFS_MAGIC          0x43415d53
 #define SMACKFS_MNT            "/smack"
-#define SMACKFS_MOUNT_OPT      "smackfsroot=*,smackfsdef=*"
 
 #ifndef ST_RDONLY
-#define ST_RDONLY      0x0001
+#define ST_RDONLY              0x0001
 #endif
 
-#define MMC_PARENT_PATH     "/opt/storage"
-
-#define BUF_LEN             20
-
 #define MMC_32GB_SIZE           61315072
 
 typedef enum {
-       FS_TYPE_NONE = 0,
-       FS_TYPE_FAT = 1,
-       FS_TYPE_EXT4
-} mmc_fs_type;
-
-typedef enum {
        FS_MOUNT_ERR = -1,
        FS_MOUNT_FAIL = 0,
        FS_MOUNT_SUCCESS = 1,
 } mmc_mount_type;
 
-
-struct fs_check {
-       unsigned int type;
-       char *name;
-       unsigned int offset;
-       unsigned int magic_sz;
-       char magic[4];
-};
-
-static struct fs_check fs_types[2] = {
-       {
-               FS_TYPE_FAT,
-               "vfat",
-               0x1fe,
-               2,
-               {0x55, 0xaa}
-       },
-       {
-               FS_TYPE_EXT4,
-               "ext4",
-               0x438,
-               2,
-               {0x53, 0xef}
-       },
-};
-
-
-static const char *fsstr[] = {
-    [FS_TYPE_FAT] = "mkdosfs",
-};
-
-static const char *vfat_arg[] = {
-       "/sbin/mkfs.vfat",
-       NULL, NULL,
-};
-
-static const char *ext4_arg[] = {
-       "/sbin/mkfs.ext4",
-       NULL, NULL,
-};
-
-static const char *vfat_check_arg[] = {
-       "/sbin/fsck.vfat",
-       "-a", NULL, NULL,
-};
-
-static const char *ext4_check_arg[] = {
-       "/sbin/fsck.ext4",
-       "-f", "-y", NULL, NULL,
+static int smack = 0;
+static int mmc_popup_pid = 0;
+static enum mmc_fs_type inserted_type;
+static bool mmc_disabled = false;
+static char mmc_node[PATH_MAX];
+static const struct mmc_filesystem_ops *filesystem_type[] = {
+       &vfat_ops,
+       &ext4_ops,
 };
 
-
-static int smack;
-static int mmc_popup_pid;
-static mmc_fs_type inserted_type;
-static bool mmc_disabled = false;
+static struct mmc_filesystem_ops *mmc_filesystem;
 
 static void __attribute__ ((constructor)) smack_check(void)
 {
        struct statfs sfs;
        int ret;
 
-       if (mmc_disabled) {
-               PRT_TRACE("mmc is blocked!");
-               vconf_set_int(VCONFKEY_SYSMAN_MMC_STATUS, VCONFKEY_SYSMAN_MMC_INSERTED_NOT_MOUNTED);
-               return -ENODEV;
-       }
-
        do {
                ret = statfs(SMACKFS_MNT, &sfs);
        } while (ret < 0 && errno == EINTR);
@@ -183,7 +109,6 @@ static int exec_process(const char **argv)
                        exit(EXIT_FAILURE);
                }
        }
-
        return pid;
 }
 
@@ -285,104 +210,59 @@ int get_mmcblk_num(void)
        return -1;
 }
 
-static int __umount_fs(void)
+static int mmc_umount(int option)
 {
        int ret;
-       if ((ret = umount2(MMC_MOUNT_POINT, MNT_DETACH)) != 0) {
-               _E("Failed to unmount mmc card : %s\n", strerror(errno));
-       }
+       ret = umount2(MMC_MOUNT_POINT, option);
+       if (ret != 0)
+               _E("Failed to unmount mmc card\n");
        return ret;
 }
 
-static int __check_mmc_fs_type(const char *path)
+static int mmc_check_fs_type(void)
 {
-       int fd, ret, i;
-       char buf[20];
-       int len = 20;
-       char *tmpbuf = buf;
-       int cnr = 0;
-       struct statfs sfs;
-
+       int ret, i;
+       struct mmc_filesystem_ops *filesystem;
        inserted_type = FS_TYPE_NONE;
-       if ((fd = open(path, O_RDONLY)) < 0) {
-               _E("can't open the '%s': %s", path, strerror(errno));
-               return -1;
-       }
 
-       while (len != 0 && (ret = read(fd, tmpbuf, len)) != 0) {
-               if (ret == -1) {
-                       if (errno == EINTR) {
-                               _E("check_mmc_fs error(%d)", errno);
-                               continue;
-                       }
-                       _E("Can't read the '%s': %s", path, strerror(errno));
-                       inserted_type = FS_TYPE_FAT;
-                       goto check_return;
-               }
-               len -= ret;
-               tmpbuf += ret;
-               cnr += ret;
-       }
-       _D("mmc search path: %s, %s", path, buf);
-
-       /* check fs type with magic code */
-       for (i = 0; i < ARRAY_SIZE(fs_types); i++)
-       {
-               ret = lseek(fd, fs_types[i].offset, SEEK_SET);
-               if (ret < 0)
-                       goto check_return;
-               ret = read(fd, buf, 2);
-               if (ret < 0)
-                       goto check_return;
-               _D("mmc search magic : 0x%2x, 0x%2x", buf[0],buf[1]);
-               if (!memcmp(buf, fs_types[i].magic, fs_types[i].magic_sz)) {
-                       inserted_type =  fs_types[i].type;
-                       _D("mmc type : %s", fs_types[i].name);
-                       goto check_return;
-               }
+       for (i = 0; i < ARRAY_SIZE(filesystem_type); i++) {
+               filesystem = filesystem_type[i];
+               if (!filesystem)
+                       continue;
+               ret = filesystem->init((void *)mmc_node);
+               if (ret == -EINVAL)
+                       continue;
+               inserted_type = ret;
+               mmc_filesystem = filesystem;
+               return 0;
        }
 
-       if (inserted_type == FS_TYPE_NONE)
+       if (inserted_type == FS_TYPE_NONE) {
+               _E("set default file system");
                inserted_type = FS_TYPE_FAT;
-
-check_return:
-       close(fd);
+               mmc_filesystem = &vfat_ops;
+               if (!mmc_filesystem) {
+                       _E("fail to init mmc file system");
+                       return -EINVAL;
+               }
+               mmc_filesystem->init((void *)mmc_node);
+       }
        return 0;
 }
 
-static int get_format_type(const char *path)
+static int get_format_type(void)
 {
        unsigned int size;
 
-       if (__check_mmc_fs_type(path) != 0) {
-               _E("fail to check mount point %s", path);
-               return -1;
-       }
+       if (mmc_check_fs_type())
+               return -EINVAL;
+
        if (inserted_type == FS_TYPE_EXT4)
                return 0;
 
        return 0;
 }
 
-static const char **get_argument(const char *path, int fs)
-{
-       int argc;
-
-       switch (fs) {
-       case FS_TYPE_FAT:
-               argc = ARRAY_SIZE(vfat_arg);
-               vfat_arg[argc - 2] = path;
-               return vfat_arg;
-       case FS_TYPE_EXT4:
-               argc = ARRAY_SIZE(ext4_arg);
-               ext4_arg[argc - 2] = path;
-               return ext4_arg;
-       default:
-               break;
-       }
-       return NULL;
-}
-
 static int check_mount_state(void)
 {
        struct stat parent_stat, mount_stat;
@@ -416,13 +296,11 @@ static int create_partition(const char *dev_path)
        r = system(data);
        if (WIFSIGNALED(r) && (WTERMSIG(r) == SIGINT || WTERMSIG(r) == SIGQUIT || WEXITSTATUS(r)))
                return -1;
-
        return 0;
 }
 
-static int format_mmc(const char *path, int fs)
+static int mmc_format_exec(const char *path, int fs)
 {
-       mmc_fs_type type;
        unsigned int size;
        int mkfs_pid;
        const char **argv;
@@ -431,19 +309,25 @@ static int format_mmc(const char *path, int fs)
 
        if (path == NULL) {
                _E("Invalid parameter");
-               return -1;
+               return -EINVAL;
        }
 
-       argv = get_argument(path, fs);
+       if (get_format_type() != 0) {
+               _E("Invalid parameter");
+               return -EINVAL;
+       }
+
+       argv = mmc_filesystem->format((void *)path);
+
        if (argv == NULL) {
                _E("get_argument fail");
-               return -1;
+               return -EINVAL;
        }
 
        mkfs_pid = exec_process(argv);
        if (mkfs_pid < 0) {
                _E("%s fail");
-               return -1;
+               return -EINVAL;
        }
 
        snprintf(buf, sizeof(buf), "%s%d", "/proc/", mkfs_pid);
@@ -454,11 +338,10 @@ static int format_mmc(const char *path, int fs)
                if (access(buf, R_OK) != 0)
                        break;
        }
-
        return 0;
 }
 
-static int format_exec(int blknum)
+static int mmc_format(int blknum)
 {
        char dev_mmcblk[NAME_MAX];
        char dev_mmcblkp[NAME_MAX];
@@ -466,11 +349,12 @@ static int format_exec(int blknum)
 
        if (check_mount_state() == 1) {
                _E("Mounted, will be unmounted");
-               r = __umount_fs();
+               r = mmc_umount(MNT_DETACH);
                if (r != 0) {
                        _E("unmount_mmc fail");
-                       vconf_set_int(VCONFKEY_SYSMAN_MMC_FORMAT, VCONFKEY_SYSMAN_MMC_FORMAT_FAILED);
-                       return -1;
+                       vconf_set_int(VCONFKEY_SYSMAN_MMC_FORMAT,
+                               VCONFKEY_SYSMAN_MMC_FORMAT_FAILED);
+                       return r;
                }
        }
 
@@ -479,22 +363,22 @@ static int format_exec(int blknum)
        if (access(dev_mmcblkp, R_OK) < 0) {
                _E("%s is not valid, create the primary partition", dev_mmcblkp);
                r = create_partition(dev_mmcblk);
-               if (r < 0) {
+               if (r != 0) {
                        _E("create_partition failed");
                        vconf_set_int(VCONFKEY_SYSMAN_MMC_FORMAT, VCONFKEY_SYSMAN_MMC_FORMAT_FAILED);
                        heynoti_publish("mmcblk_remove");
-                       return -1;
+                       return r;
                }
        }
 
        _E("insert type : %d", inserted_type);
 
-       r = format_mmc(dev_mmcblkp, inserted_type);
+       r = mmc_format_exec(dev_mmcblkp, inserted_type);
        if (r < 0) {
                _E("%s format fail", dev_mmcblkp);
                vconf_set_int(VCONFKEY_SYSMAN_MMC_FORMAT, VCONFKEY_SYSMAN_MMC_FORMAT_FAILED);
                heynoti_publish("mmcblk_remove");
-               return -1;
+               return r;
        }
 
        _E("Format Successful");
@@ -502,75 +386,7 @@ static int format_exec(int blknum)
        return 0;
 }
 
-static const char **get_check_argument(const char *path)
-{
-       int argc;
-
-       switch (inserted_type) {
-       case FS_TYPE_EXT4:
-               argc = ARRAY_SIZE(ext4_check_arg);
-               ext4_check_arg[argc - 2] = path;
-               return ext4_check_arg;
-       default:
-               break;
-       }
-       return NULL;
-}
-
-int ss_mmc_unmounted(int argc, char **argv)
-{
-       int option = -1;
-       int mmc_err = 0;
-       if (argc < 1) {
-               _E("Option is wong");
-               return -1;
-       }
-       if ((option = atoi(argv[0])) < 0) {
-               _E("Option is wong : %d", option);
-               return -1;
-       }
-
-       if (umount2(MMC_MOUNT_POINT, option) != 0) {
-               mmc_err = errno;
-               _E("Failed to unmount mmc card\n");
-               vconf_set_int(VCONFKEY_SYSMAN_MMC_UNMOUNT,
-                             VCONFKEY_SYSMAN_MMC_UNMOUNT_FAILED);
-               vconf_set_int(VCONFKEY_SYSMAN_MMC_ERR_STATUS,
-                               mmc_err);
-               return -1;
-
-       }
-       vconf_set_int(VCONFKEY_SYSMAN_MMC_STATUS,
-                     VCONFKEY_SYSMAN_MMC_INSERTED_NOT_MOUNTED);
-       vconf_set_int(VCONFKEY_SYSMAN_MMC_UNMOUNT,
-                     VCONFKEY_SYSMAN_MMC_UNMOUNT_COMPLETED);
-       return 0;
-}
-
-static int __ss_check_smack_popup(void)
-{
-       bundle *b = NULL;
-       int ret = -1;
-       int val = -1;
-
-       b = bundle_create();
-       bundle_add(b, "_SYSPOPUP_CONTENT_", "checksmack");
-       ret = vconf_get_int(VCONFKEY_STARTER_SEQUENCE, &val);
-       if (val == 1 || ret != 0) {
-               if ((mmc_popup_pid = syspopup_launch("mmc-syspopup", b)) < 0) {
-                       _I("popup launch failed\n");
-               }
-       }
-       bundle_free(b);
-
-       if (ss_action_entry_call_internal(PREDEF_CHECK_SMACK_MMC, 0) < 0) {
-               _E("fail to launch mmc checker,direct mount mmc");
-       }
-       return 0;
-
-}
-
-static int __mount_fs(char *path, const char *fs_name, const char *mount_data)
+int mount_fs(char *path, const char *fs_name, const char *mount_data)
 {
        int ret, retry = 0;
 
@@ -585,13 +401,21 @@ static int __mount_fs(char *path, const char *fs_name, const char *mount_data)
        return errno;
 }
 
-static int __mmc_mount_fs(void)
+static int __ss_rw_mount(const char *szPath)
+{
+       struct statvfs mount_stat;
+       if (!statvfs(szPath, &mount_stat)) {
+               if ((mount_stat.f_flag & ST_RDONLY) == ST_RDONLY)
+                       return -1;
+       }
+       return 0;
+}
+
+static int mmc_check_node(void)
 {
-       char buf[NAME_MAX];
-       char params[NAME_MAX];
-       char options[NAME_MAX];
        int fd;
        int blk_num;
+       int ret = 0;
 
        if (access(MMC_MOUNT_POINT, R_OK) != 0) {
                if (mkdir(MMC_MOUNT_POINT, 0755) < 0) {
@@ -606,55 +430,76 @@ static int __mmc_mount_fs(void)
                return -1;
        }
 
-       snprintf(buf, sizeof(buf), "%s%dp1", MMC_DEV, blk_num);
-       fd = open(buf, O_RDONLY);
+       snprintf(mmc_node, sizeof(mmc_node), "%s%dp1", MMC_DEV, blk_num);
+       fd = open(mmc_node, O_RDONLY);
        if (fd < 0) {
-               _E("can't open the '%s': %s", buf, strerror(errno));
-               snprintf(buf, sizeof(buf), "%s%d", MMC_DEV, blk_num);
-       } else
-               close(fd);
-
-       switch (inserted_type) {
-       case FS_TYPE_FAT:
-               if (smack)
-                       snprintf(options, sizeof(options), "%s,%s", FS_VFAT_MOUNT_OPT, SMACKFS_MOUNT_OPT);
-               else
-                       snprintf(options, sizeof(options), "%s", FS_VFAT_MOUNT_OPT);
-               if (__mount_fs(buf, "vfat", options) != 0)
+               _E("can't open the '%s(%d)': %s",
+                       mmc_node, sizeof(mmc_node), strerror(errno));
+               snprintf(mmc_node, sizeof(mmc_node), "%s%d", MMC_DEV, blk_num);
+               fd = open(mmc_node, O_RDONLY);
+               if (fd < 0) {
+                       _E("can't open the '%s(%d)': %s",
+                               mmc_node, sizeof(mmc_node), strerror(errno));
                        return -1;
-               break;
-       case FS_TYPE_EXT4:
-               if (__mount_fs(buf, "ext4", NULL) != 0)
-                       return errno;
-               if (smack) {
-                       if (__ss_check_smack_popup() != 0)
-                               return -1;
                }
-               return smack;
        }
+       close(fd);
        return 0;
 }
 
-static int __ss_rw_mount(const char* szPath)
+static void mmc_check_fs(void)
 {
-       struct statvfs mount_stat;
-       if (!statvfs(szPath, &mount_stat)) {
-               if ((mount_stat.f_flag & ST_RDONLY) == ST_RDONLY)
-                       return -1;
+       const char **params;
+       char buf[NAME_MAX];
+       int pid;
+
+       if (!mmc_filesystem) {
+               _E("no inserted mmc");
+               return;
+       }
+       params = mmc_filesystem->check();
+
+       pid = exec_process(params);
+       if (pid < 0) {
+               _E("mmc checker failed");
+               return;
+       }
+
+       snprintf(buf, sizeof(buf), "%s%d", "/proc/", pid);
+       _E("child process : %s", buf);
+
+       while (1) {
+               _E("mmc checking ....");
+               if (access(buf, R_OK) != 0)
+                       break;
+               sleep(1);
        }
-       return 0;
 }
 
-static int mmc_check_mount(void)
+static int mmc_mount(void)
 {
        int r;
-       r = __mmc_mount_fs();
+
+       r = mmc_check_node();
+       if (r != 0) {
+               _E("fail to check mmc");
+               return r;
+       }
+
+       if (mmc_check_fs_type())
+               goto mount_fail;
+
+       mmc_check_fs();
+
+       r = mmc_filesystem->mount(smack, mmc_node);
+
        if (r == 0)
                goto mount_complete;
        else if (r == 1)
                goto mount_wait;
        else if (r == -1)
                goto mount_fail;
+
        vconf_set_int(VCONFKEY_SYSMAN_MMC_STATUS, VCONFKEY_SYSMAN_MMC_INSERTED_NOT_MOUNTED);
        vconf_set_int(VCONFKEY_SYSMAN_MMC_MOUNT, VCONFKEY_SYSMAN_MMC_MOUNT_FAILED);
        vconf_set_int(VCONFKEY_SYSMAN_MMC_ERR_STATUS, errno);
@@ -668,76 +513,27 @@ mount_complete:
        if (r == -1)
                return -1;
        return 0;
+
 mount_fail:
        vconf_set_int(VCONFKEY_SYSMAN_MMC_STATUS, VCONFKEY_SYSMAN_MMC_REMOVED);
        vconf_set_int(VCONFKEY_SYSMAN_MMC_MOUNT, VCONFKEY_SYSMAN_MMC_MOUNT_FAILED);
        vconf_set_int(VCONFKEY_SYSMAN_MMC_ERR_STATUS, VCONFKEY_SYSMAN_MMC_EINVAL);
        return -1;
+
 mount_wait:
        _E("wait ext4 smack rule checking");
        return 0;
 }
 
-static int mmc_check_process_launch(char *path)
-{
-       const char **params;
-       char buf[NAME_MAX];
-       int pid;
-
-       params = get_check_argument((const char*)path);
-       if ((pid = exec_process(params)) < 0) {
-               PRT_TRACE_ERR("mmc checker failed");
-               goto run_mount;
-       }
-
-       snprintf(buf, sizeof(buf), "%s%d", "/proc/", pid);
-       PRT_TRACE_ERR("child process : %s", buf);
-
-       while (1) {
-               PRT_TRACE_ERR("mmc checking ....");
-               if (access(buf, R_OK) != 0)
-                       break;
-               sleep(1);
-       }
-run_mount:
-       return mmc_check_mount();
-}
-
-static int __check_mmc_fs(void)
+int ss_mmc_removed(void)
 {
-       char buf[NAME_MAX];
-       int fd;
-       int blk_num;
-       int ret = 0;
-
-       if (access(MMC_MOUNT_POINT, R_OK) != 0) {
-               if (mkdir(MMC_MOUNT_POINT, 0755) < 0) {
-                       _E("Make Directory is failed");
-                       return errno;
-               }
-       }
-
-       blk_num = get_mmcblk_num();
-       if (blk_num  == -1) {
-               _E("fail to check mmc block");
-               return -1;
-       }
-
-       snprintf(buf, sizeof(buf), "%s%dp1", MMC_DEV, blk_num);
-       fd = open(buf, O_RDONLY);
-       if (fd < 0) {
-               _E("can't open the '%s': %s", buf, strerror(errno));
-               snprintf(buf, sizeof(buf), "%s%d", MMC_DEV, blk_num);
-       }
-       else
-               close(fd);
+       int mmc_err = 0;
 
-       if (__check_mmc_fs_type(buf) != 0) {
-               _E("fail to check mount point %s", buf);
-               return -1;
-       }
-       ret = mmc_check_process_launch(buf);
-       return ret;
+       vconf_set_int(VCONFKEY_SYSMAN_MMC_STATUS, VCONFKEY_SYSMAN_MMC_REMOVED);
+       mmc_err = mmc_umount(MNT_DETACH);
+       vconf_set_int(VCONFKEY_SYSMAN_MMC_ERR_STATUS, mmc_err);
+       mmc_filesystem = NULL;
+       return 0;
 }
 
 int ss_mmc_inserted(void)
@@ -745,6 +541,12 @@ int ss_mmc_inserted(void)
        int mmc_status;
        int ret;
 
+       if (mmc_disabled) {
+               _E("mmc is blocked!");
+               vconf_set_int(VCONFKEY_SYSMAN_MMC_STATUS, VCONFKEY_SYSMAN_MMC_INSERTED_NOT_MOUNTED);
+               return -ENODEV;
+       }
+
        vconf_get_int(VCONFKEY_SYSMAN_MMC_STATUS, &mmc_status);
 
        if (mmc_status == VCONFKEY_SYSMAN_MMC_MOUNTED) {
@@ -753,48 +555,56 @@ int ss_mmc_inserted(void)
                return 0;
        }
 
-       if ((ret = __check_mmc_fs()) != 0)
-               _E("fail to check mmc");
+       ret = mmc_mount();
+
        return ret;
 }
 
-int ss_mmc_removed(void)
+static int ss_mmc_unmounted(int argc, char **argv)
 {
-       int mmc_err = 0;
-       vconf_set_int(VCONFKEY_SYSMAN_MMC_STATUS, VCONFKEY_SYSMAN_MMC_REMOVED);
-       mmc_err = __umount_fs();
-       vconf_set_int(VCONFKEY_SYSMAN_MMC_ERR_STATUS, mmc_err);
+       int option = -1;
 
+       if (argc < 1) {
+               _E("Option is wong");
+               return -1;
+       }
+
+       option = atoi(argv[0]);
+       if (option < 0) {
+               _E("Option is wong : %d", option);
+               return -1;
+       }
+
+       if (mmc_umount(option) != 0) {
+               _E("Failed to unmount mmc card\n");
+               vconf_set_int(VCONFKEY_SYSMAN_MMC_UNMOUNT,
+                       VCONFKEY_SYSMAN_MMC_UNMOUNT_FAILED);
+               vconf_set_int(VCONFKEY_SYSMAN_MMC_ERR_STATUS, errno);
+               return -1;
+
+       }
+       vconf_set_int(VCONFKEY_SYSMAN_MMC_STATUS,
+               VCONFKEY_SYSMAN_MMC_INSERTED_NOT_MOUNTED);
+       vconf_set_int(VCONFKEY_SYSMAN_MMC_UNMOUNT,
+               VCONFKEY_SYSMAN_MMC_UNMOUNT_COMPLETED);
        return 0;
 }
 
 static int ss_mmc_format(int argc, char **argv)
 {
+       int ret;
+
        _E("mmc format called");
-       __umount_fs();
+       mmc_umount(MNT_DETACH);
 
        vconf_set_int(VCONFKEY_SYSMAN_MMC_FORMAT_PROGRESS, VCONFKEY_SYSMAN_MMC_FORMAT_PROGRESS_NOW);
-       format_exec(get_mmcblk_num());
+       ret = mmc_format(get_mmcblk_num());
        vconf_set_int(VCONFKEY_SYSMAN_MMC_FORMAT_PROGRESS, VCONFKEY_SYSMAN_MMC_FORMAT_PROGRESS_NONE);
+       if (ret != 0)
+               return ret;
 
-       if (__check_mmc_fs() != 0)
-               _E("fail to check mmc");
-
-       return 0;
-}
-
-static int ss_mmc_check_smack(int argc, char **argv)
-{
-       int pid;
-       system(FS_EXT4_SMACK_LABEL);
-       _E("smack labeling script is run");
-       vconf_set_int(VCONFKEY_SYSMAN_MMC_STATUS, VCONFKEY_SYSMAN_MMC_MOUNTED);
-       vconf_set_int(VCONFKEY_SYSMAN_MMC_MOUNT, VCONFKEY_SYSMAN_MMC_MOUNT_COMPLETED);
-       if (mmc_popup_pid > 0) {
-               _E("will be killed mmc-popup(%d)", mmc_popup_pid);
-               kill(mmc_popup_pid, SIGTERM);
-       }
-       return 0;
+       ret = mmc_mount();
+       return ret;
 }
 
 static void mmc_init(void *data)
@@ -802,23 +612,21 @@ static void mmc_init(void *data)
        ss_action_entry_add_internal(PREDEF_MOUNT_MMC, ss_mmc_inserted, NULL, NULL);
        ss_action_entry_add_internal(PREDEF_UNMOUNT_MMC, ss_mmc_unmounted, NULL, NULL);
        ss_action_entry_add_internal(PREDEF_FORMAT_MMC, ss_mmc_format, NULL, NULL);
-       ss_action_entry_add_internal(PREDEF_CHECK_SMACK_MMC, ss_mmc_check_smack, NULL, NULL);
        /* mmc card mount */
-       if (__check_mmc_fs() != 0)
-               _E("failed to check mmc");
+       mmc_mount();
 }
 
 static void mmc_start(void)
 {
        mmc_disabled = false;
-       PRT_TRACE("start");
+       _E("start");
 }
 
 static void mmc_stop(void)
 {
        mmc_disabled = true;
        vconf_set_int(VCONFKEY_SYSMAN_MMC_STATUS, VCONFKEY_SYSMAN_MMC_REMOVED);
-       PRT_TRACE("stop");
+       _E("stop");
 }
 
 const struct device_ops mmc_device_ops = {
diff --git a/src/mmc/mmc-handler.h b/src/mmc/mmc-handler.h
new file mode 100644 (file)
index 0000000..906f295
--- /dev/null
@@ -0,0 +1,74 @@
+/*
+ * deviced
+ *
+ * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+#ifndef __MMC_HANDLER_H__
+#define __MMC_HANDLER_H__
+
+#include <stdlib.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <sys/mount.h>
+#include <sys/statvfs.h>
+#include <vconf.h>
+#include <fcntl.h>
+#include <dirent.h>
+#include <sys/statfs.h>
+#include <bundle.h>
+#include <signal.h>
+#include <stdbool.h>
+
+#include "core/log.h"
+#include "core/device-handler.h"
+#include "core/common.h"
+#include "core/devices.h"
+
+#define BUF_LEN             20
+
+#define SMACKFS_MOUNT_OPT              "smackfsroot=*,smackfsdef=*"
+#define MMC_MOUNT_POINT                "/opt/storage/sdcard"
+
+enum mmc_fs_type {
+       FS_TYPE_NONE,
+       FS_TYPE_FAT,
+       FS_TYPE_EXFAT,
+       FS_TYPE_EXT4,
+};
+
+struct fs_check {
+       int type;
+       char *name;
+       unsigned int offset;
+       unsigned int magic_sz;
+       char magic[4];
+};
+
+struct mmc_filesystem_ops {
+       int (*init) (void *data);
+       const char ** (*check) (void);
+       int (*mount) (int smack, void *data);
+       const char ** (*format) (void *data);
+};
+
+extern const struct mmc_filesystem_ops exfat_ops;
+extern const struct mmc_filesystem_ops vfat_ops;
+extern const struct mmc_filesystem_ops ext4_ops;
+
+int mount_fs(char *path, const char *fs_name, const char *mount_data);
+
+#endif /* __MMC_HANDLER_H__ */
diff --git a/src/mmc/vfat.c b/src/mmc/vfat.c
new file mode 100644 (file)
index 0000000..52de71f
--- /dev/null
@@ -0,0 +1,101 @@
+/*
+ * deviced
+ *
+ * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "mmc-handler.h"
+
+#define FS_VFAT_MOUNT_OPT  "uid=0,gid=0,dmask=0000,fmask=0111,iocharset=iso8859-1,utf8,shortname=mixed"
+
+static const char *vfat_arg[] = {
+       "/sbin/mkfs.vfat",
+       NULL, NULL,
+};
+
+static const char *vfat_check_arg[] = {
+       "/sbin/fsck.vfat",
+       "-a", NULL, NULL,
+};
+
+static struct fs_check fs_vfat_type = {
+       FS_TYPE_FAT,
+       "vfat",
+       0x1fe,
+       2,
+       {0x55, 0xaa},
+};
+
+static int vfat_init(void *data)
+{
+       int fd, ret, argc;
+       char buf[BUF_LEN];
+       char *path = (char *)data;
+
+       argc = ARRAY_SIZE(vfat_check_arg);
+       vfat_check_arg[argc - 2] = path;
+
+       if ((fd = open(path, O_RDONLY)) < 0) {
+               PRT_TRACE_ERR("can't open the '%s': %s", path, strerror(errno));
+               return -EINVAL;
+       }
+       /* check fs type with magic code */
+       lseek(fd, fs_vfat_type.offset, SEEK_SET);
+       ret = read(fd, buf, 2);
+       PRT_TRACE("mmc search magic : 0x%2x, 0x%2x", buf[0],buf[1]);
+       if (!memcmp(buf, fs_vfat_type.magic, fs_vfat_type.magic_sz)) {
+               PRT_TRACE("mmc type : %s", fs_vfat_type.name);
+               close(fd);
+               return fs_vfat_type.type;
+       }
+       close(fd);
+       return -EINVAL;
+}
+
+static const char ** vfat_check(void)
+{
+       return vfat_check_arg;
+}
+
+static int vfat_mount(int smack, void *data)
+{
+       char options[NAME_MAX];
+
+       PRT_TRACE_ERR("vfat_mount");
+       if (smack)
+               snprintf(options, sizeof(options), "%s,%s", FS_VFAT_MOUNT_OPT, SMACKFS_MOUNT_OPT);
+       else
+               snprintf(options, sizeof(options), "%s", FS_VFAT_MOUNT_OPT);
+       if (mount_fs((char *)data, "vfat", options) != 0)
+               return -1;
+       return 0;
+}
+
+static const char **vfat_format(void *data)
+{
+       int argc;
+       char *path = (char *)data;
+       argc = ARRAY_SIZE(vfat_arg);
+       vfat_arg[argc - 2] = path;
+       return vfat_arg;
+}
+
+const struct mmc_filesystem_ops vfat_ops = {
+       .init = vfat_init,
+       .check = vfat_check,
+       .mount = vfat_mount,
+       .format = vfat_format,
+};
+