• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 
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>
9 #include <errno.h>
10 
11 #define LOOPDEV_MAXLEN 64
12 #define LOOP_MAJOR 7
13 
is_loop(char * dev)14 static 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 
is_loop_mount(const char * path,char * loopdev)28 static int is_loop_mount(const char* path, char *loopdev)
29 {
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) {
40         fprintf(stdout, "could not open /proc/mounts: %s\n", strerror(errno));
41         return -1;
42     }
43 
44     do {
45         count = fscanf(f, "%255s %255s %255s\n", device, mount_path, rest);
46         if (count == 3) {
47             if (is_loop(device) && strcmp(path, mount_path) == 0) {
48                 strlcpy(loopdev, device, LOOPDEV_MAXLEN);
49                 result = 1;
50                 break;
51             }
52         }
53     } while (count == 3);
54 
55     fclose(f);
56     return result;
57 }
58 
umount_main(int argc,char * argv[])59 int umount_main(int argc, char *argv[])
60 {
61     int loop, loop_fd;
62     char loopdev[LOOPDEV_MAXLEN];
63 
64     if(argc != 2) {
65         fprintf(stderr,"umount <path>\n");
66         return 1;
67     }
68 
69     loop = is_loop_mount(argv[1], loopdev);
70     if (umount(argv[1])) {
71         fprintf(stderr, "failed: %s\n", strerror(errno));
72         return 1;
73     }
74 
75     if (loop) {
76         // free the loop device
77         loop_fd = open(loopdev, O_RDONLY);
78         if (loop_fd < 0) {
79             fprintf(stderr, "open loop device failed: %s\n", strerror(errno));
80             return 1;
81         }
82         if (ioctl(loop_fd, LOOP_CLR_FD, 0) < 0) {
83             fprintf(stderr, "ioctl LOOP_CLR_FD failed: %s\n", strerror(errno));
84             return 1;
85         }
86 
87         close(loop_fd);
88     }
89 
90     return 0;
91 }
92