Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 8ccb3a55 authored by San Mehat's avatar San Mehat
Browse files

system: Remove dead vold1 code



Signed-off-by: default avatarSan Mehat <san@google.com>
parent bbfe1368
Loading
Loading
Loading
Loading

vold/Android.mk

deleted100644 → 0
+0 −37
Original line number Diff line number Diff line
BUILD_VOLD := false
ifeq ($(BUILD_VOLD),true)

LOCAL_PATH:= $(call my-dir)

include $(CLEAR_VARS)

LOCAL_SRC_FILES:=                \
                  vold.c       \
                  cmd_dispatch.c \
                  uevent.c       \
                  mmc.c          \
		  misc.c         \
                  blkdev.c       \
                  ums.c          \
                  geom_mbr_enc.c \
                  volmgr.c       \
                  media.c        \
                  volmgr_vfat.c  \
                  volmgr_ext3.c  \
                  logwrapper.c   \
                  ProcessKiller.c\
                  switch.c       \
                  format.c       \
                  devmapper.c

LOCAL_MODULE:= vold

LOCAL_C_INCLUDES := $(KERNEL_HEADERS)

LOCAL_CFLAGS := 

LOCAL_SHARED_LIBRARIES := libcutils

include $(BUILD_EXECUTABLE)

endif # ifeq ($(BUILD_VOLD),true)

vold/ProcessKiller.c

deleted100644 → 0
+0 −222
Original line number Diff line number Diff line
/*
 * 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.
 */

/*
** mountd process killer
*/

#include "vold.h"

#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#include <dirent.h>
#include <ctype.h>
#include <pwd.h>
#include <stdlib.h>
#include <poll.h>
#include <sys/stat.h>


static boolean ReadSymLink(const char* path, char* link)
{
    struct stat s;
    int length;

    if (lstat(path, &s) < 0)
        return false;
    if ((s.st_mode & S_IFMT) != S_IFLNK)
        return false;
   
    // we have a symlink    
    length = readlink(path, link, PATH_MAX - 1);
    if (length <= 0) 
        return false;
    link[length] = 0;
    return true;
}

static boolean PathMatchesMountPoint(const char* path, const char* mountPoint)
{
    int length = strlen(mountPoint);
    if (length > 1 && strncmp(path, mountPoint, length) == 0)
    {
        // we need to do extra checking if mountPoint does not end in a '/'
        if (mountPoint[length - 1] == '/')
            return true;
        // if mountPoint does not have a trailing slash, we need to make sure
        // there is one in the path to avoid partial matches.
        return (path[length] == 0 || path[length] == '/');
    }
    
    return false;
}

static void GetProcessName(int pid, char buffer[PATH_MAX])
{
    int fd;
    sprintf(buffer, "/proc/%d/cmdline", pid);
    fd = open(buffer, O_RDONLY);
    if (fd < 0) {
        strcpy(buffer, "???");
    } else {
        int length = read(fd, buffer, PATH_MAX - 1);
        buffer[length] = 0;
        close(fd);
    }
}

static boolean CheckFileDescriptorSymLinks(int pid, const char* mountPoint)
{
    DIR*    dir;
    struct dirent* de;
    boolean fileOpen = false;
    char    path[PATH_MAX];
    char    link[PATH_MAX];
    int     parent_length;

    // compute path to process's directory of open files
    sprintf(path, "/proc/%d/fd", pid);
    dir = opendir(path);
    if (!dir)
        return false;

    // remember length of the path
    parent_length = strlen(path);
    // append a trailing '/'
    path[parent_length++] = '/';
    
    while ((de = readdir(dir)) != 0 && !fileOpen) {
        if (!strcmp(de->d_name, ".") || !strcmp(de->d_name, ".."))
            continue;
        
        // append the file name, after truncating to parent directory
        path[parent_length] = 0;
        strcat(path, de->d_name);

        if (ReadSymLink(path, link) && PathMatchesMountPoint(link, mountPoint))
        {
            char    name[PATH_MAX];
            GetProcessName(pid, name);
            LOG_ERROR("process %s (%d) has open file %s", name, pid, link);
            fileOpen = true;
        }
    }

    closedir(dir);
    return fileOpen;
}

