diff --git a/SOURCES/0151-update-initscripts-and-docs.patch b/SOURCES/0151-update-initscripts-and-docs.patch index e2d4cdc..74c33e8 100644 --- a/SOURCES/0151-update-initscripts-and-docs.patch +++ b/SOURCES/0151-update-initscripts-and-docs.patch @@ -1,7 +1,7 @@ -From c255c2cd43afeaefa428237a3200f02fb238d89e Mon Sep 17 00:00:00 2001 +From da244b1fbbbe9c0ebc6e3f6083e1aa72c09f7fce Mon Sep 17 00:00:00 2001 From: Chris Leech Date: Mon, 19 Nov 2012 16:37:13 -0800 -Subject: update initscripts and docs +Subject: [PATCH] update initscripts and docs --- README | 9 +++------ @@ -10,7 +10,7 @@ Subject: update initscripts and docs 3 files changed, 18 insertions(+), 18 deletions(-) diff --git a/README b/README -index ec22098..2a8319a 100644 +index 06d1b6f..0ac4529 100644 --- a/README +++ b/README @@ -74,11 +74,6 @@ the cache sync command will fail. @@ -25,7 +25,7 @@ index ec22098..2a8319a 100644 By default the kernel's iSCSI modules will be used. Running: make -@@ -997,7 +992,7 @@ Red Hat or Fedora: +@@ -1118,7 +1113,7 @@ Red Hat or Fedora: ----------------- To start open-iscsi in Red Hat/Fedora you can do: @@ -34,7 +34,7 @@ index ec22098..2a8319a 100644 To get open-iscsi to automatically start at run time you may have to run: -@@ -1205,6 +1200,8 @@ iscsid will only perform rediscovery when it gets a SCN from the server. +@@ -1326,6 +1321,8 @@ iscsid will only perform rediscovery when it gets a SCN from the server. # linux-isns (SLES's iSNS server) where it sometimes does not send SCN # events in the proper format, so they may not get handled. @@ -44,7 +44,7 @@ index ec22098..2a8319a 100644 Example: -------- diff --git a/etc/iscsid.conf b/etc/iscsid.conf -index ef76dc0..ac1d231 100644 +index 6d9a5c0..7a2e3ca 100644 --- a/etc/iscsid.conf +++ b/etc/iscsid.conf @@ -17,10 +17,10 @@ @@ -58,9 +58,9 @@ index ef76dc0..ac1d231 100644 -iscsid.startup = /sbin/iscsid +# iscsid.startup = /sbin/iscsid - - ############################# -@@ -36,8 +36,8 @@ iscsid.startup = /sbin/iscsid + # Check for active mounts on devices reachable through a session + # and refuse to logout if there are any. Defaults to "No". +@@ -39,8 +39,8 @@ iscsid.startup = /sbin/iscsid # To request that the iscsi initd scripts startup a session set to "automatic". # node.startup = automatic # @@ -71,7 +71,7 @@ index ef76dc0..ac1d231 100644 # For "automatic" startup nodes, setting this to "Yes" will try logins on each # available iface until one succeeds, and then stop. The default "No" will try -@@ -259,28 +259,27 @@ node.conn[0].iscsi.MaxXmitDataSegmentLength = 0 +@@ -262,28 +262,27 @@ node.conn[0].iscsi.MaxXmitDataSegmentLength = 0 discovery.sendtargets.iscsi.MaxRecvDataSegmentLength = 32768 # To allow the targets to control the setting of the digest checking, @@ -108,10 +108,10 @@ index ef76dc0..ac1d231 100644 # For multipath configurations, you may want more than one session to be # created on each iface record. If node.session.nr_sessions is greater diff --git a/usr/idbm.c b/usr/idbm.c -index 4d30aa9..a1d7d37 100644 +index 5731e60..ce9fb6a 100644 --- a/usr/idbm.c +++ b/usr/idbm.c -@@ -399,9 +399,13 @@ idbm_recinfo_node(node_rec_t *r, recinfo_t *ri) +@@ -514,9 +514,13 @@ idbm_recinfo_node(node_rec_t *r, recinfo_t *ri) IDBM_SHOW, "None", "CRC32C", "CRC32C,None", "None,CRC32C", num, 1); sprintf(key, CONN_DATA_DIGEST, i); @@ -126,5 +126,5 @@ index 4d30aa9..a1d7d37 100644 __recinfo_int_o2(key, ri, r, conn[i].iscsi.IFMarker, IDBM_SHOW, "No", "Yes", num, 1); -- -1.7.11.7 +2.1.0 diff --git a/SOURCES/0155-dont-use-static.patch b/SOURCES/0155-dont-use-static.patch index 9e43b7b..6d0d3b0 100644 --- a/SOURCES/0155-dont-use-static.patch +++ b/SOURCES/0155-dont-use-static.patch @@ -1,17 +1,17 @@ -From ff224a16d409c4b479b3ac1ff662093cb067e281 Mon Sep 17 00:00:00 2001 +From 0daa5488cfad023c2a333f35ba12e3d8797ba6e9 Mon Sep 17 00:00:00 2001 From: Chris Leech Date: Mon, 19 Nov 2012 17:04:29 -0800 -Subject: dont use static +Subject: [PATCH] dont use static --- usr/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/usr/Makefile b/usr/Makefile -index 015f1b9..1669890 100644 +index 5f4fb2f..bbf8568 100644 --- a/usr/Makefile +++ b/usr/Makefile -@@ -61,7 +61,7 @@ iscsiadm: $(ISCSI_LIB_SRCS) $(DISCOVERY_SRCS) iscsiadm.o session_mgmt.o +@@ -62,7 +62,7 @@ iscsiadm: $(ISCSI_LIB_SRCS) $(DISCOVERY_SRCS) iscsiadm.o session_mgmt.o mntcheck iscsistart: $(ISCSI_LIB_SRCS) $(INITIATOR_SRCS) $(FW_BOOT_SRCS) \ iscsistart.o statics.o @@ -21,5 +21,5 @@ index 015f1b9..1669890 100644 rm -f *.o $(PROGRAMS) .depend $(LIBSYS) -- -1.7.11.7 +2.1.0 diff --git a/SOURCES/0199-use-Red-Hat-version-string-to-match-RPM-package-vers.patch b/SOURCES/0199-use-Red-Hat-version-string-to-match-RPM-package-vers.patch index c222d9d..e9b626e 100644 --- a/SOURCES/0199-use-Red-Hat-version-string-to-match-RPM-package-vers.patch +++ b/SOURCES/0199-use-Red-Hat-version-string-to-match-RPM-package-vers.patch @@ -16,7 +16,7 @@ index a090522..aef0c3d 100644 * some other maintainer could merge a patch without going through us */ -#define ISCSI_VERSION_STR "2.0-873" -+#define ISCSI_VERSION_STR "6.2.0.873-28" ++#define ISCSI_VERSION_STR "6.2.0.873-30" #define ISCSI_VERSION_FILE "/sys/module/scsi_transport_iscsi/version" #endif diff --git a/SOURCES/open-iscsi-2.0-873-safe-logout-flashnode.patch b/SOURCES/open-iscsi-2.0-873-safe-logout-flashnode.patch new file mode 100644 index 0000000..346a905 --- /dev/null +++ b/SOURCES/open-iscsi-2.0-873-safe-logout-flashnode.patch @@ -0,0 +1,585 @@ +From 4d3d30ea5bcb917fed58f1cb57154de5e6ce2349 Mon Sep 17 00:00:00 2001 +From: Chris Leech +Date: Fri, 24 Jul 2015 14:18:30 -0700 +Subject: [PATCH] share session use checks with iscsiadm, apply for flashnode + session + +--- + usr/Makefile | 8 +- + usr/initiator.c | 196 +---------------------------------------- + usr/initiator.h | 1 + + usr/initiator_common.c | 3 + + usr/iscsiadm.c | 23 +++++ + usr/iscsistart.c | 2 + + usr/mntcheck.c | 234 +++++++++++++++++++++++++++++++++++++++++++++++++ + 7 files changed, 268 insertions(+), 199 deletions(-) + create mode 100644 usr/mntcheck.c + +diff --git a/usr/Makefile b/usr/Makefile +index b2c1504..93b03d5 100644 +--- a/usr/Makefile ++++ b/usr/Makefile +@@ -54,15 +54,15 @@ DISCOVERY_SRCS = $(FW_BOOT_SRCS) strings.o discovery.o + all: $(PROGRAMS) + + iscsid: $(ISCSI_LIB_SRCS) $(INITIATOR_SRCS) $(DISCOVERY_SRCS) \ +- iscsid.o session_mgmt.o discoveryd.o ++ iscsid.o session_mgmt.o discoveryd.o mntcheck.o + $(CC) $(CFLAGS) $^ -o $@ -L../utils/open-isns -lisns -lmount + +-iscsiadm: $(ISCSI_LIB_SRCS) $(DISCOVERY_SRCS) iscsiadm.o session_mgmt.o +- $(CC) $(CFLAGS) $^ -o $@ -L../utils/open-isns -lisns ++iscsiadm: $(ISCSI_LIB_SRCS) $(DISCOVERY_SRCS) iscsiadm.o session_mgmt.o mntcheck.o ++ $(CC) $(CFLAGS) $^ -o $@ -L../utils/open-isns -lisns -lmount + + iscsistart: $(ISCSI_LIB_SRCS) $(INITIATOR_SRCS) $(FW_BOOT_SRCS) \ + iscsistart.o statics.o +- $(CC) $(CFLAGS) -static $^ -o $@ -lmount ++ $(CC) $(CFLAGS) -static $^ -o $@ + clean: + rm -f *.o $(PROGRAMS) .depend $(LIBSYS) + +diff --git a/usr/initiator.c b/usr/initiator.c +index 1b4c90a..701b9a5 100644 +--- a/usr/initiator.c ++++ b/usr/initiator.c +@@ -30,7 +30,6 @@ + #include + #include + #include +-#include + + #include "initiator.h" + #include "transport.h" +@@ -2141,199 +2140,6 @@ static int session_unbind(struct iscsi_session *session) + return err; + } + +-static struct libmnt_table *mtab, *swaps; +-static struct libmnt_cache *mntcache; +- +-static void libmount_cleanup(void) +-{ +- mnt_free_table(mtab); +- mnt_free_table(swaps); +- mnt_free_cache(mntcache); +- mtab = swaps = mntcache = NULL; +-} +- +-static int libmount_init(void) +-{ +- mnt_init_debug(0); +- mtab = mnt_new_table(); +- swaps = mnt_new_table(); +- mntcache = mnt_new_cache(); +- if (!mtab || !swaps || !mntcache) { +- libmount_cleanup(); +- return -ENOMEM; +- } +- mnt_table_set_cache(mtab, mntcache); +- mnt_table_set_cache(swaps, mntcache); +- mnt_table_parse_mtab(mtab, NULL); +- mnt_table_parse_swaps(swaps, NULL); +- return 0; +-} +- +-static int trans_filter(const struct dirent *d) +-{ +- if (!strcmp(".", d->d_name) || !strcmp("..", d->d_name)) +- return 0; +- return 1; +-} +- +-static int subdir_filter(const struct dirent *d) +-{ +- if (!(d->d_type & DT_DIR)) +- return 0; +- return trans_filter(d); +-} +- +-static int is_partition(const char *path) +-{ +- char *devtype; +- int rc = 0; +- +- devtype = sysfs_get_uevent_devtype(path); +- if (!devtype) +- return 0; +- if (strcmp(devtype, "partition") == 0) +- rc = 1; +- free(devtype); +- return rc; +-} +- +-static int blockdev_check_mnts(char *syspath) +-{ +- struct libmnt_fs *fs; +- char *devname = NULL; +- char *_devname = NULL; +- int rc = 0; +- +- devname = sysfs_get_uevent_devname(syspath); +- if (!devname) +- goto out; +- +- _devname = calloc(1, PATH_MAX); +- if (!_devname) +- goto out; +- snprintf(_devname, PATH_MAX, "/dev/%s", devname); +- +- fs = mnt_table_find_source(mtab, _devname, MNT_ITER_FORWARD); +- if (fs) { +- rc = 1; +- goto out; +- } +- fs = mnt_table_find_source(swaps, _devname, MNT_ITER_FORWARD); +- if (fs) +- rc = 1; +-out: +- free(devname); +- free(_devname); +- return rc; +-} +- +-static int count_device_users(char *syspath); +- +-static int blockdev_get_partitions(char *syspath) +-{ +- struct dirent **parts = NULL; +- int n, i; +- int count = 0; +- +- n = scandir(syspath, &parts, subdir_filter, alphasort); +- for (i = 0; i < n; i++) { +- char *newpath; +- +- newpath = calloc(1, PATH_MAX); +- if (!newpath) +- continue; +- snprintf(newpath, PATH_MAX, "%s/%s", syspath, parts[i]->d_name); +- free(parts[i]); +- if (is_partition(newpath)) { +- count += count_device_users(newpath); +- } +- free(newpath); +- } +- free(parts); +- return count; +-} +- +-static int blockdev_get_holders(char *syspath) +-{ +- char *path = NULL; +- struct dirent **holds = NULL; +- int n, i; +- int count = 0; +- +- path = calloc(1, PATH_MAX); +- if (!path) +- return 0; +- snprintf(path, PATH_MAX, "%s/holders", syspath); +- +- n = scandir(path, &holds, trans_filter, alphasort); +- for (i = 0; i < n; i++) { +- char *newpath; +- char *rp; +- +- newpath = calloc(1, PATH_MAX); +- if (!newpath) +- continue; +- snprintf(newpath, PATH_MAX, "%s/%s", path, holds[i]->d_name); +- +- free(holds[i]); +- rp = realpath(newpath, NULL); +- if (rp) +- count += count_device_users(rp); +- free(newpath); +- free(rp); +- } +- free(path); +- free(holds); +- return count; +-} +- +-static int count_device_users(char *syspath) +-{ +- int count = 0; +- count += blockdev_check_mnts(syspath); +- count += blockdev_get_partitions(syspath); +- count += blockdev_get_holders(syspath); +- return count; +-}; +- +-static void device_in_use(void *data, int host_no, int target, int lun) +-{ +- char *syspath = NULL; +- char *devname = NULL; +- int *count = data; +- +- devname = iscsi_sysfs_get_blockdev_from_lun(host_no, target, lun); +- if (!devname) +- goto out; +- syspath = calloc(1, PATH_MAX); +- if (!syspath) +- goto out; +- snprintf(syspath, PATH_MAX, "/sys/class/block/%s", devname); +- *count += count_device_users(syspath); +-out: +- free(syspath); +- free(devname); +-} +- +-static int session_in_use(int sid) +-{ +- int host_no = -1, err = 0; +- int count = 0; +- +- if (libmount_init()) { +- log_error("Failed to initialize libmount, " +- "not checking for active mounts on session [%d].\n", sid); +- return 0; +- } +- +- host_no = iscsi_sysfs_get_host_no_from_sid(sid, &err); +- if (!err) +- iscsi_sysfs_for_each_device(&count, host_no, sid, device_in_use); +- +- libmount_cleanup(); +- return count; +-} +- + int session_logout_task(int sid, queue_task_t *qtask) + { + iscsi_session_t *session; +@@ -2363,7 +2169,7 @@ invalid_state: + + if (dconfig->safe_logout && session_in_use(sid)) { + log_error("Session is actively in use for mounted storage, " +- "and iscsid.safe_logout is configured.\n"); ++ "and iscsid.safe_logout is configured."); + return ISCSI_ERR_BUSY; + } + +diff --git a/usr/initiator.h b/usr/initiator.h +index c34625b..e8bce45 100644 +--- a/usr/initiator.h ++++ b/usr/initiator.h +@@ -360,4 +360,5 @@ extern int iscsi_set_net_config(struct iscsi_transport *t, + struct iface_rec *iface); + extern void iscsi_session_init_params(struct iscsi_session *session); + ++extern int session_in_use(int sid); + #endif /* INITIATOR_H */ +diff --git a/usr/initiator_common.c b/usr/initiator_common.c +index 8ff993d..4e574b4 100644 +--- a/usr/initiator_common.c ++++ b/usr/initiator_common.c +@@ -23,6 +23,8 @@ + #include + #include + #include ++#include ++#include + + #include "initiator.h" + #include "transport.h" +@@ -741,3 +743,4 @@ int iscsi_host_set_net_params(struct iface_rec *iface, + } + return 0; + } ++ +diff --git a/usr/iscsiadm.c b/usr/iscsiadm.c +index f886d39..d5d38b1 100644 +--- a/usr/iscsiadm.c ++++ b/usr/iscsiadm.c +@@ -1898,11 +1898,34 @@ exit_logout: + return rc; + } + ++static int iscsi_check_session_use_count(uint32_t sid) { ++ char *config_file; ++ char *safe_logout; ++ ++ config_file = get_config_file(); ++ if (!config_file) { ++ log_error("Could not get config file from iscsid"); ++ return 0; ++ } ++ ++ safe_logout = cfg_get_string_param(config_file, "iscsid.safe_logout"); ++ if (!safe_logout || strcmp(safe_logout, "Yes")) ++ return 0; ++ ++ return session_in_use(sid); ++} ++ + int iscsi_logout_flashnode_sid(struct iscsi_transport *t, uint32_t host_no, + uint32_t sid) + { + int fd, rc = 0; + ++ if (iscsi_check_session_use_count(sid)) { ++ log_error("Session is actively in use for mounted storage, " ++ "and iscsid.safe_logout is configured."); ++ return ISCSI_ERR_BUSY; ++ } ++ + fd = ipc->ctldev_open(); + if (fd < 0) { + log_error("Netlink open failed."); +diff --git a/usr/iscsistart.c b/usr/iscsistart.c +index 6924d49..26ba014 100644 +--- a/usr/iscsistart.c ++++ b/usr/iscsistart.c +@@ -279,6 +279,8 @@ static int setup_session(void) + return rc; + } + ++int session_in_use(int sid) { return 0; } ++ + static void catch_signal(int signo) + { + log_warning("pid %d caught signal -%d", getpid(), signo); +diff --git a/usr/mntcheck.c b/usr/mntcheck.c +new file mode 100644 +index 0000000..57bf007 +--- /dev/null ++++ b/usr/mntcheck.c +@@ -0,0 +1,234 @@ ++/* ++ * Common code for checking sessions for mnt use ++ * ++ * Copyright (C) 2014 - 2015 Chris Leech ++ * Copyright (C) 2014 - 2015 Red Hat, Inc. All rights reserved. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published ++ * by the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ * ++ * See the file COPYING included with this distribution for more details. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "initiator.h" ++#include "transport.h" ++#include "iscsid.h" ++#include "iscsi_ipc.h" ++#include "log.h" ++#include "iscsi_sysfs.h" ++#include "iscsi_settings.h" ++#include "iface.h" ++#include "host.h" ++#include "sysdeps.h" ++#include "iscsi_err.h" ++#include "iscsi_net_util.h" ++ ++static struct libmnt_table *mtab, *swaps; ++static struct libmnt_cache *mntcache; ++ ++static void libmount_cleanup(void) ++{ ++ mnt_free_table(mtab); ++ mnt_free_table(swaps); ++ mnt_free_cache(mntcache); ++ mtab = NULL; ++ swaps = NULL; ++ mntcache = NULL; ++} ++ ++static int libmount_init(void) ++{ ++ mnt_init_debug(0); ++ mtab = mnt_new_table(); ++ swaps = mnt_new_table(); ++ mntcache = mnt_new_cache(); ++ if (!mtab || !swaps || !mntcache) { ++ libmount_cleanup(); ++ return -ENOMEM; ++ } ++ mnt_table_set_cache(mtab, mntcache); ++ mnt_table_set_cache(swaps, mntcache); ++ mnt_table_parse_mtab(mtab, NULL); ++ mnt_table_parse_swaps(swaps, NULL); ++ return 0; ++} ++ ++static int trans_filter(const struct dirent *d) ++{ ++ if (!strcmp(".", d->d_name) || !strcmp("..", d->d_name)) ++ return 0; ++ return 1; ++} ++ ++static int subdir_filter(const struct dirent *d) ++{ ++ if (!(d->d_type & DT_DIR)) ++ return 0; ++ return trans_filter(d); ++} ++ ++static int is_partition(const char *path) ++{ ++ char *devtype; ++ int rc = 0; ++ ++ devtype = sysfs_get_uevent_devtype(path); ++ if (!devtype) ++ return 0; ++ if (strcmp(devtype, "partition") == 0) ++ rc = 1; ++ free(devtype); ++ return rc; ++} ++ ++static int blockdev_check_mnts(char *syspath) ++{ ++ struct libmnt_fs *fs; ++ char *devname = NULL; ++ char *_devname = NULL; ++ int rc = 0; ++ ++ devname = sysfs_get_uevent_devname(syspath); ++ if (!devname) ++ goto out; ++ ++ _devname = calloc(1, PATH_MAX); ++ if (!_devname) ++ goto out; ++ snprintf(_devname, PATH_MAX, "/dev/%s", devname); ++ ++ fs = mnt_table_find_source(mtab, _devname, MNT_ITER_FORWARD); ++ if (fs) { ++ rc = 1; ++ goto out; ++ } ++ fs = mnt_table_find_source(swaps, _devname, MNT_ITER_FORWARD); ++ if (fs) ++ rc = 1; ++out: ++ free(devname); ++ free(_devname); ++ return rc; ++} ++ ++static int count_device_users(char *syspath); ++ ++static int blockdev_get_partitions(char *syspath) ++{ ++ struct dirent **parts = NULL; ++ int n, i; ++ int count = 0; ++ ++ n = scandir(syspath, &parts, subdir_filter, alphasort); ++ for (i = 0; i < n; i++) { ++ char *newpath; ++ ++ newpath = calloc(1, PATH_MAX); ++ if (!newpath) ++ continue; ++ snprintf(newpath, PATH_MAX, "%s/%s", syspath, parts[i]->d_name); ++ free(parts[i]); ++ if (is_partition(newpath)) { ++ count += count_device_users(newpath); ++ } ++ free(newpath); ++ } ++ free(parts); ++ return count; ++} ++ ++static int blockdev_get_holders(char *syspath) ++{ ++ char *path = NULL; ++ struct dirent **holds = NULL; ++ int n, i; ++ int count = 0; ++ ++ path = calloc(1, PATH_MAX); ++ if (!path) ++ return 0; ++ snprintf(path, PATH_MAX, "%s/holders", syspath); ++ ++ n = scandir(path, &holds, trans_filter, alphasort); ++ for (i = 0; i < n; i++) { ++ char *newpath; ++ char *rp; ++ ++ newpath = calloc(1, PATH_MAX); ++ if (!newpath) ++ continue; ++ snprintf(newpath, PATH_MAX, "%s/%s", path, holds[i]->d_name); ++ ++ free(holds[i]); ++ rp = realpath(newpath, NULL); ++ if (rp) ++ count += count_device_users(rp); ++ free(newpath); ++ free(rp); ++ } ++ free(path); ++ free(holds); ++ return count; ++} ++ ++static int count_device_users(char *syspath) ++{ ++ int count = 0; ++ count += blockdev_check_mnts(syspath); ++ count += blockdev_get_partitions(syspath); ++ count += blockdev_get_holders(syspath); ++ return count; ++}; ++ ++static void device_in_use(void *data, int host_no, int target, int lun) ++{ ++ char *syspath = NULL; ++ char *devname = NULL; ++ int *count = data; ++ ++ devname = iscsi_sysfs_get_blockdev_from_lun(host_no, target, lun); ++ if (!devname) ++ goto out; ++ syspath = calloc(1, PATH_MAX); ++ if (!syspath) ++ goto out; ++ snprintf(syspath, PATH_MAX, "/sys/class/block/%s", devname); ++ *count += count_device_users(syspath); ++out: ++ free(syspath); ++ free(devname); ++} ++ ++int session_in_use(int sid) ++{ ++ int host_no = -1, err = 0; ++ int count = 0; ++ ++ if (libmount_init()) { ++ log_error("Failed to initialize libmount, " ++ "not checking for active mounts on session [%d].\n", sid); ++ return 0; ++ } ++ ++ host_no = iscsi_sysfs_get_host_no_from_sid(sid, &err); ++ if (!err) ++ iscsi_sysfs_for_each_device(&count, host_no, sid, device_in_use); ++ ++ libmount_cleanup(); ++ return count; ++} ++ +-- +2.1.0 + diff --git a/SOURCES/open-iscsi-2.0.873-125-iscsid-safe-session-logout.patch b/SOURCES/open-iscsi-2.0.873-125-iscsid-safe-session-logout.patch new file mode 100644 index 0000000..47c4904 --- /dev/null +++ b/SOURCES/open-iscsi-2.0.873-125-iscsid-safe-session-logout.patch @@ -0,0 +1,354 @@ +From 46ba8eed79fa13b32947b5c5b1bf0bc133b14c41 Mon Sep 17 00:00:00 2001 +From: Chris Leech +Date: Tue, 3 Feb 2015 16:28:15 -0800 +Subject: [PATCH] iscsid safe session logout + +Implement a safe logout option, which uses libmount from util-linux to +check for active mounts (and swaps) over devices, their partitions, and +any holders (like LVM and multipath device maps). When enabled iscsid +will refuse to logout of sessions actively being used for mounts, +returning a status of EBUSY to the ipc request. + +I've made it a configuration option (iscsid.safe_logout) that defaults +to "No" to preserve the existing behavior as the default, while making +it available for users that prefer a safety check. + +This does add a new dependency on libmount. + +Signed-off-by: Chris Leech +--- + etc/iscsid.conf | 3 + + usr/Makefile | 4 +- + usr/initiator.c | 199 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + usr/sysfs.c | 40 ++++++++++++ + usr/sysfs.h | 4 ++ + 5 files changed, 248 insertions(+), 2 deletions(-) + +diff --git a/etc/iscsid.conf b/etc/iscsid.conf +index ef76dc0..6d9a5c0 100644 +--- a/etc/iscsid.conf ++++ b/etc/iscsid.conf +@@ -22,6 +22,9 @@ + # Default for upstream open-iscsi scripts (uncomment to activate). + iscsid.startup = /sbin/iscsid + ++# Check for active mounts on devices reachable through a session ++# and refuse to logout if there are any. Defaults to "No". ++# iscsid.safe_logout = Yes + + ############################# + # NIC/HBA and driver settings +diff --git a/usr/Makefile b/usr/Makefile +index 3d8ee22..b2c1504 100644 +--- a/usr/Makefile ++++ b/usr/Makefile +@@ -55,14 +55,14 @@ all: $(PROGRAMS) + + iscsid: $(ISCSI_LIB_SRCS) $(INITIATOR_SRCS) $(DISCOVERY_SRCS) \ + iscsid.o session_mgmt.o discoveryd.o +- $(CC) $(CFLAGS) $^ -o $@ -L../utils/open-isns -lisns ++ $(CC) $(CFLAGS) $^ -o $@ -L../utils/open-isns -lisns -lmount + + iscsiadm: $(ISCSI_LIB_SRCS) $(DISCOVERY_SRCS) iscsiadm.o session_mgmt.o + $(CC) $(CFLAGS) $^ -o $@ -L../utils/open-isns -lisns + + iscsistart: $(ISCSI_LIB_SRCS) $(INITIATOR_SRCS) $(FW_BOOT_SRCS) \ + iscsistart.o statics.o +- $(CC) $(CFLAGS) -static $^ -o $@ ++ $(CC) $(CFLAGS) -static $^ -o $@ -lmount + clean: + rm -f *.o $(PROGRAMS) .depend $(LIBSYS) + +diff --git a/usr/initiator.c b/usr/initiator.c +index 9d02f47..ac1a3ac 100644 +--- a/usr/initiator.c ++++ b/usr/initiator.c +@@ -30,6 +30,7 @@ + #include + #include + #include ++#include + + #include "initiator.h" + #include "transport.h" +@@ -2140,11 +2141,200 @@ static int session_unbind(struct iscsi_session *session) + return err; + } + ++static struct libmnt_table *mtab, *swaps; ++ ++static void libmount_cleanup(void) ++{ ++ mnt_free_table(mtab); ++ mnt_free_table(swaps); ++ mtab = swaps = NULL; ++} ++ ++static int libmount_init(void) ++{ ++ mnt_init_debug(0); ++ mtab = mnt_new_table(); ++ swaps = mnt_new_table(); ++ if (!mtab || !swaps) { ++ libmount_cleanup(); ++ return -ENOMEM; ++ } ++ mnt_table_parse_mtab(mtab, NULL); ++ mnt_table_parse_swaps(swaps, NULL); ++ return 0; ++} ++ ++static int trans_filter(const struct dirent *d) ++{ ++ if (!strcmp(".", d->d_name) || !strcmp("..", d->d_name)) ++ return 0; ++ return 1; ++} ++ ++static int subdir_filter(const struct dirent *d) ++{ ++ if (!(d->d_type & DT_DIR)) ++ return 0; ++ return trans_filter(d); ++} ++ ++static int is_partition(const char *path) ++{ ++ char *devtype; ++ int rc = 0; ++ ++ devtype = sysfs_get_uevent_devtype(path); ++ if (!devtype) ++ return 0; ++ if (strcmp(devtype, "partition") == 0) ++ rc = 1; ++ free(devtype); ++ return rc; ++} ++ ++static int blockdev_check_mnts(char *syspath) ++{ ++ struct libmnt_fs *fs; ++ char *devname = NULL; ++ char *_devname = NULL; ++ int rc = 0; ++ ++ devname = sysfs_get_uevent_devname(syspath); ++ if (!devname) ++ goto out; ++ ++ _devname = calloc(1, PATH_MAX); ++ if (!_devname) ++ goto out; ++ snprintf(_devname, PATH_MAX, "/dev/%s", devname); ++ ++ fs = mnt_table_find_source(mtab, _devname, MNT_ITER_FORWARD); ++ if (fs) { ++ rc = 1; ++ goto out; ++ } ++ fs = mnt_table_find_source(swaps, _devname, MNT_ITER_FORWARD); ++ if (fs) ++ rc = 1; ++out: ++ free(devname); ++ free(_devname); ++ return rc; ++} ++ ++static int count_device_users(char *syspath); ++ ++static int blockdev_get_partitions(char *syspath) ++{ ++ struct dirent **parts = NULL; ++ int n, i; ++ int count = 0; ++ ++ n = scandir(syspath, &parts, subdir_filter, alphasort); ++ for (i = 0; i < n; i++) { ++ char *newpath; ++ ++ newpath = calloc(1, PATH_MAX); ++ if (!newpath) ++ continue; ++ snprintf(newpath, PATH_MAX, "%s/%s", syspath, parts[i]->d_name); ++ free(parts[i]); ++ if (is_partition(newpath)) { ++ count += count_device_users(newpath); ++ } ++ free(newpath); ++ } ++ free(parts); ++ return count; ++} ++ ++static int blockdev_get_holders(char *syspath) ++{ ++ char *path = NULL; ++ struct dirent **holds = NULL; ++ int n, i; ++ int count = 0; ++ ++ path = calloc(1, PATH_MAX); ++ if (!path) ++ return 0; ++ snprintf(path, PATH_MAX, "%s/holders", syspath); ++ ++ n = scandir(path, &holds, trans_filter, alphasort); ++ for (i = 0; i < n; i++) { ++ char *newpath; ++ char *rp; ++ ++ newpath = calloc(1, PATH_MAX); ++ if (!newpath) ++ continue; ++ snprintf(newpath, PATH_MAX, "%s/%s", path, holds[i]->d_name); ++ ++ free(holds[i]); ++ rp = realpath(newpath, NULL); ++ if (rp) ++ count += count_device_users(rp); ++ free(newpath); ++ free(rp); ++ } ++ free(path); ++ free(holds); ++ return count; ++} ++ ++static int count_device_users(char *syspath) ++{ ++ int count = 0; ++ count += blockdev_check_mnts(syspath); ++ count += blockdev_get_partitions(syspath); ++ count += blockdev_get_holders(syspath); ++ return count; ++}; ++ ++static void device_in_use(void *data, int host_no, int target, int lun) ++{ ++ char *syspath = NULL; ++ char *devname = NULL; ++ int *count = data; ++ ++ devname = iscsi_sysfs_get_blockdev_from_lun(host_no, target, lun); ++ if (!devname) ++ goto out; ++ syspath = calloc(1, PATH_MAX); ++ if (!syspath) ++ goto out; ++ snprintf(syspath, PATH_MAX, "/sys/class/block/%s", devname); ++ *count += count_device_users(syspath); ++out: ++ free(syspath); ++ free(devname); ++} ++ ++static int session_in_use(int sid) ++{ ++ int host_no = -1, err = 0; ++ int count = 0; ++ ++ if (libmount_init()) { ++ log_error("Failed to initialize libmount, " ++ "not checking for active mounts on session [%d].\n", sid); ++ return 0; ++ } ++ ++ host_no = iscsi_sysfs_get_host_no_from_sid(sid, &err); ++ if (!err) ++ iscsi_sysfs_for_each_device(&count, host_no, sid, device_in_use); ++ ++ libmount_cleanup(); ++ return count; ++} ++ + int session_logout_task(int sid, queue_task_t *qtask) + { + iscsi_session_t *session; + iscsi_conn_t *conn; + int rc = ISCSI_SUCCESS; ++ char *safe; + + session = session_find_by_sid(sid); + if (!session) { +@@ -2167,6 +2357,15 @@ invalid_state: + return ISCSI_ERR_INTERNAL; + } + ++ safe = cfg_get_string_param(dconfig->config_file, "iscsid.safe_logout"); ++ if (safe && !strcmp(safe, "Yes") && session_in_use(sid)) { ++ log_error("Session is actively in use for mounted storage, " ++ "and iscsid.safe_logout is configured.\n"); ++ free(safe); ++ return ISCSI_ERR_BUSY; ++ } ++ free(safe); ++ + /* FIXME: logout all active connections */ + conn = &session->conn[0]; + if (conn->logout_qtask) +diff --git a/usr/sysfs.c b/usr/sysfs.c +index d00c925..bbb00c0 100644 +--- a/usr/sysfs.c ++++ b/usr/sysfs.c +@@ -709,3 +709,43 @@ int sysfs_set_param(char *id, char *subsys, char *attr_name, + close(fd); + return rc; + } ++ ++char *sysfs_get_uevent_field(const char *path, const char *field) ++{ ++ char *uevent_path = NULL; ++ FILE *f = NULL; ++ char *line, buffer[1024]; ++ char *ff, *d; ++ char *out = NULL; ++ ++ uevent_path = calloc(1, PATH_MAX); ++ if (!uevent_path) ++ return NULL; ++ snprintf(uevent_path, PATH_MAX, "%s/uevent", path); ++ ++ f = fopen(uevent_path, "r"); ++ if (!f) ++ goto out; ++ while ((line = fgets(buffer, sizeof (buffer), f))) { ++ ff = strtok(line, "="); ++ d = strtok(NULL, "\n"); ++ if (strcmp(ff, field)) ++ continue; ++ out = strdup(d); ++ break; ++ } ++ fclose(f); ++out: ++ free(uevent_path); ++ return out; ++} ++ ++char *sysfs_get_uevent_devtype(const char *path) ++{ ++ return sysfs_get_uevent_field(path, "DEVTYPE"); ++} ++ ++char *sysfs_get_uevent_devname(const char *path) ++{ ++ return sysfs_get_uevent_field(path, "DEVNAME"); ++} +diff --git a/usr/sysfs.h b/usr/sysfs.h +index 304dbbf..462060e 100644 +--- a/usr/sysfs.h ++++ b/usr/sysfs.h +@@ -66,4 +66,8 @@ extern int sysfs_get_uint16(char *id, char *subsys, char *param, + extern int sysfs_set_param(char *id, char *subsys, char *attr_name, + char *write_buf, ssize_t buf_size); + ++extern char *sysfs_get_uevent_field(const char *path, const char *field); ++extern char *sysfs_get_uevent_devtype(const char *path); ++extern char *sysfs_get_uevent_devname(const char *path); ++ + #endif +-- +2.1.0 + diff --git a/SOURCES/open-iscsi-2.0.873-126-iscsid-don-t-re-read-config-file-for-every-session-l.patch b/SOURCES/open-iscsi-2.0.873-126-iscsid-don-t-re-read-config-file-for-every-session-l.patch new file mode 100644 index 0000000..51163da --- /dev/null +++ b/SOURCES/open-iscsi-2.0.873-126-iscsid-don-t-re-read-config-file-for-every-session-l.patch @@ -0,0 +1,82 @@ +From 006270c0f9a1fa1e78574a7eaa04bb9ae1ef62b6 Mon Sep 17 00:00:00 2001 +From: Chris Leech +Date: Thu, 12 Feb 2015 16:38:00 -0800 +Subject: [PATCH] iscsid: don't re-read config file for every session logout + +Follow up to the safe_logout feature patch. +Cache the safe_logout setting when iscsid is started. + +Signed-off-by: Chris Leech +--- + usr/initiator.c | 6 +----- + usr/iscsid.c | 6 ++++++ + usr/iscsid.h | 1 + + 3 files changed, 8 insertions(+), 5 deletions(-) + +diff --git a/usr/initiator.c b/usr/initiator.c +index 2f17882..b25ded8 100644 +--- a/usr/initiator.c ++++ b/usr/initiator.c +@@ -2333,7 +2333,6 @@ int session_logout_task(int sid, queue_task_t *qtask) + iscsi_session_t *session; + iscsi_conn_t *conn; + int rc = ISCSI_SUCCESS; +- char *safe; + + session = session_find_by_sid(sid); + if (!session) { +@@ -2356,14 +2355,11 @@ invalid_state: + return ISCSI_ERR_INTERNAL; + } + +- safe = cfg_get_string_param(dconfig->config_file, "iscsid.safe_logout"); +- if (safe && !strcmp(safe, "Yes") && session_in_use(sid)) { ++ if (dconfig->safe_logout && session_in_use(sid)) { + log_error("Session is actively in use for mounted storage, " + "and iscsid.safe_logout is configured.\n"); +- free(safe); + return ISCSI_ERR_BUSY; + } +- free(safe); + + /* FIXME: logout all active connections */ + conn = &session->conn[0]; +diff --git a/usr/iscsid.c b/usr/iscsid.c +index f4f4f38..033a71f 100644 +--- a/usr/iscsid.c ++++ b/usr/iscsid.c +@@ -341,6 +341,7 @@ int main(int argc, char *argv[]) + char *config_file = CONFIG_FILE; + char *initiatorname_file = INITIATOR_NAME_FILE; + char *pid_file = PID_FILE; ++ char *safe_logout; + int ch, longindex; + uid_t uid = 0; + struct sigaction sa_old; +@@ -520,6 +521,11 @@ int main(int argc, char *argv[]) + daemon_config.initiator_name : "NOT SET"); + log_debug(1, "InitiatorAlias=%s", daemon_config.initiator_alias); + ++ safe_logout = cfg_get_string_param(config_file, "iscsid.safe_logout"); ++ if (safe_logout && !strcmp(safe_logout, "Yes")) ++ daemon_config.safe_logout = 1; ++ free(safe_logout); ++ + pid = fork(); + if (pid == 0) { + int nr_found = 0; +diff --git a/usr/iscsid.h b/usr/iscsid.h +index 15f264f..b9f3d54 100644 +--- a/usr/iscsid.h ++++ b/usr/iscsid.h +@@ -29,6 +29,7 @@ struct iscsi_daemon_config { + char *pid_file; + char *initiator_name; + char *initiator_alias; ++ int safe_logout; + }; + extern struct iscsi_daemon_config *dconfig; + +-- +2.1.0 + diff --git a/SOURCES/open-iscsi-2.0.873-fix-device-path-canonicalization-by-using-libmount-c.patch b/SOURCES/open-iscsi-2.0.873-fix-device-path-canonicalization-by-using-libmount-c.patch new file mode 100644 index 0000000..f00ded3 --- /dev/null +++ b/SOURCES/open-iscsi-2.0.873-fix-device-path-canonicalization-by-using-libmount-c.patch @@ -0,0 +1,47 @@ +From b6c9ebe86c45d0a318ec9bb42a6373b4f77a1ba7 Mon Sep 17 00:00:00 2001 +From: Chris Leech +Date: Tue, 21 Jul 2015 16:15:30 -0700 +Subject: [PATCH 1/1] fix device path canonicalization by using libmount cache + +--- + usr/initiator.c | 9 +++++++-- + 1 file changed, 7 insertions(+), 2 deletions(-) + +diff --git a/usr/initiator.c b/usr/initiator.c +index 3b39c5d..0519d46 100644 +--- a/usr/initiator.c ++++ b/usr/initiator.c +@@ -2141,12 +2141,14 @@ static int session_unbind(struct iscsi_session *session) + } + + static struct libmnt_table *mtab, *swaps; ++static struct libmnt_cache *mntcache; + + static void libmount_cleanup(void) + { + mnt_free_table(mtab); + mnt_free_table(swaps); +- mtab = swaps = NULL; ++ mnt_free_cache(mntcache); ++ mtab = swaps = mntcache = NULL; + } + + static int libmount_init(void) +@@ -2154,10 +2156,13 @@ static int libmount_init(void) + mnt_init_debug(0); + mtab = mnt_new_table(); + swaps = mnt_new_table(); +- if (!mtab || !swaps) { ++ mntcache = mnt_new_cache(); ++ if (!mtab || !swaps || !mntcache) { + libmount_cleanup(); + return -ENOMEM; + } ++ mnt_table_set_cache(mtab, mntcache); ++ mnt_table_set_cache(swaps, mntcache); + mnt_table_parse_mtab(mtab, NULL); + mnt_table_parse_swaps(swaps, NULL); + return 0; +-- +2.1.0 + diff --git a/SPECS/iscsi-initiator-utils.spec b/SPECS/iscsi-initiator-utils.spec index 05e382f..d692b6c 100644 --- a/SPECS/iscsi-initiator-utils.spec +++ b/SPECS/iscsi-initiator-utils.spec @@ -4,7 +4,7 @@ Summary: iSCSI daemon and utility programs Name: iscsi-initiator-utils Version: 6.%{open_iscsi_version}.%{open_iscsi_build} -Release: 29%{?dist} +Release: 32%{?dist} Group: System Environment/Daemons License: GPLv2+ URL: http://www.open-iscsi.org @@ -94,6 +94,10 @@ Patch82: 0082-Remove-unused-variable-path.patch Patch83: 0083-Parse-origin-value-from-iBFT.patch Patch84: 0084-isns-Add-docs-for-deregistering-discovery-domains.patch Patch114: 0114-fix-regression-in-iscsi_tcp-iface-binding.patch +Patch125: open-iscsi-2.0.873-125-iscsid-safe-session-logout.patch +Patch126: open-iscsi-2.0.873-126-iscsid-don-t-re-read-config-file-for-every-session-l.patch +Patch127: open-iscsi-2.0.873-fix-device-path-canonicalization-by-using-libmount-c.patch +Patch128: open-iscsi-2.0-873-safe-logout-flashnode.patch # not (yet) upstream merged Patch130: 0130-guard-against-NULL-ptr-during-discovery-from-unexpec.patch @@ -128,7 +132,7 @@ Patch172: 0172-move-cleanup-to-seperate-service.patch # version string, needs to be updated with each build Patch199: 0199-use-Red-Hat-version-string-to-match-RPM-package-vers.patch -BuildRequires: flex bison python-devel doxygen kmod-devel systemd-devel +BuildRequires: flex bison python-devel doxygen kmod-devel systemd-devel libmount-devel # For dir ownership Requires: %{name}-iscsiuio >= %{version}-%{release} Requires(post): systemd @@ -164,120 +168,7 @@ The %{name}-devel package contains libraries and header files for developing applications that use %{name}. %prep -%setup -q -n open-iscsi-%{open_iscsi_version}-%{open_iscsi_build} -# upstream patches -%patch1 -p1 -%patch2 -p1 -%patch3 -p1 -%patch4 -p1 -%patch5 -p1 -%patch6 -p1 -%patch7 -p1 -%patch8 -p1 -%patch9 -p1 -%patch10 -p1 -%patch11 -p1 -%patch12 -p1 -%patch13 -p1 -%patch14 -p1 -%patch15 -p1 -%patch16 -p1 -%patch17 -p1 -%patch18 -p1 -%patch19 -p1 -%patch20 -p1 -%patch21 -p1 -%patch22 -p1 -%patch23 -p1 -%patch24 -p1 -%patch25 -p1 -%patch26 -p1 -%patch27 -p1 -%patch28 -p1 -%patch29 -p1 -%patch30 -p1 -%patch31 -p1 -%patch32 -p1 -%patch33 -p1 -%patch34 -p1 -%patch35 -p1 -%patch36 -p1 -%patch37 -p1 -%patch38 -p1 -%patch39 -p1 -%patch40 -p1 -%patch41 -p1 -%patch42 -p1 -%patch43 -p1 -%patch44 -p1 -%patch45 -p1 -%patch46 -p1 -%patch47 -p1 -%patch48 -p1 -%patch49 -p1 -%patch50 -p1 -%patch51 -p1 -%patch52 -p1 -%patch53 -p1 -%patch54 -p1 -%patch55 -p1 -%patch56 -p1 -%patch57 -p1 -%patch58 -p1 -%patch59 -p1 -%patch60 -p1 -%patch61 -p1 -%patch62 -p1 -%patch63 -p1 -%patch64 -p1 -%patch68 -p1 -%patch69 -p1 -%patch70 -p1 -%patch71 -p1 -%patch72 -p1 -%patch74 -p1 -%patch75 -p1 -%patch76 -p1 -%patch77 -p1 -%patch78 -p1 -%patch79 -p1 -%patch81 -p1 -%patch82 -p1 -%patch83 -p1 -%patch84 -p1 -%patch114 -p1 -# pending upstream merge -%patch130 -p1 -%patch140 -p1 -%patch143 -p1 -%patch145 -p1 -%patch146 -p1 -%patch147 -p1 -%patch149 -p1 -%patch150 -p1 -# distro specific modifications -%patch151 -p1 -%patch152 -p1 -%patch153 -p1 -%patch154 -p1 -%patch155 -p1 -%patch156 -p1 -%patch159 -p1 -%patch160 -p1 -%patch161 -p1 -%patch162 -p1 -%patch163 -p1 -%patch164 -p1 -%patch165 -p1 -%patch166 -p1 -%patch167 -p1 -%patch168 -p1 -%patch169 -p1 -%patch170 -p1 -%patch171 -p1 -%patch172 -p1 -# version string -%patch199 -p1 +%autosetup -p1 -n open-iscsi-%{open_iscsi_version}-%{open_iscsi_build} # change exec_prefix, there's no easy way to override %{__sed} -i -e 's|^exec_prefix = /$|exec_prefix = %{_exec_prefix}|' Makefile @@ -479,6 +370,16 @@ fi %{_includedir}/libiscsi.h %changelog +* Fri Jul 24 2015 Chris Leech - 6.2.0.873-32 +- 1235684 apply safe_logout setting to flashnode sessions as well + but only when logging out by session id, not by flashnode index + +* Tue Jul 21 2015 Chris Leech - 6.2.0.873-31 +- 1235684 fix safe logout DM name canonicalization, use libmount cache + +* Mon Jul 06 2015 Chris Leech - 6.2.0.873-30 +- 1235684 add iscsid safe logout option + * Fri Jan 30 2015 Chris Leech - 6.2.0.873-29 - 1166713 1187792 add missing ExecStart, only newer systemd lets that be optional for oneshot services