Home | History | Annotate | Download | only in toolbox
      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 
     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 
     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 
     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