#include <app2ext_interface.h>
#include <libmount.h>
#include <blkid/blkid.h>
+#include <glib.h>
+#include <glib/gstdio.h>
+#include <gio/gio.h>
+#include <libsyscommon/libgdbus.h>
+#include <libsyscommon/ini-parser.h>
+#include <libsyscommon/list.h>
+#ifdef EXTENDED_STORAGE
+#include <ode/luks.h>
+#endif
#include "log.h"
-#include "config-parser.h"
#include "module-intf.h"
#include "udev.h"
-#include "list.h"
#include "block.h"
-#include "dbus.h"
#include "fd_handler.h"
#include "utils.h"
#include "apps.h"
+#include "storaged_common.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_PATH "*/mmcblk[0-9]*"
+#define MMC_PARTITION_PATH "mmcblk[0-9]p[0-9]"
/* Emulator send devlink for sdcard as \*\/sdcard\/\* */
-#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 EXTENDEDSD_PATH "/dev/mapper/extendedsd*"
+#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 EXTENDEDSD_NODE_PATH "/dev/mapper/extendedsd"
-#define FILESYSTEM "filesystem"
+#define FILESYSTEM_NAME "filesystem"
-#define DEV_PREFIX "/dev/"
-#define ROOT_DIR "/"
+#define DEV_PREFIX "/dev/"
+#define ROOT_DIR "/"
-#define UNMOUNT_RETRY 5
-#define TIMEOUT_MAKE_OBJECT 500 /* milliseconds */
+#define UNMOUNT_RETRY 5
+#define TIMEOUT_MAKE_OBJECT 500 /* milliseconds */
#define SIGNAL_POWEROFF_STATE "ChangeState"
+#define METHOD_ADD_POWEROFF_WAIT "AddPowerOffWait"
+#define METHOD_REMOVE_POWEROFF_WAIT "RemovePowerOffWait"
#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_CONF_FILE "/etc/storaged/block.conf"
-#define EXTERNAL_STORAGE_PATH "/run/external-storage"
-#define EXTENDED_INTERNAL_PATH "/run/extended-internal-sd"
+#define EXTERNAL_STORAGE_PATH "/run/storaged/external-storage"
+#define EXTENDED_INTERNAL_PATH "/run/storaged/extended-internal-sd"
#define PATH_LEN 55
-#define EXTENDED_SD_PATH "/opt/extendedsd"
-#define EXTENDED_SD_STRING "ExtendedInternalSD"
+#define EXTENDEDSD_MOUNT_PATH "/opt/extendedsd"
+#define VFAT_NAME "vfat"
+#define EXFAT_NAME "exfat"
#define EXT4_NAME "ext4"
#define LUKS_NAME "crypto_LUKS"
+#define EXTENDEDSD_NAME "extendedsd"
/* Minimum value of block id */
-#define BLOCK_ID_MIN 10
+#define BLOCK_ID_MIN 10
/* For 2.4 Backward Compatibility */
#define EXT_PRIMARY_SD_FIXID 1
/* Maximum number of thread */
-#define THREAD_MAX 5
+#define THREAD_MAX 5
-#define SPEEDCHECK 16
+#define SPEEDCHECK_SIZE 16
+#define SPEEDCHECK_CRITERION 4 /* MB/s */
#define PKGDIR_BUS_NAME "org.tizen.pkgdir_tool"
#define PKGDIR_PATH "/org/tizen/pkgdir_tool"
#define PKGDIR_INTERFACE "org.tizen.pkgdir_tool"
-#define ARRAY_SIZE(name) (sizeof(name)/sizeof(name[0]))
+#define POPUP_KEY_CONTENT "_SYSPOPUP_CONTENT_"
+#define VIEWTYPE_KEY "viewtype"
+#define DEVPATH_KEY "dev_path"
+#define MAPPING_NODE_KEY "mapping_node"
+#define INSERT_SD_CARD "INSERT_SD_CARD"
+
+#define MMC_POPUP_NOTI "SDcardNoti"
+#define MMC_INSERTED "inserted"
+#define MMC_REMOVED "removed"
+
+#define ARRAY_SIZE(name) (sizeof(name)/sizeof(name[0]))
+
+#define FILE_NAME_LEN_MAX 255
enum block_dev_operation {
BLOCK_DEV_MOUNT,
BLOCK_DEV_FORMAT,
BLOCK_DEV_INSERT,
BLOCK_DEV_REMOVE,
+ BLOCK_LUKS_CLOSE,
};
enum private_operation_state {
struct operation_queue {
enum block_dev_operation op;
- dbus_method_reply_handle_h reply_handle;
+ GDBusMethodInvocation *invocation;
void *data;
bool done;
};
struct block_device {
struct block_data *data;
- dd_list *op_queue;
+ GList *op_queue;
int thread_id; /* Current thread ID */
bool removed; /* True when device is physically removed but operation is not precessed yet */
enum private_operation_state on_private_op;
} block_conf[BLOCK_EXTENDEDSD_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 */
+ GList *th_node_list; /* List of devnode which thread dealt with. Only main thread access */
+ GList *block_dev_list; /* Use thread mutex */
pthread_t th;
pthread_mutex_t mutex;
pthread_cond_t cond;
bool start_th;
} th_manager[THREAD_MAX];
-static dd_list *fs_head;
-static dd_list *block_ops_list;
+char mmc_default_path[][FILE_NAME_LEN_MAX + 1] = {
+ {"Images"},
+ {"Videos"},
+ {"Sounds"},
+ {"Downloads"},
+};
+
+#define DIR_NUM ((int)(sizeof(mmc_default_path)/sizeof(mmc_default_path[0])))
+
+static GList *fs_head;
+static GList *block_ops_list;
static bool smack;
static int pfds[2];
static fd_handler_h phandler;
static bool block_control = false;
static bool block_boot = false;
static pthread_mutex_t pipe_mutex = PTHREAD_MUTEX_INITIALIZER;
+static bool add_poweroff_wait = false;
/* Assume there is only one physical internal storage */
static int dev_internal = -1;
static char dev_internal_scsi = '\0';
static char dev_internal_emul = '\0';
+static int block_start(void *data);
+static int block_stop(void *data);
+
static int add_operation(struct block_device *bdev,
enum block_dev_operation operation,
- dbus_method_reply_handle_h reply_handle, void *data);
+ GDBusMethodInvocation *invocation, 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 check_removed(struct block_device *bdev, GList **queue, struct operation_queue **op);
+static bool check_unmount(struct block_device *bdev, GList **queue, struct operation_queue **op);
static int change_mount_point(struct block_device *bdev, const char *mount_point);
+static void terminate_threads(void);
+
+#define nullstr(x) (x ? x : "")
+static GVariant *block_data_to_gvariant(struct block_data *data, int flags);
+
+#define block_send_dbus_reply(invocation, result) if (invocation) {g_dbus_method_invocation_return_value(invocation, g_variant_new("(i)", result)); }
static void uevent_block_handler(struct udev_device *dev);
static struct uevent_handler uh = {
void add_fs(const struct block_fs_ops *fs)
{
- DD_LIST_APPEND(fs_head, (void *)fs);
+ SYS_G_LIST_APPEND(fs_head, (void *)fs);
}
void remove_fs(const struct block_fs_ops *fs)
{
- DD_LIST_REMOVE(fs_head, (void *)fs);
+ SYS_G_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;
+ GList *elem;
- DD_LIST_FOREACH(fs_head, elem, fs) {
+ SYS_G_LIST_FOREACH(fs_head, elem, fs) {
if (fs->type == type)
return fs;
}
void add_block_dev(const struct block_dev_ops *ops)
{
- DD_LIST_APPEND(block_ops_list, (void *)ops);
+ SYS_G_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);
+ SYS_G_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;
+ GList *elem;
if (data->primary != true)
return;
- DD_LIST_FOREACH(block_ops_list, elem, ops) {
- if (ops->block_type != data->block_type)
+ SYS_G_LIST_FOREACH(block_ops_list, elem, ops) {
+ int data_block_type = (data->block_type == BLOCK_EXTENDEDSD_DEV)
+ ? BLOCK_MMC_DEV : data->block_type;
+
+ if (ops->block_type != data_block_type)
continue;
// TODO What happend on extended internal storage case?
if (op == BLOCK_DEV_MOUNT) {
- if (data->block_type == BLOCK_EXTENDEDSD_DEV)
- ops->mounted(data, result, true);
- else
- ops->mounted(data, result, false);
+ ops->mounted(data, result, data->block_type == BLOCK_EXTENDEDSD_DEV);
} else if (op == BLOCK_DEV_UNMOUNT) {
- if (data->block_type == BLOCK_EXTENDEDSD_DEV)
- ops->unmounted(data, result, true);
- else
- ops->unmounted(data, result, false);
+ ops->unmounted(data, result, data->block_type == BLOCK_EXTENDEDSD_DEV);
} else if (op == BLOCK_DEV_FORMAT) {
- if (data->block_type == BLOCK_EXTENDEDSD_DEV)
- ops->formatted(data, result, true);
- else
- ops->formatted(data, result, false);
+ ops->formatted(data, result, data->block_type == BLOCK_EXTENDEDSD_DEV);
} else if (op == BLOCK_DEV_INSERT)
ops->inserted(data);
else if (op == BLOCK_DEV_REMOVE)
{
static int id = BLOCK_ID_MIN;
struct block_device *bdev;
- dd_list *elem;
+ GList *elem;
bool found;
int i, j;
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) {
+ SYS_G_LIST_FOREACH(th_manager[j].block_dev_list, elem, bdev) {
if (bdev->data->id == id) {
found = true;
break;
static void remove_file(int id, bool extendedsd)
{
char file_name[PATH_LEN];
- int ret;
+ int ret_val;
if (id < 0)
return;
else
snprintf(file_name, sizeof(file_name), EXTERNAL_STORAGE_PATH"/%d", id);
- ret = remove(file_name);
- if (ret < 0)
- _E("Fail to remove %s. errno: %d", file_name, errno);
+ ret_val = remove(file_name);
+ if (ret_val < 0)
+ _E("Failed to remove '%s': %d", file_name, errno);
}
static void create_file(int id, char *mount_point, bool extendedsd)
fprintf(fp, "%s", mount_point);
fclose(fp);
} else
- _E("Fail to open %s", file_name);
+ _E("Failed to open '%s'.", file_name);
}
-static void signal_device_blocked(struct block_device *bdev)
+static void broadcast_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;
+ int ret_dbus;
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_dbus_signal(STORAGED_PATH_BLOCK_MANAGER,
+ ret_dbus = gdbus_signal_emit(NULL,
+ STORAGED_PATH_BLOCK_MANAGER,
STORAGED_INTERFACE_BLOCK_MANAGER,
BLOCK_DEVICE_BLOCKED,
- "issssssisibii", arr);
+ block_data_to_gvariant(data, 0));
+ if (ret_dbus < 0)
+ _E("Failed to send dbus signal");
}
-static void signal_device_changed(struct block_device *bdev,
+static void broadcast_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;
+ GVariant *param = NULL;
+ const char *signal_name = NULL;
+ int flags = 0;
+ int ret_dbus;
- if (!bdev || !bdev->data)
+ if (!bdev || !bdev->data) {
+ _E("Failed to broadcast device changed signal. op(%d)", op);
return;
+ }
data = bdev->data;
+ /* set flags and signal name */
switch (op) {
case BLOCK_DEV_MOUNT:
BLOCK_GET_MOUNT_FLAGS(data, flags);
+ signal_name = BLOCK_DEVICE_CHANGED;
break;
case BLOCK_DEV_UNMOUNT:
BLOCK_GET_UNMOUNT_FLAGS(data, flags);
+ signal_name = BLOCK_DEVICE_CHANGED;
break;
case BLOCK_DEV_FORMAT:
BLOCK_GET_FORMAT_FLAGS(data, flags);
+ signal_name = BLOCK_DEVICE_CHANGED;
break;
- default:
+ case BLOCK_DEV_INSERT:
+ flags = 0;
+ signal_name = BLOCK_DEVICE_ADDED;
+ break;
+ case BLOCK_DEV_REMOVE:
flags = 0;
+ signal_name = BLOCK_DEVICE_REMOVED;
break;
+ default:
+ /* unknown op */
+ _E("Failed to broadcast device changed signal. op(%d)", op);
+ return;
}
/* 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_dbus_signal(STORAGED_PATH_BLOCK_MANAGER,
- STORAGED_INTERFACE_BLOCK_MANAGER,
- BLOCK_DEVICE_ADDED,
- "issssssisibii", arr);
- else if (op == BLOCK_DEV_REMOVE)
- broadcast_dbus_signal(STORAGED_PATH_BLOCK_MANAGER,
- STORAGED_INTERFACE_BLOCK_MANAGER,
- BLOCK_DEVICE_REMOVED,
- "issssssisibii", arr);
- else {
- broadcast_dbus_signal(STORAGED_PATH_BLOCK_MANAGER,
- STORAGED_INTERFACE_BLOCK_MANAGER,
- BLOCK_DEVICE_CHANGED,
- "issssssisibii", arr);
- broadcast_dbus_signal(STORAGED_PATH_BLOCK_MANAGER,
+ param = block_data_to_gvariant(data, flags);
+
+ ret_dbus = gdbus_signal_emit(NULL,
+ STORAGED_PATH_BLOCK_MANAGER,
STORAGED_INTERFACE_BLOCK_MANAGER,
- BLOCK_DEVICE_CHANGED_2,
- "issssssisibi", arr);
- }
+ signal_name,
+ param);
+ if (ret_dbus < 0)
+ _E("Failed to broadcast device changed signal. op(%d)", op);
}
static int get_mmc_mount_node(char *devnode, char *node, size_t len)
{
const char *str;
char *name, node[64];
- int ret;
+ int ret_val;
- if (!data || !data->devnode || !data->fs_usage || strcmp(data->fs_usage, FILESYSTEM))
+ if (!data || !data->devnode || !data->fs_usage || (strcmp(data->fs_usage, FILESYSTEM_NAME) && strncmp(data->fs_usage, "crypto", strlen("crypto"))))
return NULL;
name = strrchr(data->devnode, '/');
switch (data->block_type) {
case BLOCK_MMC_DEV:
- ret = get_mmc_mount_node(name, node, sizeof(node));
+ ret_val = get_mmc_mount_node(name, node, sizeof(node));
break;
case BLOCK_SCSI_DEV:
- ret = get_scsi_mount_node(name, node, sizeof(node));
+ ret_val = get_scsi_mount_node(name, node, sizeof(node));
break;
case BLOCK_EXTENDEDSD_DEV:
- return strdup(EXTENDED_SD_PATH);
+ return strdup(EXTENDEDSD_MOUNT_PATH);
default:
- _E("Invalid block type (%d)", data->block_type);
+ _E("Invalid block type(%d).", data->block_type);
return NULL;
}
- if (ret < 0)
+ if (ret_val < 0)
goto out;
str = tzplatform_mkpath(TZ_SYS_MEDIA, node);
return strdup(str);
out:
- _E("Invalid devnode (%s)", data->devnode ? data->devnode : "NULL");
+ _E("Invalid devnode(%s).", data->devnode ? data->devnode : "NULL");
return NULL;
}
{
struct block_fs_ops *fs;
blkid_probe probe;
- dd_list *elem;
+ GList *elem;
const char *filesystem = NULL;
char *temp;
char str[PATH_MAX];
char str2[PATH_MAX];
size_t fs_len;
int len;
- int ret;
+ int ret_val;
int i;
bool found = false;
if (fnmatch(MMC_LINK_PATH, devnode, 0) &&
fnmatch(MMC_PATH, devnode, 0) &&
fnmatch(SCSI_PATH, devnode, 0) &&
- fnmatch(EXTENDEDSD_PATH, devnode, 0))
+ fnmatch(EXTENDEDSD_NODE_PATH, devnode, 0))
return false;
temp = strrchr(devnode, '/');
str[len - 1] = '\0';
for (i = 1; i <= 9; ++i) {
- snprintf(str2, sizeof(str2), "%s%d", str, i);
+ if ((ret_val = snprintf(str2, sizeof(str2), "%s%d", str, i)) > sizeof(str2) - 1) {
+ _E("Filename is longer than buffer. Need %d size of buffer.", ret_val + 1);
+ continue;
+ }
+
if (access(str2, R_OK) != 0)
continue;
if (blkid_do_probe(probe) != 0)
continue;
- ret = blkid_probe_lookup_value(probe, "TYPE", &filesystem, &fs_len);
- if (ret < 0) {
+ ret_val = blkid_probe_lookup_value(probe, "TYPE", &filesystem, &fs_len);
+ if (ret_val < 0) {
blkid_free_probe(probe);
continue;
}
- DD_LIST_FOREACH(fs_head, elem, fs) {
+ SYS_G_LIST_FOREACH(fs_head, elem, fs) {
if (!strncmp(fs->name, filesystem, fs_len)) {
found = true;
break;
return NULL;
if (!fs_type)
- _I("Unknown fs type");
+ _I("Unknown fs type.");
data = calloc(1, sizeof(struct block_data));
if (!data) {
- _E("calloc() failed");
+ _E("Failed to calloc().");
return NULL;
}
data->block_type = BLOCK_MMC_DEV;
else if (!fnmatch(SCSI_PATH, devnode, 0))
data->block_type = BLOCK_SCSI_DEV;
- else if (!fnmatch(EXTENDEDSD_PATH, devnode, 0))
+ else if (!fnmatch(EXTENDEDSD_NODE_PATH, devnode, 0))
data->block_type = BLOCK_EXTENDEDSD_DEV;
else
data->block_type = -1;
/* for 2.4 backward compatibility */
// What if storage id 1 is existed? (multi sdcard case)
if (data->primary == true && data->block_type == BLOCK_MMC_DEV &&
- data->fs_usage && !strcmp(data->fs_usage, FILESYSTEM))
+ data->fs_usage && !strcmp(data->fs_usage, FILESYSTEM_NAME))
data->id = EXT_PRIMARY_SD_FIXID;
else
data->id = block_get_new_id();
// Called by MainThread - Remove DevNode
static void free_block_device(struct block_device *bdev)
{
- dd_list *l, *next;
+ GList *l, *next;
struct operation_queue *op;
int thread_id;
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);
+ SYS_G_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) {
+ SYS_G_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);
+ SYS_G_LIST_REMOVE(bdev->op_queue, op);
free(op);
}
pthread_mutex_unlock(&(th_manager[thread_id].mutex));
static struct block_device *find_block_device(const char *devnode)
{
struct block_device *bdev;
- dd_list *elem;
+ GList *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) {
+ SYS_G_LIST_FOREACH(th_manager[i].block_dev_list, elem, bdev) {
if (bdev->data && !bdev->removed &&
!strncmp(bdev->data->devnode, devnode, len)) {
pthread_mutex_unlock(&(th_manager[i].mutex));
return NULL;
}
+// Called By MainThread - Remove Device
+static struct block_device *find_block_device_path(const char *mount_point)
+{
+ struct block_device *bdev;
+ GList *elem;
+ int len;
+ int i;
+
+ len = strlen(mount_point) + 1;
+ for (i = 0; i < THREAD_MAX; i++) {
+ pthread_mutex_lock(&(th_manager[i].mutex));
+ SYS_G_LIST_FOREACH(th_manager[i].block_dev_list, elem, bdev) {
+ if (bdev->data && !bdev->removed &&
+ (bdev->data->mount_point != NULL && !strncmp(bdev->data->mount_point, mount_point, 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;
+ GList *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) {
+ SYS_G_LIST_FOREACH(th_manager[i].block_dev_list, elem, bdev) {
if (!bdev->data)
continue;
if (bdev->removed)
return NULL;
}
-static char *get_operation_char(enum block_dev_operation op,
- char *name, unsigned int len)
+static const char *get_operation_char(enum block_dev_operation op)
{
- char *str = "unknown";
-
- if (!name)
- return NULL;
-
switch (op) {
case BLOCK_DEV_MOUNT:
- str = "MOUNT";
- break;
+ return "MOUNT";
+
case BLOCK_DEV_UNMOUNT:
- str = "UNMOUNT";
- break;
+ return "UNMOUNT";
+
case BLOCK_DEV_FORMAT:
- str = "FORMAT";
- break;
+ return "FORMAT";
+
case BLOCK_DEV_INSERT:
- str = "INSERT";
- break;
+ return "INSERT";
+
case BLOCK_DEV_REMOVE:
- str = "REMOVE";
- break;
- default:
- _E("invalid operation (%d)", op);
- break;
+ return "REMOVE";
+
+ case BLOCK_LUKS_CLOSE:
+ return "LUKS CLOSE";
}
- snprintf(name, len, "%s", str);
- return name;
+ _E("Invalid operation(%d).", op);
+ return "unknown";
+}
+
+void mmc_make_default_path(const char *mount_path)
+{
+ int i = 0;
+ int ret_val = 0;
+ char mmc_path[FILE_NAME_LEN_MAX + 1] = {0, };
+
+ for (i = 0; i < DIR_NUM; ++i) {
+ if ((ret_val = snprintf(mmc_path, sizeof(mmc_path), "%s/%s", mount_path, mmc_default_path[i])) > sizeof(mmc_path) - 1) {
+ _E("Path is longer than buffer. Need %d size of buffer.", ret_val + 1);
+ continue;
+ }
+
+ if (!g_file_test(mmc_path, G_FILE_TEST_IS_DIR)) {
+ _D("Path(%s) did not exist.", mmc_path);
+ ret_val = mkdir(mmc_path, 0777);
+ if (ret_val != 0)
+ _E("Failed to mkdir: %d", errno);
+
+ /*this fuction for emulator*/
+ /*at the first time, the directroies are made permission 755*/
+ ret_val = chmod(mmc_path, 0777);
+ if (ret_val != 0)
+ _E("Failed to chmod: %d", errno);
+
+ ret_val = chown(mmc_path, 0, 10001);
+ if (ret_val != 0)
+ _E("Failed to chown: %d", errno);
+ }
+ }
}
static void create_external_apps_directory(void)
{
- int ret;
+ int ret_dbus;
- ret = call_dbus_method_async(PKGDIR_BUS_NAME, PKGDIR_PATH,
- PKGDIR_INTERFACE, "CreateExternalDirsForAllPkgs",
- NULL, NULL, NULL, DBUS_TIMEOUT_USE_DEFAULT, NULL);
- if (ret)
- _E("Fail to create external directory");
+ ret_dbus = gdbus_call_async(PKGDIR_BUS_NAME, PKGDIR_PATH,
+ PKGDIR_INTERFACE, "CreateExternalDirsForAllPkgs", NULL);
+ if (ret_dbus)
+ _E("Failed to create external directory.");
}
static int pipe_trigger(enum block_dev_operation op,
{
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)),
+ _D("op=%s bdev=%p result=%d",
+ get_operation_char(pdata.op),
pdata.bdev, pdata.result);
// Multi thread should not write at the same time
struct pipe_data pdata = {0,};
int n;
int thread_id;
- int ret;
- char name[16];
+ int ret_val;
n = read(fd, &pdata, sizeof(pdata));
if (n != sizeof(pdata) || !pdata.bdev) {
- _E("fail to read struct pipe data");
+ _E("Failed to read struct pipe data.");
goto out;
}
- _I("op : %s, bdev : %p, result : %d",
- get_operation_char(pdata.op, name, sizeof(name)),
+ _I("op=%s bdev=%p result=%d",
+ get_operation_char(pdata.op),
pdata.bdev, pdata.result);
+ if (pdata.op == BLOCK_LUKS_CLOSE)
+ goto out;
+
if (pdata.op == BLOCK_DEV_MOUNT && pdata.result < 0) {
if (pdata.bdev->data->state == BLOCK_UNMOUNT) {
- ret = change_mount_point(pdata.bdev, "");
+ ret_val = change_mount_point(pdata.bdev, "");
/* Modify /run/external-storage/id file */
- if (ret == 0) {
+ if (ret_val == 0) {
if (pdata.bdev->data->block_type == BLOCK_EXTENDEDSD_DEV)
create_file(pdata.bdev->data->id, pdata.bdev->data->mount_point, true);
else
}
goto out;
}
+
+ if (pdata.op == BLOCK_DEV_MOUNT && (pdata.result == 0)) {
+ /* Create file for block device /run/external-storage/id */
+ create_file(pdata.bdev->data->id, pdata.bdev->data->mount_point, pdata.bdev->data->block_type == BLOCK_EXTENDEDSD_DEV);
+ }
+
if (pdata.op == BLOCK_DEV_MOUNT &&
pdata.bdev->data->state == BLOCK_MOUNT &&
pdata.bdev->data->block_type == BLOCK_MMC_DEV &&
- pdata.bdev->data->primary)
+ pdata.bdev->data->primary) {
create_external_apps_directory();
+ mmc_make_default_path(pdata.bdev->data->mount_point);
+
+ ret_val = gdbus_call_sync_with_reply_int(POPUP_BUS_NAME,
+ POPUP_PATH_NOTI,
+ POPUP_INTERFACE_NOTI,
+ MMC_POPUP_NOTI,
+ g_variant_new("(s)", MMC_INSERTED),
+ NULL);
+ if (ret_val != 0)
+ _E("Failed to popup: %d", ret_val);
+ }
+
if (pdata.op == BLOCK_DEV_UNMOUNT) {
/* Remove file for block device /run/xxxxxx/id */
remove_file(pdata.bdev->data->id, pdata.bdev->data->block_type == BLOCK_EXTENDEDSD_DEV);
+
+ if (pdata.bdev->data->block_type == BLOCK_MMC_DEV &&
+ pdata.bdev->data->primary &&
+ BLOCK_IS_FLAG_SET(pdata.bdev->data, UNMOUNT_UNSAFE)) {
+
+ ret_val = gdbus_call_sync_with_reply_int(POPUP_BUS_NAME,
+ POPUP_PATH_NOTI,
+ POPUP_INTERFACE_NOTI,
+ MMC_POPUP_NOTI,
+ g_variant_new("(s)", MMC_REMOVED),
+ NULL);
+ if (ret_val != 0)
+ _E("Failed to popup: %d", ret_val);
+ }
}
/* Broadcast to mmc and usb storage module */
/* Broadcast outside with Block iface */
if (pdata.bdev->on_private_op == REQ_NORMAL)
- signal_device_changed(pdata.bdev, pdata.op);
+ broadcast_device_changed(pdata.bdev, pdata.op);
else if (pdata.bdev->on_private_op == REQ_PRIVATE) {
if (pdata.op == BLOCK_DEV_UNMOUNT) {
pdata.bdev->on_private_op = REQ_NORMAL;
- _D("Private operation state: %d", pdata.bdev->on_private_op);
+ _D("Private operation state(%d).", pdata.bdev->on_private_op);
}
} else {
if (pdata.op == BLOCK_DEV_MOUNT) {
pdata.bdev->on_private_op = REQ_PRIVATE;
- _D("Private operation state: %d", pdata.bdev->on_private_op);
+ _D("Private operation state(%d).", pdata.bdev->on_private_op);
}
}
static int pipe_init(void)
{
- int ret;
+ int ret_val;
- ret = pipe2(pfds, O_CLOEXEC);
- if (ret == -1)
+ ret_val = pipe2(pfds, O_CLOEXEC);
+ if (ret_val == -1)
return -errno;
- ret = add_fd_read_handler(pfds[0], pipe_cb,
+ ret_val = add_fd_read_handler(pfds[0], pipe_cb,
NULL, NULL, &phandler);
- if (ret < 0) {
- _E("Failed to add pipe handler (%d)", ret);
- return ret;
+ if (ret_val < 0) {
+ _E("Failed to add pipe handler: %d", ret_val);
+ return ret_val;
}
return 0;
{
struct udev *udev;
struct udev_device *dev;
+ const char *fs_type;
+ const char *fs_usage;
int r;
+ int wait;
if (!data)
return -EINVAL;
- udev = udev_new();
- if (!udev) {
- _E("fail to create udev library context");
- return -EPERM;
- }
+ for (wait = 0; wait < 10; wait++) {
+ udev = udev_new();
+ if (!udev) {
+ _E("Failed 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");
+ dev = udev_device_new_from_syspath(udev, data->syspath);
+ if (!dev) {
+ _E("Failed to create new udev device.");
+ udev_unref(udev);
+ return -EPERM;
+ }
+
+ fs_type = udev_device_get_property_value(dev, "ID_FS_TYPE");
+ fs_usage = udev_device_get_property_value(dev, "ID_FS_USAGE");
+ /* fs_usage for crpto_LUKS is crypto */
+ if (!fs_type || (strncmp(fs_type, VFAT_NAME, strlen(VFAT_NAME)) && strncmp(fs_type, EXT4_NAME, strlen(EXT4_NAME))))
+ sleep(1);
+ else if (!fs_usage || strncmp(FILESYSTEM_NAME, fs_usage, strlen(FILESYSTEM_NAME)))
+ sleep(1);
+ else
+ break;
+
+ udev_device_unref(dev);
udev_unref(udev);
- return -EPERM;
}
r = update_block_data(data,
udev_device_get_sysattr_value(dev, "ro"),
mount_point_updated);
if (r < 0)
- _E("fail to update block data for %s", data->devnode);
+ _E("Failed to update block data for %s.", data->devnode);
udev_device_unref(dev);
udev_unref(udev);
static int block_mount(struct block_data *data)
{
struct block_fs_ops *fs;
- dd_list *elem;
+ GList *elem;
int r;
int len;
/* check matched file system */
if (!data->fs_usage ||
- strncmp(data->fs_usage, FILESYSTEM,
- sizeof(FILESYSTEM)) != 0) {
+ strncmp(data->fs_usage, FILESYSTEM_NAME,
+ sizeof(FILESYSTEM_NAME)) != 0) {
r = -ENODEV;
goto out;
}
if (!data->fs_type) {
- _E("There is no file system");
+ _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) {
+ SYS_G_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);
+ _E("Not supported file system(%s).", data->fs_type);
BLOCK_FLAG_SET(data, FS_NOT_SUPPORTED);
r = -ENOTSUP;
goto out;
static int mount_start(struct block_device *bdev)
{
struct block_data *data;
- int ret;
+ int ret_val;
int r;
assert(bdev);
assert(bdev->data);
data = bdev->data;
- _I("Mount Start : (%s -> %s)",
+ _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);
+ _E("Failed to mount device(%s): %d", data->devnode, r);
goto out;
}
if (data->block_type == BLOCK_MMC_DEV) {
/* app2ext_migrate_legacy_all has dbus method call to deviced */
- ret = app2ext_migrate_legacy_all();
- if (ret < 0)
- _E("app2ext failed");
+ ret_val = app2ext_migrate_legacy_all();
+ if (ret_val < 0)
+ _E("Failed to app2ext.");
}
out:
if (r < 0 && r != -EROFS)
data->state = BLOCK_UNMOUNT;
- _I("%s result : %s, %d", __func__, data->devnode, r);
+ _I("%s result=%s: %d", __func__, data->devnode, r);
if (pipe_trigger(BLOCK_DEV_MOUNT, bdev, r) < 0)
- _E("fail to trigger pipe");
+ _E("Failed to trigger pipe.");
return r;
}
data = bdev->data;
if (data->state == BLOCK_MOUNT) {
- _I("%s is already mounted", data->devnode);
+ _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");
+ _I("Not support multi mount by config info.");
return 0;
}
r = mount_start(bdev);
if (r < 0) {
- _E("Failed to mount (%s)", data->devnode);
+ _E("Failed to mount %s.", data->devnode);
return r;
}
{
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;
if (bdev->on_private_op == REQ_NORMAL)
- signal_device_blocked(bdev);
+ broadcast_device_blocked(bdev);
/* 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);
+ _I("Failed to unmount with normal option: %d", r);
return r;
}
- _I("Execute force unmount!");
+ _I("Execute force unmount.");
/* Force Unmount Scenario */
- while (1) {
- switch (retry++) {
- case 0:
- /* Mobile specific:
- * should unmount the below vconf key. */
- if ((data->block_type == BLOCK_MMC_DEV ||
- data->block_type == BLOCK_EXTENDEDSD_DEV) &&
- data->primary) {
- /* At first, notify to other app
- * who already access sdcard */
- _I("Notify to other app who already access sdcard");
- 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);
+ /* Mobile specific:
+ * should unmount the below vconf key. */
+ if ((data->block_type == BLOCK_MMC_DEV ||
+ data->block_type == BLOCK_EXTENDEDSD_DEV) &&
+ data->primary) {
+ /* At first, notify to other app who already access sdcard */
+ _I("Notify to other app who already access sdcard.");
+ vconf_set_int(VCONFKEY_SYSMAN_MMC_STATUS,
+ VCONFKEY_SYSMAN_MMC_INSERTED_NOT_MOUNTED);
- print_open_files(data->mount_point);
+ /* Wait for 700 msec to release open files */
+ usleep(700 * 1000);
+ }
- r = mmc_check_and_unmount(data->mount_point);
- if (!r) {
- _D("Success to unmount (%s)", data->mount_point);
+ sync();
+
+ if (umount2(data->mount_point, MNT_DETACH) != 0) {
+ _I("Failed to unmount with lazy option: %m");
+ return -errno;
+ }
+
+ while (retry++ < UNMOUNT_RETRY) {
+ _I("Kill app with SIGTERM.");
+ terminate_process(data->devnode, false);
+ usleep(500 * 1000);
+
+ if (!is_in_use_partition(data->devnode))
+ break;
+
+ _I("Kill app with SIGKILL.");
+ terminate_process(data->devnode, true);
+ usleep(500 * 1000);
+
+ if (!is_in_use_partition(data->devnode))
break;
- }
}
+ sync();
+
out:
data->state = BLOCK_UNMOUNT;
if (rmdir(data->mount_point) < 0)
- _E("fail to remove %s directory", data->mount_point);
+ _E("Failed to remove '%s' directory.", data->mount_point);
return r;
}
data = bdev->data;
if (data->state == BLOCK_UNMOUNT) {
- _I("%s is already unmounted", data->devnode);
+ _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)",
+ _E("The path was existed, but could not delete it(%s).",
data->mount_point);
return 0;
}
- _I("Unmount Start : (%s -> %s)",
+ _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);
+ _E("Failed 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);
+ _I("%s result=%s: %d", __func__, data->devnode, r);
if (pipe_trigger(BLOCK_DEV_UNMOUNT, bdev, r) < 0)
- _E("fail to trigger pipe");
+ _E("Failed to trigger pipe.");
return r;
}
static int block_format(struct block_data *data,
- const char *fs_type, bool mount_point_updated, bool udev_update)
+ const char *fs_type, bool mount_point_updated)
{
const struct block_fs_ops *fs;
- dd_list *elem;
+ GList *elem;
const char *fstype;
int len;
int r;
} else
fstype = fs_type;
}
+ if (!strcmp(fstype, EXFAT_NAME))
+ fstype = VFAT_NAME;
fs = NULL;
len = strlen(fstype);
- DD_LIST_FOREACH(fs_head, elem, fs) {
+ SYS_G_LIST_FOREACH(fs_head, elem, fs) {
if (!strncmp(fs->name, fstype, len))
break;
}
- if (!fs) {
+ if (!fs || !fs->format) {
BLOCK_FLAG_SET(data, FS_NOT_SUPPORTED);
- _E("not supported file system(%s)", fstype);
+ _E("Not supported file system(%s).", fstype);
return -ENOTSUP;
}
- _I("format path : %s", data->devnode);
- fs->check(data->devnode);
+ _I("Format path=%s", data->devnode);
r = fs->format(data->devnode);
if (r < 0) {
- _E("fail to format block data for %s", data->devnode);
+ _E("Failed to format block data for %s.", data->devnode);
goto out;
}
- /* it takes some seconds til kernel set udev property */
- sleep(2);
-
/* need to update the partition data.
* It can be changed in doing format. */
- if (udev_update)
- retrieve_udev_device(data, mount_point_updated);
+ retrieve_udev_device(data, mount_point_updated);
out:
return r;
}
data = bdev->data;
- _I("Format Start : (%s -> %s)",
+ _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);
+ _E("Failed to unmount %s device: %d", data->devnode, r);
goto out;
}
}
- r = block_format(data, fs_type, bdev->mount_point_updated, false);
+ r = block_format(data, fs_type, bdev->mount_point_updated);
if (r < 0)
- _E("fail to format %s device : %d", data->devnode, r);
+ _E("Failed to format %s device: %d", data->devnode, r);
out:
- _I("%s result : %s, %d", __func__, data->devnode, r);
+ _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");
+ _E("Failed to trigger pipe.");
return r;
}
fdata = (struct format_data *)malloc(sizeof(struct format_data));
if (!fdata) {
- _E("fail to allocate format data");
+ _E("Failed to allocate format data.");
return NULL;
}
// Called by BlockThread - Real Mount Op
static int block_mount_device(struct block_device *bdev, void *data)
{
- dd_list *l;
+ GList *l;
int ret;
int 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);
+ l = SYS_G_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);
+ _E("'%s' 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);
+ _E("Failed 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;
+ GList *l;
int ret;
int thread_id;
struct format_data *fdata = (struct format_data *)data;
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);
+ l = SYS_G_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);
+ _E("'%s' 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);
+ _E("Failed to format block device for %s.", bdev->data->devnode);
out:
release_format_data(fdata);
ret = unmount_block_device(bdev, option);
if (ret < 0) {
- _E("Failed to unmount block device (%s)", bdev->data->devnode);
+ _E("Failed to unmount block device(%s).", bdev->data->devnode);
return ret;
}
static void remove_operation(struct block_device *bdev)
{
struct operation_queue *op;
- dd_list *l, *next;
- char name[16];
+ GList *l, *next;
int thread_id;
assert(bdev);
if (thread_id < 0 || thread_id >= THREAD_MAX)
return;
- DD_LIST_FOREACH_SAFE(bdev->op_queue, l, next, op) {
+ SYS_G_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)),
+ _D("Remove operation(%s, %s).",
+ get_operation_char(op->op),
bdev->data->devnode);
- DD_LIST_REMOVE(bdev->op_queue, op);
+ SYS_G_LIST_REMOVE(bdev->op_queue, op);
free(op);
}
}
}
-static void block_send_dbus_reply(dbus_method_reply_handle_h reply_handle, int result)
-{
- DBusMessage *rep;
-
- if (!reply_handle)
- return;
-
- rep = make_dbus_reply_message_simple(reply_handle, result);
- reply_dbus_method_result(reply_handle, rep);
-}
-
// Called by BlockThread
-static void check_removed(struct block_device *bdev, dd_list **queue, struct operation_queue **op)
+static void check_removed(struct block_device *bdev, GList **queue, struct operation_queue **op)
{
struct operation_queue *temp;
- dd_list *l;
+ GList *l;
int thread_id;
if (!bdev)
pthread_mutex_lock(&(th_manager[thread_id].mutex));
- DD_LIST_FOREACH(*queue, l, temp) {
+ SYS_G_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)->reply_handle, 0);
+ block_send_dbus_reply((*op)->invocation, 0);
}
remove_operation(bdev);
}
// Called by BlockThread
-static bool check_unmount(struct block_device *bdev, dd_list **queue, struct operation_queue **op)
+static bool check_unmount(struct block_device *bdev, GList **queue, struct operation_queue **op)
{
struct operation_queue *temp;
- dd_list *l;
+ GList *l;
int thread_id;
bool unmounted = false;
return false;
pthread_mutex_lock(&(th_manager[thread_id].mutex));
- DD_LIST_FOREACH(*queue, l, temp) {
+ SYS_G_LIST_FOREACH(*queue, l, temp) {
if (temp->op == BLOCK_DEV_UNMOUNT) {
unmounted = true;
- _D("Operation queue has unmount operation");
+ _D("Operation queue has unmount operation.");
break;
}
}
pthread_mutex_lock(&(th_manager[thread_id].mutex));
- DD_LIST_FOREACH(*queue, l, temp) {
+ SYS_G_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)->reply_handle, 0);
+ block_send_dbus_reply((*op)->invocation, 0);
}
remove_operation(bdev);
}
// Called by BlockThread
-static void trigger_operation(struct block_device *bdev, dd_list *queue, struct operation_queue *op)
+static void trigger_operation(struct block_device *bdev, GList *queue, struct operation_queue *op)
{
- int ret = 0;
+ int ret_val = 0;
int thread_id;
char devnode[PATH_MAX];
- char name[16];
enum block_dev_operation operation;
bool unmounted = false;
operation = op->op;
- _D("Thread id %d Trigger operation (%s, %s)", thread_id,
- get_operation_char(operation, name, sizeof(name)), devnode);
+ _D("Thread id(%d) Trigger operation(%s, %s)", thread_id,
+ get_operation_char(operation), 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);
+ _D("Trigger operation again(%s, %s).",
+ get_operation_char(operation), 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);
+ _D("Trigger operation again(%s, %s).",
+ get_operation_char(operation), devnode);
}
}
case BLOCK_DEV_INSERT:
break;
case BLOCK_DEV_MOUNT:
- ret = block_mount_device(bdev, op->data);
- _D("Mount (%s) result:(%d)", devnode, ret);
+ ret_val = block_mount_device(bdev, op->data);
+ _D("Mount '%s': %d", devnode, ret_val);
break;
case BLOCK_DEV_FORMAT:
- ret = block_format_device(bdev, op->data);
- _D("Format (%s) result:(%d)", devnode, ret);
+ ret_val = block_format_device(bdev, op->data);
+ _D("Format '%s': %d", devnode, ret_val);
break;
case BLOCK_DEV_UNMOUNT:
- ret = block_unmount_device(bdev, op->data);
- _D("Unmount (%s) result:(%d)", devnode, ret);
+ ret_val = block_unmount_device(bdev, op->data);
+ _D("Unmount '%s': %d", devnode, ret_val);
break;
case BLOCK_DEV_REMOVE:
/* Do nothing */
break;
+ case BLOCK_LUKS_CLOSE:
+#ifdef EXTENDED_STORAGE
+ ret_val = ode_luks_close_sync(EXTENDEDSD_NAME);
+ if (ret_val < 0)
+ _E("Failed on ode_luks_close(%s).", EXTENDEDSD_NAME);
+#endif
+ break;
default:
- _E("Operation type is invalid (%d)", op->op);
- ret = -EINVAL;
+ _E("Operation type(%d) is invalid.", op->op);
+ ret_val = -EINVAL;
break;
}
op->done = true;
th_manager[thread_id].op_len--;
- block_send_dbus_reply(op->reply_handle, ret);
+ block_send_dbus_reply(op->invocation, ret_val);
queue = bdev->op_queue;
if (queue != NULL) {
- queue = DD_LIST_NEXT(queue);
+ queue = SYS_G_LIST_NEXT(queue);
if (queue != NULL)
- op = DD_LIST_NTH(queue, 0);
+ op = SYS_G_LIST_NTH(queue, 0);
else
op = NULL;
} else
pthread_mutex_unlock(&(th_manager[thread_id].mutex));
/* UNLOCK */
- if (operation == BLOCK_DEV_INSERT || operation == BLOCK_DEV_REMOVE) {
+ if (operation == BLOCK_DEV_INSERT || operation == BLOCK_DEV_REMOVE || operation == BLOCK_LUKS_CLOSE) {
if (pipe_trigger(operation, bdev, 0) < 0)
- _E("fail to trigger pipe");
+ _E("Failed to trigger pipe.");
}
} while (true);
struct block_device *temp;
struct manage_thread *th = (struct manage_thread *)arg;
struct operation_queue *op = NULL;
- dd_list *elem;
- dd_list *queue = NULL;
+ GList *elem;
+ GList *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);
+ _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");
+ _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);
+ _D("Wake up thread=%d.", thread_id);
}
- DD_LIST_FOREACH(th_manager[thread_id].block_dev_list, elem, temp) {
+ SYS_G_LIST_FOREACH(th_manager[thread_id].block_dev_list, elem, temp) {
queue = temp->op_queue;
do {
- op = DD_LIST_NTH(queue, 0);
+ op = SYS_G_LIST_NTH(queue, 0);
if (!op) {
- _D("Operation queue for device %s is Empty", temp->data->devnode);
+ _D("Operation queue for device %s is Empty.", temp->data->devnode);
break;
}
if (op->done) {
- queue = DD_LIST_NEXT(queue);
+ queue = SYS_G_LIST_NEXT(queue);
continue;
}
break;
// Especially, we don't need to keep th_node_list.
static int find_thread(char *devnode)
{
- dd_list *elem;
+ GList *elem;
char str[PATH_MAX];
char *th_node;
char *temp;
min_num = 1000;
min = -1;
for (i = 0; i < THREAD_MAX; i++) {
- DD_LIST_FOREACH(th_manager[i].th_node_list, elem, temp) {
+ SYS_G_LIST_FOREACH(th_manager[i].th_node_list, elem, temp) {
if (!strncmp(temp, th_node, len)) {
free(th_node);
return i;
}
if (min >= 0 && min < THREAD_MAX) {
- DD_LIST_APPEND(th_manager[min].th_node_list, th_node);
+ SYS_G_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);
+ _E("Failed to find thread.");
+ SYS_G_LIST_APPEND(th_manager[0].th_node_list, th_node);
return 0;
}
// Called by MainThread
static int add_operation(struct block_device *bdev,
enum block_dev_operation operation,
- dbus_method_reply_handle_h reply_handle, void *data)
+ GDBusMethodInvocation *invocation, void *data)
{
struct operation_queue *op;
- int ret;
+ int ret_val;
int thread_id;
bool start_th;
- char name[16];
if (!bdev)
return -EINVAL;
- _I("Add operation (%s, %s)",
- get_operation_char(operation, name, sizeof(name)),
+ _I("Add operation(%s, %s).",
+ get_operation_char(operation),
bdev->data->devnode);
thread_id = bdev->thread_id;
if (thread_id < 0 || thread_id >= THREAD_MAX) {
- _E("Fail to find thread to add");
+ _E("Failed to find thread to add.");
return -EPERM;
}
op = (struct operation_queue *)malloc(sizeof(struct operation_queue));
if (!op) {
- _E("malloc failed");
+ _E("Failed to malloc.");
return -ENOMEM;
}
op->op = operation;
op->data = data;
- op->reply_handle = reply_handle;
+ op->invocation = invocation;
+
+ /* Need to disble app2ext whenever unmounting mmc */
+ /* app2ext_disable_all_external_pkgs inside a critical section need to be avoided. */
+ if (operation == BLOCK_DEV_UNMOUNT &&
+ bdev->data->state == BLOCK_MOUNT &&
+ bdev->data->block_type == BLOCK_MMC_DEV &&
+ bdev->data->primary)
+ if (app2ext_disable_all_external_pkgs() < 0)
+ _E("Failed to app2ext_disable_all_external_pkgs().");
/* LOCK
* during adding queue and checking the queue length */
op->done = false;
start_th = th_manager[thread_id].start_th;
- DD_LIST_APPEND(bdev->op_queue, op);
+ SYS_G_LIST_APPEND(bdev->op_queue, op);
th_manager[thread_id].op_len++;
- if (th_manager[thread_id].op_len == 1 && !start_th)
+ 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 */
- /* Need to disble app2ext whenever unmounting mmc */
- if (op->op == BLOCK_DEV_UNMOUNT &&
- bdev->data->state == BLOCK_MOUNT &&
- bdev->data->block_type == BLOCK_MMC_DEV &&
- bdev->data->primary)
- if (app2ext_disable_all_external_pkgs() < 0)
- _E("app2ext_disable_all_external_pkgs() failed");
-
-
- 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);
+ if (!start_th) {
+ _D("Start new thread for block device.");
+ th_manager[thread_id].start_th = true;
+ ret_val = pthread_create(&(th_manager[thread_id].th), NULL, block_th_start, &th_manager[thread_id]);
+ if (ret_val != 0) {
+ _E("Failed to create thread for %s.", bdev->data->devnode);
return -EPERM;
}
dp = opendir(syspath);
if (!dp) {
- _E("fail to open %s", syspath);
+ _E("Failed to open '%s'.", syspath);
goto out;
}
fs_usage = udev_device_get_property_value(dev,
"ID_FS_USAGE");
if (fs_usage &&
- strncmp(fs_usage, FILESYSTEM, sizeof(FILESYSTEM)) == 0) {
+ strncmp(fs_usage, FILESYSTEM_NAME, sizeof(FILESYSTEM_NAME)) == 0) {
if (!disk_is_partitioned_by_kernel(dev))
goto out;
}
partition = check_partition(dev);
if (partition) {
/* if there is a partition, skip this request */
- _I("%s device has partitions, skip this time", devnode);
+ _I("%s device has partitions, skip this time.", devnode);
return 0;
}
if (mapper && !udev_device_get_property_value(dev, "ID_FS_TYPE")) {
+ char syspath[128] = {0};
+ char *r;
+
+ r = rindex(udev_device_get_syspath(dev), '/');
+ if (!r) return -ENODEV;
+
+ snprintf(syspath, sizeof(syspath), "/sys/block%s", r);
+
data = make_block_data(devnode,
- udev_device_get_syspath(dev),
- FILESYSTEM,
+ syspath,
+ FILESYSTEM_NAME,
EXT4_NAME,
"1.0",
udev_device_get_property_value(dev, "ID_FS_UUID_ENC"),
}
if (!data) {
- _E("fail to make block data for %s", devnode);
+ _E("Failed to make block data for %s.", devnode);
return -EPERM;
}
if (!block_conf[data->block_type].multimount && !data->primary &&
- data->fs_usage && !strcmp(data->fs_usage, FILESYSTEM)) {
- _D("Not support multi mount by config info");
+ data->fs_usage && !strcmp(data->fs_usage, FILESYSTEM_NAME)) {
+ _D("Not support multi mount by config info.");
free_block_data(data);
return -EPERM;
}
+ if (!block_control) {
+ if (!mapper && strncmp(data->fs_type, LUKS_NAME, strlen(LUKS_NAME))) {
+ _D("Block module is disabled.");
+ free_block_data(data);
+ return -EPERM;
+ }
+
+ }
+
bdev = make_block_device(data);
if (!bdev) {
- _E("fail to make block device for %s", devnode);
+ _E("Failed 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");
+ _E("Failed to find thread to add.");
free_block_device(bdev);
return -EPERM;
}
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);
+ SYS_G_LIST_APPEND(th_manager[thread_id].block_dev_list, bdev);
pthread_mutex_unlock(&(th_manager[thread_id].mutex));
if (need_format) {
- ret = block_format(bdev->data, EXT4_NAME, false, false);
+ struct format_data *fdata;
+
+ fdata = get_format_data(NULL, UNMOUNT_FORCE);
+ if (!fdata) {
+ _E("Failed to get format data.");
+ return -ENOMEM;
+ }
+
+ ret = add_operation(bdev, BLOCK_DEV_FORMAT, NULL, (void *)fdata);
if (ret < 0) {
- _E("Failed to add operation (format %s)", bdev->data->devnode);
+ _E("Failed to add operation(format, %s).", bdev->data->devnode);
+ release_format_data(fdata);
}
}
if (!bdev->data->fs_type) {
- _E("Unformatted Storage");
+ _E("Unformatted Storage.");
free_block_device(bdev);
return -EPERM;
} else if (!strncmp(bdev->data->fs_type, LUKS_NAME, strlen(LUKS_NAME))) {
- bdev->data->block_type = BLOCK_EXTENDEDSD_DEV;
- ret = change_mount_point(bdev, EXTENDED_SD_PATH);
+// bdev->data->block_type = BLOCK_EXTENDEDSD_DEV;
+ bdev->data->primary = true;
+ _D("Need to unlock encrypted sdcard.");
+ // ---- ODE UI launch ----
+ ret = launch_system_app(POPUP_DEFAULT
+ , 8
+ , POPUP_KEY_CONTENT
+ , "unlockextendedsd"
+ , VIEWTYPE_KEY
+ , INSERT_SD_CARD
+ , DEVPATH_KEY
+ , bdev->data->devnode
+ , MAPPING_NODE_KEY
+ , EXTENDEDSD_NAME);
+ if (ret < 0)
+ _E("Failed to launch popup.");
+
+ ret = add_operation(bdev, BLOCK_DEV_INSERT, NULL, (void *)data);
if (ret < 0) {
- ret = -EPERM;
+ _E("Failed to add operation(insert, %s).", devnode);
free_block_device(bdev);
return ret;
}
- /* ---- ODE UI launch ----
- snprintf(id_string, PATH_LEN, "%d", bdev->data->id);
- ret = launch_system_app(POPUP_DEFAULT, 4, POPUP_KEY_CONTENT, "sdcardsetup", POPUP_SDCARD_ID, id_string);
- if (ret < 0)
- _E("Failed to launch popup");
-
- ode_luks_set_event_cb(CALLBACK)
- */
-
return 0;
- } else if (!strncmp(bdev->data->fs_type, EXT4_NAME, strlen(EXT4_NAME))) {
+ } else if (mapper && !strncmp(bdev->data->fs_type, EXT4_NAME, strlen(EXT4_NAME))) {
bdev->data->block_type = BLOCK_EXTENDEDSD_DEV;
- ret = change_mount_point(bdev, EXTENDED_SD_PATH);
+ ret = change_mount_point(bdev, EXTENDEDSD_MOUNT_PATH);
if (ret < 0) {
ret = -EPERM;
free_block_device(bdev);
ret = add_operation(bdev, BLOCK_DEV_INSERT, NULL, (void *)data);
if (ret < 0) {
- _E("Failed to add operation (insert %s)", devnode);
+ _E("Failed to add operation(insert, %s).", devnode);
free_block_device(bdev);
return ret;
}
// Not a regular filesystem -> skip mounting
- if (!bdev->data->fs_usage || strcmp(bdev->data->fs_usage, FILESYSTEM)) {
- _I("Not a filesystem. Not mounting");
+ if (!bdev->data->fs_usage || strcmp(bdev->data->fs_usage, FILESYSTEM_NAME)) {
+ _I("Not a filesystem. Not mounting.");
return 0;
}
- /* Create file for block device /run/external-storage/id */
- create_file(bdev->data->id, bdev->data->mount_point, bdev->data->block_type == BLOCK_EXTENDEDSD_DEV);
ret = add_operation(bdev, BLOCK_DEV_MOUNT, NULL, NULL);
if (ret < 0) {
- _E("Failed to add operation (mount %s)", devnode);
+ _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;
+ struct block_device *bdev_extended;
int ret;
bdev = find_block_device(devnode);
if (!bdev) {
- _E("fail to find block data for %s", devnode);
+ _E("Failed to find block data for %s.", devnode);
return -ENODEV;
}
bdev->removed = true;
if (bdev->on_private_op != REQ_NORMAL) {
bdev->on_private_op = REQ_NORMAL;
- _D("Private operation state: %d", bdev->on_private_op);
+ _D("Private operation state(%d).", bdev->on_private_op);
+ }
+
+ if (!strncmp(bdev->data->fs_type, LUKS_NAME, strlen(LUKS_NAME))) {
+ bdev_extended = find_block_device_path(EXTENDEDSD_MOUNT_PATH);
+
+ if (bdev_extended) {
+ BLOCK_FLAG_SET(bdev_extended->data, UNMOUNT_UNSAFE);
+
+ bdev_extended->removed = true;
+ if (bdev_extended->on_private_op != REQ_NORMAL) {
+ bdev_extended->on_private_op = REQ_NORMAL;
+ _D("Private operation state(%d).", bdev_extended->on_private_op);
+ }
+
+ ret = add_operation(bdev_extended, BLOCK_DEV_UNMOUNT, NULL, (void *)UNMOUNT_FORCE);
+ if (ret < 0) {
+ _E("Failed to add operation(unmount, %s).", devnode);
+ return ret;
+ }
+
+ ret = add_operation(bdev_extended, BLOCK_LUKS_CLOSE, NULL, NULL);
+ if (ret < 0) {
+ _E("Failed to add operation(luks_close, %s).", devnode);
+ return ret;
+ }
+
+ ret = add_operation(bdev_extended, BLOCK_DEV_REMOVE, NULL, NULL);
+ if (ret < 0) {
+ _E("Failed to add operation(remove, %s).", devnode);
+ return ret;
+ }
+ } else
+ _E("Failed to find block data for extended sd card.");
}
ret = add_operation(bdev, BLOCK_DEV_UNMOUNT, NULL, (void *)UNMOUNT_FORCE);
if (ret < 0) {
- _E("Failed to add operation (unmount %s)", devnode);
+ _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);
+ _E("Failed to add operation(remove, %s).", devnode);
return ret;
}
return -EPERM;
}
temp = mnt_fs_get_srcpath(fs);
- if (!temp)
+ if (!temp) {
+ mnt_free_table(t);
return -EPERM;
+ }
name = strrchr(temp, '/');
- if (!name)
+ if (!name) {
+ mnt_free_table(t);
return -EPERM;
+ }
name++;
+
/* Boot from USB is not handled */
if (!is_emulator()) {
if (!fnmatch(MMC_PATH, temp, 0))
if (!fnmatch(MMC_PATH, devnode, 0)) {
sscanf(name, "mmcblk%d", &dev_num);
if (dev_internal == dev_num) {
- _D("%s is internal storage", devnode);
+ _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);
+ _D("%s is internal storage.", devnode);
return 0;
}
}
if (!fnmatch(MMC_LINK_PATH, devnode, 0)) {
sscanf(name, "vd%c%d", &emul, &dev_temp);
if (dev_internal_emul == emul) {
- _D("%s is internal storage", devnode);
+ _D("%s is internal storage.", devnode);
return 0;
}
}
{
struct block_device *bdev;
struct block_data *data;
- dd_list *elem;
+ GList *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) {
+ SYS_G_LIST_FOREACH(th_manager[i].block_dev_list, elem, bdev) {
data = bdev->data;
if (!data)
continue;
udev = udev_new();
if (!udev) {
- _E("fail to create udev library context");
+ _E("Failed 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");
+ _E("Failed to create an enumeration context.");
return -EPERM;
}
- if ((dev_internal < 0 && !is_emulator() && dev_internal_scsi == '\0') ||
- (is_emulator() && dev_internal_emul == '\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);
if (!devnode) {
devnode = udev_device_get_devnode(dev);
- if (!devnode)
+ if (!devnode) {
+ udev_device_unref(dev);
continue;
+ }
if (fnmatch(MMC_PATH, devnode, 0) &&
fnmatch(SCSI_PATH, devnode, 0) &&
- fnmatch(EXTENDEDSD_PATH, devnode, 0))
+ fnmatch(EXTENDEDSD_NODE_PATH, devnode, 0)) {
+ udev_device_unref(dev);
continue;
+ }
}
r = check_external_storage(devnode);
- if (r <= 0)
+ if (r <= 0) {
+ udev_device_unref(dev);
continue;
+ }
r = check_already_handled(devnode);
if (r < 0) {
- _I("%s is already handled", devnode);
+ _I("%s is already handled.", devnode);
+ udev_device_unref(dev);
continue;
}
- _I("%s device add", devnode);
+ _I("%s device add.", devnode);
add_block_device(dev, devnode, false);
udev_device_unref(dev);
{
struct block_device *bdev;
struct block_data *data;
- dd_list *elem;
+ GList *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) {
+ SYS_G_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: %d", data->block_type);
- _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",
+ _D("\tSyspath=%s", data->syspath);
+ _D("\tBlock type=%d", data->block_type);
+ _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",
+ _D("\tMount point=%s", data->mount_point);
+ _D("\tMount state=%s",
(data->state == BLOCK_MOUNT ?
"mount" : "unmount"));
- _D("\tPrimary: %s",
+ _D("\tPrimary=%s",
(data->primary ? "true" : "false"));
- _D("\tID: %d", data->id);
+ _D("\tID=%d", data->id);
}
pthread_mutex_unlock(&(th_manager[i].mutex));
}
static void remove_whole_block_device(void)
{
struct block_device *bdev;
- dd_list *elem;
- dd_list *next;
+ GList *elem;
+ GList *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) {
+ SYS_G_LIST_FOREACH_SAFE(th_manager[i].block_dev_list, elem, next, bdev) {
+ if (bdev->data->block_type == BLOCK_EXTENDEDSD_DEV ||
+ !strncmp(bdev->data->fs_type, LUKS_NAME, strlen(LUKS_NAME)))
+ continue;
if (bdev->removed == false)
break;
}
if (bdev && bdev->removed == false) {
bdev->removed = true;
- r = add_operation(bdev, BLOCK_DEV_UNMOUNT, NULL, (void *)UNMOUNT_NORMAL);
+ r = add_operation(bdev, BLOCK_DEV_UNMOUNT, NULL, (void *)UNMOUNT_FORCE);
if (r < 0)
- _E("Failed to add operation (unmount %s)", bdev->data->devnode);
+ _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);
+ _E("Failed to add operation(remove, %s).", bdev->data->devnode);
} else
break;
} while (true);
}
}
-static void booting_done(const char *sender_name,
- const char *object_path, const char *interface_name,
- const char *signal_name, DBusMessage *msg,
- void *data)
+static void add_poweroff_wait_cb(GVariant *var, void *user_data, GError *err)
+{
+ int ret_val = -ENOMSG;
+
+ if (!var)
+ return ;
+
+ if (!g_variant_get_safe(var, "(i)", &ret_val))
+ _E("Failed to get(%s): no message", g_variant_get_type_string(var));
+
+ if (ret_val >= 0)
+ add_poweroff_wait = true;
+
+ g_variant_unref(var);
+}
+
+static void booting_done(void)
{
static int done = 0;
+ int ret_val;
+
if (done > 0)
return;
done = 1;
- _I("Booting done");
+ _I("Booting done.");
+
+ /* register mmc uevent control routine */
+ ret_val = register_udev_uevent_control(&uh);
+ if (ret_val < 0)
+ _E("Failed to register block uevent: %d", ret_val);
+
+ block_control = true;
/* if there is the attached device, try to mount */
block_init_from_udev_enumerate();
- block_control = true;
+
+ ret_val = gdbus_call_async_with_reply(DEVICED_BUS_NAME,
+ DEVICED_PATH_POWEROFF,
+ DEVICED_INTERFACE_POWEROFF,
+ METHOD_ADD_POWEROFF_WAIT,
+ NULL,
+ add_poweroff_wait_cb,
+ -1, NULL);
+ if (ret_val < 0)
+ _E("Failed to call "METHOD_ADD_POWEROFF_WAIT" method.");
+
block_boot = true;
}
-static void block_poweroff(const char *sender_name,
- const char *object_path, const char *interface_name,
- const char *signal_name, DBusMessage *msg,
- void *data)
+static void block_poweroff(GDBusConnection *conn,
+ const gchar *sender,
+ const gchar *path,
+ const gchar *iface,
+ const gchar *name,
+ GVariant *param,
+ gpointer data)
{
static int status = 0;
+ int ret_dbus;
+
if (status > 0)
return;
status = 1;
- _I("Power off");
+ _I("Power off.");
/* unregister mmc uevent control routine */
unregister_udev_uevent_control(&uh);
remove_whole_block_device();
+ terminate_threads();
+
+ if (add_poweroff_wait) {
+ ret_dbus = gdbus_call_sync_with_reply_int(DEVICED_BUS_NAME,
+ DEVICED_PATH_POWEROFF,
+ DEVICED_INTERFACE_POWEROFF,
+ METHOD_REMOVE_POWEROFF_WAIT,
+ NULL, NULL);
+ if (ret_dbus < 0)
+ _E("Failed to call "METHOD_REMOVE_POWEROFF_WAIT" method.");
+ else
+ add_poweroff_wait = false;
+ }
}
static void uevent_block_handler(struct udev_device *dev)
devnode = devlink;
break;
}
- if (!fnmatch(EXTENDEDSD_PATH, devlink, 0)) {
+ if (!fnmatch(EXTENDEDSD_NODE_PATH, devlink, 0)) {
mapper = true;
devnode = devlink;
break;
if (!action)
return;
- _I("%s device %s", devnode, action);
+ _I("%s device %s.", devnode, action);
if (!strncmp(action, UDEV_ADD, sizeof(UDEV_ADD)) ||
(mapper && !strcmp(action, UDEV_CHANGE))) {
r = check_already_handled(devnode);
if (r < 0) {
- _I("%s is already handled", devnode);
+ _I("%s is already handled.", devnode);
return;
}
add_block_device(dev, devnode, mapper);
} else if (!strncmp(action, UDEV_REMOVE, sizeof(UDEV_REMOVE))) {
remove_block_device(dev, devnode);
+ } else if (!strncmp(action, UDEV_CHANGE, sizeof(UDEV_CHANGE))) {
+ struct block_device *bdev;
+ bdev = find_block_device(devnode);
+ if (!bdev) {
+ _E("Failed to find block data for %s.", devnode);
+ return;
+ }
+ if (!udev_device_get_property_value(dev, "ID_FS_TYPE"))
+ return;
+
+ r = update_block_data(bdev->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"),
+ false);
+ if (r < 0)
+ _E("Failed to update block data for %s.", bdev->data->devnode);
+ if (!strncmp(bdev->data->fs_type, LUKS_NAME, strlen(LUKS_NAME)))
+ _I("Filesystem type(crypto_LUKS) is updated.");
+ if (bdev->data->fs_usage)
+ _I("fs_usage=%s", bdev->data->fs_usage);
}
}
-static DBusMessage *request_mount_block(dbus_method_reply_handle_h reply_handle,
- DBusMessage *msg, bool onprivate)
+static GVariant *request_mount_block(GDBusConnection *conn,
+ const gchar *sender, const gchar *path, const gchar *iface, const gchar *name,
+ GVariant *param, GDBusMethodInvocation *invocation, gpointer user_data, bool onprivate)
{
struct block_device *bdev;
- char *mount_point;
+ char *mount_point = NULL;
int id;
int ret = -EBADMSG;
- if (!reply_handle || !msg)
+ if (!block_control) {
+ _D("Block module is disabled.");
+ ret = -EPERM;
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;
+ g_variant_get(param, "(is)", &id, &mount_point);
bdev = find_block_device_by_id(id);
if (!bdev) {
- _E("Failed to find (%d) in the device list", id);
+ _E("Failed to find (%d) in the device list.", id);
ret = -ENOENT;
goto out;
}
+
+ if (bdev->data->block_type == BLOCK_EXTENDEDSD_DEV ||
+ !strncmp(bdev->data->fs_type, LUKS_NAME, strlen(LUKS_NAME))) {
+ _D("Mount dbus request for extended internal storage is blocked.");
+ ret = -EPERM;
+ goto out;
+ }
+
if (bdev->on_private_op != REQ_NORMAL) {
ret = -EPERM;
goto out;
}
if (bdev->data->state == BLOCK_MOUNT) {
- _I("%s is already mounted", bdev->data->devnode);
+ _I("%s is already mounted.", bdev->data->devnode);
ret = -EALREADY;
goto out;
}
if (onprivate) {
bdev->on_private_op = REQ_PRIVATE;
- bdev->private_pid = get_dbus_method_sender_pid(reply_handle);
- _D("Private operation state: %d", bdev->on_private_op);
- } else {
- if (bdev->on_private_op != REQ_NORMAL) {
- _E("Failed to process mount operation");
- ret = -EPERM;
- goto out;
- }
+ bdev->private_pid = gdbus_connection_get_sender_pid(NULL, sender);
+ _D("Private operation state(%d). pid=%d.", bdev->on_private_op, bdev->private_pid);
}
/* if requester want to use a specific mount point */
- if (mount_point &&
- !strncmp(mount_point, EXTENDED_SD_STRING, strlen(EXTENDED_SD_STRING) + 1) != 0) {
- if (!block_conf[bdev->data->block_type].extendedinternal ||
- !bdev->data->primary) {
- _E("Not support extended internal storage");
- ret = -EPERM;
- goto out;
- } else {
- bdev->data->block_type = BLOCK_EXTENDEDSD_DEV;
- ret = change_mount_point(bdev, EXTENDED_SD_PATH);
- if (ret < 0) {
- ret = -EPERM;
- goto out;
- }
-
- create_file(bdev->data->id, bdev->data->mount_point, true);
- }
- } else if (mount_point && strncmp(mount_point, "", 1) != 0) {
+ if (mount_point && strncmp(mount_point, "", 1) != 0) {
ret = change_mount_point(bdev, mount_point);
if (ret < 0) {
ret = -EPERM;
goto out;
}
-
- /* Create /run/external-storage/id file */
- create_file(bdev->data->id, bdev->data->mount_point, false);
- } else {
- /* Create file for block device /run/external-storage/id */
- create_file(bdev->data->id, bdev->data->mount_point, false);
}
- ret = add_operation(bdev, BLOCK_DEV_MOUNT, reply_handle, NULL);
+ ret = add_operation(bdev, BLOCK_DEV_MOUNT, invocation, NULL);
if (ret < 0) {
- _E("Failed to add operation (mount %s)", bdev->data->devnode);
+ _E("Failed to add operation(mount, %s).", bdev->data->devnode);
goto out;
}
+ g_free(mount_point);
return NULL;
out:
- return make_dbus_reply_message_simple(reply_handle, ret);
+ g_free(mount_point);
+ return g_variant_new("(i)", ret);
}
-static DBusMessage *request_public_mount_block(dbus_method_reply_handle_h reply_handle,
- DBusMessage *msg)
+static GVariant *request_public_mount_block(GDBusConnection *conn,
+ const gchar *sender, const gchar *path, const gchar *iface, const gchar *name,
+ GVariant *param, GDBusMethodInvocation *invocation, gpointer user_data)
{
- return request_mount_block(reply_handle, msg, false);
+ return request_mount_block(conn, sender, path, iface, name, param, invocation, user_data, false);
}
-static DBusMessage *request_private_mount_block(dbus_method_reply_handle_h reply_handle,
- DBusMessage *msg)
+static GVariant *request_private_mount_block(GDBusConnection *conn,
+ const gchar *sender, const gchar *path, const gchar *iface, const gchar *name,
+ GVariant *param, GDBusMethodInvocation *invocation, gpointer user_data)
{
- return request_mount_block(reply_handle, msg, true);
+ return request_mount_block(conn, sender, path, iface, name, param, invocation, user_data, true);
}
-static DBusMessage *request_unmount_block(dbus_method_reply_handle_h reply_handle,
- DBusMessage *msg, bool onprivate)
+static GVariant *request_unmount_block(GDBusConnection *conn,
+ const gchar *sender, const gchar *path, const gchar *iface, const gchar *name,
+ GVariant *param, GDBusMethodInvocation *invocation, gpointer user_data, bool onprivate)
{
struct block_device *bdev;
pid_t pid;
int id;
int ret = -EBADMSG;
- if (!reply_handle || !msg)
+ if (!block_control) {
+ _D("Block module is disabled.");
+ ret = -EPERM;
goto out;
+ }
- ret = dbus_message_get_args(msg, NULL,
- DBUS_TYPE_INT32, &id,
- DBUS_TYPE_INT32, &option,
- DBUS_TYPE_INVALID);
- if (!ret)
- goto out;
+ g_variant_get(param, "(ii)", &id, &option);
bdev = find_block_device_by_id(id);
if (!bdev) {
- _E("Failed to find (%d) in the device list", id);
+ _E("Failed to find (%d) in the device list.", id);
ret = -ENOENT;
goto out;
}
- if (bdev->data->block_type == BLOCK_EXTENDEDSD_DEV) {
- _I("Impossible to request unmount extended internal sdcard");
+ /* Unmount dbus call is needed when app proceeds extended internal -> portable storage */
+ if (!strncmp(bdev->data->fs_type, LUKS_NAME, strlen(LUKS_NAME))) {
+ _D("Unmount dbus request for extended internal storage is blocked.");
ret = -EPERM;
goto out;
}
if (onprivate) {
- pid = get_dbus_method_sender_pid(reply_handle);
+ pid = gdbus_connection_get_sender_pid(NULL, sender);
if (bdev->on_private_op == REQ_NORMAL || (bdev->on_private_op != REQ_NORMAL && pid != bdev->private_pid)) {
- _E("Failed to process private unmount operation");
+ _E("Failed to process private unmount operation pid=%d private_pid=%d.", pid, bdev->private_pid);
ret = -EPERM;
goto out;
}
} else {
if (bdev->on_private_op != REQ_NORMAL) {
- _E("Failed to process unmount operation");
+ _E("Failed to process unmount operation.");
ret = -EPERM;
goto out;
}
}
- ret = add_operation(bdev, BLOCK_DEV_UNMOUNT, reply_handle, (void *)option);
+ ret = add_operation(bdev, BLOCK_DEV_UNMOUNT, invocation, (void *)option);
if (ret < 0) {
- _E("Failed to add operation (unmount %s)", bdev->data->devnode);
+ _E("Failed to add operation(unmount, %s).", bdev->data->devnode);
goto out;
}
+ if (bdev->data->block_type == BLOCK_EXTENDEDSD_DEV) {
+ ret = add_operation(bdev, BLOCK_LUKS_CLOSE, NULL, NULL);
+ if (ret < 0)
+ _E("Failed to add operation(luks_close, %s).", bdev->data->devnode);
+ }
+
return NULL;
out:
- return make_dbus_reply_message_simple(reply_handle, ret);
+ return g_variant_new("(i)", ret);
}
-static DBusMessage *request_public_unmount_block(dbus_method_reply_handle_h reply_handle,
- DBusMessage *msg)
+static GVariant *request_public_unmount_block(GDBusConnection *conn,
+ const gchar *sender, const gchar *path, const gchar *iface, const gchar *name,
+ GVariant *param, GDBusMethodInvocation *invocation, gpointer user_data)
{
- return request_unmount_block(reply_handle, msg, false);
+ return request_unmount_block(conn, sender, path, iface, name, param, invocation, user_data, false);
}
-static DBusMessage *request_private_unmount_block(dbus_method_reply_handle_h reply_handle,
- DBusMessage *msg)
+static GVariant *request_private_unmount_block(GDBusConnection *conn,
+ const gchar *sender, const gchar *path, const gchar *iface, const gchar *name,
+ GVariant *param, GDBusMethodInvocation *invocation, gpointer user_data)
{
- return request_unmount_block(reply_handle, msg, true);
+ return request_unmount_block(conn, sender, path, iface, name, param, invocation, user_data, true);
}
-static DBusMessage *request_format_block(dbus_method_reply_handle_h reply_handle,
- DBusMessage *msg)
+static GVariant *request_format_block(GDBusConnection *conn,
+ const gchar *sender, const gchar *path, const gchar *iface, const gchar *name,
+ GVariant *param, GDBusMethodInvocation *invocation, gpointer user_data)
{
struct block_device *bdev;
struct format_data *fdata;
int ret = -EBADMSG;
int prev_state;
- if (!reply_handle || !msg)
+ if (!block_control) {
+ _D("Block module is disabled.");
+ ret = -EPERM;
goto out;
+ }
- ret = dbus_message_get_args(msg, NULL,
- DBUS_TYPE_INT32, &id,
- DBUS_TYPE_INT32, &option,
- DBUS_TYPE_INVALID);
- if (!ret)
- goto out;
+ g_variant_get(param, "(ii)", &id, &option);
bdev = find_block_device_by_id(id);
if (!bdev) {
- _E("Failed to find (%d) in the device list", id);
+ _E("Failed to find (%d) in the device list.", id);
goto out;
}
- pid = get_dbus_method_sender_pid(reply_handle);
+ if (bdev->data->block_type == BLOCK_EXTENDEDSD_DEV ||
+ !strncmp(bdev->data->fs_type, LUKS_NAME, strlen(LUKS_NAME))) {
+ _D("Format dbus request for extended internal storage is blocked.");
+ ret = -EPERM;
+ goto out;
+ }
+
+ pid = gdbus_connection_get_sender_pid(NULL, sender);
if (bdev->on_private_op != REQ_NORMAL && pid != bdev->private_pid) {
- _E("Failed to format on private state");
+ _E("Failed to format on private state.");
ret = -EPERM;
goto out;
}
fdata = get_format_data(NULL, option);
if (!fdata) {
- _E("Failed to get format data");
+ _E("Failed to get format data.");
goto out;
}
if (prev_state == BLOCK_MOUNT) {
if (bdev->on_private_op == REQ_PRIVATE) {
bdev->on_private_op = REQ_PRIVATE_FORMAT;
- _D("Private operation state: %d", bdev->on_private_op);
+ _D("Private operation state(%d)", bdev->on_private_op);
}
ret = add_operation(bdev, BLOCK_DEV_UNMOUNT, NULL, (void *)UNMOUNT_FORCE);
if (ret < 0) {
- _E("Failed to add operation (unmount %s)", bdev->data->devnode);
+ _E("Failed to add operation(unmount, %s).", bdev->data->devnode);
release_format_data(fdata);
goto out;
}
}
- ret = add_operation(bdev, BLOCK_DEV_FORMAT, reply_handle, (void *)fdata);
+ ret = add_operation(bdev, BLOCK_DEV_FORMAT, invocation, (void *)fdata);
if (ret < 0) {
- _E("Failed to add operation (format %s)", bdev->data->devnode);
+ _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);
+ _E("Failed to add operation(mount, %s).", bdev->data->devnode);
goto out;
}
}
return NULL;
out:
- return make_dbus_reply_message_simple(reply_handle, ret);
+ return g_variant_new("(i)", ret);
}
-static DBusMessage *request_format_block_type(dbus_method_reply_handle_h reply_handle,
- DBusMessage *msg)
+static GVariant *request_format_block_type(GDBusConnection *conn,
+ const gchar *sender, const gchar *path, const gchar *iface, const gchar *name,
+ GVariant *param, GDBusMethodInvocation *invocation, gpointer user_data)
{
struct block_device *bdev;
struct format_data *fdata;
- char *type;
+ char *type = NULL;
pid_t pid;
int id;
int option;
int ret = -EBADMSG;
int prev_state;
- if (!reply_handle || !msg)
+ if (!block_control) {
+ _D("Block module is disabled.");
+ ret = -EPERM;
goto out;
+ }
- ret = dbus_message_get_args(msg, NULL,
- DBUS_TYPE_INT32, &id,
- DBUS_TYPE_INT32, &option,
- DBUS_TYPE_STRING, &type,
- DBUS_TYPE_INVALID);
- if (!ret)
- goto out;
+ g_variant_get(param, "(iis)", &id, &option, &type);
bdev = find_block_device_by_id(id);
if (!bdev) {
- _E("Failed to find (%d) in the device list", id);
+ _E("Failed to find (%d) in the device list.", id);
+ goto out;
+ }
+
+ /* FormatwithType dbus call is needed when app proceeds extended internal -> portable storage */
+ if (bdev->data->block_type == BLOCK_EXTENDEDSD_DEV) {
+ _D("FormatwithType dbus request for extended internal storage is blocked.");
+ ret = -EPERM;
goto out;
}
- pid = get_dbus_method_sender_pid(reply_handle);
+ pid = gdbus_connection_get_sender_pid(NULL, sender);
if (bdev->on_private_op != REQ_NORMAL && pid != bdev->private_pid) {
- _E("Failed to format on private state");
+ _E("Failed to format on private state.");
ret = -EPERM;
goto out;
}
fdata = get_format_data(type, option);
if (!fdata) {
- _E("Failed to get format data");
+ _E("Failed to get format data.");
goto out;
}
if (prev_state == BLOCK_MOUNT) {
if (bdev->on_private_op == REQ_PRIVATE) {
bdev->on_private_op = REQ_PRIVATE_FORMAT;
- _D("Private operation state: %d", bdev->on_private_op);
+ _D("Private operation state(%d).", bdev->on_private_op);
}
ret = add_operation(bdev, BLOCK_DEV_UNMOUNT, NULL, (void *)UNMOUNT_FORCE);
if (ret < 0) {
- _E("Failed to add operation (unmount %s)", bdev->data->devnode);
+ _E("Failed to add operation(unmount, %s).", bdev->data->devnode);
release_format_data(fdata);
goto out;
}
}
- ret = add_operation(bdev, BLOCK_DEV_FORMAT, reply_handle, (void *)fdata);
+ ret = add_operation(bdev, BLOCK_DEV_FORMAT, invocation, (void *)fdata);
if (ret < 0) {
- _E("Failed to add operation (format %s)", bdev->data->devnode);
+ _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);
+ _E("Failed to add operation(mount, %s).", bdev->data->devnode);
goto out;
}
}
+ g_free(type);
return NULL;
out:
- return make_dbus_reply_message_simple(reply_handle, ret);
+ g_free(type);
+ return g_variant_new("(i)", ret);
}
-static int add_device_to_iter(struct block_data *data, DBusMessageIter *piter)
+static GVariant *block_data_to_gvariant(struct block_data *data, int flags)
{
- 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(dbus_method_reply_handle_h reply_handle,
- DBusMessage *msg)
-{
- DBusMessageIter iter;
- DBusMessage *reply;
- struct block_device *bdev;
- struct block_data *data;
- int ret, id;
-
- if (!reply_handle || !msg)
- return NULL;
-
- reply = make_dbus_reply_message(reply_handle);
- if (!reply)
- goto out;
+ if (!data)
+ return gdbus_new_g_variant_tuple();
+
+ return g_variant_new("(issssssisibii)",
+ data->block_type,
+ nullstr(data->devnode),
+ nullstr(data->syspath),
+ nullstr(data->fs_usage),
+ nullstr(data->fs_type),
+ nullstr(data->fs_version),
+ nullstr(data->fs_uuid_enc),
+ data->readonly,
+ nullstr(data->mount_point),
+ data->state,
+ data->primary,
+ flags >= 0 ? flags : data->flags,
+ data->id);
+}
+
+//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 GVariant *request_get_device_info(GDBusConnection *conn,
+ const gchar *sender, const gchar *path, const gchar *iface, const gchar *name,
+ GVariant *param, GDBusMethodInvocation *invocation, gpointer user_data)
+{
+ struct block_device *bdev = NULL;
+ struct block_data *data = NULL;
+ struct block_data nodata = {0,};
+ int id;
- ret = dbus_message_get_args(msg, NULL,
- DBUS_TYPE_INT32, &id,
- DBUS_TYPE_INVALID);
- if (!ret)
- goto out;
+ g_variant_get(param, "(i)", &id);
bdev = find_block_device_by_id(id);
if (!bdev)
if (!data)
goto out;
- dbus_message_iter_init_append(reply, &iter);
- add_device_to_iter(data, &iter);
-
out:
- return reply;
+ if (!data) {
+ nodata.id = -ENODEV;
+ data = &nodata;
+ }
+
+ return block_data_to_gvariant(data, -1);
}
-static DBusMessage *request_show_device_list(dbus_method_reply_handle_h reply_handle,
- DBusMessage *msg)
+static GVariant *request_show_device_list(GDBusConnection *conn,
+ const gchar *sender, const gchar *path, const gchar *iface, const gchar *name,
+ GVariant *param, GDBusMethodInvocation *invocation, gpointer user_data)
{
show_block_device_list();
- return make_dbus_reply_message(reply_handle);
+ return gdbus_new_g_variant_tuple();
+}
+
+static enum block_device_type get_bdev_type_from_type_string(const char *type_str)
+{
+ if (!type_str)
+ return BLOCK_UNKNOWN_DEV;
+
+ if (strcmp(type_str, BLOCK_TYPE_SCSI) == 0)
+ return BLOCK_SCSI_DEV;
+ if (strcmp(type_str, BLOCK_TYPE_MMC) == 0)
+ return BLOCK_MMC_DEV;
+ if (strcmp(type_str, BLOCK_TYPE_ALL) == 0)
+ return BLOCK_ALL_DEV;
+
+ return BLOCK_UNKNOWN_DEV;
}
// Called by MainThread
-static DBusMessage *request_get_device_list(dbus_method_reply_handle_h reply_handle,
- DBusMessage *msg)
+static GVariant *request_get_device_list(GDBusConnection *conn,
+ const gchar *sender, const gchar *path, const gchar *iface, const gchar *name,
+ GVariant *param, GDBusMethodInvocation *invocation, gpointer user_data)
{
- DBusMessageIter iter;
- DBusMessageIter aiter;
- DBusMessage *reply;
+ GVariant *reply = NULL;
struct block_device *bdev;
struct block_data *data;
- dd_list *elem;
+ GList *elem;
char *type = NULL;
- int ret = -EBADMSG;
- int block_type;
+ enum block_device_type block_type;
int i;
+ GVariantBuilder *builder = NULL;
+ const char *error = NULL;
- reply = make_dbus_reply_message(reply_handle);
-
- 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;
- }
+ g_variant_get(param, "(s)", &type);
- _D("Block (%s) device list is requested", type);
+ _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);
+ block_type = get_bdev_type_from_type_string(type);
+ if (block_type == BLOCK_UNKNOWN_DEV) {
+ _E("Invalid type (%s) is requested.", type);
+ error = "Invalid type is requested";
goto out;
}
- dbus_message_iter_init_append(reply, &iter);
- dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "(issssssisibii)", &aiter);
+ builder = g_variant_builder_new(G_VARIANT_TYPE("a(issssssisibii)"));
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)
+ SYS_G_LIST_FOREACH(th_manager[i].block_dev_list, elem, bdev) {
+ if (!bdev->data || bdev->removed)
continue;
- switch (block_type) {
- case BLOCK_SCSI_DEV:
- case BLOCK_MMC_DEV:
+ data = bdev->data;
+
+ if (block_type != BLOCK_ALL_DEV) {
if (data->block_type != block_type)
continue;
- break;
- default:
- break;
}
- add_device_to_struct_iter(data, &aiter);
+
+ g_variant_builder_add(builder, "(issssssisibii)",
+ data->block_type,
+ nullstr(data->devnode),
+ nullstr(data->syspath),
+ nullstr(data->fs_usage),
+ nullstr(data->fs_type),
+ nullstr(data->fs_version),
+ nullstr(data->fs_uuid_enc),
+ data->readonly,
+ nullstr(data->mount_point),
+ data->state,
+ data->primary,
+ data->flags,
+ data->id);
}
pthread_mutex_unlock(&(th_manager[i].mutex));
}
- dbus_message_iter_close_container(&iter, &aiter);
+
+ reply = g_variant_new("(a(issssssisibii))", builder);
+
+ g_variant_builder_unref(builder);
out:
+ g_free(type);
+
+ if (!reply)
+ g_dbus_method_invocation_return_error(invocation,
+ G_DBUS_ERROR, G_DBUS_ERROR_FAILED,
+ "%s", error);
return reply;
}
// Called by MainThread
-static DBusMessage *request_get_device_list_2(dbus_method_reply_handle_h reply_handle,
- DBusMessage *msg)
+static GVariant *request_get_device_list_2(GDBusConnection *conn,
+ const gchar *sender, const gchar *path, const gchar *iface, const gchar *name,
+ GVariant *param, GDBusMethodInvocation *invocation, gpointer user_data)
{
- DBusMessageIter iter;
- DBusMessageIter aiter;
- DBusMessage *reply;
+ GVariant *reply = NULL;
struct block_device *bdev;
struct block_data *data;
- dd_list *elem;
+ GList *elem;
char *type = NULL;
- int ret = -EBADMSG;
- int block_type;
+ enum block_device_type block_type;
int i;
+ GVariantBuilder *builder = NULL;
+ const char *error = NULL;
- reply = make_dbus_reply_message(reply_handle);
-
- ret = dbus_message_get_args(msg, NULL,
- DBUS_TYPE_STRING, &type,
- DBUS_TYPE_INVALID);
- if (!ret) {
- _E("Failed to get args");
- goto out;
- }
-
+ g_variant_get(param, "(s)", &type);
if (!type) {
- _E("Delivered type is NULL");
+ _E("Delivered type is NULL.");
+ error = "Delivered type is NULL";
goto out;
}
- _D("Block (%s) device list is requested", type);
+ _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);
+ block_type = get_bdev_type_from_type_string(type);
+ if (block_type == BLOCK_UNKNOWN_DEV) {
+ _E("Invalid type (%s) is requested.", type);
+ error = "Invalid type is requested";
goto out;
}
- dbus_message_iter_init_append(reply, &iter);
- dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "(issssssisibi)", &aiter);
+ builder = g_variant_builder_new(G_VARIANT_TYPE("a(issssssisibi)"));
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)
+ SYS_G_LIST_FOREACH(th_manager[i].block_dev_list, elem, bdev) {
+ if (!bdev->data || bdev->removed)
continue;
- switch (block_type) {
- case BLOCK_SCSI_DEV:
- case BLOCK_MMC_DEV:
+ data = bdev->data;
+
+ if (block_type != BLOCK_ALL_DEV) {
if (data->block_type != block_type)
continue;
- break;
- default:
- break;
}
- add_device_to_iter_2(data, &aiter);
+ g_variant_builder_add(builder, "(issssssisibi)",
+ data->block_type,
+ nullstr(data->devnode),
+ nullstr(data->syspath),
+ nullstr(data->fs_usage),
+ nullstr(data->fs_type),
+ nullstr(data->fs_version),
+ nullstr(data->fs_uuid_enc),
+ data->readonly,
+ nullstr(data->mount_point),
+ data->state,
+ data->primary,
+ data->flags);
}
pthread_mutex_unlock(&(th_manager[i].mutex));
}
- dbus_message_iter_close_container(&iter, &aiter);
+
+ reply = g_variant_new("(a(issssssisibi))", builder);
+
+ g_variant_builder_unref(builder);
out:
+ g_free(type);
+
+ if (!reply)
+ g_dbus_method_invocation_return_error(invocation,
+ G_DBUS_ERROR, G_DBUS_ERROR_FAILED,
+ "%s", error);
return reply;
}
-static DBusMessage *request_get_mmc_primary(dbus_method_reply_handle_h reply_handle,
- DBusMessage *msg)
+static GVariant *request_get_mmc_primary(GDBusConnection *conn,
+ const gchar *sender, const gchar *path, const gchar *iface, const gchar *name,
+ GVariant *param, GDBusMethodInvocation *invocation, gpointer user_data)
{
- DBusMessageIter iter;
- DBusMessage *reply;
struct block_device *bdev;
- struct block_data *data, nodata = {0,};
- dd_list *elem;
- bool found;
+ struct block_data *data = NULL, nodata = {0,};
+ GList *elem;
+ bool found = false;
int i;
- if (!reply_handle || !msg)
- return NULL;
-
- reply = make_dbus_reply_message(reply_handle);
- 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) {
+ SYS_G_LIST_FOREACH(th_manager[i].block_dev_list, elem, bdev) {
data = bdev->data;
if (!data)
continue;
continue;
if (!data->primary)
continue;
+ // Return mapper node(/dev/mapper/extendedsd) for primary mmc (not /dev/mmcblk1p1(ex))
+ if (!strncmp(data->fs_type, LUKS_NAME, strlen(LUKS_NAME)))
+ continue;
found = true;
break;
}
break;
}
- dbus_message_iter_init_append(reply, &iter);
- if (found)
- add_device_to_iter(data, &iter);
- else {
+ if (!found) {
nodata.id = -ENODEV;
- add_device_to_iter(&nodata, &iter);
+ data = &nodata;
}
-out:
- return reply;
+ return block_data_to_gvariant(data, -1);
}
-static DBusMessage *request_check_speed(dbus_method_reply_handle_h reply_handle,
- DBusMessage *msg)
+static GVariant *request_check_speed(GDBusConnection *conn,
+ const gchar *sender, const gchar *path, const gchar *iface, const gchar *name,
+ GVariant *param, GDBusMethodInvocation *invocation, gpointer user_data)
{
struct timespec start_time, end_time;
- DBusMessageIter iter;
- DBusMessage *reply;
struct block_device *bdev;
struct block_data *data;
- char *buf;
- int ret = 0;
+ char *buf = NULL;
+ int ret_val;
+ int result = 0;
int id;
int fd;
+ int time_diff;
- if (!reply_handle || !msg)
- return NULL;
-
- ret = dbus_message_get_args(msg, NULL,
- DBUS_TYPE_INT32, &id,
- DBUS_TYPE_INVALID);
- if (!ret) {
- ret = -1;
- goto out;
- }
+ g_variant_get(param, "(i)", &id);
bdev = find_block_device_by_id(id);
if (!bdev) {
- ret = -1;
+ result = -1;
goto out;
}
data = bdev->data;
if (!data) {
- ret = -1;
+ result = -1;
goto out;
}
- _D("speed check: %s", data->devnode);
- fd = open(data->devnode, O_RDWR | O_SYNC);
- buf = calloc(1, SPEEDCHECK * 1024 * 1024);
- if (!buf) {
- _E("calloc() failed");
- close(fd);
- ret = -1;
+ _D("Speed check %s.", data->devnode);
+ fd = open(data->devnode, O_RDONLY | O_DIRECT);
+ if (fd < 0) {
+ _E("Failed to open fd(%s): %d", data->devnode, errno);
+ result = -1;
goto out;
}
+ ret_val = posix_memalign((void**)&buf, 4096, SPEEDCHECK_SIZE << 20);
+ if (ret_val) {
+ _E("Failed to posix_memalign().");
+ result = -1;
+ goto out_close;
+ }
+
clock_gettime(CLOCK_REALTIME, &start_time);
- _I("start time: %lu.%lu", start_time.tv_sec, start_time.tv_nsec);
- ret = write(fd, buf, SPEEDCHECK * 1024 * 1024);
+ _I("Start time=%lu.%lu", start_time.tv_sec, start_time.tv_nsec);
+ ret_val = read(fd, buf, SPEEDCHECK_SIZE << 20);
clock_gettime(CLOCK_REALTIME, &end_time);
- _I("end time %lu.%lu", end_time.tv_sec, end_time.tv_nsec);
+ _I("End time=%lu.%lu", end_time.tv_sec, end_time.tv_nsec);
free(buf);
- if (SPEEDCHECK / (end_time.tv_sec - start_time.tv_sec) < 4) {
- ret = -1;
- close(fd);
- goto out;
+ if (ret_val < 0) {
+ _E("Failed to read(): %d", errno);
+ result = -1;
+ goto out_close;
}
- if (ret < 0) {
- _E("write() failed %d", errno);
- close(fd);
- goto out;
+ time_diff = end_time.tv_sec - start_time.tv_sec;
+ if (time_diff > 0 && (SPEEDCHECK_SIZE / time_diff < SPEEDCHECK_CRITERION)) {
+ result = -1;
+ goto out_close;
}
+out_close:
close(fd);
out:
- reply = dbus_message_new_method_return(msg);
- dbus_message_iter_init_append(reply, &iter);
- dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &ret);
- return reply;
+ return g_variant_new("(i)", result);
+}
+
+
+static GVariant *request_control_block(GDBusConnection *conn,
+ const gchar *sender, const gchar *path, const gchar *iface, const gchar *name,
+ GVariant *param, GDBusMethodInvocation *invocation, gpointer user_data)
+{
+ int enable;
+ int result;
+
+ g_variant_get(param, "(i)", &enable);
+
+ switch (enable) {
+ case 0:
+ _I("Control block disable.");
+ result = 0;
+ block_stop(NULL);
+ break;
+ case 1:
+ _I("Control block enable.");
+ result = 0;
+ block_start(NULL);
+ break;
+ default:
+ _E("Control block. Wrong request by client.");
+ result = 1;
+ break;
+ }
+
+ return g_variant_new("(i)", result);
+}
+
+static GVariant *request_getcontrol_block(GDBusConnection *conn,
+ const gchar *sender, const gchar *path, const gchar *iface, const gchar *name,
+ GVariant *param, GDBusMethodInvocation *invocation, gpointer user_data)
+{
+ int result;
+
+ _I("Get control block.");
+
+ result = block_control;
+
+ return g_variant_new("(i)", result);
}
/*
*/
static const dbus_method_s manager_methods[] = {
- { "ShowDeviceList", NULL, request_show_device_list },
- { "GetDeviceList" , "s", request_get_device_list },
- { "GetDeviceList2", "s", request_get_device_list_2 },
- { "Mount", "is", request_public_mount_block },
- { "Unmount", "ii", request_public_unmount_block },
- { "Format", "ii", request_format_block },
- { "FormatwithType", "iis", request_format_block_type },
- { "GetDeviceInfo", "i", request_get_device_info },
- { "GetMmcPrimary" , NULL, request_get_mmc_primary },
- { "PrivateMount", "is", request_private_mount_block },
- { "PrivateUnmount", "ii", request_private_unmount_block },
- { "CheckSpeed", "i", request_check_speed },
+ { "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_public_mount_block },
+ { "Unmount", "ii", "i", request_public_unmount_block },
+ { "Format", "ii", "i", request_format_block },
+ { "FormatwithType", "iis", "i", request_format_block_type },
+ { "GetDeviceInfo", "i", "issssssisibii", request_get_device_info },
+ { "GetMmcPrimary", NULL, "issssssisibii", request_get_mmc_primary },
+ { "PrivateMount", "is", "i", request_private_mount_block },
+ { "PrivateUnmount", "ii", "i", request_private_unmount_block },
+ { "CheckSpeed", "i", "i", request_check_speed },
+ { "Control", "i", "i", request_control_block },
+ { "GetControl", NULL, "i", request_getcontrol_block },
};
-static dbus_interface_s block_interface = {
+static const dbus_interface_u block_interface = {
.name = STORAGED_INTERFACE_BLOCK_MANAGER,
.methods = manager_methods,
.nr_methods = ARRAY_SIZE(manager_methods),
#ifdef BLOCK_TMPFS
static int mount_root_path_tmpfs(void)
{
- int ret;
+ int ret_val;
const char *root;
root = tzplatform_getenv(TZ_SYS_MEDIA);
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;
+ ret_val = mount("tmpfs", root, "tmpfs", 0, "smackfsroot=System::Shared");
+ if (ret_val < 0) {
+ ret_val = -errno;
+ _E("Failed to mount tmpfs: %d", ret_val);
+ return ret_val;
}
return 0;
#define mount_root_path_tmpfs() 0
#endif
+static guint id_block_poweroff;
+
static void block_init(void *data)
{
- struct stat buf;
- int ret;
+ int ret_val;
int i;
- dbus_handle_h handle;
udev_init(NULL);
/* 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_val = config_parse(BLOCK_CONF_FILE, load_config, NULL);
+ if (ret_val < 0)
+ _E("Failed 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);
-
- ret = dbus_get_connection(&handle);
- if (ret < 0)
- _E("Failed to get dbus connection(%d)", ret);
+ ret_val = mount_root_path_tmpfs();
+ if (ret_val < 0)
+ _E("Failed to mount tmpfs to root mount path: %d", ret_val);
/* register block manager object and interface */
- ret = register_dbus_methods(handle,
- STORAGED_PATH_BLOCK_MANAGER, &block_interface,
- NULL, NULL);
- if (ret < 0)
- _E("Failed to register block interface and methods (%d)", ret);
+ ret_val = gdbus_register_object(NULL, STORAGED_PATH_BLOCK_MANAGER, &block_interface);
+ if (ret_val < 0)
+ _E("Failed to register block interface and methods: %d", ret_val);
/* 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);
-
- /* System Session is loaded completely */
- register_dbus_signal(SYSTEMD_DBUS_PATH,
- SYSTEMD_DBUS_IFACE_MANAGER,
- SYSTEMD_DBUS_SIGNAL_SYSTEM_STARTUP_FINISHED,
- booting_done, NULL, NULL);
-
- register_dbus_signal(DEVICED_PATH_POWEROFF,
- DEVICED_INTERFACE_POWEROFF,
- SIGNAL_POWEROFF_STATE,
- block_poweroff, NULL, NULL);
+ ret_val = pipe_init();
+ if (ret_val < 0)
+ _E("Failed to init pipe.");
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].start_th = false;
th_manager[i].thread_id = i;
pthread_mutex_init(&(th_manager[i].mutex), NULL);
pthread_cond_init(&(th_manager[i].cond), NULL);
}
- ret = stat(EXTERNAL_STORAGE_PATH, &buf);
- if (ret < 0) {
- ret = mkdir(EXTERNAL_STORAGE_PATH, 0755);
- if (ret < 0)
- _E("Failed to make directory: %d", errno);
- } else if (!S_ISDIR(buf.st_mode)) {
- ret = remove(EXTERNAL_STORAGE_PATH);
- if (ret < 0)
- _E("Fail to remove %s. errno: %d", EXTERNAL_STORAGE_PATH, errno);
- ret = mkdir(EXTERNAL_STORAGE_PATH, 0755);
- if (ret < 0)
- _E("Failed to make directory: %d", errno);
- } else {
- ret = chmod(EXTERNAL_STORAGE_PATH, 0644);
- if (ret < 0)
- _E("Fail to change permissions of a file");
- }
+ ret_val = remove_directory(EXTERNAL_STORAGE_PATH);
+ if (ret_val < 0)
+ _E("Failed to remove directory.");
+ ret_val = mkdir(EXTERNAL_STORAGE_PATH, 0755);
+ if (ret_val < 0)
+ _E("Failed to make directory: %d", errno);
- ret = stat(EXTENDED_INTERNAL_PATH, &buf);
- if (ret < 0) {
- ret = mkdir(EXTENDED_INTERNAL_PATH, 0755);
- if (ret < 0)
- _E("Failed to make directory: %d", errno);
- } else if (!S_ISDIR(buf.st_mode)) {
- ret = remove(EXTENDED_INTERNAL_PATH);
- if (ret < 0)
- _E("Fail to remove %s. errno: %d", EXTENDED_INTERNAL_PATH, errno);
- ret = mkdir(EXTENDED_INTERNAL_PATH, 0755);
- if (ret < 0)
- _E("Failed to make directory: %d", errno);
- } else {
- ret = chmod(EXTENDED_INTERNAL_PATH, 0644);
- if (ret < 0)
- _E("Fail to change permissions of a file");
+ ret_val = remove_directory(EXTENDED_INTERNAL_PATH);
+ if (ret_val < 0)
+ _E("Failed to remove directory.");
+ ret_val = mkdir(EXTENDED_INTERNAL_PATH, 0755);
+ if (ret_val < 0)
+ _E("Failed to make directory: %d", errno);
+
+ ret_val = get_internal_storage_number();
+ if (ret_val < 0)
+ _E("Failed to get internal storage number.");
+
+ id_block_poweroff = gdbus_signal_subscribe(NULL, DEVICED_PATH_POWEROFF,
+ DEVICED_INTERFACE_POWEROFF,
+ SIGNAL_POWEROFF_STATE,
+ block_poweroff, NULL, NULL);
+
+ booting_done();
+}
+static void terminate_threads(void)
+{
+ GList *elem, *elem_next;
+ char *temp;
+ int i, count;
+ const int WAIT_TIME = 10;
+
+ for (i = 0; i < THREAD_MAX; i++) {
+ if (th_manager[i].start_th) {
+ count = 0;
+ while ((th_manager[i].op_len != 0) && (count < WAIT_TIME)) {
+ _I("Thread(%d) job is not finished. Wait a second.", th_manager[i].thread_id);
+ usleep(200*1000);
+ count++;
+ }
+ pthread_cancel(th_manager[i].th);
+ pthread_join(th_manager[i].th, NULL);
+ }
+ SYS_G_LIST_FOREACH_SAFE(th_manager[i].th_node_list, elem, elem_next, temp) {
+ SYS_G_LIST_REMOVE(th_manager[i].th_node_list, temp);
+ free(temp);
+ }
}
}
static void block_exit(void *data)
{
- dd_list *elem, *elem_next;
- char *temp;
- int ret, i;
+ int ret_val;
udev_exit(NULL);
/* unregister notifier for below each event */
- unregister_dbus_signal(SYSTEMD_DBUS_PATH,
- SYSTEMD_DBUS_IFACE_MANAGER,
- SYSTEMD_DBUS_SIGNAL_SYSTEM_STARTUP_FINISHED,
- booting_done);
-
- unregister_dbus_signal(DEVICED_PATH_POWEROFF,
- DEVICED_INTERFACE_POWEROFF,
- SIGNAL_POWEROFF_STATE, block_poweroff);
-
- /* exit pipe */
- pipe_exit();
+ gdbus_signal_unsubscribe(NULL, id_block_poweroff);
/* unregister mmc uevent control routine */
- ret = unregister_udev_uevent_control(&uh);
- if (ret < 0)
- _E("fail to unregister block uevent : %d", ret);
+ ret_val = unregister_udev_uevent_control(&uh);
+ if (ret_val < 0)
+ _E("Failed to unregister block uevent: %d", ret_val);
/* 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);
- DD_LIST_FOREACH_SAFE(th_manager[i].th_node_list, elem, elem_next, temp) {
- DD_LIST_REMOVE(th_manager[i].th_node_list, temp);
- free(temp);
- }
+ terminate_threads();
+
+ /* exit pipe */
+ pipe_exit();
+
+ if (add_poweroff_wait) {
+ ret_val = gdbus_call_sync_with_reply_int(DEVICED_BUS_NAME,
+ DEVICED_PATH_POWEROFF,
+ DEVICED_INTERFACE_POWEROFF,
+ METHOD_REMOVE_POWEROFF_WAIT,
+ NULL, NULL);
+ if (ret_val < 0)
+ _E("Failed to call "METHOD_REMOVE_POWEROFF_WAIT" method.");
+ else
+ add_poweroff_wait = false;
}
block_control = false;
static int block_start(void *data)
{
- int ret;
-
if (!block_boot) {
- _E("Cannot be started. Booting is not ready");
+ _E("Cannot be started. Booting is not ready.");
return -ENODEV;
}
if (block_control) {
- _I("Already started");
+ _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_control = true;
block_init_from_udev_enumerate();
- block_control = true;
-
- _I("start");
+ _I("Start.");
return 0;
}
static int block_stop(void *data)
{
if (!block_boot) {
- _E("Cannot be stopped. Booting is not ready");
+ _E("Cannot be stopped. Booting is not ready.");
return -ENODEV;
}
if (!block_control) {
- _I("Already stopped");
+ _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");
+ _I("Stop.");
return 0;
}