summaryrefslogtreecommitdiffstats
path: root/toolbox
diff options
context:
space:
mode:
authorKen Sumrall <ksumrall@android.com>2011-07-13 18:57:28 -0700
committerAndroid (Google) Code Review <android-gerrit@google.com>2011-07-13 18:57:28 -0700
commite877ad7ae3ea3c1a631652c86887a627ef9feb3f (patch)
tree650c65e72f47230c854deb57920b731df0ea3190 /toolbox
parentae3736a3d1418eb1a1e57895ce410256d7106aa3 (diff)
parent940c81078e7291096b22f05f6b953658f1e1d730 (diff)
downloadsystem_core-e877ad7ae3ea3c1a631652c86887a627ef9feb3f.zip
system_core-e877ad7ae3ea3c1a631652c86887a627ef9feb3f.tar.gz
system_core-e877ad7ae3ea3c1a631652c86887a627ef9feb3f.tar.bz2
Merge "Add -o loop= option to mount, and fix error detection in mount and umount"
Diffstat (limited to 'toolbox')
-rw-r--r--toolbox/mount.c30
-rw-r--r--toolbox/umount.c32
2 files changed, 43 insertions, 19 deletions
diff --git a/toolbox/mount.c b/toolbox/mount.c
index 82ecc56..27cf3c9 100644
--- a/toolbox/mount.c
+++ b/toolbox/mount.c
@@ -15,8 +15,8 @@
#define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))
-// FIXME - only one loop mount is supported at a time
-#define LOOP_DEVICE "/dev/block/loop0"
+#define DEFAULT_LOOP_DEVICE "/dev/block/loop0"
+#define LOOPDEV_MAXLEN 64
struct mount_opts {
const char str[8];
@@ -87,7 +87,7 @@ static void add_extra_option(struct extra_opts *extra, char *s)
}
static unsigned long
-parse_mount_options(char *arg, unsigned long rwflag, struct extra_opts *extra, int* loop)
+parse_mount_options(char *arg, unsigned long rwflag, struct extra_opts *extra, int* loop, char *loopdev)
{
char *s;
@@ -100,8 +100,15 @@ parse_mount_options(char *arg, unsigned long rwflag, struct extra_opts *extra, i
if (no)
s += 2;
+ if (strncmp(s, "loop=", 5) == 0) {
+ *loop = 1;
+ strlcpy(loopdev, s + 5, LOOPDEV_MAXLEN);
+ continue;
+ }
+
if (strcmp(s, "loop") == 0) {
*loop = 1;
+ strlcpy(loopdev, DEFAULT_LOOP_DEVICE, LOOPDEV_MAXLEN);
continue;
}
for (i = 0, res = 1; i < ARRAY_SIZE(options); i++) {
@@ -131,7 +138,8 @@ static struct extra_opts extra;
static unsigned long rwflag;
static int
-do_mount(char *dev, char *dir, char *type, unsigned long rwflag, void *data, int loop)
+do_mount(char *dev, char *dir, char *type, unsigned long rwflag, void *data, int loop,
+ char *loopdev)
{
char *s;
int error = 0;
@@ -142,14 +150,13 @@ do_mount(char *dev, char *dir, char *type, unsigned long rwflag, void *data, int
flags = (rwflag & MS_RDONLY) ? O_RDONLY : O_RDWR;
- // FIXME - only one loop mount supported at a time
file_fd = open(dev, flags);
- if (file_fd < -1) {
+ if (file_fd < 0) {
perror("open backing file failed");
return 1;
}
- device_fd = open(LOOP_DEVICE, flags);
- if (device_fd < -1) {
+ device_fd = open(loopdev, flags);
+ if (device_fd < 0) {
perror("open loop device failed");
close(file_fd);
return 1;
@@ -163,7 +170,7 @@ do_mount(char *dev, char *dir, char *type, unsigned long rwflag, void *data, int
close(file_fd);
close(device_fd);
- dev = LOOP_DEVICE;
+ dev = loopdev;
}
while ((s = strsep(&type, ",")) != NULL) {
@@ -268,6 +275,7 @@ int mount_main(int argc, char *argv[])
char *dir = NULL;
int c;
int loop = 0;
+ char loopdev[LOOPDEV_MAXLEN];
progname = argv[0];
rwflag = MS_VERBOSE;
@@ -281,7 +289,7 @@ int mount_main(int argc, char *argv[])
break;
switch (c) {
case 'o':
- rwflag = parse_mount_options(optarg, rwflag, &extra, &loop);
+ rwflag = parse_mount_options(optarg, rwflag, &extra, &loop, loopdev);
break;
case 'r':
rwflag |= MS_RDONLY;
@@ -319,6 +327,6 @@ int mount_main(int argc, char *argv[])
exit(1);
}
- return do_mount(dev, dir, type, rwflag, extra.str, loop);
+ return do_mount(dev, dir, type, rwflag, extra.str, loop, loopdev);
/* We leak dev and dir in some cases, but we're about to exit */
}
diff --git a/toolbox/umount.c b/toolbox/umount.c
index 92c6076..6eb8b92 100644
--- a/toolbox/umount.c
+++ b/toolbox/umount.c
@@ -7,10 +7,24 @@
#include <unistd.h>
#include <linux/loop.h>
-// FIXME - only one loop mount is supported at a time
-#define LOOP_DEVICE "/dev/block/loop0"
+#define LOOPDEV_MAXLEN 64
+#define LOOP_MAJOR 7
-static int is_loop_mount(const char* path)
+static int is_loop(char *dev)
+{
+ struct stat st;
+ int ret = 0;
+
+ if (stat(dev, &st) == 0) {
+ if (S_ISBLK(st.st_mode) && (major(st.st_rdev) == LOOP_MAJOR)) {
+ ret = 1;
+ }
+ }
+
+ return ret;
+}
+
+static int is_loop_mount(const char* path, char *loopdev)
{
FILE* f;
int count;
@@ -29,7 +43,8 @@ static int is_loop_mount(const char* path)
do {
count = fscanf(f, "%255s %255s %255s\n", device, mount_path, rest);
if (count == 3) {
- if (strcmp(LOOP_DEVICE, device) == 0 && strcmp(path, mount_path) == 0) {
+ if (is_loop(device) && strcmp(path, mount_path) == 0) {
+ strlcpy(loopdev, device, LOOPDEV_MAXLEN);
result = 1;
break;
}
@@ -43,13 +58,14 @@ static int is_loop_mount(const char* path)
int umount_main(int argc, char *argv[])
{
int loop, loop_fd;
-
+ char loopdev[LOOPDEV_MAXLEN];
+
if(argc != 2) {
fprintf(stderr,"umount <path>\n");
return 1;
}
- loop = is_loop_mount(argv[1]);
+ loop = is_loop_mount(argv[1], loopdev);
if(umount(argv[1])){
fprintf(stderr,"failed.\n");
return 1;
@@ -57,8 +73,8 @@ int umount_main(int argc, char *argv[])
if (loop) {
// free the loop device
- loop_fd = open(LOOP_DEVICE, O_RDONLY);
- if (loop_fd < -1) {
+ loop_fd = open(loopdev, O_RDONLY);
+ if (loop_fd < 0) {
perror("open loop device failed");
return 1;
}