1dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 2dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <sys/mount.h> 3dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <sys/stat.h> 4dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <fcntl.h> 5dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <stdio.h> 6dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <string.h> 7dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <unistd.h> 8dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <linux/loop.h> 9baf6b6bdebd6e91c401f64e8013fed49697ed2ccJeff Brown#include <errno.h> 10dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 11940c81078e7291096b22f05f6b953658f1e1d730Ken Sumrall#define LOOPDEV_MAXLEN 64 12940c81078e7291096b22f05f6b953658f1e1d730Ken Sumrall#define LOOP_MAJOR 7 13dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 14940c81078e7291096b22f05f6b953658f1e1d730Ken Sumrallstatic int is_loop(char *dev) 15940c81078e7291096b22f05f6b953658f1e1d730Ken Sumrall{ 16940c81078e7291096b22f05f6b953658f1e1d730Ken Sumrall struct stat st; 17940c81078e7291096b22f05f6b953658f1e1d730Ken Sumrall int ret = 0; 18940c81078e7291096b22f05f6b953658f1e1d730Ken Sumrall 19940c81078e7291096b22f05f6b953658f1e1d730Ken Sumrall if (stat(dev, &st) == 0) { 20940c81078e7291096b22f05f6b953658f1e1d730Ken Sumrall if (S_ISBLK(st.st_mode) && (major(st.st_rdev) == LOOP_MAJOR)) { 21940c81078e7291096b22f05f6b953658f1e1d730Ken Sumrall ret = 1; 22940c81078e7291096b22f05f6b953658f1e1d730Ken Sumrall } 23940c81078e7291096b22f05f6b953658f1e1d730Ken Sumrall } 24940c81078e7291096b22f05f6b953658f1e1d730Ken Sumrall 25940c81078e7291096b22f05f6b953658f1e1d730Ken Sumrall return ret; 26940c81078e7291096b22f05f6b953658f1e1d730Ken Sumrall} 27940c81078e7291096b22f05f6b953658f1e1d730Ken Sumrall 28940c81078e7291096b22f05f6b953658f1e1d730Ken Sumrallstatic int is_loop_mount(const char* path, char *loopdev) 29dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 30dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project FILE* f; 31dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int count; 32dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char device[256]; 33dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char mount_path[256]; 34dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char rest[256]; 35dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int result = 0; 36dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int path_length = strlen(path); 37dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 38dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project f = fopen("/proc/mounts", "r"); 39dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (!f) { 40baf6b6bdebd6e91c401f64e8013fed49697ed2ccJeff Brown fprintf(stdout, "could not open /proc/mounts: %s\n", strerror(errno)); 41dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return -1; 42dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 43dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 44dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project do { 45dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project count = fscanf(f, "%255s %255s %255s\n", device, mount_path, rest); 46dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (count == 3) { 47940c81078e7291096b22f05f6b953658f1e1d730Ken Sumrall if (is_loop(device) && strcmp(path, mount_path) == 0) { 48940c81078e7291096b22f05f6b953658f1e1d730Ken Sumrall strlcpy(loopdev, device, LOOPDEV_MAXLEN); 49dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project result = 1; 50dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 51dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 52dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 53dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } while (count == 3); 54dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 55dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fclose(f); 56dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return result; 57dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 58dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 59dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint umount_main(int argc, char *argv[]) 60dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 61dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int loop, loop_fd; 62940c81078e7291096b22f05f6b953658f1e1d730Ken Sumrall char loopdev[LOOPDEV_MAXLEN]; 63940c81078e7291096b22f05f6b953658f1e1d730Ken Sumrall 64dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(argc != 2) { 65dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fprintf(stderr,"umount <path>\n"); 66dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 1; 67dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 68dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 69940c81078e7291096b22f05f6b953658f1e1d730Ken Sumrall loop = is_loop_mount(argv[1], loopdev); 70baf6b6bdebd6e91c401f64e8013fed49697ed2ccJeff Brown if (umount(argv[1])) { 71baf6b6bdebd6e91c401f64e8013fed49697ed2ccJeff Brown fprintf(stderr, "failed: %s\n", strerror(errno)); 72dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 1; 73dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 74dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 75dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (loop) { 76dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // free the loop device 77940c81078e7291096b22f05f6b953658f1e1d730Ken Sumrall loop_fd = open(loopdev, O_RDONLY); 78940c81078e7291096b22f05f6b953658f1e1d730Ken Sumrall if (loop_fd < 0) { 79baf6b6bdebd6e91c401f64e8013fed49697ed2ccJeff Brown fprintf(stderr, "open loop device failed: %s\n", strerror(errno)); 80dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 1; 81dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 82dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (ioctl(loop_fd, LOOP_CLR_FD, 0) < 0) { 83baf6b6bdebd6e91c401f64e8013fed49697ed2ccJeff Brown fprintf(stderr, "ioctl LOOP_CLR_FD failed: %s\n", strerror(errno)); 84dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 1; 85dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 86dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 87dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project close(loop_fd); 88dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 89dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 90dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 91dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 92