Skip to content

Commit d9a4e35

Browse files
author
San Mehat
committed
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 <[email protected]>
1 parent 2a5b8ce commit d9a4e35

14 files changed

+749
-41
lines changed

Android.mk

+2-1
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,8 @@ LOCAL_SRC_FILES:= \
2525
Loop.cpp \
2626
Devmapper.cpp \
2727
ResponseCode.cpp \
28-
Xwarp.cpp
28+
Xwarp.cpp \
29+
md5.c
2930

3031
LOCAL_MODULE:= vold
3132

CommandListener.cpp

+69-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
#include <errno.h>
2424
#include <fcntl.h>
2525

26-
#define LOG_TAG "CommandListener"
26+
#define LOG_TAG "VoldCmdListener"
2727
#include <cutils/log.h>
2828

2929
#include <sysutils/SocketClient.h>
@@ -33,22 +33,75 @@
3333
#include "ResponseCode.h"
3434
#include "Process.h"
3535
#include "Xwarp.h"
36+
#include "Loop.h"
37+
#include "Devmapper.h"
3638

3739
CommandListener::CommandListener() :
3840
FrameworkListener("vold") {
41+
registerCmd(new DumpCmd());
3942
registerCmd(new VolumeCmd());
4043
registerCmd(new AsecCmd());
4144
registerCmd(new ShareCmd());
4245
registerCmd(new StorageCmd());
4346
registerCmd(new XwarpCmd());
4447
}
4548

49+
void CommandListener::dumpArgs(int argc, char **argv, int argObscure) {
50+
char buffer[4096];
51+
char *p = buffer;
52+
53+
memset(buffer, 0, sizeof(buffer));
54+
int i;
55+
for (i = 0; i < argc; i++) {
56+
int len = strlen(argv[i]) + 1; // Account for space
57+
if (i == argObscure) {
58+
len += 2; // Account for {}
59+
}
60+
if (((p - buffer) + len) < (sizeof(buffer)-1)) {
61+
if (i == argObscure) {
62+
*p++ = '{';
63+
*p++ = '}';
64+
*p++ = ' ';
65+
continue;
66+
}
67+
strcpy(p, argv[i]);
68+
p+= strlen(argv[i]);
69+
if (i != (argc -1)) {
70+
*p++ = ' ';
71+
}
72+
}
73+
}
74+
LOGD("%s", buffer);
75+
}
76+
77+
CommandListener::DumpCmd::DumpCmd() :
78+
VoldCommand("dump") {
79+
}
80+
81+
int CommandListener::DumpCmd::runCommand(SocketClient *cli,
82+
int argc, char **argv) {
83+
cli->sendMsg(0, "Dumping loop status", false);
84+
if (Loop::dumpState(cli)) {
85+
cli->sendMsg(ResponseCode::CommandOkay, "Loop dump failed", true);
86+
}
87+
cli->sendMsg(0, "Dumping DM status", false);
88+
if (Devmapper::dumpState(cli)) {
89+
cli->sendMsg(ResponseCode::CommandOkay, "Devmapper dump failed", true);
90+
}
91+
92+
cli->sendMsg(ResponseCode::CommandOkay, "dump complete", false);
93+
return 0;
94+
}
95+
96+
4697
CommandListener::VolumeCmd::VolumeCmd() :
4798
VoldCommand("volume") {
4899
}
49100

