in emulator, support ext4 format for mmc control
authorjy910.yun <jy910.yun@samsung.com>
Thu, 23 May 2013 05:18:21 +0000 (14:18 +0900)
committerjy910.yun <jy910.yun@samsung.com>
Thu, 23 May 2013 05:18:21 +0000 (14:18 +0900)
before in emulator it can not support MMC because of IP issue
but we found other way, so we support ext4 format now

Signed-off-by: jy910.yun <jy910.yun@samsung.com>
CMakeLists.txt
include/ss_data.h
mmc-smack-label [new file with mode: 0755]
packaging/system-server.spec
ss_device_change_handler.c
ss_mmc_handler.c

index 19e5684..f25d552 100755 (executable)
@@ -44,7 +44,8 @@ pkg_check_modules(pkgs REQUIRED
        syspopup-caller
        notification
        devman
-       device-node)
+       device-node
+       libsmack)
 
 FOREACH(flag ${pkgs_CFLAGS})
        SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
@@ -69,7 +70,7 @@ SET(UDEV_RULES udev-rules/91-system-server.rules)
 CONFIGURE_FILE(${UDEV_RULES}.in ${UDEV_RULES} @ONLY)
 
 ADD_EXECUTABLE(${PROJECT_NAME} ${SRCS})
-TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${pkgs_LDFLAGS} "-ldl")
+TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${pkgs_LDFLAGS} "-ldl" "-lsmack")
 
 INSTALL(TARGETS ${PROJECT_NAME} DESTINATION bin)
 INSTALL(FILES ${MOVINAND_FORMAT} DESTINATION bin)
@@ -77,6 +78,7 @@ INSTALL(FILES ${UDEV_RULES} DESTINATION ${UDEV_RULES_PATH})
 INSTALL(PROGRAMS ${CMAKE_BINARY_DIR}/system_server.sh DESTINATION /etc/rc.d/init.d)
 INSTALL(FILES system-server.conf DESTINATION /etc/dbus-1/system.d)
 INSTALL(FILES ${CMAKE_SOURCE_DIR}/packaging/system-server.rule DESTINATION /opt/etc/smack/accesses.d)
+INSTALL(PROGRAMS ${CMAKE_CURRENT_SOURCE_DIR}/mmc-smack-label DESTINATION bin)
 
 ADD_SUBDIRECTORY(restarter)
 ADD_SUBDIRECTORY(sys_event)