static boolean CheckFileMaps(int pid, const char* mountPoint)
{
    FILE*   file;
    char    buffer[PATH_MAX + 100];
    boolean mapOpen = false;

    sprintf(buffer, "/proc/%d/maps", pid);
    file = fopen(buffer, "r");
    if (!file)
        return false;
    
    while (!mapOpen && fgets(buffer, sizeof(buffer), file))
    {
        // skip to the path
        const char* path = strchr(buffer, '/');
        if (path && PathMatchesMountPoint(path, mountPoint))
        {
            char    name[PATH_MAX];
            GetProcessName(pid, name);
            LOG_ERROR("process %s (%d) has open file map for %s", name, pid, path);
            mapOpen = true;
        }
    }
    
    fclose(file);
    return mapOpen;
}

static boolean CheckSymLink(int pid, const char* mountPoint, const char* name, const char* message)
{
    char    path[PATH_MAX];
    char    link[PATH_MAX];

    sprintf(path, "/proc/%d/%s", pid, name);
    if (ReadSymLink(path, link) && PathMatchesMountPoint(link, mountPoint)) 
    {
        char    name[PATH_MAX];
        GetProcessName(pid, name);
        LOG_ERROR("process %s (%d) has %s in %s", name, pid, message, mountPoint);
        return true;
    }
    else
        return false;
}

static int get_pid(const char* s)
{
    int result = 0;
    while (*s) {
        if (!isdigit(*s)) return -1;
        result = 10 * result + (*s++ - '0');
    }
    return result;
}

// hunt down and kill processes that have files open on the given mount point
void KillProcessesWithOpenFiles(const char* mountPoint, boolean sigkill, int *excluded, int num_excluded)
{
    DIR*    dir;
    struct dirent* de;

    LOG_ERROR("KillProcessesWithOpenFiles %s", mountPoint);
    dir = opendir("/proc");
    if (!dir) return;

    while ((de = readdir(dir)) != 0)
    {
        boolean killed = false;
        // does the name look like a process ID?
        int pid = get_pid(de->d_name);
        if (pid == -1) continue;

        if (CheckFileDescriptorSymLinks(pid, mountPoint)    // check for open files
                || CheckFileMaps(pid, mountPoint)           // check for mmap()
                || CheckSymLink(pid, mountPoint, "cwd", "working directory")    // check working directory
                || CheckSymLink(pid, mountPoint, "root", "chroot")              // check for chroot()
                || CheckSymLink(pid, mountPoint, "exe", "executable path")      // check executable path
            ) 
        {
            int i;
            boolean hit = false;

            for (i = 0; i < num_excluded; i++) {
                if (pid == excluded[i]) {
                    LOG_ERROR("I just need a little more TIME captain!");
                    hit = true;
                    break;
                }
            }

            if (!hit) {
                LOG_ERROR("Killing process %d", pid);
                kill(pid, (sigkill ? SIGKILL : SIGTERM));
            }
        }
    }

    closedir(dir);
}        

vold/blkdev.c

deleted100644 → 0
+0 −329
Original line number Diff line number Diff line

