Merge commit 'remotes/korg/cupcake' into merge
Conflicts: init/devices.c libpixelflinger/Android.mk
This commit is contained in:
commit
83b65486be
58 changed files with 2294 additions and 879 deletions
19
adb/adb.c
19
adb/adb.c
|
|
@ -859,8 +859,20 @@ int adb_main(int is_daemon)
|
|||
property_get("ro.kernel.qemu", value, "");
|
||||
if (strcmp(value, "1") != 0) {
|
||||
property_get("ro.secure", value, "");
|
||||
if (strcmp(value, "1") == 0)
|
||||
if (strcmp(value, "1") == 0) {
|
||||
// don't run as root if ro.secure is set...
|
||||
secure = 1;
|
||||
|
||||
// ... except we allow running as root in userdebug builds if the
|
||||
// service.adb.root property has been set by the "adb root" command
|
||||
property_get("ro.debuggable", value, "");
|
||||
if (strcmp(value, "1") == 0) {
|
||||
property_get("service.adb.root", value, "");
|
||||
if (strcmp(value, "1") == 0) {
|
||||
secure = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* don't listen on port 5037 if we are running in secure mode */
|
||||
|
|
@ -872,8 +884,10 @@ int adb_main(int is_daemon)
|
|||
** AID_INPUT to diagnose input issues (getevent)
|
||||
** AID_INET to diagnose network issues (netcfg, ping)
|
||||
** AID_GRAPHICS to access the frame buffer
|
||||
** AID_NET_BT and AID_NET_BT_ADMIN to diagnose bluetooth (hcidump)
|
||||
*/
|
||||
gid_t groups[] = { AID_ADB, AID_LOG, AID_INPUT, AID_INET, AID_GRAPHICS };
|
||||
gid_t groups[] = { AID_ADB, AID_LOG, AID_INPUT, AID_INET, AID_GRAPHICS,
|
||||
AID_NET_BT, AID_NET_BT_ADMIN };
|
||||
setgroups(sizeof(groups)/sizeof(groups[0]), groups);
|
||||
|
||||
/* then switch user and group to "shell" */
|
||||
|
|
@ -1080,4 +1094,3 @@ int main(int argc, char **argv)
|
|||
return adb_main(0);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -147,6 +147,7 @@ void help()
|
|||
" adb get-serialno - prints: <serial-number>\n"
|
||||
" adb status-window - continuously print device status for a specified device\n"
|
||||
" adb remount - remounts the /system partition on the device read-write\n"
|
||||
" adb root - restarts adb with root permissions\n"
|
||||
"\n"
|
||||
"networking:\n"
|
||||
" adb ppp <tty> [parameters] - Run PPP over USB.\n"
|
||||
|
|
@ -914,6 +915,17 @@ top:
|
|||
return 1;
|
||||
}
|
||||
|
||||
if(!strcmp(argv[0], "root")) {
|
||||
int fd = adb_connect("root:");
|
||||
if(fd >= 0) {
|
||||
read_and_dump(fd);
|
||||
adb_close(fd);
|
||||
return 0;
|
||||
}
|
||||
fprintf(stderr,"error: %s\n", adb_error());
|
||||
return 1;
|
||||
}
|
||||
|
||||
if(!strcmp(argv[0], "bugreport")) {
|
||||
if (argc != 1) {
|
||||
return 1;
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@
|
|||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <sys/socket.h>
|
||||
#include <utils/logger.h>
|
||||
#include <cutils/logger.h>
|
||||
#include "sysdeps.h"
|
||||
#include "adb.h"
|
||||
|
||||
|
|
|
|||
|
|
@ -103,6 +103,34 @@ static void recover_service(int s, void *cookie)
|
|||
adb_close(fd);
|
||||
}
|
||||
|
||||
void restart_root_service(int fd, void *cookie)
|
||||
{
|
||||
char buf[100];
|
||||
char value[PROPERTY_VALUE_MAX];
|
||||
|
||||
if (getuid() == 0) {
|
||||
snprintf(buf, sizeof(buf), "adbd is already running as root\n");
|
||||
writex(fd, buf, strlen(buf));
|
||||
adb_close(fd);
|
||||
} else {
|
||||
property_get("ro.debuggable", value, "");
|
||||
if (strcmp(value, "1") != 0) {
|
||||
snprintf(buf, sizeof(buf), "adbd cannot run as root in production builds\n");
|
||||
writex(fd, buf, strlen(buf));
|
||||
return;
|
||||
}
|
||||
|
||||
property_set("service.adb.root", "1");
|
||||
snprintf(buf, sizeof(buf), "restarting adbd as root\n");
|
||||
writex(fd, buf, strlen(buf));
|
||||
adb_close(fd);
|
||||
|
||||
// quit, and init will restart us as root
|
||||
sleep(1);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
|
|
@ -289,6 +317,8 @@ int service_to_fd(const char *name)
|
|||
ret = create_service_thread(file_sync_service, NULL);
|
||||
} else if(!strncmp(name, "remount:", 8)) {
|
||||
ret = create_service_thread(remount_service, NULL);
|
||||
} else if(!strncmp(name, "root:", 5)) {
|
||||
ret = create_service_thread(restart_root_service, NULL);
|
||||
#endif
|
||||
#if 0
|
||||
} else if(!strncmp(name, "echo:", 5)){
|
||||
|
|
|
|||
|
|
@ -292,7 +292,8 @@ static int find_usb_device(const char *base,
|
|||
}
|
||||
}
|
||||
|
||||
register_device_callback(devname, local_ep_in, local_ep_out, i, serial, zero_mask);
|
||||
register_device_callback(devname, local_ep_in, local_ep_out,
|
||||
interface->bInterfaceNumber, serial, zero_mask);
|
||||
|
||||
found_device = 1;
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -195,7 +195,7 @@ void usage(void)
|
|||
"\n"
|
||||
"commands:\n"
|
||||
" update <filename> reflash device from update.zip\n"
|
||||
" flashall 'flash boot' + 'flash system'\n"
|
||||
" flashall flash boot + recovery + system\n"
|
||||
" flash <partition> [ <filename> ] write a file to a flash partition\n"
|
||||
" erase <partition> erase a flash partition\n"
|
||||
" getvar <variable> display a bootloader variable\n"
|
||||
|
|
@ -588,6 +588,9 @@ int main(int argc, char **argv)
|
|||
} else if(!strcmp(*argv, "reboot-bootloader")) {
|
||||
wants_reboot_bootloader = 1;
|
||||
skip(1);
|
||||
} else if (!strcmp(*argv, "continue")) {
|
||||
fb_queue_command("continue", "resuming boot");
|
||||
skip(1);
|
||||
} else if(!strcmp(*argv, "boot")) {
|
||||
char *kname = 0;
|
||||
char *rname = 0;
|
||||
|
|
|
|||
46
include/cutils/logger.h
Normal file
46
include/cutils/logger.h
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
/* utils/logger.h
|
||||
**
|
||||
** Copyright 2007, The Android Open Source Project
|
||||
**
|
||||
** This file is dual licensed. It may be redistributed and/or modified
|
||||
** under the terms of the Apache 2.0 License OR version 2 of the GNU
|
||||
** General Public License.
|
||||
*/
|
||||
|
||||
#ifndef _UTILS_LOGGER_H
|
||||
#define _UTILS_LOGGER_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
struct logger_entry {
|
||||
uint16_t len; /* length of the payload */
|
||||
uint16_t __pad; /* no matter what, we get 2 bytes of padding */
|
||||
int32_t pid; /* generating process's pid */
|
||||
int32_t tid; /* generating process's tid */
|
||||
int32_t sec; /* seconds since Epoch */
|
||||
int32_t nsec; /* nanoseconds */
|
||||
char msg[0]; /* the entry's payload */
|
||||
};
|
||||
|
||||
#define LOGGER_LOG_MAIN "log/main"
|
||||
#define LOGGER_LOG_RADIO "log/radio"
|
||||
#define LOGGER_LOG_EVENTS "log/events"
|
||||
|
||||
#define LOGGER_ENTRY_MAX_LEN (4*1024)
|
||||
#define LOGGER_ENTRY_MAX_PAYLOAD \
|
||||
(LOGGER_ENTRY_MAX_LEN - sizeof(struct logger_entry))
|
||||
|
||||
#ifdef HAVE_IOCTL
|
||||
|
||||
#include <sys/ioctl.h>
|
||||
|
||||
#define __LOGGERIO 0xAE
|
||||
|
||||
#define LOGGER_GET_LOG_BUF_SIZE _IO(__LOGGERIO, 1) /* size of log */
|
||||
#define LOGGER_GET_LOG_LEN _IO(__LOGGERIO, 2) /* used log len */
|
||||
#define LOGGER_GET_NEXT_ENTRY_LEN _IO(__LOGGERIO, 3) /* next entry len */
|
||||
#define LOGGER_FLUSH_LOG _IO(__LOGGERIO, 4) /* flush log */
|
||||
|
||||
#endif // HAVE_IOCTL
|
||||
|
||||
#endif /* _UTILS_LOGGER_H */
|
||||
|
|
@ -17,8 +17,8 @@
|
|||
#ifndef _LOGPRINT_H
|
||||
#define _LOGPRINT_H
|
||||
|
||||
#include <utils/Log.h>
|
||||
#include <utils/logger.h>
|
||||
#include <cutils/log.h>
|
||||
#include <cutils/logger.h>
|
||||
#include <cutils/event_tag_map.h>
|
||||
#include <pthread.h>
|
||||
|
||||
|
|
|
|||
|
|
@ -42,8 +42,10 @@ enum GGLPixelFormat {
|
|||
// YCbCr formats (SP=semi-planar, P=planar)
|
||||
GGL_PIXEL_FORMAT_YCbCr_422_SP= 0x10,
|
||||
GGL_PIXEL_FORMAT_YCbCr_420_SP= 0x11,
|
||||
GGL_PIXEL_FORMAT_YCbCr_422_P = 0x14,
|
||||
GGL_PIXEL_FORMAT_YCbCr_420_P = 0x15,
|
||||
GGL_PIXEL_FORMAT_YCbCr_422_P = 0x12,
|
||||
GGL_PIXEL_FORMAT_YCbCr_420_P = 0x13,
|
||||
GGL_PIXEL_FORMAT_YCbCr_422_I = 0x14,
|
||||
GGL_PIXEL_FORMAT_YCbCr_420_I = 0x15,
|
||||
|
||||
// reserved/special formats
|
||||
GGL_PIXEL_FORMAT_Z_16 = 0x18,
|
||||
|
|
@ -60,7 +62,10 @@ enum GGLFormatComponents {
|
|||
GGL_RGBA = 0x1908,
|
||||
GGL_LUMINANCE = 0x1909,
|
||||
GGL_LUMINANCE_ALPHA = 0x190A,
|
||||
GGL_Y_CB_CR = 0x8000,
|
||||
GGL_Y_CB_CR_SP = 0x8000,
|
||||
GGL_Y_CB_CR = GGL_Y_CB_CR_SP,
|
||||
GGL_Y_CB_CR_P = 0x8001,
|
||||
GGL_Y_CB_CR_I = 0x8002,
|
||||
};
|
||||
|
||||
enum GGLFormatComponentIndex {
|
||||
|
|
|
|||
|
|
@ -123,14 +123,13 @@ static struct perms_ devperms[] = {
|
|||
{ "/dev/msm_pcm_ctl", 0660, AID_SYSTEM, AID_AUDIO, 1 },
|
||||
{ "/dev/msm_snd", 0660, AID_SYSTEM, AID_AUDIO, 1 },
|
||||
{ "/dev/msm_mp3", 0660, AID_SYSTEM, AID_AUDIO, 1 },
|
||||
{ "/dev/msm_snd", 0660, AID_SYSTEM, AID_AUDIO, 1 },
|
||||
{ "/dev/msm_audpre", 0660, AID_SYSTEM, AID_AUDIO, 0 },
|
||||
{ "/dev/htc-acoustic", 0660, AID_SYSTEM, AID_AUDIO, 0 },
|
||||
{ "/dev/smd0", 0640, AID_RADIO, AID_RADIO, 0 },
|
||||
{ "/dev/qmi", 0640, AID_RADIO, AID_RADIO, 0 },
|
||||
{ "/dev/qmi0", 0640, AID_RADIO, AID_RADIO, 0 },
|
||||
{ "/dev/qmi1", 0640, AID_RADIO, AID_RADIO, 0 },
|
||||
{ "/dev/qmi2", 0640, AID_RADIO, AID_RADIO, 0 },
|
||||
{ "/dev/htc-acoustic", 0640, AID_RADIO, AID_RADIO, 0 },
|
||||
{ "/dev/snd/", 0664, AID_SYSTEM, AID_AUDIO, 1 },
|
||||
{ NULL, 0, 0, 0, 0 },
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -69,6 +69,7 @@ struct {
|
|||
{ "dhcp.", AID_DHCP },
|
||||
{ "debug.", AID_SHELL },
|
||||
{ "log.", AID_SHELL },
|
||||
{ "service.adb.root", AID_SHELL },
|
||||
{ "persist.sys.", AID_SYSTEM },
|
||||
{ "persist.service.", AID_SYSTEM },
|
||||
{ NULL, 0 }
|
||||
|
|
|
|||
|
|
@ -18,8 +18,10 @@
|
|||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <limits.h>
|
||||
|
||||
#define INITIAL_CAPACITY (4)
|
||||
#define MAX_CAPACITY ((int)(UINT_MAX/sizeof(void*)))
|
||||
|
||||
struct Array {
|
||||
void** contents;
|
||||
|
|
@ -45,13 +47,26 @@ void arrayFree(Array* array) {
|
|||
static int ensureCapacity(Array* array, int capacity) {
|
||||
int oldCapacity = array->capacity;
|
||||
if (capacity > oldCapacity) {
|
||||
int newCapacity = (oldCapacity == 0) ? INITIAL_CAPACITY : oldCapacity * 2;
|
||||
|
||||
// Keep doubling capacity until we surpass necessary capacity.
|
||||
int newCapacity = (oldCapacity == 0) ? INITIAL_CAPACITY : oldCapacity;
|
||||
|
||||
// Ensure we're not doing something nasty
|
||||
if (capacity > MAX_CAPACITY)
|
||||
return -1;
|
||||
|
||||
// Keep doubling capacity until we surpass necessary capacity.
|
||||
while (newCapacity < capacity) {
|
||||
newCapacity *= 2;
|
||||
int newCap = newCapacity*2;
|
||||
// Handle integer overflows
|
||||
if (newCap < newCapacity || newCap > MAX_CAPACITY) {
|
||||
newCap = MAX_CAPACITY;
|
||||
}
|
||||
newCapacity = newCap;
|
||||
}
|
||||
|
||||
|
||||
// Should not happen, but better be safe than sorry
|
||||
if (newCapacity < 0 || newCapacity > MAX_CAPACITY)
|
||||
return -1;
|
||||
|
||||
void** newContents;
|
||||
if (array->contents == NULL) {
|
||||
// Allocate new array.
|
||||
|
|
@ -151,5 +166,5 @@ int arraySize(Array* array) {
|
|||
}
|
||||
|
||||
const void** arrayUnwrap(Array* array) {
|
||||
return array->contents;
|
||||
return (const void**)array->contents;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@
|
|||
#include <cutils/jstring.h>
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include <limits.h>
|
||||
|
||||
/* See http://www.unicode.org/reports/tr22/ for discussion
|
||||
* on invalid sequences
|
||||
|
|
@ -48,6 +49,10 @@ extern char16_t * strdup8to16 (const char* s, size_t *out_len)
|
|||
|
||||
len = strlen8to16(s);
|
||||
|
||||
// fail on overflow
|
||||
if (len && SIZE_MAX/len < sizeof(char16_t))
|
||||
return NULL;
|
||||
|
||||
// no plus-one here. UTF-16 strings are not null terminated
|
||||
ret = (char16_t *) malloc (sizeof(char16_t) * len);
|
||||
|
||||
|
|
|
|||
|
|
@ -438,31 +438,38 @@ static void showLog(LogState *state,
|
|||
if (*p++ == '\n') numLines++;
|
||||
}
|
||||
if (p > msg && *(p-1) != '\n') numLines++;
|
||||
|
||||
|
||||
/*
|
||||
* Create an array of iovecs large enough to write all of
|
||||
* the lines with a prefix and a suffix.
|
||||
*/
|
||||
const size_t INLINE_VECS = 6;
|
||||
const size_t MAX_LINES = ((size_t)~0)/(3*sizeof(struct iovec*));
|
||||
struct iovec stackVec[INLINE_VECS];
|
||||
struct iovec* vec = stackVec;
|
||||
|
||||
numLines *= 3; // 3 iovecs per line.
|
||||
if (numLines > INLINE_VECS) {
|
||||
size_t numVecs;
|
||||
|
||||
if (numLines > MAX_LINES)
|
||||
numLines = MAX_LINES;
|
||||
|
||||
numVecs = numLines*3; // 3 iovecs per line.
|
||||
if (numVecs > INLINE_VECS) {
|
||||
vec = (struct iovec*)malloc(sizeof(struct iovec)*numLines);
|
||||
if (vec == NULL) {
|
||||
msg = "LOG: write failed, no memory";
|
||||
numLines = 3;
|
||||
numVecs = 3;
|
||||
numLines = 1;
|
||||
vec = stackVec;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Fill in the iovec pointers.
|
||||
*/
|
||||
p = msg;
|
||||
struct iovec* v = vec;
|
||||
int totalLen = 0;
|
||||
while (p < end) {
|
||||
while (numLines > 0 && p < end) {
|
||||
if (prefixLen > 0) {
|
||||
v->iov_base = prefixBuf;
|
||||
v->iov_len = prefixLen;
|
||||
|
|
@ -484,6 +491,7 @@ static void showLog(LogState *state,
|
|||
totalLen += suffixLen;
|
||||
v++;
|
||||
}
|
||||
numLines -= 1;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@
|
|||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#include <utils/logger.h>
|
||||
#include <cutils/logger.h>
|
||||
#include <cutils/logd.h>
|
||||
|
||||
#define LOG_BUF_SIZE 1024
|
||||
|
|
|
|||
|
|
@ -170,14 +170,19 @@ int dhcp_do_request(const char *interface,
|
|||
*/
|
||||
int dhcp_stop(const char *interface)
|
||||
{
|
||||
char result_prop_name[PROPERTY_KEY_MAX];
|
||||
const char *ctrl_prop = "ctl.stop";
|
||||
const char *desired_status = "stopped";
|
||||
|
||||
snprintf(result_prop_name, sizeof(result_prop_name), "%s.%s.result",
|
||||
DHCP_PROP_NAME_PREFIX,
|
||||
interface);
|
||||
/* Stop the daemon and wait until it's reported to be stopped */
|
||||
property_set(ctrl_prop, DAEMON_NAME);
|
||||
if (wait_for_property(DAEMON_PROP_NAME, desired_status, 5) < 0) {
|
||||
return -1;
|
||||
}
|
||||
property_set(result_prop_name, "failed");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -48,9 +48,7 @@ ifeq ($(TARGET_ARCH),arm)
|
|||
PIXELFLINGER_CFLAGS += -fstrict-aliasing -fomit-frame-pointer
|
||||
endif
|
||||
|
||||
LOCAL_SHARED_LIBRARIES := \
|
||||
libhardware_legacy \
|
||||
libcutils
|
||||
LOCAL_SHARED_LIBRARIES := libcutils
|
||||
|
||||
ifneq ($(TARGET_ARCH),arm)
|
||||
# Required to define logging functions on the simulator.
|
||||
|
|
@ -68,11 +66,9 @@ LOCAL_SRC_FILES := $(PIXELFLINGER_SRC_FILES)
|
|||
LOCAL_CFLAGS := $(PIXELFLINGER_CFLAGS)
|
||||
|
||||
ifneq ($(BUILD_TINY_ANDROID),true)
|
||||
# this is for some qemu-tracing cruft, which
|
||||
# 1. should not depend on libhardware
|
||||
# 2. should not be build except in emulator builds
|
||||
# but this at least stops it from breaking the tiny android build
|
||||
LOCAL_SHARED_LIBRARIES += libhardware
|
||||
# Really this should go away entirely or at least not depend on
|
||||
# libhardware, but this at least gets us built.
|
||||
LOCAL_SHARED_LIBRARIES += libhardware_legacy
|
||||
LOCAL_CFLAGS += -DWITH_LIB_HARDWARE
|
||||
endif
|
||||
|
||||
|
|
|
|||
|
|
@ -40,12 +40,12 @@ static GGLFormat const gPixelFormatInfos[] =
|
|||
{ 0, 0, {{ 0, 0, 0, 0, 0, 0, 0, 0 }}, 0 }, // PIXEL_FORMAT_NONE
|
||||
{ 0, 0, {{ 0, 0, 0, 0, 0, 0, 0, 0 }}, 0 }, // PIXEL_FORMAT_NONE
|
||||
|
||||
{ 1, 16, {{ 0, 8, 0, 8, 0, 8, 0, 0 }}, GGL_Y_CB_CR },// PIXEL_FORMAT_YCbCr_422_SP
|
||||
{ 1, 12, {{ 0, 8, 0, 8, 0, 8, 0, 0 }}, GGL_Y_CB_CR },// PIXEL_FORMAT_YCbCr_420_SP
|
||||
{ 0, 0, {{ 0, 0, 0, 0, 0, 0, 0, 0 }}, 0 }, // PIXEL_FORMAT_NONE
|
||||
{ 0, 0, {{ 0, 0, 0, 0, 0, 0, 0, 0 }}, 0 }, // PIXEL_FORMAT_NONE
|
||||
{ 0, 0, {{ 0, 0, 0, 0, 0, 0, 0, 0 }}, 0 }, // PIXEL_FORMAT_NONE
|
||||
{ 0, 0, {{ 0, 0, 0, 0, 0, 0, 0, 0 }}, 0 }, // PIXEL_FORMAT_NONE
|
||||
{ 1, 16, {{ 0, 8, 0, 8, 0, 8, 0, 0 }}, GGL_Y_CB_CR_SP },// PIXEL_FORMAT_YCbCr_422_SP
|
||||
{ 1, 12, {{ 0, 8, 0, 8, 0, 8, 0, 0 }}, GGL_Y_CB_CR_SP },// PIXEL_FORMAT_YCbCr_420_SP
|
||||
{ 1, 16, {{ 0, 8, 0, 8, 0, 8, 0, 0 }}, GGL_Y_CB_CR_P }, // PIXEL_FORMAT_YCbCr_422_P
|
||||
{ 1, 12, {{ 0, 8, 0, 8, 0, 8, 0, 0 }}, GGL_Y_CB_CR_P }, // PIXEL_FORMAT_YCbCr_420_P
|
||||
{ 1, 16, {{ 0, 8, 0, 8, 0, 8, 0, 0 }}, GGL_Y_CB_CR_I }, // PIXEL_FORMAT_YCbCr_422_I
|
||||
{ 1, 12, {{ 0, 8, 0, 8, 0, 8, 0, 0 }}, GGL_Y_CB_CR_I }, // PIXEL_FORMAT_YCbCr_420_I
|
||||
{ 0, 0, {{ 0, 0, 0, 0, 0, 0, 0, 0 }}, 0 }, // PIXEL_FORMAT_NONE
|
||||
{ 0, 0, {{ 0, 0, 0, 0, 0, 0, 0, 0 }}, 0 }, // PIXEL_FORMAT_NONE
|
||||
|
||||
|
|
|
|||
|
|
@ -1256,7 +1256,7 @@ finish:
|
|||
void scanline_t32cb16(context_t* c)
|
||||
{
|
||||
int32_t x = c->iterators.xl;
|
||||
size_t ct = c->iterators.xr - x;
|
||||
size_t ct = c->iterators.xr - x;
|
||||
int32_t y = c->iterators.y;
|
||||
surface_t* cb = &(c->state.buffers.color);
|
||||
union {
|
||||
|
|
@ -1282,7 +1282,7 @@ last_one:
|
|||
ct--;
|
||||
}
|
||||
|
||||
while (ct > 0) {
|
||||
while (ct >= 2) {
|
||||
s = GGL_RGBA_TO_HOST( *src++ );
|
||||
sR = (s >> ( 3))&0x1F;
|
||||
sG = (s >> ( 8+2))&0x3F;
|
||||
|
|
|
|||
|
|
@ -16,8 +16,6 @@ include $(CLEAR_VARS)
|
|||
|
||||
LOCAL_MODULE := event-log-tags
|
||||
|
||||
#LOCAL_MODULE_TAGS := user development
|
||||
|
||||
# This will install the file in /system/etc
|
||||
#
|
||||
LOCAL_MODULE_CLASS := ETC
|
||||
|
|
|
|||
|
|
@ -58,6 +58,9 @@
|
|||
# This is logged when the partial wake lock (keeping the device awake
|
||||
# regardless of whether the screen is off) is acquired or released.
|
||||
2729 power_partial_wake_state (releasedorAcquired|1|5),(tag|3)
|
||||
# This is logged when battery goes from discharging to charging.
|
||||
# It lets us count the total amount of time between charges and the discharge level
|
||||
2730 battery_discharge (duration|2|3),(minLevel|1|6),(maxLevel|1|6)
|
||||
#
|
||||
# Leave IDs through 2739 for more power logs
|
||||
#
|
||||
|
|
@ -188,10 +191,23 @@
|
|||
30030 am_create_service (Service Record|1|5),(Name|3),(Intent|3),(PID|1|5)
|
||||
# A service is being destroyed
|
||||
30031 am_destroy_service (Service Record|1|5),(Name|3),(PID|1|5)
|
||||
# A process has crashed too many times, it is being cleared
|
||||
30032 am_process_crashed_too_much (Name|3),(PID|1|5)
|
||||
# An unknown process is trying to attach to the activity manager
|
||||
30033 am_drop_process (PID|1|5)
|
||||
# A service has crashed too many times, it is being stopped
|
||||
30034 am_service_crashed_too_much (Crash Count|1|1),(Component Name|3),(PID|1|5)
|
||||
# A service is going to be restarted after its process went away
|
||||
30035 am_schedule_service_restart (Component Name|3),(Time|2|3)
|
||||
# A client was waiting for a content provider, but its process was lost
|
||||
30036 am_provider_lost_process (Package Name|3),(UID|1|5),(Name|3)
|
||||
|
||||
# Out of memory for surfaces.
|
||||
31000 wm_no_surface_memory (Window|3),(PID|1|5),(Operation|3)
|
||||
|
||||
# Re-connecting to input method service because we haven't received its interface
|
||||
32000 imf_force_reconnect_ime (IME|4),(Time Since Connect|2|3),(Showing|1|1)
|
||||
|
||||
# dvm_gc_info: LIST (LONG, LONG, LONG)
|
||||
#
|
||||
# First LONG:
|
||||
|
|
@ -295,19 +311,28 @@
|
|||
# PDP Setup failures
|
||||
50105 pdp_setup_fail (cause|1|5), (cid|1|5), (network_type|1|5)
|
||||
|
||||
# Call drops
|
||||
# Call drops
|
||||
50106 call_drop (cause|1|5), (cid|1|5), (network_type|1|5)
|
||||
|
||||
# Data network registration failed after successful voice registration
|
||||
50107 data_network_registration_fail (op_numeric|1|5), (cid|1|5)
|
||||
|
||||
# Suspicious status of data connection while radio poweroff
|
||||
# Suspicious status of data connection while radio poweroff
|
||||
50108 data_network_status_on_radio_off (dc_state|3), (enable|1|5)
|
||||
|
||||
# PDP drop caused by network
|
||||
50109 pdp_network_drop (cid|1|5), (network_type|1|5)
|
||||
|
||||
# Do not change these names without updating tag in:
|
||||
#//device/dalvik/libcore/luni/src/main/native/org_apache_harmony_luni_platform_OSNetworkSystem.c
|
||||
51000 socket_stats (send|1|2),(recv|1|2),(ip|1|5),(port|1|5),(close|1|5)
|
||||
|
||||
# db stats. 0 is query, 1 is write (may become more fine grained in the
|
||||
# future)
|
||||
52000 db_operation (name|3),(op_type|1|5),(time|2|3)
|
||||
|
||||
# http request/response stats
|
||||
52001 http_stats (useragent|3),(response|2|3),(processing|2|3),(tx|1|2),(rx|1|2)
|
||||
60000 viewroot_draw (Draw time|1|3)
|
||||
60001 viewroot_layout (Layout time|1|3)
|
||||
60002 view_build_drawing_cache (View created drawing cache|1|5)
|
||||
|
|
@ -315,3 +340,7 @@
|
|||
|
||||
# 0 for screen off, 1 for screen on, 2 for key-guard done
|
||||
70000 screen_toggled (screen_state|1|5)
|
||||
|
||||
# browser stats for diary study
|
||||
70101 browser_zoom_level_change (start level|1|5),(end level|1|5),(time|2|3)
|
||||
70102 browser_double_tap_duration (duration|1|3),(time|2|3)
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
// Copyright 2006 The Android Open Source Project
|
||||
|
||||
#include <utils/misc.h>
|
||||
#include <utils/logger.h>
|
||||
#include <cutils/logger.h>
|
||||
#include <cutils/logd.h>
|
||||
#include <cutils/sockets.h>
|
||||
#include <cutils/logprint.h>
|
||||
|
|
|
|||
|
|
@ -18,4 +18,5 @@ LOCAL_CFLAGS := -DCREATE_MOUNT_POINTS=0
|
|||
|
||||
LOCAL_SHARED_LIBRARIES := libcutils
|
||||
|
||||
include $(BUILD_EXECUTABLE)
|
||||
# disabled - we are using vold now instead
|
||||
# include $(BUILD_EXECUTABLE)
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@ include $(CLEAR_VARS)
|
|||
# files that live under /system/etc/...
|
||||
|
||||
copy_from := \
|
||||
etc/mountd.conf \
|
||||
etc/dbus.conf \
|
||||
etc/init.goldfish.sh \
|
||||
etc/hosts
|
||||
|
|
|
|||
|
|
@ -87,11 +87,15 @@ on boot
|
|||
# set RLIMIT_NICE to allow priorities from 19 to -20
|
||||
setrlimit 13 40 40
|
||||
|
||||
# Set timeout value for rmnet stats.
|
||||
write /sys/devices/virtual/net/rmnet0/timeout_suspend 5000000
|
||||
|
||||
# Define the oom_adj values for the classes of processes that can be
|
||||
# killed by the kernel. These are used in ActivityManagerService.
|
||||
setprop ro.FOREGROUND_APP_ADJ 0
|
||||
setprop ro.VISIBLE_APP_ADJ 1
|
||||
setprop ro.SECONDARY_SERVER_ADJ 2
|
||||
setprop ro.HOME_APP_ADJ 4
|
||||
setprop ro.HIDDEN_APP_MIN_ADJ 7
|
||||
setprop ro.CONTENT_PROVIDER_ADJ 14
|
||||
setprop ro.EMPTY_APP_ADJ 15
|
||||
|
|
@ -101,14 +105,18 @@ on boot
|
|||
setprop ro.FOREGROUND_APP_MEM 1536
|
||||
setprop ro.VISIBLE_APP_MEM 2048
|
||||
setprop ro.SECONDARY_SERVER_MEM 4096
|
||||
setprop ro.HOME_APP_MEM 4096
|
||||
setprop ro.HIDDEN_APP_MEM 5120
|
||||
setprop ro.CONTENT_PROVIDER_MEM 5632
|
||||
setprop ro.EMPTY_APP_MEM 6144
|
||||
|
||||
# Write value must be consistent with the above properties.
|
||||
# Note that the driver only supports 6 slots, so we have HOME_APP at the
|
||||
# same memory level as services.
|
||||
write /sys/module/lowmemorykiller/parameters/adj 0,1,2,7,14,15
|
||||
|
||||
write /proc/sys/vm/overcommit_memory 1
|
||||
write /proc/sys/vm/min_free_order_shift 4
|
||||
write /sys/module/lowmemorykiller/parameters/minfree 1536,2048,4096,5120,5632,6144
|
||||
|
||||
# Set init its forked children's oom_adj.
|
||||
|
|
@ -187,8 +195,11 @@ service servicemanager /system/bin/servicemanager
|
|||
onrestart restart zygote
|
||||
onrestart restart media
|
||||
|
||||
service mountd /system/bin/mountd
|
||||
socket mountd stream 0660 root mount
|
||||
service vold /system/bin/vold
|
||||
socket vold stream 0660 root mount
|
||||
|
||||
#service mountd /system/bin/mountd
|
||||
# socket mountd stream 0660 root mount
|
||||
|
||||
service debuggerd /system/bin/debuggerd
|
||||
|
||||
|
|
@ -217,8 +228,8 @@ service dbus /system/bin/dbus-daemon --system --nofork
|
|||
user bluetooth
|
||||
group bluetooth net_bt_admin
|
||||
|
||||
#STOPSHIP: disable the verbose logging
|
||||
service hcid /system/bin/logwrapper /system/bin/hcid -d -s -n -f /etc/bluez/hcid.conf
|
||||
#STOPSHIP: dont use logwrapper in production
|
||||
service hcid /system/bin/logwrapper /system/bin/hcid -s -n -f /etc/bluez/hcid.conf
|
||||
socket bluetooth stream 660 bluetooth bluetooth
|
||||
socket dbus_bluetooth stream 660 bluetooth bluetooth
|
||||
# init.rc does not yet support applying capabilities, so run as root and
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@ TOOLS := \
|
|||
printenv \
|
||||
smd \
|
||||
chmod \
|
||||
chown \
|
||||
mkdosfs \
|
||||
netstat \
|
||||
ioctl \
|
||||
|
|
|
|||
62
toolbox/chown.c
Normal file
62
toolbox/chown.c
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <dirent.h>
|
||||
#include <errno.h>
|
||||
#include <pwd.h>
|
||||
#include <grp.h>
|
||||
|
||||
#include <unistd.h>
|
||||
#include <time.h>
|
||||
|
||||
int chown_main(int argc, char **argv)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (argc < 3) {
|
||||
fprintf(stderr, "Usage: chown <USER>[.GROUP] <FILE1> [FILE2] ...\n");
|
||||
return 10;
|
||||
}
|
||||
|
||||
// Copy argv[1] to 'user' so we can truncate it at the period
|
||||
// if a group id specified.
|
||||
char user[32];
|
||||
char *group = NULL;
|
||||
strncpy(user, argv[1], sizeof(user));
|
||||
if ((group = strchr(user, '.')) != NULL) {
|
||||
*group++ = '\0';
|
||||
}
|
||||
|
||||
// Lookup uid (and gid if specified)
|
||||
struct passwd *pw;
|
||||
struct group *grp = NULL;
|
||||
uid_t uid;
|
||||
gid_t gid = -1; // passing -1 to chown preserves current group
|
||||
|
||||
pw = getpwnam(user);
|
||||
if (pw == NULL) {
|
||||
fprintf(stderr, "No such user '%s'\n", user);
|
||||
return 10;
|
||||
}
|
||||
uid = pw->pw_uid;
|
||||
|
||||
if (group != NULL) {
|
||||
grp = getgrnam(group);
|
||||
if (grp == NULL) {
|
||||
fprintf(stderr, "No such group '%s'\n", group);
|
||||
return 10;
|
||||
}
|
||||
gid = grp->gr_gid;
|
||||
}
|
||||
|
||||
for (i = 2; i < argc; i++) {
|
||||
if (chown(argv[i], uid, gid) < 0) {
|
||||
fprintf(stderr, "Unable to chmod %s: %s\n", argv[i], strerror(errno));
|
||||
return 10;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -45,10 +45,12 @@ bail:
|
|||
return buffer;
|
||||
}
|
||||
|
||||
#define min(x,y) ((x) < (y) ? (x) : (y))
|
||||
int insmod_main(int argc, char **argv)
|
||||
{
|
||||
void *file;
|
||||
ssize_t size;
|
||||
ssize_t size = 0;
|
||||
char opts[1024];
|
||||
int ret;
|
||||
|
||||
/* make sure we've got an argument */
|
||||
|
|
@ -64,9 +66,24 @@ int insmod_main(int argc, char **argv)
|
|||
return -1;
|
||||
}
|
||||
|
||||
opts[0] = '\0';
|
||||
if (argc > 2) {
|
||||
int i, len;
|
||||
char *end = opts + sizeof(opts) - 1;
|
||||
char *ptr = opts;
|
||||
|
||||
for (i = 2; (i < argc) && (ptr < end); i++) {
|
||||
len = min(strlen(argv[i]), end - ptr);
|
||||
memcpy(ptr, argv[i], len);
|
||||
ptr += len;
|
||||
*ptr++ = ' ';
|
||||
*ptr++ = '\0';
|
||||
}
|
||||
*(ptr - 1) = '\0';
|
||||
}
|
||||
|
||||
/* pass it to the kernel */
|
||||
/* XXX options */
|
||||
ret = init_module(file, size, "");
|
||||
ret = init_module(file, size, opts);
|
||||
if (ret != 0) {
|
||||
fprintf(stderr,
|
||||
"insmod: init_module '%s' failed (%s)\n",
|
||||
|
|
|
|||
|
|
@ -387,9 +387,8 @@ mkdosfs_main(int argc, char *argv[])
|
|||
exit(1);
|
||||
}
|
||||
|
||||
lseek(fd1, 0, SEEK_SET);
|
||||
off_t length = lseek(fd1, 0, SEEK_END);
|
||||
fprintf(stderr, "lseek returned %ld\n", length);
|
||||
lseek64(fd1, 0, SEEK_SET);
|
||||
loff_t length = lseek64(fd1, 0, SEEK_END);
|
||||
if (length > 0) {
|
||||
bpb.bsec = length / bpb.bps;
|
||||
bpb.spt = bpb.bsec;
|
||||
|
|
@ -615,8 +614,8 @@ mkdosfs_main(int argc, char *argv[])
|
|||
fat == 32 && bpb.bkbs != MAXU16 &&
|
||||
bss <= bpb.bkbs && x >= bpb.bkbs) {
|
||||
x -= bpb.bkbs;
|
||||
if (!x && lseek(fd1, 0, SEEK_SET))
|
||||
fprintf(stderr, "lseek failed for %s\n", bname);
|
||||
if (!x && lseek64(fd1, 0, SEEK_SET))
|
||||
fprintf(stderr, "lseek64 failed for %s\n", bname);
|
||||
}
|
||||
if (opt_B && x < bss) {
|
||||
if ((n = read(fd1, img, bpb.bps)) == -1)
|
||||
|
|
|
|||
|
|
@ -41,15 +41,20 @@
|
|||
|
||||
struct cpu_info {
|
||||
long unsigned utime, ntime, stime, itime;
|
||||
long unsigned iowtime, irqtime, sirqtime;
|
||||
};
|
||||
|
||||
#define PROC_NAME_LEN 64
|
||||
#define THREAD_NAME_LEN 32
|
||||
|
||||
struct proc_info {
|
||||
struct proc_info *next;
|
||||
pid_t pid;
|
||||
pid_t tid;
|
||||
uid_t uid;
|
||||
gid_t gid;
|
||||
char name[256];
|
||||
char name[PROC_NAME_LEN];
|
||||
char tname[THREAD_NAME_LEN];
|
||||
char state;
|
||||
long unsigned utime;
|
||||
long unsigned stime;
|
||||
|
|
@ -69,7 +74,7 @@ struct proc_list {
|
|||
#define die(...) { fprintf(stderr, __VA_ARGS__); exit(EXIT_FAILURE); }
|
||||
|
||||
#define INIT_PROCS 50
|
||||
#define THREAD_MULT 4
|
||||
#define THREAD_MULT 8
|
||||
static struct proc_info **old_procs, **new_procs;
|
||||
static int num_old_procs, num_new_procs;
|
||||
static struct proc_info *free_procs;
|
||||
|
|
@ -228,7 +233,8 @@ static void read_procs(void) {
|
|||
|
||||
file = fopen("/proc/stat", "r");
|
||||
if (!file) die("Could not open /proc/stat.\n");
|
||||
fscanf(file, "cpu %lu %lu %lu %lu", &new_cpu.utime, &new_cpu.ntime, &new_cpu.stime, &new_cpu.itime);
|
||||
fscanf(file, "cpu %lu %lu %lu %lu %lu %lu %lu", &new_cpu.utime, &new_cpu.ntime, &new_cpu.stime,
|
||||
&new_cpu.itime, &new_cpu.iowtime, &new_cpu.irqtime, &new_cpu.sirqtime);
|
||||
fclose(file);
|
||||
|
||||
proc_num = 0;
|
||||
|
|
@ -237,7 +243,9 @@ static void read_procs(void) {
|
|||
continue;
|
||||
|
||||
pid = atoi(pid_dir->d_name);
|
||||
|
||||
|
||||
struct proc_info cur_proc;
|
||||
|
||||
if (!threads) {
|
||||
proc = alloc_proc();
|
||||
|
||||
|
|
@ -254,6 +262,12 @@ static void read_procs(void) {
|
|||
|
||||
proc->num_threads = 0;
|
||||
} else {
|
||||
sprintf(filename, "/proc/%d/cmdline", pid);
|
||||
read_cmdline(filename, &cur_proc);
|
||||
|
||||
sprintf(filename, "/proc/%d/status", pid);
|
||||
read_status(filename, &cur_proc);
|
||||
|
||||
proc = NULL;
|
||||
}
|
||||
|
||||
|
|
@ -275,11 +289,9 @@ static void read_procs(void) {
|
|||
sprintf(filename, "/proc/%d/task/%d/stat", pid, tid);
|
||||
read_stat(filename, proc);
|
||||
|
||||
sprintf(filename, "/proc/%d/task/%d/cmdline", pid, tid);
|
||||
read_cmdline(filename, proc);
|
||||
|
||||
sprintf(filename, "/proc/%d/task/%d/status", pid, tid);
|
||||
read_status(filename, proc);
|
||||
strcpy(proc->name, cur_proc.name);
|
||||
proc->uid = cur_proc.uid;
|
||||
proc->gid = cur_proc.gid;
|
||||
|
||||
add_proc(proc_num++, proc);
|
||||
} else {
|
||||
|
|
@ -315,8 +327,9 @@ static int read_stat(char *filename, struct proc_info *proc) {
|
|||
if (!open_paren || !close_paren) return 1;
|
||||
|
||||
*open_paren = *close_paren = '\0';
|
||||
strcpy(proc->name, open_paren + 1);
|
||||
|
||||
strncpy(proc->tname, open_paren + 1, THREAD_NAME_LEN);
|
||||
proc->tname[THREAD_NAME_LEN-1] = 0;
|
||||
|
||||
/* Scan rest of string. */
|
||||
sscanf(close_paren + 1, " %c %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d "
|
||||
"%lu %lu %*d %*d %*d %*d %*d %*d %*d %lu %ld",
|
||||
|
|
@ -347,8 +360,11 @@ static int read_cmdline(char *filename, struct proc_info *proc) {
|
|||
if (!file) return 1;
|
||||
fgets(line, MAX_LINE, file);
|
||||
fclose(file);
|
||||
if (strlen(line) > 0)
|
||||
strcpy(proc->name, line);
|
||||
if (strlen(line) > 0) {
|
||||
strncpy(proc->name, line, PROC_NAME_LEN);
|
||||
proc->name[PROC_NAME_LEN-1] = 0;
|
||||
} else
|
||||
proc->name[0] = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -391,16 +407,34 @@ static void print_procs(void) {
|
|||
}
|
||||
}
|
||||
|
||||
total_delta_time = (new_cpu.utime + new_cpu.ntime + new_cpu.stime + new_cpu.itime)
|
||||
- (old_cpu.utime + old_cpu.ntime + old_cpu.stime + old_cpu.itime);
|
||||
total_delta_time = (new_cpu.utime + new_cpu.ntime + new_cpu.stime + new_cpu.itime
|
||||
+ new_cpu.iowtime + new_cpu.irqtime + new_cpu.sirqtime)
|
||||
- (old_cpu.utime + old_cpu.ntime + old_cpu.stime + old_cpu.itime
|
||||
+ old_cpu.iowtime + old_cpu.irqtime + old_cpu.sirqtime);
|
||||
|
||||
qsort(new_procs, num_new_procs, sizeof(struct proc_info *), proc_cmp);
|
||||
|
||||
printf("\n\n\n");
|
||||
printf("User %ld%%, System %ld%%, IOW %ld%%, IRQ %ld%%\n",
|
||||
((new_cpu.utime + new_cpu.ntime) - (old_cpu.utime + old_cpu.ntime)) * 100 / total_delta_time,
|
||||
((new_cpu.stime ) - (old_cpu.stime)) * 100 / total_delta_time,
|
||||
((new_cpu.iowtime) - (old_cpu.iowtime)) * 100 / total_delta_time,
|
||||
((new_cpu.irqtime + new_cpu.sirqtime)
|
||||
- (old_cpu.irqtime + old_cpu.sirqtime)) * 100 / total_delta_time);
|
||||
printf("User %ld + Nice %ld + Sys %ld + Idle %ld + IOW %ld + IRQ %ld + SIRQ %ld = %ld\n",
|
||||
new_cpu.utime - old_cpu.utime,
|
||||
new_cpu.ntime - old_cpu.ntime,
|
||||
new_cpu.stime - old_cpu.stime,
|
||||
new_cpu.itime - old_cpu.itime,
|
||||
new_cpu.iowtime - old_cpu.iowtime,
|
||||
new_cpu.irqtime - old_cpu.irqtime,
|
||||
new_cpu.sirqtime - old_cpu.sirqtime,
|
||||
total_delta_time);
|
||||
printf("\n");
|
||||
if (!threads)
|
||||
printf("%5s %4s %1s %5s %7s %7s %-8s %s\n", "PID", "CPU%", "S", "#THR", "VSS", "RSS", "UID", "Name");
|
||||
else
|
||||
printf("%5s %5s %4s %1s %7s %7s %-8s %s\n", "PID", "TID", "CPU%", "S", "VSS", "RSS", "UID", "Name");
|
||||
printf("%5s %5s %4s %1s %7s %7s %-8s %-15s %s\n", "PID", "TID", "CPU%", "S", "VSS", "RSS", "UID", "Thread", "Proc");
|
||||
|
||||
for (i = 0; i < num_new_procs; i++) {
|
||||
proc = new_procs[i];
|
||||
|
|
@ -423,10 +457,10 @@ static void print_procs(void) {
|
|||
}
|
||||
if (!threads)
|
||||
printf("%5d %3ld%% %c %5d %6ldK %6ldK %-8.8s %s\n", proc->pid, proc->delta_time * 100 / total_delta_time, proc->state, proc->num_threads,
|
||||
proc->vss / 1024, proc->rss * getpagesize() / 1024, user_str, proc->name);
|
||||
proc->vss / 1024, proc->rss * getpagesize() / 1024, user_str, proc->name[0] != 0 ? proc->name : proc->tname);
|
||||
else
|
||||
printf("%5d %5d %3ld%% %c %6ldK %6ldK %-8.8s %s\n", proc->pid, proc->tid, proc->delta_time * 100 / total_delta_time, proc->state,
|
||||
proc->vss / 1024, proc->rss * getpagesize() / 1024, user_str, proc->name);
|
||||
printf("%5d %5d %3ld%% %c %6ldK %6ldK %-8.8s %-15s %s\n", proc->pid, proc->tid, proc->delta_time * 100 / total_delta_time, proc->state,
|
||||
proc->vss / 1024, proc->rss * getpagesize() / 1024, user_str, proc->tname, proc->name);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,3 @@
|
|||
BUILD_VOLD := false
|
||||
|
||||
ifeq ($(BUILD_VOLD),true)
|
||||
|
||||
LOCAL_PATH:= $(call my-dir)
|
||||
|
||||
include $(CLEAR_VARS)
|
||||
|
|
@ -10,7 +6,6 @@ LOCAL_SRC_FILES:= \
|
|||
vold.c \
|
||||
cmd_dispatch.c \
|
||||
uevent.c \
|
||||
inotify.c \
|
||||
mmc.c \
|
||||
misc.c \
|
||||
blkdev.c \
|
||||
|
|
@ -22,6 +17,9 @@ LOCAL_SRC_FILES:= \
|
|||
volmgr_ext3.c \
|
||||
logwrapper.c \
|
||||
ProcessKiller.c\
|
||||
switch.c \
|
||||
format.c \
|
||||
devmapper.c
|
||||
|
||||
LOCAL_MODULE:= vold
|
||||
|
||||
|
|
@ -32,5 +30,3 @@ LOCAL_CFLAGS :=
|
|||
LOCAL_SHARED_LIBRARIES := libcutils
|
||||
|
||||
include $(BUILD_EXECUTABLE)
|
||||
|
||||
endif
|
||||
|
|
|
|||
|
|
@ -112,7 +112,7 @@ static boolean CheckFileDescriptorSymLinks(int pid, const char* mountPoint)
|
|||
{
|
||||
char name[PATH_MAX];
|
||||
GetProcessName(pid, name);
|
||||
LOG_ERROR("process %s (%d) has open file %s\n", name, pid, link);
|
||||
LOG_ERROR("process %s (%d) has open file %s", name, pid, link);
|
||||
fileOpen = true;
|
||||
}
|
||||
}
|
||||
|
|
@ -140,7 +140,7 @@ static boolean CheckFileMaps(int pid, const char* mountPoint)
|
|||
{
|
||||
char name[PATH_MAX];
|
||||
GetProcessName(pid, name);
|
||||
LOG_ERROR("process %s (%d) has open file map for %s\n", name, pid, path);
|
||||
LOG_ERROR("process %s (%d) has open file map for %s", name, pid, path);
|
||||
mapOpen = true;
|
||||
}
|
||||
}
|
||||
|
|
@ -159,7 +159,7 @@ static boolean CheckSymLink(int pid, const char* mountPoint, const char* name, c
|
|||
{
|
||||
char name[PATH_MAX];
|
||||
GetProcessName(pid, name);
|
||||
LOG_ERROR("process %s (%d) has %s in %s\n", name, pid, message, mountPoint);
|
||||
LOG_ERROR("process %s (%d) has %s in %s", name, pid, message, mountPoint);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
|
|
@ -182,7 +182,7 @@ void KillProcessesWithOpenFiles(const char* mountPoint, boolean sigkill, int *ex
|
|||
DIR* dir;
|
||||
struct dirent* de;
|
||||
|
||||
LOG_ERROR("KillProcessesWithOpenFiles %s\n", mountPoint);
|
||||
LOG_ERROR("KillProcessesWithOpenFiles %s", mountPoint);
|
||||
dir = opendir("/proc");
|
||||
if (!dir) return;
|
||||
|
||||
|
|
@ -205,14 +205,14 @@ void KillProcessesWithOpenFiles(const char* mountPoint, boolean sigkill, int *ex
|
|||
|
||||
for (i = 0; i < num_excluded; i++) {
|
||||
if (pid == excluded[i]) {
|
||||
LOG_ERROR("I just need a little more TIME captain!\n");
|
||||
LOG_ERROR("I just need a little more TIME captain!");
|
||||
hit = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!hit) {
|
||||
LOG_ERROR("Killing process %d\n", pid);
|
||||
LOG_ERROR("Killing process %d", pid);
|
||||
kill(pid, (sigkill ? SIGKILL : SIGTERM));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
253
vold/blkdev.c
253
vold/blkdev.c
|
|
@ -27,6 +27,7 @@
|
|||
#include <sys/mman.h>
|
||||
|
||||
#include <linux/fs.h>
|
||||
#include <linux/msdos_fs.h>
|
||||
|
||||
#include "vold.h"
|
||||
#include "blkdev.h"
|
||||
|
|
@ -37,158 +38,145 @@
|
|||
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, char *dev_fspath);
|
||||
static void blkdev_dev_fspath_set(blkdev_t *blk, char *dev_fspath);
|
||||
int minor, char *type, struct media *media);
|
||||
|
||||
int blkdev_handle_devicefile_removed(blkdev_t *blk, char *dev_fspath)
|
||||
static int fat_valid_media(unsigned char media)
|
||||
{
|
||||
return 0xf8 <= media || media == 0xf0;
|
||||
}
|
||||
|
||||
char *blkdev_get_devpath(blkdev_t *blk)
|
||||
{
|
||||
#if DEBUG_BLKDEV
|
||||
LOG_VOL("blkdev_handle_devicefile_removed(%s):\n", dev_fspath);
|
||||
#endif
|
||||
blkdev_dev_fspath_set(blk, NULL);
|
||||
return 0;
|
||||
char *dp = malloc(256);
|
||||
sprintf(dp, "%s/vold/%d:%d", DEVPATH, blk->major, blk->minor);
|
||||
return dp;
|
||||
}
|
||||
|
||||
int blkdev_handle_devicefile_created(blkdev_t *blk, char *dev_fspath)
|
||||
int blkdev_refresh(blkdev_t *blk)
|
||||
{
|
||||
int rc = 0;
|
||||
blkdev_t *disk;
|
||||
|
||||
#if DEBUG_BLKDEV
|
||||
LOG_VOL("blkdev_handle_devicefile_created(%s):\n", dev_fspath);
|
||||
#endif
|
||||
int fd = 0;
|
||||
char *devpath = NULL;
|
||||
unsigned char *block = NULL;
|
||||
int i, rc;
|
||||
|
||||
if (!blk) {
|
||||
/*
|
||||
* This device does not yet have a backing blkdev associated with it.
|
||||
* Create a new one in the pending state and fill in the information
|
||||
* we have.
|
||||
*/
|
||||
struct stat sbuf;
|
||||
|
||||
if (stat(dev_fspath, &sbuf) < 0) {
|
||||
LOGE("Unable to stat device '%s' (%s)\n", dev_fspath, strerror(errno));
|
||||
return -errno;
|
||||
}
|
||||
|
||||
int major = (sbuf.st_rdev & 0xfff00) >> 8;
|
||||
int minor = (sbuf.st_rdev & 0xff) | ((sbuf.st_rdev >> 12) & 0xfff00);
|
||||
|
||||
disk = blkdev_lookup_by_devno(major, 0);
|
||||
|
||||
if (!disk) {
|
||||
/*
|
||||
* If there isn't a disk associated with this device, then
|
||||
* its not what we're looking for
|
||||
*/
|
||||
#if DEBUG_BLKDEV
|
||||
LOG_VOL("Ignoring device file '%s' (no disk found)\n", dev_fspath);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!(blk = blkdev_create_pending_partition(disk, dev_fspath, major,
|
||||
minor, disk->media))) {
|
||||
LOGE("Unable to create pending blkdev\n");
|
||||
return -1;
|
||||
}
|
||||
} else
|
||||
blkdev_dev_fspath_set(blk, dev_fspath);
|
||||
if (!(block = malloc(512)))
|
||||
goto out;
|
||||
|
||||
/*
|
||||
* If we're a disk, then read the partition table. Otherwise we're
|
||||
* a partition so get the partition type
|
||||
* Get the device size
|
||||
*/
|
||||
disk = blk->disk;
|
||||
devpath = blkdev_get_devpath(blk);
|
||||
|
||||
int fd;
|
||||
|
||||
if ((fd = open(disk->dev_fspath, O_RDWR)) < 0) {
|
||||
LOGE("Unable to open device '%s' (%s)\n", disk->dev_fspath, strerror(errno));
|
||||
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 (%m)\n");
|
||||
LOGE("Unable to get device size (%m)");
|
||||
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;
|
||||
}
|
||||
|
||||
#if DEBUG_BLKDEV
|
||||
LOG_VOL("New device '%s' size = %u sectors\n", dev_fspath, blk->nr_sec);
|
||||
#endif
|
||||
free(devpath);
|
||||
|
||||
void *raw_pt;
|
||||
unsigned char *chr_pt;
|
||||
int i;
|
||||
|
||||
raw_pt = chr_pt = mmap(NULL, 512, PROT_READ, MAP_PRIVATE, fd, 0);
|
||||
if (raw_pt == MAP_FAILED) {
|
||||
LOGE("Unable to mmap device paritition table (%m)\n");
|
||||
goto out_nommap;
|
||||
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 ((chr_pt[0x1fe] != 0x55) && (chr_pt[0x1ff] != 0xAA)) {
|
||||
LOG_VOL("Disk '%s' does not contain a partition table\n", dev_fspath);
|
||||
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 < 4; i++) {
|
||||
struct dos_partition part;
|
||||
|
||||
dos_partition_dec(raw_pt + DOSPARTOFF + i * sizeof(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++;
|
||||
}
|
||||
LOG_VOL("Disk device '%s' (blkdev %s) contains %d partitions\n",
|
||||
dev_fspath, blk->devpath, blk->nr_parts);
|
||||
} else if (blk->type == blkdev_partition) {
|
||||
struct dos_partition part;
|
||||
int part_no = blk->minor -1;
|
||||
|
||||
dos_partition_dec(raw_pt + DOSPARTOFF + part_no * sizeof(struct dos_partition), &part);
|
||||
|
||||
if (!part.dp_typ)
|
||||
LOG_VOL("Warning - Partition device '%s' (blkdev %s) has no partition type set\n",
|
||||
dev_fspath, blk->devpath);
|
||||
dos_partition_dec(block + DOSPARTOFF + part_no * sizeof(struct dos_partition), &part);
|
||||
blk->part_type = part.dp_typ;
|
||||
|
||||
LOG_VOL("Partition device '%s' (blkdev %s) partition type 0x%x\n",
|
||||
dev_fspath, blk->devpath, blk->part_type);
|
||||
} else {
|
||||
LOGE("Bad blkdev type '%d'\n", blk->type);
|
||||
rc = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
out:
|
||||
munmap(raw_pt, 512);
|
||||
out_nommap:
|
||||
close(fd);
|
||||
return rc;
|
||||
}
|
||||
|
||||
blkdev_t *blkdev_create_pending_partition(blkdev_t *disk, char *dev_fspath, int major,
|
||||
int minor, struct media *media)
|
||||
{
|
||||
return _blkdev_create(disk, NULL, major, minor, "partition", media, dev_fspath);
|
||||
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, NULL);
|
||||
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, char *dev_fspath)
|
||||
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!\n");
|
||||
LOGE("Non disk parent specified for blkdev!");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
@ -218,8 +206,6 @@ static blkdev_t *_blkdev_create(blkdev_t *disk, char *devpath, int major,
|
|||
new->major = major;
|
||||
new->minor = minor;
|
||||
new->media = media;
|
||||
if (dev_fspath)
|
||||
new->dev_fspath = strdup(dev_fspath);
|
||||
new->nr_sec = 0xffffffff;
|
||||
|
||||
if (disk)
|
||||
|
|
@ -227,12 +213,23 @@ static blkdev_t *_blkdev_create(blkdev_t *disk, char *devpath, int major,
|
|||
else
|
||||
new->disk = new; // Note the self disk pointer
|
||||
|
||||
/* Create device nodes */
|
||||
char nodepath[255];
|
||||
mode_t mode = 0666 | 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'\n", type);
|
||||
LOGE("Unknown block device type '%s'", type);
|
||||
new->type = blkdev_unknown;
|
||||
}
|
||||
|
||||
|
|
@ -258,8 +255,11 @@ void blkdev_destroy(blkdev_t *blkdev)
|
|||
|
||||
if (blkdev->devpath)
|
||||
free(blkdev->devpath);
|
||||
if (blkdev->dev_fspath)
|
||||
free(blkdev->dev_fspath);
|
||||
|
||||
char nodepath[255];
|
||||
sprintf(nodepath, "%s/vold/%d:%d", DEVPATH, blkdev->major, blkdev->minor);
|
||||
unlink(nodepath);
|
||||
|
||||
free(blkdev);
|
||||
}
|
||||
|
||||
|
|
@ -272,9 +272,6 @@ blkdev_t *blkdev_lookup_by_path(char *devpath)
|
|||
return list_scan->dev;
|
||||
list_scan = list_scan->next;
|
||||
}
|
||||
#if DEBUG_BLKDEV
|
||||
LOG_VOL("blkdev_lookup_by_path(): No blkdev found @ %s\n", devpath);
|
||||
#endif
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
@ -288,32 +285,12 @@ blkdev_t *blkdev_lookup_by_devno(int maj, int min)
|
|||
return list_scan->dev;
|
||||
list_scan = list_scan->next;
|
||||
}
|
||||
#if DEBUG_BLKDEV
|
||||
LOG_VOL("blkdev_lookup_by_devno(): No blkdev found for %d.%d\n", maj, min);
|
||||
#endif
|
||||
return NULL;
|
||||
}
|
||||
|
||||
blkdev_t *blkdev_lookup_by_dev_fspath(char *dev_fspath)
|
||||
{
|
||||
struct blkdev_list *list_scan = list_root;
|
||||
|
||||
while (list_scan) {
|
||||
if (list_scan->dev->dev_fspath) {
|
||||
if (!strcmp(list_scan->dev->dev_fspath, dev_fspath))
|
||||
return list_scan->dev;
|
||||
}
|
||||
|
||||
list_scan = list_scan->next;
|
||||
}
|
||||
// LOG_VOL("blkdev_lookup_by_devno(): No blkdev found for %d.%d\n", maj, min);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Given a disk device, return the number of partitions yet to be
|
||||
* processed.
|
||||
* Given a disk device, return the number of partitions which
|
||||
* have yet to be processed.
|
||||
*/
|
||||
int blkdev_get_num_pending_partitions(blkdev_t *blk)
|
||||
{
|
||||
|
|
@ -330,25 +307,13 @@ int blkdev_get_num_pending_partitions(blkdev_t *blk)
|
|||
if (list_scan->dev->major != blk->major)
|
||||
goto next;
|
||||
|
||||
if (list_scan->dev->nr_sec != 0xffffffff)
|
||||
if (list_scan->dev->nr_sec != 0xffffffff &&
|
||||
list_scan->dev->devpath) {
|
||||
num--;
|
||||
}
|
||||
next:
|
||||
list_scan = list_scan->next;
|
||||
}
|
||||
return num;
|
||||
}
|
||||
|
||||
void blkdev_devpath_set(blkdev_t *blk, char *devpath)
|
||||
{
|
||||
blk->devpath = strdup(devpath);
|
||||
}
|
||||
|
||||
static void blkdev_dev_fspath_set(blkdev_t *blk, char *dev_fspath)
|
||||
{
|
||||
if (dev_fspath)
|
||||
blk->dev_fspath = strdup(dev_fspath);
|
||||
else {
|
||||
free(blk->dev_fspath);
|
||||
blk->dev_fspath = NULL;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -41,7 +41,6 @@ struct blkdev {
|
|||
|
||||
int major;
|
||||
int minor;
|
||||
char *dev_fspath;
|
||||
};
|
||||
|
||||
struct blkdev_list {
|
||||
|
|
@ -56,11 +55,10 @@ blkdev_t *blkdev_create(blkdev_t *disk, char *devpath, int major, int minor, str
|
|||
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);
|
||||
blkdev_t *blkdev_lookup_by_dev_fspath(char *dev_fspath);
|
||||
char *blkdev_get_devpath(blkdev_t *blk);
|
||||
|
||||
void blkdev_destroy(blkdev_t *blk);
|
||||
|
||||
int blkdev_handle_devicefile_created(blkdev_t *blk, char *dev_fspath);
|
||||
int blkdev_handle_devicefile_removed(blkdev_t *blk, char *dev_fspath);
|
||||
int blkdev_get_num_pending_partitions(blkdev_t *blk);
|
||||
void blkdev_devpath_set(blkdev_t *blk, char *dev_fspath);
|
||||
int blkdev_refresh(blkdev_t *blk);
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -33,13 +33,15 @@ 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_MOUNT_VOLUME, do_mount_volume },
|
||||
{ VOLD_CMD_EJECT_MEDIA, do_eject_media },
|
||||
{ VOLD_CMD_FORMAT_MEDIA, do_format_media },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
|
|
@ -49,9 +51,10 @@ int process_framework_command(int socket)
|
|||
char buffer[101];
|
||||
|
||||
if ((rc = read(socket, buffer, sizeof(buffer) -1)) < 0) {
|
||||
LOGE("Unable to read framework command (%s)\n", strerror(errno));
|
||||
LOGE("Unable to read framework command (%s)", strerror(errno));
|
||||
return -errno;
|
||||
}
|
||||
} else if (!rc)
|
||||
return -ECONNRESET;
|
||||
|
||||
int start = 0;
|
||||
int i;
|
||||
|
|
@ -71,7 +74,7 @@ static void dispatch_cmd(char *cmd)
|
|||
{
|
||||
struct cmd_dispatch *c;
|
||||
|
||||
LOG_VOL("dispatch_cmd(%s):\n", cmd);
|
||||
LOG_VOL("dispatch_cmd(%s):", cmd);
|
||||
|
||||
for (c = dispatch_table; c->cmd != NULL; c++) {
|
||||
if (!strncmp(c->cmd, cmd, strlen(c->cmd))) {
|
||||
|
|
@ -80,7 +83,7 @@ static void dispatch_cmd(char *cmd)
|
|||
}
|
||||
}
|
||||
|
||||
LOGE("No cmd handlers defined for '%s'\n", cmd);
|
||||
LOGE("No cmd handlers defined for '%s'", cmd);
|
||||
}
|
||||
|
||||
static int do_send_ums_status(char *cmd)
|
||||
|
|
@ -101,6 +104,11 @@ 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:")]);
|
||||
|
|
|
|||
|
|
@ -26,5 +26,6 @@
|
|||
// these commands should contain a volume mount point after the colon
|
||||
#define VOLD_CMD_MOUNT_VOLUME "mount_volume:"
|
||||
#define VOLD_CMD_EJECT_MEDIA "eject_media:"
|
||||
#define VOLD_CMD_FORMAT_MEDIA "format_media:"
|
||||
|
||||
#endif
|
||||
|
|
|
|||
463
vold/devmapper.c
Normal file
463
vold/devmapper.c
Normal file
|
|
@ -0,0 +1,463 @@
|
|||
|
||||
/*
|
||||
* 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 <errno.h>
|
||||
#include <dirent.h>
|
||||
#include <unistd.h>
|
||||
#include <sched.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#include <sys/mount.h>
|
||||
|
||||
#include <linux/loop.h>
|
||||
#include <linux/dm-ioctl.h>
|
||||
|
||||
#include <cutils/config_utils.h>
|
||||
#include <cutils/properties.h>
|
||||
|
||||
#include "vold.h"
|
||||
#include "devmapper.h"
|
||||
|
||||
#define DEBUG_DEVMAPPER 1
|
||||
|
||||
static void *_align(void *ptr, unsigned int a)
|
||||
{
|
||||
register unsigned long agn = --a;
|
||||
|
||||
return (void *) (((unsigned long) ptr + agn) & ~agn);
|
||||
}
|
||||
|
||||
static struct dm_ioctl *_dm_ioctl_setup(struct devmapping *dm, int flags)
|
||||
{
|
||||
void *buffer;
|
||||
void *p;
|
||||
const size_t min_size = 16 * 1024;
|
||||
size_t len = sizeof(struct dm_ioctl);
|
||||
struct dm_ioctl *io;
|
||||
struct dm_target_spec *tgt;
|
||||
int i;
|
||||
char params[1024];
|
||||
char key[80];
|
||||
|
||||
key[0] = '\0';
|
||||
for (i = 0; i < (int) sizeof(dm->key); i++) {
|
||||
char tmp[8];
|
||||
|
||||
sprintf(tmp, "%02x", dm->key[i]);
|
||||
strcat(key, tmp);
|
||||
}
|
||||
|
||||
char srcdev[128];
|
||||
|
||||
// XXX: Handle non crypt targets and non twofish (use param)
|
||||
if (dm->src_type == dmsrc_loopback)
|
||||
strcpy(srcdev, dm->type_data.loop.loop_dev);
|
||||
else if (dm->src_type == dmsrc_partition)
|
||||
strcpy(srcdev, dm->type_data.part.part_dev);
|
||||
|
||||
sprintf(params, "twofish %s 0 %s 0", key, srcdev);
|
||||
|
||||
LOG_VOL("Params = '%s'", params);
|
||||
|
||||
if (len < min_size)
|
||||
len = min_size;
|
||||
|
||||
if (!(buffer = malloc(len))) {
|
||||
LOGE("out of memory");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memset(buffer, 0, len);
|
||||
io = buffer;
|
||||
tgt = (struct dm_target_spec *) &buffer[sizeof(struct dm_ioctl)];
|
||||
|
||||
io->version[0] = 4;
|
||||
io->version[1] = 0;
|
||||
io->version[2] = 0;
|
||||
|
||||
io->data_size = len;
|
||||
io->data_start = sizeof(struct dm_ioctl);
|
||||
|
||||
io->flags = flags;
|
||||
io->dev = 0;
|
||||
|
||||
io->target_count = 1;
|
||||
io->event_nr = 1;
|
||||
strncpy(io->name, dm->target, sizeof(io->name));
|
||||
|
||||
tgt->status = 0;
|
||||
tgt->sector_start = 0;
|
||||
tgt->length = (dm->size_mb * (1024 * 1024)) / 512;
|
||||
strncpy(tgt->target_type, "crypt", sizeof(tgt->target_type));
|
||||
|
||||
p = buffer + sizeof(struct dm_ioctl) + sizeof(struct dm_target_spec);
|
||||
strcpy((char *) p, params);
|
||||
p+= strlen(params) + 1;
|
||||
|
||||
p = _align(p, 8);
|
||||
tgt->next = p - buffer;
|
||||
|
||||
return io;
|
||||
}
|
||||
|
||||
static int get_next_available_dm()
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 8; i++) {
|
||||
char path[255];
|
||||
sprintf(path, "/dev/block/dm-%d", i);
|
||||
if ((access(path, F_OK) < 0) && (errno == ENOENT))
|
||||
return i;
|
||||
}
|
||||
|
||||
LOGE("Out of device mapper numbers");
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int create_devmapping(struct devmapping *dm)
|
||||
{
|
||||
struct dm_ioctl *io;
|
||||
int rc, fd;
|
||||
|
||||
#if DEBUG_DEVMAPPER
|
||||
LOG_VOL("create_devmapping():");
|
||||
#endif
|
||||
|
||||
if (dm->dm_no < 0) {
|
||||
LOGE("Invalid dm_no set");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if ((fd = open("/dev/device-mapper", O_RDWR)) < 0) {
|
||||
LOGE("Error opening device mapper (%d)", errno);
|
||||
return -errno;
|
||||
}
|
||||
|
||||
if (!(io = _dm_ioctl_setup(dm, 0))) {
|
||||
LOGE("Unable to setup ioctl (out of memory)");
|
||||
close(fd);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
if ((rc = ioctl(fd, DM_DEV_CREATE, io)) < 0) {
|
||||
LOGE("device-mapper create ioctl failed (%d)", errno);
|
||||
rc = -errno;
|
||||
goto out_free;
|
||||
}
|
||||
|
||||
free(io);
|
||||
|
||||
if (!(io = _dm_ioctl_setup(dm, DM_STATUS_TABLE_FLAG))) {
|
||||
LOGE("Unable to setup ioctl (out of memory)");
|
||||
rc = -ENOMEM;
|
||||
goto out_nofree;
|
||||
}
|
||||
|
||||
if ((rc = ioctl(fd, DM_TABLE_LOAD, io)) < 0) {
|
||||
LOGE("device-mapper load ioctl failed (%d)", errno);
|
||||
rc = -errno;
|
||||
goto out_free;
|
||||
}
|
||||
|
||||
free(io);
|
||||
|
||||
if (!(io = _dm_ioctl_setup(dm, 0))) {
|
||||
LOGE("Unable to setup ioctl (out of memory)");
|
||||
rc = -ENOMEM;
|
||||
goto out_nofree;
|
||||
}
|
||||
|
||||
if ((rc = ioctl(fd, DM_DEV_SUSPEND, io)) < 0) {
|
||||
LOGE("device-mapper resume ioctl failed (%d)", errno);
|
||||
rc = -errno;
|
||||
goto out_free;
|
||||
}
|
||||
|
||||
out_free:
|
||||
free (io);
|
||||
out_nofree:
|
||||
close (fd);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int loopback_start(struct devmapping *dm)
|
||||
{
|
||||
int i;
|
||||
int fd;
|
||||
char filename[255];
|
||||
int rc;
|
||||
|
||||
#if DEBUG_DEVMAPPER
|
||||
LOG_VOL("loopback_start(%s):", dm->type_data.loop.loop_src);
|
||||
#endif
|
||||
|
||||
for (i = 0; i < MAX_LOOP; i++) {
|
||||
struct loop_info info;
|
||||
|
||||
sprintf(filename, "/dev/block/loop%d", i);
|
||||
|
||||
if ((fd = open(filename, O_RDWR)) < 0) {
|
||||
LOGE("Unable to open %s (%s)", filename, strerror(errno));
|
||||
return -errno;
|
||||
}
|
||||
|
||||
rc = ioctl(fd, LOOP_GET_STATUS, &info);
|
||||
if (rc < 0 && errno == ENXIO)
|
||||
break;
|
||||
|
||||
close(fd);
|
||||
|
||||
if (rc < 0) {
|
||||
LOGE("Unable to get loop status for %s (%s)", filename,
|
||||
strerror(errno));
|
||||
return -errno;
|
||||
}
|
||||
}
|
||||
|
||||
if (i == MAX_LOOP) {
|
||||
LOGE("Out of loop devices");
|
||||
return -ENOSPC;
|
||||
}
|
||||
|
||||
int file_fd;
|
||||
|
||||
if ((file_fd = open(dm->type_data.loop.loop_src, O_RDWR)) < 0) {
|
||||
LOGE("Unable to open %s (%s)", dm->type_data.loop.loop_src,
|
||||
strerror(errno));
|
||||
return -errno;
|
||||
}
|
||||
|
||||
if (ioctl(fd, LOOP_SET_FD, file_fd) < 0) {
|
||||
LOGE("Error setting up loopback interface (%s)", strerror(errno));
|
||||
return -errno;
|
||||
}
|
||||
|
||||
dm->type_data.loop.loop_dev = strdup(filename);
|
||||
dm->type_data.loop.loop_no = i;
|
||||
|
||||
close(fd);
|
||||
close(file_fd);
|
||||
|
||||
#if DEBUG_DEVMAPPER
|
||||
LOG_VOL("Loop setup on %s for %s", dm->type_data.loop.loop_dev,
|
||||
dm->type_data.loop.loop_src);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int devmapper_start(struct devmapping *dm)
|
||||
{
|
||||
int rc;
|
||||
char src_blkdev_path[255];
|
||||
|
||||
#if DEBUG_DEVMAPPER
|
||||
LOG_VOL("devmapper_start()");
|
||||
#endif
|
||||
|
||||
if (dm->src_type == dmsrc_loopback) {
|
||||
if ((rc = loopback_start(dm)) < 0)
|
||||
return rc;
|
||||
} else if (dm->src_type == dmsrc_partition) {
|
||||
LOGE("partition maps not yet supported");
|
||||
return -ENOSYS;
|
||||
} else {
|
||||
LOGE("devmapper_start(): Unsupported source type '%d'", dm->src_type);
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
/*
|
||||
* Configure the device mapper
|
||||
*/
|
||||
if ((rc = create_devmapping(dm)) < 0) {
|
||||
LOGE("Failed to create devmapping (%d)", rc);
|
||||
// XXX: if loopback then tear down
|
||||
return rc;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct devmapping *devmapper_init(char *src, char *src_type, uint32_t size_mb,
|
||||
char *target, char *params, char *tgt_fs, char *mediapath)
|
||||
{
|
||||
struct devmapping *dm;
|
||||
|
||||
if (!(dm = malloc(sizeof(struct devmapping)))) {
|
||||
LOGE("devmapper_init(): out of memory");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memset(dm, 0, sizeof(struct devmapping));
|
||||
|
||||
if (!strcmp(src_type, "loopback_file")) {
|
||||
dm->src_type = dmsrc_loopback;
|
||||
dm->type_data.loop.loop_src = strdup(src);
|
||||
} else if (!strncmp(src_type, "partition ", strlen("partition "))) {
|
||||
dm->src_type = dmsrc_partition;
|
||||
char *p = strtok(src_type, " ");
|
||||
if (!p) {
|
||||
LOGE("Invalid partition specifier");
|
||||
goto out_free;
|
||||
}
|
||||
dm->type_data.part.part_type = strtoul(p, NULL, 0);
|
||||
} else {
|
||||
LOGE("Invalid src_type defined (%s)", src_type);
|
||||
goto out_free;
|
||||
}
|
||||
|
||||
// XXX: Validate these
|
||||
dm->size_mb = size_mb;
|
||||
dm->target = strdup(target);
|
||||
dm->params = strdup(params);
|
||||
dm->tgt_fs = strdup(tgt_fs);
|
||||
|
||||
if ((dm->dm_no = get_next_available_dm()) < 0)
|
||||
goto out_free;
|
||||
|
||||
sprintf(mediapath, "/devices/virtual/block/dm-%d", dm->dm_no);
|
||||
|
||||
if (!(dm->media = media_create(mediapath,
|
||||
"unknown",
|
||||
"unknown",
|
||||
media_devmapper))) {
|
||||
LOGE("Unable to create media");
|
||||
goto out_free;
|
||||
}
|
||||
|
||||
return dm;
|
||||
out_free:
|
||||
if (dm->target)
|
||||
free(dm->target);
|
||||
if (dm->params)
|
||||
free(dm->params);
|
||||
if (dm->tgt_fs)
|
||||
free(dm->tgt_fs);
|
||||
|
||||
free(dm);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int devmapper_genesis(struct devmapping *dm)
|
||||
{
|
||||
|
||||
if (dm->src_type == dmsrc_loopback) {
|
||||
int fd;
|
||||
|
||||
LOG_VOL("devmapper_genesis(): Working on %s",
|
||||
dm->type_data.loop.loop_src);
|
||||
|
||||
unlink(dm->type_data.loop.loop_src);
|
||||
|
||||
LOG_VOL("devmapper_genesis(): Creating imagefile (%u MB)",
|
||||
dm->size_mb);
|
||||
|
||||
if ((fd = creat(dm->type_data.loop.loop_src, 0600)) < 0) {
|
||||
LOGE("Error creating imagefile (%s)", strerror(errno));
|
||||
return -errno;
|
||||
}
|
||||
|
||||
if (ftruncate(fd, (dm->size_mb * (1024 * 1024))) < 0) {
|
||||
LOGE("Error truncating imagefile (%s)", strerror(errno));
|
||||
close(fd);
|
||||
return -errno;
|
||||
}
|
||||
close(fd);
|
||||
} else if (dm->src_type == dmsrc_partition) {
|
||||
LOGE("partition maps not yet supported");
|
||||
return -ENOSYS;
|
||||
}
|
||||
|
||||
return devmapper_start(dm);
|
||||
}
|
||||
|
||||
static int destroy_devmapping(struct devmapping *dm)
|
||||
{
|
||||
struct dm_ioctl *io;
|
||||
int dmFd;
|
||||
int rc = 0;
|
||||
|
||||
LOG_VOL("destroy_devmapping():");
|
||||
|
||||
if ((dmFd = open("/dev/device-mapper", O_RDWR)) < 0) {
|
||||
LOGE("Error opening device mapper (%d)", errno);
|
||||
return -errno;
|
||||
}
|
||||
|
||||
if (!(io = _dm_ioctl_setup(dm, DM_PERSISTENT_DEV_FLAG))) {
|
||||
LOGE("Unable to setup ioctl (out of memory)");
|
||||
rc = -ENOMEM;
|
||||
goto out_nofree;
|
||||
}
|
||||
|
||||
if ((rc = ioctl(dmFd, DM_DEV_REMOVE, io)) < 0) {
|
||||
LOGE("device-mapper remove ioctl failed (%d)", errno);
|
||||
rc = -errno;
|
||||
goto out_free;
|
||||
}
|
||||
|
||||
out_free:
|
||||
free (io);
|
||||
out_nofree:
|
||||
close (dmFd);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int loopback_stop(struct devmapping *dm)
|
||||
{
|
||||
char devname[255];
|
||||
int device_fd;
|
||||
int rc = 0;
|
||||
|
||||
LOG_VOL("loopback_stop():");
|
||||
|
||||
device_fd = open(dm->type_data.loop.loop_dev, O_RDONLY);
|
||||
if (device_fd < 0) {
|
||||
LOG_ERROR("Failed to open loop (%d)", errno);
|
||||
return -errno;
|
||||
}
|
||||
|
||||
if (ioctl(device_fd, LOOP_CLR_FD, 0) < 0) {
|
||||
LOG_ERROR("Failed to destroy loop (%d)", errno);
|
||||
rc = -errno;
|
||||
}
|
||||
|
||||
close(device_fd);
|
||||
return rc;
|
||||
}
|
||||
|
||||
int devmapper_stop(struct devmapping *dm)
|
||||
{
|
||||
int rc;
|
||||
|
||||
LOG_VOL("devmapper_stop():");
|
||||
|
||||
if ((rc = destroy_devmapping(dm)))
|
||||
return rc;
|
||||
|
||||
if (dm->src_type == dmsrc_loopback) {
|
||||
if ((rc = loopback_stop(dm)))
|
||||
return rc;
|
||||
} else if (dm->src_type == dmsrc_partition) {
|
||||
LOGE("partition maps not yet supported");
|
||||
return -ENOSYS;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
70
vold/devmapper.h
Normal file
70
vold/devmapper.h
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
|
||||
/*
|
||||
* 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 _DEVMAPPER_H
|
||||
#define _DEVMAPPER_H
|
||||
|
||||
#include <pthread.h>
|
||||
|
||||
#include "vold.h"
|
||||
#include "blkdev.h"
|
||||
#include "media.h"
|
||||
|
||||
#define MAX_LOOP 8
|
||||
|
||||
enum dm_src_type {
|
||||
dmsrc_unknown,
|
||||
dmsrc_loopback,
|
||||
dmsrc_partition,
|
||||
};
|
||||
|
||||
struct loop_data {
|
||||
char *loop_src;
|
||||
|
||||
char *loop_dev;
|
||||
int loop_no;
|
||||
};
|
||||
|
||||
struct part_data {
|
||||
char part_type;
|
||||
|
||||
char *part_dev;
|
||||
};
|
||||
|
||||
struct devmapping {
|
||||
enum dm_src_type src_type;
|
||||
union {
|
||||
struct loop_data loop;
|
||||
struct part_data part;
|
||||
} type_data;
|
||||
|
||||
uint32_t size_mb;
|
||||
char *target;
|
||||
char *params;
|
||||
char *tgt_fs;
|
||||
|
||||
unsigned char key[16];
|
||||
int dm_no;
|
||||
|
||||
media_t *media;
|
||||
};
|
||||
|
||||
struct devmapping *devmapper_init(char *, char *, unsigned int, char *, char *, char *, char *);
|
||||
int devmapper_start(struct devmapping *);
|
||||
int devmapper_stop(struct devmapping *);
|
||||
int devmapper_genesis(struct devmapping *);
|
||||
#endif
|
||||
113
vold/format.c
Executable file
113
vold/format.c
Executable file
|
|
@ -0,0 +1,113 @@
|
|||
|
||||
/*
|
||||
* 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 <fcntl.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <linux/fs.h>
|
||||
|
||||
#include "vold.h"
|
||||
#include "blkdev.h"
|
||||
#include "format.h"
|
||||
#include "diskmbr.h"
|
||||
#include "logwrapper.h"
|
||||
|
||||
static char MKDOSFS_PATH[] = "/system/bin/mkdosfs";
|
||||
static char MKE2FS_PATH[] = "/system/bin/mke2fs";
|
||||
|
||||
int format_partition(blkdev_t *part, char *type)
|
||||
{
|
||||
char *devpath;
|
||||
int rc = -EINVAL;
|
||||
|
||||
devpath = blkdev_get_devpath(part);
|
||||
|
||||
if (!strcmp(type, FORMAT_TYPE_FAT32)) {
|
||||
char *args[7];
|
||||
args[0] = MKDOSFS_PATH;
|
||||
args[1] = "-F 32";
|
||||
args[2] = "-c 32";
|
||||
args[3] = "-n 2";
|
||||
args[4] = "-O android";
|
||||
args[5] = devpath;
|
||||
args[6] = NULL;
|
||||
rc = logwrap(6, args);
|
||||
} else {
|
||||
char *args[7];
|
||||
args[0] = MKE2FS_PATH;
|
||||
args[1] = "-b 4096";
|
||||
args[2] = "-m 1";
|
||||
args[3] = "-L android";
|
||||
args[4] = "-v";
|
||||
args[5] = devpath;
|
||||
args[6] = NULL;
|
||||
rc = logwrap(6, args);
|
||||
}
|
||||
|
||||
free(devpath);
|
||||
|
||||
if (rc == 0) {
|
||||
LOG_VOL("Filesystem formatted OK");
|
||||
return 0;
|
||||
} else {
|
||||
LOGE("Format failed (unknokwn exit code %d)", rc);
|
||||
return -EIO;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int initialize_mbr(blkdev_t *disk)
|
||||
{
|
||||
int fd, rc;
|
||||
unsigned char block[512];
|
||||
struct dos_partition part;
|
||||
char *devpath;
|
||||
|
||||
devpath = blkdev_get_devpath(disk);
|
||||
|
||||
memset(&part, 0, sizeof(part));
|
||||
part.dp_flag = 0x80;
|
||||
part.dp_typ = 0xc;
|
||||
part.dp_start = ((1024 * 64) / 512) + 1;
|
||||
part.dp_size = disk->nr_sec - part.dp_start;
|
||||
|
||||
memset(block, 0, sizeof(block));
|
||||
block[0x1fe] = 0x55;
|
||||
block[0x1ff] = 0xaa;
|
||||
|
||||
dos_partition_enc(block + DOSPARTOFF, &part);
|
||||
|
||||
if ((fd = open(devpath, O_RDWR)) < 0) {
|
||||
LOGE("Error opening disk file (%s)", strerror(errno));
|
||||
return -errno;
|
||||
}
|
||||
free(devpath);
|
||||
|
||||
if (write(fd, block, sizeof(block)) < 0) {
|
||||
LOGE("Error writing MBR (%s)", strerror(errno));
|
||||
close(fd);
|
||||
return -errno;
|
||||
}
|
||||
|
||||
if (ioctl(fd, BLKRRPART, NULL) < 0) {
|
||||
LOGE("Error re-reading partition table (%s)", strerror(errno));
|
||||
close(fd);
|
||||
return -errno;
|
||||
}
|
||||
close(fd);
|
||||
return 0;
|
||||
}
|
||||
26
vold/format.h
Normal file
26
vold/format.h
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
|
||||
/*
|
||||
* 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 _FORMAT_H
|
||||
#define _FORMAT_H
|
||||
|
||||
#define FORMAT_TYPE_EXT2 "ext2"
|
||||
#define FORMAT_TYPE_FAT32 "fat32"
|
||||
|
||||
int format_partition(blkdev_t *part, char *type);
|
||||
int initialize_mbr(blkdev_t *disk);
|
||||
#endif
|
||||
|
|
@ -44,6 +44,17 @@ le32dec(const void *buf)
|
|||
return ((p[3] << 24) | (p[2] << 16) | (p[1] << 8) | p[0]);
|
||||
}
|
||||
|
||||
static __inline void
|
||||
le32enc(void *pp, uint32_t u)
|
||||
{
|
||||
unsigned char *p = (unsigned char *)pp;
|
||||
|
||||
p[0] = u & 0xff;
|
||||
p[1] = (u >> 8) & 0xff;
|
||||
p[2] = (u >> 16) & 0xff;
|
||||
p[3] = (u >> 24) & 0xff;
|
||||
}
|
||||
|
||||
void
|
||||
dos_partition_dec(void const *pp, struct dos_partition *d)
|
||||
{
|
||||
|
|
@ -60,3 +71,20 @@ dos_partition_dec(void const *pp, struct dos_partition *d)
|
|||
d->dp_start = le32dec(p + 8);
|
||||
d->dp_size = le32dec(p + 12);
|
||||
}
|
||||
|
||||
void
|
||||
dos_partition_enc(void *pp, struct dos_partition *d)
|
||||
{
|
||||
unsigned char *p = pp;
|
||||
|
||||
p[0] = d->dp_flag;
|
||||
p[1] = d->dp_shd;
|
||||
p[2] = d->dp_ssect;
|
||||
p[3] = d->dp_scyl;
|
||||
p[4] = d->dp_typ;
|
||||
p[5] = d->dp_ehd;
|
||||
p[6] = d->dp_esect;
|
||||
p[7] = d->dp_ecyl;
|
||||
le32enc(p + 8, d->dp_start);
|
||||
le32enc(p + 12, d->dp_size);
|
||||
}
|
||||
|
|
|
|||
270
vold/inotify.c
270
vold/inotify.c
|
|
@ -1,270 +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 <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <dirent.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/inotify.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include "vold.h"
|
||||
#include "inotify.h"
|
||||
#include "blkdev.h"
|
||||
#include "volmgr.h"
|
||||
|
||||
#define DEBUG_INOTIFY 0
|
||||
|
||||
static int handle_inotify_event(struct inotify_event *evt);
|
||||
|
||||
int process_inotify_event(int fd)
|
||||
{
|
||||
char buffer[512];
|
||||
int len;
|
||||
int offset = 0;
|
||||
|
||||
if ((len = read(fd, buffer, sizeof(buffer))) < 0) {
|
||||
LOGE("Unable to read inotify event (%m)\n");
|
||||
return -errno;
|
||||
}
|
||||
|
||||
while (len >= (int) sizeof(struct inotify_event)) {
|
||||
struct inotify_event *evt = (struct inotify_event *) &buffer[offset];
|
||||
|
||||
if (handle_inotify_event(evt) < 0)
|
||||
LOGE("Error handling inotify event (%m)\n");
|
||||
|
||||
len -= sizeof(struct inotify_event) + evt->len;
|
||||
offset += sizeof(struct inotify_event) + evt->len;
|
||||
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct blk_dev_entry {
|
||||
int minor;
|
||||
char *name;
|
||||
struct blk_dev_entry *next;
|
||||
};
|
||||
|
||||
int inotify_bootstrap(void)
|
||||
{
|
||||
DIR *d;
|
||||
struct dirent *de;
|
||||
|
||||
if (!(d = opendir(DEVPATH))) {
|
||||
LOGE("Unable to open directory '%s' (%m)\n", DEVPATH);
|
||||
return -errno;
|
||||
}
|
||||
|
||||
struct blk_dev_entry *blkdevs[255];
|
||||
|
||||
memset(blkdevs, 0, sizeof(blkdevs));
|
||||
|
||||
while((de = readdir(d))) {
|
||||
char filename[255];
|
||||
struct stat sbuf;
|
||||
|
||||
if (de->d_name[0] == '.')
|
||||
continue;
|
||||
|
||||
sprintf(filename, "%s/%s", DEVPATH, de->d_name);
|
||||
|
||||
if (stat(filename, &sbuf) < 0) {
|
||||
LOGE("Unable to stat '%s' (%m)\n", filename);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!S_ISBLK(sbuf.st_mode))
|
||||
continue;
|
||||
|
||||
|
||||
int major = (sbuf.st_rdev & 0xfff00) >> 8;
|
||||
int minor = (sbuf.st_rdev & 0xff) | ((sbuf.st_rdev >> 12) & 0xfff00);
|
||||
|
||||
struct blk_dev_entry *entry;
|
||||
|
||||
if (!(entry = malloc(sizeof(struct blk_dev_entry)))) {
|
||||
LOGE("Out of memory\n");
|
||||
break;
|
||||
}
|
||||
entry->minor = minor;
|
||||
entry->name = strdup(de->d_name);
|
||||
entry->next = NULL;
|
||||
|
||||
if (!blkdevs[major])
|
||||
blkdevs[major] = entry;
|
||||
else {
|
||||
struct blk_dev_entry *scan = blkdevs[major];
|
||||
|
||||
/*
|
||||
* Insert the entry in minor number ascending order
|
||||
*/
|
||||
while(scan) {
|
||||
if (minor < scan->minor) {
|
||||
entry->next = scan;
|
||||
|
||||
if (scan == blkdevs[major])
|
||||
blkdevs[major] = entry;
|
||||
else
|
||||
scan->next = entry;
|
||||
break;
|
||||
}
|
||||
scan = scan->next;
|
||||
}
|
||||
if (!scan) {
|
||||
scan = blkdevs[major];
|
||||
while(scan->next)
|
||||
scan = scan->next;
|
||||
scan->next = entry;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
closedir(d);
|
||||
|
||||
int i = 0;
|
||||
|
||||
for (i = 0; i < 255; i++) {
|
||||
if (!blkdevs[i])
|
||||
continue;
|
||||
struct blk_dev_entry *scan = blkdevs[i];
|
||||
|
||||
while(scan) {
|
||||
struct inotify_event *evt;
|
||||
int len;
|
||||
|
||||
len = sizeof(struct inotify_event) + strlen(scan->name);
|
||||
|
||||
if (!(evt = malloc(len))) {
|
||||
LOGE("Out of memory\n");
|
||||
break;
|
||||
}
|
||||
memset(evt, 0, len);
|
||||
strcpy(evt->name, scan->name);
|
||||
evt->mask = IN_CREATE;
|
||||
|
||||
if (handle_inotify_event(evt) < 0)
|
||||
LOGE("Error handling bootstrapped inotify event (%m)\n");
|
||||
free(evt);
|
||||
|
||||
scan = scan->next;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < 255; i++) {
|
||||
if (!blkdevs[i])
|
||||
continue;
|
||||
|
||||
if (!blkdevs[i]->next) {
|
||||
free(blkdevs[i]->name);
|
||||
free(blkdevs[i]);
|
||||
blkdevs[i] = NULL;
|
||||
continue;
|
||||
}
|
||||
|
||||
struct blk_dev_entry *scan = blkdevs[i];
|
||||
while(scan) {
|
||||
struct blk_dev_entry *next = scan->next->next;
|
||||
|
||||
free(scan->next->name);
|
||||
free(scan->next);
|
||||
|
||||
scan->next = next;
|
||||
scan = next;
|
||||
}
|
||||
|
||||
} // for
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int handle_inotify_event(struct inotify_event *evt)
|
||||
{
|
||||
char filename[255];
|
||||
int rc;
|
||||
|
||||
#if DEBUG_INOTIFY
|
||||
LOG_VOL("Inotify '%s' %s\n", evt->name, (evt->mask == IN_CREATE ? "created" : "deleted"));
|
||||
#endif
|
||||
|
||||
sprintf(filename, "%s%s", DEVPATH, evt->name);
|
||||
|
||||
if (evt->mask == IN_CREATE) {
|
||||
struct stat sbuf;
|
||||
|
||||
if (stat(filename, &sbuf) < 0) {
|
||||
LOGE("Unable to stat '%s' (%m)\n", filename);
|
||||
return -errno;
|
||||
}
|
||||
|
||||
if (!S_ISBLK(sbuf.st_mode)) {
|
||||
#if DEBUG_INOTIFY
|
||||
LOG_VOL("Ignoring inotify on '%s' (not a block device)\n", evt->name);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
int major = (sbuf.st_rdev & 0xfff00) >> 8;
|
||||
int minor = (sbuf.st_rdev & 0xff) | ((sbuf.st_rdev >> 12) & 0xfff00);
|
||||
|
||||
blkdev_t *blkdev = blkdev_lookup_by_devno(major, minor);
|
||||
|
||||
if ((rc = blkdev_handle_devicefile_created(blkdev, filename)) < 0) {
|
||||
LOGE("Error handling device file '%s' creation (%s)\n", filename, strerror(rc));
|
||||
return rc;
|
||||
}
|
||||
|
||||
if (!blkdev) {
|
||||
#if DEBUG_INOTIFY
|
||||
LOG_VOL("No backing blkdev for '%s' available (yet) - pending volmgr dispatch\n", filename);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if DEBUG_INOTIFY
|
||||
LOG_VOL("NUM_PENDING_PARTITIONS = %d\n", blkdev_get_num_pending_partitions(blkdev));
|
||||
#endif
|
||||
if (blkdev_get_num_pending_partitions(blkdev->disk) == 0) {
|
||||
if ((rc = volmgr_consider_disk(blkdev->disk)) < 0) {
|
||||
LOGE("Error from volmgr - %d\n", rc);
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
blkdev_t *blkdev;
|
||||
|
||||
if (!(blkdev = blkdev_lookup_by_dev_fspath(filename))) {
|
||||
#if DEBUG_INOTIFY
|
||||
LOG_VOL("Ignoring removal of '%s' (no backend blkdev)\n", filename);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((rc = blkdev_handle_devicefile_removed(blkdev, filename)) < 0) {
|
||||
LOGE("Error handling device file '%s' removal (%s)\n", filename, strerror(rc));
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -95,7 +95,7 @@ void child(int argc, char* argv[]) {
|
|||
// XXX: PROTECT FROM VIKING KILLER
|
||||
if (execvp(argv_child[0], argv_child)) {
|
||||
LOG(LOG_ERROR, "logwrapper",
|
||||
"executing %s failed: %s\n", argv_child[0], strerror(errno));
|
||||
"executing %s failed: %s", argv_child[0], strerror(errno));
|
||||
exit(-1);
|
||||
}
|
||||
}
|
||||
|
|
@ -111,24 +111,24 @@ int logwrap(int argc, char* argv[], pid_t *childPid)
|
|||
/* Use ptty instead of socketpair so that STDOUT is not buffered */
|
||||
parent_ptty = open("/dev/ptmx", O_RDWR);
|
||||
if (parent_ptty < 0) {
|
||||
LOG(LOG_ERROR, "logwrapper", "Cannot create parent ptty\n");
|
||||
LOG(LOG_ERROR, "logwrapper", "Cannot create parent ptty");
|
||||
return -errno;
|
||||
}
|
||||
|
||||
if (grantpt(parent_ptty) || unlockpt(parent_ptty) ||
|
||||
((child_devname = (char*)ptsname(parent_ptty)) == 0)) {
|
||||
LOG(LOG_ERROR, "logwrapper", "Problem with /dev/ptmx\n");
|
||||
LOG(LOG_ERROR, "logwrapper", "Problem with /dev/ptmx");
|
||||
return -1;
|
||||
}
|
||||
|
||||
pid = fork();
|
||||
if (pid < 0) {
|
||||
LOG(LOG_ERROR, "logwrapper", "Failed to fork\n");
|
||||
LOG(LOG_ERROR, "logwrapper", "Failed to fork");
|
||||
return -errno;
|
||||
} else if (pid == 0) {
|
||||
child_ptty = open(child_devname, O_RDWR);
|
||||
if (child_ptty < 0) {
|
||||
LOG(LOG_ERROR, "logwrapper", "Problem with child ptty\n");
|
||||
LOG(LOG_ERROR, "logwrapper", "Problem with child ptty");
|
||||
return -errno;
|
||||
}
|
||||
|
||||
|
|
|
|||
10
vold/media.c
10
vold/media.c
|
|
@ -85,8 +85,8 @@ void media_destroy(media_t *media)
|
|||
free(media->devpath);
|
||||
free(media->name);
|
||||
|
||||
if (media->devs)
|
||||
LOGE("media_destroy(): media still has blkdevs associated with it! Possible leak\n");
|
||||
while(media->devs)
|
||||
media_remove_blkdev(media, media->devs->dev);
|
||||
free(media);
|
||||
}
|
||||
|
||||
|
|
@ -105,7 +105,7 @@ media_t *media_lookup_by_path(char *devpath, boolean fuzzy_match)
|
|||
list_scan = list_scan->next;
|
||||
}
|
||||
#if DEBUG_MEDIA
|
||||
LOG_VOL("media_lookup_by_path(): No media found @ %s\n", devpath);
|
||||
LOG_VOL("media_lookup_by_path(): No media found @ %s", devpath);
|
||||
#endif
|
||||
return NULL;
|
||||
}
|
||||
|
|
@ -114,10 +114,8 @@ int media_add_blkdev(media_t *card, blkdev_t *dev)
|
|||
{
|
||||
blkdev_list_t *list_entry;
|
||||
|
||||
if (!(list_entry = malloc(sizeof(blkdev_list_t)))) {
|
||||
LOGE("Out of memory\n");
|
||||
if (!(list_entry = malloc(sizeof(blkdev_list_t))))
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
list_entry->next = NULL;
|
||||
list_entry->dev = dev;
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@
|
|||
typedef enum media_type {
|
||||
media_unknown,
|
||||
media_mmc,
|
||||
media_dm
|
||||
media_devmapper,
|
||||
} media_type_t;
|
||||
|
||||
typedef struct media {
|
||||
|
|
|
|||
44
vold/mmc.c
44
vold/mmc.c
|
|
@ -43,7 +43,7 @@ int mmc_bootstrap()
|
|||
struct dirent *de;
|
||||
|
||||
if (!(d = opendir(SYSFS_CLASS_MMC_PATH))) {
|
||||
LOG_ERROR("Unable to open '%s' (%m)\n", SYSFS_CLASS_MMC_PATH);
|
||||
LOG_ERROR("Unable to open '%s' (%m)", SYSFS_CLASS_MMC_PATH);
|
||||
return -errno;
|
||||
}
|
||||
|
||||
|
|
@ -55,7 +55,7 @@ int mmc_bootstrap()
|
|||
|
||||
sprintf(tmp, "%s/%s", SYSFS_CLASS_MMC_PATH, de->d_name);
|
||||
if (mmc_bootstrap_controller(tmp))
|
||||
LOG_ERROR("Error bootstrapping controller '%s' (%m)\n", tmp);
|
||||
LOG_ERROR("Error bootstrapping controller '%s' (%m)", tmp);
|
||||
}
|
||||
|
||||
closedir(d);
|
||||
|
|
@ -69,10 +69,10 @@ static int mmc_bootstrap_controller(char *sysfs_path)
|
|||
struct dirent *de;
|
||||
|
||||
#if DEBUG_BOOTSTRAP
|
||||
LOG_VOL("bootstrap_controller(%s):\n", sysfs_path);
|
||||
LOG_VOL("bootstrap_controller(%s):", sysfs_path);
|
||||
#endif
|
||||
if (!(d = opendir(sysfs_path))) {
|
||||
LOG_ERROR("Unable to open '%s' (%m)\n", sysfs_path);
|
||||
LOG_ERROR("Unable to open '%s' (%m)", sysfs_path);
|
||||
return -errno;
|
||||
}
|
||||
|
||||
|
|
@ -92,7 +92,7 @@ static int mmc_bootstrap_controller(char *sysfs_path)
|
|||
sprintf(tmp, "%s/%s", sysfs_path, de->d_name);
|
||||
|
||||
if (mmc_bootstrap_card(tmp) < 0)
|
||||
LOG_ERROR("Error bootstrapping card '%s' (%m)\n", tmp);
|
||||
LOG_ERROR("Error bootstrapping card '%s' (%m)", tmp);
|
||||
} // while
|
||||
|
||||
closedir(d);
|
||||
|
|
@ -111,29 +111,29 @@ static int mmc_bootstrap_card(char *sysfs_path)
|
|||
ssize_t sz;
|
||||
|
||||
#if DEBUG_BOOTSTRAP
|
||||
LOG_VOL("bootstrap_card(%s):\n", sysfs_path);
|
||||
LOG_VOL("bootstrap_card(%s):", sysfs_path);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* sysfs_path is based on /sys/class, but we want the actual device class
|
||||
*/
|
||||
if (!getcwd(saved_cwd, sizeof(saved_cwd))) {
|
||||
LOGE("Buffer too small for working dir path\n");
|
||||
LOGE("Error getting working dir path");
|
||||
return -errno;
|
||||
}
|
||||
|
||||
if (chdir(sysfs_path) < 0) {
|
||||
LOGE("Unable to chdir to %s (%m)\n", sysfs_path);
|
||||
LOGE("Unable to chdir to %s (%m)", sysfs_path);
|
||||
return -errno;
|
||||
}
|
||||
|
||||
if (!getcwd(new_cwd, sizeof(new_cwd))) {
|
||||
LOGE("Buffer too small for device path\n");
|
||||
LOGE("Buffer too small for device path");
|
||||
return -errno;
|
||||
}
|
||||
|
||||
if (chdir(saved_cwd) < 0) {
|
||||
LOGE("Unable to restore working dir\n");
|
||||
LOGE("Unable to restore working dir");
|
||||
return -errno;
|
||||
}
|
||||
|
||||
|
|
@ -162,7 +162,7 @@ static int mmc_bootstrap_card(char *sysfs_path)
|
|||
uevent_params[3] = (char *) NULL;
|
||||
|
||||
if (simulate_uevent("mmc", devpath, "add", uevent_params) < 0) {
|
||||
LOGE("Error simulating uevent (%m)\n");
|
||||
LOGE("Error simulating uevent (%m)");
|
||||
return -errno;
|
||||
}
|
||||
|
||||
|
|
@ -174,7 +174,7 @@ static int mmc_bootstrap_card(char *sysfs_path)
|
|||
sprintf(filename, "/sys%s/block", devpath);
|
||||
if (!access(filename, F_OK)) {
|
||||
if (mmc_bootstrap_block(tmp)) {
|
||||
LOGE("Error bootstrapping block @ %s\n", tmp);
|
||||
LOGE("Error bootstrapping block @ %s", tmp);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -188,13 +188,13 @@ static int mmc_bootstrap_block(char *devpath)
|
|||
struct dirent *de;
|
||||
|
||||
#if DEBUG_BOOTSTRAP
|
||||
LOG_VOL("mmc_bootstrap_block(%s):\n", devpath);
|
||||
LOG_VOL("mmc_bootstrap_block(%s):", devpath);
|
||||
#endif
|
||||
|
||||
sprintf(blockdir_path, "/sys%s", devpath);
|
||||
|
||||
if (!(d = opendir(blockdir_path))) {
|
||||
LOGE("Failed to opendir %s\n", devpath);
|
||||
LOGE("Failed to opendir %s", devpath);
|
||||
return -errno;
|
||||
}
|
||||
|
||||
|
|
@ -205,7 +205,7 @@ static int mmc_bootstrap_block(char *devpath)
|
|||
continue;
|
||||
sprintf(tmp, "%s/%s", devpath, de->d_name);
|
||||
if (mmc_bootstrap_mmcblk(tmp))
|
||||
LOGE("Error bootstraping mmcblk @ %s\n", tmp);
|
||||
LOGE("Error bootstraping mmcblk @ %s", tmp);
|
||||
}
|
||||
closedir(d);
|
||||
return 0;
|
||||
|
|
@ -218,11 +218,11 @@ static int mmc_bootstrap_mmcblk(char *devpath)
|
|||
int rc;
|
||||
|
||||
#if DEBUG_BOOTSTRAP
|
||||
LOG_VOL("mmc_bootstrap_mmcblk(%s):\n", devpath);
|
||||
LOG_VOL("mmc_bootstrap_mmcblk(%s):", devpath);
|
||||
#endif
|
||||
|
||||
if ((rc = mmc_bootstrap_mmcblk_partition(devpath))) {
|
||||
LOGE("Error bootstrapping mmcblk partition '%s'\n", devpath);
|
||||
LOGE("Error bootstrapping mmcblk partition '%s'", devpath);
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
|
@ -238,7 +238,7 @@ static int mmc_bootstrap_mmcblk(char *devpath)
|
|||
|
||||
sprintf(part_devpath, "%s/%sp%d", devpath, mmcblk_devname, part_no);
|
||||
if (mmc_bootstrap_mmcblk_partition(part_devpath))
|
||||
LOGE("Error bootstrapping mmcblk partition '%s'\n", part_devpath);
|
||||
LOGE("Error bootstrapping mmcblk partition '%s'", part_devpath);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -256,7 +256,7 @@ static int mmc_bootstrap_mmcblk_partition(char *devpath)
|
|||
char line[255];
|
||||
|
||||
#if DEBUG_BOOTSTRAP
|
||||
LOG_VOL("mmc_bootstrap_mmcblk_partition(%s):\n", devpath);
|
||||
LOG_VOL("mmc_bootstrap_mmcblk_partition(%s):", devpath);
|
||||
#endif
|
||||
|
||||
sprintf(tmp, "DEVPATH=%s", devpath);
|
||||
|
|
@ -264,7 +264,7 @@ static int mmc_bootstrap_mmcblk_partition(char *devpath)
|
|||
|
||||
sprintf(filename, "/sys%s/uevent", devpath);
|
||||
if (!(fp = fopen(filename, "r"))) {
|
||||
LOGE("Unable to open '%s' (%m)\n", filename);
|
||||
LOGE("Unable to open '%s' (%m)", filename);
|
||||
return -errno;
|
||||
}
|
||||
|
||||
|
|
@ -280,13 +280,13 @@ static int mmc_bootstrap_mmcblk_partition(char *devpath)
|
|||
fclose(fp);
|
||||
|
||||
if (!uevent_params[1] || !uevent_params[2] || !uevent_params[3]) {
|
||||
LOGE("mmcblk uevent missing required params\n");
|
||||
LOGE("mmcblk uevent missing required params");
|
||||
return -1;
|
||||
}
|
||||
uevent_params[4] = '\0';
|
||||
|
||||
if (simulate_uevent("block", devpath, "add", uevent_params) < 0) {
|
||||
LOGE("Error simulating uevent (%m)\n");
|
||||
LOGE("Error simulating uevent (%m)");
|
||||
return -errno;
|
||||
}
|
||||
return 0;
|
||||
|
|
|
|||
121
vold/switch.c
Normal file
121
vold/switch.c
Normal file
|
|
@ -0,0 +1,121 @@
|
|||
|
||||
/*
|
||||
* 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 <sys/types.h>
|
||||
|
||||
#include "vold.h"
|
||||
#include "switch.h"
|
||||
|
||||
#define DEBUG_BOOTSTRAP 0
|
||||
|
||||
static int mmc_bootstrap_switch(char *sysfs_path);
|
||||
|
||||
int switch_bootstrap()
|
||||
{
|
||||
DIR *d;
|
||||
struct dirent *de;
|
||||
|
||||
if (!(d = opendir(SYSFS_CLASS_SWITCH_PATH))) {
|
||||
LOG_ERROR("Unable to open '%s' (%m)", SYSFS_CLASS_SWITCH_PATH);
|
||||
return -errno;
|
||||
}
|
||||
|
||||
while ((de = readdir(d))) {
|
||||
char tmp[255];
|
||||
|
||||
if (de->d_name[0] == '.')
|
||||
continue;
|
||||
|
||||
sprintf(tmp, "%s/%s", SYSFS_CLASS_SWITCH_PATH, de->d_name);
|
||||
if (mmc_bootstrap_switch(tmp))
|
||||
LOG_ERROR("Error bootstrapping switch '%s' (%m)", tmp);
|
||||
}
|
||||
|
||||
closedir(d);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mmc_bootstrap_switch(char *sysfs_path)
|
||||
{
|
||||
#if DEBUG_BOOTSTRAP
|
||||
LOG_VOL("bootstrap_switch(%s):", sysfs_path);
|
||||
#endif
|
||||
|
||||
char filename[255];
|
||||
char name[255];
|
||||
char state[255];
|
||||
char tmp[255];
|
||||
char *uevent_params[3];
|
||||
char devpath[255];
|
||||
FILE *fp;
|
||||
|
||||
/*
|
||||
* Read switch name
|
||||
*/
|
||||
sprintf(filename, "%s/name", sysfs_path);
|
||||
if (!(fp = fopen(filename, "r"))) {
|
||||
LOGE("Error opening switch name path '%s' (%s)",
|
||||
sysfs_path, strerror(errno));
|
||||
return -errno;
|
||||
}
|
||||
if (!fgets(name, sizeof(name), fp)) {
|
||||
LOGE("Unable to read switch name");
|
||||
fclose(fp);
|
||||
return -EIO;
|
||||
}
|
||||
fclose(fp);
|
||||
|
||||
name[strlen(name) -1] = '\0';
|
||||
sprintf(devpath, "/devices/virtual/switch/%s", name);
|
||||
sprintf(tmp, "SWITCH_NAME=%s", name);
|
||||
uevent_params[0] = (char *) strdup(tmp);
|
||||
|
||||
/*
|
||||
* Read switch state
|
||||
*/
|
||||
sprintf(filename, "%s/state", sysfs_path);
|
||||
if (!(fp = fopen(filename, "r"))) {
|
||||
LOGE("Error opening switch state path '%s' (%s)",
|
||||
sysfs_path, strerror(errno));
|
||||
return -errno;
|
||||
}
|
||||
if (!fgets(state, sizeof(state), fp)) {
|
||||
LOGE("Unable to read switch state");
|
||||
fclose(fp);
|
||||
return -EIO;
|
||||
}
|
||||
fclose(fp);
|
||||
|
||||
state[strlen(state) -1] = '\0';
|
||||
sprintf(tmp, "SWITCH_STATE=%s", state);
|
||||
uevent_params[1] = (char *) strdup(tmp);
|
||||
|
||||
uevent_params[2] = (char *) NULL;
|
||||
|
||||
if (simulate_uevent("switch", devpath, "add", uevent_params) < 0) {
|
||||
LOGE("Error simulating uevent (%s)", strerror(errno));
|
||||
return -errno;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -15,8 +15,11 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef _INOTIFY_EVT_H
|
||||
#define _INOTIFY_EVT_H
|
||||
#ifndef _SWITCH_H
|
||||
#define _SWITCH_H
|
||||
|
||||
#include "vold.h"
|
||||
|
||||
#define SYSFS_CLASS_SWITCH_PATH "/sys/class/switch"
|
||||
|
||||
#endif
|
||||
152
vold/uevent.c
152
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);
|
||||
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 (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;
|
||||
}
|
||||
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))) {
|
||||
#if DEBUG_UEVENT
|
||||
LOG_VOL("We aren't handling blkdev @ %s\n", event->path);
|
||||
#endif
|
||||
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("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\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
|
||||
}
|
||||
|
||||
|
|
|
|||
24
vold/ums.c
24
vold/ums.c
|
|
@ -21,6 +21,8 @@
|
|||
#include "vold.h"
|
||||
#include "ums.h"
|
||||
|
||||
#define DEBUG_UMS 0
|
||||
|
||||
static boolean host_connected = false;
|
||||
static boolean ums_enabled = false;
|
||||
|
||||
|
|
@ -42,7 +44,9 @@ boolean ums_enabled_get()
|
|||
|
||||
void ums_hostconnected_set(boolean connected)
|
||||
{
|
||||
LOG_VOL("ums_hostconnected_set(%d):\n", connected);
|
||||
#if DEBUG_UMS
|
||||
LOG_VOL("ums_hostconnected_set(%d):", connected);
|
||||
#endif
|
||||
host_connected = connected;
|
||||
|
||||
if (!connected)
|
||||
|
|
@ -52,19 +56,19 @@ void ums_hostconnected_set(boolean connected)
|
|||
|
||||
int ums_enable(char *dev_fspath, char *lun_syspath)
|
||||
{
|
||||
LOG_VOL("ums_enable(%s, %s):\n", dev_fspath, lun_syspath);
|
||||
LOG_VOL("ums_enable(%s, %s):", dev_fspath, lun_syspath);
|
||||
|
||||
int fd;
|
||||
char filename[255];
|
||||
|
||||
sprintf(filename, "/sys/%s/file", lun_syspath);
|
||||
if ((fd = open(filename, O_WRONLY)) < 0) {
|
||||
LOGE("Unable to open '%s' (%s)\n", filename, strerror(errno));
|
||||
LOGE("Unable to open '%s' (%s)", filename, strerror(errno));
|
||||
return -errno;
|
||||
}
|
||||
|
||||
if (write(fd, dev_fspath, strlen(dev_fspath)) < 0) {
|
||||
LOGE("Unable to write to ums lunfile (%s)\n", strerror(errno));
|
||||
LOGE("Unable to write to ums lunfile (%s)", strerror(errno));
|
||||
close(fd);
|
||||
return -errno;
|
||||
}
|
||||
|
|
@ -75,21 +79,23 @@ int ums_enable(char *dev_fspath, char *lun_syspath)
|
|||
|
||||
int ums_disable(char *lun_syspath)
|
||||
{
|
||||
LOG_VOL("ums_disable(%s):\n", lun_syspath);
|
||||
#if DEBUG_UMS
|
||||
LOG_VOL("ums_disable(%s):", lun_syspath);
|
||||
#endif
|
||||
|
||||
int fd;
|
||||
char filename[255];
|
||||
|
||||
sprintf(filename, "/sys/%s/file", lun_syspath);
|
||||
if ((fd = open(filename, O_WRONLY)) < 0) {
|
||||
LOGE("Unable to open '%s' (%s)\n", filename, strerror(errno));
|
||||
LOGE("Unable to open '%s' (%s)", filename, strerror(errno));
|
||||
return -errno;
|
||||
}
|
||||
|
||||
char ch = 0;
|
||||
|
||||
if (write(fd, &ch, 1) < 0) {
|
||||
LOGE("Unable to write to ums lunfile (%s)\n", strerror(errno));
|
||||
LOGE("Unable to write to ums lunfile (%s)", strerror(errno));
|
||||
close(fd);
|
||||
return -errno;
|
||||
}
|
||||
|
|
@ -107,7 +113,9 @@ int ums_send_status(void)
|
|||
{
|
||||
int rc;
|
||||
|
||||
LOG_VOL("ums_send_status():\n");
|
||||
#if DEBUG_UMS
|
||||
LOG_VOL("ums_send_status():");
|
||||
#endif
|
||||
|
||||
rc = send_msg(ums_enabled_get() ? VOLD_EVT_UMS_ENABLED :
|
||||
VOLD_EVT_UMS_DISABLED);
|
||||
|
|
|
|||
76
vold/vold.c
76
vold/vold.c
|
|
@ -27,7 +27,6 @@
|
|||
#include <sys/select.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/inotify.h>
|
||||
#include <sys/un.h>
|
||||
|
||||
#include <cutils/config_utils.h>
|
||||
|
|
@ -57,12 +56,11 @@ static int fw_sock = -1;
|
|||
int main(int argc, char **argv)
|
||||
{
|
||||
int door_sock = -1;
|
||||
int inotify_sock = -1;
|
||||
int uevent_sock = -1;
|
||||
struct sockaddr_nl nladdr;
|
||||
int uevent_sz = 64 * 1024;
|
||||
|
||||
LOG_VOL("Android Volume Daemon version %d.%d\n", ver_major, ver_minor);
|
||||
LOGI("Android Volume Daemon version %d.%d", ver_major, ver_minor);
|
||||
|
||||
/*
|
||||
* Create all the various sockets we'll need
|
||||
|
|
@ -70,29 +68,18 @@ int main(int argc, char **argv)
|
|||
|
||||
// Socket to listen on for incomming framework connections
|
||||
if ((door_sock = android_get_control_socket(VOLD_SOCKET)) < 0) {
|
||||
LOGE("Obtaining file descriptor socket '%s' failed: %s\n",
|
||||
LOGE("Obtaining file descriptor socket '%s' failed: %s",
|
||||
VOLD_SOCKET, strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (listen(door_sock, 4) < 0) {
|
||||
LOGE("Unable to listen on fd '%d' for socket '%s': %s\n",
|
||||
LOGE("Unable to listen on fd '%d' for socket '%s': %s",
|
||||
door_sock, VOLD_SOCKET, strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// Socket to listen on for changes to /dev/block
|
||||
if ((inotify_sock = inotify_init()) < 0) {
|
||||
LOGE("Unable to initialize inotify interface (%s)\n", strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
fcntl(inotify_sock, F_SETFL, O_NONBLOCK | fcntl(inotify_sock, F_GETFL));
|
||||
|
||||
if (inotify_add_watch(inotify_sock, DEVPATH, IN_CREATE | IN_DELETE) < 0) {
|
||||
LOGE("Unable to add inotify watch (%s)\n", strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
mkdir("/dev/block/vold", 0755);
|
||||
|
||||
// Socket to listen on for uevent changes
|
||||
memset(&nladdr, 0, sizeof(nladdr));
|
||||
|
|
@ -102,18 +89,18 @@ int main(int argc, char **argv)
|
|||
|
||||
if ((uevent_sock = socket(PF_NETLINK,
|
||||
SOCK_DGRAM,NETLINK_KOBJECT_UEVENT)) < 0) {
|
||||
LOGE("Unable to create uevent socket: %s\n", strerror(errno));
|
||||
LOGE("Unable to create uevent socket: %s", strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (setsockopt(uevent_sock, SOL_SOCKET, SO_RCVBUFFORCE, &uevent_sz,
|
||||
sizeof(uevent_sz)) < 0) {
|
||||
LOGE("Unable to set uevent socket options: %s\n", strerror(errno));
|
||||
LOGE("Unable to set uevent socket options: %s", strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (bind(uevent_sock, (struct sockaddr *) &nladdr, sizeof(nladdr)) < 0) {
|
||||
LOGE("Unable to bind uevent socket: %s\n", strerror(errno));
|
||||
LOGE("Unable to bind uevent socket: %s", strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
|
@ -121,22 +108,22 @@ int main(int argc, char **argv)
|
|||
* Bootstrap
|
||||
*/
|
||||
|
||||
// Volume Manager
|
||||
volmgr_bootstrap();
|
||||
|
||||
// SD Card system
|
||||
mmc_bootstrap();
|
||||
|
||||
// USB Mass Storage
|
||||
ums_bootstrap();
|
||||
|
||||
// Volume Manager
|
||||
volmgr_bootstrap();
|
||||
|
||||
// Block device system
|
||||
inotify_bootstrap();
|
||||
// Switch
|
||||
switch_bootstrap();
|
||||
|
||||
/*
|
||||
* Main loop
|
||||
*/
|
||||
|
||||
LOG_VOL("Bootstrapping complete");
|
||||
while(1) {
|
||||
fd_set read_fds;
|
||||
struct timeval to;
|
||||
|
|
@ -146,12 +133,10 @@ int main(int argc, char **argv)
|
|||
to.tv_sec = (60 * 60);
|
||||
to.tv_usec = 0;
|
||||
|
||||
FD_ZERO(&read_fds);
|
||||
FD_SET(door_sock, &read_fds);
|
||||
if (door_sock > max)
|
||||
max = door_sock;
|
||||
FD_SET(inotify_sock, &read_fds);
|
||||
if (inotify_sock > max)
|
||||
max = inotify_sock;
|
||||
FD_SET(uevent_sock, &read_fds);
|
||||
if (uevent_sock > max)
|
||||
max = uevent_sock;
|
||||
|
|
@ -163,7 +148,7 @@ int main(int argc, char **argv)
|
|||
}
|
||||
|
||||
if ((rc = select(max + 1, &read_fds, NULL, NULL, &to)) < 0) {
|
||||
LOGE("select() failed (%s)\n", strerror(errno));
|
||||
LOGE("select() failed (%s)", strerror(errno));
|
||||
sleep(1);
|
||||
continue;
|
||||
}
|
||||
|
|
@ -178,42 +163,41 @@ int main(int argc, char **argv)
|
|||
|
||||
alen = sizeof(addr);
|
||||
|
||||
if (fw_sock != -1) {
|
||||
LOGE("Dropping duplicate framework connection");
|
||||
int tmp = accept(door_sock, &addr, &alen);
|
||||
close(tmp);
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((fw_sock = accept(door_sock, &addr, &alen)) < 0) {
|
||||
LOGE("Unable to accept framework connection (%s)\n",
|
||||
LOGE("Unable to accept framework connection (%s)",
|
||||
strerror(errno));
|
||||
}
|
||||
LOG_VOL("Accepted connection from framework\n");
|
||||
LOG_VOL("Accepted connection from framework");
|
||||
if ((rc = volmgr_send_states()) < 0) {
|
||||
LOGE("Unable to send volmgr status to framework (%d)\n", rc);
|
||||
LOGE("Unable to send volmgr status to framework (%d)", rc);
|
||||
}
|
||||
}
|
||||
|
||||
if (FD_ISSET(fw_sock, &read_fds)) {
|
||||
if ((rc = process_framework_command(fw_sock)) < 0) {
|
||||
if (rc == -ECONNRESET) {
|
||||
LOGE("Framework disconnected\n");
|
||||
LOGE("Framework disconnected");
|
||||
close(fw_sock);
|
||||
fw_sock = -1;
|
||||
} else {
|
||||
LOGE("Error processing framework command (%s)\n",
|
||||
LOGE("Error processing framework command (%s)",
|
||||
strerror(errno));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (FD_ISSET(inotify_sock, &read_fds)) {
|
||||
if ((rc = process_inotify_event(inotify_sock)) < 0) {
|
||||
LOGE("Error processing inotify msg (%s)\n", strerror(errno));
|
||||
}
|
||||
}
|
||||
|
||||
if (FD_ISSET(uevent_sock, &read_fds)) {
|
||||
if ((rc = process_uevent_message(uevent_sock)) < 0) {
|
||||
LOGE("Error processing uevent msg (%s)\n", strerror(errno));
|
||||
LOGE("Error processing uevent msg (%s)", strerror(errno));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
} // while
|
||||
|
||||
}
|
||||
|
|
@ -224,7 +208,7 @@ int send_msg(char* message)
|
|||
|
||||
pthread_mutex_lock(&write_mutex);
|
||||
|
||||
LOG_VOL("send_msg(%s):\n", message);
|
||||
// LOG_VOL("send_msg(%s):", message);
|
||||
|
||||
if (fw_sock >= 0)
|
||||
result = write(fw_sock, message, strlen(message) + 1);
|
||||
|
|
@ -240,7 +224,7 @@ int send_msg_with_data(char *message, char *data)
|
|||
|
||||
char* buffer = (char *)alloca(strlen(message) + strlen(data) + 1);
|
||||
if (!buffer) {
|
||||
LOGE("alloca failed in send_msg_with_data\n");
|
||||
LOGE("alloca failed in send_msg_with_data");
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -86,6 +86,8 @@ int ums_bootstrap(void);
|
|||
|
||||
int volmgr_bootstrap(void);
|
||||
|
||||
int switch_bootstrap(void);
|
||||
|
||||
void *read_file(char *filename, ssize_t *_size);
|
||||
char *truncate_sysfs_path(char *path, int num_elements_to_remove, char *buffer);
|
||||
char *read_sysfs_var(char *buffer, size_t maxlen, char *devpath, char *var);
|
||||
|
|
|
|||
732
vold/volmgr.c
732
vold/volmgr.c
File diff suppressed because it is too large
Load diff
|
|
@ -23,6 +23,7 @@
|
|||
#include "vold.h"
|
||||
#include "blkdev.h"
|
||||
#include "media.h"
|
||||
#include "devmapper.h"
|
||||
|
||||
#define PROP_EXTERNAL_STORAGE_STATE "EXTERNAL_STORAGE_STATE"
|
||||
|
||||
|
|
@ -70,15 +71,18 @@ typedef enum volume_state {
|
|||
volstate_ejecting,
|
||||
#define VOLD_EVT_EJECTING "volume_ejecting:"
|
||||
#define VOLD_ES_PVAL_EJECTING "ejecting"
|
||||
|
||||
volstate_formatting,
|
||||
} volume_state_t;
|
||||
|
||||
struct volume;
|
||||
|
||||
struct volmgr_fstable_entry {
|
||||
char *name;
|
||||
int (*identify_fn) (blkdev_t *dev);
|
||||
int (*check_fn) (blkdev_t *dev);
|
||||
int (*mount_fn) (blkdev_t *dev, struct volume *vol);
|
||||
int (*identify_fn) (blkdev_t *dev);
|
||||
int (*check_fn) (blkdev_t *dev);
|
||||
int (*mount_fn) (blkdev_t *dev, struct volume *vol, boolean safe_mode);
|
||||
boolean case_sensitive_paths;
|
||||
};
|
||||
|
||||
struct volmgr_start_args {
|
||||
|
|
@ -86,21 +90,35 @@ struct volmgr_start_args {
|
|||
blkdev_t *dev;
|
||||
};
|
||||
|
||||
struct volmgr_reaper_args {
|
||||
void (*cb) (struct volume *, void *);
|
||||
void *cb_arg;
|
||||
};
|
||||
|
||||
#define VOLMGR_MAX_MEDIAPATHS_PER_VOLUME 8
|
||||
|
||||
typedef struct volume {
|
||||
char *media_path;
|
||||
media_type_t media_type;
|
||||
char *mount_point;
|
||||
char *ums_path;
|
||||
char *media_paths[VOLMGR_MAX_MEDIAPATHS_PER_VOLUME];
|
||||
|
||||
media_type_t media_type;
|
||||
char *mount_point;
|
||||
char *ums_path;
|
||||
struct devmapping *dm;
|
||||
|
||||
pthread_mutex_t lock;
|
||||
volume_state_t state;
|
||||
blkdev_t *dev;
|
||||
pid_t worker_pid;
|
||||
pthread_t worker_thread;
|
||||
struct volmgr_start_args worker_args;
|
||||
union {
|
||||
struct volmgr_start_args start_args;
|
||||
struct volmgr_reaper_args reaper_args;
|
||||
} worker_args;
|
||||
boolean worker_running;
|
||||
pthread_mutex_t worker_sem;
|
||||
|
||||
struct volmgr_fstable_entry *fs;
|
||||
|
||||
struct volume *next;
|
||||
} volume_t;
|
||||
|
||||
|
|
@ -110,6 +128,8 @@ int volmgr_send_states(void);
|
|||
int volmgr_enable_ums(boolean enable);
|
||||
int volmgr_stop_volume_by_mountpoint(char *mount_point);
|
||||
int volmgr_start_volume_by_mountpoint(char *mount_point);
|
||||
|
||||
int volmgr_safe_mode(boolean enable);
|
||||
int volmgr_format_volume(char *mount_point);
|
||||
int volmgr_set_volume_key(char *mount_point, unsigned char *key);
|
||||
void KillProcessesWithOpenFiles(const char* mountPoint, boolean sigkill, int *excluded, int num_excluded);
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -15,34 +15,170 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/mount.h>
|
||||
|
||||
#include <linux/ext2_fs.h>
|
||||
#include <linux/ext3_fs.h>
|
||||
|
||||
#include "vold.h"
|
||||
#include "volmgr.h"
|
||||
#include "volmgr_ext3.h"
|
||||
#include "logwrapper.h"
|
||||
|
||||
#define EXT3_DEBUG 0
|
||||
|
||||
int ext3_identify(blkdev_t *dev)
|
||||
#define EXT_DEBUG 0
|
||||
|
||||
static char E2FSCK_PATH[] = "/system/bin/e2fsck";
|
||||
|
||||
int ext_identify(blkdev_t *dev)
|
||||
{
|
||||
#if EXT3_DEBUG
|
||||
LOG_VOL("ext3_identify(%s):\n", dev->dev_fspath);
|
||||
int rc = -1;
|
||||
int fd;
|
||||
struct ext3_super_block sb;
|
||||
char *devpath;
|
||||
|
||||
#if EXT_DEBUG
|
||||
LOG_VOL("ext_identify(%d:%d):", dev-major, dev->minor);
|
||||
#endif
|
||||
return -ENOSYS;
|
||||
|
||||
devpath = blkdev_get_devpath(dev);
|
||||
|
||||
if ((fd = open(devpath, O_RDWR)) < 0) {
|
||||
LOGE("Unable to open device '%s' (%s)", devpath,
|
||||
strerror(errno));
|
||||
free(devpath);
|
||||
return -errno;
|
||||
}
|
||||
|
||||
if (lseek(fd, 1024, SEEK_SET) < 0) {
|
||||
LOGE("Unable to lseek to get superblock (%s)", strerror(errno));
|
||||
rc = -errno;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (read(fd, &sb, sizeof(sb)) != sizeof(sb)) {
|
||||
LOGE("Unable to read superblock (%s)", strerror(errno));
|
||||
rc = -errno;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (sb.s_magic == EXT2_SUPER_MAGIC ||
|
||||
sb.s_magic == EXT3_SUPER_MAGIC)
|
||||
rc = 0;
|
||||
else
|
||||
rc = -ENODATA;
|
||||
|
||||
out:
|
||||
#if EXT_DEBUG
|
||||
LOG_VOL("ext_identify(%s): rc = %d", devpath, rc);
|
||||
#endif
|
||||
free(devpath);
|
||||
close(fd);
|
||||
return rc;
|
||||
}
|
||||
|
||||
int ext3_check(blkdev_t *dev)
|
||||
int ext_check(blkdev_t *dev)
|
||||
{
|
||||
#if EXT3_DEBUG
|
||||
LOG_VOL("ext3_check(%s):\n", dev->dev_fspath);
|
||||
char *devpath;
|
||||
|
||||
#if EXT_DEBUG
|
||||
LOG_VOL("ext_check(%s):", dev->dev_fspath);
|
||||
#endif
|
||||
return -ENOSYS;
|
||||
|
||||
devpath = blkdev_get_devpath(dev);
|
||||
|
||||
if (access(E2FSCK_PATH, X_OK)) {
|
||||
LOGE("ext_check(%s): %s not found (skipping checks)",
|
||||
devpath, E2FSCK_PATH);
|
||||
free(devpath);
|
||||
return 0;
|
||||
}
|
||||
|
||||
char *args[5];
|
||||
|
||||
args[0] = E2FSCK_PATH;
|
||||
args[1] = "-v";
|
||||
args[2] = "-p";
|
||||
args[3] = devpath;
|
||||
args[4] = NULL;
|
||||
|
||||
int rc = logwrap(4, args);
|
||||
|
||||
if (rc == 0) {
|
||||
LOG_VOL("filesystem '%s' had no errors", devpath);
|
||||
} else if (rc == 1) {
|
||||
LOG_VOL("filesystem '%s' had corrected errors", devpath);
|
||||
rc = 0;
|
||||
} else if (rc == 2) {
|
||||
LOGE("VOL volume '%s' had corrected errors (system should be rebooted)", devpath);
|
||||
rc = -EIO;
|
||||
} else if (rc == 4) {
|
||||
LOGE("VOL volume '%s' had uncorrectable errors", devpath);
|
||||
rc = -EIO;
|
||||
} else if (rc == 8) {
|
||||
LOGE("Operational error while checking volume '%s'", devpath);
|
||||
rc = -EIO;
|
||||
} else {
|
||||
LOGE("Unknown e2fsck exit code (%d)", rc);
|
||||
rc = -EIO;
|
||||
}
|
||||
free(devpath);
|
||||
return rc;
|
||||
}
|
||||
|
||||
int ext3_mount(blkdev_t *dev, volume_t *vol)
|
||||
int ext_mount(blkdev_t *dev, volume_t *vol, boolean safe_mode)
|
||||
{
|
||||
#if EXT3_DEBUG
|
||||
LOG_VOL("ext3_mount(%s, %s):\n", dev->dev_fspath, vol->mount_point);
|
||||
#if EXT_DEBUG
|
||||
LOG_VOL("ext_mount(%s, %s, %d):", dev->dev_fspath, vol->mount_point, safe_mode);
|
||||
#endif
|
||||
return -ENOSYS;
|
||||
|
||||
char *fs[] = { "ext3", "ext2", NULL };
|
||||
char *devpath;
|
||||
|
||||
devpath = blkdev_get_devpath(dev);
|
||||
|
||||
int flags, rc = 0;
|
||||
|
||||
flags = MS_NODEV | MS_NOEXEC | MS_NOSUID | MS_NOATIME | MS_NODIRATIME;
|
||||
|
||||
if (safe_mode)
|
||||
flags |= MS_SYNCHRONOUS;
|
||||
|
||||
if (vol->state == volstate_mounted) {
|
||||
LOG_VOL("Remounting %s on %s, safe mode %d", devpath,
|
||||
vol->mount_point, safe_mode);
|
||||
flags |= MS_REMOUNT;
|
||||
}
|
||||
|
||||
char **f;
|
||||
for (f = fs; *f != NULL; f++) {
|
||||
rc = mount(devpath, vol->mount_point, *f, flags, NULL);
|
||||
if (rc && errno == EROFS) {
|
||||
LOGE("ext_mount(%s, %s): Read only filesystem - retrying mount RO",
|
||||
devpath, vol->mount_point);
|
||||
flags |= MS_RDONLY;
|
||||
rc = mount(devpath, vol->mount_point, *f, flags, NULL);
|
||||
}
|
||||
#if EXT_DEBUG
|
||||
LOG_VOL("ext_mount(%s, %s): %s mount rc = %d", devpath, *f,
|
||||
vol->mount_point, rc);
|
||||
#endif
|
||||
if (!rc)
|
||||
break;
|
||||
}
|
||||
free(devpath);
|
||||
|
||||
// Chmod the mount point so that its a free-for-all.
|
||||
// (required for consistency with VFAT.. sigh)
|
||||
if (chmod(vol->mount_point, 0777) < 0) {
|
||||
LOGE("Failed to chmod %s (%s)", vol->mount_point, strerror(errno));
|
||||
return -errno;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,9 +21,7 @@
|
|||
#include "volmgr.h"
|
||||
#include "blkdev.h"
|
||||
|
||||
|
||||
|
||||
int ext3_identify(blkdev_t *blkdev);
|
||||
int ext3_check(blkdev_t *blkdev);
|
||||
int ext3_mount(blkdev_t *blkdev, volume_t *vol);
|
||||
int ext_identify(blkdev_t *blkdev);
|
||||
int ext_check(blkdev_t *blkdev);
|
||||
int ext_mount(blkdev_t *blkdev, volume_t *vol, boolean safe_mode);
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ static char FSCK_MSDOS_PATH[] = "/system/bin/dosfsck";
|
|||
int vfat_identify(blkdev_t *dev)
|
||||
{
|
||||
#if VFAT_DEBUG
|
||||
LOG_VOL("vfat_identify(%s):\n", dev->dev_fspath);
|
||||
LOG_VOL("vfat_identify(%d:%d):", dev->major, dev->minor);
|
||||
#endif
|
||||
return 0; // XXX: Implement
|
||||
}
|
||||
|
|
@ -41,12 +41,12 @@ int vfat_check(blkdev_t *dev)
|
|||
int rc;
|
||||
|
||||
#if VFAT_DEBUG
|
||||
LOG_VOL("vfat_check(%s):\n", dev->dev_fspath);
|
||||
LOG_VOL("vfat_check(%d:%d):", dev->major, dev->minor);
|
||||
#endif
|
||||
|
||||
if (access(FSCK_MSDOS_PATH, X_OK)) {
|
||||
LOGE("vfat_check(%s): %s not found (skipping checks)\n",
|
||||
FSCK_MSDOS_PATH, dev->dev_fspath);
|
||||
LOGE("vfat_check(%d:%d): %s not found (skipping checks)",
|
||||
dev->major, dev->minor, FSCK_MSDOS_PATH);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -57,61 +57,77 @@ int vfat_check(blkdev_t *dev)
|
|||
args[2] = "-V";
|
||||
args[3] = "-w";
|
||||
args[4] = "-p";
|
||||
args[5] = dev->dev_fspath;
|
||||
args[5] = blkdev_get_devpath(dev);
|
||||
args[6] = NULL;
|
||||
rc = logwrap(6, args);
|
||||
free(args[5]);
|
||||
#else
|
||||
char *args[6];
|
||||
args[0] = FSCK_MSDOS_PATH;
|
||||
args[1] = "-v";
|
||||
args[2] = "-w";
|
||||
args[3] = "-p";
|
||||
args[4] = dev->dev_fspath;
|
||||
args[4] = blkdev_get_devpath(dev);
|
||||
args[5] = NULL;
|
||||
rc = logwrap(5, args);
|
||||
free(args[4]);
|
||||
#endif
|
||||
|
||||
if (rc == 0) {
|
||||
LOG_VOL("Filesystem check completed OK\n");
|
||||
LOG_VOL("Filesystem check completed OK");
|
||||
return 0;
|
||||
} else if (rc == 1) {
|
||||
LOG_VOL("Filesystem check failed (general failure)\n");
|
||||
LOG_VOL("Filesystem check failed (general failure)");
|
||||
return -EINVAL;
|
||||
} else if (rc == 2) {
|
||||
LOG_VOL("Filesystem check failed (invalid usage)\n");
|
||||
LOG_VOL("Filesystem check failed (invalid usage)");
|
||||
return -EIO;
|
||||
} else if (rc == 4) {
|
||||
LOG_VOL("Filesystem check completed (errors fixed)\n");
|
||||
LOG_VOL("Filesystem check completed (errors fixed)");
|
||||
} else if (rc == 8) {
|
||||
LOG_VOL("Filesystem check failed (not a FAT filesystem)");
|
||||
return -ENODATA;
|
||||
} else {
|
||||
LOG_VOL("Filesystem check failed (unknown exit code %d)\n", rc);
|
||||
LOG_VOL("Filesystem check failed (unknown exit code %d)", rc);
|
||||
return -EIO;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int vfat_mount(blkdev_t *dev, volume_t *vol)
|
||||
int vfat_mount(blkdev_t *dev, volume_t *vol, boolean safe_mode)
|
||||
{
|
||||
int flags, rc;
|
||||
char *devpath;
|
||||
|
||||
devpath = blkdev_get_devpath(dev);
|
||||
|
||||
#if VFAT_DEBUG
|
||||
LOG_VOL("vfat_mount(%s, %s):\n", dev->dev_fspath, vol->mount_point);
|
||||
LOG_VOL("vfat_mount(%d:%d, %s, %d):", dev->major, dev->minor, vol->mount_point, safe_mode);
|
||||
#endif
|
||||
|
||||
flags = MS_NODEV | MS_NOEXEC | MS_NOSUID | MS_DIRSYNC;
|
||||
rc = mount(dev->dev_fspath, vol->mount_point, "vfat", flags,
|
||||
"utf8,uid=1000,gid=1000,fmask=711,dmask=700");
|
||||
|
||||
if (vol->state == volstate_mounted) {
|
||||
LOG_VOL("Remounting %d:%d on %s, safe mode %d", dev->major,
|
||||
dev->minor, vol->mount_point, safe_mode);
|
||||
flags |= MS_REMOUNT;
|
||||
}
|
||||
|
||||
rc = mount(devpath, vol->mount_point, "vfat", flags,
|
||||
"utf8,uid=1000,gid=1000,fmask=711,dmask=700,shortname=mixed");
|
||||
|
||||
if (rc && errno == EROFS) {
|
||||
LOGE("vfat_mount(%s, %s): Read only filesystem - retrying mount RO\n",
|
||||
dev->dev_fspath, vol->mount_point);
|
||||
LOGE("vfat_mount(%d:%d, %s): Read only filesystem - retrying mount RO",
|
||||
dev->major, dev->minor, vol->mount_point);
|
||||
flags |= MS_RDONLY;
|
||||
rc = mount(dev->dev_fspath, vol->mount_point, "vfat", flags,
|
||||
"utf8,uid=1000,gid=1000,fmask=711,dmask=700");
|
||||
rc = mount(devpath, vol->mount_point, "vfat", flags,
|
||||
"utf8,uid=1000,gid=1000,fmask=711,dmask=700,shortname=mixed");
|
||||
}
|
||||
|
||||
#if VFAT_DEBUG
|
||||
LOG_VOL("vfat_mount(%s, %s): mount rc = %d\n", dev->dev_fspath,
|
||||
LOG_VOL("vfat_mount(%s, %d:%d): mount rc = %d", dev->major,k dev->minor,
|
||||
vol->mount_point, rc);
|
||||
#endif
|
||||
free (devpath);
|
||||
return rc;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,5 +25,5 @@
|
|||
|
||||
int vfat_identify(blkdev_t *blkdev);
|
||||
int vfat_check(blkdev_t *blkdev);
|
||||
int vfat_mount(blkdev_t *blkdev, volume_t *vol);
|
||||
int vfat_mount(blkdev_t *blkdev, volume_t *vol, boolean safe_mode);
|
||||
#endif
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue