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