50101
int CommandListener::VolumeCmd::runCommand(SocketClient *cli,
51102
int argc, char **argv) {
103+
dumpArgs(argc, argv, -1);
104+
52105
if (argc < 2) {
53106
cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing Argument", false);
54107
return 0;
@@ -59,6 +112,8 @@ int CommandListener::VolumeCmd::runCommand(SocketClient *cli,
59112

60113
if (!strcmp(argv[1], "list")) {
61114
return vm->listVolumes(cli);
115+
} else if (!strcmp(argv[1], "debug")) {
116+
vm->setDebug(true);
62117
} else if (!strcmp(argv[1], "mount")) {
63118
rc = vm->mountVolume(argv[2]);
64119
} else if (!strcmp(argv[1], "unmount")) {
@@ -105,6 +160,8 @@ CommandListener::ShareCmd::ShareCmd() :
105160

106161
int CommandListener::ShareCmd::runCommand(SocketClient *cli,
107162
int argc, char **argv) {
163+
dumpArgs(argc, argv, -1);
164+
108165
if (argc < 2) {
109166
cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing Argument", false);
110167
return 0;
@@ -136,6 +193,8 @@ CommandListener::StorageCmd::StorageCmd() :
136193

137194
int CommandListener::StorageCmd::runCommand(SocketClient *cli,
138195
int argc, char **argv) {
196+
dumpArgs(argc, argv, -1);
197+
139198
if (argc < 2) {
140199
cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing Argument", false);
141200
return 0;
@@ -194,6 +253,7 @@ int CommandListener::AsecCmd::runCommand(SocketClient *cli,
194253
int rc = 0;
195254

196255
if (!strcmp(argv[1], "list")) {
256+
dumpArgs(argc, argv, -1);
197257
DIR *d = opendir(Volume::SEC_ASECDIR);
198258

199259
if (!d) {
@@ -214,6 +274,7 @@ int CommandListener::AsecCmd::runCommand(SocketClient *cli,
214274
}
215275
closedir(d);
216276
} else if (!strcmp(argv[1], "create")) {
277+
dumpArgs(argc, argv, 5);
217278
if (argc != 7) {
218279
cli->sendMsg(ResponseCode::CommandSyntaxError,
219280
"Usage: asec create <container-id> <size_mb> <fstype> <key> <ownerUid>", false);
@@ -223,12 +284,14 @@ int CommandListener::AsecCmd::runCommand(SocketClient *cli,
223284
unsigned int numSectors = (atoi(argv[3]) * (1024 * 1024)) / 512;
224285
rc = vm->createAsec(argv[2], numSectors, argv[4], argv[5], atoi(argv[6]));
225286
} else if (!strcmp(argv[1], "finalize")) {
287+
dumpArgs(argc, argv, -1);
226288
if (argc != 3) {
227289
cli->sendMsg(ResponseCode::CommandSyntaxError, "Usage: asec finalize <container-id>", false);
228290
return 0;
229291
}
230292
rc = vm->finalizeAsec(argv[2]);
231293
} else if (!strcmp(argv[1], "destroy")) {
294+
dumpArgs(argc, argv, -1);
232295
if (argc < 3) {
233296
cli->sendMsg(ResponseCode::CommandSyntaxError, "Usage: asec destroy <container-id> [force]", false);
234297
return 0;
@@ -239,13 +302,15 @@ int CommandListener::AsecCmd::runCommand(SocketClient *cli,
239302
}
240303
rc = vm->destroyAsec(argv[2], force);
241304
} else if (!strcmp(argv[1], "mount")) {
305+
dumpArgs(argc, argv, 3);
242306
if (argc != 5) {
243307
cli->sendMsg(ResponseCode::CommandSyntaxError,
244308
"Usage: asec mount <namespace-id> <key> <ownerUid>", false);
245309
return 0;
246310
}
247311
rc = vm->mountAsec(argv[2], argv[3], atoi(argv[4]));
248312
} else if (!strcmp(argv[1], "unmount")) {
313+
dumpArgs(argc, argv, -1);
249314
if (argc < 3) {
250315
cli->sendMsg(ResponseCode::CommandSyntaxError, "Usage: asec unmount <container-id> [force]", false);
251316
return 0;
@@ -256,13 +321,15 @@ int CommandListener::AsecCmd::runCommand(SocketClient *cli,
256321
}
257322
rc = vm->unmountAsec(argv[2], force);
258323
} else if (!strcmp(argv[1], "rename")) {
324+
dumpArgs(argc, argv, -1);
259325
if (argc != 4) {
260326
cli->sendMsg(ResponseCode::CommandSyntaxError,
261327
"Usage: asec rename <old_id> <new_id>", false);
262328
return 0;
263329
}
264330
rc = vm->renameAsec(argv[2], argv[3]);
265331
} else if (!strcmp(argv[1], "path")) {
332+
dumpArgs(argc, argv, -1);
266333
if (argc != 3) {
267334
cli->sendMsg(ResponseCode::CommandSyntaxError, "Usage: asec path <container-id>", false);
268335
return 0;
@@ -276,6 +343,7 @@ int CommandListener::AsecCmd::runCommand(SocketClient *cli,
276343
}
277344
return 0;
278345
} else {
346+
dumpArgs(argc, argv, -1);
279347
cli->sendMsg(ResponseCode::CommandSyntaxError, "Unknown asec cmd", false);
280348
}
281349

CommandListener.h

+8
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,14 @@ class CommandListener : public FrameworkListener {
2626
virtual ~CommandListener() {}
2727

2828
private:
29+
static void dumpArgs(int argc, char **argv, int argObscure);
30+
31+
class DumpCmd : public VoldCommand {
32+
public:
33+
DumpCmd();
34+
virtual ~DumpCmd() {}
35+
int runCommand(SocketClient *c, int argc, char ** argv);
36+
};
2937

3038
class VolumeCmd : public VoldCommand {
3139
public:

Devmapper.cpp

+83-1
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,92 @@
2424
#include <sys/ioctl.h>
2525
#include <sys/stat.h>
2626

27+
#include <linux/kdev_t.h>
28+
2729
#define LOG_TAG "Vold"
2830

2931
#include <cutils/log.h>
3032

33+
#include <sysutils/SocketClient.h>
34+
3135
#include "Devmapper.h"
3236

37+
int Devmapper::dumpState(SocketClient *c) {
38+
39+
char *buffer = (char *) malloc(1024 * 64);
40+
if (!buffer) {
41+
LOGE("Error allocating memory (%s)", strerror(errno));
42+
return -1;
43+
}
44+
memset(buffer, 0, (1024 * 64));
45+
46+
char *buffer2 = (char *) malloc(4096);
47+
if (!buffer2) {
48+
LOGE("Error allocating memory (%s)", strerror(errno));
49+
free(buffer);
50+
return -1;
51+
}
52+
53+
int fd;
54+
if ((fd = open("/dev/device-mapper", O_RDWR)) < 0) {
55+
LOGE("Error opening devmapper (%s)", strerror(errno));
56+
free(buffer);
57+
free(buffer2);
58+
return -1;
59+
}
60+
61+
struct dm_ioctl *io = (struct dm_ioctl *) buffer;
62+
ioctlInit(io, (1024 * 64), NULL, 0);
63+
64+
if (ioctl(fd, DM_LIST_DEVICES, io)) {
65+
LOGE("DM_LIST_DEVICES ioctl failed (%s)", strerror(errno));
66+
free(buffer);
67+
free(buffer2);
68+
close(fd);
69+
return -1;
70+
}
71+
72+
struct dm_name_list *n = (struct dm_name_list *) (((char *) buffer) + io->data_start);
73+
if (!n->dev) {
74+
free(buffer);
75+
free(buffer2);
76+
close(fd);
77+
return 0;
78+
}
79+
80+
unsigned nxt = 0;
81+
do {
82+
n = (struct dm_name_list *) (((char *) n) + nxt);
83+
84+
memset(buffer2, 0, 4096);
85+
struct dm_ioctl *io2 = (struct dm_ioctl *) buffer2;
86+
ioctlInit(io2, 4096, n->name, 0);
87+
if (ioctl(fd, DM_DEV_STATUS, io2)) {
88+
if (errno != ENXIO) {
89+
LOGE("DM_DEV_STATUS ioctl failed (%s)", strerror(errno));
90+
}
91+
io2 = NULL;
92+
}
93+
94+
char *tmp;
95+
if (!io2) {
96+
asprintf(&tmp, "%s %llu:%llu (no status available)", n->name, MAJOR(n->dev), MINOR(n->dev));
97+
} else {
98+
asprintf(&tmp, "%s %llu:%llu %d %d 0x%.8x %llu:%llu", n->name, MAJOR(n->dev),
99+
MINOR(n->dev), io2->target_count, io2->open_count, io2->flags, MAJOR(io2->dev),
100+
MINOR(io2->dev));
101+
}
102+
c->sendMsg(0, tmp, false);
103+
free(tmp);
104+
nxt = n->next;
105+
} while (nxt);
106+
107+
free(buffer);
108+
free(buffer2);
109+
close(fd);
110+
return 0;
111+
}
112+
33113
void Devmapper::ioctlInit(struct dm_ioctl *io, size_t dataSize,
34114
const char *name, unsigned flags) {
35115
memset(io, 0, dataSize);
@@ -39,7 +119,9 @@ void Devmapper::ioctlInit(struct dm_ioctl *io, size_t dataSize,
39119
io->version[1] = 0;
40120
io->version[2] = 0;
41121
io->flags = flags;
42-
strncpy(io->name, name, sizeof(io->name));
122+
if (name) {
123+
strncpy(io->name, name, sizeof(io->name));
124+
}
43125
}
44126

45127
int Devmapper::lookupActive(const char *name, char *ubuffer, size_t len) {

Devmapper.h

+4
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,16 @@
2020
#include <unistd.h>
2121
#include <linux/dm-ioctl.h>
2222

23+
class SocketClient;
24+
2325
class Devmapper {
2426
public:
2527
static int create(const char *name, const char *loopFile, const char *key,
2628
unsigned int numSectors, char *buffer, size_t len);
2729
static int destroy(const char *name);
2830
static int lookupActive(const char *name, char *buffer, size_t len);
31+
static int dumpState(SocketClient *c);
32+
2933
private:
3034
static void *_align(void *ptr, unsigned int a);
3135
static void ioctlInit(struct dm_ioctl *io, size_t data_size,

0 commit comments

Comments
 (0)