index d56aad7..497659c 100644 (file)
@@ -71,6 +71,9 @@ enum {
 #define PREDEF_MOUNT_MMC               "mountmmc"
 #define PREDEF_UNMOUNT_MMC             "unmountmmc"
 #define PREDEF_FORMAT_MMC              "formatmmc"
+#define PREDEF_CHECK_SMACK_MMC "checksmackmmc"
+#define PREDEF_CHECK_MMC               "checkmmc"
+#define PREDEF_CHECK_MMC_PROC  "checkmmcproc"
 
 #define PREDEF_SET_MAX_FREQUENCY       "set_max_frequency"     
 #define PREDEF_SET_MIN_FREQUENCY       "set_min_frequency"     
diff --git a/mmc-smack-label b/mmc-smack-label
new file mode 100755 (executable)
index 0000000..aa5f793
--- /dev/null
@@ -0,0 +1,5 @@
+#!/bin/bash
+MOUNT_DIRECTORY=$1
+find $MOUNT_DIRECTORY -type d | xargs chsmack -a '*' -e ''
+find $MOUNT_DIRECTORY -type f | xargs chsmack -a '*'
+find $MOUNT_DIRECTORY | xargs chown app:app
index 98ffba5..63bc67d 100755 (executable)
@@ -25,6 +25,7 @@ BuildRequires:  pkgconfig(svi)
 BuildRequires:  pkgconfig(notification)
 BuildRequires:  pkgconfig(usbutils)
 BuildRequires:  pkgconfig(device-node)
+BuildRequires:  pkgconfig(libsmack)
 BuildRequires: gettext
 Requires(preun): /usr/bin/systemctl
 Requires(post): /usr/bin/systemctl
@@ -142,6 +143,7 @@ systemctl daemon-reload
 %{_bindir}/sys_event
 %{_bindir}/sys_device_noti
 %{_bindir}/sys_pci_noti
+%{_bindir}/mmc-smack-label
 %{_libdir}/systemd/system/multi-user.target.wants/system-server.service
 %{_libdir}/systemd/system/system-server.service
 %{_datadir}/system-server/sys_device_noti/batt_full_icon.png
index 2ef3bc1..c905ef7 100755 (executable)
@@ -222,13 +222,19 @@ static void keyboard_chgdet_cb(struct ss_main_data *ad)
 
 static void mmc_chgdet_cb(void *data)
 {
+       static int inserted;
        int ret = -1;
        int val = -1;
+
        if (data == NULL) {
                PRT_TRACE("mmc removed");
                ss_mmc_removed();
+               inserted = 0;
        } else {
                PRT_TRACE("mmc added");
+               if (inserted)
+                       return;
+               inserted = 1;
                ret = ss_mmc_inserted();
                if (ret == -1) {
                        vconf_get_int(VCONFKEY_SYSMAN_MMC_MOUNT,&val);
index 61074b8..b6b8ea2 100644 (file)
 
 #include <unistd.h>
 #include <sys/mount.h>
+#include <sys/smack.h>
+#include <sys/statvfs.h>
 #include <errno.h>
 #include <vconf.h>
 #include <fcntl.h>
 #include <dirent.h>
-#include <sysman.h>
+#include <sys/statfs.h>
+#include <bundle.h>
 #include "ss_log.h"
 #include "ss_device_handler.h"
+#include "ss_predefine.h"
 
+#define VCONFKEY_INTERNAL_PRIVATE_MMC_ID       "db/private/sysman/mmc_device_id"
+
+#define MMC_MOUNT_POINT                        "/opt/storage/sdcard"
+
+#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_MOUNT_OPT  "uid=0,gid=0,dmask=0000,fmask=0111,iocharset=iso8859-1,utf8,shortname=mixed,smackfsroot=*,smackfsdef=*"
+#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
+#endif
 
 #define MMC_PARENT_PATH     "/opt/storage"
 
 
 #define MMC_32GB_SIZE           61315072
 
+#define ARRAY_SIZE(name) (sizeof(name)/sizeof(name[0]))
+
+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,
 };
 
-int mmc_status;
-int ss_mmc_inserted(void);
-static int __umount_fs(void);
+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;
+static int mmc_popup_pid;
+static mmc_fs_type inserted_type;
+
+static void __attribute__ ((constructor)) smack_check(void)
+{
+       struct statfs sfs;
+       int ret;
+
+       do {
+               ret = statfs(SMACKFS_MNT, &sfs);
+       } while (ret < 0 && errno == EINTR);
+
+       if (ret == 0 && sfs.f_type == SMACKFS_MAGIC)
+               smack = 1;
+       PRT_TRACE_ERR("smackfs check %d", smack);
+}
 
 static int exec_process(const char **argv)
 {
@@ -72,7 +170,7 @@ static int exec_process(const char **argv)
        return pid;
 }
 
-int get_mmcblk_num()
+int get_mmcblk_num(void)
 {
        DIR *dp;
        struct dirent *dir;
@@ -81,6 +179,8 @@ int get_mmcblk_num()
        int fd;
        int r;
        int mmcblk_num;
+       char *pre_mmc_device_id = NULL;
+       int mmc_dev_changed = 0;
 
        if ((dp = opendir("/sys/block")) == NULL) {
                PRT_TRACE_ERR("Can not open directory..\n");
@@ -117,7 +217,7 @@ int get_mmcblk_num()
                                        if (str_mmcblk_num == NULL) {
                                                PRT_TRACE_ERR("Memory Allocation Failed");
                                                closedir(dp);
-                                               return -1; 
+                                               return -1;
                                        }
                                        mmcblk_num =
                                            atoi(str_mmcblk_num);
@@ -125,6 +225,38 @@ int get_mmcblk_num()
                                        free(str_mmcblk_num);
                                        closedir(dp);
                                        PRT_TRACE("%d \n", mmcblk_num);
+
+                                       snprintf(buf, 255, "/sys/block/%s/device/cid", dir->d_name);
+
+                                       fd = open(buf, O_RDONLY);
+                                       if (fd == -1) {
+                                               PRT_TRACE_ERR("%s open error", buf, strerror(errno));
+                                               return mmcblk_num;
+                                       }
+                                       r = read(fd, buf, 255);
+                                       if ((r >=0) && (r < 255)) {
+                                               buf[r] = '\0';
+                                       } else {
+                                               PRT_TRACE_ERR("%s read error: %s", buf,strerror(errno));
+                                       }
+                                       close(fd);
+                                       pre_mmc_device_id = vconf_get_str(VCONFKEY_INTERNAL_PRIVATE_MMC_ID);
+                                       if (pre_mmc_device_id) {
+                                               if (strcmp(pre_mmc_device_id, "") == 0) {
+                                                       vconf_set_str(VCONFKEY_INTERNAL_PRIVATE_MMC_ID, buf);
+                                               } else if (strncmp(pre_mmc_device_id,buf,33) == 0) {
+                                                       if ( vconf_get_int(VCONFKEY_SYSMAN_MMC_DEVICE_CHANGED,&mmc_dev_changed) == 0
+                                                       && mmc_dev_changed != VCONFKEY_SYSMAN_MMC_NOT_CHANGED) {
+                                                               vconf_set_int(VCONFKEY_SYSMAN_MMC_DEVICE_CHANGED, VCONFKEY_SYSMAN_MMC_NOT_CHANGED);
+                                                       }
+                                               } else if (strncmp(pre_mmc_device_id,buf,32) != 0) {
+                                                       vconf_set_str(VCONFKEY_INTERNAL_PRIVATE_MMC_ID, buf);
+                                                       vconf_set_int(VCONFKEY_SYSMAN_MMC_DEVICE_CHANGED, VCONFKEY_SYSMAN_MMC_CHANGED);
+                                               }
+                                               free(pre_mmc_device_id);
+                                       } else {
+                                               PRT_TRACE_ERR("failed to get pre_mmc_device_id");
+                                       }
                                        return mmcblk_num;
                                }
                        }
@@ -136,6 +268,100 @@ int get_mmcblk_num()
        return -1;
 }
 
+static int __umount_fs(void)
+{
+       int ret;
+       if ((ret = umount2(MMC_MOUNT_POINT, MNT_DETACH)) != 0) {
+               PRT_TRACE_ERR("Failed to unmount mmc card : %s\n", strerror(errno));
+       }
+       return ret;
+}
+
+static int __check_mmc_fs_type(const char *path)
+{
+       int fd, ret, i;
+       char buf[20];
+       int len = 20;
+       char *tmpbuf = buf;
+       int cnr = 0;
+       struct statfs sfs;
+
+       inserted_type = FS_TYPE_NONE;
+       if ((fd = open(path, O_RDONLY)) < 0) {
+               PRT_TRACE_ERR("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) {
+                               PRT_TRACE_ERR("check_mmc_fs error(%d)", errno);
+                               continue;
+                       }
+                       PRT_TRACE_ERR("Can't read the '%s': %s", path, strerror(errno));
+                       inserted_type = FS_TYPE_FAT;
+                       goto check_return;
+               }
+               len -= ret;
+               tmpbuf += ret;
+               cnr += ret;
+       }
+       PRT_TRACE("mmc search path: %s, %s", path, buf);
+
+       /* check fs type with magic code */
+       for (i = 0; i < ARRAY_SIZE(fs_types); i++)
+       {
+               lseek(fd, fs_types[i].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_types[i].magic, fs_types[i].magic_sz)) {
+                       inserted_type =  fs_types[i].type;
+                       PRT_TRACE("mmc type : %s", fs_types[i].name);
+                       goto check_return;
+               }
+       }
+
+       if (inserted_type == FS_TYPE_NONE)
+               inserted_type = FS_TYPE_FAT;
+
+check_return:
+       close(fd);
+       return 0;
+}
+
+static int get_format_type(const char *path)
+{
+       unsigned int size;
+
+       if (__check_mmc_fs_type(path) != 0) {
+               PRT_TRACE_ERR("fail to check mount point %s", path);
+               return -1;
+       }
+       if (inserted_type == FS_TYPE_EXT4)
+               return 0;
+
+       return 0;
+}
+
+static const char **get_argument(const char *path)
+{
+       int argc;
+
+       switch (inserted_type) {
+       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;
@@ -172,18 +398,29 @@ static int create_partition(const char *dev_path)
 
 static int format_mmc(const char *path)
 {
+       mmc_fs_type type;
+       unsigned int size;
        int mkfs_pid;
+       const char **argv;
        char buf[NAME_MAX];
+       int r;
 
        if (path == NULL) {
                PRT_TRACE_ERR("Invalid parameter");
                return -1;
        }
 
-       vfat_arg[1] = path;
-
-       mkfs_pid = exec_process(vfat_arg);
+       if (get_format_type(path) < 0) {
+               PRT_TRACE_ERR("Invalid parameter");
+               return -1;
+       }
+       argv = get_argument(path);
+       if (argv == NULL) {
+               PRT_TRACE_ERR("get_argument fail");
+               return -1;
+       }
 
+       mkfs_pid = exec_process(argv);
        if (mkfs_pid < 0) {
                PRT_TRACE_ERR("%s fail");
                return -1;
@@ -243,15 +480,46 @@ static int format_exec(int blknum)
        return 0;
 }
 
-static int ss_mmc_format(keynode_t *key_nodes, void *data)
+static const char **get_check_argument(const char *path)
 {
-       PRT_TRACE_ERR("mmc format called");
-       __umount_fs();
-       vconf_set_int(VCONFKEY_SYSMAN_MMC_FORMAT_PROGRESS, VCONFKEY_SYSMAN_MMC_FORMAT_PROGRESS_NOW);
-       format_exec(get_mmcblk_num());
-       vconf_set_int(VCONFKEY_SYSMAN_MMC_FORMAT_PROGRESS, VCONFKEY_SYSMAN_MMC_FORMAT_PROGRESS_NONE);
-       ss_mmc_inserted();
+       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;
+}
+
+static int mmc_check_process_launch(int argc,  char **argv)
+{
+       const char **params;
+       char buf[NAME_MAX];
+       int pid;
+
+       params = get_check_argument((const char*)argv[1]);
+       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) {
+               sleep(1);
+               PRT_TRACE_ERR("mmc checking ....");
+               if (access(buf, R_OK) != 0)
+                       break;
+       }
+run_mount:
+       ss_action_entry_call_internal(PREDEF_CHECK_MMC,0);
        return 0;
+
 }
 
 int ss_mmc_unmounted(int argc, char **argv)
@@ -281,20 +549,41 @@ int ss_mmc_unmounted(int argc, char **argv)
                      VCONFKEY_SYSMAN_MMC_INSERTED_NOT_MOUNTED);
        vconf_set_int(VCONFKEY_SYSMAN_MMC_UNMOUNT,
                      VCONFKEY_SYSMAN_MMC_UNMOUNT_COMPLETED);
-       mmc_status = VCONFKEY_SYSMAN_MMC_INSERTED_NOT_MOUNTED;
+       return 0;
+}
+
 
