150e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o/* 219c78dc07fce2d6f39b5e541562afc3ca1ea38ffTheodore Ts'o * ismounted.c --- Check to see if the filesystem was mounted 3efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o * 4cc86017b593ddfbd4d7a12ed8695e62998f30944Theodore Ts'o * Copyright (C) 1995,1996,1997,1998,1999,2000 Theodore Ts'o. 519c78dc07fce2d6f39b5e541562afc3ca1ea38ffTheodore Ts'o * 619c78dc07fce2d6f39b5e541562afc3ca1ea38ffTheodore Ts'o * %Begin-Header% 7543547a52a20cb7e69d74921b2f691078fd55d83Theodore Ts'o * This file may be redistributed under the terms of the GNU Library 8543547a52a20cb7e69d74921b2f691078fd55d83Theodore Ts'o * General Public License, version 2. 919c78dc07fce2d6f39b5e541562afc3ca1ea38ffTheodore Ts'o * %End-Header% 1050e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o */ 1150e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o 128f6f8602dc1037fb8fc2051fb062c0209f8baa2aTheodore Ts'o/* define BSD_SOURCE to make sure we get the major() macro */ 138f6f8602dc1037fb8fc2051fb062c0209f8baa2aTheodore Ts'o#ifndef _BSD_SOURCE 148f6f8602dc1037fb8fc2051fb062c0209f8baa2aTheodore Ts'o#define _BSD_SOURCE 158f6f8602dc1037fb8fc2051fb062c0209f8baa2aTheodore Ts'o#endif 168f6f8602dc1037fb8fc2051fb062c0209f8baa2aTheodore Ts'o#ifndef _DEFAULT_SOURCE 178f6f8602dc1037fb8fc2051fb062c0209f8baa2aTheodore Ts'o#define _DEFAULT_SOURCE /* since glibc 2.20 _SVID_SOURCE is deprecated */ 188f6f8602dc1037fb8fc2051fb062c0209f8baa2aTheodore Ts'o#endif 198f6f8602dc1037fb8fc2051fb062c0209f8baa2aTheodore Ts'o 20d1154eb460efe588eaed3d439c1caaca149fa362Theodore Ts'o#include "config.h" 2150e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o#include <stdio.h> 2250e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o#if HAVE_UNISTD_H 2350e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o#include <unistd.h> 2450e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o#endif 25c4e749abd8451f02418fe552b2af14f226f7bd1eTheodore Ts'o#if HAVE_ERRNO_H 26c4e749abd8451f02418fe552b2af14f226f7bd1eTheodore Ts'o#include <errno.h> 27c4e749abd8451f02418fe552b2af14f226f7bd1eTheodore Ts'o#endif 2850e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o#include <fcntl.h> 2950e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o#ifdef HAVE_LINUX_FD_H 3050e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o#include <linux/fd.h> 3150e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o#endif 32fbabd5c44c2303501ad79b0e0386fe6436e0e147Kazuya Mio#ifdef HAVE_LINUX_LOOP_H 33fbabd5c44c2303501ad79b0e0386fe6436e0e147Kazuya Mio#include <linux/loop.h> 34fbabd5c44c2303501ad79b0e0386fe6436e0e147Kazuya Mio#include <sys/ioctl.h> 35fbabd5c44c2303501ad79b0e0386fe6436e0e147Kazuya Mio#ifdef HAVE_LINUX_MAJOR_H 36fbabd5c44c2303501ad79b0e0386fe6436e0e147Kazuya Mio#include <linux/major.h> 37fbabd5c44c2303501ad79b0e0386fe6436e0e147Kazuya Mio#endif /* HAVE_LINUX_MAJOR_H */ 38fbabd5c44c2303501ad79b0e0386fe6436e0e147Kazuya Mio#endif /* HAVE_LINUX_LOOP_H */ 3950e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o#ifdef HAVE_MNTENT_H 4050e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o#include <mntent.h> 4150e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o#endif 4250e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o#ifdef HAVE_GETMNTINFO 4350e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o#include <paths.h> 4450e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o#include <sys/param.h> 4550e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o#include <sys/mount.h> 4650e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o#endif /* HAVE_GETMNTINFO */ 4731dbecd482405e0d3a67eb58e1a1c8cb9f2ad83eTheodore Ts'o#include <string.h> 48cc86017b593ddfbd4d7a12ed8695e62998f30944Theodore Ts'o#include <sys/stat.h> 498f6f8602dc1037fb8fc2051fb062c0209f8baa2aTheodore Ts'o#if HAVE_SYS_TYPES_H 508f6f8602dc1037fb8fc2051fb062c0209f8baa2aTheodore Ts'o#include <sys/types.h> 518f6f8602dc1037fb8fc2051fb062c0209f8baa2aTheodore Ts'o#endif 5295e97131a0e96ad2c30c67d1c167dc586619486bMike Frysinger#ifdef HAVE_SYS_SYSMACROS_H 5395e97131a0e96ad2c30c67d1c167dc586619486bMike Frysinger#include <sys/sysmacros.h> 5495e97131a0e96ad2c30c67d1c167dc586619486bMike Frysinger#endif 5550e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o 56b5abe6fac9c9e7caf4710501d1657d30e4857ef6Theodore Ts'o#include "ext2_fs.h" 5750e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o#include "ext2fs.h" 5850e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o 59aee40b870cd70a884fd98a56d9c956945584b429Theodore Ts'o#ifdef HAVE_SETMNTENT 60fbabd5c44c2303501ad79b0e0386fe6436e0e147Kazuya Mio/* 61fbabd5c44c2303501ad79b0e0386fe6436e0e147Kazuya Mio * Check to see if a regular file is mounted. 62fbabd5c44c2303501ad79b0e0386fe6436e0e147Kazuya Mio * If /etc/mtab/ is a symlink of /proc/mounts, you will need the following check 63fbabd5c44c2303501ad79b0e0386fe6436e0e147Kazuya Mio * because the name in /proc/mounts is a loopback device not a regular file. 64fbabd5c44c2303501ad79b0e0386fe6436e0e147Kazuya Mio */ 65fbabd5c44c2303501ad79b0e0386fe6436e0e147Kazuya Miostatic int check_loop_mounted(const char *mnt_fsname, dev_t mnt_rdev, 66fbabd5c44c2303501ad79b0e0386fe6436e0e147Kazuya Mio dev_t file_dev, ino_t file_ino) 67fbabd5c44c2303501ad79b0e0386fe6436e0e147Kazuya Mio{ 68fbabd5c44c2303501ad79b0e0386fe6436e0e147Kazuya Mio#if defined(HAVE_LINUX_LOOP_H) && defined(HAVE_LINUX_MAJOR_H) 69fbabd5c44c2303501ad79b0e0386fe6436e0e147Kazuya Mio struct loop_info64 loopinfo; 70fbabd5c44c2303501ad79b0e0386fe6436e0e147Kazuya Mio int loop_fd, ret; 71fbabd5c44c2303501ad79b0e0386fe6436e0e147Kazuya Mio 72fbabd5c44c2303501ad79b0e0386fe6436e0e147Kazuya Mio if (major(mnt_rdev) == LOOP_MAJOR) { 73fbabd5c44c2303501ad79b0e0386fe6436e0e147Kazuya Mio loop_fd = open(mnt_fsname, O_RDONLY); 74fbabd5c44c2303501ad79b0e0386fe6436e0e147Kazuya Mio if (loop_fd < 0) 75fbabd5c44c2303501ad79b0e0386fe6436e0e147Kazuya Mio return -1; 76fbabd5c44c2303501ad79b0e0386fe6436e0e147Kazuya Mio 77fbabd5c44c2303501ad79b0e0386fe6436e0e147Kazuya Mio ret = ioctl(loop_fd, LOOP_GET_STATUS64, &loopinfo); 78fbabd5c44c2303501ad79b0e0386fe6436e0e147Kazuya Mio close(loop_fd); 79fbabd5c44c2303501ad79b0e0386fe6436e0e147Kazuya Mio if (ret < 0) 80fbabd5c44c2303501ad79b0e0386fe6436e0e147Kazuya Mio return -1; 81fbabd5c44c2303501ad79b0e0386fe6436e0e147Kazuya Mio 82fbabd5c44c2303501ad79b0e0386fe6436e0e147Kazuya Mio if (file_dev == loopinfo.lo_device && 83fbabd5c44c2303501ad79b0e0386fe6436e0e147Kazuya Mio file_ino == loopinfo.lo_inode) 84fbabd5c44c2303501ad79b0e0386fe6436e0e147Kazuya Mio return 1; 85fbabd5c44c2303501ad79b0e0386fe6436e0e147Kazuya Mio } 86fbabd5c44c2303501ad79b0e0386fe6436e0e147Kazuya Mio#endif /* defined(HAVE_LINUX_LOOP_H) && defined(HAVE_LINUX_MAJOR_H) */ 87fbabd5c44c2303501ad79b0e0386fe6436e0e147Kazuya Mio return 0; 88fbabd5c44c2303501ad79b0e0386fe6436e0e147Kazuya Mio} 89fbabd5c44c2303501ad79b0e0386fe6436e0e147Kazuya Mio 9050e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o/* 9152db0b4178553318aac08bb9cdc1d42743e6beebTheodore Ts'o * Helper function which checks a file in /etc/mtab format to see if a 9252db0b4178553318aac08bb9cdc1d42743e6beebTheodore Ts'o * filesystem is mounted. Returns an error if the file doesn't exist 93efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o * or can't be opened. 9450e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o */ 95efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'ostatic errcode_t check_mntent_file(const char *mtab_file, const char *file, 9652db0b4178553318aac08bb9cdc1d42743e6beebTheodore Ts'o int *mount_flags, char *mtpt, int mtlen) 9750e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o{ 982038b636b2a72d997b7a6b4123e50d7f8dcb7108Theodore Ts'o struct mntent *mnt; 99a8fd6e36b866f2cf14edaa19d452fa64bd0fba40Theodore Ts'o struct stat st_buf; 1002038b636b2a72d997b7a6b4123e50d7f8dcb7108Theodore Ts'o errcode_t retval = 0; 1013a42fe220c301c8b9a8df595938c9a923cf5c494Theodore Ts'o dev_t file_dev=0, file_rdev=0; 1023a42fe220c301c8b9a8df595938c9a923cf5c494Theodore Ts'o ino_t file_ino=0; 1032038b636b2a72d997b7a6b4123e50d7f8dcb7108Theodore Ts'o FILE *f; 1042038b636b2a72d997b7a6b4123e50d7f8dcb7108Theodore Ts'o int fd; 10550e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o 10650e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o *mount_flags = 0; 1072b8772f522be1c82c92e7e0401126808431d06a2Darrick J. Wong 10842b61c50e5af99a10fc56975ecd08ab71e4f00e8Theodore Ts'o if ((f = setmntent (mtab_file, "r")) == NULL) { 10942b61c50e5af99a10fc56975ecd08ab71e4f00e8Theodore Ts'o if (errno == ENOENT) { 11042b61c50e5af99a10fc56975ecd08ab71e4f00e8Theodore Ts'o if (getenv("EXT2FS_NO_MTAB_OK")) 11142b61c50e5af99a10fc56975ecd08ab71e4f00e8Theodore Ts'o return 0; 11242b61c50e5af99a10fc56975ecd08ab71e4f00e8Theodore Ts'o else 1138ab395524b95875818505a497428cab73e80c0d5Zheng Liu return EXT2_ET_NO_MTAB_FILE; 11442b61c50e5af99a10fc56975ecd08ab71e4f00e8Theodore Ts'o } 11542b61c50e5af99a10fc56975ecd08ab71e4f00e8Theodore Ts'o return errno; 11642b61c50e5af99a10fc56975ecd08ab71e4f00e8Theodore Ts'o } 1173a42fe220c301c8b9a8df595938c9a923cf5c494Theodore Ts'o if (stat(file, &st_buf) == 0) { 1183a42fe220c301c8b9a8df595938c9a923cf5c494Theodore Ts'o if (S_ISBLK(st_buf.st_mode)) { 119a8fd6e36b866f2cf14edaa19d452fa64bd0fba40Theodore Ts'o#ifndef __GNU__ /* The GNU hurd is broken with respect to stat devices */ 1203a42fe220c301c8b9a8df595938c9a923cf5c494Theodore Ts'o file_rdev = st_buf.st_rdev; 121f0efd2976b69d31b752b5e5ce4f5e8341a130c45Theodore Ts'o#endif /* __GNU__ */ 1223a42fe220c301c8b9a8df595938c9a923cf5c494Theodore Ts'o } else { 1233a42fe220c301c8b9a8df595938c9a923cf5c494Theodore Ts'o file_dev = st_buf.st_dev; 1243a42fe220c301c8b9a8df595938c9a923cf5c494Theodore Ts'o file_ino = st_buf.st_ino; 1253a42fe220c301c8b9a8df595938c9a923cf5c494Theodore Ts'o } 1263a42fe220c301c8b9a8df595938c9a923cf5c494Theodore Ts'o } 127a8fd6e36b866f2cf14edaa19d452fa64bd0fba40Theodore Ts'o while ((mnt = getmntent (f)) != NULL) { 128f9110f4480eade2d849c4cc08efa49bf0f7f5148Theodore Ts'o if (mnt->mnt_fsname[0] != '/') 129f9110f4480eade2d849c4cc08efa49bf0f7f5148Theodore Ts'o continue; 13050e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o if (strcmp(file, mnt->mnt_fsname) == 0) 13150e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o break; 1323a42fe220c301c8b9a8df595938c9a923cf5c494Theodore Ts'o if (stat(mnt->mnt_fsname, &st_buf) == 0) { 1333a42fe220c301c8b9a8df595938c9a923cf5c494Theodore Ts'o if (S_ISBLK(st_buf.st_mode)) { 134a8fd6e36b866f2cf14edaa19d452fa64bd0fba40Theodore Ts'o#ifndef __GNU__ 1353a42fe220c301c8b9a8df595938c9a923cf5c494Theodore Ts'o if (file_rdev && (file_rdev == st_buf.st_rdev)) 1363a42fe220c301c8b9a8df595938c9a923cf5c494Theodore Ts'o break; 137fbabd5c44c2303501ad79b0e0386fe6436e0e147Kazuya Mio if (check_loop_mounted(mnt->mnt_fsname, 138fbabd5c44c2303501ad79b0e0386fe6436e0e147Kazuya Mio st_buf.st_rdev, file_dev, 139fbabd5c44c2303501ad79b0e0386fe6436e0e147Kazuya Mio file_ino) == 1) 140fbabd5c44c2303501ad79b0e0386fe6436e0e147Kazuya Mio break; 141f0efd2976b69d31b752b5e5ce4f5e8341a130c45Theodore Ts'o#endif /* __GNU__ */ 1423a42fe220c301c8b9a8df595938c9a923cf5c494Theodore Ts'o } else { 1433a42fe220c301c8b9a8df595938c9a923cf5c494Theodore Ts'o if (file_dev && ((file_dev == st_buf.st_dev) && 1443a42fe220c301c8b9a8df595938c9a923cf5c494Theodore Ts'o (file_ino == st_buf.st_ino))) 1453a42fe220c301c8b9a8df595938c9a923cf5c494Theodore Ts'o break; 1463a42fe220c301c8b9a8df595938c9a923cf5c494Theodore Ts'o } 1473a42fe220c301c8b9a8df595938c9a923cf5c494Theodore Ts'o } 148a8fd6e36b866f2cf14edaa19d452fa64bd0fba40Theodore Ts'o } 149cc86017b593ddfbd4d7a12ed8695e62998f30944Theodore Ts'o 150cc86017b593ddfbd4d7a12ed8695e62998f30944Theodore Ts'o if (mnt == 0) { 15166a461469ccafd7aad2a824b0ab66fd9096d6e94Theodore Ts'o#ifndef __GNU__ /* The GNU hurd is broken with respect to stat devices */ 152cc86017b593ddfbd4d7a12ed8695e62998f30944Theodore Ts'o /* 153cc86017b593ddfbd4d7a12ed8695e62998f30944Theodore Ts'o * Do an extra check to see if this is the root device. We 1542038b636b2a72d997b7a6b4123e50d7f8dcb7108Theodore Ts'o * can't trust /etc/mtab, and /proc/mounts will only list 155cc86017b593ddfbd4d7a12ed8695e62998f30944Theodore Ts'o * /dev/root for the root filesystem. Argh. Instead we 156cc86017b593ddfbd4d7a12ed8695e62998f30944Theodore Ts'o * check if the given device has the same major/minor number 157cc86017b593ddfbd4d7a12ed8695e62998f30944Theodore Ts'o * as the device that the root directory is on. 158cc86017b593ddfbd4d7a12ed8695e62998f30944Theodore Ts'o */ 1593a42fe220c301c8b9a8df595938c9a923cf5c494Theodore Ts'o if (file_rdev && stat("/", &st_buf) == 0) { 1603a42fe220c301c8b9a8df595938c9a923cf5c494Theodore Ts'o if (st_buf.st_dev == file_rdev) { 161cc86017b593ddfbd4d7a12ed8695e62998f30944Theodore Ts'o *mount_flags = EXT2_MF_MOUNTED; 162cc86017b593ddfbd4d7a12ed8695e62998f30944Theodore Ts'o if (mtpt) 163d5f858dd7f02532ad90e4121537c358e86d0eecfTheodore Ts'o strncpy(mtpt, "/", mtlen); 164cc86017b593ddfbd4d7a12ed8695e62998f30944Theodore Ts'o goto is_root; 165cc86017b593ddfbd4d7a12ed8695e62998f30944Theodore Ts'o } 166cc86017b593ddfbd4d7a12ed8695e62998f30944Theodore Ts'o } 167f0efd2976b69d31b752b5e5ce4f5e8341a130c45Theodore Ts'o#endif /* __GNU__ */ 16848e6e81362f264aee4f3945c14928efaf71a06c9Theodore Ts'o goto errout; 1692038b636b2a72d997b7a6b4123e50d7f8dcb7108Theodore Ts'o } 1702038b636b2a72d997b7a6b4123e50d7f8dcb7108Theodore Ts'o#ifndef __GNU__ /* The GNU hurd is deficient; what else is new? */ 1712038b636b2a72d997b7a6b4123e50d7f8dcb7108Theodore Ts'o /* Validate the entry in case /etc/mtab is out of date */ 172efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o /* 1732038b636b2a72d997b7a6b4123e50d7f8dcb7108Theodore Ts'o * We need to be paranoid, because some broken distributions 1742038b636b2a72d997b7a6b4123e50d7f8dcb7108Theodore Ts'o * (read: Slackware) don't initialize /etc/mtab before checking 1752038b636b2a72d997b7a6b4123e50d7f8dcb7108Theodore Ts'o * all of the non-root filesystems on the disk. 1762038b636b2a72d997b7a6b4123e50d7f8dcb7108Theodore Ts'o */ 177a8fd6e36b866f2cf14edaa19d452fa64bd0fba40Theodore Ts'o if (stat(mnt->mnt_dir, &st_buf) < 0) { 1782038b636b2a72d997b7a6b4123e50d7f8dcb7108Theodore Ts'o retval = errno; 1792038b636b2a72d997b7a6b4123e50d7f8dcb7108Theodore Ts'o if (retval == ENOENT) { 1802038b636b2a72d997b7a6b4123e50d7f8dcb7108Theodore Ts'o#ifdef DEBUG 1812038b636b2a72d997b7a6b4123e50d7f8dcb7108Theodore Ts'o printf("Bogus entry in %s! (%s does not exist)\n", 1822038b636b2a72d997b7a6b4123e50d7f8dcb7108Theodore Ts'o mtab_file, mnt->mnt_dir); 183f0efd2976b69d31b752b5e5ce4f5e8341a130c45Theodore Ts'o#endif /* DEBUG */ 1842038b636b2a72d997b7a6b4123e50d7f8dcb7108Theodore Ts'o retval = 0; 1852038b636b2a72d997b7a6b4123e50d7f8dcb7108Theodore Ts'o } 18648e6e81362f264aee4f3945c14928efaf71a06c9Theodore Ts'o goto errout; 1872038b636b2a72d997b7a6b4123e50d7f8dcb7108Theodore Ts'o } 1883a42fe220c301c8b9a8df595938c9a923cf5c494Theodore Ts'o if (file_rdev && (st_buf.st_dev != file_rdev)) { 1892038b636b2a72d997b7a6b4123e50d7f8dcb7108Theodore Ts'o#ifdef DEBUG 190a8fd6e36b866f2cf14edaa19d452fa64bd0fba40Theodore Ts'o printf("Bogus entry in %s! (%s not mounted on %s)\n", 191a8fd6e36b866f2cf14edaa19d452fa64bd0fba40Theodore Ts'o mtab_file, file, mnt->mnt_dir); 192f0efd2976b69d31b752b5e5ce4f5e8341a130c45Theodore Ts'o#endif /* DEBUG */ 19348e6e81362f264aee4f3945c14928efaf71a06c9Theodore Ts'o goto errout; 194cc86017b593ddfbd4d7a12ed8695e62998f30944Theodore Ts'o } 195f0efd2976b69d31b752b5e5ce4f5e8341a130c45Theodore Ts'o#endif /* __GNU__ */ 19650e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o *mount_flags = EXT2_MF_MOUNTED; 197efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o 198fff45483ede7fe38a31b3364a9c07e2418776deeTheodore Ts'o#ifdef MNTOPT_RO 19952db0b4178553318aac08bb9cdc1d42743e6beebTheodore Ts'o /* Check to see if the ro option is set */ 20052db0b4178553318aac08bb9cdc1d42743e6beebTheodore Ts'o if (hasmntopt(mnt, MNTOPT_RO)) 20152db0b4178553318aac08bb9cdc1d42743e6beebTheodore Ts'o *mount_flags |= EXT2_MF_READONLY; 202fff45483ede7fe38a31b3364a9c07e2418776deeTheodore Ts'o#endif 20352db0b4178553318aac08bb9cdc1d42743e6beebTheodore Ts'o 204cc86017b593ddfbd4d7a12ed8695e62998f30944Theodore Ts'o if (mtpt) 205cc86017b593ddfbd4d7a12ed8695e62998f30944Theodore Ts'o strncpy(mtpt, mnt->mnt_dir, mtlen); 20652db0b4178553318aac08bb9cdc1d42743e6beebTheodore Ts'o /* 20752db0b4178553318aac08bb9cdc1d42743e6beebTheodore Ts'o * Check to see if we're referring to the root filesystem. 20852db0b4178553318aac08bb9cdc1d42743e6beebTheodore Ts'o * If so, do a manual check to see if we can open /etc/mtab 209cc86017b593ddfbd4d7a12ed8695e62998f30944Theodore Ts'o * read/write, since if the root is mounted read/only, the 210cc86017b593ddfbd4d7a12ed8695e62998f30944Theodore Ts'o * contents of /etc/mtab may not be accurate. 21152db0b4178553318aac08bb9cdc1d42743e6beebTheodore Ts'o */ 21250e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o if (!strcmp(mnt->mnt_dir, "/")) { 213cc86017b593ddfbd4d7a12ed8695e62998f30944Theodore Ts'ois_root: 214efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o#define TEST_FILE "/.ismount-test-file" 21550e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o *mount_flags |= EXT2_MF_ISROOT; 2168cdd6a6f34a66806fb200f2a55c8fa4142d79511Andreas Dilger fd = open(TEST_FILE, O_RDWR|O_CREAT, 0600); 21750e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o if (fd < 0) { 21850e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o if (errno == EROFS) 21950e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o *mount_flags |= EXT2_MF_READONLY; 22050e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o } else 22150e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o close(fd); 222997b820e94468aeb3fb1a6fd38bc52e34af6f9e6Theodore Ts'o (void) unlink(TEST_FILE); 22350e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o } 2242038b636b2a72d997b7a6b4123e50d7f8dcb7108Theodore Ts'o retval = 0; 22548e6e81362f264aee4f3945c14928efaf71a06c9Theodore Ts'oerrout: 226cc86017b593ddfbd4d7a12ed8695e62998f30944Theodore Ts'o endmntent (f); 2272038b636b2a72d997b7a6b4123e50d7f8dcb7108Theodore Ts'o return retval; 22850e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o} 22952db0b4178553318aac08bb9cdc1d42743e6beebTheodore Ts'o 23052db0b4178553318aac08bb9cdc1d42743e6beebTheodore Ts'ostatic errcode_t check_mntent(const char *file, int *mount_flags, 23152db0b4178553318aac08bb9cdc1d42743e6beebTheodore Ts'o char *mtpt, int mtlen) 23252db0b4178553318aac08bb9cdc1d42743e6beebTheodore Ts'o{ 23352db0b4178553318aac08bb9cdc1d42743e6beebTheodore Ts'o errcode_t retval; 23452db0b4178553318aac08bb9cdc1d42743e6beebTheodore Ts'o 2352038b636b2a72d997b7a6b4123e50d7f8dcb7108Theodore Ts'o#ifdef DEBUG 2362038b636b2a72d997b7a6b4123e50d7f8dcb7108Theodore Ts'o retval = check_mntent_file("/tmp/mtab", file, mount_flags, 2372038b636b2a72d997b7a6b4123e50d7f8dcb7108Theodore Ts'o mtpt, mtlen); 2382038b636b2a72d997b7a6b4123e50d7f8dcb7108Theodore Ts'o if (retval == 0) 2392038b636b2a72d997b7a6b4123e50d7f8dcb7108Theodore Ts'o return 0; 240f0efd2976b69d31b752b5e5ce4f5e8341a130c45Theodore Ts'o#endif /* DEBUG */ 24152db0b4178553318aac08bb9cdc1d42743e6beebTheodore Ts'o#ifdef __linux__ 24252db0b4178553318aac08bb9cdc1d42743e6beebTheodore Ts'o retval = check_mntent_file("/proc/mounts", file, mount_flags, 24352db0b4178553318aac08bb9cdc1d42743e6beebTheodore Ts'o mtpt, mtlen); 2443a42fe220c301c8b9a8df595938c9a923cf5c494Theodore Ts'o if (retval == 0 && (*mount_flags != 0)) 24552db0b4178553318aac08bb9cdc1d42743e6beebTheodore Ts'o return 0; 246f0efd2976b69d31b752b5e5ce4f5e8341a130c45Theodore Ts'o#endif /* __linux__ */ 2475818d6789aaa795aeee1fdb0f7d812a1cabe3d1dTheodore Ts'o#if defined(MOUNTED) || defined(_PATH_MOUNTED) 2485818d6789aaa795aeee1fdb0f7d812a1cabe3d1dTheodore Ts'o#ifndef MOUNTED 2495818d6789aaa795aeee1fdb0f7d812a1cabe3d1dTheodore Ts'o#define MOUNTED _PATH_MOUNTED 2505818d6789aaa795aeee1fdb0f7d812a1cabe3d1dTheodore Ts'o#endif /* MOUNTED */ 25152db0b4178553318aac08bb9cdc1d42743e6beebTheodore Ts'o retval = check_mntent_file(MOUNTED, file, mount_flags, mtpt, mtlen); 25252db0b4178553318aac08bb9cdc1d42743e6beebTheodore Ts'o return retval; 253efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o#else 2545818d6789aaa795aeee1fdb0f7d812a1cabe3d1dTheodore Ts'o *mount_flags = 0; 2555818d6789aaa795aeee1fdb0f7d812a1cabe3d1dTheodore Ts'o return 0; 2565818d6789aaa795aeee1fdb0f7d812a1cabe3d1dTheodore Ts'o#endif /* defined(MOUNTED) || defined(_PATH_MOUNTED) */ 25752db0b4178553318aac08bb9cdc1d42743e6beebTheodore Ts'o} 25852db0b4178553318aac08bb9cdc1d42743e6beebTheodore Ts'o 25948e6e81362f264aee4f3945c14928efaf71a06c9Theodore Ts'o#else 26048e6e81362f264aee4f3945c14928efaf71a06c9Theodore Ts'o#if defined(HAVE_GETMNTINFO) 26150e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o 26243ec8734f2ecd0a345e831f45fd3dfb077426811Theodore Ts'ostatic errcode_t check_getmntinfo(const char *file, int *mount_flags, 26343ec8734f2ecd0a345e831f45fd3dfb077426811Theodore Ts'o char *mtpt, int mtlen) 26450e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o{ 26550e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o struct statfs *mp; 26650e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o int len, n; 26750e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o const char *s1; 26850e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o char *s2; 26950e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o 27050e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o n = getmntinfo(&mp, MNT_NOWAIT); 27150e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o if (n == 0) 27250e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o return errno; 27350e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o 27450e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o len = sizeof(_PATH_DEV) - 1; 27550e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o s1 = file; 27650e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o if (strncmp(_PATH_DEV, s1, len) == 0) 27750e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o s1 += len; 278efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o 27950e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o *mount_flags = 0; 28050e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o while (--n >= 0) { 28150e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o s2 = mp->f_mntfromname; 28250e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o if (strncmp(_PATH_DEV, s2, len) == 0) { 28350e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o s2 += len - 1; 28450e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o *s2 = 'r'; 28550e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o } 28650e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o if (strcmp(s1, s2) == 0 || strcmp(s1, &s2[1]) == 0) { 28750e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o *mount_flags = EXT2_MF_MOUNTED; 28850e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o break; 28950e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o } 29050e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o ++mp; 29150e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o } 29243ec8734f2ecd0a345e831f45fd3dfb077426811Theodore Ts'o if (mtpt) 29343ec8734f2ecd0a345e831f45fd3dfb077426811Theodore Ts'o strncpy(mtpt, mp->f_mntonname, mtlen); 29450e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o return 0; 29550e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o} 29650e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o#endif /* HAVE_GETMNTINFO */ 297b24efa218794b567c27ad99db319b4bd5d696958Theodore Ts'o#endif /* HAVE_SETMNTENT */ 29850e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o 29950e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o/* 300f0efd2976b69d31b752b5e5ce4f5e8341a130c45Theodore Ts'o * Check to see if we're dealing with the swap device. 301f0efd2976b69d31b752b5e5ce4f5e8341a130c45Theodore Ts'o */ 302f0efd2976b69d31b752b5e5ce4f5e8341a130c45Theodore Ts'ostatic int is_swap_device(const char *file) 303f0efd2976b69d31b752b5e5ce4f5e8341a130c45Theodore Ts'o{ 304f0efd2976b69d31b752b5e5ce4f5e8341a130c45Theodore Ts'o FILE *f; 305f0efd2976b69d31b752b5e5ce4f5e8341a130c45Theodore Ts'o char buf[1024], *cp; 306f0efd2976b69d31b752b5e5ce4f5e8341a130c45Theodore Ts'o dev_t file_dev; 307f0efd2976b69d31b752b5e5ce4f5e8341a130c45Theodore Ts'o struct stat st_buf; 308f0efd2976b69d31b752b5e5ce4f5e8341a130c45Theodore Ts'o int ret = 0; 309f0efd2976b69d31b752b5e5ce4f5e8341a130c45Theodore Ts'o 310f0efd2976b69d31b752b5e5ce4f5e8341a130c45Theodore Ts'o file_dev = 0; 311f0efd2976b69d31b752b5e5ce4f5e8341a130c45Theodore Ts'o#ifndef __GNU__ /* The GNU hurd is broken with respect to stat devices */ 312f0efd2976b69d31b752b5e5ce4f5e8341a130c45Theodore Ts'o if ((stat(file, &st_buf) == 0) && 313f0efd2976b69d31b752b5e5ce4f5e8341a130c45Theodore Ts'o S_ISBLK(st_buf.st_mode)) 314f0efd2976b69d31b752b5e5ce4f5e8341a130c45Theodore Ts'o file_dev = st_buf.st_rdev; 315f0efd2976b69d31b752b5e5ce4f5e8341a130c45Theodore Ts'o#endif /* __GNU__ */ 316f0efd2976b69d31b752b5e5ce4f5e8341a130c45Theodore Ts'o 317f0efd2976b69d31b752b5e5ce4f5e8341a130c45Theodore Ts'o if (!(f = fopen("/proc/swaps", "r"))) 318f0efd2976b69d31b752b5e5ce4f5e8341a130c45Theodore Ts'o return 0; 319f0efd2976b69d31b752b5e5ce4f5e8341a130c45Theodore Ts'o /* Skip the first line */ 3205f91561ae7e08d79b6a5feca167259fd7634713fKarel Zak if (!fgets(buf, sizeof(buf), f)) 3215f91561ae7e08d79b6a5feca167259fd7634713fKarel Zak goto leave; 3225f91561ae7e08d79b6a5feca167259fd7634713fKarel Zak if (*buf && strncmp(buf, "Filename\t", 9)) 3235f91561ae7e08d79b6a5feca167259fd7634713fKarel Zak /* Linux <=2.6.19 contained a bug in the /proc/swaps 3245f91561ae7e08d79b6a5feca167259fd7634713fKarel Zak * code where the header would not be displayed 3255f91561ae7e08d79b6a5feca167259fd7634713fKarel Zak */ 3265f91561ae7e08d79b6a5feca167259fd7634713fKarel Zak goto valid_first_line; 3275f91561ae7e08d79b6a5feca167259fd7634713fKarel Zak 328d9039ae0ff3f7929ede576058b3ad3e9c62a47c4Dmitry V. Levin while (fgets(buf, sizeof(buf), f)) { 3295f91561ae7e08d79b6a5feca167259fd7634713fKarel Zakvalid_first_line: 330f0efd2976b69d31b752b5e5ce4f5e8341a130c45Theodore Ts'o if ((cp = strchr(buf, ' ')) != NULL) 331f0efd2976b69d31b752b5e5ce4f5e8341a130c45Theodore Ts'o *cp = 0; 332f0efd2976b69d31b752b5e5ce4f5e8341a130c45Theodore Ts'o if ((cp = strchr(buf, '\t')) != NULL) 333f0efd2976b69d31b752b5e5ce4f5e8341a130c45Theodore Ts'o *cp = 0; 334f0efd2976b69d31b752b5e5ce4f5e8341a130c45Theodore Ts'o if (strcmp(buf, file) == 0) { 335f0efd2976b69d31b752b5e5ce4f5e8341a130c45Theodore Ts'o ret++; 336f0efd2976b69d31b752b5e5ce4f5e8341a130c45Theodore Ts'o break; 337f0efd2976b69d31b752b5e5ce4f5e8341a130c45Theodore Ts'o } 338f0efd2976b69d31b752b5e5ce4f5e8341a130c45Theodore Ts'o#ifndef __GNU__ 339f0efd2976b69d31b752b5e5ce4f5e8341a130c45Theodore Ts'o if (file_dev && (stat(buf, &st_buf) == 0) && 340f0efd2976b69d31b752b5e5ce4f5e8341a130c45Theodore Ts'o S_ISBLK(st_buf.st_mode) && 341f0efd2976b69d31b752b5e5ce4f5e8341a130c45Theodore Ts'o file_dev == st_buf.st_rdev) { 342f0efd2976b69d31b752b5e5ce4f5e8341a130c45Theodore Ts'o ret++; 343f0efd2976b69d31b752b5e5ce4f5e8341a130c45Theodore Ts'o break; 344f0efd2976b69d31b752b5e5ce4f5e8341a130c45Theodore Ts'o } 345f0efd2976b69d31b752b5e5ce4f5e8341a130c45Theodore Ts'o#endif /* __GNU__ */ 346f0efd2976b69d31b752b5e5ce4f5e8341a130c45Theodore Ts'o } 3475f91561ae7e08d79b6a5feca167259fd7634713fKarel Zak 3485f91561ae7e08d79b6a5feca167259fd7634713fKarel Zakleave: 349f0efd2976b69d31b752b5e5ce4f5e8341a130c45Theodore Ts'o fclose(f); 350f0efd2976b69d31b752b5e5ce4f5e8341a130c45Theodore Ts'o return ret; 351f0efd2976b69d31b752b5e5ce4f5e8341a130c45Theodore Ts'o} 352f0efd2976b69d31b752b5e5ce4f5e8341a130c45Theodore Ts'o 353f0efd2976b69d31b752b5e5ce4f5e8341a130c45Theodore Ts'o 354f0efd2976b69d31b752b5e5ce4f5e8341a130c45Theodore Ts'o/* 3552fa8f37ffff4687228d9f204062f2d27b0e5b919Theodore Ts'o * ext2fs_check_mount_point() fills determines if the device is 3562fa8f37ffff4687228d9f204062f2d27b0e5b919Theodore Ts'o * mounted or otherwise busy, and fills in mount_flags with one or 3572fa8f37ffff4687228d9f204062f2d27b0e5b919Theodore Ts'o * more of the following flags: EXT2_MF_MOUNTED, EXT2_MF_ISROOT, 3582fa8f37ffff4687228d9f204062f2d27b0e5b919Theodore Ts'o * EXT2_MF_READONLY, EXT2_MF_SWAP, and EXT2_MF_BUSY. If mtpt is 3592fa8f37ffff4687228d9f204062f2d27b0e5b919Theodore Ts'o * non-NULL, the directory where the device is mounted is copied to 3602fa8f37ffff4687228d9f204062f2d27b0e5b919Theodore Ts'o * where mtpt is pointing, up to mtlen characters. 36143ec8734f2ecd0a345e831f45fd3dfb077426811Theodore Ts'o */ 36243ec8734f2ecd0a345e831f45fd3dfb077426811Theodore Ts'o#ifdef __TURBOC__ 36331dbecd482405e0d3a67eb58e1a1c8cb9f2ad83eTheodore Ts'o #pragma argsused 36443ec8734f2ecd0a345e831f45fd3dfb077426811Theodore Ts'o#endif 36543ec8734f2ecd0a345e831f45fd3dfb077426811Theodore Ts'oerrcode_t ext2fs_check_mount_point(const char *device, int *mount_flags, 36643ec8734f2ecd0a345e831f45fd3dfb077426811Theodore Ts'o char *mtpt, int mtlen) 36743ec8734f2ecd0a345e831f45fd3dfb077426811Theodore Ts'o{ 3682fa8f37ffff4687228d9f204062f2d27b0e5b919Theodore Ts'o errcode_t retval = 0; 3692fa8f37ffff4687228d9f204062f2d27b0e5b919Theodore Ts'o 37043b7b054cd3165645c9b22977247674f9465e0e1Theodore Ts'o if (getenv("EXT2FS_PRETEND_RO_MOUNT")) { 37143b7b054cd3165645c9b22977247674f9465e0e1Theodore Ts'o *mount_flags = EXT2_MF_MOUNTED | EXT2_MF_READONLY; 37243b7b054cd3165645c9b22977247674f9465e0e1Theodore Ts'o if (getenv("EXT2FS_PRETEND_ROOTFS")) 37343b7b054cd3165645c9b22977247674f9465e0e1Theodore Ts'o *mount_flags = EXT2_MF_ISROOT; 37443b7b054cd3165645c9b22977247674f9465e0e1Theodore Ts'o return 0; 37543b7b054cd3165645c9b22977247674f9465e0e1Theodore Ts'o } 37643b7b054cd3165645c9b22977247674f9465e0e1Theodore Ts'o if (getenv("EXT2FS_PRETEND_RW_MOUNT")) { 37743b7b054cd3165645c9b22977247674f9465e0e1Theodore Ts'o *mount_flags = EXT2_MF_MOUNTED; 37843b7b054cd3165645c9b22977247674f9465e0e1Theodore Ts'o if (getenv("EXT2FS_PRETEND_ROOTFS")) 37943b7b054cd3165645c9b22977247674f9465e0e1Theodore Ts'o *mount_flags = EXT2_MF_ISROOT; 38043b7b054cd3165645c9b22977247674f9465e0e1Theodore Ts'o return 0; 38143b7b054cd3165645c9b22977247674f9465e0e1Theodore Ts'o } 38243b7b054cd3165645c9b22977247674f9465e0e1Theodore Ts'o 38307cefe7a7051e32f14b93d9003a6dbb308597bd3Theodore Ts'o if (is_swap_device(device)) { 38407cefe7a7051e32f14b93d9003a6dbb308597bd3Theodore Ts'o *mount_flags = EXT2_MF_MOUNTED | EXT2_MF_SWAP; 38507cefe7a7051e32f14b93d9003a6dbb308597bd3Theodore Ts'o strncpy(mtpt, "<swap>", mtlen); 3862fa8f37ffff4687228d9f204062f2d27b0e5b919Theodore Ts'o } else { 387b24efa218794b567c27ad99db319b4bd5d696958Theodore Ts'o#ifdef HAVE_SETMNTENT 3882fa8f37ffff4687228d9f204062f2d27b0e5b919Theodore Ts'o retval = check_mntent(device, mount_flags, mtpt, mtlen); 389efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o#else 39043ec8734f2ecd0a345e831f45fd3dfb077426811Theodore Ts'o#ifdef HAVE_GETMNTINFO 3912fa8f37ffff4687228d9f204062f2d27b0e5b919Theodore Ts'o retval = check_getmntinfo(device, mount_flags, mtpt, mtlen); 39243ec8734f2ecd0a345e831f45fd3dfb077426811Theodore Ts'o#else 393ed78c021c3b111d8ab9a51aef5d5156e3004083fTheodore Ts'o#ifdef __GNUC__ 39448e6e81362f264aee4f3945c14928efaf71a06c9Theodore Ts'o #warning "Can't use getmntent or getmntinfo to check for mounted filesystems!" 395ed78c021c3b111d8ab9a51aef5d5156e3004083fTheodore Ts'o#endif 3962fa8f37ffff4687228d9f204062f2d27b0e5b919Theodore Ts'o *mount_flags = 0; 39743ec8734f2ecd0a345e831f45fd3dfb077426811Theodore Ts'o#endif /* HAVE_GETMNTINFO */ 398b24efa218794b567c27ad99db319b4bd5d696958Theodore Ts'o#endif /* HAVE_SETMNTENT */ 3992fa8f37ffff4687228d9f204062f2d27b0e5b919Theodore Ts'o } 4002fa8f37ffff4687228d9f204062f2d27b0e5b919Theodore Ts'o if (retval) 4012fa8f37ffff4687228d9f204062f2d27b0e5b919Theodore Ts'o return retval; 4022fa8f37ffff4687228d9f204062f2d27b0e5b919Theodore Ts'o 4032fa8f37ffff4687228d9f204062f2d27b0e5b919Theodore Ts'o#ifdef __linux__ /* This only works on Linux 2.6+ systems */ 4041d6fd6d0c3766a8165e69284c75812574a29c804Andreas Dilger { 4051d6fd6d0c3766a8165e69284c75812574a29c804Andreas Dilger struct stat st_buf; 4061d6fd6d0c3766a8165e69284c75812574a29c804Andreas Dilger 4071d6fd6d0c3766a8165e69284c75812574a29c804Andreas Dilger if (stat(device, &st_buf) == 0 && S_ISBLK(st_buf.st_mode)) { 4081d6fd6d0c3766a8165e69284c75812574a29c804Andreas Dilger int fd = open(device, O_RDONLY | O_EXCL); 4091d6fd6d0c3766a8165e69284c75812574a29c804Andreas Dilger 4101d6fd6d0c3766a8165e69284c75812574a29c804Andreas Dilger if (fd >= 0) 4111d6fd6d0c3766a8165e69284c75812574a29c804Andreas Dilger close(fd); 4121d6fd6d0c3766a8165e69284c75812574a29c804Andreas Dilger else if (errno == EBUSY) 4131d6fd6d0c3766a8165e69284c75812574a29c804Andreas Dilger *mount_flags |= EXT2_MF_BUSY; 4141d6fd6d0c3766a8165e69284c75812574a29c804Andreas Dilger } 4151d6fd6d0c3766a8165e69284c75812574a29c804Andreas Dilger } 416406ba674fe33469c600a4dd7ed5853cac34ca4e7Matthias Andree#endif 4172fa8f37ffff4687228d9f204062f2d27b0e5b919Theodore Ts'o 4182fa8f37ffff4687228d9f204062f2d27b0e5b919Theodore Ts'o return 0; 41943ec8734f2ecd0a345e831f45fd3dfb077426811Theodore Ts'o} 42043ec8734f2ecd0a345e831f45fd3dfb077426811Theodore Ts'o 42143ec8734f2ecd0a345e831f45fd3dfb077426811Theodore Ts'o/* 4226bd134809ca75741941f41c11fa2b24fbc5ecfacTheodore Ts'o * ext2fs_check_if_mounted() sets the mount_flags EXT2_MF_MOUNTED, 423d5f858dd7f02532ad90e4121537c358e86d0eecfTheodore Ts'o * EXT2_MF_READONLY, and EXT2_MF_ROOT 424efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o * 42550e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o */ 42650e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'oerrcode_t ext2fs_check_if_mounted(const char *file, int *mount_flags) 42750e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o{ 428d5f858dd7f02532ad90e4121537c358e86d0eecfTheodore Ts'o return ext2fs_check_mount_point(file, mount_flags, NULL, 0); 42950e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o} 43052db0b4178553318aac08bb9cdc1d42743e6beebTheodore Ts'o 43152db0b4178553318aac08bb9cdc1d42743e6beebTheodore Ts'o#ifdef DEBUG 43252db0b4178553318aac08bb9cdc1d42743e6beebTheodore Ts'oint main(int argc, char **argv) 43352db0b4178553318aac08bb9cdc1d42743e6beebTheodore Ts'o{ 43452db0b4178553318aac08bb9cdc1d42743e6beebTheodore Ts'o int retval, mount_flags; 435a8fd6e36b866f2cf14edaa19d452fa64bd0fba40Theodore Ts'o char mntpt[80]; 436efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o 43752db0b4178553318aac08bb9cdc1d42743e6beebTheodore Ts'o if (argc < 2) { 43852db0b4178553318aac08bb9cdc1d42743e6beebTheodore Ts'o fprintf(stderr, "Usage: %s device\n", argv[0]); 43952db0b4178553318aac08bb9cdc1d42743e6beebTheodore Ts'o exit(1); 44052db0b4178553318aac08bb9cdc1d42743e6beebTheodore Ts'o } 44152db0b4178553318aac08bb9cdc1d42743e6beebTheodore Ts'o 44204f13d6685b57c29974e4ce2d9074679123bf8a9Theodore Ts'o add_error_table(&et_ext2_error_table); 443a8fd6e36b866f2cf14edaa19d452fa64bd0fba40Theodore Ts'o mntpt[0] = 0; 444a8fd6e36b866f2cf14edaa19d452fa64bd0fba40Theodore Ts'o retval = ext2fs_check_mount_point(argv[1], &mount_flags, 445a8fd6e36b866f2cf14edaa19d452fa64bd0fba40Theodore Ts'o mntpt, sizeof(mntpt)); 44652db0b4178553318aac08bb9cdc1d42743e6beebTheodore Ts'o if (retval) { 44752db0b4178553318aac08bb9cdc1d42743e6beebTheodore Ts'o com_err(argv[0], retval, 44852db0b4178553318aac08bb9cdc1d42743e6beebTheodore Ts'o "while calling ext2fs_check_if_mounted"); 44952db0b4178553318aac08bb9cdc1d42743e6beebTheodore Ts'o exit(1); 45052db0b4178553318aac08bb9cdc1d42743e6beebTheodore Ts'o } 45152db0b4178553318aac08bb9cdc1d42743e6beebTheodore Ts'o printf("Device %s reports flags %02x\n", argv[1], mount_flags); 4522fa8f37ffff4687228d9f204062f2d27b0e5b919Theodore Ts'o if (mount_flags & EXT2_MF_BUSY) 4532fa8f37ffff4687228d9f204062f2d27b0e5b919Theodore Ts'o printf("\t%s is apparently in use.\n", argv[1]); 45452db0b4178553318aac08bb9cdc1d42743e6beebTheodore Ts'o if (mount_flags & EXT2_MF_MOUNTED) 455cc86017b593ddfbd4d7a12ed8695e62998f30944Theodore Ts'o printf("\t%s is mounted.\n", argv[1]); 45607cefe7a7051e32f14b93d9003a6dbb308597bd3Theodore Ts'o if (mount_flags & EXT2_MF_SWAP) 45707cefe7a7051e32f14b93d9003a6dbb308597bd3Theodore Ts'o printf("\t%s is a swap device.\n", argv[1]); 45852db0b4178553318aac08bb9cdc1d42743e6beebTheodore Ts'o if (mount_flags & EXT2_MF_READONLY) 459cc86017b593ddfbd4d7a12ed8695e62998f30944Theodore Ts'o printf("\t%s is read-only.\n", argv[1]); 46052db0b4178553318aac08bb9cdc1d42743e6beebTheodore Ts'o if (mount_flags & EXT2_MF_ISROOT) 461cc86017b593ddfbd4d7a12ed8695e62998f30944Theodore Ts'o printf("\t%s is the root filesystem.\n", argv[1]); 462a8fd6e36b866f2cf14edaa19d452fa64bd0fba40Theodore Ts'o if (mntpt[0]) 463a8fd6e36b866f2cf14edaa19d452fa64bd0fba40Theodore Ts'o printf("\t%s is mounted on %s.\n", argv[1], mntpt); 46452db0b4178553318aac08bb9cdc1d42743e6beebTheodore Ts'o exit(0); 46552db0b4178553318aac08bb9cdc1d42743e6beebTheodore Ts'o} 466f0efd2976b69d31b752b5e5ce4f5e8341a130c45Theodore Ts'o#endif /* DEBUG */ 467