/*
 * 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 <stdlib.h>
#include <string.h>
#include <dirent.h>
#include <errno.h>
#include <fcntl.h>

#include <sys/types.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/mman.h>

#include <linux/fs.h>
#include <linux/msdos_fs.h>

#include "vold.h"
#include "blkdev.h"
#include "diskmbr.h"
#include "media.h"

#define DEBUG_BLKDEV 0

static blkdev_list_t *list_root = NULL;

static blkdev_t *_blkdev_create(blkdev_t *disk, char *devpath, int major,
                                int minor, char *type, struct media *media);

static int fat_valid_media(unsigned char media)
{                       
        return 0xf8 <= media || media == 0xf0;
}                               

char *blkdev_get_devpath(blkdev_t *blk)
{
    char *dp = malloc(256);
    sprintf(dp, "%s/vold/%d:%d", DEVPATH, blk->major, blk->minor);
    return dp;
}

int blkdev_refresh(blkdev_t *blk)
{
    int fd = 0;
    char *devpath = NULL;
    unsigned char *block = NULL;
    int i, rc;

    if (!(block = malloc(512)))
        goto out;

    /*
     * Get the device size
     */
    devpath = blkdev_get_devpath(blk);

    if ((fd = open(devpath, O_RDONLY)) < 0) {
        LOGE("Unable to open device '%s' (%s)", devpath, strerror(errno));
        return -errno;
    }

    if (ioctl(fd, BLKGETSIZE, &blk->nr_sec)) {
        LOGE("Unable to get device size (%s)", strerror(errno));
        return -errno;
    }
    close(fd);
    free(devpath);

    /*
     * Open the disk partition table
     */
    devpath = blkdev_get_devpath(blk->disk);
    if ((fd = open(devpath, O_RDONLY)) < 0) {
        LOGE("Unable to open device '%s' (%s)", devpath,
             strerror(errno));
        free(devpath);
        return -errno;
    }

    free(devpath);

    if ((rc = read(fd, block, 512)) != 512) {
        LOGE("Unable to read device partition table (%d, %s)",
             rc, strerror(errno));
        goto out;
    }

    /*
     * If we're a disk, then process the partition table. Otherwise we're
     * a partition so get the partition type
     */

    if (blk->type == blkdev_disk) {
        blk->nr_parts = 0;

        if ((block[0x1fe] != 0x55) || (block[0x1ff] != 0xAA)) {
            LOGI("Disk %d:%d does not contain a partition table",
                 blk->major, blk->minor);
            goto out;
        }

        for (i = 0; i < NDOSPART; i++) {
            struct dos_partition part;

            dos_partition_dec(block + DOSPARTOFF + i * sizeof(struct dos_partition), &part);
            if (part.dp_flag != 0 && part.dp_flag != 0x80) {
                struct fat_boot_sector *fb = (struct fat_boot_sector *) &block[0];
             
                if (!i && fb->reserved && fb->fats && fat_valid_media(fb->media)) {
                    LOGI("Detected FAT filesystem in partition table");
                    break;
                } else {
                    LOGI("Partition table looks corrupt");
                    break;
                }
            }
            if (part.dp_size != 0 && part.dp_typ != 0)
                blk->nr_parts++;
        }
    } else if (blk->type == blkdev_partition) {
        struct dos_partition part;
	int part_no;

        if (blk->media->media_type == media_mmc)
            part_no = blk->minor % MMC_PARTS_PER_CARD -1;
        else
            part_no = blk->minor -1;

        if (part_no < NDOSPART) {
            dos_partition_dec(block + DOSPARTOFF + part_no * sizeof(struct dos_partition), &part);
            blk->part_type = part.dp_typ;
        } else {
            LOGW("Skipping partition %d", part_no);
        }
    }

 out:

    if (block)
        free(block);

    char tmp[255];
    char tmp2[32];
    sprintf(tmp, "%s (blkdev %d:%d), %u secs (%u MB)",
                 (blk->type == blkdev_disk ? "Disk" : "Partition"),
                 blk->major, blk->minor,
                 blk->nr_sec,
                 (uint32_t) (((uint64_t) blk->nr_sec * 512) / 1024) / 1024);

    if (blk->type == blkdev_disk) 
        sprintf(tmp2, " %d partitions", blk->nr_parts);
    else
        sprintf(tmp2, " type 0x%x", blk->part_type);

    strcat(tmp, tmp2);
    LOGI(tmp);

    close(fd);

    return 0;
}

blkdev_t *blkdev_create(blkdev_t *disk, char *devpath, int major, int minor, struct media *media, char *type)
{
    return _blkdev_create(disk, devpath, major, minor, type, media);
}