+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;
 }
 
-int ss_mmc_init()
+static int __ss_check_smack_popup(void)
 {
-       /* mmc card mount */
-       ss_mmc_inserted();
+       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);
 
-       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);
+       if (ss_action_entry_call_internal(PREDEF_CHECK_SMACK_MMC, 0) < 0) {
+               PRT_TRACE_ERR("fail to launch mmc checker,direct mount mmc");
+       }
        return 0;
+
 }
 
 static int __mount_fs(char *path, const char *fs_name, const char *mount_data)
@@ -303,7 +592,7 @@ static int __mount_fs(char *path, const char *fs_name, const char *mount_data)
 
        do {
                if ((ret = mount(path, MMC_MOUNT_POINT, fs_name, 0, mount_data)) == 0) {
-                       PRT_TRACE("Mounted mmc card\n");
+                       PRT_TRACE_ERR("Mounted mmc card %s", fs_name);
                        return 0;
                }
                usleep(100000);
@@ -316,6 +605,7 @@ static int __mmc_mount_fs(void)
 {
        char buf[NAME_MAX];
        char params[NAME_MAX];
+       char options[NAME_MAX];
        int fd;
        int blk_num;
 
@@ -340,57 +630,121 @@ static int __mmc_mount_fs(void)
        } else
                close(fd);
 
-       if (__mount_fs(buf, "vfat", FS_VFAT_MOUNT_OPT) != 0)
-               return errno;
+       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)
+                       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;
+       }
        return 0;
