diff options
Diffstat (limited to 'vold/uevent.c')
-rw-r--r-- | vold/uevent.c | 447 |
1 files changed, 0 insertions, 447 deletions
diff --git a/vold/uevent.c b/vold/uevent.c deleted file mode 100644 index dc15d80d6..000000000 --- a/vold/uevent.c +++ /dev/null @@ -1,447 +0,0 @@ - -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <string.h> -#include <stdlib.h> -#include <errno.h> - -#include <sys/types.h> -#include <sys/socket.h> - -#include "vold.h" -#include "uevent.h" -#include "mmc.h" -#include "blkdev.h" -#include "volmgr.h" -#include "media.h" - -#define DEBUG_UEVENT 0 - -#define UEVENT_PARAMS_MAX 32 - -enum uevent_action { action_add, action_remove, action_change }; - -struct uevent { - char *path; - enum uevent_action action; - char *subsystem; - char *param[UEVENT_PARAMS_MAX]; - unsigned int seqnum; -}; - -struct uevent_dispatch { - char *subsystem; - int (* dispatch) (struct uevent *); -}; - -static void dump_uevent(struct uevent *); -static int dispatch_uevent(struct uevent *event); -static void free_uevent(struct uevent *event); -static char *get_uevent_param(struct uevent *event, char *param_name); - -static int handle_powersupply_event(struct uevent *event); -static int handle_switch_event(struct uevent *); -static int handle_battery_event(struct uevent *); -static int handle_mmc_event(struct uevent *); -static int handle_block_event(struct uevent *); -static int handle_bdi_event(struct uevent *); -static void _cb_blkdev_ok_to_destroy(blkdev_t *dev); - -static struct uevent_dispatch dispatch_table[] = { - { "switch", handle_switch_event }, - { "battery", handle_battery_event }, - { "mmc", handle_mmc_event }, - { "block", handle_block_event }, - { "bdi", handle_bdi_event }, - { "power_supply", handle_powersupply_event }, - { 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 :) - int count; - char *s = buffer; - char *end; - struct uevent *event; - int param_idx = 0; - int i; - int first = 1; - int rc = 0; - - if ((count = recv(socket, buffer, sizeof(buffer), 0)) < 0) { - LOGE("Error receiving uevent (%s)", strerror(errno)); - return -errno; - } - - if (!(event = malloc(sizeof(struct uevent)))) { - LOGE("Error allocating memory (%s)", strerror(errno)); - return -errno; - } - - memset(event, 0, sizeof(struct uevent)); - - end = s + count; - while (s < end) { - if (first) { - char *p; - for (p = s; *p != '@'; p++); - p++; - event->path = strdup(p); - first = 0; - } else { - if (!strncmp(s, "ACTION=", strlen("ACTION="))) { - char *a = s + strlen("ACTION="); - - if (!strcmp(a, "add")) - event->action = action_add; - else if (!strcmp(a, "change")) - event->action = action_change; - else if (!strcmp(a, "remove")) - event->action = action_remove; - } else if (!strncmp(s, "SEQNUM=", strlen("SEQNUM="))) - event->seqnum = atoi(s + strlen("SEQNUM=")); - else if (!strncmp(s, "SUBSYSTEM=", strlen("SUBSYSTEM="))) - event->subsystem = strdup(s + strlen("SUBSYSTEM=")); - else - event->param[param_idx++] = strdup(s); - } - s+= strlen(s) + 1; - } - - rc = dispatch_uevent(event); - - free_uevent(event); - return rc; -} - -int simulate_uevent(char *subsys, char *path, char *action, char **params) -{ - struct uevent *event; - char tmp[255]; - int i, rc; - - if (!(event = malloc(sizeof(struct uevent)))) { - LOGE("Error allocating memory (%s)", strerror(errno)); - return -errno; - } - - memset(event, 0, sizeof(struct uevent)); - - event->subsystem = strdup(subsys); - - if (!strcmp(action, "add")) - event->action = action_add; - else if (!strcmp(action, "change")) - event->action = action_change; - else if (!strcmp(action, "remove")) - event->action = action_remove; - else { - LOGE("Invalid action '%s'", action); - return -1; - } - - event->path = strdup(path); - - for (i = 0; i < UEVENT_PARAMS_MAX; i++) { - if (!params[i]) - break; - event->param[i] = strdup(params[i]); - } - - rc = dispatch_uevent(event); - free_uevent(event); - return rc; -} - -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", event->subsystem); -#endif - return 0; -} - -static void dump_uevent(struct uevent *event) -{ - int i; - - 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", event->param[i]); - } -} - -static void free_uevent(struct uevent *event) -{ - int i; - free(event->path); - free(event->subsystem); - for (i = 0; i < UEVENT_PARAMS_MAX; i++) { - if (!event->param[i]) - break; - free(event->param[i]); - } - free(event); -} - -static char *get_uevent_param(struct uevent *event, char *param_name) -{ - int i; - - for (i = 0; i < UEVENT_PARAMS_MAX; i++) { - if (!event->param[i]) - break; - if (!strncmp(event->param[i], param_name, strlen(param_name))) - return &event->param[i][strlen(param_name) + 1]; - } - - LOGE("get_uevent_param(): No parameter '%s' found", param_name); - return NULL; -} - -/* - * --------------- - * Uevent Handlers - * --------------- - */ - -static int handle_powersupply_event(struct uevent *event) -{ - char *ps_type = get_uevent_param(event, "POWER_SUPPLY_TYPE"); - - if (!strcasecmp(ps_type, "battery")) { - char *ps_cap = get_uevent_param(event, "POWER_SUPPLY_CAPACITY"); - int capacity = atoi(ps_cap); - - if (capacity < 5) - low_batt = true; - else - low_batt = false; - volmgr_safe_mode(low_batt || door_open); - } - return 0; -} - -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); - } - - return 0; -} - -static int handle_battery_event(struct uevent *event) -{ - return 0; -} - -static int handle_block_event(struct uevent *event) -{ - char mediapath[255]; - media_t *media; - int n; - int maj, min; - blkdev_t *blkdev; - - /* - * Look for backing media for this block device - */ - 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'", get_uevent_param(event, "DEVTYPE")); - return -EINVAL; - } - - truncate_sysfs_path(event->path, n, mediapath, sizeof(mediapath)); - - if (!(media = media_lookup_by_path(mediapath, false))) { -#if DEBUG_UEVENT - LOG_VOL("No backend media found @ device path '%s'", mediapath); -#endif - return 0; - } - - maj = atoi(get_uevent_param(event, "MAJOR")); - min = atoi(get_uevent_param(event, "MINOR")); - - if (event->action == action_add) { - blkdev_t *disk; - - /* - * If there isn't a disk already its because *we* - * are the disk - */ - if (media->media_type == media_mmc) - disk = blkdev_lookup_by_devno(maj, ALIGN_MMC_MINOR(min)); - else - disk = blkdev_lookup_by_devno(maj, 0); - - if (!(blkdev = blkdev_create(disk, - event->path, - maj, - min, - media, - get_uevent_param(event, "DEVTYPE")))) { - LOGE("Unable to allocate new blkdev (%s)", strerror(errno)); - 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)", 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) { - if (rc == -EBUSY) { - LOGI("Volmgr not ready to handle device"); - } else { - LOGE("Volmgr failed to handle device (%d)", rc); - return rc; - } - } - } - } else if (event->action == action_remove) { - if (!(blkdev = blkdev_lookup_by_devno(maj, min))) - return 0; - - 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; - - 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", event->action); -#endif - } - return 0; -} - -static void _cb_blkdev_ok_to_destroy(blkdev_t *dev) -{ - media_t *media = media_lookup_by_dev(dev); - if (media) - media_remove_blkdev(media, dev); - blkdev_destroy(dev); -} - -static int handle_bdi_event(struct uevent *event) -{ - return 0; -} - -static int handle_mmc_event(struct uevent *event) -{ - if (event->action == action_add) { - media_t *media; - char serial[80]; - char *type; - - /* - * Pull card information from sysfs - */ - type = get_uevent_param(event, "MMC_TYPE"); - if (strcmp(type, "SD") && strcmp(type, "MMC")) - return 0; - - read_sysfs_var(serial, sizeof(serial), event->path, "serial"); - if (!(media = media_create(event->path, - get_uevent_param(event, "MMC_NAME"), - serial, - media_mmc))) { - LOGE("Unable to allocate new media (%s)", strerror(errno)); - return -1; - } - 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'", event->path); - return -1; - } - - LOGI("MMC card '%s' (serial %u) @ %s removed", media->name, - media->serial, media->devpath); - media_destroy(media); - } else { -#if DEBUG_UEVENT - LOG_VOL("No handler implemented for action %d", event->action); -#endif - } - - return 0; -} |