static blkdev_t *_blkdev_create(blkdev_t *disk, char *devpath, int major,
                                int minor, char *type, struct media *media)
{
    blkdev_t *new;
    struct blkdev_list *list_entry;

    if (disk && disk->type != blkdev_disk) {
        LOGE("Non disk parent specified for blkdev!");
        return NULL;
    }

    if (!(new = malloc(sizeof(blkdev_t))))
        return NULL;

    memset(new, 0, sizeof(blkdev_t));

    if (!(list_entry = malloc(sizeof(struct blkdev_list)))) {
        free (new);
        return NULL;
    }
    list_entry->dev = new;
    list_entry->next = NULL;

    if (!list_root)
        list_root = list_entry;
    else {
        struct blkdev_list *list_scan = list_root;
        while (list_scan->next)
            list_scan = list_scan->next;
        list_scan->next = list_entry;
    }

    if (devpath)
        new->devpath = strdup(devpath);
    new->major = major;
    new->minor = minor;
    new->media = media;
    new->nr_sec = 0xffffffff;

    if (disk)
        new->disk = disk;
    else 
        new->disk = new; // Note the self disk pointer

    /* Create device nodes */
    char nodepath[255];
    mode_t mode = 0660 | S_IFBLK;
    dev_t dev = (major << 8) | minor;

    sprintf(nodepath, "%s/vold/%d:%d", DEVPATH, major, minor);
    if (mknod(nodepath, mode, dev) < 0) {
        LOGE("Error making device nodes for '%s' (%s)",
             nodepath, strerror(errno));
    }

    if (!strcmp(type, "disk"))
        new->type = blkdev_disk;
    else if (!strcmp(type, "partition"))
        new->type = blkdev_partition;
    else {
        LOGE("Unknown block device type '%s'", type);
        new->type = blkdev_unknown;
    }

    return new;
}

void blkdev_destroy(blkdev_t *blkdev)
{
    struct blkdev_list *list_next;

    if (list_root->dev == blkdev) {
        list_next = list_root->next;
        free (list_root);
        list_root = list_next;
    } else {
        struct blkdev_list *list_scan = list_root;
        while (list_scan->next->dev != blkdev)
            list_scan = list_scan -> next;
        list_next = list_scan->next->next;
        free(list_scan->next);
        list_scan->next = list_next;
    }

    if (blkdev->devpath)
        free(blkdev->devpath);

    char nodepath[255];
    sprintf(nodepath, "%s/vold/%d:%d", DEVPATH, blkdev->major, blkdev->minor);
    unlink(nodepath);

    free(blkdev);
}

blkdev_t *blkdev_lookup_by_path(char *devpath)
{
    struct blkdev_list *list_scan = list_root;

    while (list_scan) {
        if (!strcmp(list_scan->dev->devpath, devpath)) 
            return list_scan->dev;
        list_scan = list_scan->next;
    }
    return NULL;
}

blkdev_t *blkdev_lookup_by_devno(int maj, int min)
{
    struct blkdev_list *list_scan = list_root;

    while (list_scan) {
        if ((list_scan->dev->major == maj) &&
            (list_scan->dev->minor == min))
            return list_scan->dev;
        list_scan = list_scan->next;
    }
    return NULL;
}

/*
 * Given a disk device, return the number of partitions which 
 * have yet to be processed.
 */
int blkdev_get_num_pending_partitions(blkdev_t *blk)
{
    struct blkdev_list *list_scan = list_root;
    int num = blk->nr_parts;

    if (blk->type != blkdev_disk)
        return -EINVAL;

    while (list_scan) {
        if (list_scan->dev->type != blkdev_partition)
            goto next;

        if (list_scan->dev->major != blk->major)
            goto next;

        if (list_scan->dev->nr_sec != 0xffffffff &&
            list_scan->dev->devpath) {
            num--;
        }
 next:
        list_scan = list_scan->next;
    }
    return num;
}

vold/blkdev.h

deleted100644 → 0
+0 −64
Original line number Diff line number Diff line

/*
 * 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.
 */

#ifndef _BLKDEV_H
#define _BLKDEV_H

#include <sys/types.h>

struct media;

enum blk_type { blkdev_unknown, blkdev_disk, blkdev_partition };

struct blkdev {
    char          *devpath;
    enum blk_type type;
    struct media  *media;

