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