From 8e599e35e36966afe1b0abf761db00ce07eb34bf Mon Sep 17 00:00:00 2001 From: Wook Song Date: Fri, 18 Nov 2016 16:35:51 +0900 Subject: [PATCH] pass: Remove block module and related features This patch removes the block module, which is not required for pass. Several features related to the block module including TIZEN_FEATURE_BLOCK_SET_PERMISION and block_tmpfs are also eliminated as well. Signed-off-by: Wook Song --- CMakeLists.txt | 22 - packaging/pass.spec | 25 - scripts/mmc-smack-label | 12 - src/block/block.c | 2964 ----------------------------------------------- src/block/block.conf | 7 - src/block/block.h | 177 --- src/block/ext4.c | 178 --- src/block/mmc.c | 123 -- src/block/storage.c | 410 ------- src/block/storage.conf | 7 - src/block/vfat.c | 162 --- 11 files changed, 4087 deletions(-) delete mode 100755 scripts/mmc-smack-label delete mode 100644 src/block/block.c delete mode 100644 src/block/block.conf delete mode 100644 src/block/block.h delete mode 100644 src/block/ext4.c delete mode 100644 src/block/mmc.c delete mode 100755 src/block/storage.c delete mode 100644 src/block/storage.conf delete mode 100644 src/block/vfat.c diff --git a/CMakeLists.txt b/CMakeLists.txt index 05bdf40..e2c8598 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -80,14 +80,6 @@ SET(SRCS src/time/time-handler.c ) -IF(BLOCK_MODULE STREQUAL on) - ADD_SOURCE(src/block BLOCK_SRCS) - SET(SRCS ${SRCS} ${BLOCK_SRCS}) - IF(BLOCK_TMPFS STREQUAL on) - ADD_DEFINITIONS("-DBLOCK_TMPFS") - ENDIF(BLOCK_TMPFS STREQUAL on) -ENDIF() - IF(EXTCON_MODULE STREQUAL on) ADD_SOURCE(src/extcon EXTCON_SRCS) SET(SRCS ${SRCS} ${EXTCON_SRCS}) @@ -146,9 +138,6 @@ IF(DISPLAY_MODULE STREQUAL on) ENDIF() SET(PKG_MODULES ${PKG_MODULES} libinput capi-system-sensor) ENDIF() -IF(BLOCK_MODULE STREQUAL on) - SET(PKG_MODULES ${PKG_MODULES} storage app2sd capi-system-info) -ENDIF() INCLUDE(FindPkgConfig) pkg_check_modules(pkgs REQUIRED ${PKG_MODULES}) @@ -185,9 +174,6 @@ ELSEIF(USE_64BIT) ADD_DEFINITIONS("-DARCH_64BIT") ENDIF() ADD_DEFINITIONS("-DDEBUG") -IF(TIZEN_FEATURE_BLOCK_SET_PERMISSION STREQUAL on) - ADD_DEFINITIONS("-DTIZEN_FEATURE_BLOCK_SET_PERMISSION") -ENDIF(TIZEN_FEATURE_BLOCK_SET_PERMISSION STREQUAL on) ADD_EXECUTABLE(${PROJECT_NAME} ${SRCS}) TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${pkgs_LDFLAGS} "-ldl" "-lm" shared) @@ -198,14 +184,6 @@ INSTALL(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/src/deviced/ DESTINATION include/$ PATTERN "*_doc.h" EXCLUDE PATTERN "*.h") -IF(BLOCK_MODULE STREQUAL on) - INSTALL_CONF(src/block block) - INSTALL_CONF(src/block storage) - IF(TIZEN_FEATURE_BLOCK_SET_PERMISSION STREQUAL on) - INSTALL(PROGRAMS ${CMAKE_CURRENT_SOURCE_DIR}/scripts/mmc-smack-label DESTINATION bin) - ENDIF(TIZEN_FEATURE_BLOCK_SET_PERMISSION STREQUAL on) -ENDIF() - IF(DISPLAY_MODULE STREQUAL on) INSTALL_CONF(src/display display) ENDIF() diff --git a/packaging/pass.spec b/packaging/pass.spec index 9aec94e..b824f56 100644 --- a/packaging/pass.spec +++ b/packaging/pass.spec @@ -9,9 +9,6 @@ %define libdaemon_name lib%{daemon_name} # display, extcon, power, usb are always enable -%define block_module on -%define TIZEN_FEATURE_BLOCK_SET_PERMISSION on -%define block_tmpfs off %define display_module on %define extcon_module on %define haptic_module off @@ -30,11 +27,9 @@ %define touchscreen_module on %endif %if "%{?profile}" == "tv" -%define block_tmpfs on %endif %if "%{?profile}" == "ivi" %if "%{?_repository}" == "x86_64" -%define TIZEN_FEATURE_BLOCK_SET_PERMISSION off %endif %endif @@ -72,21 +67,11 @@ BuildRequires: pkgconfig(xext) BuildRequires: pkgconfig(libinput) BuildRequires: pkgconfig(capi-system-sensor) %endif -%if %{?block_module} == on -BuildRequires: pkgconfig(storage) -BuildRequires: pkgconfig(app2sd) -BuildRequires: pkgconfig(capi-system-info) -%endif Requires: %{name}-tools = %{version}-%{release} %{?systemd_requires} Requires(post): /usr/bin/vconftool -%if %{?block_module} == on -Requires: /usr/bin/fsck_msdosfs -Requires: /usr/bin/newfs_msdos -%endif - %description PASS (Power-Aware System Service) @@ -137,9 +122,6 @@ PASS systemd daemon. -DDPMS=%{DPMS} \ -DENGINEER_MODE=%{engineer_mode} \ -DPROFILE=%{profile} \ - -DBLOCK_MODULE=%{block_module} \ - -DTIZEN_FEATURE_BLOCK_SET_PERMISSION=%{TIZEN_FEATURE_BLOCK_SET_PERMISSION} \ - -DBLOCK_TMPFS=%{block_tmpfs} \ -DDISPLAY_MODULE=%{display_module} \ -DEXTCON_MODULE=%{extcon_module} \ -DHAPTIC_MODULE=%{haptic_module} \ @@ -201,13 +183,6 @@ systemctl daemon-reload %{_unitdir}/sockets.target.wants/%{daemon_name}.socket %{_unitdir}/%{daemon_name}.service %{_unitdir}/%{daemon_name}.socket -%if %{?block_module} == on -%if %{?TIZEN_FEATURE_BLOCK_SET_PERMISSION} == on -%{_bindir}/mmc-smack-label -%endif -%config %{_sysconfdir}/deviced/block.conf -%config %{_sysconfdir}/deviced/storage.conf -%endif %if %{?display_module} == on %config %{_sysconfdir}/deviced/display.conf %endif diff --git a/scripts/mmc-smack-label b/scripts/mmc-smack-label deleted file mode 100755 index c206758..0000000 --- a/scripts/mmc-smack-label +++ /dev/null @@ -1,12 +0,0 @@ -#!/bin/bash - -PATH=/bin:/usr/bin:/sbin:/usr/sbin - -source /etc/tizen-platform.conf -MOUNT_DIRECTORY=$1 -find $MOUNT_DIRECTORY -type d | xargs chsmack -a '*' -t -find $MOUNT_DIRECTORY -type f | xargs chsmack -a '*' -find $MOUNT_DIRECTORY -type d | xargs chmod 770 -find $MOUNT_DIRECTORY -type f | xargs chmod 660 -find $MOUNT_DIRECTORY -type d | xargs chown root:priv_externalstorage -find $MOUNT_DIRECTORY -type f | xargs chown root:priv_externalstorage diff --git a/src/block/block.c b/src/block/block.c deleted file mode 100644 index 47f2e8c..0000000 --- a/src/block/block.c +++ /dev/null @@ -1,2964 +0,0 @@ -/* - * deviced - * - * Copyright (c) 2012 - 2015 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. - */ - -#define _GNU_SOURCE - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "core/log.h" -#include "core/config-parser.h" -#include "core/device-idler.h" -#include "core/device-notifier.h" -#include "core/devices.h" -#include "core/udev.h" -#include "core/edbus-handler.h" -#include "core/list.h" -#include "block.h" - -/** - * TODO Assume root device is always mmcblk0*. - */ -#define MMC_PATH "*/mmcblk[0-9]*" -#define MMC_PARTITION_PATH "mmcblk[0-9]p[0-9]" -#define MMC_LINK_PATH "*/sdcard/*" -#define SCSI_PATH "*/sd[a-z]*" -#define SCSI_PARTITION_PATH "sd[a-z][0-9]" -#define SCSI_PARTITION_LENGTH 9 -#define EMUL_PATH "*/vd[a-z]*" -#define EMUL_PARTITION_PATH "vd[a-z][0-9]" - -#define FILESYSTEM "filesystem" - -#define DEV_PREFIX "/dev/" -#define ROOT_DIR "/" - -#define UNMOUNT_RETRY 5 -#define TIMEOUT_MAKE_OBJECT 500 /* milliseconds */ - -#define BLOCK_DEVICE_ADDED "DeviceAdded" -#define BLOCK_DEVICE_REMOVED "DeviceRemoved" -#define BLOCK_DEVICE_BLOCKED "DeviceBlocked" -#define BLOCK_DEVICE_CHANGED "DeviceChanged" -#define BLOCK_DEVICE_CHANGED_2 "DeviceChanged2" - -#define BLOCK_TYPE_MMC "mmc" -#define BLOCK_TYPE_SCSI "scsi" -#define BLOCK_TYPE_ALL "all" - -#define BLOCK_MMC_NODE_PREFIX "SDCard" -#define BLOCK_SCSI_NODE_PREFIX "USBDrive" - -#define BLOCK_CONF_FILE "/etc/deviced/block.conf" -#define MODEL_NAME "http://tizen.org/system/model_name" -#define MODEL_EMULATOR "Emulator" - -/* Minimum value of block id */ -#define BLOCK_ID_MIN 10 -/* For 2.4 Backward Compatibility */ -#define EXT_PRIMARY_SD_FIXID 1 - -/* Maximum number of thread */ -#define THREAD_MAX 5 - -enum block_dev_operation { - BLOCK_DEV_MOUNT, - BLOCK_DEV_UNMOUNT, - BLOCK_DEV_FORMAT, - BLOCK_DEV_INSERT, - BLOCK_DEV_REMOVE, -}; - -struct operation_queue { - enum block_dev_operation op; - DBusMessage *msg; - void *data; - bool done; -}; - -struct block_device { - struct block_data *data; - dd_list *op_queue; - int thread_id; /* Current thread ID */ - bool removed; /* True when device is physically removed but operation is not precessed yet */ -}; - -struct format_data { - struct block_device *bdev; - char *fs_type; - enum unmount_operation option; -}; - -struct pipe_data { - enum block_dev_operation op; - struct block_device *bdev; - int result; -}; - -static struct block_conf { - bool multimount; -} block_conf[BLOCK_MMC_DEV + 1]; - -static struct manage_thread { - dd_list *th_node_list; /* List of devnode which thread dealt with. Only main thread access */ - dd_list *block_dev_list; /* Use thread mutex */ - pthread_t th; - pthread_mutex_t mutex; - pthread_cond_t cond; - int num_dev; /* Number of devices which thread holds. Only main thread access */ - int op_len; /* Number of operation of thread. Use thread mutex */ - int thread_id; /* Never changed */ - bool start_th; -} th_manager[THREAD_MAX]; - -static dd_list *fs_head; -static dd_list *block_ops_list; -static bool smack; -static int pfds[2]; -static Ecore_Fd_Handler *phandler; -static bool block_control = false; -static bool block_boot = false; - -static bool emulator = false; - -/* Assume there is only one physical internal storage */ -static int dev_internal = -1; -static char dev_emul = '\0'; -static char dev_internal_scsi = '\0'; - -static int add_operation(struct block_device *bdev, - enum block_dev_operation operation, - DBusMessage *msg, void *data); -static void remove_operation(struct block_device *bdev); -static void check_removed(struct block_device *bdev, dd_list **queue, struct operation_queue **op); -static bool check_unmount(struct block_device *bdev, dd_list **queue, struct operation_queue **op); - -static void uevent_block_handler(struct udev_device *dev); -static struct uevent_handler uh = { - .subsystem = BLOCK_SUBSYSTEM, - .uevent_func = uevent_block_handler, -}; - -static void __CONSTRUCTOR__ smack_check(void) -{ - FILE *fp; - char buf[128]; - - fp = fopen("/proc/filesystems", "r"); - if (!fp) - return; - - while (fgets(buf, sizeof(buf), fp) != NULL) { - if (strstr(buf, "smackfs")) { - smack = true; - break; - } - } - - fclose(fp); -} - -void add_fs(const struct block_fs_ops *fs) -{ - DD_LIST_APPEND(fs_head, (void *)fs); -} - -void remove_fs(const struct block_fs_ops *fs) -{ - DD_LIST_REMOVE(fs_head, (void *)fs); -} - -const struct block_fs_ops *find_fs(enum block_fs_type type) -{ - struct block_fs_ops *fs; - dd_list *elem; - - DD_LIST_FOREACH(fs_head, elem, fs) { - if (fs->type == type) - return fs; - } - return NULL; -} - -void add_block_dev(const struct block_dev_ops *ops) -{ - DD_LIST_APPEND(block_ops_list, (void *)ops); -} - -void remove_block_dev(const struct block_dev_ops *ops) -{ - DD_LIST_REMOVE(block_ops_list, (void *)ops); -} - -static void broadcast_block_info(enum block_dev_operation op, - struct block_data *data, int result) -{ - struct block_dev_ops *ops; - dd_list *elem; - - DD_LIST_FOREACH(block_ops_list, elem, ops) { - if (ops->block_type != data->block_type) - continue; - if (op == BLOCK_DEV_MOUNT) - ops->mounted(data, result); - else if (op == BLOCK_DEV_UNMOUNT) - ops->unmounted(data, result); - else if (op == BLOCK_DEV_FORMAT) - ops->formatted(data, result); - else if (op == BLOCK_DEV_INSERT) - ops->inserted(data); - else if (op == BLOCK_DEV_REMOVE) - ops->removed(data); - } -} - -// Called by MainThread - Insert -static int block_get_new_id(void) -{ - static int id = BLOCK_ID_MIN; - struct block_device *bdev; - dd_list *elem; - bool found; - int i, j; - - for (i = 0 ; i < INT_MAX ; i++) { - found = false; - for (j = 0; j < THREAD_MAX; j++) { - pthread_mutex_lock(&(th_manager[j].mutex)); - DD_LIST_FOREACH(th_manager[j].block_dev_list, elem, bdev) { - if (bdev->data->id == id) { - found = true; - break; - } - } - pthread_mutex_unlock(&(th_manager[j].mutex)); - if (found) - break; - } - - if (!found) - return id++; - - if (++id == INT_MAX) - id = BLOCK_ID_MIN; - } - - return -ENOENT; -} - -static void signal_device_blocked(struct block_device *bdev) -{ - struct block_data *data; - char *arr[13]; - char str_block_type[32]; - char str_readonly[32]; - char str_state[32]; - char str_primary[32]; - char str_flags[32]; - char str_id[32]; - char *str_null = ""; - int flags; - - if (!bdev || !bdev->data) - return; - - data = bdev->data; - flags = 0; - - /* Broadcast outside with BlockManager iface */ - snprintf(str_block_type, sizeof(str_block_type), - "%d", data->block_type); - arr[0] = str_block_type; - arr[1] = (data->devnode ? data->devnode : str_null); - arr[2] = (data->syspath ? data->syspath : str_null); - arr[3] = (data->fs_usage ? data->fs_usage : str_null); - arr[4] = (data->fs_type ? data->fs_type : str_null); - arr[5] = (data->fs_version ? data->fs_version : str_null); - arr[6] = (data->fs_uuid_enc ? data->fs_uuid_enc : str_null); - snprintf(str_readonly, sizeof(str_readonly), - "%d", data->readonly); - arr[7] = str_readonly; - arr[8] = (data->mount_point ? data->mount_point : str_null); - snprintf(str_state, sizeof(str_state), - "%d", data->state); - arr[9] = str_state; - snprintf(str_primary, sizeof(str_primary), - "%d", data->primary); - arr[10] = str_primary; - snprintf(str_flags, sizeof(str_flags), "%d", flags); - arr[11] = str_flags; - snprintf(str_id, sizeof(str_id), "%d", data->id); - arr[12] = str_id; - - - broadcast_block_edbus_signal(DEVICED_PATH_BLOCK_MANAGER, - DEVICED_INTERFACE_BLOCK_MANAGER, - BLOCK_DEVICE_BLOCKED, - "issssssisibii", arr); -} - -static void signal_device_changed(struct block_device *bdev, - enum block_dev_operation op) -{ - struct block_data *data; - char *arr[13]; - char str_block_type[32]; - char str_readonly[32]; - char str_state[32]; - char str_primary[32]; - char str_flags[32]; - char str_id[32]; - char *str_null = ""; - int flags; - - if (!bdev || !bdev->data) - return; - - data = bdev->data; - - switch (op) { - case BLOCK_DEV_MOUNT: - BLOCK_GET_MOUNT_FLAGS(data, flags); - break; - case BLOCK_DEV_UNMOUNT: - BLOCK_GET_UNMOUNT_FLAGS(data, flags); - break; - case BLOCK_DEV_FORMAT: - BLOCK_GET_FORMAT_FLAGS(data, flags); - break; - default: - flags = 0; - break; - } - - /* Broadcast outside with BlockManager iface */ - snprintf(str_block_type, sizeof(str_block_type), - "%d", data->block_type); - arr[0] = str_block_type; - arr[1] = (data->devnode ? data->devnode : str_null); - arr[2] = (data->syspath ? data->syspath : str_null); - arr[3] = (data->fs_usage ? data->fs_usage : str_null); - arr[4] = (data->fs_type ? data->fs_type : str_null); - arr[5] = (data->fs_version ? data->fs_version : str_null); - arr[6] = (data->fs_uuid_enc ? data->fs_uuid_enc : str_null); - snprintf(str_readonly, sizeof(str_readonly), - "%d", data->readonly); - arr[7] = str_readonly; - arr[8] = (data->mount_point ? data->mount_point : str_null); - snprintf(str_state, sizeof(str_state), - "%d", data->state); - arr[9] = str_state; - snprintf(str_primary, sizeof(str_primary), - "%d", data->primary); - arr[10] = str_primary; - snprintf(str_flags, sizeof(str_flags), "%d", flags); - arr[11] = str_flags; - snprintf(str_id, sizeof(str_id), "%d", data->id); - arr[12] = str_id; - - if (op == BLOCK_DEV_INSERT) - broadcast_block_edbus_signal(DEVICED_PATH_BLOCK_MANAGER, - DEVICED_INTERFACE_BLOCK_MANAGER, - BLOCK_DEVICE_ADDED, - "issssssisibii", arr); - else if (op == BLOCK_DEV_REMOVE) - broadcast_block_edbus_signal(DEVICED_PATH_BLOCK_MANAGER, - DEVICED_INTERFACE_BLOCK_MANAGER, - BLOCK_DEVICE_REMOVED, - "issssssisibii", arr); - else { - broadcast_block_edbus_signal(DEVICED_PATH_BLOCK_MANAGER, - DEVICED_INTERFACE_BLOCK_MANAGER, - BLOCK_DEVICE_CHANGED, - "issssssisibii", arr); - broadcast_block_edbus_signal(DEVICED_PATH_BLOCK_MANAGER, - DEVICED_INTERFACE_BLOCK_MANAGER, - BLOCK_DEVICE_CHANGED_2, - "issssssisibi", arr); - } -} - -static int get_mmc_mount_node(char *devnode, char *node, size_t len) -{ - char *name = devnode; - int dev = -1, part = -1; - char emul[32] = { 0, }; - int i; - - if (!name) - return -EINVAL; - - /* Check Target */ - sscanf(name, "mmcblk%dp%d", &dev, &part); - if (dev >= 0) { - if (part < 0) - snprintf(node, len, "%s%c", BLOCK_MMC_NODE_PREFIX, dev + 'A' - 1); - else - snprintf(node, len, "%s%c%d", BLOCK_MMC_NODE_PREFIX, dev + 'A' - 1, part); - return 0; - } - - /* Check Emulator */ - sscanf(name, "vd%s", emul); - if (emul[0] == '\0') - return -EINVAL; - for (i = 0 ; i < strlen(emul) ; i++) - emul[i] = toupper(emul[i]); - snprintf(node, len, "%s%s", BLOCK_MMC_NODE_PREFIX, emul); - return 0; -} - -static int get_scsi_mount_node(char *devnode, char *node, size_t len) -{ - char dev[64], *name; - int i; - - if (!devnode) - return -EINVAL; - - snprintf(dev, sizeof(dev), "%s", devnode); - - if (!strstr(dev, "sd")) - return -EINVAL; - - name = dev; - name += strlen("sd"); - - for (i = 0 ; i < strlen(name) ; i++) - name[i] = toupper(name[i]); - snprintf(node, len, "%s%s", BLOCK_SCSI_NODE_PREFIX, name); - - return 0; -} - -static char *generate_mount_path(struct block_data *data) -{ - const char *str; - char *name, node[64]; - int ret; - - if (!data || !data->devnode) - return NULL; - - name = strrchr(data->devnode, '/'); - if (!name) - goto out; - name++; - - switch (data->block_type) { - case BLOCK_MMC_DEV: - ret = get_mmc_mount_node(name, node, sizeof(node)); - break; - case BLOCK_SCSI_DEV: - ret = get_scsi_mount_node(name, node, sizeof(node)); - break; - default: - _E("Invalid block type (%d)", data->block_type); - return NULL; - } - if (ret < 0) - goto out; - - str = tzplatform_mkpath(TZ_SYS_MEDIA, node); - if (!str) - return NULL; - return strdup(str); - -out: - _E("Invalid devnode (%s)", data->devnode ? data->devnode : "NULL"); - return NULL; -} - -static bool check_primary_partition(const char *devnode) -{ - char str[PATH_MAX]; - char str2[PATH_MAX]; - int len; - int i; - - /* if no partition */ - if (!fnmatch(MMC_LINK_PATH, devnode, 0) || - !fnmatch(MMC_PATH, devnode, 0) || - !fnmatch(SCSI_PATH, devnode, 0)) - return true; - - snprintf(str, sizeof(str), "%s", devnode); - - len = strlen(str); - str[len - 1] = '\0'; - - for (i = 1; i < 9; ++i) { - snprintf(str2, sizeof(str2), "%s%d", str, i); - if (access(str2, R_OK) == 0) - break; - } - - if (!strncmp(devnode, str2, strlen(str2) + 1)) - return true; - - return false; -} - -/* Whole data in struct block_data should be freed. */ -static struct block_data *make_block_data(const char *devnode, - const char *syspath, - const char *fs_usage, - const char *fs_type, - const char *fs_version, - const char *fs_uuid_enc, - const char *readonly) -{ - struct block_data *data; - - /* devnode is unique value so it should exist. */ - if (!devnode) - return NULL; - - data = calloc(1, sizeof(struct block_data)); - if (!data) - return NULL; - - data->devnode = strdup(devnode); - if (syspath) - data->syspath = strdup(syspath); - if (fs_usage) - data->fs_usage = strdup(fs_usage); - if (fs_type) - data->fs_type = strdup(fs_type); - if (fs_version) - data->fs_version = strdup(fs_version); - if (fs_uuid_enc) - data->fs_uuid_enc = strdup(fs_uuid_enc); - if (readonly) - data->readonly = atoi(readonly); - data->primary = check_primary_partition(devnode); - - /* TODO should we know block dev type? */ - if (!fnmatch(MMC_LINK_PATH, devnode, 0)) - data->block_type = BLOCK_MMC_DEV; - else if (!fnmatch(MMC_PATH, devnode, 0)) - data->block_type = BLOCK_MMC_DEV; - else if (!fnmatch(SCSI_PATH, devnode, 0)) - data->block_type = BLOCK_SCSI_DEV; - else - data->block_type = -1; - - data->mount_point = generate_mount_path(data); - BLOCK_FLAG_CLEAR_ALL(data); - - /* for 2.4 backward compatibility */ - if (data->primary == true && data->block_type == BLOCK_MMC_DEV) - data->id = EXT_PRIMARY_SD_FIXID; - else - data->id = block_get_new_id(); - - return data; -} - -static void free_block_data(struct block_data *data) -{ - if (!data) - return; - free(data->devnode); - free(data->syspath); - free(data->fs_usage); - free(data->fs_type); - free(data->fs_version); - free(data->fs_uuid_enc); - free(data->mount_point); - free(data); -} - -static int update_block_data(struct block_data *data, - const char *fs_usage, - const char *fs_type, - const char *fs_version, - const char *fs_uuid_enc, - const char *readonly) -{ - if (!data) - return -EINVAL; - - free(data->fs_usage); - data->fs_usage = NULL; - if (fs_usage) - data->fs_usage = strdup(fs_usage); - - free(data->fs_type); - data->fs_type = NULL; - if (fs_type) - data->fs_type = strdup(fs_type); - - free(data->fs_version); - data->fs_version = NULL; - if (fs_version) - data->fs_version = strdup(fs_version); - - free(data->fs_uuid_enc); - data->fs_uuid_enc = NULL; - if (fs_uuid_enc) - data->fs_uuid_enc = strdup(fs_uuid_enc); - - /* generate_mount_path function should be invoked - * after fs_uuid_enc is updated */ - free(data->mount_point); - data->mount_point = generate_mount_path(data); - - data->readonly = false; - if (readonly) - data->readonly = atoi(readonly); - - BLOCK_FLAG_MOUNT_CLEAR(data); - - return 0; -} - -static struct block_device *make_block_device(struct block_data *data) -{ - struct block_device *bdev; - - if (!data) - return NULL; - - bdev = calloc(1, sizeof(struct block_device)); - if (!bdev) - return NULL; - - bdev->data = data; - bdev->thread_id = -1; - bdev->removed = false; - - return bdev; -} - -// Called by MainThread - Remove DevNode -static void free_block_device(struct block_device *bdev) -{ - dd_list *l, *next; - struct operation_queue *op; - int thread_id; - - if (!bdev) - return; - - thread_id = bdev->thread_id; - if (thread_id < 0 || thread_id >= THREAD_MAX) - return; - - pthread_mutex_lock(&(th_manager[thread_id].mutex)); - - th_manager[thread_id].num_dev--; - DD_LIST_REMOVE(th_manager[thread_id].block_dev_list, bdev); - free_block_data(bdev->data); - - DD_LIST_FOREACH_SAFE(bdev->op_queue, l, next, op) { - if (!op->done) - th_manager[thread_id].op_len--; - DD_LIST_REMOVE(bdev->op_queue, op); - free(op); - } - pthread_mutex_unlock(&(th_manager[thread_id].mutex)); - - free(bdev); -} - -// Called By MainThread - Remove Device -static struct block_device *find_block_device(const char *devnode) -{ - struct block_device *bdev; - dd_list *elem; - int len; - int i; - - len = strlen(devnode) + 1; - for (i = 0; i < THREAD_MAX; i++) { - pthread_mutex_lock(&(th_manager[i].mutex)); - DD_LIST_FOREACH(th_manager[i].block_dev_list, elem, bdev) { - if (bdev->data && - !strncmp(bdev->data->devnode, devnode, len)) { - pthread_mutex_unlock(&(th_manager[i].mutex)); - return bdev; - } - } - pthread_mutex_unlock(&(th_manager[i].mutex)); - } - - return NULL; -} - -// Called By MainThread - Mount,Unmount,Format,GetInfo -static struct block_device *find_block_device_by_id(int id) -{ - struct block_device *bdev; - dd_list *elem; - int i; - - for (i = 0; i < THREAD_MAX; i++) { - pthread_mutex_lock(&(th_manager[i].mutex)); - DD_LIST_FOREACH(th_manager[i].block_dev_list, elem, bdev) { - if (!bdev->data) - continue; - if (bdev->data->id == id) { - pthread_mutex_unlock(&(th_manager[i].mutex)); - return bdev; - } - } - pthread_mutex_unlock(&(th_manager[i].mutex)); - } - - return NULL; -} - -static char *get_operation_char(enum block_dev_operation op, - char *name, unsigned int len) -{ - char *str = "unknown"; - - if (!name) - return NULL; - - switch (op) { - case BLOCK_DEV_MOUNT: - str = "MOUNT"; - break; - case BLOCK_DEV_UNMOUNT: - str = "UNMOUNT"; - break; - case BLOCK_DEV_FORMAT: - str = "FORMAT"; - break; - case BLOCK_DEV_INSERT: - str = "INSERT"; - break; - case BLOCK_DEV_REMOVE: - str = "REMOVE"; - break; - default: - _E("invalid operation (%d)", op); - break; - } - - snprintf(name, len, "%s", str); - return name; -} - -static int pipe_trigger(enum block_dev_operation op, - struct block_device *bdev, int result) -{ - struct pipe_data pdata = { op, bdev, result }; - int n; - char name[16]; - - _D("op : %s, bdev : %p, result : %d", - get_operation_char(pdata.op, name, sizeof(name)), - pdata.bdev, pdata.result); - - n = write(pfds[1], &pdata, sizeof(struct pipe_data)); - - return (n != sizeof(struct pipe_data)) ? -EPERM : 0; -} - -static Eina_Bool pipe_cb(void *data, Ecore_Fd_Handler *fdh) -{ - struct pipe_data pdata = {0,}; - int fd; - int n; - int thread_id; - char name[16]; - - if (ecore_main_fd_handler_active_get(fdh, ECORE_FD_ERROR)) { - _E("an error has occured. Ignore it."); - goto out; - } - - fd = ecore_main_fd_handler_fd_get(fdh); - if (fd <= 0) { - _E("fail to get fd"); - goto out; - } - - n = read(fd, &pdata, sizeof(pdata)); - if (n != sizeof(pdata) || !pdata.bdev) { - _E("fail to read struct pipe data"); - goto out; - } - - _D("op : %s, bdev : %p, result : %d", - get_operation_char(pdata.op, name, sizeof(name)), - pdata.bdev, pdata.result); - - /* Broadcast to mmc and usb storage module */ - broadcast_block_info(pdata.op, pdata.bdev->data, pdata.result); - - /* Broadcast outside with Block iface */ - signal_device_changed(pdata.bdev, pdata.op); - - if (pdata.op == BLOCK_DEV_REMOVE) { - thread_id = pdata.bdev->thread_id; - if (thread_id < 0 || thread_id >= THREAD_MAX) - return ECORE_CALLBACK_RENEW; - free_block_device(pdata.bdev); - } - -out: - return ECORE_CALLBACK_RENEW; - -} - -static int pipe_init(void) -{ - int ret; - - ret = pipe2(pfds, O_CLOEXEC); - if (ret == -1) - return -errno; - - phandler = ecore_main_fd_handler_add(pfds[0], - ECORE_FD_READ | ECORE_FD_ERROR, - pipe_cb, NULL, NULL, NULL); - if (!phandler) - return -EPERM; - - return 0; -} - -static void pipe_exit(void) -{ - if (phandler) { - ecore_main_fd_handler_del(phandler); - phandler = NULL; - } - - if (pfds[0]) - close(pfds[0]); - if (pfds[1]) - close(pfds[1]); -} - -static int mmc_check_and_unmount(const char *path) -{ - int ret = 0; - int retry = 0; - - if (!path) - return 0; - - while (mount_check(path)) { - ret = umount(path); - if (ret < 0) { - retry++; - if (retry > UNMOUNT_RETRY) - return -errno; - } - } - return ret; -} - -static bool check_rw_mount(const char *szPath) -{ - struct statvfs mount_stat; - - if (!statvfs(szPath, &mount_stat)) { - if ((mount_stat.f_flag & ST_RDONLY) == ST_RDONLY) - return false; - } - return true; -} - -static int retrieve_udev_device(struct block_data *data) -{ - struct udev *udev; - struct udev_device *dev; - int r; - - if (!data) - return -EINVAL; - - udev = udev_new(); - if (!udev) { - _E("fail to create udev library context"); - return -EPERM; - } - - dev = udev_device_new_from_syspath(udev, data->syspath); - if (!dev) { - _E("fail to create new udev device"); - udev_unref(udev); - return -EPERM; - } - - r = update_block_data(data, - udev_device_get_property_value(dev, "ID_FS_USAGE"), - udev_device_get_property_value(dev, "ID_FS_TYPE"), - udev_device_get_property_value(dev, "ID_FS_VERSION"), - udev_device_get_property_value(dev, "ID_FS_UUID_ENC"), - udev_device_get_sysattr_value(dev, "ro")); - if (r < 0) - _E("fail to update block data for %s", data->devnode); - - udev_device_unref(dev); - udev_unref(udev); - return r; -} - -static int block_mount(struct block_data *data) -{ - struct block_fs_ops *fs; - dd_list *elem; - int r; - int len; - - if (!data || !data->devnode || !data->mount_point) - return -EINVAL; - - /* check existing mounted */ - if (mount_check(data->mount_point)) - return -EEXIST; - - /* create mount point */ - if (access(data->mount_point, R_OK) != 0) { - if (mkdir(data->mount_point, 0755) < 0) - return -errno; - } - - /* check matched file system */ - if (!data->fs_usage || - strncmp(data->fs_usage, FILESYSTEM, - sizeof(FILESYSTEM)) != 0) { - r = -ENODEV; - goto out; - } - - if (!data->fs_type) { - _E("There is no file system"); - BLOCK_FLAG_SET(data, FS_EMPTY); - r = -ENODATA; - goto out; - } - - fs = NULL; - len = strlen(data->fs_type) + 1; - DD_LIST_FOREACH(fs_head, elem, fs) { - if (!strncmp(fs->name, data->fs_type, len)) - break; - } - - if (!fs) { - _E("Not supported file system (%s)", data->fs_type); - BLOCK_FLAG_SET(data, FS_NOT_SUPPORTED); - r = -ENOTSUP; - goto out; - } - - r = fs->mount(smack, data->devnode, data->mount_point); - - if (r == -EIO) - BLOCK_FLAG_SET(data, FS_BROKEN); - - if (r < 0) - goto out; - - r = check_rw_mount(data->mount_point); - if (!r) - return -EROFS; - - return 0; - -out: - rmdir(data->mount_point); - return r; -} - -static int mount_start(struct block_device *bdev) -{ - struct block_data *data; - int r; - - assert(bdev); - assert(bdev->data); - - data = bdev->data; - _I("Mount Start : (%s -> %s)", - data->devnode, data->mount_point); - - /* mount operation */ - r = block_mount(data); - if (r != -EROFS && r < 0) { - _E("fail to mount %s device : %d", data->devnode, r); - goto out; - } - - if (r == -EROFS) { - data->readonly = true; - BLOCK_FLAG_SET(data, MOUNT_READONLY); - } - - data->state = BLOCK_MOUNT; - -out: - _I("%s result : %s, %d", __func__, data->devnode, r); - - if (pipe_trigger(BLOCK_DEV_MOUNT, bdev, r) < 0) - _E("fail to trigger pipe"); - - return r; -} - -static int change_mount_point(struct block_device *bdev, - const char *mount_point) -{ - struct block_data *data; - - if (!bdev) - return -EINVAL; - - data = bdev->data; - free(data->mount_point); - - /* If the mount path already exists, the path cannot be used */ - if (mount_point && - access(mount_point, F_OK) != 0) - data->mount_point = strdup(mount_point); - else - data->mount_point = generate_mount_path(data); - - return 0; -} - -static int mount_block_device(struct block_device *bdev) -{ - struct block_data *data; - int r; - - if (!bdev || !bdev->data) - return -EINVAL; - - data = bdev->data; - if (data->state == BLOCK_MOUNT) { - _I("%s is already mounted", data->devnode); - return 0; - } - - if (!block_conf[data->block_type].multimount && - !data->primary) { - _I("Not support multi mount by config info"); - return 0; - } - - r = mount_start(bdev); - if (r < 0) { - _E("Failed to mount (%d)", data->devnode); - return r; - } - - return 0; -} - -static int block_unmount(struct block_device *bdev, - enum unmount_operation option) -{ - struct block_data *data; - int r, retry = 0; - struct timespec time = {0,}; - - if (!bdev || !bdev->data || !bdev->data->mount_point) - return -EINVAL; - - data = bdev->data; - - signal_device_blocked(bdev); - - /* Need to disble app2ext whenever unmounting mmc */ - if (data->block_type == BLOCK_MMC_DEV && data->primary) - if (app2ext_disable_all_external_pkgs() < 0) - _E("app2ext_disable_all_external_pkgs() failed"); - - /* it must called before unmounting mmc */ - r = mmc_check_and_unmount(data->mount_point); - if (!r) - goto out; - if (option == UNMOUNT_NORMAL) { - _I("Failed to unmount with normal option : %d", r); - return r; - } - - _I("Execute force unmount!"); - /* Force Unmount Scenario */ - while (1) { - switch (retry++) { - case 0: - /* At first, notify to other app - * who already access sdcard */ - _I("Notify to other app who already access sdcard"); - - /* Mobile specific: - * should unmount the below vconf key. */ - if (data->block_type == BLOCK_MMC_DEV && data->primary) - vconf_set_int(VCONFKEY_SYSMAN_MMC_STATUS, - VCONFKEY_SYSMAN_MMC_INSERTED_NOT_MOUNTED); - break; - case 1: - /* Second, kill app with SIGTERM */ - _I("Kill app with SIGTERM"); - terminate_process(data->mount_point, false); - break; - case 2: - /* Last time, kill app with SIGKILL */ - _I("Kill app with SIGKILL"); - terminate_process(data->mount_point, true); - break; - default: - if (umount2(data->mount_point, MNT_DETACH) != 0) { - _I("Failed to unmount with lazy option : %d", - errno); - return -errno; - } - goto out; - } - - /* it takes some seconds til other app completely clean up */ - time.tv_nsec = 500 * NANO_SECOND_MULTIPLIER; - nanosleep(&time, NULL); - - /* Need to disble app2ext whenever unmounting mmc */ - if (data->block_type == BLOCK_MMC_DEV && data->primary) - if (app2ext_disable_all_external_pkgs() < 0) - _E("app2ext_disable_all_external_pkgs() failed"); - - r = mmc_check_and_unmount(data->mount_point); - if (!r) { - _E("Failed to unmount (%d)", data->mount_point); - break; - } - } - -out: - data->state = BLOCK_UNMOUNT; - - if (rmdir(data->mount_point) < 0) - _E("fail to remove %s directory", data->mount_point); - - return r; -} - -static int unmount_block_device(struct block_device *bdev, - enum unmount_operation option) -{ - struct block_data *data; - int r; - - if (!bdev || !bdev->data) - return -EINVAL; - - data = bdev->data; - if (data->state == BLOCK_UNMOUNT) { - _I("%s is already unmounted", data->devnode); - r = mmc_check_and_unmount(data->mount_point); - if (r < 0) - _E("The path was existed, but could not delete it(%s)", - data->mount_point); - return 0; - } - - _I("Unmount Start : (%s -> %s)", - data->devnode, data->mount_point); - - r = block_unmount(bdev, option); - if (r < 0) { - _E("fail to unmount %s device : %d", data->devnode, r); - goto out; - } - - BLOCK_FLAG_MOUNT_CLEAR(data); - -out: - _I("%s result : %s, %d", __func__, data->devnode, r); - - if (pipe_trigger(BLOCK_DEV_UNMOUNT, bdev, r) < 0) - _E("fail to trigger pipe"); - - return r; -} - -static int block_format(struct block_data *data, - const char *fs_type) -{ - const struct block_fs_ops *fs; - dd_list *elem; - int len; - int r; - - if (!data || !data->devnode || !data->mount_point) - return -EINVAL; - - if (!fs_type) - fs_type = data->fs_type; - - fs = NULL; - len = strlen(fs_type); - DD_LIST_FOREACH(fs_head, elem, fs) { - if (!strncmp(fs->name, fs_type, len)) - break; - } - - if (!fs) { - BLOCK_FLAG_SET(data, FS_NOT_SUPPORTED); - _E("not supported file system(%s)", fs_type); - return -ENOTSUP; - } - - _I("format path : %s", data->devnode); - fs->check(data->devnode); - r = fs->format(data->devnode); - if (r < 0) { - _E("fail to format block data for %s", data->devnode); - goto out; - } - - /* need to update the partition data. - * It can be changed in doing format. */ - retrieve_udev_device(data); - -out: - return r; -} - -static int format_block_device(struct block_device *bdev, - const char *fs_type, - enum unmount_operation option) -{ - struct block_data *data; - int r; - - assert(bdev); - assert(bdev->data); - - data = bdev->data; - - _I("Format Start : (%s -> %s)", - data->devnode, data->mount_point); - - if (data->state == BLOCK_MOUNT) { - r = block_unmount(bdev, option); - if (r < 0) { - _E("fail to unmount %s device : %d", data->devnode, r); - goto out; - } - } - - r = block_format(data, fs_type); - if (r < 0) - _E("fail to format %s device : %d", data->devnode, r); - -out: - _I("%s result : %s, %d", __func__, data->devnode, r); - - r = pipe_trigger(BLOCK_DEV_FORMAT, bdev, r); - if (r < 0) - _E("fail to trigger pipe"); - - return r; -} - -static struct format_data *get_format_data( - const char *fs_type, enum unmount_operation option) -{ - struct format_data *fdata; - - fdata = (struct format_data *)malloc(sizeof(struct format_data)); - if (!fdata) { - _E("fail to allocate format data"); - return NULL; - } - - if (fs_type) - fdata->fs_type = strdup(fs_type); - else - fdata->fs_type = NULL; - fdata->option = option; - - return fdata; -} - -static void release_format_data(struct format_data *data) -{ - if (data) { - free(data->fs_type); - free(data); - } -} - -// Called by BlockThread - Real Mount Op -static int block_mount_device(struct block_device *bdev, void *data) -{ - dd_list *l; - int ret; - int thread_id; - - if (!bdev) - return -EINVAL; - - thread_id = bdev->thread_id; - if (thread_id < 0 || thread_id >= THREAD_MAX) - return -EINVAL; - pthread_mutex_lock(&(th_manager[thread_id].mutex)); - l = DD_LIST_FIND(th_manager[thread_id].block_dev_list, bdev); - pthread_mutex_unlock(&(th_manager[thread_id].mutex)); - if (!l) { - _E("(%d) does not exist in the device list", bdev->data->devnode); - return -ENOENT; - } - - /* mount automatically */ - ret = mount_block_device(bdev); - if (ret < 0) - _E("fail to mount block device for %s", bdev->data->devnode); - - return ret; -} - -// Called by BlockThread - Real Format Op -static int block_format_device(struct block_device *bdev, void *data) -{ - dd_list *l; - int ret; - int thread_id; - struct format_data *fdata = (struct format_data *)data; - - if (!bdev || !fdata) { - ret = -EINVAL; - goto out; - } - - thread_id = bdev->thread_id; - if (thread_id < 0 || thread_id >= THREAD_MAX) - return -EINVAL; - pthread_mutex_lock(&(th_manager[thread_id].mutex)); - l = DD_LIST_FIND(th_manager[thread_id].block_dev_list, bdev); - pthread_mutex_unlock(&(th_manager[thread_id].mutex)); - if (!l) { - _E("(%d) does not exist in the device list", bdev->data->devnode); - ret = -ENOENT; - goto out; - } - - ret = format_block_device(bdev, fdata->fs_type, fdata->option); - if (ret < 0) - _E("fail to mount block device for %s", bdev->data->devnode); - -out: - release_format_data(fdata); - - return ret; -} - -// Called by BlockThread - Real Unmount Op -static int block_unmount_device(struct block_device *bdev, void *data) -{ - int ret; - long option = (long)data; - - if (!bdev) - return -EINVAL; - - ret = unmount_block_device(bdev, option); - if (ret < 0) { - _E("Failed to unmount block device (%s)", bdev->data->devnode); - return ret; - } - - return 0; -} - -/* Called by BlockThread - Remove Operation - Direct Call at BlockThread - Previously this function was called by MainThread. However, it will increase complexity. - Need thread lock before to call remove_operation -*/ -static void remove_operation(struct block_device *bdev) -{ - struct operation_queue *op; - dd_list *l, *next; - char name[16]; - int thread_id; - - assert(bdev); - - thread_id = bdev->thread_id; - if (thread_id < 0 || thread_id >= THREAD_MAX) - return; - - DD_LIST_FOREACH_SAFE(bdev->op_queue, l, next, op) { - if (op->done) { - _D("Remove operation (%s, %s)", - get_operation_char(op->op, name, sizeof(name)), - bdev->data->devnode); - - DD_LIST_REMOVE(bdev->op_queue, op); - free(op); - } - } -} - -static void block_send_dbus_reply(DBusMessage *msg, int result) -{ - DBusMessage *rep; - int ret; - DBusConnection *conn = NULL; - - if (!msg) - return; - - conn = get_block_dbus_connection(); - if (!conn) { - _E("dbus_bus_get error"); - return; - } - - rep = make_reply_message(msg, result); - ret = dbus_connection_send(conn, rep, NULL); - dbus_message_unref(msg); - dbus_message_unref(rep); - - if (ret == TRUE) - _I("Success to send reply"); - else - _E("Failed to send reply"); -} - -// Called by BlockThread -static void check_removed(struct block_device *bdev, dd_list **queue, struct operation_queue **op) -{ - struct operation_queue *temp; - dd_list *l; - int thread_id; - - if (!bdev) - return; - - if (!queue) - return; - - if (!op) - return; - - thread_id = bdev->thread_id; - if (thread_id < 0 || thread_id >= THREAD_MAX) - return; - - pthread_mutex_lock(&(th_manager[thread_id].mutex)); - - DD_LIST_FOREACH(*queue, l, temp) { - if (temp->op == BLOCK_DEV_REMOVE) { - *op = temp; - break; - } - temp->done = true; - th_manager[thread_id].op_len--; - block_send_dbus_reply((*op)->msg, 0); - } - - remove_operation(bdev); - pthread_mutex_unlock(&(th_manager[thread_id].mutex)); -} - -// Called by BlockThread -static bool check_unmount(struct block_device *bdev, dd_list **queue, struct operation_queue **op) -{ - struct operation_queue *temp; - dd_list *l; - int thread_id; - bool unmounted = false; - - if (!bdev) - return false; - - if (!queue) - return false; - - if (!op) - return false; - - thread_id = bdev->thread_id; - if (thread_id < 0 || thread_id >= THREAD_MAX) - return false; - - pthread_mutex_lock(&(th_manager[thread_id].mutex)); - DD_LIST_FOREACH(*queue, l, temp) { - if (temp->op == BLOCK_DEV_UNMOUNT) { - unmounted = true; - _D("Operation queue has unmount operation"); - break; - } - } - pthread_mutex_unlock(&(th_manager[thread_id].mutex)); - - if (!unmounted) - return unmounted; - - pthread_mutex_lock(&(th_manager[thread_id].mutex)); - - DD_LIST_FOREACH(*queue, l, temp) { - if (temp->op == BLOCK_DEV_UNMOUNT) { - *op = temp; - break; - } - temp->done = true; - th_manager[thread_id].op_len--; - block_send_dbus_reply((*op)->msg, 0); - } - - remove_operation(bdev); - pthread_mutex_unlock(&(th_manager[thread_id].mutex)); - - return unmounted; -} - -// Called by BlockThread -static void trigger_operation(struct block_device *bdev, dd_list *queue, struct operation_queue *op) -{ - int ret = 0; - int thread_id; - char devnode[PATH_MAX]; - char name[16]; - enum block_dev_operation operation; - bool unmounted = false; - - assert(bdev); - - if (!queue) - return; - - thread_id = bdev->thread_id; - if (thread_id < 0 || thread_id >= THREAD_MAX) - return; - - snprintf(devnode, sizeof(devnode), "%s", bdev->data->devnode); - - do { - if (!op) - return; - if (op->done) - return; - - operation = op->op; - - _D("Thread id %d Trigger operation (%s, %s)", thread_id, - get_operation_char(operation, name, sizeof(name)), devnode); - - unmounted = false; - if (operation == BLOCK_DEV_INSERT && bdev->removed) { - check_removed(bdev, &queue, &op); - operation = op->op; - _D("Trigger operation again (%s, %s)", - get_operation_char(operation, name, sizeof(name)), devnode); - } - if (operation == BLOCK_DEV_MOUNT) { - unmounted = check_unmount(bdev, &queue, &op); - if (unmounted) { - operation = op->op; - _D("Trigger operation again (%s, %s)", - get_operation_char(operation, name, sizeof(name)), devnode); - } - } - - switch (operation) { - case BLOCK_DEV_INSERT: - break; - case BLOCK_DEV_MOUNT: - ret = block_mount_device(bdev, op->data); - _D("Mount (%s) result:(%d)", devnode, ret); - break; - case BLOCK_DEV_FORMAT: - ret = block_format_device(bdev, op->data); - _D("Format (%s) result:(%d)", devnode, ret); - break; - case BLOCK_DEV_UNMOUNT: - ret = block_unmount_device(bdev, op->data); - _D("Unmount (%s) result:(%d)", devnode, ret); - break; - case BLOCK_DEV_REMOVE: - /* Do nothing */ - break; - default: - _E("Operation type is invalid (%d)", op->op); - ret = -EINVAL; - break; - } - - /* LOCK - * during checking the queue length */ - pthread_mutex_lock(&(th_manager[thread_id].mutex)); - - op->done = true; - th_manager[thread_id].op_len--; - - block_send_dbus_reply(op->msg, ret); - - queue = bdev->op_queue; - queue = DD_LIST_NEXT(queue); - op = DD_LIST_NTH(queue, 0); - remove_operation(bdev); - - pthread_mutex_unlock(&(th_manager[thread_id].mutex)); - /* UNLOCK */ - - - if (operation == BLOCK_DEV_INSERT || operation == BLOCK_DEV_REMOVE) { - if (pipe_trigger(operation, bdev, 0) < 0) - _E("fail to trigger pipe"); - } - - } while(true); - -} - -// Called by BlockThread -static void *block_th_start(void *arg) -{ - struct block_device *temp; - struct manage_thread *th = (struct manage_thread *)arg; - struct operation_queue *op = NULL; - dd_list *elem; - dd_list *queue = NULL; - int thread_id; - - assert(th); - - thread_id = th->thread_id; - if (thread_id < 0 || thread_id >= THREAD_MAX) { - _E("Thread Number: %d", th->thread_id); - return NULL; - } - - do { - pthread_mutex_lock(&(th_manager[thread_id].mutex)); - if (th_manager[thread_id].op_len == 0) { - _D("Operation queue of thread is empty"); - pthread_cond_wait(&(th_manager[thread_id].cond), &(th_manager[thread_id].mutex)); - _D("Wake up %d", thread_id); - } - - DD_LIST_FOREACH(th_manager[thread_id].block_dev_list, elem, temp) { - queue = temp->op_queue; - do { - op = DD_LIST_NTH(queue, 0); - if (!op) { - _D("Operation queue for device %s is Empty", temp->data->devnode); - break; - } - if (op->done) { - queue = DD_LIST_NEXT(queue); - continue; - } - break; - } while(true); - if (op) - break; - } - pthread_mutex_unlock(&(th_manager[thread_id].mutex)); - - if (op && !op->done) - trigger_operation(temp, queue, op); - - } while (true); -} - -// This function will be refactored later -// Especially, we don't need to keep th_node_list. -static int find_thread(char *devnode) -{ - dd_list *elem; - char str[PATH_MAX]; - char *th_node; - char *temp; - char dev_scsi; - int i, len, min, min_num; - int dev_mmc = -1, part = -1, num; - - len = 0; - if (!fnmatch("*/"MMC_PARTITION_PATH, devnode, 0)) { - sscanf(devnode, "/dev/mmcblk%dp%d", &dev_mmc, &part); - num = dev_mmc; - while (num > 0) { - num = num / 10; - len++; - } - len = len + 12; - snprintf(str, len, "/dev/mmcblk%d", dev_mmc); - th_node = strdup(str); - } else if (!fnmatch("*/"SCSI_PARTITION_PATH, devnode, 0)) { - sscanf(devnode, "/dev/sd%c%d", &dev_scsi, &part); - snprintf(str, SCSI_PARTITION_LENGTH, "/dev/sd%c", dev_scsi); - th_node = strdup(str); - } else - th_node = devnode; - - len = strlen(str) + 1; - min_num = 1000; - min = -1; - for (i = 0; i < THREAD_MAX; i++){ - DD_LIST_FOREACH(th_manager[i].th_node_list, elem, temp) { - if (!temp) - continue; - if (!strncmp(temp, th_node, len)) - return i; - } - if (th_manager[i].num_dev < min_num) { - min_num = th_manager[i].num_dev; - min = i; - } - } - - if (min >= 0 && min < THREAD_MAX) { - DD_LIST_APPEND(th_manager[min].th_node_list, th_node); - return min; - } - - _E("Finding thread is failed"); - DD_LIST_APPEND(th_manager[0].th_node_list, th_node); - return 0; -} - -/* Only Main thread is permmited */ -// Called by MainThread -static int add_operation(struct block_device *bdev, - enum block_dev_operation operation, - DBusMessage *msg, void *data) -{ - struct operation_queue *op; - int ret; - int thread_id; - bool start_th; - char name[16]; - - if (!bdev) - return -EINVAL; - - _D("Add operation (%s, %s)", - get_operation_char(operation, name, sizeof(name)), - bdev->data->devnode); - - op = (struct operation_queue *)malloc(sizeof(struct operation_queue)); - if (!op) { - _E("malloc failed"); - return -ENOMEM; - } - - op->op = operation; - op->data = data; - op->done = false; - - if (msg) - msg = dbus_message_ref(msg); - op->msg = msg; - - thread_id = bdev->thread_id; - if (thread_id < 0 || thread_id >= THREAD_MAX) { - _E("Fail to find thread to add"); - return -EPERM; - } - - /* LOCK - * during adding queue and checking the queue length */ - pthread_mutex_lock(&(th_manager[thread_id].mutex)); - - start_th = th_manager[thread_id].start_th; - DD_LIST_APPEND(bdev->op_queue, op); - th_manager[thread_id].op_len++; - - if (th_manager[thread_id].op_len == 1 && !start_th) - pthread_cond_signal(&(th_manager[thread_id].cond)); - - pthread_mutex_unlock(&(th_manager[thread_id].mutex)); - /* UNLOCK */ - - if (start_th) { - _D("Start New thread for block device"); - th_manager[thread_id].start_th = false; - ret = pthread_create(&(th_manager[thread_id].th), NULL, block_th_start, &th_manager[thread_id]); - if (ret != 0) { - _E("fail to create thread for %s", bdev->data->devnode); - return -EPERM; - } - - pthread_detach(th_manager[thread_id].th); - } - - return 0; -} - -static bool disk_is_partitioned_by_kernel(struct udev_device *dev) -{ - DIR *dp; - struct dirent entry; - struct dirent *dir; - const char *syspath; - bool ret = false; - - syspath = udev_device_get_syspath(dev); - if (!syspath) - goto out; - - dp = opendir(syspath); - if (!dp) { - _E("fail to open %s", syspath); - goto out; - } - - /* TODO compare devname and d_name */ - while (readdir_r(dp, &entry, &dir) == 0 && dir != NULL) { - if (!fnmatch(MMC_PARTITION_PATH, dir->d_name, 0) || - !fnmatch(SCSI_PARTITION_PATH, dir->d_name, 0)) { - ret = true; - break; - } - } - - closedir(dp); - -out: - return ret; -} - -static bool check_partition(struct udev_device *dev) -{ - const char *devtype; - const char *part_table_type; - const char *fs_usage; - bool ret = false; - - /* only consider disk type, never partitions */ - devtype = udev_device_get_devtype(dev); - if (!devtype) - goto out; - - if (strncmp(devtype, BLOCK_DEVTYPE_DISK, - sizeof(BLOCK_DEVTYPE_DISK)) != 0) - goto out; - - part_table_type = udev_device_get_property_value(dev, - "ID_PART_TABLE_TYPE"); - if (part_table_type) { - fs_usage = udev_device_get_property_value(dev, - "ID_FS_USAGE"); - if (fs_usage && - strncmp(fs_usage, FILESYSTEM, sizeof(FILESYSTEM)) == 0) { - if (!disk_is_partitioned_by_kernel(dev)) - goto out; - } - ret = true; - goto out; - } - - if (disk_is_partitioned_by_kernel(dev)) { - ret = true; - goto out; - } - -out: - return ret; -} - -// Called by MainThread -static int add_block_device(struct udev_device *dev, const char *devnode) -{ - struct block_data *data; - struct block_device *bdev; - bool partition; - int ret; - int thread_id; - - partition = check_partition(dev); - if (partition) { - /* if there is a partition, skip this request */ - _I("%s device has partitions, skip this time", devnode); - return 0; - } - - data = make_block_data(devnode, - udev_device_get_syspath(dev), - udev_device_get_property_value(dev, "ID_FS_USAGE"), - udev_device_get_property_value(dev, "ID_FS_TYPE"), - udev_device_get_property_value(dev, "ID_FS_VERSION"), - udev_device_get_property_value(dev, "ID_FS_UUID_ENC"), - udev_device_get_sysattr_value(dev, "ro")); - if (!data) { - _E("fail to make block data for %s", devnode); - return -EPERM; - } - - bdev = make_block_device(data); - if (!bdev) { - _E("fail to make block device for %s", devnode); - free_block_data(data); - return -EPERM; - } - - thread_id = find_thread(bdev->data->devnode); - if (thread_id < 0 || thread_id >= THREAD_MAX) { - _E("Fail to find thread to add"); - return -EPERM; - } - bdev->thread_id = thread_id; - - pthread_mutex_lock(&(th_manager[thread_id].mutex)); - th_manager[thread_id].num_dev++; - DD_LIST_APPEND(th_manager[thread_id].block_dev_list, bdev); - pthread_mutex_unlock(&(th_manager[thread_id].mutex)); - - ret = add_operation(bdev, BLOCK_DEV_INSERT, NULL, (void *)data); - if (ret < 0) { - _E("Failed to add operation (mount %s)", devnode); - return ret; - } - - ret = add_operation(bdev, BLOCK_DEV_MOUNT, NULL, NULL); - if (ret < 0) { - _E("Failed to add operation (mount %s)", devnode); - return ret; - } - - return 0; -} - -static int remove_block_device(struct udev_device *dev, const char *devnode) -{ - struct block_device *bdev; - int ret; - - bdev = find_block_device(devnode); - if (!bdev) { - _E("fail to find block data for %s", devnode); - return -ENODEV; - } - - BLOCK_FLAG_SET(bdev->data, UNMOUNT_UNSAFE); - - bdev->removed = true; - ret = add_operation(bdev, BLOCK_DEV_UNMOUNT, NULL, (void *)UNMOUNT_FORCE); - if (ret < 0) { - _E("Failed to add operation (unmount %s)", devnode); - return ret; - } - - ret = add_operation(bdev, BLOCK_DEV_REMOVE, NULL, NULL); - if (ret < 0) { - _E("Failed to add operation (remove %s)", devnode); - return ret; - } - - return 0; -} - -static int get_internal_storage_number(void) -{ - struct libmnt_table *t = NULL; - struct libmnt_fs *fs; - const char *temp; - char *name; - int r = 0; - - if (dev_internal >= 0 || dev_internal_scsi != '\0' || dev_emul != '\0') - return 0; - - t = mnt_new_table(); - if (!t) - return -EPERM; - - r = mnt_table_parse_mtab(t, NULL); - if (r < 0) { - mnt_free_table(t); - return -EPERM; - } - - fs = mnt_table_find_target(t, ROOT_DIR, MNT_ITER_BACKWARD); - - if (!fs) { - mnt_free_table(t); - return -EPERM; - } - temp = mnt_fs_get_srcpath(fs); - name = strrchr(temp, '/'); - if (!name) - return -EPERM; - name++; - /* Boot from USB is not handled */ - if (!emulator) { - if (!fnmatch(MMC_PATH, temp, 0)) - sscanf(name, "mmcblk%d", &dev_internal); - else if (!fnmatch(SCSI_PATH, temp, 0)) - sscanf(name, "sd%c", &dev_internal_scsi); - } else { - if (!fnmatch(EMUL_PATH, temp, 0)) - sscanf(name, "vd%c", &dev_emul); - } - - mnt_free_table(t); - - return 0; -} - -static int check_external_storage(const char* devnode) -{ - char emul = '\0'; - char dev_scsi = '\0'; - char *name; - int dev_num = -1; - - if (!devnode) - return -EPERM; - - name = strrchr(devnode, '/'); - if (!name) - return -EPERM; - name++; - if (!emulator) { - if (!fnmatch(MMC_PATH, devnode, 0)) { - sscanf(name, "mmcblk%d", &dev_num); - if (dev_internal == dev_num) { - _D("%s is internal storage", devnode); - return 0; - } - } else if (!fnmatch(SCSI_PATH, devnode, 0)) { - sscanf(name, "sd%c", &dev_scsi); - if (dev_internal_scsi == dev_scsi) { - _D("%s is internal storage", devnode); - return 0; - } - } - } else { - if (!fnmatch(EMUL_PATH, devnode, 0)) { - sscanf(name, "vd%c", &emul); - if (emul == '\0') - return -EPERM; - if (dev_emul == emul) { - _D("%s is internal storage", devnode); - return 0; - } - } - } - - return 1; -} - -static int block_init_from_udev_enumerate(void) -{ - struct udev *udev; - struct udev_enumerate *enumerate; - struct udev_list_entry *list_entry, *list_sub_entry; - struct udev_device *dev; - const char *syspath; - const char *devnode; - int r = 0; - - udev = udev_new(); - if (!udev) { - _E("fail to create udev library context"); - return -EPERM; - } - - /* create a list of the devices in the 'usb' subsystem */ - enumerate = udev_enumerate_new(udev); - if (!enumerate) { - _E("fail to create an enumeration context"); - return -EPERM; - } - - if (dev_internal < 0 && dev_emul == '\0' && dev_internal_scsi == '\0') { - r = get_internal_storage_number(); - if (r < 0) - return -EPERM; - } - - udev_enumerate_add_match_subsystem(enumerate, BLOCK_SUBSYSTEM); - udev_enumerate_add_match_property(enumerate, - UDEV_DEVTYPE, BLOCK_DEVTYPE_DISK); - udev_enumerate_add_match_property(enumerate, - UDEV_DEVTYPE, BLOCK_DEVTYPE_PARTITION); - udev_enumerate_scan_devices(enumerate); - - udev_list_entry_foreach(list_entry, - udev_enumerate_get_list_entry(enumerate)) { - syspath = udev_list_entry_get_name(list_entry); - if (!syspath) - continue; - - dev = udev_device_new_from_syspath( - udev_enumerate_get_udev(enumerate), - syspath); - if (!dev) - continue; - - devnode = NULL; - udev_list_entry_foreach(list_sub_entry, - udev_device_get_devlinks_list_entry(dev)) { - const char *devlink = udev_list_entry_get_name(list_sub_entry); - if (!fnmatch(MMC_LINK_PATH, devlink, 0)) { - devnode = devlink; - break; - } - } - - if (!devnode) { - devnode = udev_device_get_devnode(dev); - if (!devnode) - continue; - - if (fnmatch(MMC_PATH, devnode, 0) && - fnmatch(SCSI_PATH, devnode, 0)) - continue; - } - - r = check_external_storage(devnode); - if (r <= 0) - continue; - - _D("%s device add", devnode); - add_block_device(dev, devnode); - - udev_device_unref(dev); - } - - udev_enumerate_unref(enumerate); - udev_unref(udev); - return 0; -} - -// Called by MainThread -static void show_block_device_list(void) -{ - struct block_device *bdev; - struct block_data *data; - dd_list *elem; - int i; - - for (i = 0; i < THREAD_MAX; i++) { - pthread_mutex_lock(&(th_manager[i].mutex)); - DD_LIST_FOREACH(th_manager[i].block_dev_list, elem, bdev) { - data = bdev->data; - if (!data) - continue; - if (bdev->removed) - continue; - _D("%s:", data->devnode); - _D("\tSyspath: %s", data->syspath); - _D("\tBlock type: %s", - (data->block_type == BLOCK_MMC_DEV ? - BLOCK_TYPE_MMC : BLOCK_TYPE_SCSI)); - _D("\tFs type: %s", data->fs_type); - _D("\tFs usage: %s", data->fs_usage); - _D("\tFs version: %s", data->fs_version); - _D("\tFs uuid enc: %s", data->fs_uuid_enc); - _D("\tReadonly: %s", - (data->readonly ? "true" : "false")); - _D("\tMount point: %s", data->mount_point); - _D("\tMount state: %s", - (data->state == BLOCK_MOUNT ? - "mount" : "unmount")); - _D("\tPrimary: %s", - (data->primary ? "true" : "false")); - _D("\tID: %d", data->id); - } - pthread_mutex_unlock(&(th_manager[i].mutex)); - } -} - -// Called by MainThread -static void remove_whole_block_device(void) -{ - struct block_device *bdev; - dd_list *elem; - dd_list *next; - int r; - int i; - - for (i = 0; i < THREAD_MAX; i++) { - do { - pthread_mutex_lock(&(th_manager[i].mutex)); - DD_LIST_FOREACH_SAFE(th_manager[i].block_dev_list, elem, next, bdev) { - if (bdev->removed == false) { - break; - } - } - pthread_mutex_unlock(&(th_manager[i].mutex)); - - if (bdev && bdev->removed == false) { - bdev->removed = true; - r = add_operation(bdev, BLOCK_DEV_UNMOUNT, NULL, (void *)UNMOUNT_NORMAL); - if (r < 0) - _E("Failed to add operation (unmount %s)", bdev->data->devnode); - - r = add_operation(bdev, BLOCK_DEV_REMOVE, NULL, NULL); - if (r < 0) - _E("Failed to add operation (remove %s)", bdev->data->devnode); - } else - break; - } while(true); - } -} - -static int booting_done(void *data) -{ - /* if there is the attached device, try to mount */ - block_init_from_udev_enumerate(); - block_control = true; - block_boot = true; - return 0; -} - -static int block_poweroff(void *data) -{ - /* unregister mmc uevent control routine */ - unregister_udev_uevent_control(&uh); - remove_whole_block_device(); - return 0; -} - -static void uevent_block_handler(struct udev_device *dev) -{ - const char *devnode = NULL; - const char *action; - struct udev_list_entry *list_entry; - int r; - - udev_list_entry_foreach(list_entry, udev_device_get_devlinks_list_entry(dev)) { - const char *devlink = udev_list_entry_get_name(list_entry); - if (!fnmatch(MMC_LINK_PATH, devlink, 0)) { - devnode = devlink; - break; - } - } - - if (!devnode) { - devnode = udev_device_get_devnode(dev); - if (!devnode) - return; - - if (fnmatch(MMC_PATH, devnode, 0) && - fnmatch(SCSI_PATH, devnode, 0)) - return; - } - - r = check_external_storage(devnode); - if (r <= 0) - return; - - action = udev_device_get_action(dev); - if (!action) - return; - - _D("%s device %s", devnode, action); - if (!strncmp(action, UDEV_ADD, sizeof(UDEV_ADD))) - add_block_device(dev, devnode); - else if (!strncmp(action, UDEV_REMOVE, sizeof(UDEV_REMOVE))) - remove_block_device(dev, devnode); -} - -static DBusMessage *request_mount_block(E_DBus_Object *obj, - DBusMessage *msg) -{ - struct block_device *bdev; - char *mount_point; - int id; - int ret = -EBADMSG; - - if (!obj || !msg) - goto out; - - ret = dbus_message_get_args(msg, NULL, - DBUS_TYPE_INT32, &id, - DBUS_TYPE_STRING, &mount_point, - DBUS_TYPE_INVALID); - if (!ret) - goto out; - bdev = find_block_device_by_id(id); - if (!bdev) { - _E("Failed to find (%d) in the device list", id); - ret = -ENOENT; - goto out; - } - - /* if requester want to use a specific mount point */ - if (mount_point && strncmp(mount_point, "", 1) != 0) { - ret = change_mount_point(bdev, mount_point); - if (ret < 0) { - ret = -EPERM; - goto out; - } - } - - ret = add_operation(bdev, BLOCK_DEV_MOUNT, msg, NULL); - if (ret < 0) { - _E("Failed to add operation (mount %s)", bdev->data->devnode); - goto out; - } - - return NULL; - -out: - return make_reply_message(msg, ret); -} - -static DBusMessage *request_unmount_block(E_DBus_Object *obj, - DBusMessage *msg) -{ - struct block_device *bdev; - long option; - int id; - int ret = -EBADMSG; - - if (!obj || !msg) - goto out; - - ret = dbus_message_get_args(msg, NULL, - DBUS_TYPE_INT32, &id, - DBUS_TYPE_INT32, &option, - DBUS_TYPE_INVALID); - if (!ret) - goto out; - bdev = find_block_device_by_id(id); - if (!bdev) { - _E("Failed to find (%d) in the device list", id); - ret = -ENOENT; - goto out; - } - - ret = add_operation(bdev, BLOCK_DEV_UNMOUNT, msg, (void *)option); - if (ret < 0) { - _E("Failed to add operation (unmount %s)", bdev->data->devnode); - goto out; - } - - return NULL; - -out: - return make_reply_message(msg, ret); -} - -static DBusMessage *request_format_block(E_DBus_Object *obj, - DBusMessage *msg) -{ - struct block_device *bdev; - struct format_data *fdata; - int id; - int option; - int ret = -EBADMSG; - int prev_state; - - if (!obj || !msg) - goto out; - - ret = dbus_message_get_args(msg, NULL, - DBUS_TYPE_INT32, &id, - DBUS_TYPE_INT32, &option, - DBUS_TYPE_INVALID); - if (!ret) - goto out; - bdev = find_block_device_by_id(id); - if (!bdev) { - _E("Failed to find (%d) in the device list", id); - goto out; - } - - fdata = get_format_data(NULL, option); - if (!fdata) { - _E("Failed to get format data"); - goto out; - } - - prev_state = bdev->data->state; - if (prev_state == BLOCK_MOUNT) { - ret = add_operation(bdev, BLOCK_DEV_UNMOUNT, NULL, (void *)UNMOUNT_FORCE); - if (ret < 0) { - _E("Failed to add operation (unmount %s)", bdev->data->devnode); - release_format_data(fdata); - goto out; - } - } - - ret = add_operation(bdev, BLOCK_DEV_FORMAT, msg, (void *)fdata); - if (ret < 0) { - _E("Failed to add operation (format %s)", bdev->data->devnode); - release_format_data(fdata); - } - - /* Maintain previous state of mount/unmount */ - if (prev_state == BLOCK_MOUNT) { - if (add_operation(bdev, BLOCK_DEV_MOUNT, NULL, NULL) < 0) { - _E("Failed to add operation (mount %s)", bdev->data->devnode); - goto out; - } - } - - return NULL; - -out: - return make_reply_message(msg, ret); -} - -static int add_device_to_iter(struct block_data *data, DBusMessageIter *piter) -{ - char *str_null = ""; - - if (!data || !piter) - return -EINVAL; - - dbus_message_iter_append_basic(piter, DBUS_TYPE_INT32, - &(data->block_type)); - dbus_message_iter_append_basic(piter, DBUS_TYPE_STRING, - data->devnode ? &(data->devnode) : &str_null); - dbus_message_iter_append_basic(piter, DBUS_TYPE_STRING, - data->syspath ? &(data->syspath) : &str_null); - dbus_message_iter_append_basic(piter, DBUS_TYPE_STRING, - data->fs_usage ? &(data->fs_usage) : &str_null); - dbus_message_iter_append_basic(piter, DBUS_TYPE_STRING, - data->fs_type ? &(data->fs_type) : &str_null); - dbus_message_iter_append_basic(piter, DBUS_TYPE_STRING, - data->fs_version ? &(data->fs_version) : &str_null); - dbus_message_iter_append_basic(piter, DBUS_TYPE_STRING, - data->fs_uuid_enc ? &(data->fs_uuid_enc) : &str_null); - dbus_message_iter_append_basic(piter, DBUS_TYPE_INT32, - &(data->readonly)); - dbus_message_iter_append_basic(piter, DBUS_TYPE_STRING, - data->mount_point ? &(data->mount_point) : &str_null); - dbus_message_iter_append_basic(piter, DBUS_TYPE_INT32, - &(data->state)); - dbus_message_iter_append_basic(piter, DBUS_TYPE_BOOLEAN, - &(data->primary)); - dbus_message_iter_append_basic(piter, DBUS_TYPE_INT32, - &(data->flags)); - dbus_message_iter_append_basic(piter, DBUS_TYPE_INT32, - &(data->id)); - - return 0; -} - - -static int add_device_to_struct_iter(struct block_data *data, DBusMessageIter *iter) -{ - DBusMessageIter piter; - - if (!data || !iter) - return -EINVAL; - - dbus_message_iter_open_container(iter, DBUS_TYPE_STRUCT, NULL, &piter); - add_device_to_iter(data, &piter); - dbus_message_iter_close_container(iter, &piter); - - return 0; -} - -static int add_device_to_iter_2(struct block_data *data, DBusMessageIter *iter) -{ - DBusMessageIter piter; - char *str_null = ""; - - if (!data || !iter) - return -EINVAL; - - dbus_message_iter_open_container(iter, DBUS_TYPE_STRUCT, NULL, &piter); - dbus_message_iter_append_basic(&piter, DBUS_TYPE_INT32, - &(data->block_type)); - dbus_message_iter_append_basic(&piter, DBUS_TYPE_STRING, - data->devnode ? &(data->devnode) : &str_null); - dbus_message_iter_append_basic(&piter, DBUS_TYPE_STRING, - data->syspath ? &(data->syspath) : &str_null); - dbus_message_iter_append_basic(&piter, DBUS_TYPE_STRING, - data->fs_usage ? &(data->fs_usage) : &str_null); - dbus_message_iter_append_basic(&piter, DBUS_TYPE_STRING, - data->fs_type ? &(data->fs_type) : &str_null); - dbus_message_iter_append_basic(&piter, DBUS_TYPE_STRING, - data->fs_version ? &(data->fs_version) : &str_null); - dbus_message_iter_append_basic(&piter, DBUS_TYPE_STRING, - data->fs_uuid_enc ? &(data->fs_uuid_enc) : &str_null); - dbus_message_iter_append_basic(&piter, DBUS_TYPE_INT32, - &(data->readonly)); - dbus_message_iter_append_basic(&piter, DBUS_TYPE_STRING, - data->mount_point ? &(data->mount_point) : &str_null); - dbus_message_iter_append_basic(&piter, DBUS_TYPE_INT32, - &(data->state)); - dbus_message_iter_append_basic(&piter, DBUS_TYPE_BOOLEAN, - &(data->primary)); - dbus_message_iter_append_basic(&piter, DBUS_TYPE_INT32, - &(data->flags)); - dbus_message_iter_close_container(iter, &piter); - - return 0; -} - -static DBusMessage *request_get_device_info(E_DBus_Object *obj, - DBusMessage *msg) -{ - DBusMessageIter iter; - DBusMessage *reply; - struct block_device *bdev; - struct block_data *data; - int ret, id; - - if (!obj || !msg) - return NULL; - - reply = dbus_message_new_method_return(msg); - if (!reply) - goto out; - - ret = dbus_message_get_args(msg, NULL, - DBUS_TYPE_INT32, &id, - DBUS_TYPE_INVALID); - if (!ret) - goto out; - - bdev = find_block_device_by_id(id); - if (!bdev) - goto out; - data = bdev->data; - if (!data) - goto out; - - dbus_message_iter_init_append(reply, &iter); - add_device_to_iter(data, &iter); - -out: - return reply; -} - -static DBusMessage *request_show_device_list(E_DBus_Object *obj, - DBusMessage *msg) -{ - show_block_device_list(); - return dbus_message_new_method_return(msg); -} - -// Called by MainThread -static DBusMessage *request_get_device_list(E_DBus_Object *obj, - DBusMessage *msg) -{ - DBusMessageIter iter; - DBusMessageIter aiter; - DBusMessage *reply; - struct block_device *bdev; - struct block_data *data; - dd_list *elem; - char *type = NULL; - int ret = -EBADMSG; - int block_type; - int i; - - reply = dbus_message_new_method_return(msg); - - ret = dbus_message_get_args(msg, NULL, - DBUS_TYPE_STRING, &type, - DBUS_TYPE_INVALID); - if (!ret) { - _E("Failed to get args"); - goto out; - } - - if (!type) { - _E("Delivered type is NULL"); - goto out; - } - - _D("Block (%s) device list is requested", type); - - if (!strncmp(type, BLOCK_TYPE_SCSI, sizeof(BLOCK_TYPE_SCSI))) - block_type = BLOCK_SCSI_DEV; - else if (!strncmp(type, BLOCK_TYPE_MMC, sizeof(BLOCK_TYPE_MMC))) - block_type = BLOCK_MMC_DEV; - else if (!strncmp(type, BLOCK_TYPE_ALL, sizeof(BLOCK_TYPE_ALL))) - block_type = -1; - else { - _E("Invalid type (%s) is requested", type); - goto out; - } - - dbus_message_iter_init_append(reply, &iter); - dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "(issssssisibii)", &aiter); - - for (i = 0; i < THREAD_MAX; i++) { - pthread_mutex_lock(&(th_manager[i].mutex)); - DD_LIST_FOREACH(th_manager[i].block_dev_list, elem, bdev) { - data = bdev->data; - if (!data) - continue; - if (bdev->removed) - continue; - - switch (block_type) { - case BLOCK_SCSI_DEV: - case BLOCK_MMC_DEV: - if (data->block_type != block_type) - continue; - break; - default: - break; - } - add_device_to_struct_iter(data, &aiter); - } - pthread_mutex_unlock(&(th_manager[i].mutex)); - } - dbus_message_iter_close_container(&iter, &aiter); - -out: - return reply; -} - -// Called by MainThread -static DBusMessage *request_get_device_list_2(E_DBus_Object *obj, - DBusMessage *msg) -{ - DBusMessageIter iter; - DBusMessageIter aiter; - DBusMessage *reply; - struct block_device *bdev; - struct block_data *data; - dd_list *elem; - char *type = NULL; - int ret = -EBADMSG; - int block_type; - int i; - - reply = dbus_message_new_method_return(msg); - - ret = dbus_message_get_args(msg, NULL, - DBUS_TYPE_STRING, &type, - DBUS_TYPE_INVALID); - if (!ret) { - _E("Failed to get args"); - goto out; - } - - if (!type) { - _E("Delivered type is NULL"); - goto out; - } - - _D("Block (%s) device list is requested", type); - - if (!strncmp(type, BLOCK_TYPE_SCSI, sizeof(BLOCK_TYPE_SCSI))) - block_type = BLOCK_SCSI_DEV; - else if (!strncmp(type, BLOCK_TYPE_MMC, sizeof(BLOCK_TYPE_MMC))) - block_type = BLOCK_MMC_DEV; - else if (!strncmp(type, BLOCK_TYPE_ALL, sizeof(BLOCK_TYPE_ALL))) - block_type = -1; - else { - _E("Invalid type (%s) is requested", type); - goto out; - } - - dbus_message_iter_init_append(reply, &iter); - dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "(issssssisibi)", &aiter); - - for (i = 0; i < THREAD_MAX; i++) { - pthread_mutex_lock(&(th_manager[i].mutex)); - DD_LIST_FOREACH(th_manager[i].block_dev_list, elem, bdev) { - data = bdev->data; - if (!data) - continue; - if (bdev->removed) - continue; - - switch (block_type) { - case BLOCK_SCSI_DEV: - case BLOCK_MMC_DEV: - if (data->block_type != block_type) - continue; - break; - default: - break; - } - - add_device_to_iter_2(data, &aiter); - } - pthread_mutex_unlock(&(th_manager[i].mutex)); - } - dbus_message_iter_close_container(&iter, &aiter); - -out: - return reply; -} - -static DBusMessage *request_get_mmc_primary(E_DBus_Object *obj, DBusMessage *msg) -{ - DBusMessageIter iter; - DBusMessage *reply; - struct block_device *bdev; - struct block_data *data, nodata = {0,}; - dd_list *elem; - bool found; - int i; - - if (!obj || !msg) - return NULL; - - reply = dbus_message_new_method_return(msg); - if (!reply) - goto out; - - found = false; - for (i = 0; i < THREAD_MAX; i++) { - pthread_mutex_lock(&(th_manager[i].mutex)); - DD_LIST_FOREACH(th_manager[i].block_dev_list, elem, bdev) { - data = bdev->data; - if (!data) - continue; - if (bdev->removed) - continue; - if (data->block_type != BLOCK_MMC_DEV) - continue; - if (!data->primary) - continue; - found = true; - break; - } - pthread_mutex_unlock(&(th_manager[i].mutex)); - if (found) - break; - } - - dbus_message_iter_init_append(reply, &iter); - if (found) - add_device_to_iter(data, &iter); - else { - nodata.id = -ENODEV; - add_device_to_iter(&nodata, &iter); - } - -out: - return reply; -} - -static const struct edbus_method manager_methods[] = { - { "ShowDeviceList", NULL, NULL, request_show_device_list }, - { "GetDeviceList" , "s", "a(issssssisibii)", request_get_device_list }, - { "GetDeviceList2", "s", "a(issssssisibi)", request_get_device_list_2 }, - { "Mount", "is", "i", request_mount_block }, - { "Unmount", "ii", "i", request_unmount_block }, - { "Format", "ii", "i", request_format_block }, - { "GetDeviceInfo", "i", "(issssssisibii)", request_get_device_info }, - { "GetMmcPrimary" , NULL, "(issssssisibii)" , request_get_mmc_primary }, -}; - -static int load_config(struct parse_result *result, void *user_data) -{ - int index; - - if (MATCH(result->section, "Block")) - return 0; - - if (MATCH(result->section, "SCSI")) - index = BLOCK_SCSI_DEV; - else if (MATCH(result->section, "MMC")) - index = BLOCK_MMC_DEV; - else - return -EINVAL; - - if (MATCH(result->name, "Multimount")) - block_conf[index].multimount = - (MATCH(result->value, "yes") ? true : false); - - return 0; -} - -#ifdef BLOCK_TMPFS -static int mount_root_path_tmpfs(void) -{ - int ret; - char *root; - - root = tzplatform_getenv(TZ_SYS_MEDIA); - if (!root) - return -ENOTSUP; - - if (access(root, F_OK) != 0) - return -ENODEV; - - if (mount_check(root)) - return 0; - - ret = mount("tmpfs", root, "tmpfs", 0, "smackfsroot=System::Shared"); - if (ret < 0) { - ret = -errno; - _E("tmpfs mount failed (%d)", ret); - return ret; - } - - return 0; -} -#else -#define mount_root_path_tmpfs() 0 -#endif - -static void block_init(void *data) -{ - char *model_name; - int ret; - int i; - - /* load config */ - ret = config_parse(BLOCK_CONF_FILE, load_config, NULL); - if (ret < 0) - _E("fail to load %s, Use default value", BLOCK_CONF_FILE); - - ret = mount_root_path_tmpfs(); - if (ret < 0) - _E("Failed to mount tmpfs to root mount path (%d)", ret); - - /* register block manager object and interface */ - ret = register_block_edbus_interface_and_method(DEVICED_PATH_BLOCK_MANAGER, - DEVICED_INTERFACE_BLOCK_MANAGER, - manager_methods, ARRAY_SIZE(manager_methods)); - if (ret < 0) - _E("fail to init edbus interface and method(%d)", ret); - - /* init pipe */ - ret = pipe_init(); - if (ret < 0) - _E("fail to init pipe"); - - /* register mmc uevent control routine */ - ret = register_udev_uevent_control(&uh); - if (ret < 0) - _E("fail to register block uevent : %d", ret); - - /* register notifier */ - register_notifier(DEVICE_NOTIFIER_POWEROFF, block_poweroff); - register_notifier(DEVICE_NOTIFIER_BOOTING_DONE, booting_done); - - ret = system_info_get_platform_string(MODEL_NAME, &model_name); - if (!strncmp(MODEL_EMULATOR, model_name, strlen(model_name))) - emulator = true; - - for (i = 0; i < THREAD_MAX; i++) { - th_manager[i].num_dev = 0; - th_manager[i].op_len = 0; - th_manager[i].start_th = true; - th_manager[i].thread_id = i; - pthread_mutex_init(&(th_manager[i].mutex), NULL); - pthread_cond_init(&(th_manager[i].cond), NULL); - } -} - -static void block_exit(void *data) -{ - int ret, i; - - /* unregister notifier */ - unregister_notifier(DEVICE_NOTIFIER_POWEROFF, block_poweroff); - unregister_notifier(DEVICE_NOTIFIER_BOOTING_DONE, booting_done); - - /* exit pipe */ - pipe_exit(); - - /* unregister mmc uevent control routine */ - ret = unregister_udev_uevent_control(&uh); - if (ret < 0) - _E("fail to unregister block uevent : %d", ret); - - /* remove remaining blocks */ - remove_whole_block_device(); - - for (i = 0; i < THREAD_MAX; i++) { - if (!th_manager[i].start_th) - pthread_cancel(th_manager[i].th); - } - - block_control = false; -} - -static int block_start(enum device_flags flags) -{ - int ret; - - if (!block_boot) { - _E("Cannot be started. Booting is not ready"); - return -ENODEV; - } - - if (block_control) { - _I("Already started"); - return 0; - } - - /* register mmc uevent control routine */ - ret = register_udev_uevent_control(&uh); - if (ret < 0) - _E("fail to register block uevent : %d", ret); - - block_init_from_udev_enumerate(); - - block_control = true; - - _I("start"); - return 0; -} - -static int block_stop(enum device_flags flags) -{ - if (!block_boot) { - _E("Cannot be stopped. Booting is not ready"); - return -ENODEV; - } - - if (!block_control) { - _I("Already stopped"); - return 0; - } - - /* unregister mmc uevent control routine */ - unregister_udev_uevent_control(&uh); - - /* remove the existing blocks */ - remove_whole_block_device(); - - block_control = false; - - _I("stop"); - return 0; -} - -const struct device_ops block_device_ops = { - .name = "block", - .init = block_init, - .exit = block_exit, - .start = block_start, - .stop = block_stop, -}; - -DEVICE_OPS_REGISTER(&block_device_ops) diff --git a/src/block/block.conf b/src/block/block.conf deleted file mode 100644 index 8898468..0000000 --- a/src/block/block.conf +++ /dev/null @@ -1,7 +0,0 @@ -[Block] - -[MMC] -Multimount=no # yes or no - -[SCSI] -Multimount=yes # yes or no diff --git a/src/block/block.h b/src/block/block.h deleted file mode 100644 index 22ea223..0000000 --- a/src/block/block.h +++ /dev/null @@ -1,177 +0,0 @@ -/* - * deviced - * - * Copyright (c) 2015 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 __BLOCK_H__ -#define __BLOCK_H__ - -#include -#include "core/common.h" - -#define SMACKFS_MOUNT_OPT "smackfsroot=*,smackfsdef=*" - -#define RETRY_COUNT 10 - -enum block_fs_type { - FS_TYPE_VFAT = 0, - FS_TYPE_EXT4, -}; - -struct block_fs_ops { - enum block_fs_type type; - const char *name; - bool (*match) (const char *); - int (*check) (const char *); - int (*mount) (bool, const char *, const char *); - int (*format) (const char *); -}; - -struct fs_check { - int type; - char *name; - unsigned int offset; - unsigned int magic_sz; - char magic[4]; -}; - -void add_fs(const struct block_fs_ops *fs); -void remove_fs(const struct block_fs_ops *fs); - -enum block_device_type { - BLOCK_SCSI_DEV, - BLOCK_MMC_DEV, -}; - -enum mount_state { - BLOCK_UNMOUNT, - BLOCK_MOUNT, -}; - -enum unmount_operation { - UNMOUNT_NORMAL, - UNMOUNT_FORCE, -}; - -struct block_data { - enum block_device_type block_type; - char *devnode; - char *syspath; - char *fs_usage; - char *fs_type; - char *fs_version; - char *fs_uuid_enc; - bool readonly; - char *mount_point; - enum mount_state state; - bool primary; /* the first partition */ - int flags; - int id; /* libstorage uses the id as the storage_id */ -}; - -struct block_dev_ops { - const char *name; - enum block_device_type block_type; - void (*mounted) (struct block_data *data, int result); - void (*unmounted) (struct block_data *data, int result); - void (*formatted) (struct block_data *data, int result); - void (*inserted) (struct block_data *data); - void (*removed) (struct block_data *data); -}; - -void add_block_dev(const struct block_dev_ops *ops); -void remove_block_dev(const struct block_dev_ops *ops); - -#define BLOCK_DEVICE_OPS_REGISTER(dev) \ -static void __CONSTRUCTOR__ block_dev_init(void) \ -{ \ - add_block_dev(dev); \ -} \ -static void __DESTRUCTOR__ block_dev_exit(void) \ -{ \ - remove_block_dev(dev); \ -} - -enum block_flags { - FLAG_NONE = 0, - UNMOUNT_UNSAFE = 1 << 0, - FS_BROKEN = 1 << 1, - FS_EMPTY = 1 << 2, - FS_NOT_SUPPORTED = 1 << 3, - MOUNT_READONLY = 1 << 4, -}; - -/* a: struct block_data - * b: enum block_flags */ -#define BLOCK_FLAG_SET(a, b) \ - do { \ - if (a) { \ - (((a)->flags) |= (b)); \ - } \ - } while (0) - -#define BLOCK_FLAG_UNSET(a, b) \ - do { \ - if (a) { \ - (((a)->flags) &= ~(b)); \ - } \ - } while (0) - -#define BLOCK_IS_FLAG_SET(a, b) \ - ((a) ? ((((a)->flags) & (b)) ? true : false) : false) - -#define BLOCK_FLAG_CLEAR_ALL(a) \ - do { \ - if (a) { \ - ((a)->flags) = FLAG_NONE; \ - } \ - } while (0) - -#define BLOCK_FLAG_MOUNT_CLEAR(a) \ - do { \ - BLOCK_FLAG_UNSET((a), FS_BROKEN); \ - BLOCK_FLAG_UNSET((a), FS_EMPTY); \ - BLOCK_FLAG_UNSET((a), FS_NOT_SUPPORTED); \ - BLOCK_FLAG_UNSET((a), MOUNT_READONLY); \ - } while (0) - -#define BLOCK_FLAG_UNMOUNT_CLEAR(a) \ - do { \ - BLOCK_FLAG_UNSET((a), UNMOUNT_UNSAFE); \ - } while (0) - -#define BLOCK_GET_MOUNT_FLAGS(a, c) \ - do { \ - (c) = (a)->flags; \ - (c) &= ~UNMOUNT_UNSAFE; \ - } while (0) - -#define BLOCK_GET_UNMOUNT_FLAGS(a, c) \ - do { \ - (c) = 0; \ - if (BLOCK_IS_FLAG_SET((a), UNMOUNT_UNSAFE)) \ - (c) |= UNMOUNT_UNSAFE; \ - } while (0) - -#define BLOCK_GET_FORMAT_FLAGS(a, c) \ - do { \ - (c) = 0; \ - if (BLOCK_IS_FLAG_SET((a), FS_NOT_SUPPORTED)) \ - (c) |= FS_NOT_SUPPORTED; \ - } while (0) - -#endif /* __BLOCK_H__ */ diff --git a/src/block/ext4.c b/src/block/ext4.c deleted file mode 100644 index 24f7e7e..0000000 --- a/src/block/ext4.c +++ /dev/null @@ -1,178 +0,0 @@ -/* - * deviced - * - * Copyright (c) 2012 - 2015 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 -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "core/common.h" -#include "core/devices.h" -#include "core/launch.h" -#include "core/log.h" -#include "block.h" - -#define FS_EXT4_NAME "ext4" - -#define FS_EXT4_SMACK_LABEL "/usr/bin/mmc-smack-label" - -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 ext4_info = { - FS_TYPE_EXT4, - "ext4", - 0x438, - 2, - {0x53, 0xef}, -}; - -static int mmc_popup_pid; - -static bool ext4_match(const char *devpath) -{ - char buf[4]; - int fd, r; - - fd = open(devpath, O_RDONLY); - if (fd < 0) { - _E("failed to open fd(%s) : %d", devpath, errno); - return false; - } - - /* check fs type with magic code */ - r = lseek(fd, ext4_info.offset, SEEK_SET); - if (r < 0) - goto error; - - r = read(fd, buf, 2); - if (r < 0) - goto error; - - _I("mmc search magic : 0x%2x, 0x%2x", buf[0], buf[1]); - if (memcmp(buf, ext4_info.magic, ext4_info.magic_sz)) - goto error; - - close(fd); - _I("MMC type : %s", ext4_info.name); - return true; - -error: - close(fd); - _E("failed to match with ext4(%s)", devpath); - return false; -} - -static int ext4_check(const char *devpath) -{ - int argc; - argc = ARRAY_SIZE(ext4_check_arg); - ext4_check_arg[argc - 2] = devpath; - return run_child(argc, ext4_check_arg); -} - -static int mmc_check_smack(const char *mount_point) -{ - char buf[NAME_MAX] = {0,}; - - snprintf(buf, sizeof(buf), "%s", mount_point); - -#ifdef TIZEN_FEATURE_BLOCK_SET_PERMISSION - launch_evenif_exist(FS_EXT4_SMACK_LABEL, buf); -#endif - - if (mmc_popup_pid > 0) { - _E("will be killed mmc-popup(%d)", mmc_popup_pid); - kill(mmc_popup_pid, SIGTERM); - } - return 0; -} - -static int check_smack_popup(void) -{ - /* TODO: show smack popup */ - return 0; -} - -static int ext4_mount(bool smack, const char *devpath, const char *mount_point) -{ - int r, retry = RETRY_COUNT; - struct timespec time = {0,}; - unsigned long mountflags = MS_NOSUID | MS_NOEXEC | MS_NODEV | MS_DIRSYNC; - - do { - r = mount(devpath, mount_point, "ext4", mountflags, NULL); - if (!r) { - _I("Mounted mmc card [ext4]"); - if (smack) { - check_smack_popup(); - mmc_check_smack(mount_point); - } - return 0; - } - _I("mount fail : r = %d, err = %d", r, errno); - time.tv_nsec = 100 * NANO_SECOND_MULTIPLIER; - nanosleep(&time, NULL); - if (r < 0 && errno == EROFS) - mountflags |= MS_RDONLY; - } while (r < 0 && (errno == ENOENT || errno == EROFS) && retry-- > 0); - - return -errno; -} - -static int ext4_format(const char *devpath) -{ - int argc; - argc = ARRAY_SIZE(ext4_arg); - ext4_arg[argc - 2] = devpath; - return run_child(argc, ext4_arg); -} - -static const struct block_fs_ops ext4_ops = { - .type = FS_TYPE_EXT4, - .name = "ext4", - .match = ext4_match, - .check = ext4_check, - .mount = ext4_mount, - .format = ext4_format, -}; - -static void __CONSTRUCTOR__ module_init(void) -{ - add_fs(&ext4_ops); -} -/* -static void __DESTRUCTOR__ module_exit(void) -{ - remove_fs(&ext4_ops); -} -*/ diff --git a/src/block/mmc.c b/src/block/mmc.c deleted file mode 100644 index b3990cf..0000000 --- a/src/block/mmc.c +++ /dev/null @@ -1,123 +0,0 @@ -/* - * deviced - * - * Copyright (c) 2015 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 -#include -#include -#include - -#include "core/log.h" -#include "core/common.h" -#include "block/block.h" - -static void mmc_update_state(int state) -{ - static int old = -1; - - if (old == state) - return; - - if (vconf_set_int(VCONFKEY_SYSMAN_MMC_STATUS, state) == 0) - old = state; -} - -static void mmc_update_mount_state(int state) -{ - static int old = -1; - - if (old == state) - return; - - if (vconf_set_int(VCONFKEY_SYSMAN_MMC_MOUNT, state) == 0) - old = state; -} - -static void mmc_mount(struct block_data *data, int result) -{ - int r; - - /* Only the primary partition is valid. */ - if (!data || !data->primary) - return; - - if (result < 0) { - mmc_update_state(VCONFKEY_SYSMAN_MMC_INSERTED_NOT_MOUNTED); - mmc_update_mount_state(VCONFKEY_SYSMAN_MMC_MOUNT_FAILED); - return; - } - - /* Give a transmutable attribute to mount_point */ - r = setxattr(data->mount_point, "security.SMACK64TRANSMUTE", - "TRUE", strlen("TRUE"), 0); - if (r < 0) - _E("setxattr error : %d", errno); - - mmc_update_state(VCONFKEY_SYSMAN_MMC_MOUNTED); - mmc_update_mount_state(VCONFKEY_SYSMAN_MMC_MOUNT_COMPLETED); -} - -static void mmc_unmount(struct block_data *data, int result) -{ - /* Only the primary partition is valid. */ - if (!data || !data->primary) - return; - - if (result == 0) - mmc_update_state(VCONFKEY_SYSMAN_MMC_INSERTED_NOT_MOUNTED); - else - mmc_update_state(VCONFKEY_SYSMAN_MMC_MOUNTED); -} - -static void mmc_format(struct block_data *data, int result) -{ - /* Only the primary partition is valid. */ - if (!data || !data->primary) - return; - - if (data->state == BLOCK_MOUNT) { - mmc_update_state(VCONFKEY_SYSMAN_MMC_MOUNTED); - mmc_update_mount_state(VCONFKEY_SYSMAN_MMC_MOUNT_COMPLETED); - } -} - -static void mmc_insert(struct block_data *data) -{ - /* Do nothing */ -} - -static void mmc_remove(struct block_data *data) -{ - /* Only the primary partition is valid. */ - if (!data || !data->primary) - return; - - mmc_update_state(VCONFKEY_SYSMAN_MMC_REMOVED); -} - -const struct block_dev_ops mmc_block_ops = { - .name = "mmc", - .block_type = BLOCK_MMC_DEV, - .mounted = mmc_mount, - .unmounted = mmc_unmount, - .formatted = mmc_format, - .inserted = mmc_insert, - .removed = mmc_remove, -}; - -BLOCK_DEVICE_OPS_REGISTER(&mmc_block_ops) diff --git a/src/block/storage.c b/src/block/storage.c deleted file mode 100755 index c5fb269..0000000 --- a/src/block/storage.c +++ /dev/null @@ -1,410 +0,0 @@ -/* - * 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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "device-node.h" -#include "core/log.h" -#include "core/devices.h" -#include "core/common.h" -#include "core/edbus-handler.h" -#include "core/device-notifier.h" -#include "core/config-parser.h" -#include "apps/apps.h" - -#define MEMORY_STATUS_TMP_PATH "/tmp" -#define MEMNOTI_TMP_CRITICAL_VALUE (20) - -#define MEMORY_MEGABYTE_VALUE 1048576 - -#define MEMNOTI_WARNING_VALUE (5) /* 5% under */ -#define MEMNOTI_CRITICAL_VALUE (0.1) /* 0.1% under */ -#define MEMNOTI_FULL_VALUE (0.0) /* 0.0% under */ - -#define SIGNAL_LOWMEM_STATE "ChangeState" -#define SIGNAL_LOWMEM_FULL "Full" -#define MEMNOTI_TIMER_INTERVAL 5 - -#define STORAGE_CONF_FILE "/etc/deviced/storage.conf" - -enum memnoti_level { - MEMNOTI_LEVEL_CRITICAL = 0, - MEMNOTI_LEVEL_WARNING, - MEMNOTI_LEVEL_NORMAL, - MEMNOTI_LEVEL_FULL, -}; - -enum memnoti_status { - MEMNOTI_DISABLE, - MEMNOTI_ENABLE, -}; - -struct storage_config_info { - enum memnoti_level current_noti_level; - double warning_level; - double critical_level; - double full_level; -}; - -static Ecore_Timer *memnoti_timer; - -static struct storage_config_info storage_internal_info = { - .current_noti_level = MEMNOTI_LEVEL_NORMAL, - .warning_level = MEMNOTI_WARNING_VALUE, - .critical_level = MEMNOTI_CRITICAL_VALUE, - .full_level = MEMNOTI_FULL_VALUE, -}; - -static struct storage_config_info storage_tmp_info = { - .current_noti_level = MEMNOTI_LEVEL_NORMAL, - .warning_level = MEMNOTI_TMP_CRITICAL_VALUE, - .critical_level = MEMNOTI_TMP_CRITICAL_VALUE, - .full_level = MEMNOTI_FULL_VALUE, -}; - -static void memnoti_send_broadcast(char *signal, int status) -{ - char *arr[1]; - char str_status[32]; - - _I("signal %s status %d", signal, status); - snprintf(str_status, sizeof(str_status), "%d", status); - arr[0] = str_status; - broadcast_edbus_signal(DEVICED_PATH_LOWMEM, DEVICED_INTERFACE_LOWMEM, - signal, "i", arr); -} - -static int memnoti_popup(enum memnoti_level level) -{ - int ret = -1; - int val = -1; - char *value = NULL; - - if (level != MEMNOTI_LEVEL_WARNING && level != MEMNOTI_LEVEL_CRITICAL) { - _E("level check error : %d", level); - return 0; - } - - if (level == MEMNOTI_LEVEL_WARNING) - value = "lowstorage_warning"; - else if (level == MEMNOTI_LEVEL_CRITICAL) - value = "lowstorage_critical"; - - ret = vconf_get_int(VCONFKEY_STARTER_SEQUENCE, &val); - if (val == 0 || ret != 0) - goto out; - - if (value) { - ret = launch_system_app(APP_DEFAULT, - 2, APP_KEY_TYPE, value); - if (ret < 0) - _E("Failed to launch (%s) popup", value); - } - - return 0; -out: - return -1; -} - -static void storage_status_broadcast(struct storage_config_info *info, double total, double avail) -{ - double level = (avail/total)*100; - int status = MEMNOTI_DISABLE; - - if (level <= info->full_level) { - if (info->current_noti_level == MEMNOTI_LEVEL_FULL) - return; - info->current_noti_level = MEMNOTI_LEVEL_FULL; - status = MEMNOTI_ENABLE; - memnoti_send_broadcast(SIGNAL_LOWMEM_FULL, status); - return; - } - - if (level <= info->critical_level) { - if (info->current_noti_level == MEMNOTI_LEVEL_CRITICAL) - return; - if (info->current_noti_level == MEMNOTI_LEVEL_FULL) - memnoti_send_broadcast(SIGNAL_LOWMEM_FULL, status); - info->current_noti_level = MEMNOTI_LEVEL_CRITICAL; - status = MEMNOTI_ENABLE; - memnoti_send_broadcast(SIGNAL_LOWMEM_STATE, status); - return; - } - - if (info->current_noti_level == MEMNOTI_LEVEL_FULL) - memnoti_send_broadcast(SIGNAL_LOWMEM_FULL, status); - if (info->current_noti_level == MEMNOTI_LEVEL_CRITICAL) - memnoti_send_broadcast(SIGNAL_LOWMEM_STATE, status); - if (level <= info->warning_level) - info->current_noti_level = MEMNOTI_LEVEL_WARNING; - else - info->current_noti_level = MEMNOTI_LEVEL_NORMAL; -} - -static int storage_get_memory_size(const char *path, struct statvfs *s) -{ - int ret; - - if (!path) { - _E("input param error"); - return -EINVAL; - } - - ret = statvfs(path, s); - if (ret) { - _E("fail to get storage size"); - return -errno; - } - - return 0; -} - -static void get_storage_status(const char *path, struct statvfs *s) -{ - if (strcmp(path, tzplatform_getenv(TZ_SYS_HOME)) == 0) - storage_get_internal_memory_size(s); - else - storage_get_memory_size(path, s); -} - -static void init_storage_config_info(const char *path, struct storage_config_info *info) -{ - struct statvfs s; - double dAvail = 0.0; - double dTotal = 0.0; - - get_storage_status(path, &s); - - dTotal = (double)(s.f_frsize * s.f_blocks); - dAvail = (double)(s.f_bsize * s.f_bavail); - - info->full_level += (MEMORY_MEGABYTE_VALUE/dTotal)*100; - - _I("%s t: %4.0lf a: %4.0lf(%4.2lf) c:%4.4lf f:%4.4lf", - path, dTotal, dAvail, (dAvail*100/dTotal), info->critical_level, info->full_level); -} - -static void check_internal_storage_popup(struct storage_config_info *info) -{ - static enum memnoti_level old = MEMNOTI_LEVEL_NORMAL; - int ret; - - if (info->current_noti_level < MEMNOTI_LEVEL_NORMAL && info->current_noti_level < old) { - ret = memnoti_popup(info->current_noti_level); - if (ret != 0) - info->current_noti_level = MEMNOTI_LEVEL_NORMAL; - } - old = info->current_noti_level; -} - -static Eina_Bool check_storage_status(void *data) -{ - struct statvfs s; - double dAvail = 0.0; - double dTotal = 0.0; - - /* check internal */ - storage_get_internal_memory_size(&s); - dTotal = (double)s.f_frsize * s.f_blocks; - dAvail = (double)s.f_bsize * s.f_bavail; - storage_status_broadcast(&storage_internal_info, dTotal, dAvail); - check_internal_storage_popup(&storage_internal_info); - /* check tmp */ - storage_get_memory_size(MEMORY_STATUS_TMP_PATH, &s); - dTotal = (double)s.f_frsize * s.f_blocks; - dAvail = (double)s.f_bsize * s.f_bavail; - storage_status_broadcast(&storage_tmp_info, dTotal, dAvail); - - if (memnoti_timer) - ecore_timer_interval_set(memnoti_timer, MEMNOTI_TIMER_INTERVAL); - - return EINA_TRUE; -} - -static int init_storage_config_info_all(void) -{ - init_storage_config_info(tzplatform_getenv(TZ_SYS_HOME), &storage_internal_info); - init_storage_config_info(MEMORY_STATUS_TMP_PATH, &storage_tmp_info); - memnoti_timer = ecore_timer_add(MEMNOTI_TIMER_INTERVAL, - check_storage_status, NULL); - if (memnoti_timer == NULL) - _E("fail mem available noti timer add"); - return 0; -} - -static DBusMessage *edbus_getstatus(E_DBus_Object *obj, DBusMessage *msg) -{ - DBusMessageIter iter; - DBusMessage *reply; - struct statvfs s; - unsigned long long dAvail = 0.0; - unsigned long long dTotal = 0.0; - - storage_get_internal_memory_size(&s); - dTotal = (unsigned long long)s.f_frsize * s.f_blocks; - dAvail = (unsigned long long)s.f_bsize * s.f_bavail; - - reply = dbus_message_new_method_return(msg); - dbus_message_iter_init_append(reply, &iter); - dbus_message_iter_append_basic(&iter, DBUS_TYPE_UINT64, &dTotal); - dbus_message_iter_append_basic(&iter, DBUS_TYPE_UINT64, &dAvail); - return reply; -} - -static DBusMessage *edbus_get_storage_status(E_DBus_Object *obj, DBusMessage *msg) -{ - DBusMessageIter iter; - DBusMessage *reply; - DBusError err; - char *path; - struct statvfs s; - pid_t pid; - unsigned long long dAvail = 0.0; - unsigned long long dTotal = 0.0; - - dbus_error_init(&err); - if (!dbus_message_get_args(msg, &err, DBUS_TYPE_STRING, &path, DBUS_TYPE_INVALID)) { - _E("Bad message: [%s:%s]", err.name, err.message); - dbus_error_free(&err); - goto out; - } - - if (!strcmp(path, tzplatform_getenv(TZ_SYS_HOME))) - storage_get_internal_memory_size(&s); - else - storage_get_memory_size(path, &s); - - dTotal = (unsigned long long)s.f_frsize * s.f_blocks; - dAvail = (unsigned long long)s.f_bsize * s.f_bavail; - - pid = get_edbus_sender_pid(msg); - - _D("[request %d] path %s total %4.0lf avail %4.0lf", pid, path, dTotal, dAvail); - -out: - reply = dbus_message_new_method_return(msg); - dbus_message_iter_init_append(reply, &iter); - dbus_message_iter_append_basic(&iter, DBUS_TYPE_UINT64, &dTotal); - dbus_message_iter_append_basic(&iter, DBUS_TYPE_UINT64, &dAvail); - return reply; -} - -static const struct edbus_method edbus_methods[] = { - { "getstorage", NULL, "tt", edbus_getstatus }, - { "GetStatus", "s", "tt", edbus_get_storage_status}, - /* Add methods here */ -}; - -static int booting_done(void *data) -{ - static int done; - - if (data == NULL) - return done; - done = *(int *)data; - if (done == 0) - return done; - - _I("booting done"); - - if (init_storage_config_info_all() == -1) - _E("fail remain mem noti control fd init"); - return done; -} - -static int storage_poweroff(void *data) -{ - if (memnoti_timer) { - ecore_timer_del(memnoti_timer); - memnoti_timer = NULL; - } - return 0; -} - -static int load_config(struct parse_result *result, void *user_data) -{ - struct storage_config_info *info = (struct storage_config_info *)user_data; - char *name; - char *value; - - if (!info) - return -EINVAL; - - if (!MATCH(result->section, "LOWSTORAGE")) - return -EINVAL; - - _D("%s,%s,%s", result->section, result->name, result->value); - - name = result->name; - value = result->value; - - if (MATCH(name, "WARNING_LEVEL")) - info->warning_level = (double)atof(value); - else if (MATCH(name, "CRITICAL_LEVEL")) - info->critical_level = (double)atof(value); - else if (MATCH(name, "FULL_LEVEL")) - info->full_level = (double)atof(value); - - return 0; -} - -static void storage_config_load(struct storage_config_info *info) -{ - int ret; - - ret = config_parse(STORAGE_CONF_FILE, load_config, info); - if (ret < 0) - _E("Failed to load %s, %d Use default value!", STORAGE_CONF_FILE, ret); -} - -static void storage_init(void *data) -{ - int ret; - - storage_config_load(&storage_internal_info); - register_notifier(DEVICE_NOTIFIER_BOOTING_DONE, booting_done); - register_notifier(DEVICE_NOTIFIER_POWEROFF, storage_poweroff); - ret = register_edbus_method(DEVICED_PATH_STORAGE, edbus_methods, ARRAY_SIZE(edbus_methods)); - if (ret < 0) - _E("fail to init edbus method(%d)", ret); -} - -static void storage_exit(void *data) -{ - unregister_notifier(DEVICE_NOTIFIER_BOOTING_DONE, booting_done); - unregister_notifier(DEVICE_NOTIFIER_POWEROFF, storage_poweroff); -} - -static const struct device_ops storage_device_ops = { - .name = "storage", - .init = storage_init, - .exit = storage_exit, -}; - -DEVICE_OPS_REGISTER(&storage_device_ops) diff --git a/src/block/storage.conf b/src/block/storage.conf deleted file mode 100644 index 331e786..0000000 --- a/src/block/storage.conf +++ /dev/null @@ -1,7 +0,0 @@ -[LOWSTORAGE] -#5% -WARNING_LEVEL=5 -#0.1% -CRITICAL_LEVEL=0.1 -#0.0% -FULL_LEVEL=0 diff --git a/src/block/vfat.c b/src/block/vfat.c deleted file mode 100644 index 5ad8e07..0000000 --- a/src/block/vfat.c +++ /dev/null @@ -1,162 +0,0 @@ -/* - * deviced - * - * Copyright (c) 2012 - 2015 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 -#include -#include -#include -#include -#include -#include - -#include "core/common.h" -#include "core/log.h" -#include "block.h" - -#define FS_VFAT_NAME "mkdosfs" - -#ifdef TIZEN_FEATURE_BLOCK_SET_PERMISSION -/* guid 10001 - group priv_externalstorage */ -#define FS_VFAT_MOUNT_OPT "uid=0,gid=10001,dmask=0007,fmask=0117,iocharset=iso8859-1,utf8,shortname=mixed" -#else -#define FS_VFAT_MOUNT_OPT "iocharset=iso8859-1,utf8,shortname=mixed" -#endif - -static const char *vfat_arg[] = { - "/usr/bin/newfs_msdos", - "-F", "32", "-O", "tizen", "-c", "8", NULL, NULL, -}; - -static const char *vfat_check_arg[] = { - "/usr/bin/fsck_msdosfs", - "-pf", NULL, NULL, -}; - -static struct fs_check vfat_info = { - FS_TYPE_VFAT, - "vfat", - 0x1fe, - 2, - {0x55, 0xAA}, -}; - -static int vfat_check(const char *devpath) -{ - int argc, r, pass = 0; - - argc = ARRAY_SIZE(vfat_check_arg); - vfat_check_arg[argc - 2] = devpath; - - do { - r = run_child(argc, vfat_check_arg); - - switch (r) { - case 0: - _I("filesystem check completed OK"); - return 0; - case 2: - _I("file system check failed (not a FAT filesystem)"); - errno = ENODATA; - return -1; - case 4: - if (pass++ <= 2) { - _I("filesystem modified - rechecking (pass : %d)", pass); - continue; - } - _I("failing check after rechecks, but file system modified"); - errno = EIO; - return -1; - default: - _I("filesystem check failed (unknown exit code %d)", r); - errno = EIO; - return -1; - } - } while (1); -} - -static bool vfat_match(const char *devpath) -{ - int r; - - r = vfat_check(devpath); - if (r < 0) { - _E("failed to match with vfat(%s)", devpath); - return false; - } - - _I("MMC type : %s", vfat_info.name); - return true; -} - -static int vfat_mount(bool smack, const char *devpath, const char *mount_point) -{ - char options[NAME_MAX]; - int r, retry = RETRY_COUNT; - struct timespec time = {0,}; - unsigned long mountflags = MS_NOSUID | MS_NOEXEC | MS_NODEV | MS_DIRSYNC; - - 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); - - do { - r = mount(devpath, mount_point, "vfat", mountflags, options); - if (!r) { - _I("Mounted mmc card [vfat]"); - return 0; - } - _I("mount fail : r = %d, err = %d", r, errno); - time.tv_nsec = 100 * NANO_SECOND_MULTIPLIER; - nanosleep(&time, NULL); - if (r < 0 && errno == EROFS) - mountflags |= MS_RDONLY; - } while (r < 0 && (errno == ENOENT || errno == EROFS) && retry-- > 0); - - return -errno; -} - -static int vfat_format(const char *devpath) -{ - int argc; - argc = ARRAY_SIZE(vfat_arg); - vfat_arg[argc - 2] = devpath; - return run_child(argc, vfat_arg); -} - -static const struct block_fs_ops vfat_ops = { - .type = FS_TYPE_VFAT, - .name = "vfat", - .match = vfat_match, - .check = vfat_check, - .mount = vfat_mount, - .format = vfat_format, -}; - -static void __CONSTRUCTOR__ module_init(void) -{ - add_fs(&vfat_ops); -} -/* -static void __DESTRUCTOR__ module_exit(void) -{ - _I("module exit"); - remove_fs(&vfat_ops); -} -*/ -- 2.7.4