Add ismounted.c and related from util-linux.
These are supposed to be LGPL or GPL 2 or later. The licensing is unclear but in util-linux the relevant files are treated as LGPL. is_mounted is wrapped in helpers.h Compared to libparted, this has the benefit of not requiring a PedPartition object, and it's supposed to be reliable and cross-platform.
This commit is contained in:
parent
1135a36b68
commit
815cb3caad
|
@ -1,3 +1,5 @@
|
|||
set_source_files_properties( util/ismounted.c PROPERTIES LANGUAGE CXX )
|
||||
|
||||
set(UTIL_SRC
|
||||
util/capacity.cpp
|
||||
util/externalcommand.cpp
|
||||
|
@ -5,6 +7,7 @@ set(UTIL_SRC
|
|||
util/helpers.cpp
|
||||
util/htmlreport.cpp
|
||||
util/report.cpp
|
||||
util/ismounted.c
|
||||
)
|
||||
|
||||
set(UTIL_LIB_HDRS
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
|
||||
#include "util/helpers.h"
|
||||
#include "../util/globallog.h"
|
||||
#include "../util/ismounted.h"
|
||||
|
||||
#include "../ops/operation.h"
|
||||
|
||||
|
@ -66,3 +67,8 @@ void showColumnsContextMenu(const QPoint& p, QTreeWidget& tree)
|
|||
tree.resizeColumnToContents(action->data().toInt());
|
||||
}
|
||||
}
|
||||
|
||||
bool isMounted(const QString& deviceNode)
|
||||
{
|
||||
return is_mounted(deviceNode.toLatin1().constData());
|
||||
}
|
||||
|
|
|
@ -19,10 +19,10 @@
|
|||
|
||||
#define HELPERS__H
|
||||
|
||||
#include "../util/libpartitionmanagerexport.h"
|
||||
|
||||
#include "../fs/filesystem.h"
|
||||
|
||||
#include "../util/libpartitionmanagerexport.h"
|
||||
|
||||
class QString;
|
||||
class QPoint;
|
||||
class QTreeWidget;
|
||||
|
@ -35,4 +35,6 @@ LIBKPMCORE_EXPORT void showColumnsContextMenu(const QPoint& p, QTreeWidget& tree
|
|||
|
||||
LIBKPMCORE_EXPORT bool checkAccessibleDevices();
|
||||
|
||||
LIBKPMCORE_EXPORT bool isMounted(const QString& deviceNode);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -0,0 +1,400 @@
|
|||
/*
|
||||
* ismounted.c --- Check to see if the filesystem was mounted
|
||||
*
|
||||
* Copyright (C) 1995,1996,1997,1998,1999,2000,2008 Theodore Ts'o.
|
||||
*
|
||||
* This file may be redistributed under the terms of the GNU Public
|
||||
* License.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#ifdef HAVE_MNTENT_H
|
||||
#include <mntent.h>
|
||||
#endif
|
||||
#include <string.h>
|
||||
#include <sys/stat.h>
|
||||
#include <ctype.h>
|
||||
#include <sys/param.h>
|
||||
#ifdef __APPLE__
|
||||
#include <sys/ucred.h>
|
||||
#include <sys/mount.h>
|
||||
#endif
|
||||
|
||||
#include "pathnames.h"
|
||||
#include "ismounted.h"
|
||||
#ifdef __linux__
|
||||
# include "loopdev.h"
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* Fallback defines for old versions of glibc
|
||||
*/
|
||||
#ifdef O_CLOEXEC
|
||||
#define UL_CLOEXECSTR "e"
|
||||
#else
|
||||
#define UL_CLOEXECSTR ""
|
||||
#endif
|
||||
|
||||
#ifndef O_CLOEXEC
|
||||
#define O_CLOEXEC 0
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef HAVE_MNTENT_H
|
||||
/*
|
||||
* Helper function which checks a file in /etc/mtab format to see if a
|
||||
* filesystem is mounted. Returns an error if the file doesn't exist
|
||||
* or can't be opened.
|
||||
*/
|
||||
static int check_mntent_file(const char *mtab_file, const char *file,
|
||||
int *mount_flags, char *mtpt, int mtlen)
|
||||
{
|
||||
struct mntent *mnt;
|
||||
struct stat st_buf;
|
||||
int retval = 0;
|
||||
dev_t file_dev=0, file_rdev=0;
|
||||
ino_t file_ino=0;
|
||||
FILE *f;
|
||||
int fd;
|
||||
|
||||
*mount_flags = 0;
|
||||
if ((f = setmntent (mtab_file, "r")) == NULL)
|
||||
return errno;
|
||||
|
||||
if (stat(file, &st_buf) == 0) {
|
||||
if (S_ISBLK(st_buf.st_mode)) {
|
||||
#ifndef __GNU__ /* The GNU hurd is broken with respect to stat devices */
|
||||
file_rdev = st_buf.st_rdev;
|
||||
#endif /* __GNU__ */
|
||||
} else {
|
||||
file_dev = st_buf.st_dev;
|
||||
file_ino = st_buf.st_ino;
|
||||
}
|
||||
}
|
||||
|
||||
while ((mnt = getmntent (f)) != NULL) {
|
||||
if (mnt->mnt_fsname[0] != '/')
|
||||
continue;
|
||||
if (strcmp(file, mnt->mnt_fsname) == 0)
|
||||
break;
|
||||
if (stat(mnt->mnt_fsname, &st_buf) != 0)
|
||||
continue;
|
||||
|
||||
if (S_ISBLK(st_buf.st_mode)) {
|
||||
#ifndef __GNU__
|
||||
if (file_rdev && file_rdev == st_buf.st_rdev)
|
||||
break;
|
||||
#ifdef __linux__
|
||||
/* maybe the file is loopdev backing file */
|
||||
if (file_dev
|
||||
&& major(st_buf.st_rdev) == LOOPDEV_MAJOR
|
||||
&& loopdev_is_used(mnt->mnt_fsname, file, 0, 0))
|
||||
break;
|
||||
#endif /* __linux__ */
|
||||
#endif /* __GNU__ */
|
||||
} else {
|
||||
if (file_dev && ((file_dev == st_buf.st_dev) &&
|
||||
(file_ino == st_buf.st_ino)))
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (mnt == NULL) {
|
||||
#ifndef __GNU__ /* The GNU hurd is broken with respect to stat devices */
|
||||
/*
|
||||
* Do an extra check to see if this is the root device. We
|
||||
* can't trust /etc/mtab, and /proc/mounts will only list
|
||||
* /dev/root for the root filesystem. Argh. Instead we
|
||||
* check if the given device has the same major/minor number
|
||||
* as the device that the root directory is on.
|
||||
*/
|
||||
if (file_rdev && stat("/", &st_buf) == 0 &&
|
||||
st_buf.st_dev == file_rdev) {
|
||||
*mount_flags = MF_MOUNTED;
|
||||
if (mtpt)
|
||||
strncpy(mtpt, "/", mtlen);
|
||||
goto is_root;
|
||||
}
|
||||
#endif /* __GNU__ */
|
||||
goto errout;
|
||||
}
|
||||
#ifndef __GNU__ /* The GNU hurd is deficient; what else is new? */
|
||||
/* Validate the entry in case /etc/mtab is out of date */
|
||||
/*
|
||||
* We need to be paranoid, because some broken distributions
|
||||
* (read: Slackware) don't initialize /etc/mtab before checking
|
||||
* all of the non-root filesystems on the disk.
|
||||
*/
|
||||
if (stat(mnt->mnt_dir, &st_buf) < 0) {
|
||||
retval = errno;
|
||||
if (retval == ENOENT) {
|
||||
#ifdef DEBUG
|
||||
printf("Bogus entry in %s! (%s does not exist)\n",
|
||||
mtab_file, mnt->mnt_dir);
|
||||
#endif /* DEBUG */
|
||||
retval = 0;
|
||||
}
|
||||
goto errout;
|
||||
}
|
||||
if (file_rdev && (st_buf.st_dev != file_rdev)) {
|
||||
#ifdef DEBUG
|
||||
printf("Bogus entry in %s! (%s not mounted on %s)\n",
|
||||
mtab_file, file, mnt->mnt_dir);
|
||||
#endif /* DEBUG */
|
||||
goto errout;
|
||||
}
|
||||
#endif /* __GNU__ */
|
||||
*mount_flags = MF_MOUNTED;
|
||||
|
||||
#ifdef MNTOPT_RO
|
||||
/* Check to see if the ro option is set */
|
||||
if (hasmntopt(mnt, MNTOPT_RO))
|
||||
*mount_flags |= MF_READONLY;
|
||||
#endif
|
||||
|
||||
if (mtpt)
|
||||
strncpy(mtpt, mnt->mnt_dir, mtlen);
|
||||
/*
|
||||
* Check to see if we're referring to the root filesystem.
|
||||
* If so, do a manual check to see if we can open /etc/mtab
|
||||
* read/write, since if the root is mounted read/only, the
|
||||
* contents of /etc/mtab may not be accurate.
|
||||
*/
|
||||
if (!strcmp(mnt->mnt_dir, "/")) {
|
||||
is_root:
|
||||
#define TEST_FILE "/.ismount-test-file"
|
||||
*mount_flags |= MF_ISROOT;
|
||||
fd = open(TEST_FILE, O_RDWR|O_CREAT|O_CLOEXEC, 0600);
|
||||
if (fd < 0) {
|
||||
if (errno == EROFS)
|
||||
*mount_flags |= MF_READONLY;
|
||||
} else
|
||||
close(fd);
|
||||
(void) unlink(TEST_FILE);
|
||||
}
|
||||
retval = 0;
|
||||
errout:
|
||||
endmntent (f);
|
||||
return retval;
|
||||
}
|
||||
|
||||
static int check_mntent(const char *file, int *mount_flags,
|
||||
char *mtpt, int mtlen)
|
||||
{
|
||||
int retval;
|
||||
|
||||
#ifdef DEBUG
|
||||
retval = check_mntent_file("/tmp/mtab", file, mount_flags,
|
||||
mtpt, mtlen);
|
||||
if (retval == 0)
|
||||
return 0;
|
||||
#endif /* DEBUG */
|
||||
#ifdef __linux__
|
||||
retval = check_mntent_file("/proc/mounts", file, mount_flags,
|
||||
mtpt, mtlen);
|
||||
if (retval == 0 && (*mount_flags != 0))
|
||||
return 0;
|
||||
if (access("/proc/mounts", R_OK) == 0) {
|
||||
*mount_flags = 0;
|
||||
return retval;
|
||||
}
|
||||
#endif /* __linux__ */
|
||||
#if defined(MOUNTED) || defined(_PATH_MOUNTED)
|
||||
#ifndef MOUNTED
|
||||
#define MOUNTED _PATH_MOUNTED
|
||||
#endif /* MOUNTED */
|
||||
retval = check_mntent_file(MOUNTED, file, mount_flags, mtpt, mtlen);
|
||||
return retval;
|
||||
#else
|
||||
*mount_flags = 0;
|
||||
return 0;
|
||||
#endif /* defined(MOUNTED) || defined(_PATH_MOUNTED) */
|
||||
}
|
||||
|
||||
#else
|
||||
#if defined(HAVE_GETMNTINFO)
|
||||
|
||||
static int check_getmntinfo(const char *file, int *mount_flags,
|
||||
char *mtpt, int mtlen)
|
||||
{
|
||||
struct statfs *mp;
|
||||
int len, n;
|
||||
const char *s1;
|
||||
char *s2;
|
||||
|
||||
n = getmntinfo(&mp, MNT_NOWAIT);
|
||||
if (n == 0)
|
||||
return errno;
|
||||
|
||||
len = sizeof(_PATH_DEV) - 1;
|
||||
s1 = file;
|
||||
if (strncmp(_PATH_DEV, s1, len) == 0)
|
||||
s1 += len;
|
||||
|
||||
*mount_flags = 0;
|
||||
while (--n >= 0) {
|
||||
s2 = mp->f_mntfromname;
|
||||
if (strncmp(_PATH_DEV, s2, len) == 0) {
|
||||
s2 += len - 1;
|
||||
*s2 = 'r';
|
||||
}
|
||||
if (strcmp(s1, s2) == 0 || strcmp(s1, &s2[1]) == 0) {
|
||||
*mount_flags = MF_MOUNTED;
|
||||
break;
|
||||
}
|
||||
++mp;
|
||||
}
|
||||
if (mtpt)
|
||||
strncpy(mtpt, mp->f_mntonname, mtlen);
|
||||
return 0;
|
||||
}
|
||||
#endif /* HAVE_GETMNTINFO */
|
||||
#endif /* HAVE_MNTENT_H */
|
||||
|
||||
/*
|
||||
* Check to see if we're dealing with the swap device.
|
||||
*/
|
||||
static int is_swap_device(const char *file)
|
||||
{
|
||||
FILE *f;
|
||||
char buf[1024], *cp;
|
||||
dev_t file_dev;
|
||||
struct stat st_buf;
|
||||
int ret = 0;
|
||||
|
||||
file_dev = 0;
|
||||
#ifndef __GNU__ /* The GNU hurd is broken with respect to stat devices */
|
||||
if ((stat(file, &st_buf) == 0) &&
|
||||
S_ISBLK(st_buf.st_mode))
|
||||
file_dev = st_buf.st_rdev;
|
||||
#endif /* __GNU__ */
|
||||
|
||||
if (!(f = fopen("/proc/swaps", "r" UL_CLOEXECSTR)))
|
||||
return 0;
|
||||
/* Skip the first line */
|
||||
if (!fgets(buf, sizeof(buf), f))
|
||||
goto leave;
|
||||
if (*buf && strncmp(buf, "Filename\t", 9))
|
||||
/* Linux <=2.6.19 contained a bug in the /proc/swaps
|
||||
* code where the header would not be displayed
|
||||
*/
|
||||
goto valid_first_line;
|
||||
|
||||
while (fgets(buf, sizeof(buf), f)) {
|
||||
valid_first_line:
|
||||
if ((cp = strchr(buf, ' ')) != NULL)
|
||||
*cp = 0;
|
||||
if ((cp = strchr(buf, '\t')) != NULL)
|
||||
*cp = 0;
|
||||
if (strcmp(buf, file) == 0) {
|
||||
ret++;
|
||||
break;
|
||||
}
|
||||
#ifndef __GNU__
|
||||
if (file_dev && (stat(buf, &st_buf) == 0) &&
|
||||
S_ISBLK(st_buf.st_mode) &&
|
||||
file_dev == st_buf.st_rdev) {
|
||||
ret++;
|
||||
break;
|
||||
}
|
||||
#endif /* __GNU__ */
|
||||
}
|
||||
|
||||
leave:
|
||||
fclose(f);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* check_mount_point() fills determines if the device is mounted or otherwise
|
||||
* busy, and fills in mount_flags with one or more of the following flags:
|
||||
* MF_MOUNTED, MF_ISROOT, MF_READONLY, MF_SWAP, and MF_BUSY. If mtpt is
|
||||
* non-NULL, the directory where the device is mounted is copied to where mtpt
|
||||
* is pointing, up to mtlen characters.
|
||||
*/
|
||||
#ifdef __TURBOC__
|
||||
#pragma argsused
|
||||
#endif
|
||||
int check_mount_point(const char *device, int *mount_flags,
|
||||
char *mtpt, int mtlen)
|
||||
{
|
||||
struct stat st_buf;
|
||||
int retval = 0;
|
||||
int fd;
|
||||
|
||||
if (is_swap_device(device)) {
|
||||
*mount_flags = MF_MOUNTED | MF_SWAP;
|
||||
if (mtpt && mtlen)
|
||||
strncpy(mtpt, "[SWAP]", mtlen);
|
||||
} else {
|
||||
#ifdef HAVE_MNTENT_H
|
||||
retval = check_mntent(device, mount_flags, mtpt, mtlen);
|
||||
#else
|
||||
#ifdef HAVE_GETMNTINFO
|
||||
retval = check_getmntinfo(device, mount_flags, mtpt, mtlen);
|
||||
#else
|
||||
#ifdef __GNUC__
|
||||
#warning "Can't use getmntent or getmntinfo to check for mounted filesystems!"
|
||||
#endif
|
||||
*mount_flags = 0;
|
||||
#endif /* HAVE_GETMNTINFO */
|
||||
#endif /* HAVE_MNTENT_H */
|
||||
}
|
||||
if (retval)
|
||||
return retval;
|
||||
|
||||
#ifdef __linux__ /* This only works on Linux 2.6+ systems */
|
||||
if ((stat(device, &st_buf) != 0) ||
|
||||
!S_ISBLK(st_buf.st_mode))
|
||||
return 0;
|
||||
fd = open(device, O_RDONLY|O_EXCL|O_CLOEXEC);
|
||||
if (fd < 0) {
|
||||
if (errno == EBUSY)
|
||||
*mount_flags |= MF_BUSY;
|
||||
} else
|
||||
close(fd);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int is_mounted(const char *file)
|
||||
{
|
||||
int retval;
|
||||
int mount_flags = 0;
|
||||
|
||||
retval = check_mount_point(file, &mount_flags, NULL, 0);
|
||||
if (retval)
|
||||
return 0;
|
||||
return mount_flags & MF_MOUNTED;
|
||||
}
|
||||
|
||||
#ifdef TEST_PROGRAM
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int flags = 0;
|
||||
char devname[PATH_MAX];
|
||||
|
||||
if (argc < 2) {
|
||||
fprintf(stderr, "Usage: %s device\n", argv[0]);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
if (check_mount_point(argv[1], &flags, devname, sizeof(devname)) == 0 &&
|
||||
(flags & MF_MOUNTED)) {
|
||||
if (flags & MF_SWAP)
|
||||
printf("used swap device\n");
|
||||
else
|
||||
printf("mounted on %s\n", devname);
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
printf("not mounted\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
#endif /* DEBUG */
|
|
@ -0,0 +1,14 @@
|
|||
#ifndef IS_MOUNTED_H
|
||||
#define IS_MOUNTED_H
|
||||
|
||||
#define MF_MOUNTED 1
|
||||
#define MF_ISROOT 2
|
||||
#define MF_READONLY 4
|
||||
#define MF_SWAP 8
|
||||
#define MF_BUSY 16
|
||||
|
||||
extern int is_mounted(const char *file);
|
||||
extern int check_mount_point(const char *device, int *mount_flags,
|
||||
char *mtpt, int mtlen);
|
||||
|
||||
#endif /* IS_MOUNTED_H */
|
|
@ -0,0 +1,193 @@
|
|||
#ifndef UTIL_LINUX_LOOPDEV_H
|
||||
#define UTIL_LINUX_LOOPDEV_H
|
||||
|
||||
#include "sysfs.h"
|
||||
|
||||
/*
|
||||
* loop_info.lo_encrypt_type
|
||||
*/
|
||||
#define LO_CRYPT_NONE 0
|
||||
#define LO_CRYPT_XOR 1
|
||||
#define LO_CRYPT_DES 2
|
||||
#define LO_CRYPT_CRYPTOAPI 18
|
||||
|
||||
#define LOOP_SET_FD 0x4C00
|
||||
#define LOOP_CLR_FD 0x4C01
|
||||
/*
|
||||
* Obsolete (kernel < 2.6)
|
||||
*
|
||||
* #define LOOP_SET_STATUS 0x4C02
|
||||
* #define LOOP_GET_STATUS 0x4C03
|
||||
*/
|
||||
#define LOOP_SET_STATUS64 0x4C04
|
||||
#define LOOP_GET_STATUS64 0x4C05
|
||||
/* #define LOOP_CHANGE_FD 0x4C06 */
|
||||
#define LOOP_SET_CAPACITY 0x4C07
|
||||
|
||||
/* /dev/loop-control interface */
|
||||
#ifndef LOOP_CTL_ADD
|
||||
# define LOOP_CTL_ADD 0x4C80
|
||||
# define LOOP_CTL_REMOVE 0x4C81
|
||||
# define LOOP_CTL_GET_FREE 0x4C82
|
||||
#endif
|
||||
|
||||
/*
|
||||
* loop_info.lo_flags
|
||||
*/
|
||||
enum {
|
||||
LO_FLAGS_READ_ONLY = 1,
|
||||
LO_FLAGS_USE_AOPS = 2,
|
||||
LO_FLAGS_AUTOCLEAR = 4, /* kernel >= 2.6.25 */
|
||||
LO_FLAGS_PARTSCAN = 8, /* kernel >= 3.2 */
|
||||
};
|
||||
|
||||
#define LO_NAME_SIZE 64
|
||||
#define LO_KEY_SIZE 32
|
||||
|
||||
/*
|
||||
* Linux LOOP_{SET,GET}_STATUS64 ioctl struct
|
||||
*/
|
||||
struct loop_info64 {
|
||||
uint64_t lo_device;
|
||||
uint64_t lo_inode;
|
||||
uint64_t lo_rdevice;
|
||||
uint64_t lo_offset;
|
||||
uint64_t lo_sizelimit; /* bytes, 0 == max available */
|
||||
uint32_t lo_number;
|
||||
uint32_t lo_encrypt_type;
|
||||
uint32_t lo_encrypt_key_size;
|
||||
uint32_t lo_flags;
|
||||
uint8_t lo_file_name[LO_NAME_SIZE];
|
||||
uint8_t lo_crypt_name[LO_NAME_SIZE];
|
||||
uint8_t lo_encrypt_key[LO_KEY_SIZE];
|
||||
uint64_t lo_init[2];
|
||||
};
|
||||
|
||||
#define LOOPDEV_MAJOR 7 /* loop major number */
|
||||
#define LOOPDEV_DEFAULT_NNODES 8 /* default number of loop devices */
|
||||
|
||||
struct loopdev_iter {
|
||||
FILE *proc; /* /proc/partitions */
|
||||
DIR *sysblock; /* /sys/block */
|
||||
int ncur; /* current position */
|
||||
int *minors; /* ary of minor numbers (when scan whole /dev) */
|
||||
int nminors; /* number of items in *minors */
|
||||
int ct_perm; /* count permission problems */
|
||||
int ct_succ; /* count number of detected devices */
|
||||
|
||||
unsigned int done:1; /* scanning done */
|
||||
unsigned int default_check:1;/* check first LOOPDEV_NLOOPS */
|
||||
int flags; /* LOOPITER_FL_* flags */
|
||||
};
|
||||
|
||||
enum {
|
||||
LOOPITER_FL_FREE = (1 << 0),
|
||||
LOOPITER_FL_USED = (1 << 1)
|
||||
};
|
||||
|
||||
/*
|
||||
* handler for work with loop devices
|
||||
*/
|
||||
struct loopdev_cxt {
|
||||
char device[128]; /* device path (e.g. /dev/loop<N>) */
|
||||
char *filename; /* backing file for loopcxt_set_... */
|
||||
int fd; /* open(/dev/looo<N>) */
|
||||
int mode; /* fd mode O_{RDONLY,RDWR} */
|
||||
|
||||
int flags; /* LOOPDEV_FL_* flags */
|
||||
unsigned int has_info:1; /* .info contains data */
|
||||
unsigned int extra_check:1; /* unusual stuff for iterator */
|
||||
unsigned int info_failed:1; /* LOOP_GET_STATUS ioctl failed */
|
||||
unsigned int control_ok:1; /* /dev/loop-control success */
|
||||
|
||||
struct sysfs_cxt sysfs; /* pointer to /sys/dev/block/<maj:min>/ */
|
||||
struct loop_info64 info; /* for GET/SET ioctl */
|
||||
struct loopdev_iter iter; /* scans /sys or /dev for used/free devices */
|
||||
};
|
||||
|
||||
#define UL_LOOPDEVCXT_EMPTY { .fd = -1, .sysfs = UL_SYSFSCXT_EMPTY }
|
||||
|
||||
/*
|
||||
* loopdev_cxt.flags
|
||||
*/
|
||||
enum {
|
||||
LOOPDEV_FL_RDONLY = (1 << 0), /* open(/dev/loop) mode; default */
|
||||
LOOPDEV_FL_RDWR = (1 << 1), /* necessary for loop setup only */
|
||||
LOOPDEV_FL_OFFSET = (1 << 4),
|
||||
LOOPDEV_FL_NOSYSFS = (1 << 5),
|
||||
LOOPDEV_FL_NOIOCTL = (1 << 6),
|
||||
LOOPDEV_FL_DEVSUBDIR = (1 << 7),
|
||||
LOOPDEV_FL_CONTROL = (1 << 8), /* system with /dev/loop-control */
|
||||
LOOPDEV_FL_SIZELIMIT = (1 << 9)
|
||||
};
|
||||
|
||||
/*
|
||||
* High-level
|
||||
*/
|
||||
extern int loopmod_supports_partscan(void);
|
||||
|
||||
extern int is_loopdev(const char *device);
|
||||
extern int loopdev_is_autoclear(const char *device);
|
||||
|
||||
extern char *loopdev_get_backing_file(const char *device);
|
||||
extern int loopdev_is_used(const char *device, const char *filename,
|
||||
uint64_t offset, int flags);
|
||||
extern char *loopdev_find_by_backing_file(const char *filename,
|
||||
uint64_t offset, int flags);
|
||||
extern int loopcxt_find_unused(struct loopdev_cxt *lc);
|
||||
extern int loopdev_delete(const char *device);
|
||||
extern int loopdev_count_by_backing_file(const char *filename, char **loopdev);
|
||||
|
||||
/*
|
||||
* Low-level
|
||||
*/
|
||||
extern int loopcxt_init(struct loopdev_cxt *lc, int flags)
|
||||
__attribute__ ((warn_unused_result));
|
||||
extern void loopcxt_deinit(struct loopdev_cxt *lc);
|
||||
|
||||
extern int loopcxt_set_device(struct loopdev_cxt *lc, const char *device)
|
||||
__attribute__ ((warn_unused_result));
|
||||
extern int loopcxt_has_device(struct loopdev_cxt *lc);
|
||||
extern int loopcxt_add_device(struct loopdev_cxt *lc);
|
||||
extern char *loopcxt_strdup_device(struct loopdev_cxt *lc);
|
||||
extern const char *loopcxt_get_device(struct loopdev_cxt *lc);
|
||||
extern struct sysfs_cxt *loopcxt_get_sysfs(struct loopdev_cxt *lc);
|
||||
extern struct loop_info64 *loopcxt_get_info(struct loopdev_cxt *lc);
|
||||
|
||||
extern int loopcxt_get_fd(struct loopdev_cxt *lc);
|
||||
extern int loopcxt_set_fd(struct loopdev_cxt *lc, int fd, int mode);
|
||||
|
||||
extern int loopcxt_init_iterator(struct loopdev_cxt *lc, int flags);
|
||||
extern int loopcxt_deinit_iterator(struct loopdev_cxt *lc);
|
||||
extern int loopcxt_next(struct loopdev_cxt *lc);
|
||||
|
||||
extern int loopcxt_setup_device(struct loopdev_cxt *lc);
|
||||
extern int loopcxt_delete_device(struct loopdev_cxt *lc);
|
||||
extern int loopcxt_set_capacity(struct loopdev_cxt *lc);
|
||||
|
||||
int loopcxt_set_offset(struct loopdev_cxt *lc, uint64_t offset);
|
||||
int loopcxt_set_sizelimit(struct loopdev_cxt *lc, uint64_t sizelimit);
|
||||
int loopcxt_set_flags(struct loopdev_cxt *lc, uint32_t flags);
|
||||
int loopcxt_set_backing_file(struct loopdev_cxt *lc, const char *filename);
|
||||
|
||||
extern char *loopcxt_get_backing_file(struct loopdev_cxt *lc);
|
||||
extern int loopcxt_get_backing_devno(struct loopdev_cxt *lc, dev_t *devno);
|
||||
extern int loopcxt_get_backing_inode(struct loopdev_cxt *lc, ino_t *ino);
|
||||
extern int loopcxt_get_offset(struct loopdev_cxt *lc, uint64_t *offset);
|
||||
extern int loopcxt_get_sizelimit(struct loopdev_cxt *lc, uint64_t *size);
|
||||
extern int loopcxt_get_encrypt_type(struct loopdev_cxt *lc, uint32_t *type);
|
||||
extern const char *loopcxt_get_crypt_name(struct loopdev_cxt *lc);
|
||||
extern int loopcxt_is_autoclear(struct loopdev_cxt *lc);
|
||||
extern int loopcxt_is_readonly(struct loopdev_cxt *lc);
|
||||
extern int loopcxt_is_partscan(struct loopdev_cxt *lc);
|
||||
extern int loopcxt_find_by_backing_file(struct loopdev_cxt *lc,
|
||||
const char *filename,
|
||||
uint64_t offset, int flags);
|
||||
|
||||
extern int loopcxt_is_used(struct loopdev_cxt *lc,
|
||||
struct stat *st,
|
||||
const char *backing_file,
|
||||
uint64_t offset,
|
||||
int flags);
|
||||
|
||||
#endif /* UTIL_LINUX_LOOPDEV_H */
|
|
@ -0,0 +1,212 @@
|
|||
/*
|
||||
* Vaguely based on
|
||||
* @(#)pathnames.h 5.3 (Berkeley) 5/9/89
|
||||
* This code is in the public domain.
|
||||
*/
|
||||
#ifndef PATHNAMES_H
|
||||
#define PATHNAMES_H
|
||||
|
||||
#ifdef HAVE_PATHS_H
|
||||
#include <paths.h>
|
||||
#endif
|
||||
|
||||
#ifndef __STDC__
|
||||
# error "we need an ANSI compiler"
|
||||
#endif
|
||||
|
||||
/* used by kernel in /proc (e.g. /proc/swaps) for deleted files */
|
||||
#define PATH_DELETED_SUFFIX "\\040(deleted)"
|
||||
#define PATH_DELETED_SUFFIX_SZ (sizeof(PATH_DELETED_SUFFIX) - 1)
|
||||
|
||||
/* DEFPATHs from <paths.h> don't include /usr/local */
|
||||
#undef _PATH_DEFPATH
|
||||
|
||||
#ifdef USE_USRDIR_PATHS_ONLY
|
||||
# define _PATH_DEFPATH "/usr/local/bin:/usr/bin"
|
||||
#else
|
||||
# define _PATH_DEFPATH "/usr/local/bin:/bin:/usr/bin"
|
||||
#endif
|
||||
|
||||
#undef _PATH_DEFPATH_ROOT
|
||||
|
||||
#ifdef USE_USRDIR_PATHS_ONLY
|
||||
# define _PATH_DEFPATH_ROOT "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin"
|
||||
#else
|
||||
# define _PATH_DEFPATH_ROOT "/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin"
|
||||
#endif
|
||||
|
||||
#define _PATH_SECURETTY "/etc/securetty"
|
||||
#define _PATH_WTMPLOCK "/etc/wtmplock"
|
||||
|
||||
#define _PATH_HUSHLOGIN ".hushlogin"
|
||||
#define _PATH_HUSHLOGINS "/etc/hushlogins"
|
||||
|
||||
#define _PATH_NOLOGIN_TXT "/etc/nologin.txt"
|
||||
|
||||
#ifndef _PATH_MAILDIR
|
||||
#define _PATH_MAILDIR "/var/spool/mail"
|
||||
#endif
|
||||
#define _PATH_MOTDFILE "/etc/motd"
|
||||
#define _PATH_NOLOGIN "/etc/nologin"
|
||||
#define _PATH_VAR_NOLOGIN "/var/run/nologin"
|
||||
|
||||
#define _PATH_LOGIN "/bin/login"
|
||||
#define _PATH_INITTAB "/etc/inittab"
|
||||
#define _PATH_RC "/etc/rc"
|
||||
#define _PATH_REBOOT "/sbin/reboot"
|
||||
#define _PATH_SHUTDOWN "/sbin/shutdown"
|
||||
#define _PATH_SINGLE "/etc/singleboot"
|
||||
#define _PATH_SHUTDOWN_CONF "/etc/shutdown.conf"
|
||||
|
||||
#define _PATH_SECURE "/etc/securesingle"
|
||||
#define _PATH_USERTTY "/etc/usertty"
|
||||
|
||||
#define _PATH_TERMCOLORS_DIRNAME "terminal-colors.d"
|
||||
#define _PATH_TERMCOLORS_DIR "/etc/" _PATH_TERMCOLORS_DIRNAME
|
||||
|
||||
/* used in login-utils/shutdown.c */
|
||||
|
||||
/* used in login-utils/setpwnam.h and login-utils/islocal.c */
|
||||
#define _PATH_PASSWD "/etc/passwd"
|
||||
|
||||
/* used in login-utils/newgrp and login-utils/setpwnam.h*/
|
||||
#define _PATH_GSHADOW "/etc/gshadow"
|
||||
|
||||
/* used in login-utils/setpwnam.h */
|
||||
#define _PATH_GROUP "/etc/group"
|
||||
#define _PATH_SHADOW_PASSWD "/etc/shadow"
|
||||
#define _PATH_SHELLS "/etc/shells"
|
||||
|
||||
/* used in term-utils/agetty.c */
|
||||
#define _PATH_ISSUE "/etc/issue"
|
||||
#define _PATH_OS_RELEASE_ETC "/etc/os-release"
|
||||
#define _PATH_OS_RELEASE_USR "/usr/lib/os-release"
|
||||
|
||||
#define _PATH_NUMLOCK_ON _PATH_LOCALSTATEDIR "/numlock-on"
|
||||
|
||||
#define _PATH_LOGINDEFS "/etc/login.defs"
|
||||
|
||||
/* used in misc-utils/look.c */
|
||||
#define _PATH_WORDS "/usr/share/dict/words"
|
||||
#define _PATH_WORDS_ALT "/usr/share/dict/web2"
|
||||
|
||||
/* mount paths */
|
||||
#define _PATH_UMOUNT "/bin/umount"
|
||||
|
||||
#define _PATH_FILESYSTEMS "/etc/filesystems"
|
||||
#define _PATH_PROC_SWAPS "/proc/swaps"
|
||||
#define _PATH_PROC_FILESYSTEMS "/proc/filesystems"
|
||||
#define _PATH_PROC_MOUNTS "/proc/mounts"
|
||||
#define _PATH_PROC_PARTITIONS "/proc/partitions"
|
||||
#define _PATH_PROC_DEVICES "/proc/devices"
|
||||
#define _PATH_PROC_MOUNTINFO "/proc/self/mountinfo"
|
||||
#define _PATH_PROC_LOCKS "/proc/locks"
|
||||
#define _PATH_PROC_CDROMINFO "/proc/sys/dev/cdrom/info"
|
||||
|
||||
#define _PATH_PROC_UIDMAP "/proc/self/uid_map"
|
||||
#define _PATH_PROC_GIDMAP "/proc/self/gid_map"
|
||||
#define _PATH_PROC_SETGROUPS "/proc/self/setgroups"
|
||||
|
||||
#define _PATH_PROC_ATTR_CURRENT "/proc/self/attr/current"
|
||||
#define _PATH_PROC_ATTR_EXEC "/proc/self/attr/exec"
|
||||
#define _PATH_PROC_CAPLASTCAP "/proc/sys/kernel/cap_last_cap"
|
||||
|
||||
|
||||
#define _PATH_SYS_BLOCK "/sys/block"
|
||||
#define _PATH_SYS_DEVBLOCK "/sys/dev/block"
|
||||
#define _PATH_SYS_CLASS "/sys/class"
|
||||
#define _PATH_SYS_SCSI "/sys/bus/scsi"
|
||||
|
||||
#define _PATH_SYS_SELINUX "/sys/fs/selinux"
|
||||
#define _PATH_SYS_APPARMOR "/sys/kernel/security/apparmor"
|
||||
|
||||
#ifndef _PATH_MOUNTED
|
||||
# ifdef MOUNTED /* deprecated */
|
||||
# define _PATH_MOUNTED MOUNTED
|
||||
# else
|
||||
# define _PATH_MOUNTED "/etc/mtab"
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef _PATH_MNTTAB
|
||||
# ifdef MNTTAB /* deprecated */
|
||||
# define _PATH_MNTTAB MNTTAB
|
||||
# else
|
||||
# define _PATH_MNTTAB "/etc/fstab"
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#define _PATH_MNTTAB_DIR _PATH_MNTTAB ".d"
|
||||
|
||||
#define _PATH_MOUNTED_LOCK _PATH_MOUNTED "~"
|
||||
#define _PATH_MOUNTED_TMP _PATH_MOUNTED ".tmp"
|
||||
|
||||
#ifndef _PATH_DEV
|
||||
/*
|
||||
* The tailing '/' in _PATH_DEV is there for compatibility with libc.
|
||||
*/
|
||||
# define _PATH_DEV "/dev/"
|
||||
#endif
|
||||
|
||||
#define _PATH_DEV_MEM "/dev/mem"
|
||||
|
||||
#define _PATH_DEV_LOOP "/dev/loop"
|
||||
#define _PATH_DEV_LOOPCTL "/dev/loop-control"
|
||||
#define _PATH_DEV_TTY "/dev/tty"
|
||||
|
||||
|
||||
/* udev paths */
|
||||
#define _PATH_DEV_BYLABEL "/dev/disk/by-label"
|
||||
#define _PATH_DEV_BYUUID "/dev/disk/by-uuid"
|
||||
#define _PATH_DEV_BYID "/dev/disk/by-id"
|
||||
#define _PATH_DEV_BYPATH "/dev/disk/by-path"
|
||||
#define _PATH_DEV_BYPARTLABEL "/dev/disk/by-partlabel"
|
||||
#define _PATH_DEV_BYPARTUUID "/dev/disk/by-partuuid"
|
||||
|
||||
/* hwclock paths */
|
||||
#ifdef CONFIG_ADJTIME_PATH
|
||||
# define _PATH_ADJTIME CONFIG_ADJTIME_PATH
|
||||
#else
|
||||
# define _PATH_ADJTIME "/etc/adjtime"
|
||||
#endif
|
||||
|
||||
#define _PATH_LASTDATE "/var/lib/lastdate"
|
||||
#ifdef __ia64__
|
||||
# define _PATH_RTC_DEV "/dev/efirtc"
|
||||
#else
|
||||
# define _PATH_RTC_DEV "/dev/rtc"
|
||||
#endif
|
||||
|
||||
#ifndef _PATH_BTMP
|
||||
#define _PATH_BTMP "/var/log/btmp"
|
||||
#endif
|
||||
|
||||
/* raw paths*/
|
||||
#define _PATH_RAWDEVDIR "/dev/raw/"
|
||||
#define _PATH_RAWDEVCTL _PATH_RAWDEVDIR "rawctl"
|
||||
/* deprecated */
|
||||
#define _PATH_RAWDEVCTL_OLD "/dev/rawctl"
|
||||
|
||||
/* wdctl path */
|
||||
#define _PATH_WATCHDOG_DEV "/dev/watchdog"
|
||||
|
||||
/* ipc paths */
|
||||
#define _PATH_PROC_SYSV_MSG "/proc/sysvipc/msg"
|
||||
#define _PATH_PROC_SYSV_SEM "/proc/sysvipc/sem"
|
||||
#define _PATH_PROC_SYSV_SHM "/proc/sysvipc/shm"
|
||||
#define _PATH_PROC_IPC_MSGMAX "/proc/sys/kernel/msgmax"
|
||||
#define _PATH_PROC_IPC_MSGMNB "/proc/sys/kernel/msgmnb"
|
||||
#define _PATH_PROC_IPC_MSGMNI "/proc/sys/kernel/msgmni"
|
||||
#define _PATH_PROC_IPC_SEM "/proc/sys/kernel/sem"
|
||||
#define _PATH_PROC_IPC_SHMALL "/proc/sys/kernel/shmall"
|
||||
#define _PATH_PROC_IPC_SHMMAX "/proc/sys/kernel/shmmax"
|
||||
#define _PATH_PROC_IPC_SHMMNI "/proc/sys/kernel/shmmni"
|
||||
|
||||
/* kernel command line */
|
||||
#define _PATH_PROC_CMDLINE "/proc/cmdline"
|
||||
|
||||
/* logger paths */
|
||||
#define _PATH_DEVLOG "/dev/log"
|
||||
|
||||
#endif /* PATHNAMES_H */
|
||||
|
|
@ -0,0 +1,127 @@
|
|||
/*
|
||||
* Copyright (C) 2011 Karel Zak <kzak@redhat.com>
|
||||
*/
|
||||
#ifndef UTIL_LINUX_SYSFS_H
|
||||
#define UTIL_LINUX_SYSFS_H
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <stdint.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <string.h>
|
||||
#include <inttypes.h>
|
||||
#include <dirent.h>
|
||||
|
||||
struct sysfs_cxt {
|
||||
dev_t devno;
|
||||
int dir_fd; /* /sys/block/<name> */
|
||||
char *dir_path;
|
||||
struct sysfs_cxt *parent;
|
||||
|
||||
unsigned int scsi_host,
|
||||
scsi_channel,
|
||||
scsi_target,
|
||||
scsi_lun;
|
||||
|
||||
unsigned int has_hctl : 1;
|
||||
};
|
||||
|
||||
#define UL_SYSFSCXT_EMPTY { 0, -1, NULL, NULL, 0, 0, 0, 0, 0 }
|
||||
|
||||
extern char *sysfs_devno_attribute_path(dev_t devno, char *buf,
|
||||
size_t bufsiz, const char *attr);
|
||||
extern int sysfs_devno_has_attribute(dev_t devno, const char *attr);
|
||||
extern char *sysfs_devno_path(dev_t devno, char *buf, size_t bufsiz);
|
||||
extern char *sysfs_devno_to_devpath(dev_t devno, char *buf, size_t bufsiz);
|
||||
extern dev_t sysfs_devname_to_devno(const char *name, const char *parent);
|
||||
|
||||
extern int sysfs_init(struct sysfs_cxt *cxt, dev_t devno, struct sysfs_cxt *parent)
|
||||
__attribute__ ((warn_unused_result));
|
||||
extern void sysfs_deinit(struct sysfs_cxt *cxt);
|
||||
|
||||
extern DIR *sysfs_opendir(struct sysfs_cxt *cxt, const char *attr);
|
||||
|
||||
extern int sysfs_stat(struct sysfs_cxt *cxt, const char *attr, struct stat *st);
|
||||
extern ssize_t sysfs_readlink(struct sysfs_cxt *cxt, const char *attr,
|
||||
char *buf, size_t bufsiz);
|
||||
extern int sysfs_has_attribute(struct sysfs_cxt *cxt, const char *attr);
|
||||
|
||||
extern int sysfs_scanf(struct sysfs_cxt *cxt, const char *attr,
|
||||
const char *fmt, ...)
|
||||
__attribute__ ((format (scanf, 3, 4)));
|
||||
|
||||
extern int sysfs_read_s64(struct sysfs_cxt *cxt, const char *attr, int64_t *res);
|
||||
extern int sysfs_read_u64(struct sysfs_cxt *cxt, const char *attr, uint64_t *res);
|
||||
extern int sysfs_read_int(struct sysfs_cxt *cxt, const char *attr, int *res);
|
||||
|
||||
extern int sysfs_write_string(struct sysfs_cxt *cxt, const char *attr, const char *str);
|
||||
extern int sysfs_write_u64(struct sysfs_cxt *cxt, const char *attr, uint64_t num);
|
||||
|
||||
extern char *sysfs_get_devname(struct sysfs_cxt *cxt, char *buf, size_t bufsiz);
|
||||
|
||||
extern char *sysfs_strdup(struct sysfs_cxt *cxt, const char *attr);
|
||||
|
||||
extern int sysfs_count_dirents(struct sysfs_cxt *cxt, const char *attr);
|
||||
extern int sysfs_count_partitions(struct sysfs_cxt *cxt, const char *devname);
|
||||
extern dev_t sysfs_partno_to_devno(struct sysfs_cxt *cxt, int partno);
|
||||
extern char *sysfs_get_slave(struct sysfs_cxt *cxt);
|
||||
|
||||
extern char *sysfs_get_devchain(struct sysfs_cxt *cxt, char *buf, size_t bufsz);
|
||||
extern int sysfs_next_subsystem(struct sysfs_cxt *cxt, char *devchain, char **subsys);
|
||||
extern int sysfs_is_hotpluggable(struct sysfs_cxt *cxt);
|
||||
|
||||
extern int sysfs_is_partition_dirent(DIR *dir, struct dirent *d,
|
||||
const char *parent_name);
|
||||
|
||||
extern int sysfs_devno_to_wholedisk(dev_t dev, char *diskname,
|
||||
size_t len, dev_t *diskdevno);
|
||||
|
||||
extern int sysfs_devno_is_lvm_private(dev_t devno);
|
||||
extern int sysfs_devno_is_wholedisk(dev_t devno);
|
||||
|
||||
extern int sysfs_scsi_get_hctl(struct sysfs_cxt *cxt, int *h,
|
||||
int *c, int *t, int *l);
|
||||
extern char *sysfs_scsi_host_strdup_attribute(struct sysfs_cxt *cxt,
|
||||
const char *type, const char *attr);
|
||||
extern int sysfs_scsi_host_is(struct sysfs_cxt *cxt, const char *type);
|
||||
extern int sysfs_scsi_has_attribute(struct sysfs_cxt *cxt, const char *attr);
|
||||
extern int sysfs_scsi_path_contains(struct sysfs_cxt *cxt, const char *pattern);
|
||||
|
||||
/**
|
||||
* sysfs_devname_sys_to_dev:
|
||||
* @name: devname to be converted in place
|
||||
*
|
||||
* Linux kernel linux/drivers/base/core.c: device_get_devnode()
|
||||
* defines a replacement of '!' in the /sys device name by '/' in the
|
||||
* /dev device name. This helper replaces all ocurrences of '!' in
|
||||
* @name by '/' to convert from /sys to /dev.
|
||||
*/
|
||||
static inline void sysfs_devname_sys_to_dev(char *name)
|
||||
{
|
||||
char *c;
|
||||
|
||||
if (name)
|
||||
while ((c = strchr(name, '!')))
|
||||
c[0] = '/';
|
||||
}
|
||||
|
||||
/**
|
||||
* sysfs_devname_dev_to_sys:
|
||||
* @name: devname to be converted in place
|
||||
*
|
||||
* See sysfs_devname_sys_to_dev().
|
||||
*/
|
||||
static inline void sysfs_devname_dev_to_sys(char *name)
|
||||
{
|
||||
char *c;
|
||||
|
||||
if (name)
|
||||
while ((c = strchr(name, '/')))
|
||||
c[0] = '!';
|
||||
}
|
||||
|
||||
#endif /* UTIL_LINUX_SYSFS_H */
|
Loading…
Reference in New Issue