return NULL;
}
+static struct block_device *find_first_primary_block()
+{
+ struct block_device *bdev;
+ GList *elem;
+ int i;
+
+ 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)
+ continue;
+ if (bdev->removed)
+ continue;
+ if (bdev->data->primary) {
+ pthread_mutex_unlock(&(th_manager[i].mutex));
+ return bdev;
+ }
+ }
+ pthread_mutex_unlock(&(th_manager[i].mutex));
+ }
+
+ return NULL;
+}
+
static const char *get_operation_char(enum block_dev_operation op)
{
switch (op) {
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.");
+ _D("Format request for extended internal storage is not allowed.");
ret = -EPERM;
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.");
+ _D("FormatwithType request for extended internal storage is not allowed.");
ret = -EPERM;
goto out;
}
return g_variant_new("(i)", ret);
}
+static GVariant *request_format_first_primary_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;
+ pid_t pid;
+ int option;
+ int ret = -EBADMSG;
+ int prev_state;
+
+ if (!block_control) {
+ _D("Block module is disabled.");
+ ret = -EPERM;
+ goto out;
+ }
+
+ g_variant_get(param, "(i)", &option);
+
+ bdev = find_first_primary_block();
+ _E("FORMAT=%d", bdev->data->id);
+ if (!bdev) {
+ _E("Failed to find the first primary block in the device list.");
+ goto out;
+ }
+
+ if (strncmp(bdev->data->fs_type, VFAT_NAME, strlen(VFAT_NAME))) {
+ _D("Format request for non-VFAT first primary storage is not allowed.");
+ goto out;
+ }
+
+ if (bdev->data->block_type == BLOCK_EXTENDEDSD_DEV ||
+ !strncmp(bdev->data->fs_type, LUKS_NAME, strlen(LUKS_NAME))) {
+ _D("Format request for extended internal storage is not allowed.");
+ 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.");
+ ret = -EPERM;
+ goto out;
+ }
+
+ fdata = get_format_data(NULL, option);
+ if (!fdata) {
+ _E("Failed to get format data.");
+ goto out;
+ }
+
+ prev_state = bdev->data->state;
+ if (prev_state == BLOCK_MOUNT) {
+ if (bdev->on_private_op == REQ_PRIVATE) {
+ bdev->on_private_op = REQ_PRIVATE_FORMAT;
+ _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);
+ release_format_data(fdata);
+ goto out;
+ }
+ }
+
+ ret = add_operation(bdev, BLOCK_DEV_FORMAT, invocation, (void *)fdata);
+ if (ret < 0) {
+ _E("Failed to add operation(format, %s).", bdev->data->devnode);
+ release_format_data(fdata);
+ }
+
+ /* Maintain previous state of mount/unmount */
+ if (prev_state == BLOCK_MOUNT) {
+ if (add_operation(bdev, BLOCK_DEV_MOUNT, NULL, NULL) < 0) {
+ _E("Failed to add operation(mount, %s).", bdev->data->devnode);
+ goto out;
+ }
+ }
+
+ return NULL;
+
+out:
+ return g_variant_new("(i)", ret);
+}
+
static GVariant *block_data_to_gvariant(struct block_data *data, int flags)
{
if (!data)
return g_variant_new("(i)", result);
}
-/*
- Method name Method call format string Reply format string
-{ "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 },
-{ "Unmoun, "ii", "i", request_public_unmount_block },
-{ "Format", "ii", "i", request_format_block },
-{ "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 },
-*/
-
-static const dbus_method_s manager_methods[] = {
- { "ShowDeviceList", NULL, NULL, request_show_device_list },
- { "GetDeviceList" , "s", "a(issssssisibii)", request_get_device_list },
- { "GetDeviceList2", "s", "a(issssssisibi)", request_get_device_list_2 },
- { "Mount", "is", "i", request_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 const dbus_interface_u block_interface = {
- .name = STORAGED_INTERFACE_BLOCK_MANAGER,
- .methods = manager_methods,
- .nr_methods = ARRAY_SIZE(manager_methods),
-};
-
static int load_config(struct parse_result *result, void *user_data)
{
int index;
#define mount_root_path_tmpfs() 0
#endif
+/*
+ Method name Method call format string Reply format string
+{ "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 },
+{ "Unmoun, "ii", "i", request_public_unmount_block },
+{ "Format", "ii", "i", request_format_block },
+{ "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 },
+*/
+
+static const dbus_method_s manager_methods[] = {
+ { "ShowDeviceList", NULL, NULL, request_show_device_list },
+ { "GetDeviceList" , "s", "a(issssssisibii)", request_get_device_list },
+ { "GetDeviceList2", "s", "a(issssssisibi)", request_get_device_list_2 },
+ { "Mount", "is", "i", request_public_mount_block },
+ { "Unmount", "ii", "i", request_public_unmount_block },
+ { "Format", "ii", "i", request_format_block },
+ { "FormatwithType", "iis", "i", request_format_block_type },
+ { "FormatFirstPrimary", "i", "i", request_format_first_primary_block },
+ { "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 const dbus_interface_u block_interface = {
+ .name = STORAGED_INTERFACE_BLOCK_MANAGER,
+ .methods = manager_methods,
+ .nr_methods = ARRAY_SIZE(manager_methods),
+};
+
static guint id_block_poweroff;
static void block_init(void *data)
booting_done();
}
+
static void terminate_threads(void)
{
GList *elem, *elem_next;