diff options
Diffstat (limited to 'vold/uevent.c')
-rw-r--r-- | vold/uevent.c | 152 |
1 files changed, 81 insertions, 71 deletions
diff --git a/vold/uevent.c b/vold/uevent.c index 6b724d0..d16f315 100644 --- a/vold/uevent.c +++ b/vold/uevent.c @@ -71,6 +71,9 @@ static struct uevent_dispatch dispatch_table[] = { { NULL, NULL } }; +static boolean low_batt = false; +static boolean door_open = true; + int process_uevent_message(int socket) { char buffer[64 * 1024]; // Thank god we're not in the kernel :) @@ -84,12 +87,12 @@ int process_uevent_message(int socket) int rc = 0; if ((count = recv(socket, buffer, sizeof(buffer), 0)) < 0) { - LOGE("Error receiving uevent (%s)\n", strerror(errno)); + LOGE("Error receiving uevent (%s)", strerror(errno)); return -errno; } if (!(event = malloc(sizeof(struct uevent)))) { - LOGE("Error allocating memory (%s)\n", strerror(errno)); + LOGE("Error allocating memory (%s)", strerror(errno)); return -errno; } @@ -120,7 +123,7 @@ int process_uevent_message(int socket) else event->param[param_idx++] = strdup(s); } - s+= (strlen(s) + 1); + s+= strlen(s) + 1; } rc = dispatch_uevent(event); @@ -136,7 +139,7 @@ int simulate_uevent(char *subsys, char *path, char *action, char **params) int i, rc; if (!(event = malloc(sizeof(struct uevent)))) { - LOGE("Error allocating memory (%s)\n", strerror(errno)); + LOGE("Error allocating memory (%s)", strerror(errno)); return -errno; } @@ -151,7 +154,7 @@ int simulate_uevent(char *subsys, char *path, char *action, char **params) else if (!strcmp(action, "remove")) event->action = action_remove; else { - LOGE("Invalid action '%s'\n", action); + LOGE("Invalid action '%s'", action); return -1; } @@ -172,13 +175,16 @@ static int dispatch_uevent(struct uevent *event) { int i; +#if DEBUG_UEVENT + dump_uevent(event); +#endif for (i = 0; dispatch_table[i].subsystem != NULL; i++) { if (!strcmp(dispatch_table[i].subsystem, event->subsystem)) return dispatch_table[i].dispatch(event); } #if DEBUG_UEVENT - LOG_VOL("No uevent handlers registered for '%s' subsystem\n", event->subsystem); + LOG_VOL("No uevent handlers registered for '%s' subsystem", event->subsystem); #endif return 0; } @@ -187,12 +193,12 @@ static void dump_uevent(struct uevent *event) { int i; - LOG_VOL("[UEVENT] Sq: %u S: %s A: %d P: %s\n", + LOG_VOL("[UEVENT] Sq: %u S: %s A: %d P: %s", event->seqnum, event->subsystem, event->action, event->path); for (i = 0; i < UEVENT_PARAMS_MAX; i++) { if (!event->param[i]) break; - LOG_VOL("%s\n", event->param[i]); + LOG_VOL("%s", event->param[i]); } } @@ -220,7 +226,7 @@ static char *get_uevent_param(struct uevent *event, char *param_name) return &event->param[i][strlen(param_name) + 1]; } - LOGE("get_uevent_param(): No parameter '%s' found\n", param_name); + LOGE("get_uevent_param(): No parameter '%s' found", param_name); return NULL; } @@ -232,7 +238,18 @@ static char *get_uevent_param(struct uevent *event, char *param_name) static int handle_powersupply_event(struct uevent *event) { - dump_uevent(event); + char *ps_type = get_uevent_param(event, "POWER_SUPPLY_TYPE"); + char *ps_cap = get_uevent_param(event, "POWER_SUPPLY_CAPACITY"); + + if (!strcasecmp(ps_type, "battery")) { + int capacity = atoi(ps_cap); + + if (capacity < 5) + low_batt = true; + else + low_batt = false; + volmgr_safe_mode(low_batt || door_open); + } return 0; } @@ -241,21 +258,28 @@ static int handle_switch_event(struct uevent *event) char *name = get_uevent_param(event, "SWITCH_NAME"); char *state = get_uevent_param(event, "SWITCH_STATE"); + if (!strcmp(name, "usb_mass_storage")) { if (!strcmp(state, "online")) { ums_hostconnected_set(true); } else { ums_hostconnected_set(false); + volmgr_enable_ums(false); } + } else if (!strcmp(name, "sd-door")) { + if (!strcmp(state, "open")) + door_open = true; + else + door_open = false; + volmgr_safe_mode(low_batt || door_open); } else - LOG_VOL("handle_switch_event(): Ignoring switch '%s'\n", name); + LOG_VOL("handle_switch_event(): Ignoring switch '%s'", name); return 0; } static int handle_battery_event(struct uevent *event) { - dump_uevent(event); return 0; } @@ -270,12 +294,16 @@ static int handle_block_event(struct uevent *event) /* * Look for backing media for this block device */ - if (!strcmp(get_uevent_param(event, "DEVTYPE"), "disk")) + if (!strncmp(get_uevent_param(event, "DEVPATH"), + "/devices/virtual/", + strlen("/devices/virtual/"))) { + n = 0; + } else if (!strcmp(get_uevent_param(event, "DEVTYPE"), "disk")) n = 2; else if (!strcmp(get_uevent_param(event, "DEVTYPE"), "partition")) n = 3; else { - LOGE("Bad blockdev type '%s'\n", get_uevent_param(event, "DEVTYPE")); + LOGE("Bad blockdev type '%s'", get_uevent_param(event, "DEVTYPE")); return -EINVAL; } @@ -283,7 +311,7 @@ static int handle_block_event(struct uevent *event) if (!(media = media_lookup_by_path(mediapath, false))) { #if DEBUG_UEVENT - LOG_VOL("No backend media found @ device path '%s'\n", mediapath); + LOG_VOL("No backend media found @ device path '%s'", mediapath); #endif return 0; } @@ -293,7 +321,6 @@ static int handle_block_event(struct uevent *event) if (event->action == action_add) { blkdev_t *disk; - boolean pending = false; /* * If there isn't a disk already its because *we* @@ -301,70 +328,56 @@ static int handle_block_event(struct uevent *event) */ disk = blkdev_lookup_by_devno(maj, 0); - /* - * It is possible that there is already a blkdev - * for this device (created by blkdev_create_pending_partition()) - */ - - if ((blkdev = blkdev_lookup_by_devno(maj, min))) { - blkdev_devpath_set(blkdev, event->path); - pending = true; - } else { - if (!(blkdev = blkdev_create(disk, - event->path, - maj, - min, - media, - get_uevent_param(event, "DEVTYPE")))) { - LOGE("Unable to allocate new blkdev (%m)\n"); - return -1; - } + if (!(blkdev = blkdev_create(disk, + event->path, + maj, + min, + media, + get_uevent_param(event, "DEVTYPE")))) { + LOGE("Unable to allocate new blkdev (%m)"); + return -1; } + blkdev_refresh(blkdev); + /* * Add the blkdev to media */ int rc; if ((rc = media_add_blkdev(media, blkdev)) < 0) { - LOGE("Unable to add blkdev to card (%d)\n", rc); + LOGE("Unable to add blkdev to card (%d)", rc); return rc; } - LOG_VOL("New blkdev %d.%d on media %s, media path %s\n", blkdev->major, blkdev->minor, media->name, mediapath); - - if (pending) { - /* - * This blkdev already has its dev_fspath set so - * if all partitions are read, pass it off to - * the volume manager - */ - LOG_VOL("Pending disk '%d.%d' has %d pending partitions\n", - blkdev->disk->major, blkdev->disk->minor, - blkdev_get_num_pending_partitions(blkdev->disk)); - - if (blkdev_get_num_pending_partitions(blkdev->disk) == 0) { - if ((rc = volmgr_consider_disk(blkdev->disk)) < 0) { - LOGE("Volmgr failed to handle pending device (%d)\n", rc); - return rc; - } + LOGI("New blkdev %d.%d on media %s, media path %s, Dpp %d", + blkdev->major, blkdev->minor, media->name, mediapath, + blkdev_get_num_pending_partitions(blkdev->disk)); + + if (blkdev_get_num_pending_partitions(blkdev->disk) == 0) { + if ((rc = volmgr_consider_disk(blkdev->disk)) < 0) { + LOGE("Volmgr failed to handle device (%d)", rc); + return rc; } } } else if (event->action == action_remove) { - int rc; + if (!(blkdev = blkdev_lookup_by_devno(maj, min))) + return 0; - if (!(blkdev = blkdev_lookup_by_devno(maj, min))) { -#if DEBUG_UEVENT - LOG_VOL("We aren't handling blkdev @ %s\n", event->path); -#endif + LOGI("Destroying blkdev %d.%d @ %s on media %s", blkdev->major, + blkdev->minor, blkdev->devpath, media->name); + volmgr_notify_eject(blkdev, _cb_blkdev_ok_to_destroy); + + } else if (event->action == action_change) { + if (!(blkdev = blkdev_lookup_by_devno(maj, min))) return 0; - } - LOG_VOL("Destroying blkdev %d.%d @ %s on media %s\n", blkdev->major, blkdev->minor, blkdev->devpath, media->name); - if ((rc = volmgr_notify_eject(blkdev, _cb_blkdev_ok_to_destroy)) < 0) - LOGE("Error notifying volmgr of eject\n"); - } else { + LOGI("Modified blkdev %d.%d @ %s on media %s", blkdev->major, + blkdev->minor, blkdev->devpath, media->name); + + blkdev_refresh(blkdev); + } else { #if DEBUG_UEVENT - LOG_VOL("No handler implemented for action %d\n", event->action); + LOG_VOL("No handler implemented for action %d", event->action); #endif } return 0; @@ -402,28 +415,25 @@ static int handle_mmc_event(struct uevent *event) get_uevent_param(event, "MMC_NAME"), serial, media_mmc))) { - LOGE("Unable to allocate new media (%m)\n"); + LOGE("Unable to allocate new media (%m)"); return -1; } - LOG_VOL("New MMC card '%s' (serial %u) added @ %s\n", media->name, + LOGI("New MMC card '%s' (serial %u) added @ %s", media->name, media->serial, media->devpath); } else if (event->action == action_remove) { media_t *media; if (!(media = media_lookup_by_path(event->path, false))) { - LOGE("Unable to lookup media '%s'\n", event->path); + LOGE("Unable to lookup media '%s'", event->path); return -1; } - LOG_VOL("MMC card '%s' (serial %u) @ %s removed\n", media->name, + LOGI("MMC card '%s' (serial %u) @ %s removed", media->name, media->serial, media->devpath); - /* - * If this media is still mounted, then we have an unsafe removal - */ media_destroy(media); } else { #if DEBUG_UEVENT - LOG_VOL("No handler implemented for action %d\n", event->action); + LOG_VOL("No handler implemented for action %d", event->action); #endif } |