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