    // If type == blkdev_disk then nr_parts = number of partitions
    int           nr_parts;

    // If type == blkdev_partition then part_type = partition type
    uint8_t       part_type;
    // If type == blkdev_partition
    struct blkdev *disk;

    unsigned int  nr_sec;

    int           major;
    int           minor;
};

struct blkdev_list {
    struct blkdev      *dev;
    struct blkdev_list *next;
};

typedef struct blkdev blkdev_t;
typedef struct blkdev_list blkdev_list_t;

blkdev_t *blkdev_create(blkdev_t *disk, char *devpath, int major, int minor, struct media *media, char *type);
blkdev_t *blkdev_create_pending_partition(blkdev_t *disk, char *dev_fspath, int major, int minor, struct media *media);
blkdev_t *blkdev_lookup_by_path(char *devpath);
blkdev_t *blkdev_lookup_by_devno(int maj, int min);
char *blkdev_get_devpath(blkdev_t *blk);

void blkdev_destroy(blkdev_t *blk);

int blkdev_get_num_pending_partitions(blkdev_t *blk);
int blkdev_refresh(blkdev_t *blk);
#endif

vold/cmd_dispatch.c

deleted100644 → 0
+0 −115
Original line number Diff line number Diff line

/*
 * 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 <unistd.h>
#include <errno.h>

#include "vold.h"
#include "cmd_dispatch.h"
#include "ums.h"
#include "volmgr.h"

struct cmd_dispatch {
    char *cmd;
    int (* dispatch) (char *);
};

static void dispatch_cmd(char *cmd);
static int do_send_ums_status(char *cmd);
static int do_set_ums_enable(char *cmd);
static int do_mount_volume(char *cmd);
static int do_eject_media(char *cmd);
static int do_format_media(char *cmd);

static struct cmd_dispatch dispatch_table[] = {
    { VOLD_CMD_ENABLE_UMS,      do_set_ums_enable },
    { VOLD_CMD_DISABLE_UMS,     do_set_ums_enable },
    { VOLD_CMD_SEND_UMS_STATUS, do_send_ums_status },
    { VOLD_CMD_MOUNT_VOLUME,    do_mount_volume },
    { VOLD_CMD_EJECT_MEDIA,     do_eject_media },
    { VOLD_CMD_FORMAT_MEDIA,    do_format_media },
    { NULL, NULL }
};

int process_framework_command(int socket)
{
    int rc;
    char buffer[101];

    if ((rc = read(socket, buffer, sizeof(buffer) -1)) < 0) {
        LOGE("Unable to read framework command (%s)", strerror(errno));
        return -errno;
    } else if (!rc)
        return -ECONNRESET;

    int start = 0;
    int i;

    buffer[rc] = 0;

    for (i = 0; i < rc; i++) {
        if (buffer[i] == 0) {
            dispatch_cmd(buffer + start);
            start = i + 1;
        }
    }
    return 0;
}

static void dispatch_cmd(char *cmd)
{
    struct cmd_dispatch *c;

    LOG_VOL("dispatch_cmd(%s):", cmd);

    for (c = dispatch_table; c->cmd != NULL; c++) {
        if (!strncmp(c->cmd, cmd, strlen(c->cmd))) {
            c->dispatch(cmd);
            return;
        }
    }

    LOGE("No cmd handlers defined for '%s'", cmd);
}

static int do_send_ums_status(char *cmd)
{
    return ums_send_status();
}

static int do_set_ums_enable(char *cmd)
{
    if (!strcmp(cmd, VOLD_CMD_ENABLE_UMS))
        return volmgr_enable_ums(true);

    return volmgr_enable_ums(false);
}

static int do_mount_volume(char *cmd)
{
    return volmgr_start_volume_by_mountpoint(&cmd[strlen("mount_volume:")]);
}

static int do_format_media(char *cmd)
{
    return volmgr_format_volume(&cmd[strlen("format_media:")]);
}

static int do_eject_media(char *cmd)
{
    return volmgr_stop_volume_by_mountpoint(&cmd[strlen("eject_media:")]);
}
Loading