-
 }
-int ss_mmc_inserted(void)
-{
-       int r = 0;
-
-       if (mmc_status == VCONFKEY_SYSMAN_MMC_MOUNTED) {
-               PRT_DBG("Mmc is already mounted.\n");
-               vconf_set_int(VCONFKEY_SYSMAN_MMC_STATUS, VCONFKEY_SYSMAN_MMC_MOUNTED);
-               vconf_set_int(VCONFKEY_SYSMAN_MMC_MOUNT, VCONFKEY_SYSMAN_MMC_MOUNT_ALREADY);
-
-               return -1;
-       }
 
+static int mmc_check_mount(int argc,  char **argv)
+{
+       int r;
        r = __mmc_mount_fs();
        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);
-       mmc_status = VCONFKEY_SYSMAN_MMC_INSERTED_NOT_MOUNTED;
        PRT_TRACE_ERR("Failed to mount mmc card\n");
        return -1;
 
 mount_complete:
+       r = __ss_rw_mount(MMC_MOUNT_POINT);
        vconf_set_int(VCONFKEY_SYSMAN_MMC_STATUS, VCONFKEY_SYSMAN_MMC_MOUNTED);
        vconf_set_int(VCONFKEY_SYSMAN_MMC_MOUNT, VCONFKEY_SYSMAN_MMC_MOUNT_COMPLETED);
-       mmc_status = VCONFKEY_SYSMAN_MMC_MOUNTED;
+       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);
-       mmc_status = VCONFKEY_SYSMAN_MMC_REMOVED;
+       return 0;
+mount_wait:
+       PRT_TRACE_ERR("wait ext4 smack rule checking");
        return 0;
 }
