blob: 890e8706bdc9c2e6d25fcca88a0e0323b71a2de4 [file] [log] [blame]
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001
2#include <sys/mount.h>
3#include <sys/stat.h>
4#include <fcntl.h>
5#include <stdio.h>
6#include <string.h>
7#include <unistd.h>
8#include <linux/loop.h>
Jeff Brownbaf6b6b2011-07-13 22:12:18 -07009#include <errno.h>
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080010
Ken Sumrall940c8102011-07-12 19:47:06 -070011#define LOOPDEV_MAXLEN 64
12#define LOOP_MAJOR 7
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080013
Ken Sumrall940c8102011-07-12 19:47:06 -070014static int is_loop(char *dev)
15{
16 struct stat st;
17 int ret = 0;
18
19 if (stat(dev, &st) == 0) {
20 if (S_ISBLK(st.st_mode) && (major(st.st_rdev) == LOOP_MAJOR)) {
21 ret = 1;
22 }
23 }
24
25 return ret;
26}
27
28static int is_loop_mount(const char* path, char *loopdev)
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080029{
30 FILE* f;
31 int count;
32 char device[256];
33 char mount_path[256];
34 char rest[256];
35 int result = 0;
36 int path_length = strlen(path);
37
38 f = fopen("/proc/mounts", "r");
39 if (!f) {
Jeff Brownbaf6b6b2011-07-13 22:12:18 -070040 fprintf(stdout, "could not open /proc/mounts: %s\n", strerror(errno));
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080041 return -1;
42 }
43
44 do {
45 count = fscanf(f, "%255s %255s %255s\n", device, mount_path, rest);
46 if (count == 3) {
Ken Sumrall940c8102011-07-12 19:47:06 -070047 if (is_loop(device) && strcmp(path, mount_path) == 0) {
48 strlcpy(loopdev, device, LOOPDEV_MAXLEN);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080049 result = 1;
50 break;
51 }
52 }
53 } while (count == 3);
54
55 fclose(f);
56 return result;
57}
58
59int umount_main(int argc, char *argv[])
60{
61 int loop, loop_fd;
Ken Sumrall940c8102011-07-12 19:47:06 -070062 char loopdev[LOOPDEV_MAXLEN];
63
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080064 if(argc != 2) {
65 fprintf(stderr,"umount <path>\n");
66 return 1;
67 }
68
Ken Sumrall940c8102011-07-12 19:47:06 -070069 loop = is_loop_mount(argv[1], loopdev);
Jeff Brownbaf6b6b2011-07-13 22:12:18 -070070 if (umount(argv[1])) {
71 fprintf(stderr, "failed: %s\n", strerror(errno));
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080072 return 1;
73 }
74
75 if (loop) {
76 // free the loop device
Ken Sumrall940c8102011-07-12 19:47:06 -070077 loop_fd = open(loopdev, O_RDONLY);
78 if (loop_fd < 0) {
Jeff Brownbaf6b6b2011-07-13 22:12:18 -070079 fprintf(stderr, "open loop device failed: %s\n", strerror(errno));
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080080 return 1;
81 }
82 if (ioctl(loop_fd, LOOP_CLR_FD, 0) < 0) {
Jeff Brownbaf6b6b2011-07-13 22:12:18 -070083 fprintf(stderr, "ioctl LOOP_CLR_FD failed: %s\n", strerror(errno));
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080084 return 1;
85 }
86
87 close(loop_fd);
88 }
89
90 return 0;
91}