vold: Bugfixes & cleanups
- Fix issue where container-names > 64 bytes were getting truncated in the
kernel. lo_name is only 64 bytes in length, so we now hash the container
id via md5
- Add 'dump' command to dump loop and devicemapper status
- Add 'debug' command to enable more detailed logging at runtime
- Log vold IPC arguments (minus encryption keys)
- Fix premature return from Loop::lookupActive() and friends
Change-Id: I0e833261a445ce9dc1a8187e5501d27daba1ca76
Signed-off-by: San Mehat <san@google.com>
diff --git a/Devmapper.cpp b/Devmapper.cpp
index c1aa713..ec36fdb 100644
--- a/Devmapper.cpp
+++ b/Devmapper.cpp
@@ -24,12 +24,92 @@
#include <sys/ioctl.h>
#include <sys/stat.h>
+#include <linux/kdev_t.h>
+
#define LOG_TAG "Vold"
#include <cutils/log.h>
+#include <sysutils/SocketClient.h>
+
#include "Devmapper.h"
+int Devmapper::dumpState(SocketClient *c) {
+
+ char *buffer = (char *) malloc(1024 * 64);
+ if (!buffer) {
+ LOGE("Error allocating memory (%s)", strerror(errno));
+ return -1;
+ }
+ memset(buffer, 0, (1024 * 64));
+
+ char *buffer2 = (char *) malloc(4096);
+ if (!buffer2) {
+ LOGE("Error allocating memory (%s)", strerror(errno));
+ free(buffer);
+ return -1;
+ }
+
+ int fd;
+ if ((fd = open("/dev/device-mapper", O_RDWR)) < 0) {
+ LOGE("Error opening devmapper (%s)", strerror(errno));
+ free(buffer);
+ free(buffer2);
+ return -1;
+ }
+
+ struct dm_ioctl *io = (struct dm_ioctl *) buffer;
+ ioctlInit(io, (1024 * 64), NULL, 0);
+
+ if (ioctl(fd, DM_LIST_DEVICES, io)) {
+ LOGE("DM_LIST_DEVICES ioctl failed (%s)", strerror(errno));
+ free(buffer);
+ free(buffer2);
+ close(fd);
+ return -1;
+ }
+
+ struct dm_name_list *n = (struct dm_name_list *) (((char *) buffer) + io->data_start);
+ if (!n->dev) {
+ free(buffer);
+ free(buffer2);
+ close(fd);
+ return 0;
+ }
+
+ unsigned nxt = 0;
+ do {
+ n = (struct dm_name_list *) (((char *) n) + nxt);
+
+ memset(buffer2, 0, 4096);
+ struct dm_ioctl *io2 = (struct dm_ioctl *) buffer2;
+ ioctlInit(io2, 4096, n->name, 0);
+ if (ioctl(fd, DM_DEV_STATUS, io2)) {
+ if (errno != ENXIO) {
+ LOGE("DM_DEV_STATUS ioctl failed (%s)", strerror(errno));
+ }
+ io2 = NULL;
+ }
+
+ char *tmp;
+ if (!io2) {
+ asprintf(&tmp, "%s %llu:%llu (no status available)", n->name, MAJOR(n->dev), MINOR(n->dev));
+ } else {
+ asprintf(&tmp, "%s %llu:%llu %d %d 0x%.8x %llu:%llu", n->name, MAJOR(n->dev),
+ MINOR(n->dev), io2->target_count, io2->open_count, io2->flags, MAJOR(io2->dev),
+ MINOR(io2->dev));
+ }
+ c->sendMsg(0, tmp, false);
+ free(tmp);
+ nxt = n->next;
+ } while (nxt);
+
+ free(buffer);
+ free(buffer2);
+ close(fd);
+ return 0;
+}
+
void Devmapper::ioctlInit(struct dm_ioctl *io, size_t dataSize,
const char *name, unsigned flags) {
memset(io, 0, dataSize);
@@ -39,7 +119,9 @@
io->version[1] = 0;
io->version[2] = 0;
io->flags = flags;
- strncpy(io->name, name, sizeof(io->name));
+ if (name) {
+ strncpy(io->name, name, sizeof(io->name));
+ }
}
int Devmapper::lookupActive(const char *name, char *ubuffer, size_t len) {