From: Krzysztof Sasiak Date: Wed, 17 Jul 2013 10:24:57 +0000 (+0900) Subject: separate main handling routine and file system dependent codes X-Git-Tag: submit/tizen_ivi_release/20140401.030119~107 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=refs%2Fchanges%2F40%2F14740%2F2;p=platform%2Fcore%2Fsystem%2Fsystem-server.git separate main handling routine and file system dependent codes Change-Id: I2b626119f70f037f7008f81b82b84f7d1f8c31a1 Signed-off-by: Krzysztof Sasiak --- diff --git a/CMakeLists.txt b/CMakeLists.txt index 3e01631..146bd18 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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 index 0000000..5522661 --- /dev/null +++ b/src/mmc/ext4.c @@ -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, +}; diff --git a/src/mmc/mmc-handler.c b/src/mmc/mmc-handler.c index 115cf03..e866621 100644 --- a/src/mmc/mmc-handler.c +++ b/src/mmc/mmc-handler.c @@ -35,123 +35,49 @@ #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 index 0000000..906f295 --- /dev/null +++ b/src/mmc/mmc-handler.h @@ -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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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 index 0000000..52de71f --- /dev/null +++ b/src/mmc/vfat.c @@ -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, +}; +