#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"
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 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 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);
_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;
+ /* 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);
+ }
+
+ sync();
+ if (umount2(data->mount_point, MNT_DETACH) != 0) {
+ _I("Failed to unmount with lazy option: %m");
+ return -errno;
+ }
+
+ time.tv_nsec = 500 * NANO_SECOND_MULTIPLIER;
+
+ while (retry++ < UNMOUNT_RETRY) {
+ _I("Kill app with SIGTERM.");
+ terminate_process(data->devnode, false);
nanosleep(&time, NULL);
- print_open_files(data->mount_point);
+ _I("Kill app with SIGKILL.");
+ terminate_process(data->devnode, true);
+ nanosleep(&time, NULL);
- r = mmc_check_and_unmount(data->mount_point);
- if (!r) {
- _D("Success to unmount '%s'.", data->mount_point);
+ if (!is_in_use_partition(data->devnode))
break;
- }
}
+ sync();
out:
data->state = BLOCK_UNMOUNT;
/* if there is the attached device, try to mount */
block_init_from_udev_enumerate();
+ ret = dbus_handle_method_sync(DEVICED_BUS_NAME,
+ DEVICED_PATH_POWEROFF,
+ DEVICED_INTERFACE_POWEROFF,
+ METHOD_ADD_POWEROFF_WAIT,
+ NULL, NULL);
+ if (ret < 0)
+ _E("Failed to call "METHOD_ADD_POWEROFF_WAIT" method.");
+ else
+ add_poweroff_wait = true;
+
block_boot = true;
}
gpointer data)
{
static int status = 0;
+ int ret;
+
if (status > 0)
return;
status = 1;
/* unregister mmc uevent control routine */
unregister_udev_uevent_control(&uh);
remove_whole_block_device();
+ terminate_threads();
+
+ if (add_poweroff_wait) {
+ ret = dbus_handle_method_sync(DEVICED_BUS_NAME,
+ DEVICED_PATH_POWEROFF,
+ DEVICED_INTERFACE_POWEROFF,
+ METHOD_REMOVE_POWEROFF_WAIT,
+ NULL, NULL);
+ if (ret < 0)
+ _E("Failed to call "METHOD_REMOVE_POWEROFF_WAIT" method.");
+ else
+ add_poweroff_wait = false;
+ }
}
static void uevent_block_handler(struct udev_device *dev)
/* exit pipe */
pipe_exit();
+ if (add_poweroff_wait) {
+ ret = dbus_handle_method_sync(DEVICED_BUS_NAME,
+ DEVICED_PATH_POWEROFF,
+ DEVICED_INTERFACE_POWEROFF,
+ METHOD_REMOVE_POWEROFF_WAIT,
+ NULL, NULL);
+ if (ret < 0)
+ _E("Failed to call "METHOD_REMOVE_POWEROFF_WAIT" method.");
+ else
+ add_poweroff_wait = false;
+ }
+
block_control = false;
}