|
|
d087b3 |
From 723e7b342ec311a59f92eb94936ce769e804b43d Mon Sep 17 00:00:00 2001
|
|
|
6cc97b |
From: Chris Leech <cleech@redhat.com>
|
|
|
6cc97b |
Date: Fri, 24 Jul 2015 14:18:30 -0700
|
|
|
d087b3 |
Subject: [PATCH v2 8/9] iscsid: make safe_logut session checks apply for
|
|
|
d087b3 |
flashnode session
|
|
|
6cc97b |
|
|
|
d087b3 |
Make the safe_logout option work with flashnode sessions as well.
|
|
|
d087b3 |
Moves the code into a new file shared between iscsid and iscsiadm.
|
|
|
6cc97b |
---
|
|
|
6cc97b |
usr/Makefile | 8 +-
|
|
|
d087b3 |
usr/initiator.c | 195 -----------------------------------------
|
|
|
6cc97b |
usr/initiator.h | 1 +
|
|
|
d087b3 |
usr/initiator_common.c | 2 +
|
|
|
6cc97b |
usr/iscsiadm.c | 23 +++++
|
|
|
6cc97b |
usr/iscsistart.c | 2 +
|
|
|
d087b3 |
usr/mntcheck.c | 233 +++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
d087b3 |
7 files changed, 265 insertions(+), 199 deletions(-)
|
|
|
6cc97b |
create mode 100644 usr/mntcheck.c
|
|
|
6cc97b |
|
|
|
6cc97b |
diff --git a/usr/Makefile b/usr/Makefile
|
|
|
d087b3 |
index 277ac6a..c1866b6 100644
|
|
|
6cc97b |
--- a/usr/Makefile
|
|
|
6cc97b |
+++ b/usr/Makefile
|
|
|
d087b3 |
@@ -53,15 +53,15 @@ DISCOVERY_SRCS = $(FW_BOOT_SRCS) strings.o discovery.o
|
|
|
6cc97b |
all: $(PROGRAMS)
|
|
|
6cc97b |
|
|
|
6cc97b |
iscsid: $(ISCSI_LIB_SRCS) $(INITIATOR_SRCS) $(DISCOVERY_SRCS) \
|
|
|
6cc97b |
- iscsid.o session_mgmt.o discoveryd.o
|
|
|
6cc97b |
+ iscsid.o session_mgmt.o discoveryd.o mntcheck.o
|
|
|
d087b3 |
$(CC) $(CFLAGS) $(LDFLAGS) $^ -o $@ -lisns -lcrypto -lrt -lmount
|
|
|
6cc97b |
|
|
|
6cc97b |
-iscsiadm: $(ISCSI_LIB_SRCS) $(DISCOVERY_SRCS) iscsiadm.o session_mgmt.o
|
|
|
d087b3 |
- $(CC) $(CFLAGS) $(LDFLAGS) $^ -o $@ -lisns -lcrypto
|
|
|
6cc97b |
+iscsiadm: $(ISCSI_LIB_SRCS) $(DISCOVERY_SRCS) iscsiadm.o session_mgmt.o mntcheck.o
|
|
|
d087b3 |
+ $(CC) $(CFLAGS) $(LDFLAGS) $^ -o $@ -lisns -lcrypto -lmount
|
|
|
6cc97b |
|
|
|
6cc97b |
iscsistart: $(ISCSI_LIB_SRCS) $(INITIATOR_SRCS) $(FW_BOOT_SRCS) \
|
|
|
6cc97b |
iscsistart.o statics.o
|
|
|
d087b3 |
- $(CC) $(CFLAGS) $(LDFLAGS) $^ -o $@ -lrt -lmount
|
|
|
d087b3 |
+ $(CC) $(CFLAGS) $(LDFLAGS) $^ -o $@ -lrt
|
|
|
6cc97b |
clean:
|
|
|
6cc97b |
rm -f *.o $(PROGRAMS) .depend $(LIBSYS)
|
|
|
6cc97b |
|
|
|
6cc97b |
diff --git a/usr/initiator.c b/usr/initiator.c
|
|
|
d087b3 |
index b0f0147..072bcc9 100644
|
|
|
6cc97b |
--- a/usr/initiator.c
|
|
|
6cc97b |
+++ b/usr/initiator.c
|
|
|
6cc97b |
@@ -30,7 +30,6 @@
|
|
|
6cc97b |
#include <errno.h>
|
|
|
6cc97b |
#include <dirent.h>
|
|
|
6cc97b |
#include <fcntl.h>
|
|
|
6cc97b |
-#include <libmount/libmount.h>
|
|
|
6cc97b |
|
|
|
6cc97b |
#include "initiator.h"
|
|
|
6cc97b |
#include "transport.h"
|
|
|
d087b3 |
@@ -2044,200 +2043,6 @@ static int session_unbind(struct iscsi_session *session)
|
|
|
6cc97b |
return err;
|
|
|
6cc97b |
}
|
|
|
6cc97b |
|
|
|
6cc97b |
-static struct libmnt_table *mtab, *swaps;
|
|
|
6cc97b |
-static struct libmnt_cache *mntcache;
|
|
|
6cc97b |
-
|
|
|
6cc97b |
-static void libmount_cleanup(void)
|
|
|
6cc97b |
-{
|
|
|
6cc97b |
- mnt_free_table(mtab);
|
|
|
6cc97b |
- mnt_free_table(swaps);
|
|
|
6cc97b |
- mnt_free_cache(mntcache);
|
|
|
6cc97b |
- mtab = swaps = mntcache = NULL;
|
|
|
6cc97b |
-}
|
|
|
6cc97b |
-
|
|
|
6cc97b |
-static int libmount_init(void)
|
|
|
6cc97b |
-{
|
|
|
6cc97b |
- mnt_init_debug(0);
|
|
|
6cc97b |
- mtab = mnt_new_table();
|
|
|
6cc97b |
- swaps = mnt_new_table();
|
|
|
6cc97b |
- mntcache = mnt_new_cache();
|
|
|
6cc97b |
- if (!mtab || !swaps || !mntcache) {
|
|
|
6cc97b |
- libmount_cleanup();
|
|
|
6cc97b |
- return -ENOMEM;
|
|
|
6cc97b |
- }
|
|
|
6cc97b |
- mnt_table_set_cache(mtab, mntcache);
|
|
|
6cc97b |
- mnt_table_set_cache(swaps, mntcache);
|
|
|
6cc97b |
- mnt_table_parse_mtab(mtab, NULL);
|
|
|
6cc97b |
- mnt_table_parse_swaps(swaps, NULL);
|
|
|
6cc97b |
- return 0;
|
|
|
6cc97b |
-}
|
|
|
6cc97b |
-
|
|
|
6cc97b |
-static int trans_filter(const struct dirent *d)
|
|
|
6cc97b |
-{
|
|
|
6cc97b |
- if (!strcmp(".", d->d_name) || !strcmp("..", d->d_name))
|
|
|
6cc97b |
- return 0;
|
|
|
6cc97b |
- return 1;
|
|
|
6cc97b |
-}
|
|
|
6cc97b |
-
|
|
|
6cc97b |
-static int subdir_filter(const struct dirent *d)
|
|
|
6cc97b |
-{
|
|
|
6cc97b |
- if (!(d->d_type & DT_DIR))
|
|
|
6cc97b |
- return 0;
|
|
|
6cc97b |
- return trans_filter(d);
|
|
|
6cc97b |
-}
|
|
|
6cc97b |
-
|
|
|
6cc97b |
-static int is_partition(const char *path)
|
|
|
6cc97b |
-{
|
|
|
6cc97b |
- char *devtype;
|
|
|
6cc97b |
- int rc = 0;
|
|
|
6cc97b |
-
|
|
|
6cc97b |
- devtype = sysfs_get_uevent_devtype(path);
|
|
|
6cc97b |
- if (!devtype)
|
|
|
6cc97b |
- return 0;
|
|
|
6cc97b |
- if (strcmp(devtype, "partition") == 0)
|
|
|
6cc97b |
- rc = 1;
|
|
|
6cc97b |
- free(devtype);
|
|
|
6cc97b |
- return rc;
|
|
|
6cc97b |
-}
|
|
|
6cc97b |
-
|
|
|
6cc97b |
-static int blockdev_check_mnts(char *syspath)
|
|
|
6cc97b |
-{
|
|
|
6cc97b |
- struct libmnt_fs *fs;
|
|
|
6cc97b |
- char *devname = NULL;
|
|
|
6cc97b |
- char *_devname = NULL;
|
|
|
6cc97b |
- int rc = 0;
|
|
|
6cc97b |
-
|
|
|
6cc97b |
- devname = sysfs_get_uevent_devname(syspath);
|
|
|
6cc97b |
- if (!devname)
|
|
|
6cc97b |
- goto out;
|
|
|
6cc97b |
-
|
|
|
6cc97b |
- _devname = calloc(1, PATH_MAX);
|
|
|
6cc97b |
- if (!_devname)
|
|
|
6cc97b |
- goto out;
|
|
|
6cc97b |
- snprintf(_devname, PATH_MAX, "/dev/%s", devname);
|
|
|
6cc97b |
-
|
|
|
6cc97b |
- fs = mnt_table_find_source(mtab, _devname, MNT_ITER_FORWARD);
|
|
|
6cc97b |
- if (fs) {
|
|
|
6cc97b |
- rc = 1;
|
|
|
6cc97b |
- goto out;
|
|
|
6cc97b |
- }
|
|
|
6cc97b |
- fs = mnt_table_find_source(swaps, _devname, MNT_ITER_FORWARD);
|
|
|
6cc97b |
- if (fs)
|
|
|
6cc97b |
- rc = 1;
|
|
|
6cc97b |
-out:
|
|
|
6cc97b |
- free(devname);
|
|
|
6cc97b |
- free(_devname);
|
|
|
6cc97b |
- return rc;
|
|
|
6cc97b |
-}
|
|
|
6cc97b |
-
|
|
|
6cc97b |
-static int count_device_users(char *syspath);
|
|
|
6cc97b |
-
|
|
|
6cc97b |
-static int blockdev_get_partitions(char *syspath)
|
|
|
6cc97b |
-{
|
|
|
6cc97b |
- struct dirent **parts = NULL;
|
|
|
6cc97b |
- int n, i;
|
|
|
6cc97b |
- int count = 0;
|
|
|
6cc97b |
-
|
|
|
6cc97b |
- n = scandir(syspath, &parts, subdir_filter, alphasort);
|
|
|
6cc97b |
- for (i = 0; i < n; i++) {
|
|
|
6cc97b |
- char *newpath;
|
|
|
6cc97b |
-
|
|
|
6cc97b |
- newpath = calloc(1, PATH_MAX);
|
|
|
6cc97b |
- if (!newpath)
|
|
|
6cc97b |
- continue;
|
|
|
6cc97b |
- snprintf(newpath, PATH_MAX, "%s/%s", syspath, parts[i]->d_name);
|
|
|
6cc97b |
- free(parts[i]);
|
|
|
6cc97b |
- if (is_partition(newpath)) {
|
|
|
6cc97b |
- count += count_device_users(newpath);
|
|
|
6cc97b |
- }
|
|
|
6cc97b |
- free(newpath);
|
|
|
6cc97b |
- }
|
|
|
6cc97b |
- free(parts);
|
|
|
6cc97b |
- return count;
|
|
|
6cc97b |
-}
|
|
|
6cc97b |
-
|
|
|
6cc97b |
-static int blockdev_get_holders(char *syspath)
|
|
|
6cc97b |
-{
|
|
|
6cc97b |
- char *path = NULL;
|
|
|
6cc97b |
- struct dirent **holds = NULL;
|
|
|
6cc97b |
- int n, i;
|
|
|
6cc97b |
- int count = 0;
|
|
|
6cc97b |
-
|
|
|
6cc97b |
- path = calloc(1, PATH_MAX);
|
|
|
6cc97b |
- if (!path)
|
|
|
6cc97b |
- return 0;
|
|
|
6cc97b |
- snprintf(path, PATH_MAX, "%s/holders", syspath);
|
|
|
6cc97b |
-
|
|
|
6cc97b |
- n = scandir(path, &holds, trans_filter, alphasort);
|
|
|
6cc97b |
- for (i = 0; i < n; i++) {
|
|
|
6cc97b |
- char *newpath;
|
|
|
6cc97b |
- char *rp;
|
|
|
6cc97b |
-
|
|
|
6cc97b |
- newpath = calloc(1, PATH_MAX);
|
|
|
6cc97b |
- if (!newpath)
|
|
|
6cc97b |
- continue;
|
|
|
6cc97b |
- snprintf(newpath, PATH_MAX, "%s/%s", path, holds[i]->d_name);
|
|
|
6cc97b |
-
|
|
|
6cc97b |
- free(holds[i]);
|
|
|
6cc97b |
- rp = realpath(newpath, NULL);
|
|
|
6cc97b |
- if (rp)
|
|
|
6cc97b |
- count += count_device_users(rp);
|
|
|
6cc97b |
- free(newpath);
|
|
|
6cc97b |
- free(rp);
|
|
|
6cc97b |
- }
|
|
|
6cc97b |
- free(path);
|
|
|
6cc97b |
- free(holds);
|
|
|
6cc97b |
- return count;
|
|
|
6cc97b |
-}
|
|
|
6cc97b |
-
|
|
|
6cc97b |
-static int count_device_users(char *syspath)
|
|
|
6cc97b |
-{
|
|
|
6cc97b |
- int count = 0;
|
|
|
6cc97b |
- count += blockdev_check_mnts(syspath);
|
|
|
6cc97b |
- count += blockdev_get_partitions(syspath);
|
|
|
6cc97b |
- count += blockdev_get_holders(syspath);
|
|
|
6cc97b |
- return count;
|
|
|
6cc97b |
-};
|
|
|
6cc97b |
-
|
|
|
6cc97b |
-static void device_in_use(void *data, int host_no, int target, int lun)
|
|
|
6cc97b |
-{
|
|
|
6cc97b |
- char *syspath = NULL;
|
|
|
6cc97b |
- char *devname = NULL;
|
|
|
6cc97b |
- int *count = data;
|
|
|
6cc97b |
-
|
|
|
6cc97b |
- devname = iscsi_sysfs_get_blockdev_from_lun(host_no, target, lun);
|
|
|
6cc97b |
- if (!devname)
|
|
|
6cc97b |
- goto out;
|
|
|
6cc97b |
- syspath = calloc(1, PATH_MAX);
|
|
|
6cc97b |
- if (!syspath)
|
|
|
6cc97b |
- goto out;
|
|
|
6cc97b |
- snprintf(syspath, PATH_MAX, "/sys/class/block/%s", devname);
|
|
|
6cc97b |
- *count += count_device_users(syspath);
|
|
|
6cc97b |
-out:
|
|
|
6cc97b |
- free(syspath);
|
|
|
6cc97b |
- free(devname);
|
|
|
6cc97b |
-}
|
|
|
6cc97b |
-
|
|
|
6cc97b |
-static int session_in_use(int sid)
|
|
|
6cc97b |
-{
|
|
|
6cc97b |
- int host_no = -1, err = 0;
|
|
|
6cc97b |
- int count = 0;
|
|
|
6cc97b |
-
|
|
|
6cc97b |
- if (libmount_init()) {
|
|
|
6cc97b |
- log_error("Failed to initialize libmount, "
|
|
|
d087b3 |
- "not checking for active mounts on session [%d].",
|
|
|
d087b3 |
- sid);
|
|
|
6cc97b |
- return 0;
|
|
|
6cc97b |
- }
|
|
|
6cc97b |
-
|
|
|
6cc97b |
- host_no = iscsi_sysfs_get_host_no_from_sid(sid, &err;;
|
|
|
6cc97b |
- if (!err)
|
|
|
6cc97b |
- iscsi_sysfs_for_each_device(&count, host_no, sid, device_in_use);
|
|
|
6cc97b |
-
|
|
|
6cc97b |
- libmount_cleanup();
|
|
|
6cc97b |
- return count;
|
|
|
6cc97b |
-}
|
|
|
6cc97b |
-
|
|
|
6cc97b |
int session_logout_task(int sid, queue_task_t *qtask)
|
|
|
6cc97b |
{
|
|
|
6cc97b |
iscsi_session_t *session;
|
|
|
6cc97b |
diff --git a/usr/initiator.h b/usr/initiator.h
|
|
|
d087b3 |
index c11d77f..4f96d6b 100644
|
|
|
6cc97b |
--- a/usr/initiator.h
|
|
|
6cc97b |
+++ b/usr/initiator.h
|
|
|
d087b3 |
@@ -359,4 +359,5 @@ extern int iscsi_set_net_config(struct iscsi_transport *t,
|
|
|
6cc97b |
struct iface_rec *iface);
|
|
|
6cc97b |
extern void iscsi_session_init_params(struct iscsi_session *session);
|
|
|
6cc97b |
|
|
|
6cc97b |
+extern int session_in_use(int sid);
|
|
|
6cc97b |
#endif /* INITIATOR_H */
|
|
|
6cc97b |
diff --git a/usr/initiator_common.c b/usr/initiator_common.c
|
|
|
d087b3 |
index c02643a..1d1d822 100644
|
|
|
6cc97b |
--- a/usr/initiator_common.c
|
|
|
6cc97b |
+++ b/usr/initiator_common.c
|
|
|
6cc97b |
@@ -23,6 +23,8 @@
|
|
|
6cc97b |
#include <stdio.h>
|
|
|
6cc97b |
#include <stdlib.h>
|
|
|
6cc97b |
#include <errno.h>
|
|
|
6cc97b |
+#include <dirent.h>
|
|
|
6cc97b |
+#include <libmount/libmount.h>
|
|
|
6cc97b |
|
|
|
6cc97b |
#include "initiator.h"
|
|
|
6cc97b |
#include "transport.h"
|
|
|
6cc97b |
diff --git a/usr/iscsiadm.c b/usr/iscsiadm.c
|
|
|
d087b3 |
index c6705bd..fc0c8bc 100644
|
|
|
6cc97b |
--- a/usr/iscsiadm.c
|
|
|
6cc97b |
+++ b/usr/iscsiadm.c
|
|
|
6cc97b |
@@ -1898,11 +1898,34 @@ exit_logout:
|
|
|
6cc97b |
return rc;
|
|
|
6cc97b |
}
|
|
|
6cc97b |
|
|
|
6cc97b |
+static int iscsi_check_session_use_count(uint32_t sid) {
|
|
|
6cc97b |
+ char *config_file;
|
|
|
6cc97b |
+ char *safe_logout;
|
|
|
6cc97b |
+
|
|
|
6cc97b |
+ config_file = get_config_file();
|
|
|
6cc97b |
+ if (!config_file) {
|
|
|
6cc97b |
+ log_error("Could not get config file from iscsid");
|
|
|
6cc97b |
+ return 0;
|
|
|
6cc97b |
+ }
|
|
|
6cc97b |
+
|
|
|
6cc97b |
+ safe_logout = cfg_get_string_param(config_file, "iscsid.safe_logout");
|
|
|
6cc97b |
+ if (!safe_logout || strcmp(safe_logout, "Yes"))
|
|
|
6cc97b |
+ return 0;
|
|
|
6cc97b |
+
|
|
|
6cc97b |
+ return session_in_use(sid);
|
|
|
6cc97b |
+}
|
|
|
6cc97b |
+
|
|
|
6cc97b |
int iscsi_logout_flashnode_sid(struct iscsi_transport *t, uint32_t host_no,
|
|
|
6cc97b |
uint32_t sid)
|
|
|
6cc97b |
{
|
|
|
6cc97b |
int fd, rc = 0;
|
|
|
6cc97b |
|
|
|
6cc97b |
+ if (iscsi_check_session_use_count(sid)) {
|
|
|
6cc97b |
+ log_error("Session is actively in use for mounted storage, "
|
|
|
6cc97b |
+ "and iscsid.safe_logout is configured.");
|
|
|
6cc97b |
+ return ISCSI_ERR_BUSY;
|
|
|
6cc97b |
+ }
|
|
|
6cc97b |
+
|
|
|
6cc97b |
fd = ipc->ctldev_open();
|
|
|
6cc97b |
if (fd < 0) {
|
|
|
6cc97b |
log_error("Netlink open failed.");
|
|
|
6cc97b |
diff --git a/usr/iscsistart.c b/usr/iscsistart.c
|
|
|
d087b3 |
index 7ff2236..79d6622 100644
|
|
|
6cc97b |
--- a/usr/iscsistart.c
|
|
|
6cc97b |
+++ b/usr/iscsistart.c
|
|
|
6cc97b |
@@ -279,6 +279,8 @@ static int setup_session(void)
|
|
|
6cc97b |
return rc;
|
|
|
6cc97b |
}
|
|
|
6cc97b |
|
|
|
6cc97b |
+int session_in_use(int sid) { return 0; }
|
|
|
6cc97b |
+
|
|
|
6cc97b |
static void catch_signal(int signo)
|
|
|
6cc97b |
{
|
|
|
6cc97b |
log_warning("pid %d caught signal -%d", getpid(), signo);
|
|
|
6cc97b |
diff --git a/usr/mntcheck.c b/usr/mntcheck.c
|
|
|
6cc97b |
new file mode 100644
|
|
|
d087b3 |
index 0000000..6ae03e0
|
|
|
6cc97b |
--- /dev/null
|
|
|
6cc97b |
+++ b/usr/mntcheck.c
|
|
|
d087b3 |
@@ -0,0 +1,233 @@
|
|
|
6cc97b |
+/*
|
|
|
6cc97b |
+ * Common code for checking sessions for mnt use
|
|
|
6cc97b |
+ *
|
|
|
6cc97b |
+ * Copyright (C) 2014 - 2015 Chris Leech
|
|
|
6cc97b |
+ * Copyright (C) 2014 - 2015 Red Hat, Inc. All rights reserved.
|
|
|
6cc97b |
+ *
|
|
|
6cc97b |
+ * This program is free software; you can redistribute it and/or modify
|
|
|
6cc97b |
+ * it under the terms of the GNU General Public License as published
|
|
|
6cc97b |
+ * by the Free Software Foundation; either version 2 of the License, or
|
|
|
6cc97b |
+ * (at your option) any later version.
|
|
|
6cc97b |
+ *
|
|
|
6cc97b |
+ * This program is distributed in the hope that it will be useful, but
|
|
|
6cc97b |
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
6cc97b |
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
6cc97b |
+ * General Public License for more details.
|
|
|
6cc97b |
+ *
|
|
|
6cc97b |
+ * See the file COPYING included with this distribution for more details.
|
|
|
6cc97b |
+ */
|
|
|
6cc97b |
+
|
|
|
6cc97b |
+#include <string.h>
|
|
|
6cc97b |
+#include <stdio.h>
|
|
|
6cc97b |
+#include <stdlib.h>
|
|
|
6cc97b |
+#include <errno.h>
|
|
|
6cc97b |
+#include <dirent.h>
|
|
|
6cc97b |
+#include <libmount/libmount.h>
|
|
|
6cc97b |
+
|
|
|
6cc97b |
+#include "initiator.h"
|
|
|
6cc97b |
+#include "transport.h"
|
|
|
6cc97b |
+#include "iscsid.h"
|
|
|
6cc97b |
+#include "iscsi_ipc.h"
|
|
|
6cc97b |
+#include "log.h"
|
|
|
6cc97b |
+#include "iscsi_sysfs.h"
|
|
|
6cc97b |
+#include "iscsi_settings.h"
|
|
|
6cc97b |
+#include "iface.h"
|
|
|
6cc97b |
+#include "host.h"
|
|
|
6cc97b |
+#include "sysdeps.h"
|
|
|
6cc97b |
+#include "iscsi_err.h"
|
|
|
6cc97b |
+#include "iscsi_net_util.h"
|
|
|
6cc97b |
+
|
|
|
6cc97b |
+static struct libmnt_table *mtab, *swaps;
|
|
|
6cc97b |
+static struct libmnt_cache *mntcache;
|
|
|
6cc97b |
+
|
|
|
6cc97b |
+static void libmount_cleanup(void)
|
|
|
6cc97b |
+{
|
|
|
6cc97b |
+ mnt_free_table(mtab);
|
|
|
6cc97b |
+ mnt_free_table(swaps);
|
|
|
6cc97b |
+ mnt_free_cache(mntcache);
|
|
|
6cc97b |
+ mtab = NULL;
|
|
|
6cc97b |
+ swaps = NULL;
|
|
|
6cc97b |
+ mntcache = NULL;
|
|
|
6cc97b |
+}
|
|
|
6cc97b |
+
|
|
|
6cc97b |
+static int libmount_init(void)
|
|
|
6cc97b |
+{
|
|
|
6cc97b |
+ mnt_init_debug(0);
|
|
|
6cc97b |
+ mtab = mnt_new_table();
|
|
|
6cc97b |
+ swaps = mnt_new_table();
|
|
|
6cc97b |
+ mntcache = mnt_new_cache();
|
|
|
6cc97b |
+ if (!mtab || !swaps || !mntcache) {
|
|
|
6cc97b |
+ libmount_cleanup();
|
|
|
6cc97b |
+ return -ENOMEM;
|
|
|
6cc97b |
+ }
|
|
|
6cc97b |
+ mnt_table_set_cache(mtab, mntcache);
|
|
|
6cc97b |
+ mnt_table_set_cache(swaps, mntcache);
|
|
|
6cc97b |
+ mnt_table_parse_mtab(mtab, NULL);
|
|
|
6cc97b |
+ mnt_table_parse_swaps(swaps, NULL);
|
|
|
6cc97b |
+ return 0;
|
|
|
6cc97b |
+}
|
|
|
6cc97b |
+
|
|
|
6cc97b |
+static int trans_filter(const struct dirent *d)
|
|
|
6cc97b |
+{
|
|
|
6cc97b |
+ if (!strcmp(".", d->d_name) || !strcmp("..", d->d_name))
|
|
|
6cc97b |
+ return 0;
|
|
|
6cc97b |
+ return 1;
|
|
|
6cc97b |
+}
|
|
|
6cc97b |
+
|
|
|
6cc97b |
+static int subdir_filter(const struct dirent *d)
|
|
|
6cc97b |
+{
|
|
|
6cc97b |
+ if (!(d->d_type & DT_DIR))
|
|
|
6cc97b |
+ return 0;
|
|
|
6cc97b |
+ return trans_filter(d);
|
|
|
6cc97b |
+}
|
|
|
6cc97b |
+
|
|
|
6cc97b |
+static int is_partition(const char *path)
|
|
|
6cc97b |
+{
|
|
|
6cc97b |
+ char *devtype;
|
|
|
6cc97b |
+ int rc = 0;
|
|
|
6cc97b |
+
|
|
|
6cc97b |
+ devtype = sysfs_get_uevent_devtype(path);
|
|
|
6cc97b |
+ if (!devtype)
|
|
|
6cc97b |
+ return 0;
|
|
|
6cc97b |
+ if (strcmp(devtype, "partition") == 0)
|
|
|
6cc97b |
+ rc = 1;
|
|
|
6cc97b |
+ free(devtype);
|
|
|
6cc97b |
+ return rc;
|
|
|
6cc97b |
+}
|
|
|
6cc97b |
+
|
|
|
6cc97b |
+static int blockdev_check_mnts(char *syspath)
|
|
|
6cc97b |
+{
|
|
|
6cc97b |
+ struct libmnt_fs *fs;
|
|
|
6cc97b |
+ char *devname = NULL;
|
|
|
6cc97b |
+ char *_devname = NULL;
|
|
|
6cc97b |
+ int rc = 0;
|
|
|
6cc97b |
+
|
|
|
6cc97b |
+ devname = sysfs_get_uevent_devname(syspath);
|
|
|
6cc97b |
+ if (!devname)
|
|
|
6cc97b |
+ goto out;
|
|
|
6cc97b |
+
|
|
|
6cc97b |
+ _devname = calloc(1, PATH_MAX);
|
|
|
6cc97b |
+ if (!_devname)
|
|
|
6cc97b |
+ goto out;
|
|
|
6cc97b |
+ snprintf(_devname, PATH_MAX, "/dev/%s", devname);
|
|
|
6cc97b |
+
|
|
|
6cc97b |
+ fs = mnt_table_find_source(mtab, _devname, MNT_ITER_FORWARD);
|
|
|
6cc97b |
+ if (fs) {
|
|
|
6cc97b |
+ rc = 1;
|
|
|
6cc97b |
+ goto out;
|
|
|
6cc97b |
+ }
|
|
|
6cc97b |
+ fs = mnt_table_find_source(swaps, _devname, MNT_ITER_FORWARD);
|
|
|
6cc97b |
+ if (fs)
|
|
|
6cc97b |
+ rc = 1;
|
|
|
6cc97b |
+out:
|
|
|
6cc97b |
+ free(devname);
|
|
|
6cc97b |
+ free(_devname);
|
|
|
6cc97b |
+ return rc;
|
|
|
6cc97b |
+}
|
|
|
6cc97b |
+
|
|
|
6cc97b |
+static int count_device_users(char *syspath);
|
|
|
6cc97b |
+
|
|
|
6cc97b |
+static int blockdev_get_partitions(char *syspath)
|
|
|
6cc97b |
+{
|
|
|
6cc97b |
+ struct dirent **parts = NULL;
|
|
|
6cc97b |
+ int n, i;
|
|
|
6cc97b |
+ int count = 0;
|
|
|
6cc97b |
+
|
|
|
6cc97b |
+ n = scandir(syspath, &parts, subdir_filter, alphasort);
|
|
|
6cc97b |
+ for (i = 0; i < n; i++) {
|
|
|
6cc97b |
+ char *newpath;
|
|
|
6cc97b |
+
|
|
|
6cc97b |
+ newpath = calloc(1, PATH_MAX);
|
|
|
6cc97b |
+ if (!newpath)
|
|
|
6cc97b |
+ continue;
|
|
|
6cc97b |
+ snprintf(newpath, PATH_MAX, "%s/%s", syspath, parts[i]->d_name);
|
|
|
6cc97b |
+ free(parts[i]);
|
|
|
6cc97b |
+ if (is_partition(newpath)) {
|
|
|
6cc97b |
+ count += count_device_users(newpath);
|
|
|
6cc97b |
+ }
|
|
|
6cc97b |
+ free(newpath);
|
|
|
6cc97b |
+ }
|
|
|
6cc97b |
+ free(parts);
|
|
|
6cc97b |
+ return count;
|
|
|
6cc97b |
+}
|
|
|
6cc97b |
+
|
|
|
6cc97b |
+static int blockdev_get_holders(char *syspath)
|
|
|
6cc97b |
+{
|
|
|
6cc97b |
+ char *path = NULL;
|
|
|
6cc97b |
+ struct dirent **holds = NULL;
|
|
|
6cc97b |
+ int n, i;
|
|
|
6cc97b |
+ int count = 0;
|
|
|
6cc97b |
+
|
|
|
6cc97b |
+ path = calloc(1, PATH_MAX);
|
|
|
6cc97b |
+ if (!path)
|
|
|
6cc97b |
+ return 0;
|
|
|
6cc97b |
+ snprintf(path, PATH_MAX, "%s/holders", syspath);
|
|
|
6cc97b |
+
|
|
|
6cc97b |
+ n = scandir(path, &holds, trans_filter, alphasort);
|
|
|
6cc97b |
+ for (i = 0; i < n; i++) {
|
|
|
6cc97b |
+ char *newpath;
|
|
|
6cc97b |
+ char *rp;
|
|
|
6cc97b |
+
|
|
|
6cc97b |
+ newpath = calloc(1, PATH_MAX);
|
|
|
6cc97b |
+ if (!newpath)
|
|
|
6cc97b |
+ continue;
|
|
|
6cc97b |
+ snprintf(newpath, PATH_MAX, "%s/%s", path, holds[i]->d_name);
|
|
|
6cc97b |
+
|
|
|
6cc97b |
+ free(holds[i]);
|
|
|
6cc97b |
+ rp = realpath(newpath, NULL);
|
|
|
6cc97b |
+ if (rp)
|
|
|
6cc97b |
+ count += count_device_users(rp);
|
|
|
6cc97b |
+ free(newpath);
|
|
|
6cc97b |
+ free(rp);
|
|
|
6cc97b |
+ }
|
|
|
6cc97b |
+ free(path);
|
|
|
6cc97b |
+ free(holds);
|
|
|
6cc97b |
+ return count;
|
|
|
6cc97b |
+}
|
|
|
6cc97b |
+
|
|
|
6cc97b |
+static int count_device_users(char *syspath)
|
|
|
6cc97b |
+{
|
|
|
6cc97b |
+ int count = 0;
|
|
|
6cc97b |
+ count += blockdev_check_mnts(syspath);
|
|
|
6cc97b |
+ count += blockdev_get_partitions(syspath);
|
|
|
6cc97b |
+ count += blockdev_get_holders(syspath);
|
|
|
6cc97b |
+ return count;
|
|
|
6cc97b |
+};
|
|
|
6cc97b |
+
|
|
|
6cc97b |
+static void device_in_use(void *data, int host_no, int target, int lun)
|
|
|
6cc97b |
+{
|
|
|
6cc97b |
+ char *syspath = NULL;
|
|
|
6cc97b |
+ char *devname = NULL;
|
|
|
6cc97b |
+ int *count = data;
|
|
|
6cc97b |
+
|
|
|
6cc97b |
+ devname = iscsi_sysfs_get_blockdev_from_lun(host_no, target, lun);
|
|
|
6cc97b |
+ if (!devname)
|
|
|
6cc97b |
+ goto out;
|
|
|
6cc97b |
+ syspath = calloc(1, PATH_MAX);
|
|
|
6cc97b |
+ if (!syspath)
|
|
|
6cc97b |
+ goto out;
|
|
|
6cc97b |
+ snprintf(syspath, PATH_MAX, "/sys/class/block/%s", devname);
|
|
|
6cc97b |
+ *count += count_device_users(syspath);
|
|
|
6cc97b |
+out:
|
|
|
6cc97b |
+ free(syspath);
|
|
|
6cc97b |
+ free(devname);
|
|
|
6cc97b |
+}
|
|
|
6cc97b |
+
|
|
|
6cc97b |
+int session_in_use(int sid)
|
|
|
6cc97b |
+{
|
|
|
6cc97b |
+ int host_no = -1, err = 0;
|
|
|
6cc97b |
+ int count = 0;
|
|
|
6cc97b |
+
|
|
|
6cc97b |
+ if (libmount_init()) {
|
|
|
6cc97b |
+ log_error("Failed to initialize libmount, "
|
|
|
d087b3 |
+ "not checking for active mounts on session [%d].", sid);
|
|
|
6cc97b |
+ return 0;
|
|
|
6cc97b |
+ }
|
|
|
6cc97b |
+
|
|
|
6cc97b |
+ host_no = iscsi_sysfs_get_host_no_from_sid(sid, &err;;
|
|
|
6cc97b |
+ if (!err)
|
|
|
6cc97b |
+ iscsi_sysfs_for_each_device(&count, host_no, sid, device_in_use);
|
|
|
6cc97b |
+
|
|
|
6cc97b |
+ libmount_cleanup();
|
|
|
6cc97b |
+ return count;
|
|
|
6cc97b |
+}
|
|
|
6cc97b |
--
|
|
|
d087b3 |
2.5.5
|
|
|
6cc97b |
|