summaryrefslogtreecommitdiffstats
path: root/libdm/libdm-common.c
diff options
context:
space:
mode:
Diffstat (limited to 'libdm/libdm-common.c')
-rw-r--r--libdm/libdm-common.c100
1 files changed, 100 insertions, 0 deletions
diff --git a/libdm/libdm-common.c b/libdm/libdm-common.c
index cbdbc22c..b62b712f 100644
--- a/libdm/libdm-common.c
+++ b/libdm/libdm-common.c
@@ -1056,6 +1056,106 @@ const char *dm_sysfs_dir(void)
return _sysfs_dir;
}
+int dm_device_has_holders(uint32_t major, uint32_t minor)
+{
+ char sysfs_path[PATH_MAX];
+ struct stat st;
+
+ if (!*_sysfs_dir)
+ return 0;
+
+ if (dm_snprintf(sysfs_path, PATH_MAX, "%sdev/block/%" PRIu32
+ ":%" PRIu32 "/holders", _sysfs_dir, major, minor) < 0) {
+ log_error("sysfs_path dm_snprintf failed");
+ return 0;
+ }
+
+ if (stat(sysfs_path, &st)) {
+ log_sys_error("stat", sysfs_path);
+ return 0;
+ }
+
+ return !dm_is_empty_dir(sysfs_path);
+}
+
+static int _mounted_fs_on_device(const char *kernel_dev_name)
+{
+ char sysfs_path[PATH_MAX];
+ struct dirent *dirent;
+ DIR *d;
+ struct stat st;
+ int r = 0;
+
+ if (dm_snprintf(sysfs_path, PATH_MAX, "%sfs", _sysfs_dir) < 0) {
+ log_error("sysfs_path dm_snprintf failed");
+ return 0;
+ }
+
+ if (!(d = opendir(sysfs_path))) {
+ if (errno != ENOENT)
+ log_sys_error("opendir", sysfs_path);
+ return 0;
+ }
+
+ while ((dirent = readdir(d))) {
+ if (!strcmp(dirent->d_name, ".") || !strcmp(dirent->d_name, ".."))
+ continue;
+
+ if (dm_snprintf(sysfs_path, PATH_MAX, "%sfs/%s/%s",
+ _sysfs_dir, dirent->d_name, kernel_dev_name) < 0) {
+ log_error("sysfs_path dm_snprintf failed");
+ break;
+ }
+
+ if (!stat(sysfs_path, &st)) {
+ /* found! */
+ r = 1;
+ break;
+ }
+ else if (errno != ENOENT) {
+ log_sys_error("stat", sysfs_path);
+ break;
+ }
+ }
+
+ if (closedir(d))
+ log_error("_fs_present_on_device: %s: closedir failed", kernel_dev_name);
+
+ return r;
+}
+
+int dm_device_has_mounted_fs(uint32_t major, uint32_t minor)
+{
+ char sysfs_path[PATH_MAX];
+ char temp_path[PATH_MAX];
+ char *kernel_dev_name;
+ ssize_t size;
+
+ if (!*_sysfs_dir)
+ return 0;
+
+ /* Get kernel device name first */
+ if (dm_snprintf(sysfs_path, PATH_MAX, "%sdev/block/%" PRIu32 ":%" PRIu32,
+ _sysfs_dir, major, minor) < 0) {
+ log_error("sysfs_path dm_snprintf failed");
+ return 0;
+ }
+
+ if ((size = readlink(sysfs_path, temp_path, PATH_MAX)) < 0) {
+ log_sys_error("readlink", sysfs_path);
+ return 0;
+ }
+
+ if (!(kernel_dev_name = strrchr(temp_path, '/'))) {
+ log_error("Could not locate device kernel name in sysfs path %s", temp_path);
+ return 0;
+ }
+ kernel_dev_name += 1;
+
+ /* Check /sys/fs/<fs_name>/<kernel_dev_name> presence */
+ return _mounted_fs_on_device(kernel_dev_name);
+}
+
int dm_mknodes(const char *name)
{
struct dm_task *dmt;