-static int __umount_fs(void)
+
+static int __check_mmc_fs(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) {
+                       PRT_TRACE_ERR("Make Directory is failed");
+                       return errno;
+               }
+       }
+
+       blk_num = get_mmcblk_num();
+       if (blk_num  == -1) {
+               PRT_TRACE_ERR("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) {
+               PRT_TRACE_ERR("can't open the '%s': %s", buf, strerror(errno));
+               snprintf(buf, sizeof(buf), "%s%d", MMC_DEV, blk_num);
+       }
+       close(fd);
+
+       if (__check_mmc_fs_type(buf) != 0) {
+               PRT_TRACE_ERR("fail to check mount point %s", buf);
+               return -1;
+       }
+       snprintf(params, sizeof(params), "%d", inserted_type);
+       if (ss_action_entry_call_internal(PREDEF_CHECK_MMC_PROC, 2, params, buf) < 0) {
+               PRT_TRACE_ERR("fail to launch mmc checker,direct mount mmc");
+               ret = mmc_check_mount(0, NULL);
+       }
+       return ret;
+}
+
+int ss_mmc_inserted(void)
 {
+       int mmc_status;
        int ret;
-       if ((ret = umount2(MMC_MOUNT_POINT, MNT_DETACH)) != 0) {
-               PRT_TRACE_ERR("Failed to unmount mmc card\n");
+
+       vconf_get_int(VCONFKEY_SYSMAN_MMC_STATUS, &mmc_status);
+
+       if (mmc_status == VCONFKEY_SYSMAN_MMC_MOUNTED) {
+               PRT_DBG("Mmc is already mounted.\n");
+               vconf_set_int(VCONFKEY_SYSMAN_MMC_MOUNT, VCONFKEY_SYSMAN_MMC_MOUNT_ALREADY);
+               return 0;
        }
-       mmc_status = VCONFKEY_SYSMAN_MMC_REMOVED;
+
+       if ((ret = __check_mmc_fs()) != 0)
+               PRT_TRACE_ERR("fail to check mmc");
        return ret;
 }
-int ss_mmc_removed()
+
+int ss_mmc_removed(void)
 {
        int mmc_err = 0;
        vconf_set_int(VCONFKEY_SYSMAN_MMC_STATUS, VCONFKEY_SYSMAN_MMC_REMOVED);
@@ -399,3 +753,47 @@ int ss_mmc_removed()
 
        return 0;
 }
+
+static int ss_mmc_format(int argc, char **argv)
+{
+       PRT_TRACE_ERR("mmc format called");
+       __umount_fs();
+
+       vconf_set_int(VCONFKEY_SYSMAN_MMC_FORMAT_PROGRESS, VCONFKEY_SYSMAN_MMC_FORMAT_PROGRESS_NOW);
+       format_exec(get_mmcblk_num());
+       vconf_set_int(VCONFKEY_SYSMAN_MMC_FORMAT_PROGRESS, VCONFKEY_SYSMAN_MMC_FORMAT_PROGRESS_NONE);
+
+       if (__check_mmc_fs() != 0)
+               PRT_TRACE_ERR("fail to check mmc");
+
+       return 0;
+}
+
+static int ss_mmc_check_smack(int argc, char **argv)
+{
+       int smack_checked;
+       int pid;
+       system(FS_EXT4_SMACK_LABEL);
+       PRT_TRACE_ERR("smack labeling script is run(%d)", smack_checked);
+       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;
+}
+
+int ss_mmc_init(void)
+{
+       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);
+       ss_action_entry_add_internal(PREDEF_CHECK_MMC, mmc_check_mount, NULL, NULL);
+       ss_action_entry_add_internal(PREDEF_CHECK_MMC_PROC, mmc_check_process_launch, NULL, NULL);
+       /* mmc card mount */
+       if (__check_mmc_fs() != 0)
+               PRT_TRACE_ERR("fail to check mmc");
+       return 0;
+}