From 15876381341fc49a53f44266195d6ba55d553eb2 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 22 Nov 2018 22:13:40 +0000 Subject: [PATCH] Remove support for "make enable_proc" and "make disable_proc" Since RHEL 5 and kernel versions before 2.6.26 rely on procfs support, this patch removes support for RHEL 5.x and also for kernel versions before 2.6.26. git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@7829 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- Makefile | 25 +- ibmvstgt/README.procfs | 121 - iscsi-scst/Makefile | 12 +- iscsi-scst/doc/iscsi-scst-howto.txt | 6 - qla2x00t/qla2x00-target/Makefile | 12 +- scripts/run-regression-tests | 1 - scst/Makefile | 8 +- scst/README | 287 --- scst/src/Makefile | 22 +- scstadmin/Makefile | 10 +- scstadmin/README.procfs | 64 - scstadmin/examples/scst.conf.procfs | 120 - scstadmin/scstadmin.procfs/Makefile | 38 - .../scstadmin.procfs/scst-0.8.22/MANIFEST | 4 - .../scstadmin.procfs/scst-0.8.22/Makefile.PL | 13 - scstadmin/scstadmin.procfs/scst-0.8.22/README | 16 - .../scst-0.8.22/lib/SCST/SCST.pm | 1587 ------------- scstadmin/scstadmin.procfs/scstadmin | 2058 ----------------- usr/Makefile | 12 +- 19 files changed, 7 insertions(+), 4409 deletions(-) delete mode 100644 ibmvstgt/README.procfs delete mode 100644 scstadmin/README.procfs delete mode 100644 scstadmin/examples/scst.conf.procfs delete mode 100644 scstadmin/scstadmin.procfs/Makefile delete mode 100644 scstadmin/scstadmin.procfs/scst-0.8.22/MANIFEST delete mode 100644 scstadmin/scstadmin.procfs/scst-0.8.22/Makefile.PL delete mode 100644 scstadmin/scstadmin.procfs/scst-0.8.22/README delete mode 100644 scstadmin/scstadmin.procfs/scst-0.8.22/lib/SCST/SCST.pm delete mode 100755 scstadmin/scstadmin.procfs/scstadmin diff --git a/Makefile b/Makefile index be84bef4b..2b6d54e53 100644 --- a/Makefile +++ b/Makefile @@ -138,9 +138,6 @@ help: @echo " usr_install : usr target: install" @echo " usr_uninstall : usr target: uninstall" @echo "" - @echo " enable_proc : switch to procfs interface" - @echo " disable_proc : switch to sysfs interface (default)" - @echo "" @echo " 2perf : changes debug state to full performance" @echo " 2release : changes debug state to release" @echo " 2debug : changes debug state to full debug" @@ -579,26 +576,6 @@ release-archive: @if [ -d $(SCST_LOCAL_DIR) ]; then cd $(SCST_LOCAL_DIR) && $(MAKE) $@; fi @if [ -d $(FCST_DIR) ]; then cd $(FCST_DIR) && $(MAKE) $@; fi -enable_proc: extraclean - cd $(SCST_DIR) && $(MAKE) $@ - @if [ -d $(QLA_DIR) ]; then cd $(QLA_DIR) && $(MAKE) $@; fi - @if [ -d $(QLA_OLD_DIR) ]; then cd $(QLA_OLD_DIR) && $(MAKE) $@; fi -# @if [ -d $(LSI_DIR) ]; then cd $(LSI_DIR) && $(MAKE) $@; fi -# @if [ -d $(SRP_DIR) ]; then cd $(SRP_DIR) && $(MAKE) $@; fi - @if [ -d $(ISCSI_DIR) ]; then cd $(ISCSI_DIR) && $(MAKE) $@; fi -# @if [ -d $(SCST_LOCAL_DIR) ]; then cd $(SCST_LOCAL_DIR) && $(MAKE) $@; fi - @if [ -d $(SCSTADM_DIR) ]; then cd $(SCSTADM_DIR) && $(MAKE) $@; fi - -disable_proc: extraclean - cd $(SCST_DIR) && $(MAKE) $@ - @if [ -d $(QLA_DIR) ]; then cd $(QLA_DIR) && $(MAKE) $@; fi - @if [ -d $(QLA_OLD_DIR) ]; then cd $(QLA_OLD_DIR) && $(MAKE) $@; fi -# @if [ -d $(LSI_DIR) ]; then cd $(LSI_DIR) && $(MAKE) $@; fi -# @if [ -d $(SRP_DIR) ]; then cd $(SRP_DIR) && $(MAKE) $@; fi - @if [ -d $(ISCSI_DIR) ]; then cd $(ISCSI_DIR) && $(MAKE) $@; fi -# @if [ -d $(SCST_LOCAL_DIR) ]; then cd $(SCST_LOCAL_DIR) && $(MAKE) $@; fi - @if [ -d $(SCSTADM_DIR) ]; then cd $(SCSTADM_DIR) && $(MAKE) $@; fi - .PHONY: all install uninstall clean extraclean tags help \ qla qla_install qla_uninstall qla_clean qla_extraclean \ qla_old qla_old_install qla_old_uninstall qla_old_clean qla_old_extraclean \ @@ -614,4 +591,4 @@ disable_proc: extraclean mvsas mvsas_install mvsas_uninstall mvsas_clean mvsas_extraclean \ fcst fcst_install fcst_uninstall fcst_clean fcst_extraclean \ scst-rpm scst-dkms-rpm dpkg \ - 2perf 2release 2debug enable_proc disable_proc + 2perf 2release 2debug diff --git a/ibmvstgt/README.procfs b/ibmvstgt/README.procfs deleted file mode 100644 index 5316df8d4..000000000 --- a/ibmvstgt/README.procfs +++ /dev/null @@ -1,121 +0,0 @@ -IBM Virtual SCSI Target (ibmvstgt) -================================== - - -Introduction ------------- -The virtual SCSI (VSCSI) protocol as defined in [2] is a protocol that allows -one logical partition (LPAR) to access SCSI targets provided by another LPAR. -The LPAR that provides one or more SCSI targets is called the VIO server or -VIOS. The ibmvstgt driver is a VIOS driver that makes it possible to access -exported target devices via the VSCSI protocol. - -Setup ------ -After having configured the LPARs, boot the LPARs and load the ibmvstgt kernel -module in the VIOS. After the target driver has been loaded, verify that a -message similar to the following appears in the initiator kernel log: - -ibmvscsi 30000028: partner initialized -ibmvscsi 30000028: host srp version: 16.a, host partition VIOS3-P6 (40), OS 2, max io 67108864 -ibmvscsi 30000028: sent SRP login -ibmvscsi 30000028: SRP_LOGIN succeeded - -In the above log messages, the number 30000028 refers to the VIOS. The last -two digits, 0x28, refer to the VIOS partition number (0x28 = 40). - -The next step is to decide which SCSI devices to export. Here is an example of -a configuration in which 16 RAM disks have been exported (see also [1] for -more information): - -$ cat /proc/scsi_tgt/vdisk/vdisk -Name Size(MB) Block size Options File name T10 device id -ram000 16 512 NV /dev/ram0 c726a6ab -ram001 16 512 NV /dev/ram1 eca3eb12 -ram002 16 512 NV /dev/ram2 8e9fb87 -ram003 16 512 NV /dev/ram3 912b0e46 -ram004 16 512 NV /dev/ram4 c52a6cdf -ram005 16 512 NV /dev/ram5 b3f98ada -ram006 16 512 NV /dev/ram6 fb5fd9ce -ram007 16 512 NV /dev/ram7 3285b724 -ram008 16 512 NV /dev/ram8 6a93ad6d -ram009 16 512 NV /dev/ram9 f0c60f83 -ram010 16 512 NV /dev/ram10 f0c60f84 -ram011 16 512 NV /dev/ram11 f0c60f85 -ram012 16 512 NV /dev/ram12 f0c60f86 -ram013 16 512 NV /dev/ram13 f0c60f87 -ram014 16 512 NV /dev/ram14 f0c60f88 -ram015 16 512 NV /dev/ram15 f0c60f89 - -After this step a LUN has to be assigned to each exported SCSI device. Some -non-Linux initiator operating systems only accept LUN numbes that are -multiples of 256 and require that the LUN addressing method is used. The LUN -addressing method is only available for other groups than the Default group. -Configuring such a group can be done e.g. as follows: - - vios_id="30000028" - echo "add_group ${vios_id} LUN" >/proc/scsi_tgt/scsi_tgt - echo "add ${vios_id}" >/proc/scsi_tgt/groups/${vios_id}/names - lun=0 - for name in ram000 ram001 ram002 ram003 ram004 ram005 ram006 ram007 \ - ram008 ram009 ram010 ram011 ram012 ram013 ram014 ram015 - do - lun=$((lun+256)) - echo "add $name $lun" >/proc/scsi_tgt/groups/${vios_id}/devices - done - -In the above, the first echo command will create a group and will enable LUN -addressing for that group. The second echo command tells SCST to use this -group instead of the Default group for VSCSI. And the subsequent commands -assign LUNs to the exported vdisks. The result of the above commands will -be as follows: - -# cat /proc/scsi_tgt/groups/30000028/devices -Device (host:ch:id:lun or name) LUN Options -ram000 256 -ram001 512 -ram002 768 -ram003 1024 -ram004 1280 -ram005 1536 -ram006 1792 -ram007 2048 -ram008 2304 -ram009 2560 -ram010 2816 -ram011 3072 -ram012 3328 -ram013 3584 -ram014 3840 -ram015 4096 - -After SCST has been configured, make the new configuration available to the -initiator by rescanning the SCSI bus, e.g. as follows: - -# rescan-scsi-bus --hosts=2 --ids=0-31 -# lsscsi 2: -[2:0:1:0] disk IBM VDASD blkdev 0001 /dev/sdb -[2:0:2:0] disk IBM VDASD blkdev 0001 /dev/sdc -[2:0:3:0] disk IBM VDASD blkdev 0001 /dev/sdd -[2:0:4:0] disk IBM VDASD blkdev 0001 /dev/sde -[2:0:5:0] disk IBM VDASD blkdev 0001 /dev/sdf -[2:0:6:0] disk IBM VDASD blkdev 0001 /dev/sdg -[2:0:7:0] disk IBM VDASD blkdev 0001 /dev/sdh -[2:0:8:0] disk IBM VDASD blkdev 0001 /dev/sdi -[2:0:9:0] disk IBM VDASD blkdev 0001 /dev/sdj -[2:0:10:0] disk IBM VDASD blkdev 0001 /dev/sdk -[2:0:11:0] disk IBM VDASD blkdev 0001 /dev/sdl -[2:0:12:0] disk IBM VDASD blkdev 0001 /dev/sdm -[2:0:13:0] disk IBM VDASD blkdev 0001 /dev/sdn -[2:0:14:0] disk IBM VDASD blkdev 0001 /dev/sdo -[2:0:15:0] disk IBM VDASD blkdev 0001 /dev/sdp -[2:0:16:0] disk IBM VDASD blkdev 0001 /dev/sdq - - -References ----------- -[1] SCST Configuration Interface, Documentation/scst/README.scst. -[2] Power.org Standard for Power Architecture Platform Requirements (PAPR) -(Workstation, Server), Version 2.4, December 7, 2009, http://www.power.org. -[3] Virtual I/O (VIO) and Virtualization, IBM Developerworks, 2010, -http://www.ibm.com/developerworks/wikis/display/virtualization/VIO. diff --git a/iscsi-scst/Makefile b/iscsi-scst/Makefile index ec37c8578..056ce6ec0 100644 --- a/iscsi-scst/Makefile +++ b/iscsi-scst/Makefile @@ -379,17 +379,7 @@ conftest/use_pre_440_wr_structure/result-$(KVER).txt: \ grep "^#EXTRA_CFLAGS += \-DCONFIG_SCST_DEBUG -g -fno-inline -fno-inline-functions" $(ISERTMOD)/Makefile >/dev/null rm $(ISERTMOD)/Makefile.aa -disable_proc: - sed -i.aa s/"^#\?define CONFIG_SCST_PROC"/"\/* #define CONFIG_SCST_PROC *\/"/ $(INCDIR)/iscsi_scst_ver.h - grep "^\/\* #define CONFIG_SCST_PROC \*\/" $(INCDIR)/iscsi_scst_ver.h >/dev/null - rm $(INCDIR)/iscsi_scst_ver.h.aa - -enable_proc: - sed -i.aa s/"^\/\?\* #define CONFIG_SCST_PROC \*\/"/"#define CONFIG_SCST_PROC"/ $(INCDIR)/iscsi_scst_ver.h - grep "^#define CONFIG_SCST_PROC" $(INCDIR)/iscsi_scst_ver.h >/dev/null - rm $(INCDIR)/iscsi_scst_ver.h.aa - release-archive: ../scripts/generate-release-archive iscsi-scst "$$(sed -n 's/^#define[[:blank:]]ISCSI_VERSION_STRING[[:blank:]]*\"\([^\"]*\)\".*/\1/p' include/iscsi_scst_ver.h)" -.PHONY: all mods progs install clean extraclean 2release 2debug 2perf disable_proc enable_proc +.PHONY: all mods progs install clean extraclean 2release 2debug 2perf diff --git a/iscsi-scst/doc/iscsi-scst-howto.txt b/iscsi-scst/doc/iscsi-scst-howto.txt index 2cc640b5b..392ad25de 100644 --- a/iscsi-scst/doc/iscsi-scst-howto.txt +++ b/iscsi-scst/doc/iscsi-scst-howto.txt @@ -25,12 +25,6 @@ do that by running the following command from the SCST directory: make 2release make scst scst_install iscsi iscsi_install scstadm scstadm_install -When using RHEL 5 or CentOS 5, use these commands instead: - - make 2release - make enable_proc - make scst scst_install iscsi iscsi_install scstadm scstadm_install - iSCSI-SCST includes the following components: * kernel modules: iscsi-scst.ko scst.ko scst_vdisk.ko * iscsi-scstd - daemon diff --git a/qla2x00t/qla2x00-target/Makefile b/qla2x00t/qla2x00-target/Makefile index b1704b902..1c466011f 100644 --- a/qla2x00t/qla2x00-target/Makefile +++ b/qla2x00t/qla2x00-target/Makefile @@ -182,14 +182,4 @@ extraclean: clean grep "^#EXTRA_CFLAGS += \-DCONFIG_SCST_DEBUG -g -fno-inline -fno-inline-functions" Makefile >/dev/null rm Makefile.aa -disable_proc: - sed -i.aa s/"^#\?define CONFIG_SCST_PROC"/"\/* #define CONFIG_SCST_PROC *\/"/ ../qla_attr.c - grep "^\/\* #define CONFIG_SCST_PROC \*\/" ../qla_attr.c >/dev/null - rm ../qla_attr.c.aa - -enable_proc: - sed -i.aa s/"^\/\?\* #define CONFIG_SCST_PROC \*\/"/"#define CONFIG_SCST_PROC"/ ../qla_attr.c - grep "^#define CONFIG_SCST_PROC" ../qla_attr.c >/dev/null - rm ../qla_attr.c.aa - -.PHONY: all tgt install uninstall clean extraclean 2perf 2release 2debug disable_proc enable_proc qla2xxx_scst +.PHONY: all tgt install uninstall clean extraclean 2perf 2release 2debug qla2xxx_scst diff --git a/scripts/run-regression-tests b/scripts/run-regression-tests index ecfc5c6ae..fa37fdc0a 100755 --- a/scripts/run-regression-tests +++ b/scripts/run-regression-tests @@ -603,7 +603,6 @@ if [ "${run_local_compilation}" = "true" ]; then compile_scst_no_dlm || exit $? compile_scst_patched 2release || exit $? compile_scst_patched 2perf || exit $? - # compile_scst_patched enable_proc || exit $? if type rpmbuild >/dev/null 2>&1; then make_rpm || exit $? fi diff --git a/scst/Makefile b/scst/Makefile index 9282ea3de..8551c656b 100644 --- a/scst/Makefile +++ b/scst/Makefile @@ -47,12 +47,6 @@ extraclean: 2perf: cd $(SCST_DIR) && $(MAKE) $@ -disable_proc: - cd $(SCST_DIR) && $(MAKE) $@ - -enable_proc: - cd $(SCST_DIR) && $(MAKE) $@ - release-archive: ../scripts/generate-release-archive scst \ "$$(sed -n 's/^#define[[:blank:]]SCST_VERSION_NAME[[:blank:]]*\"\([^\"]*\)\".*/\1/p' include/scst_const.h)" \ @@ -68,4 +62,4 @@ help: @echo " - be sure to compile qla against the correct initiator" @echo " driver. Read its README for details." -.PHONY: all install uninstall clean extraclean help 2release 2debug 2perf disable_proc enable_proc +.PHONY: all install uninstall clean extraclean help 2release 2debug 2perf diff --git a/scst/README b/scst/README index fed367fe1..cd8f6861a 100644 --- a/scst/README +++ b/scst/README @@ -2848,204 +2848,6 @@ or initiator-target link, you can increase SCST_MAX_TGT_DEV_COMMANDS in scst_priv.h to 64. Usually initiators don't try to push more commands on the target. - -Obsolete /proc interface ------------------------- - -Also for communications with user space programs SCST provides -proc-based interface in /proc/scsi_tgt directory. This interface is -available in the procfs build only. Starting from version 2.0.0 it is -obsolete and will be removed in one of the next versions. To switch in -the procfs build you need to run "make enable_proc" command before -building anything else. - -It contains the following entries. - - - "help" file, which provides online help for SCST commands - - - "scsi_tgt" file, which on read provides information of serving by SCST - devices and their dev handlers. On write it supports the following - command: - - * "assign H:C:I:L HANDLER_NAME" assigns dev handler "HANDLER_NAME" - on device with host:channel:id:lun. The recommended way to find out - H:C:I:L numbers is use of lsscsi utility. - - - "sessions" file, which lists currently connected initiators (open sessions) - - - "sgv" file provides some statistic about with which block sizes - commands from remote initiators come and how effective sgv_pool in - serving those allocations from the cache, i.e. without memory - allocations requests to the kernel. "Size" - is the commands data - size upper rounded to power of 2, "Hit" - how many there are - allocations from the cache, "Total" - total number of allocations. - - - "threads" file, which allows to read and set number of SCST's threads - - - "version" file, which shows version of SCST - - - "trace_level" file, which allows to read and set trace (logging) level - for SCST. Also this file allows to dump persistent reservations - information about some device in the log file. See - /proc/scsi_tgt/help file for list of commands and trace levels. See - also section "Dealing with massive logs" for more info how to make - correct logs when you enabled trace levels producing a lot of logs - data. - -Each dev handler has own subdirectory. Most dev handler have only two -files in this subdirectory: "trace_level" and "type". The first one is -similar to main SCST "trace_level" file, the latter one shows SCSI type -number of this handler as well as some text description. - -For example, "echo "assign 1:0:1:0 dev_disk" >/proc/scsi_tgt/scsi_tgt" -will assign device handler "dev_disk" to real device sitting on host 1, -channel 0, ID 1, LUN 0. - - -Access and devices visibility management (LUN masking) - /proc interface ------------------------------------------------------------------------- - -Access and devices visibility management allows for an initiator or -group of initiators to see different devices with different LUNs -with necessary access permissions. - -SCST supports two modes of access control: - -1. Target-oriented. In this mode you define for each target devices and -their LUNs, which are accessible to all initiators, connected to that -target. This is a regular access control mode, which people usually mean -thinking about access control in general. For instance, in IET this is -the only supported mode. In this mode you should create a security group -with name "Default_TARGET_NAME", where "TARGET_NAME" is name of the -target, like "Default_iqn.2007-05.com.example:storage.disk1.sys1.xyz" -for target "iqn.2007-05.com.example:storage.disk1.sys1.xyz". Then you -should add to it all LUNs, available from that target. - -2. Initiator-oriented. In this mode you define which devices and their -LUNs are accessible for each initiator. In this mode you should create -for each set of one or more initiators, which should access to the same -set of devices with the same LUNs, a separate security group, then add -to it available devices and names of allowed initiator(s). - -Both modes can be used simultaneously. In this case initiator-oriented -mode has higher priority, than target-oriented. - -When a target driver registers itself in SCST core, it tells SCST core -its name. Then, when there is a new connection from a remote initiator, -the target driver registers this connection in SCST core and tells it -the name of the remote initiator. Then SCST core finds the corresponding -devices for it using the following algorithm: - -1. It searches through all defined groups trying to find group -containing the initiator name. If it succeeds, the found group is used. - -2. Otherwise, it searches through all groups trying to find group with -name "Default_TARGET_NAME". If it succeeds, the found group is used. - -3. Otherwise, the group with name "Default" is used. This group is -always defined, but empty by default. - -Names of both target and initiator you can clarify in the kernel log. In -it SCST reports to which group each session is assigned. - -In /proc/scsi_tgt each group represented as "groups/GROUP_NAME/" -subdirectory. In it there are files "devices" and "names". File -"devices" lists devices and their LUNs in the group, file "names" lists -names of initiators, which allowed to access devices in this group. - -To configure access and devices visibility management SCST provides the -following files and directories under /proc/scsi_tgt: - - - "add_group GROUP_NAME" to /proc/scsi_tgt/scsi_tgt adds group "GROUP_NAME" - - - "del_group GROUP_NAME" to /proc/scsi_tgt/scsi_tgt deletes group "GROUP_NAME" - - - "rename_group OLD_NAME NEW_NAME" to /proc/scsi_tgt/scsi_tgt renames - group "OLD_NAME" to "NEW_NAME". - - - "add H:C:I:L lun [READ_ONLY]" to /proc/scsi_tgt/groups/GROUP_NAME/devices adds - device with host:channel:id:lun with LUN "lun" in group "GROUP_NAME". Optionally, - the device could be marked as read only. The recommended way to find out - H:C:I:L numbers is use of lsscsi utility. - - - "replace H:C:I:L lun [READ_ONLY]" to /proc/scsi_tgt/groups/GROUP_NAME/devices - replaces by device with host:channel:id:lun existing with LUN "lun" - device in group "GROUP_NAME" with generation of INQUIRY DATA HAS - CHANGED Unit Attention. If the old device doesn't exist, this - command acts as the "add" command. Optionally, the device could be - marked as read only. The recommended way to find out H:C:I:L numbers - is use of lsscsi utility. - - - "del H:C:I:L" to /proc/scsi_tgt/groups/GROUP_NAME/devices deletes device with - host:channel:id:lun from group "GROUP_NAME". The recommended way to find out - H:C:I:L numbers is use of lsscsi utility. - - - "add V_NAME lun [READ_ONLY]" to /proc/scsi_tgt/groups/GROUP_NAME/devices adds - device with virtual name "V_NAME" with LUN "lun" in group "GROUP_NAME". - Optionally, the device could be marked as read only. - - - "replace V_NAME lun [READ_ONLY]" to /proc/scsi_tgt/groups/GROUP_NAME/devices - replaces by device with virtual name "V_NAME" existing with LUN - "lun" device in group "GROUP_NAME" with generation of INQUIRY DATA - HAS CHANGED Unit Attention. If the old device doesn't exist, this - command acts as the "add" command. Optionally, the device could - be marked as read only. - - - "del V_NAME" to /proc/scsi_tgt/groups/GROUP_NAME/devices deletes device with - virtual name "V_NAME" from group "GROUP_NAME" - - - "clear" to /proc/scsi_tgt/groups/GROUP_NAME/devices clears the list of devices - for group "GROUP_NAME" - - - "add NAME" to /proc/scsi_tgt/groups/GROUP_NAME/names adds name "NAME" to group - "GROUP_NAME". For NAME you can use simple DOS-type patterns, - containing '*' and '?' symbols. '*' means match all any symbols, '?' - means match only any single symbol. For instance, "blah.xxx" will - match "bl?h.*". Additionally, you can use negative sign '!' to - revert the value of the pattern. For instance, "ah.xxx" will match - "!bl?h.*". - - - "del NAME" to /proc/scsi_tgt/groups/GROUP_NAME/names deletes name "NAME" from group - "GROUP_NAME" - - - "move NAME NEW_GROUP_NAME" to /proc/scsi_tgt/groups/OLD_GROUP_NAME/names - moves name "NAME" from group "OLD_GROUP_NAME" to group "NEW_GROUP_NAME". - - - "clear" to /proc/scsi_tgt/groups/GROUP_NAME/names clears the list of names - for group "GROUP_NAME" - -Examples: - - - "echo "add 1:0:1:0 0" >/proc/scsi_tgt/groups/Default/devices" will - add real device sitting on host 1, channel 0, ID 1, LUN 0 to "Default" - group with LUN 0. - - - "echo "add disk1 1" >/proc/scsi_tgt/groups/Default/devices" will - add virtual VDISK device with name "disk1" to "Default" group - with LUN 1. - -- "echo "21:*:e0:?b:83:*'" >/proc/scsi_tgt/groups/LAB1/names" will - add a pattern, which matches WWNs of Fibre Channel ports from LAB1. - -Consider you need to have an iSCSI target with name -"iqn.2007-05.com.example:storage.disk1.sys1.xyz" (you defined it in -iscsi-scst.conf), which should export virtual device "dev1" with LUN 0 -and virtual device "dev2" with LUN 1, but initiator with name -"iqn.2007-05.com.example:storage.disk1.spec_ini.xyz" should see only -virtual device "dev2" with LUN 0. To achieve that you should do the -following commands: - -# echo "add_group Default_iqn.2007-05.com.example:storage.disk1.sys1.xyz" >/proc/scsi_tgt/scsi_tgt -# echo "add dev1 0" >/proc/scsi_tgt/groups/Default_iqn.2007-05.com.example:storage.disk1.sys1.xyz/devices -# echo "add dev2 1" >/proc/scsi_tgt/groups/Default_iqn.2007-05.com.example:storage.disk1.sys1.xyz/devices - -# echo "add_group spec_ini" >/proc/scsi_tgt/scsi_tgt -# echo "add iqn.2007-05.com.example:storage.disk1.spec_ini.xyz" >/proc/scsi_tgt/groups/spec_ini/names -# echo "add dev2 0" >/proc/scsi_tgt/groups/spec_ini/devices - -It is highly recommended to use scstadmin utility instead of described -in this section low level interface. - IMPORTANT ========= @@ -3079,95 +2881,6 @@ initiators or add new devices to old groups, but not altering existing LUNs in them. -VDISK /proc interface ---------------------- - -This interface starting from version 2.0.0 is obsolete and will be -removed in one of the next versions. To switch to it you should run -"make enable_proc". - -After loading VDISK device handler creates in /proc/scsi_tgt/ -subdirectories "vdisk" and "vcdrom". They have the following layout: - - - "trace_level" and "type" files as described above - - - "help" file, which provides online help for VDISK commands - - - "vdisk"/"vcdrom" files, which on read provides information of - currently open device files. On write it supports the following - command: - - * "open NAME [PATH] [BLOCK_SIZE] [FLAGS]" - opens file "PATH" as - device "NAME" with block size "BLOCK_SIZE" bytes with flags - "FLAGS". "PATH" could be empty only for VDISK CDROM. "BLOCK_SIZE" - and "FLAGS" are valid only for disk VDISK. The block size must be - power of 2 and >= 512 bytes. Default is 512. Possible flags: - - - WRITE_THROUGH - write back caching disabled. Note, this option - has sense only if you also *manually* disable write-back cache - in *all* your backstorage devices and make sure it's actually - disabled, since many devices are known to lie about this mode to - get better benchmark results. - - - READ_ONLY - read only - - - O_DIRECT - both read and write caching disabled. This mode - isn't currently fully implemented, you should use user space - fileio_tgt program in O_DIRECT mode instead (see below). - - - NULLIO - in this mode no real IO will be done, but success will be - returned. Intended to be used for performance measurements at the same - way as "*_perf" handlers. - - - NV_CACHE - enables "non-volatile cache" mode. In this mode it is - assumed that the target has a GOOD UPS with ability to cleanly - shutdown target in case of power failure and it is - software/hardware bugs free, i.e. all data from the target's - cache are guaranteed sooner or later to go to the media. Hence - all data synchronization with media operations, like - SYNCHRONIZE_CACHE, are ignored in order to bring more - performance. Also in this mode target reports to initiators that - the corresponding device has write-through cache to disable all - write-back cache workarounds used by initiators. Use with - extreme caution, since in this mode after a crash of the target - journaled file systems don't guarantee the consistency after - journal recovery, therefore manual fsck MUST be ran. Note, that - since usually the journal barrier protection (see "IMPORTANT" - note below) turned off, enabling NV_CACHE could change nothing - from data protection point of view, since no data - synchronization with media operations will go from the - initiator. This option overrides WRITE_THROUGH. - - - BLOCKIO - enables block mode, which will perform direct block - IO with a block device, bypassing page-cache for all operations. - This mode works ideally with high-end storage HBAs and for - applications that either do not need caching between application - and disk or need the large block throughput. See also below. - - - REMOVABLE - with this flag set the device is reported to remote - initiators as removable. - - * "close NAME" - closes device "NAME". - - * "resync_size NAME" - refreshes size of device "NAME". Intended to be - used after device resize. - - * "change NAME [PATH]" - changes a virtual CD in the VDISK CDROM. - - * "set_t10_dev_id NAME T10_DEVICE_ID" - sets T10 vendor specific - identifier on Device Identification VPD page (0x83) of device - "NAME" in INQUIRY data. By default VDISK handler always generates - T10_DEVICE_ID for every new created device at creation time. - This parameter allows to overwrite generated by VDISK value of - T10_DEVICE_ID. - -By default, if neither BLOCKIO, nor NULLIO option is supplied, FILEIO -mode is used. - -For example, "echo "open disk1 /vdisks/disk1" >/proc/scsi_tgt/vdisk/vdisk" -will open file /vdisks/disk1 as virtual FILEIO disk with name "disk1". - - Credits ------- diff --git a/scst/src/Makefile b/scst/src/Makefile index 3da5a5225..6471eece9 100644 --- a/scst/src/Makefile +++ b/scst/src/Makefile @@ -223,24 +223,4 @@ extraclean: clean rm Makefile.aa cd $(DEV_HANDLERS_DIR) && $(MAKE) $@ -disable_proc: - sed -i.aa s/"^#\?define CONFIG_SCST_PROC"/"\/* #define CONFIG_SCST_PROC *\/"/ ../include/scst.h - grep "^\/\* #define CONFIG_SCST_PROC \*\/" ../include/scst.h >/dev/null - rm ../include/scst.h.aa - sed -i.aa s/"^s\?cst-y += scst_proc.o"/"#scst\-y += scst_proc.o"/ Makefile - grep "^#scst\-y += scst_proc.o" Makefile >/dev/null - sed -i.aa s/"^#\?scst\-y += scst_sysfs.o"/"scst\-y += scst_sysfs.o"/ Makefile - grep "^scst\-y += scst_sysfs.o" Makefile >/dev/null - rm Makefile.aa - -enable_proc: - sed -i.aa s/"^\/\?\* #define CONFIG_SCST_PROC \*\/"/"#define CONFIG_SCST_PROC"/ ../include/scst.h - grep "^#define CONFIG_SCST_PROC" ../include/scst.h >/dev/null - rm ../include/scst.h.aa - sed -i.aa s/"^#\?scst\-y += scst_proc.o"/"scst\-y += scst_proc.o"/ Makefile - grep "^scst\-y += scst_proc.o" Makefile >/dev/null - sed -i.aa s/"^s\?cst\-y += scst_sysfs.o"/"#scst\-y += scst_sysfs.o"/ Makefile - grep "^#scst\-y += scst_sysfs.o" Makefile >/dev/null - rm Makefile.aa - -.PHONY: all install uninstall clean extraclean 2release 2debug 2perf disable_proc enable_proc +.PHONY: all install uninstall clean extraclean 2release 2debug 2perf diff --git a/scstadmin/Makefile b/scstadmin/Makefile index 3369330d0..5ed1e3ac7 100644 --- a/scstadmin/Makefile +++ b/scstadmin/Makefile @@ -161,15 +161,7 @@ distclean: extraclean: cd $(SCSTADMIN_DIR) && $(MAKE) $@ -disable_proc: - -rm -f scstadmin - ln -s scstadmin.sysfs scstadmin - -enable_proc: - -rm -f scstadmin - ln -s scstadmin.procfs scstadmin - release-archive: ../scripts/generate-release-archive scstadmin "$$(sed -n 's/^\$$Version[[:blank:]]*=[[:blank:]]*'"'"'SCST Configurator v\([^'"'"']*\)'"'"'.*/\1/p' scstadmin.sysfs/scstadmin)" -.PHONY: all install uninstall perl-module clean distclean extraclean disable_proc enable_proc +.PHONY: all install uninstall perl-module clean distclean extraclean diff --git a/scstadmin/README.procfs b/scstadmin/README.procfs deleted file mode 100644 index 4ccc9cffd..000000000 --- a/scstadmin/README.procfs +++ /dev/null @@ -1,64 +0,0 @@ -Installation: -============= - -Installation is simple. - - #> make - #> make install - -This installs scstadmin, the init.d script and the perl module. If you want SCST to -startup and configure automatically upon boot, enable SCST using your favorite -SysV init editor. - -NOTE: The init.d startup & shutdown scripts now depend on lsb-core. Ensure you have -lsb-core installed or 'make install' will fail. Make sure /usr/lib/lsb/install_initd -exists. - -To enable the obsolete procfs version: - - #> make enable_proc - #> make - #> make install - - -Getting Started: -================ - -The following pertains to the older procfs based SCST. - -The scstadmin script is much more functional than scst_db at this point but uses a -standard text-based config file. The original thought behind scst_db was to write -a daemon process which would except network connections and issue SCST commands. A -client app would then connect to that port. - -Copy scst.conf to /etc and edit it to your liking. if you have an existing configuration -then have scstadmin write it out to a config file for you: - - #> scstadmin -WriteConfig /etc/scst.conf - -When removing devices, users or groups from the config file keep in mind that -"scstadmin -config" will NOT remove those configurations from the running system unless -you use the -ForceConfig flag. Also, using the init script to reload the configuration - - #> /etc/init.d/scst reload-config - -will also not remove configurations from a running system. - -NOTE! Section "[TARGETS enable]" in the config file is for qla2x00t driver only! - -Mark.Buechler@gmail.com - - -To Do: -====== - -- Compare device and assignment options between current and saved configurations and - reopen/reassign as required if -ForceConfig is used. - -Completed: -========== - -- Create options section to scst.conf which will be carried forward in a -writeconfig. - -- Add option to issue a LIP after any group assignment changes so initiators can see - the change immediately. diff --git a/scstadmin/examples/scst.conf.procfs b/scstadmin/examples/scst.conf.procfs deleted file mode 100644 index b4af9e82e..000000000 --- a/scstadmin/examples/scst.conf.procfs +++ /dev/null @@ -1,120 +0,0 @@ -# Automatically generated by SCST Configurator v1.0.11. - -# NOTE: Options are pipe (|) seperated. - -[OPTIONS] -#OPTION <1|0|YES|NO|TRUE|FALSE|VALUE> -# Copy configuration options during a -writeconfig -KEEP_CONFIG TRUE -# For FC targets, issue a LIP after every assignment change -ISSUE_LIP FALSE - -[HANDLER vdisk] -#DEVICE ,,,, -DEVICE GW15K000,/dev/evms/GW15K000,,512 -DEVICE GW15K001,/dev/evms/GW15K001,,512 -DEVICE MP15K004,/dev/evms/MP15K004,,512 -DEVICE MP15K005,/dev/evms/MP15K005,,512 -DEVICE MP15K006,/dev/evms/MP15K006,,512 -DEVICE MP15K007,/dev/evms/MP15K007,,512 -DEVICE MP15K008,/dev/evms/MP15K008,,512 -DEVICE MP15K009,/dev/evms/MP15K009,,512 -DEVICE MP15K00a,/dev/evms/MP15K00a,,512 -DEVICE MP15K00b,/dev/evms/MP15K00b,,512 -DEVICE MP15K00c,/dev/evms/MP15K00c,,512 -DEVICE MP15K00d,/dev/evms/MP15K00d,,512 -DEVICE MP15K00e,/dev/evms/MP15K00e,,512 -DEVICE MS10K006,/dev/evms/MS10K002,,512 -DEVICE MS15K000,/dev/evms/MS15K000,,512 -DEVICE MS15K001,/dev/evms/MS15K001,,512 -DEVICE MS15K002,/dev/evms/MS15K002,,512 -DEVICE MS15K005,/dev/evms/MS15K003,,512 -DEVICE RG10K000,/dev/evms/RG10K000,,512 -DEVICE RG72K001,/dev/evms/RG72K001,,512 - -[HANDLER vcdrom] - -[GROUP CORBIN2_a] -#USER -USER 21:00:00:e0:8b:11:8d:8a - -[GROUP CORBIN3_a] -#USER -USER 21:00:00:e0:8b:03:9e:1a - -[GROUP MENTASM_a] -#USER -USER 21:00:00:e0:8b:11:06:8a - -[GROUP PC1_a] -#USER -USER 21:00:00:e0:8b:11:3f:8d - -[GROUP PC2_a] -#USER -USER 21:00:00:e0:8b:03:d8:4a - -[GROUP PC3_a] -#USER -USER 21:00:00:e0:8b:13:ba:01 - -[GROUP PC4_a] -#USER -USER 21:00:00:e0:8b:11:a6:8b - -[GROUP RAISTLIN_a] -#USER -USER 21:00:00:e0:8b:11:75:8b - -[ASSIGNMENT CORBIN2_a] -#ASSIGNMENT ,, -DEVICE MP15K009,0 -DEVICE MS10K006,1 -DEVICE RG10K000,2 -DEVICE RG72K001,3 - -[ASSIGNMENT CORBIN3_a] -#ASSIGNMENT ,, -DEVICE MP15K00d,0 - -[ASSIGNMENT Default] -#ASSIGNMENT ,, -DEVICE GW15K000,0 -DEVICE GW15K001,1 - -[ASSIGNMENT MENTASM_a] -#ASSIGNMENT ,, -DEVICE MP15K006,0 -DEVICE MP15K008,1 -DEVICE MP15K00e,2 - -[ASSIGNMENT PC1_a] -#ASSIGNMENT ,, -DEVICE MS15K000,0 - -[ASSIGNMENT PC2_a] -#ASSIGNMENT ,, -DEVICE MS15K005,0 - -[ASSIGNMENT PC3_a] -#ASSIGNMENT ,, -DEVICE MP15K00c,0 - -[ASSIGNMENT PC4_a] -#ASSIGNMENT ,, -DEVICE MP15K005,0 -DEVICE MP15K007,1 - -[ASSIGNMENT RAISTLIN_a] -#ASSIGNMENT ,, -DEVICE MP15K00a,0 -DEVICE MP15K00b,1 - -[TARGETS enable] -# This section is for qla2x00t targets only -#HOST -HOST 0x50060b0000397178 -HOST 0x50060b000039717a - -[TARGETS disable] -# This section is for qla2x00t targets only diff --git a/scstadmin/scstadmin.procfs/Makefile b/scstadmin/scstadmin.procfs/Makefile deleted file mode 100644 index 5d7a4626f..000000000 --- a/scstadmin/scstadmin.procfs/Makefile +++ /dev/null @@ -1,38 +0,0 @@ -ifndef PREFIX - PREFIX=/usr/local -endif - -MODULE_VERSION = 0.8.22 -TOOL = scstadmin - -SBINDIR := $(PREFIX)/sbin - -all: perl-module - -install install_vendor: all - $(MAKE) -C scst-$(MODULE_VERSION) $@ DESTDIR=$(DESTDIR) - install -d $(DESTDIR)$(SBINDIR) - install -m 755 $(TOOL) $(DESTDIR)$(SBINDIR) - -uninstall: - -rm -f $(DESTDIR)$(SBINDIR)/$(TOOL) - $(MAKE) -C scst-$(MODULE_VERSION) uninstall - -perl-module: - @cd ./scst-$(MODULE_VERSION); \ - perl Makefile.PL; - $(MAKE) -C scst-$(MODULE_VERSION) - -test: - $(MAKE) -C scst-$(MODULE_VERSION) test - -clean: - -$(MAKE) -C scst-$(MODULE_VERSION) clean - -distclean: clean - -rm -f scst-$(MODULE_VERSION)/Makefile.old - rm -f *.orig *.rej - -extraclean: distclean - -.PHONY: all install uninstall perl-module clean distclean extraclean diff --git a/scstadmin/scstadmin.procfs/scst-0.8.22/MANIFEST b/scstadmin/scstadmin.procfs/scst-0.8.22/MANIFEST deleted file mode 100644 index 267f842ca..000000000 --- a/scstadmin/scstadmin.procfs/scst-0.8.22/MANIFEST +++ /dev/null @@ -1,4 +0,0 @@ -lib/SCST/SCST.pm -Makefile.PL -MANIFEST This list of files -README diff --git a/scstadmin/scstadmin.procfs/scst-0.8.22/Makefile.PL b/scstadmin/scstadmin.procfs/scst-0.8.22/Makefile.PL deleted file mode 100644 index 621b905d9..000000000 --- a/scstadmin/scstadmin.procfs/scst-0.8.22/Makefile.PL +++ /dev/null @@ -1,13 +0,0 @@ -#!/usr/bin/perl -w -# -# Makefile for the SCST_SCST perl module -# - -use ExtUtils::MakeMaker; - -WriteMakefile( - 'NAME' => 'SCST_SCST', - 'VERSION_FROM' => 'lib/SCST/SCST.pm', - 'AUTHOR' => 'Mark R. Buechler ', - 'PREREQ_PM' => {}, -); diff --git a/scstadmin/scstadmin.procfs/scst-0.8.22/README b/scstadmin/scstadmin.procfs/scst-0.8.22/README deleted file mode 100644 index 75b5b8f1f..000000000 --- a/scstadmin/scstadmin.procfs/scst-0.8.22/README +++ /dev/null @@ -1,16 +0,0 @@ -SCST_SCST is a perl module for querying and configuring SCST. - - -AVAILABILITY - -Currently SCST_SCST ships with SCST itself available from -http://scst.sourceforge.net. - - -INSTALLATION - -Install SCST_SCST as you would any other perl module: - - perl Makefile.PL - make - make install diff --git a/scstadmin/scstadmin.procfs/scst-0.8.22/lib/SCST/SCST.pm b/scstadmin/scstadmin.procfs/scst-0.8.22/lib/SCST/SCST.pm deleted file mode 100644 index 88e9daa86..000000000 --- a/scstadmin/scstadmin.procfs/scst-0.8.22/lib/SCST/SCST.pm +++ /dev/null @@ -1,1587 +0,0 @@ -package SCST::SCST; - -# Author: Mark R. Buechler -# License: GPLv2 -# Copyright (c) 2005-2009 Mark R. Buechler - -use 5.005; -use IO::Handle; -use IO::File; -use strict; -use Carp qw(cluck); - -my $_SCST_DIR_ = '/proc/scsi_tgt'; -my $_SCST_IO_ = $_SCST_DIR_.'/scsi_tgt'; -my $_SCST_VDISK_IO_ = $_SCST_DIR_.'/vdisk/vdisk'; -my $_SCST_VCDROM_IO_ = $_SCST_DIR_.'/vcdrom/vcdrom'; -my $_SCST_GROUPS_DIR_ = $_SCST_DIR_.'/groups'; -my $_SCST_SGV_STATS_ = $_SCST_DIR_.'/sgv'; -my $_SCST_SESSIONS_ = $_SCST_DIR_.'/sessions'; -my $_SCST_VERSION_IO_ = $_SCST_DIR_.'/version'; - -my $_SCST_USERS_IO_ = 'names'; -my $_SCST_DEVICES_IO_ = 'devices'; - -use vars qw(@ISA @EXPORT $VERSION $CDROM_TYPE $CHANGER_TYPE $DISK_TYPE $VDISK_TYPE - $VCDROM_TYPE $DISKPERF_TYPE $MODISK_TYPE $MODISKPERF_TYPE $TAPE_TYPE - $TAPEPERF_TYPE $PROCESSOR_TYPE $IOTYPE_PHYSICAL $IOTYPE_VIRTUAL - $IOTYPE_PERFORMANCE); - -$CDROM_TYPE = 1; -$CHANGER_TYPE = 2; -$DISK_TYPE = 3; -$VDISK_TYPE = 4; -$VCDROM_TYPE = 5; -$DISKPERF_TYPE = 6; -$MODISK_TYPE = 7; -$MODISKPERF_TYPE = 8; -$TAPE_TYPE = 9; -$TAPEPERF_TYPE = 10; -$PROCESSOR_TYPE = 11; - -$IOTYPE_PHYSICAL = 100; -$IOTYPE_VIRTUAL = 101; -$IOTYPE_PERFORMANCE = 102; - -$VERSION = '0.8.22'; - -my $_SCST_MIN_MAJOR_ = 2; -my $_SCST_MIN_MINOR_ = 0; -my $_SCST_MIN_RELEASE_ = 0; - -my %_IO_MAP_ = ($VDISK_TYPE => $_SCST_VDISK_IO_, - $VCDROM_TYPE => $_SCST_VCDROM_IO_); - -my %_TYPE_MAP_ = ('dev_cdrom' => $CDROM_TYPE, - 'dev_changer' => $CHANGER_TYPE, - 'dev_disk' => $DISK_TYPE, - 'vdisk' => $VDISK_TYPE, - 'vcdrom' => $VCDROM_TYPE, - 'dev_disk_perf' => $DISKPERF_TYPE, - 'dev_modisk' => $MODISK_TYPE, - 'dev_modisk_perf' => $MODISKPERF_TYPE, - 'dev_tape' => $TAPE_TYPE, - 'dev_tape_perf' => $TAPEPERF_TYPE, - 'dev_processor' => $PROCESSOR_TYPE); - -my %_REVERSE_MAP_ = ($CDROM_TYPE => 'dev_cdrom', - $CHANGER_TYPE => 'dev_changer', - $DISK_TYPE => 'dev_disk', - $VDISK_TYPE => 'vdisk', - $VCDROM_TYPE => 'vcdrom', - $DISKPERF_TYPE => 'dev_disk_perf', - $MODISK_TYPE => 'dev_modisk', - $MODISKPERF_TYPE => 'dev_modisk_perf', - $TAPE_TYPE => 'dev_tape', - $TAPEPERF_TYPE => 'dev_tape_perf', - $PROCESSOR_TYPE => 'dev_processor'); - -my %_IO_TYPES_ = ($CDROM_TYPE => $IOTYPE_PHYSICAL, - $CHANGER_TYPE => $IOTYPE_PHYSICAL, - $DISK_TYPE => $IOTYPE_PHYSICAL, - $VDISK_TYPE => $IOTYPE_VIRTUAL, - $VCDROM_TYPE => $IOTYPE_VIRTUAL, - $DISKPERF_TYPE => $IOTYPE_PERFORMANCE, - $MODISK_TYPE => $IOTYPE_PHYSICAL, - $MODISKPERF_TYPE => $IOTYPE_PERFORMANCE, - $TAPE_TYPE => $IOTYPE_PHYSICAL, - $TAPEPERF_TYPE => $IOTYPE_PERFORMANCE, - $PROCESSOR_TYPE => $IOTYPE_PHYSICAL); - -my %_HANDLER_ALIASES_ = ('vdisk_blk' => 'vdisk', - 'vdisk_fileio' => 'vdisk', - 'vdisk_blockio' => 'vdisk', - 'vdisk_nullio' => 'vdisk'); - -my %_OPEN_OPTIONS_ = ('WRITE_THROUGH' => 'WRITE_THROUGH', - 'WT' => 'WRITE_THROUGH', - 'O_DIRECT' => 'O_DIRECT', - 'DR' => 'O_DIRECT', - 'READ_ONLY' => 'READ_ONLY', - 'RO' => 'READ_ONLY', - 'NULLIO' => 'NULLIO', - 'NIO' => 'NULLIO', - 'NV_CACHE' => 'NV_CACHE', - 'NV' => 'NV_CACHE', - 'BLOCKIO' => 'BLOCKIO', - 'BIO' => 'BLOCKIO', - 'REMOVABLE' => 'REMOVABLE', - 'RM' => 'REMOVABLE'); - -my %_ASSIGN_OPTIONS_ = ('READ_ONLY' => 'READ_ONLY', - 'RO' => 'READ_ONLY'); - -my %_OPTIONS_BY_TYPE_ = ('OPEN', => \%_OPEN_OPTIONS_, - 'ASSIGN' => \%_ASSIGN_OPTIONS_); - -sub new { - my $this = shift; - my $debug = shift; - my $badVersion = 1; - - my $class = ref($this) || $this; - my $self = {}; - - bless($self, $class); - - $self->{'debug'} = $debug; - - my $scstVersion = $self->scstVersion(); - - die("Failed to obtain SCST version information. Is the scst module loaded?\n") - if ($scstVersion == -1); - - my($major, $minor, $release) = split(/\./, $scstVersion, 3); - ($release, undef) = split(/\-/, $release) if ($release =~ /\-/); - - $badVersion = 0 if (($major > $_SCST_MIN_MAJOR_) || - (($major == $_SCST_MIN_MAJOR_) && ($minor > $_SCST_MIN_MINOR_)) || - (($major == $_SCST_MIN_MAJOR_) && ($minor == $_SCST_MIN_MINOR_) && - ($release >= $_SCST_MIN_RELEASE_))); - - die("This module requires at least SCST version $_SCST_MIN_MAJOR_\.$_SCST_MIN_MINOR_\.". - "$_SCST_MIN_RELEASE_ and version $scstVersion was found") if ($badVersion); - - return $self; -} - -sub scstVersion { - my $self = shift; - - my $io = new IO::File $_SCST_VERSION_IO_, O_RDONLY; - return -1 if (!$io); - - my $version = <$io>; - chomp $version; - - return $version; -} - -sub groups { - my $self = shift; - my @groups; - my $dirHandle = new IO::Handle; - - opendir $dirHandle, $_SCST_GROUPS_DIR_ or return undef; - - foreach my $entry (readdir($dirHandle)) { - next if (($entry eq '.') || ($entry eq '..')); - - push @groups, $entry; - } - - close $dirHandle; - - return \@groups; -} - -sub groupExists { - my $self = shift; - my $group = shift; - my $groups = $self->groups(); - - foreach my $_group (@{$groups}) { - return 1 if ($group eq $_group); - } - - return 0; -} - -sub addGroup { - my $self = shift; - my $group = shift; - - return 2 if ($self->groupExists($group)); - - my $io = new IO::File $_SCST_IO_, O_WRONLY; - - if (!$io) { - $self->{'error'} = "addGroup(): Failed to open handler IO '$_SCST_IO_'"; - return 1; - } - - my $cmd = "add_group $group\n"; - - if ($self->{'debug'}) { - print "DBG($$): $_SCST_IO_ -> $cmd\n"; - } else { - print $io $cmd; - } - - close $io; - - return 0 if ($self->{'debug'}); - return !$self->groupExists($group); -} - -sub removeGroup { - my $self = shift; - my $group = shift; - - return 2 if (!$self->groupExists($group)); - - my $io = new IO::File $_SCST_IO_, O_WRONLY; - - if (!$io) { - $self->{'error'} = "removeGroup(): Failed to open handler IO '$_SCST_IO_'"; - return 1; - } - - my $cmd = "del_group $group\n"; - - if ($self->{'debug'}) { - print "DBG($$): $_SCST_IO_ -> $cmd\n"; - } else { - print $io $cmd; - } - - close $io; - - return 0 if ($self->{'debug'}); - return $self->groupExists($group); -} - -sub renameGroup { - my $self = shift; - my $oldName = shift; - my $newName = shift; - - if (!$self->groupExists($oldName)) { - $self->{'error'} = "renameGroup(): Group '$oldName' doesn't exist"; - return 1; - } - - return 2 if ($self->groupExists($newName)); - - my $io = new IO::File $_SCST_IO_, O_WRONLY; - - if (!$io) { - $self->{'error'} = "renameGroup(): Failed to open handler IO '$_SCST_IO_'"; - return 1; - } - - my $cmd = "rename_group $oldName $newName\n"; - - if ($self->{'debug'}) { - print "DBG($$): $_SCST_IO_ -> $cmd\n"; - } else { - print $io $cmd; - } - - close $io; - - return 0 if ($self->{'debug'}); - return !$self->groupExists($newName); -} - -sub sgvStats { - my $self = shift; - my $io = new IO::File $_SCST_SGV_STATS_, O_RDONLY; - my %stats; - my $first = 1; - - if (!$io) { - $self->{'error'} = "sgvStats(): Failed to open handler IO '$_SCST_IO_'"; - return undef; - } - - while (my $line = <$io>) { - chomp $line; - - if ($first || !$line) { - $first = 0; - next; - } - - my $size; - my $stat; - my $hit; - my $total; - - if ($line !~ /^\s/) { - ($stat, $hit, $total) = split(/\s+/, $line); - - $size = 'ALL'; - if ($stat eq 'big') { - $total = $hit; - $hit = -1; - } - } else { - (undef, $stat, $hit, $total) = split(/\s+/, $line); - - if ($stat =~ /(\d+)K$/) { - $size = $1; - $stat =~ s/\-$size\K//; - } - } - - $stats{$stat}->{$size}->{'HITS'} = $hit; - $stats{$stat}->{$size}->{'TOTAL'} = $total; - } - - close $io; - - return \%stats; -} - -sub sessions { - my $self = shift; - my $io = new IO::File $_SCST_SESSIONS_, O_RDONLY; - my %sessions; - my $first = 1; - - if (!$io) { - $self->{'error'} = "sessions(): Failed to open handler IO '$_SCST_IO_'"; - return undef; - } - - while (my $line = <$io>) { - chomp $line; - - if ($first) { - $first = 0; - next; - } - - my($target, $user, $group, $commands) = split(/\s+/, $line); - - $sessions{$target}->{$group}->{$user} = $commands; - } - - close $io; - - return \%sessions; -} - -sub devices { - my $self = shift; - my $io = new IO::File $_SCST_IO_, O_RDONLY; - my %devices; - my $first = 1; - - if (!$io) { - $self->{'error'} = "devices(): Failed to open handler IO '$_SCST_IO_'"; - return undef; - } - - while (my $line = <$io>) { - chomp $line; - - if ($first) { - $first = 0; - next; - } - - my($vname, $handler) = split(/\s+/, $line); - - $handler = $_HANDLER_ALIASES_{$handler} if ($_HANDLER_ALIASES_{$handler}); - $devices{$vname} = $_TYPE_MAP_{$handler}; - } - - close $io; - - return \%devices; -} - -sub handlerDevices { - my $self = shift; - my $handler = shift; - my $handler_io = $_IO_MAP_{$handler}; - my $first = 1; - my $handler_name = $_REVERSE_MAP_{$handler}; - my %devices; - - if (!$handler_io) { - $self->{'error'} = "handlerDevices(): Failed to open handler IO '$handler_io'". - " or handler '$handler_name' ($handler) invalid"; - return undef; - } - - if (!$self->handlerExists($handler)) { - $self->{'error'} = "handlerDevices(): Handler '$handler_name' ($handler) does not exist"; - return undef; - } - - my $io = new IO::File $handler_io, O_RDONLY; - - if (!$io) { - print "\nWARNING: handlerDevices(): Failed to open handler IO $handler_io, assuming disabled.\n\n"; - return \%devices; # Return an empty hash - } - - while (my $line = <$io>) { - chomp $line; - - if ($first) { - $first = 0; - next; - } - - my ($vname, $size, $blocksize, $options, $path, $t10_id) = - ($line =~ '(\S+)\s+(\S+)\s+(\S+)\s+(.*?)\s+(/\S+)\s+(.*)$'); - - $t10_id = cleanupString($t10_id); - - if ($options =~ /^\//) { - $t10_id = $path; - $path = $options; - $options = ""; - } - - if ($t10_id =~ /^\//) { - $options .= " ".$path; - $path = $t10_id; - $t10_id = ""; - } - - my $options_t; - foreach my $option (split(/\s/, cleanupString($options))) { - if (defined($_OPEN_OPTIONS_{$option})) { - $options_t .= $_OPEN_OPTIONS_{$option}.','; - } else { - cluck("WARNING: Unknown option '$option', please update your SCST version"); - } - } - - $options_t =~ s/\,$//; - - $devices{$vname}->{'OPTIONS'} = $options_t; - - $devices{$vname}->{'SIZE'} = cleanupString($size); - $devices{$vname}->{'PATH'} = cleanupString($path); - $devices{$vname}->{'BLOCKSIZE'} = cleanupString($blocksize); - $devices{$vname}->{'T10_DEVICE_ID'} = $t10_id; - } - - close $io; - - return \%devices; -} - -sub handlerDeviceExists { - my $self = shift; - my $handler = shift; - my $device = shift; - my $devices = $self->handlerDevices($handler); - - return -1 if (!defined($devices)); - return 1 if (defined($$devices{$device})); - - return 0; -} - -sub handlerType { - my $self = shift; - my $handler = shift; - my $type = $_IO_TYPES_{$handler}; - my $handler_name = $_REVERSE_MAP_{$handler}; - - if (!$type) { - $self->{'error'} = "handlerType(): Handler type for handler '$handler_name'". - " ($handler) not defined"; - return undef; - } - - return $type; -} - -sub openDevice { - my $self = shift; - my $handler = shift; - my $device = shift; - my $path = shift; - my $options = shift; - my $blocksize = shift; - my $handler_io = $_IO_MAP_{$handler}; - my $handler_name = $_REVERSE_MAP_{$handler}; - my $valid_opts; - - ($options, $valid_opts) = $self->checkOptions($options, 'OPEN'); - - if (!$valid_opts) { - $self->{'error'} = "openDevice(): Invalid option(s) '$options' given for device '$device'"; - return 1; - } - - if (!$handler_io) { - $self->{'error'} = "openDevice(): Failed to open handler IO '$handler_io' or ". - "handler '$handler_name' ($handler) invalid"; - return 1; - } - - if (!$self->handlerExists($handler)) { - $self->{'error'} = "openDevice(): Handler '$handler_name' ($handler) does not exist"; - return 1; - } - - if ($self->handlerDeviceExists($handler, $device)) { - $self->{'error'} = "openDevice(): Device '$device' is already open"; - return 2; - } - - $options = cleanupString($options); - $options =~ s/,/ /g; - - my $cmd = "open $device $path $blocksize $options\n"; - - $cmd = cleanupString($cmd); - - my $rc = $self->handler_private($handler_io, $cmd); - - return 0 if ($self->{'debug'}); - return $rc if ($rc); - - $rc = !$self->handlerDeviceExists($handler, $device); - - if ($rc) { - $self->{'error'} = "openDevice(): An error occurred while opening device '$device'. ". - "See dmesg/kernel log for more information."; - } - - return $rc; -} - -sub closeDevice { - my $self = shift; - my $handler = shift; - my $device = shift; - my $path = shift; - my $handler_io = $_IO_MAP_{$handler}; - my $handler_name = $_REVERSE_MAP_{$handler}; - - if (!$handler_io) { - $self->{'error'} = "closeDevice(): Failed to open handler IO '$handler_io'". - " or handler '$handler_name' ($handler) invalid"; - return 1; - } - - if (!$self->handlerExists($handler)) { - $self->{'error'} = "closeDevice(): Handler '$handler_name' ($handler) does not exist"; - return 1; - } - - if (!$self->handlerDeviceExists($handler, $device)) { - $self->{'error'} = "closeDevice(): Device '$device' is not open"; - return 2; - } - - my $cmd = "close $device $path\n"; - - my $rc = $self->handler_private($handler_io, $cmd); - - return 0 if ($self->{'debug'}); - return $rc if ($rc); - - $rc = $self->handlerDeviceExists($handler, $device); - - if ($rc) { - $self->{'error'} = "closeDevice(): An error occurred while closing device '$device'. ". - "See dmesg/kernel log for more information."; - } - - return $rc; -} - -sub resyncDevice { - my $self = shift; - my $handler = shift; - my $device = shift; - my $handler_io = $_IO_MAP_{$handler}; - my $handler_name = $_REVERSE_MAP_{$handler}; - - if (!$handler_io) { - $self->{'error'} = "resyncDevice(): Failed to open handler IO '$handler_io'". - " or handler '$handler_name' ($handler) invalid"; - return 1; - } - - if (!$self->handlerExists($handler)) { - $self->{'error'} = "resyncDevice(): Handler '$handler_name' ($handler) does not exist"; - return 1; - } - - if (!$self->handlerDeviceExists($handler, $device)) { - $self->{'error'} = "resyncDevice(): Device '$device' does not exist"; - return 2; - } - - my $cmd = "resync_size $device\n"; - - my $rc = $self->handler_private($handler_io, $cmd); - - return 0 if ($self->{'debug'}); - return $rc if ($rc); - - return $rc; -} - -sub setT10DeviceId { - my $self = shift; - my $handler = shift; - my $device = shift; - my $t10_id = shift; - my $handler_io = $_IO_MAP_{$handler}; - - if (!$handler_io) { - $self->{'error'} = "setT10DeviceId(): Failed to open handler IO $handler_io or handler $handler invalid"; - return 1; - } - - if (!$self->handlerExists($handler)) { - $self->{'error'} = "setT10DeviceId(): Handler $handler does not exist"; - return 1; - } - - if (!$self->handlerDeviceExists($handler, $device)) { - $self->{'error'} = "setT10DeviceId(): Device $device is not open"; - return 2; - } - - my $cmd = "set_t10_dev_id $device $t10_id\n"; - - my $rc = $self->handler_private($handler_io, $cmd); - - return 0 if ($self->{'debug'}); - return $rc if ($rc); - - my $devices = $self->handlerDevices($handler); - - if ($$devices{$device}->{'T10_DEVICE_ID'} ne $t10_id) { - $self->{'error'} = "setT10DeviceId(): An error occurred while setting T10 device ID to '$t10_id' ". - "for device '$device'. See dmesg/kernel log for more information."; - return 1; - } -} - -sub userExists { - my $self = shift; - my $user = shift; - my $group = shift; - - my $users = $self->users($group); - - return -1 if (!defined($users)); - - foreach my $_user (@{$users}) { - return 1 if ($user eq $_user); - } - - return 0; -} - -sub users { - my $self = shift; - my $group = shift; - my @users; - - return undef if (!$self->groupExists($group)); - - my $io = new IO::File $_SCST_GROUPS_DIR_."/$group/".$_SCST_USERS_IO_, O_RDONLY; - - if (!$io) { - $self->{'error'} = "users(): Failed to open handler IO '".$_SCST_GROUPS_DIR_. - "/$group/".$_SCST_USERS_IO_."'"; - return undef; - } - - while (my $line = <$io>) { - chomp $line; - - push @users, $line; - } - - close $io; - - return \@users; -} - -sub addUser { - my $self = shift; - my $user = shift; - my $group = shift; - - if (!$self->groupExists($group)) { - $self->{'error'} = "addUser(): Group '$group' does not exist"; - return 1; - } - - if ($self->userExists($user, $group)) { - $self->{'error'} = "addUser(): User '$user' already exists in group '$group'"; - return 2; - } - - my $cmd = "add $user\n"; - - my $rc = $self->group_private($group, $_SCST_USERS_IO_, $cmd); - - return 0 if ($self->{'debug'}); - return $rc if ($rc); - - $rc = !$self->userExists($user, $group); - - if ($rc) { - $self->{'error'} = "addUser(): An error occurred while adding user '$user' to group '$group'. ". - "See dmesg/kernel log for more information."; - } - - return $rc; -} - -sub removeUser { - my $self = shift; - my $user = shift; - my $group = shift; - - if (!$self->groupExists($group)) { - $self->{'error'} = "removeUser(): Group '$group' does not exist"; - return 1; - } - - if (!$self->userExists($user, $group)) { - $self->{'error'} = "removeUser(): User '$user' does not exist in group '$group'"; - return 2; - } - - my $cmd = "del $user\n"; - - my $rc = $self->group_private($group, $_SCST_USERS_IO_, $cmd); - - return 0 if ($self->{'debug'}); - return $rc if ($rc); - - $rc = $self->userExists($user, $group); - - if ($rc) { - $self->{'error'} = "removeUser(): An error occurred while removing user '$user' ". - "from group '$group'. See dmesg/kernel log for more information."; - } - - return $rc; -} - -sub moveUser { - my $self = shift; - my $user = shift; - my $fromGroup = shift; - my $toGroup = shift; - - if (!$self->groupExists($fromGroup)) { - $self->{'error'} = "moveUser(): Group '$fromGroup' does not exist"; - return 1; - } - - if (!$self->groupExists($toGroup)) { - $self->{'error'} = "moveUser(): Group '$toGroup' does not exist"; - return 1; - } - - if (!$self->userExists($user, $fromGroup)) { - $self->{'error'} = "addUser(): User '$user' doesn't exist in group '$fromGroup'"; - return 1; - } - - if ($self->userExists($user, $toGroup)) { - $self->{'error'} = "addUser(): User '$user' already exists in group '$toGroup'"; - return 2; - } - - my $cmd = "move $user $toGroup\n"; - - my $rc = $self->group_private($fromGroup, $_SCST_USERS_IO_, $cmd); - - return 0 if ($self->{'debug'}); - return $rc if ($rc); - - $rc = !$self->userExists($user, $toGroup); - - if ($rc) { - $self->{'error'} = "addUser(): An error occurred while moving user '$user' from group '$fromGroup' ". - "to group '$toGroup'. See dmesg/kernel log for more information."; - } - - return $rc; -} - -sub clearUsers { - my $self = shift; - my $group = shift; - - if (!$self->groupExists($group)) { - $self->{'error'} = "clearUsers(): Group '$group' does not exist"; - return 1; - } - - my $cmd = "clear\n"; - - my $rc = $self->group_private($group, $_SCST_USERS_IO_, $cmd); - - return 0 if ($self->{'debug'}); - - if ($rc) { - $self->{'error'} = "clearUsers(): An error occurred while clearing users from ". - "group '$group'. See dmesg/kernel log for more information."; - return $rc; - } - - my $users = $self->users($group); - - return ($#{$users} + 1); -} - -sub handlerExists { - my $self = shift; - my $handler = shift; - - my $handlers = $self->handlers(); - - foreach my $_handler (@{$handlers}) { - return 1 if ($handler eq $_handler); - } - - return 0; -} - -sub handlers { - my $self = shift; - my @handlers; - - my $dirHandle = new IO::Handle; - - opendir $dirHandle, $_SCST_DIR_ or return undef; - - foreach my $entry (readdir($dirHandle)) { - next if (($entry eq '.') || ($entry eq '..')); - if ((-d $_SCST_DIR_.'/'.$entry ) && (-f $_SCST_DIR_.'/'.$entry.'/type')) { - push @handlers, $_TYPE_MAP_{$entry} if ($_TYPE_MAP_{$entry}); - } - } - - close $dirHandle; - - return \@handlers; -} - -sub groupDeviceExists { - my $self = shift; - my $device = shift; - my $group = shift; - my $lun = shift; - my $devices = $self->groupDevices($group); - - return -1 if (!defined($devices)); - - if (defined($lun)) { - return 1 if ($$devices{$device} eq $lun); - } else { - return 1 if (defined($$devices{$device})); - } - - return 0; -} - -sub groupDevices { - my $self = shift; - my $group = shift; - my %devices; - my $first = 1; - - if (!$self->groupExists($group)) { - $self->{'error'} = "groupDevices(): Group '$group' does not exist"; - return undef; - } - - my $io = new IO::File $_SCST_GROUPS_DIR_."/$group/".$_SCST_DEVICES_IO_, O_RDONLY; - - if (!$io) { - $self->{'error'} = "groupDevices(): Failed to open handler IO '".$_SCST_GROUPS_DIR_. - "/$group/".$_SCST_DEVICES_IO_."'"; - return undef; - } - - while (my $line = <$io>) { - chomp $line; - - if ($first) { - $first = 0; - next; - } - - my($vname, $lun) = split(/\s+/, $line); - - $devices{$vname} = $lun; - } - - close $io; - - return \%devices; -} - -sub assignDeviceToGroup { - my $self = shift; - my $device = shift; - my $group = shift; - my $lun = shift; - my $options = shift; - my $valid_opts; - - ($options, $valid_opts) = $self->checkOptions($options, 'ASSIGN'); - - if (!$valid_opts) { - $self->{'error'} = "assignDeviceToGroup(): Invalid option(s) '$options' given for ". - "device '$device' in assignment"; - return 1; - } - - if (!$self->groupExists($group)) { - $self->{'error'} = "assignDeviceToGroup(): Group '$group' does not exist"; - return 1; - } - - if ($self->groupDeviceExists($device, $group, $lun)) { - $self->{'error'} = "assignDeviceToGroup(): Device '$device' is already ". - "assigned to group '$group'"; - return 2; - } - - $options = cleanupString($options); - $options =~ s/,/ /g; - - my $cmd = "add $device $lun $options\n"; - - my $rc = $self->group_private($group, $_SCST_DEVICES_IO_, $cmd); - - return 0 if ($self->{'debug'}); - return $rc if ($rc); - - $rc = !$self->groupDeviceExists($device, $group, $lun); - - if ($rc) { - $self->{'error'} = "assignDeviceToGroup(): An error occurred while assigning device '$device' ". - "to group '$group'. See dmesg/kernel log for more information."; - } - - return $rc; -} - -sub replaceDeviceInGroup { - my $self = shift; - my $newDevice = shift; - my $group = shift; - my $lun = shift; - my $options = shift; - my $valid_opts; - - ($options, $valid_opts) = $self->checkOptions($options, 'ASSIGN'); - - if (!$valid_opts) { - $self->{'error'} = "replaceDeviceInGroup(): Invalid option(s) '$options' given for ". - "device '$newDevice'"; - return 1; - } - - if (!$self->groupExists($group)) { - $self->{'error'} = "replaceDeviceInGroup(): Group '$group' does not exist"; - return 1; - } - - if ($self->groupDeviceExists($newDevice, $group, $lun)) { - $self->{'error'} = "replaceDeviceInGroup(): Device '$newDevice' is already ". - "assigned to group '$group'"; - return 2; - } - - $options = cleanupString($options); - $options =~ s/,/ /g; - - my $cmd = "replace $newDevice $lun $options\n"; - - my $rc = $self->group_private($group, $_SCST_DEVICES_IO_, $cmd); - - return 0 if ($self->{'debug'}); - return $rc if ($rc); - - $rc = !$self->groupDeviceExists($newDevice, $group, $lun); - - if ($rc) { - $self->{'error'} = "replaceDeviceInGroup(): An error occurred while replacing lun '$lun' with ". - " device '$newDevice' in group '$group'. See dmesg/kernel log for more information."; - } - - return $rc; -} - -sub assignDeviceToHandler { - my $self = shift; - my $device = shift; - my $handler = shift; - my $handler_io = $_IO_MAP_{$handler}; - my $handler_name = $_REVERSE_MAP_{$handler}; - - if (!$handler_io) { - $self->{'error'} = "assignDeviceToHandler(): Failed to open handler IO '$handler_io' or ". - "handler '$handler_name' ($handler) invalid"; - return 1; - } - - if (!$self->handlerExists($handler)) { - $self->{'error'} = "assignDeviceToHandler(): Handler '$handler_name' ($handler) does not exist"; - return 1; - } - - if ($self->handlerDeviceExists($handler, $device)) { - $self->{'error'} = "assignDeviceToHandler(): Device '$device' is already assigned". - " to handler '$handler_name' ($handler)"; - return 2; - } - - my $cmd = "assign $device $handler_name\n"; - - my $rc = $self->scst_private($cmd); - - return 0 if ($self->{'debug'}); - return $rc if($rc); - - $rc = !$self->handlerDeviceExists($handler, $device); - - if ($rc) { - $self->{'error'} = "assignDeviceToHandler(): An error occurred while assigning device '$device' ". - "to handler '$handler_name' ($handler). See dmesg/kernel log for more information."; - } - - return $rc; -} - -sub removeDeviceFromGroup { - my $self = shift; - my $device = shift; - my $group = shift; - - if (!$self->groupExists($group)) { - $self->{'error'} = "removeDeviceFromGroup(): Group '$group' does not exist"; - return 1; - } - - if (!$self->groupDeviceExists($device, $group)) { - $self->{'error'} = "removeDeviceFromGroup(): Device '$device' does not exist in group '$group'"; - return 2; - } - - my $cmd = "del $device\n"; - - my $rc = $self->group_private($group, $_SCST_DEVICES_IO_, $cmd); - - return 0 if ($self->{'debug'}); - return $rc if ($rc); - - $rc = $self->groupDeviceExists($device, $group); - - if ($rc) { - $self->{'error'} = "removeDeviceFromGroup(): An error occurred while removing device '$device' ". - "from group '$group'. See dmesg/kernel log for more information."; - } - - return $rc; -} - -sub clearGroupDevices { - my $self = shift; - my $group = shift; - - return 1 if (!$self->groupExists($group)); - - my $cmd = "clear\n"; - - my $rc = $self->group_private($group, $_SCST_DEVICES_IO_, $cmd); - - return 0 if ($self->{'debug'}); - - if ($rc) { - $self->{'error'} = "clearGroupDevices(): An error occurred while clearing devices from ". - "group '$group'. See dmesg/kernel log for more information."; - return $rc; - } - - my $devices = $self->groupDevices($group); - - return (keys %{$devices}); -} - -sub handler_private { - my $self = shift; - my $handler_io = shift; - my $cmd = shift; - - my $io = new IO::File $handler_io, O_WRONLY; - - if (!$io) { - cluck("WARNING: SCST/SCST.pm: Failed to open handler IO $handler_io, assuming disabled"); - return 0; - } - - if ($self->{'debug'}) { - print "DBG($$): '$handler_io' -> '$cmd'\n"; - } else { - print $io "$cmd\0"; - } - - close $io; - - return 0; -} - -sub scst_private { - my $self = shift; - my $cmd = shift; - - my $io = new IO::File $_SCST_IO_, O_WRONLY; - - if (!$io) { - $self->{'error'} = "SCST/SCST.pm: Failed to open handler IO '$_SCST_IO_'"; - return 1; - } - - if ($self->{'debug'}) { - print "DBG($$): '$_SCST_IO_' -> '$cmd'\n"; - } else { - print $io "$cmd\0"; - } - - close $io; - - return 0; -} - -sub group_private { - my $self = shift; - my $group = shift; - my $file = shift; - my $cmd = shift; - - my $io = new IO::File $_SCST_GROUPS_DIR_."/$group/".$file, O_WRONLY; - - if (!$io) { - $self->{'error'} = "SCST/SCST.pm: Failed to open handler IO '".$_SCST_GROUPS_DIR_."/$group/".$file."'"; - return 1; - } - - if ($self->{'debug'}) { - print "DBG($$): $_SCST_GROUPS_DIR_/$group/$file -> $cmd\n"; - } else { - print $io "$cmd\0"; - } - - close $io; - - return 0; -} - -sub checkOptions { - my $self = shift; - my $options = shift; - my $type = shift; - my $o_string; - my $b_string; - my $bad = 0; - - return undef, 1 if (!$options || !$type); - - my $_options_ = $_OPTIONS_BY_TYPE_{$type}; - - foreach my $option (split(/[\s+|\,]/, $options)) { - my $map = $$_options_{$option}; - - if (!$map) { - $bad = 1; - $b_string .= ",$option"; - } else { - $o_string .= ",$map"; - } - } - - if ($bad) { - $b_string =~ s/^\,//; - return $b_string, 0; - } - - $o_string =~ s/^\,//; - - return $o_string, 1; -} - -sub errorString { - my $self = shift; - - return undef if (!$self->{'error'}); - - my $string = $self->{'error'}; - $self->{'error'} = undef; - - return $string; -} - -sub cleanupString { - my $string = shift; - - $string =~ s/^\s+//; - $string =~ s/\s+$//; - - return $string; -} - -;1 __END__ - -=head1 NAME - -SCST::SCST - Generic SCST methods. - -=head1 SYNOPSIS - - use SCST::SCST; - - $p = SCST::SCST->new(); - - print "Using SCST version".$p->scstVersion()."\n"; - - if ($p->handlerDeviceExists($SCST::SCST::VDISK_TYPE)) { - print "openDevice() failed\n" - if ($p->openDevice($SCST::SCST::VDISK_TYPE, 'DISK01', '/vdisk/disk01.dsk')); - } - - undef $p; - -=head1 DESCRIPTION - -Generic SCST methods. - -=head2 Methods - -=over 5 - -=item SCST::SCST->new(); - -Create a new SCST object. If the argument $debug is non-zero no changes -will be made. - -Arguments: (bool) $debug - -Returns: (object) $new - -=item SCST::SCST->scstVersion(); - -Returns the version of SCST running. - -Arguments: void - -Returns: (string) $version - -=item SCST::SCST->groups(); - -Returns a list of security groups configured. - -Arguments: void - -Returns: (array ref) $groups - -=item SCST::SCST->groupExists(); - -Checks for a specified group's existance. - -Arguments: (string) $group - -Returns: (boolean) $groupExists - -=item SCST::SCST->addGroup(); - -Adds a security group to SCST's configuration. Returns 0 upon success, 1 if -unsuccessful and 2 if the group already exists. - -Arguments: (string) $group - -Returns: (int) $success - -=item SCST::SCST->removeGroup(); - -Removes a group from SCST's configuration. Returns 0 upon success, 1 if -unsuccessful and 2 if group does not exist. - -=item SCST::SCST->renameGroup(); - -Renames an already existing group. Returns 0 upon success, 1 if unsuccessful -or 2 if the new group name already exists. - -=item SCST::SCST->sgvStats(); - -Returns a hash of stats gathered from /proc/scsi_tgt/sgv. - -Arguments: void - -Returns: (hash ref) $stats - -Hash Layout: See /proc/scsi_tgt/sgv for tokens. This methods simply hashes -what's found there and returns it with no further processing. - -=item SCST::SCST->sessions(); - -Returns a hash of current SCST initiator sessions. - -Arguments: void - -Returns: (hash ref) $sessions - -Hash Layout: See /proc/scsi_tgt/sessions for tokens. This methods simply hashes -what's found there and returns it with no further processing. - -=item SCST::SCST->devices(); - -Returns a hash of devices configured without regard to device handler. - -Arguments: void - -Returns: (hash ref) $devices - -Hash Layout: (string) $device = (int) $handler - -=item SCST::SCST->handlerDevices(); - -Returns a hash of devices configured for a specified device handler. - -Arguments: (int) $handler - -Returns: (hash ref) $devices - -Hash Layout: (string) $device -> SIZE = (int) $deviceSize - (string) $device -> PATH = (string) $devicePath - (string) $device -> OPTIONS = (string) $options (comma seperated) - -=item SCST::SCST->handlerDeviceExists(); - -Checks for a specified device is configured for a specified device handler. - -Arguments: (int) $handler, (string) $device - -Returns: (boolean) $deviceExists - -=item SCST::SCST->handlerType(); - -Return the handler type for the specified handler. Handler types are: - - SCST::SCST::IOTYPE_PHYSICAL - SCST::SCST::IOTYPE_VIRTUAL - SCST::SCST::IOTYPE_PERFORMANCE - -Arguments: (int) $handler - -Returns: (int) $handler_type - -=item SCST::SCST->openDevice(); - -Opens an already existing specified device for the specified device handler. -Returns 0 upon success, 1 if unsuccessful and 2 if the device already exists. - -Available options for the parameter $options are: WRITE_THROUGH, READ_ONLY, O_DIRECT - -Arguments: (int) $handler, (string) $device, (string) $path [, (string) $options] - -Returns: (int) $success - -=item SCST::SCST->closeDevice(); - -Closes an open device configured for the specified device handler. Returns -0 upon success, 1 if unsuccessful and 2 of the device does not exist. - -Arguments: (int) $handler, (string) $device, (string) $path - -Returns: (int) $success - -=item SCST::SCST->setT10DeviceId(); - -Changes the T10 device ID for the specified device and handler. Returns -0 upon success, 1 if unsuccessful and 2 of the device does not exist. - -Arguments: (int) $handler, (string) $device, (string) $t10_dev_id - -Returns: (int) $success - -=item SCST::SCST->userExists(); - -Checks for a specified user with the specified security group. - -Arguments: (string) $user, (string) $group - -Returns (boolean) $userExists - -=item SCST::SCST->users(); - -Returns a list of users configured for a given security group. - -Arguments: (string) $group - -Returns: (hash ref) $users - -=item SCST::SCST->addUser(); - -Adds the specified user to the specified security group. Returns 0 -upon success, 1 if unsuccessful and 2 if the user already exists. - -Arguments: (string) $user, (string) $group - -Returns: (int) $success - -=item SCST::SCST->removeUser(); - -Removed the specified user from the specified security group. Returns -0 upon success, 1 if unsuccessful and 2 if the user does not exist. - -Arguments: (string) $user, (string) $group - -Returns: (int) $success - -=item SCST::SCST->moveUser(); - -Moves a user from one group to another. Both groups must be defined -and user must already exist in the first group. Returns 0 upon -success, 1 if unsuccessful and 2 if the user already exists in the -second group. - -Arguments: (string) $user, (string) $fromGroup, (string) $toGroup - -Returns: (int) $success - -=item SCST::SCST->clearUsers(); - -Removes all users from the specified security group. Returns 0 upon -success or 1 if unsuccessful. - -Arguments: (string) $group - -Returns: (int) $success - -=item SCST::SCST->handlerExists(); - -Checks if a specified device handler exists within SCST's configuration. - -Arguments: (int) $handler - -Returns: (boolean) $handlerExists - -=item SCST::SCST->handlers(); - -Returns a list of configured device handlers. - -Arguments: void - -Returns: (array ref) $handlers - -=item SCST::SCST->groupDeviceExists(); - -Checks if a specified device is assigned to a specified security group. -If the optional $lun argument is specified, this method also matches -the lun. - -Arguments: (string) $device, (string) $group [, (int) $lun] - -Returns: (boolean) $deviceExists - -=item SCST::SCST->groupDevices(); - -Returns a hash if devices assigned to the specified security group. - -Arguments: (string) $group - -Returns: (hash ref) $devices - -Hash Layout: (string) $device = (int) $lun - -=item SCST::SCST->assignDeviceToGroup(); - -Assigns the specified device to the specified security group. Returns -0 upon success, 1 if unsuccessful and 2 if the device has already -been assigned to the specified security group. - -Arguments: (string) $device, (string) $group, (int) $lun [, (string) $options] - -Returns: (int) $success - -=item SCST::SCST->replaceDeviceInGroup(); - -Replaces an already assigned device to the specified lun in a -specified security group with $newDevice. Returns 0 upon success, 1 -if unsuccessful and 2 if the device has already been assigned to -the specified security group. - -Arguments: (string) $newDevice, (string) $group, (int) $lun [, (string) $options] - -Returns (int) $success - -=item SCST::SCST->assignDeviceToHandler(); - -Assigns specified device to specified handler. Returns 0 upon success, -1 if unsuccessful and 2 if the specified device is already assigned to -the specified handler. - -Arguments: (string) $device, (string) $handler - -Returns: (int) $success - -=item SCST::SCST->removeDeviceFromGroup(); - -Removes the specified device from the specified security group. Returns -0 upon success, 1 if unsuccessful and 2 if the device has not been -assigned to the specified security group. - -Arguments: (string) $device, (string) $group - -Returns: (int) $success - -=item SCST::SCST->clearGroupDevices(); - -Removes all devices from the specified security group. Returns 0 upon -success or 1 if unsuccessful. - -Arguments: (string) $group - -Returns: (int) $success - -=item SCST::SCST->errorString(); - -Contains a description of the last error occurred or undef if no error -has occurred or if this method has already been called once since the -last error. - -Arguments: (void) - -Returns: (string) $error_string - -=back - -=head1 WARNING - -None at this time. - -=head1 NOTES - -If the $debug parameter is specified on package new(), no actions are -performed. Rather they are printed to STDOUT and 0 is returned. - -Available Device Handlers: - -CDROM_TYPE, -CHANGER_TYPE, -DISK_TYPE, -VDISK_TYPE, -VCDROM_TYPE, -DISKPERF_TYPE, -MODISK_TYPE, -MODISKPERF_TYPE, -TAPE_TYPE, -TAPEPERF_TYPE - -To specify a device handler to a method, use the following syntax: - -$SCST::SCST:: - -For example: - -$SCST::SCST::MODISK_TYPE - -=cut diff --git a/scstadmin/scstadmin.procfs/scstadmin b/scstadmin/scstadmin.procfs/scstadmin deleted file mode 100755 index f5c4181f0..000000000 --- a/scstadmin/scstadmin.procfs/scstadmin +++ /dev/null @@ -1,2058 +0,0 @@ -#!/usr/bin/perl -$Version = 'SCST Configurator v1.0.11'; - -# Configures SCST -# -# Author: Mark R. Buechler -# License: GPLv2 -# Copyright (c) 2005-2009 Mark R. Buechler - -sub usage - { - die <<"EndUsage"; -$Version - -Usage: -General Operations - -config : Configure SCST given the specified configuration file. - -ClearConfig : Clear all SCST configuration. - -WriteConfig : Writes the current configuration out to the specified file. - -checkConfig : Checks the saved configuration in the specified file. - -sessions : List current initiator sessions. - -Target Driver Operations - -enable : Enable target mode for driver at specified WWN or host. - -disable : Disable target mode for driver at specified WWN or host. - -issuelip : Issue LIP on all target-enabled FC fabrics. - -Device Operations - -adddev : Adds a device to a handler. - -handler - -path - -options - -blocksize - -resyncdev : Resync the size of a device with the initiator(s). - -handler - -RemoveDev : Remove a device from a handler. - -handler - -SetT10DeviceId : Sets the T10 Device ID of a device. - -device - -handler - -User Operations - -adduser : Adds a user to a security group. - -group - -MoveUser : Moves a user from one security group to another. - -group - -to - -RemoveUser : Delete a user from a security group. - -group - -ClearUsers : Clear all users from a given security group. - -group - -Group Operations - -addgroup : Add a given group to available security groups. - -renamegroup : Renames a give group to a new name. - -to - -RemoveGroup : Remove a give group from available security groups. - -Assignment Operations - -assigndev : Assign a given device to a security group. - -group - -lun - -options - -ReplaceDev : Replaces a device assigned to a give LUN and group. - -group - -lun - -options - -ReleaseDev : Remove a given device from a security group. - -group - -ClearDevs : Clear all device assignments for a security group. - -group - -Options - -ForceConfig : Force all configuration changes, even deletions (DANGER!). - -noprompt : Do not prompt or pause. Use with caution! - -Debugging (limited support) - -debug : Debug mode - don\'t do anything destructive. - -Available Handlers: - disk, vdisk, disk_perf, cdrom, vcdrom, changer, modisk, modisk_perf, tape, tape_perf - -Available Options for create and open: - WRITE_THROUGH, READ_ONLY, O_DIRECT, NULLIO, NV_CACHE, BLOCK_IO, REMOVABLE - -Available Options for assign and replace: - READ_ONLY - -Examples: - Enable target mode for fibre card specifying its WWN - scstadmin -enable 50:06:0B:00:00:39:71:78 - - Disable target mode for SCSI host specifying host number - scstadmin -disable host4 - - Create a new security group: - scstadmin -addgroup HOST01 - - Create a device given an already existing disk file: - scstadmin -adddev DISK01 -handler vdisk -path /vdisks/disk01.dsk -options READ_ONLY,WRITE_THROUGH - - Setting the T10 Device ID of a device - scstadmin -SetT10DeviceId test_disk -device disk1 -handler vdisk - - Assign a device to a security group: - scstadmin -assigndev DISK01 -group HOST01 -lun 1 - - Rename a security group: - scstadmin -RenameGroup HOST01 -to SERVER01 - - Tell all initiators to rescan LUNs: - scstadmin -issuelip - -EndUsage - } - -use SCST::SCST 0.8.22; -use Getopt::Long; -use IO::File; -use IO::Dir; -use POSIX; -use strict; - -my $_DEF_CONFIG_ = '/etc/scst.conf'; - -my $TRUE = 1; -my $FALSE = 0; - -my $_MAX_LUNS_ = 255; -my $_DEFAULT_GROUP_ = 'Default'; - -my $_SCSI_CLASS_ = '/sys/class/scsi_host'; -my $_FC_CLASS_ = '/sys/class/fc_host'; -my $_SCSI_ISP_ = '/proc/scsi/isp'; -my $_SCSITGT_QLAISP_ = '/proc/scsi_tgt/qla_isp'; - -my $_TGT_DEF_PREFIX_ = 'Default_'; -my $_TGT_TMP_PREFIX_ = 'TMP_GRP'; - -my $SCST; -my $DEVICES; -my $TARGETS; -my %USERS; -my %ASSIGNMENTS; -my %HANDLERS; -my %GROUPS; -my $_DEBUG_; - -my %_HANDLER_MAP_ = ('cdrom' => $SCST::SCST::CDROM_TYPE, - 'changer' => $SCST::SCST::CHANGER_TYPE, - 'disk' => $SCST::SCST::DISK_TYPE, - 'vdisk' => $SCST::SCST::VDISK_TYPE, - 'vcdrom' => $SCST::SCST::VCDROM_TYPE, - 'disk_perf' => $SCST::SCST::DISKPERF_TYPE, - 'modisk' => $SCST::SCST::MODISK_TYPE, - 'modisk_perf' => $SCST::SCST::MODISKPERF_TYPE, - 'tape' => $SCST::SCST::TAPE_TYPE, - 'tape_perf' => $SCST::SCST::TAPEPERF_TYPE, - 'processor' => $SCST::SCST::PROCESSOR_TYPE, - # Add in the dev_ names as well - 'dev_cdrom' => $SCST::SCST::CDROM_TYPE, - 'dev_changer' => $SCST::SCST::CHANGER_TYPE, - 'dev_disk' => $SCST::SCST::DISK_TYPE, - 'dev_disk_perf' => $SCST::SCST::DISKPERF_TYPE, - 'dev_modisk' => $SCST::SCST::MODISK_TYPE, - 'dev_modisk_perf' => $SCST::SCST::MODISKPERF_TYPE, - 'dev_tape' => $SCST::SCST::TAPE_TYPE, - 'dev_tape_perf' => $SCST::SCST::TAPEPERF_TYPE, - 'dev_processor' => $SCST::SCST::PROCESSOR_TYPE); - -my %_REVERSE_MAP_ = ($SCST::SCST::CDROM_TYPE => 'cdrom', - $SCST::SCST::CHANGER_TYPE => 'changer', - $SCST::SCST::DISK_TYPE => 'disk', - $SCST::SCST::VDISK_TYPE => 'vdisk', - $SCST::SCST::VCDROM_TYPE => 'vcdrom', - $SCST::SCST::DISKPERF_TYPE => 'disk_perf', - $SCST::SCST::MODISK_TYPE => 'modisk', - $SCST::SCST::MODISKPERF_TYPE => 'modisk_perf', - $SCST::SCST::TAPE_TYPE => 'tape', - $SCST::SCST::TAPEPERF_TYPE => 'tape_perf', - $SCST::SCST::PROCESSOR_TYPE => 'processor'); - -my %_HANDLER_TYPE_MAP_ = ($SCST::SCST::IOTYPE_PHYSICAL => 'physical', - $SCST::SCST::IOTYPE_VIRTUAL => 'virtual', - $SCST::SCST::IOTYPE_PERFORMANCE => 'performance'); - -$SIG{INT} = \&commitSuicide; - -use vars qw($Version); - -POSIX::setsid(); - -&main(); - -sub getArgs { - my $applyConfig; - my $forceConfig; - my $clearConfig; - my $writeConfig; - my $checkConfig; - my $showSessions; - my $addDev; - my $devPath; - my $resyncDev; - my $replaceDev; - my $removeDev; - my $sett10id; - my $addUser; - my $moveUser; - my $removeUser; - my $clearUsers; - my $addGroup; - my $toGroup; - my $renameGroup; - my $removeGroup; - my $assignDev; - my $replaceDev; - my $releaseDev; - my $clearDevs; - my $devLun; - my $handler; - my $device; - my $group; - my $options; - my $blocksize; - my $enable; - my $disable; - my $issuelip; - my $noprompt; - - my $p = new Getopt::Long::Parser; - - if (!$p->getoptions('config:s' => \$applyConfig, - 'ClearConfig' => \$clearConfig, - 'ForceConfig' => \$forceConfig, - 'WriteConfig=s' => \$writeConfig, - 'checkConfig=s' => \$checkConfig, - 'sessions' => \$showSessions, - 'adddev=s' => \$addDev, - 'path=s' => \$devPath, - 'ReplaceDev=s' => \$replaceDev, - 'RemoveDev=s' => \$removeDev, - 'SetT10DeviceId=s' => \$sett10id, - 'lun=s' => \$devLun, - 'adduser=s' => \$addUser, - 'MoveUser=s' => \$moveUser, - 'RemoveUser=s' => \$removeUser, - 'ClearUsers' => \$clearUsers, - 'addgroup=s' => \$addGroup, - 'to=s' => \$toGroup, - 'RemoveGroup=s' => \$removeGroup, - 'renamegroup=s' => \$renameGroup, - 'assigndev=s' => \$assignDev, - 'resyncdev=s' => \$resyncDev, - 'ReleaseDev=s' => \$releaseDev, - 'ClearDevs' => \$clearDevs, - 'handler=s' => \$handler, - 'device=s' => \$device, - 'group=s' => \$group, - 'options=s' => \$options, - 'blocksize=s' => \$blocksize, - 'enable=s' => \$enable, - 'disable=s' => \$disable, - 'issuelip' => \$issuelip, - 'noprompt' => \$noprompt, - 'debug' => \$_DEBUG_)) { - &usage(); - } - - if ((defined($enable) && !$enable) || (defined($disable) && !$disable)) { - print "Argument -enable/-disable requires a WWN or host.\n\n"; - usage(); - } - - if (defined($issuelip) && ($enable || $disable)) { - print "Argument -issuelip cannot be used with -enable or -disable.\n\n"; - usage(); - } - - if ($handler && !$_HANDLER_MAP_{$handler}) { - print "Invalid handler '$handler' specified. Available handlers are:\n\n"; - foreach my $_handler (keys %_HANDLER_MAP_) { - print "\t$_handler\n"; - } - print "\n"; - exit 1; - } - - if ($addDev && !($handler && $devPath)) { - print "Please specify -handler and -path with -adddev.\n\n"; - usage(); - } - - if (defined($blocksize) && !$blocksize) { - print "Please specify bytes with -blocksize.\n\n"; - usage(); - } - - if ($blocksize && !$addDev) { - print "Please specify -adddev with -blocksize.\n"; - usage(); - } - - if (defined($forceConfig) && !defined($applyConfig)) { - print "Please specify -config with -ForceConfig.\n\n"; - usage(); - } - - if ($resyncDev && !$handler) { - print "Please specify -handler with -resyncdev.\n\n"; - usage(); - } - - if ($removeDev && !$handler) { - print "Please specify -handler with -RemoveDev.\n\n"; - usage(); - } - - if ($addUser && !defined($group)) { - print "Please specify -group with -adduser.\n\n"; - usage(); - } - - if ($moveUser && (!defined($group) || !defined($toGroup))) { - print "Please specify -group and -to with -MoveUser.\n\n"; - usage(); - } - - if ($removeUser && !defined($group)) { - print "Please specify -group with -RemoveUser.\n\n"; - usage(); - } - - if ($clearUsers && !defined($group)) { - print "Please specify -group with -ClearUsers.\n\n"; - usage(); - } - - if ($renameGroup && !defined($toGroup)) { - print "Please specify -to with -renamegroup.\n\n"; - usage(); - } - - if ($assignDev && !defined($group)) { - print "Please specify -group with -assigndev.\n\n"; - usage(); - } - - if ($replaceDev && (!defined($group) || !defined($devLun))) { - print "Please specify -group and -lun with -ReplaceDev.\n\n"; - usage(); - } - - if ($releaseDev && !defined($group)) { - print "Please specify -group with -ReleaseDev.\n\n"; - usage(); - } - - if ($sett10id && (!$device || !$handler)) { - print "Please specify -device and -handler with -SetT10DeviceId.\n\n"; - usage(); - } - - if ($clearDevs && !defined($group)) { - print "Please specify -group with -ClearDevs.\n\n"; - usage(); - } - - if (defined($writeConfig) && !$writeConfig) { - print "Please specify a file name to write configuration to..\n\n"; - usage(); - } - - $_DEBUG_ = $TRUE if (defined($_DEBUG_)); - - $forceConfig = $TRUE if (defined($forceConfig)); - $showSessions = $TRUE if (defined($showSessions)); - $issuelip = $TRUE if (defined($issuelip)); - $noprompt = $TRUE if (defined($noprompt)); - - $enable =~ tr/A-Z/a-z/; $disable =~ tr/A-Z/a-z/; - $options =~ tr/a-z/A-Z/ if ($options); - - if ((defined($showSessions) + defined($addDev) + defined($resyncDev) + - defined($removeDev)+ defined($addUser) + defined($enable) + defined($disable) + - defined($removeUser) + defined($clearUsers) + defined($assignDev) + - defined($releaseDev) + defined($clearDevs) + defined($applyConfig) + - defined($clearConfig) + defined($writeConfig) + defined($checkConfig) + - defined($sett10id)) > 1) { - print "Please specify only one operation at a time.\n"; - usage(); - } - - $applyConfig = $_DEF_CONFIG_ if (defined($applyConfig) && !$applyConfig); - $checkConfig = $_DEF_CONFIG_ if (defined($checkConfig) && !$checkConfig); - - return ($enable, $disable, $issuelip, $addDev, $devPath, $devLun, $resyncDev, $removeDev, $addUser, - $moveUser, $removeUser, $clearUsers, $addGroup, $renameGroup, $toGroup, $removeGroup, - $assignDev, $replaceDev, $releaseDev, $sett10id, $clearDevs, $handler, $device, $group, - $options, $blocksize, $applyConfig, $forceConfig, $clearConfig, $writeConfig, $checkConfig, - $showSessions, $noprompt); -} - -sub main { - my $rc; - - STDOUT->autoflush(1); - - # We need to run as root - if ( $> ) {die("This program must run as root.\n");} - - my ($enable, $disable, $issuelip, $addDev, $devPath, $devLun, $resyncDev, $removeDev, $addUser, - $moveUser, $removeUser, $clearUsers, $addGroup, $renameGroup, $toGroup, $removeGroup, - $assignDev, $replaceDev, $releaseDev, $sett10id, $clearDevs, $handler, $device, $group, - $options, $blocksize, $applyConfig, $forceConfig, $clearConfig, $writeConfig, $checkConfig, - $showSessions, $noprompt) = getArgs(); - - $SCST = new SCST::SCST($_DEBUG_); - - readWorkingConfig(); - - SWITCH: { - $applyConfig && do { - if ($forceConfig) { - $rc = applyConfiguration($applyConfig, $TRUE, $TRUE); - die("Configuration errors found, aborting.\n") if ($rc); - - if (!$noprompt) { - print "\nConfiguration will apply in 10 seconds, type ctrl-c to abort..\n"; - sleep 10; - } - } - - readWorkingConfig(); - $rc = applyConfiguration($applyConfig, $forceConfig, $FALSE); - last SWITCH; - }; - $checkConfig && do { - $rc = applyConfiguration($checkConfig, $FALSE, $TRUE); - last SWITCH; - }; - $writeConfig && do { - $rc = writeConfiguration($writeConfig); - last SWITCH; - }; - $showSessions && do { - $rc = showSessions(); - last SWITCH; - }; - defined($clearConfig) && do { - $rc = clearConfiguration($noprompt); - last SWITCH; - }; - $addDev && do { - $rc = addDevice($handler, $addDev, $devPath, $options, $blocksize); - last SWITCH; - }; - $resyncDev && do { - $rc = resyncDevice($handler, $resyncDev); - last SWITCH; - }; - $removeDev && do { - $rc = removeDevice($handler, $removeDev); - last SWITCH; - }; - $sett10id && do { - $rc = setT10DeviceId($handler, $device, $sett10id); - last SWITCH; - }; - $addUser && do { - $rc = addUser($group, $addUser); - last SWITCH; - }; - $moveUser && do { - $rc = moveUser($group, $moveUser, $toGroup); - last SWITCH; - }; - $removeUser && do { - $rc = removeUser($group, $removeUser); - last SWITCH; - }; - defined($clearUsers) && do { - $rc = clearUsers($group); - last SWITCH; - }; - $addGroup && do { - $rc = addGroup($addGroup); - last SWITCH; - }; - $renameGroup && do { - $rc = renameGroup($renameGroup, $toGroup); - last SWITCH; - }; - $removeGroup && do { - $rc = removeGroup($removeGroup); - last SWITCH; - }; - $assignDev && do { - $rc = assignDevice($group, $assignDev, $devLun, $options); - last SWITCH; - }; - $replaceDev && do { - $rc = replaceDevice($group, $replaceDev, $devLun, $options); - last SWITCH; - }; - $releaseDev && do { - $rc = releaseDevice($group, $releaseDev); - last SWITCH; - }; - defined($clearDevs) && do { - $rc = clearDevices($group); - last SWITCH; - }; - $enable && do { - $enable = unformatTarget($enable); - $rc = enableTarget($enable, $TRUE); - last SWITCH; - }; - $disable && do { - $disable = unformatTarget($disable); - $rc = enableTarget($disable, $FALSE); - last SWITCH; - }; - $issuelip && do { - $rc = issueLIP(); - last SWITCH; - }; - - print "No valid operations specified.\n"; - usage(); - exit $TRUE; - } - - print "\nAll done.\n"; - - exit $rc; -} - -sub readWorkingConfig { - my %empty; - - print "Collecting current configuration: "; - - $TARGETS = undef; - $DEVICES = undef; - %HANDLERS = (); - %GROUPS = (); - %USERS = (); - - my $eHandlers = $SCST->handlers(); - - immediateExit($SCST->errorString()); - - foreach my $handler (@{$eHandlers}) { - $HANDLERS{$handler}++; # For quick lookups - } - - $TARGETS = targets(); - - $DEVICES = $SCST->devices(); - immediateExit($SCST->errorString()); - - my $_eGroups = $SCST->groups(); - immediateExit($SCST->errorString()); - - foreach my $group (@{$_eGroups}) { - $GROUPS{$group}++; - $ASSIGNMENTS{$group} = $SCST->groupDevices($group); - my $eUsers = $SCST->users($group); - - foreach my $user (@{$eUsers}) { - $USERS{$group}->{$user}++; # For quick lookups - } - $USERS{$group} = \%empty if (!$USERS{$group}); - } - - print "done.\n\n"; -} - -sub writeConfiguration { - my $file = shift; - my $keep_config; - - my $config = readConfig($file, $TRUE); - - if (-f $file) { - if (!unlink $file) { - print "Failed to save current configuration, specified ". - "file exists and cannot be deleted.\n"; - return 1; - } - } - - my $io = new IO::File $file, O_CREAT|O_WRONLY; - - if (!$io) { - print "Failed to save configuration to file '$file': $!\n"; - return 1; - } - - print "Writing current configuration to file '$file'.. "; - - print $io "# Automatically generated by $Version.\n\n"; - - print $io "# NOTE: Options are pipe (|) seperated.\n\n"; - - print $io "[OPTIONS]\n"; - print $io "#OPTION <1|0|YES|NO|TRUE|FALSE|VALUE>\n"; - print $io "# Copy configuration options during a -writeconfig\n"; - print $io "KEEP_CONFIG "; - - if (defined($config)) { - $keep_config = $$config{'OPTIONS'}->{'default'}->{'KEEP_CONFIG'}[0]; - } else { - $keep_config = $FALSE; - } - - if (!defined($config)) { - print $io "TRUE\n"; - } elsif (!$keep_config ) { - print $io "FALSE\n"; - } else { - print $io "TRUE\n"; - } - - print $io "# For FC targets, issue a LIP after every assignment change\n"; - print $io "ISSUE_LIP "; - - if (!$keep_config) { - print $io "FALSE\n"; - } else { - print $io ($$config{'OPTIONS'}->{'default'}->{'ISSUE_LIP'}[0] ? "TRUE\n" : "FALSE\n"); - } - - print $io "\n"; - - # Device information - foreach my $handler (sort keys %HANDLERS) { - if ($SCST->handlerType($handler) == $SCST::SCST::IOTYPE_VIRTUAL) { - print $io "[HANDLER ".$_REVERSE_MAP_{$handler}."]\n"; - print $io "#DEVICE ,"; - if ($handler == $SCST::SCST::VDISK_TYPE) { - print $io ",,,\n"; - } else { - print $io "\n"; - } - - my $devices = $SCST->handlerDevices($handler); - - immediateExit($SCST->errorString()); - - foreach my $device (sort keys %{$devices}) { - my $options = $$devices{$device}->{'OPTIONS'}; - - $options =~ s/\,/\|/g; - - print $io "DEVICE $device,".$$devices{$device}->{'PATH'}; - print $io ",$options"; - print $io ",".$$devices{$device}->{'BLOCKSIZE'}; - print $io ",".$$devices{$device}->{'T10_DEVICE_ID'}; - print $io "\n"; - } - - print $io "\n"; - } - } - - # User configuration - foreach my $group (sort keys %USERS) { - print $io "[GROUP $group]\n"; - print $io "#USER \n"; - - foreach my $user (keys %{$USERS{$group}}) { - print $io "USER $user\n"; - } - - print $io "\n"; - } - - # Assignments configuration - foreach my $group (sort keys %ASSIGNMENTS) { - print $io "[ASSIGNMENT $group]\n"; - print $io "#DEVICE ,,\n"; - - my $pointer = $ASSIGNMENTS{$group}; - foreach my $device (sort keys %{$pointer}) { - print $io "DEVICE $device,".$$pointer{$device}."\n"; - } - - print $io "\n"; - } - - # Targets configuration - foreach my $type ('enable', 'disable') { - print $io "[TARGETS $type]\n"; - print $io "#HOST \n"; - - foreach my $target (sort keys %{$TARGETS}) { - if ((($type eq 'enable') && $$TARGETS{$target}->{'enabled'}) || - (($type eq 'disable') && !$$TARGETS{$target}->{'enabled'})) { - my $f_target = formatTarget($target); - print $io "HOST $f_target\n" if (!$$TARGETS{$target}->{'duplicate'}); - } - } - - print $io "\n"; - } - - print "done\n"; - - close $io; - - return 0; -} - -sub applyConfiguration { - my $confile = shift; - my $force = shift; - my $check = shift; - my $config = readConfig($confile); - my $errs; - my $changes = 0; - - my $assign_changes = 0; - my $targets_changed = $FALSE; - - my %used_devs; - my %used_users; - my %used_assignments; - my %empty; - - my %seen_users; - - my %rename_group; - - my $issue_lip = $$config{'OPTIONS'}->{'default'}->{'ISSUE_LIP'}[0]; - - # Cache device/handler configuration - foreach my $entry (keys %{$$config{'HANDLER'}}) { - foreach my $device (@{$$config{'HANDLER'}->{$entry}->{'DEVICE'}}) { - my($vname, undef) = split(/\,/, $device, 2); - $vname = cleanupString($vname); - $used_devs{$vname} = $entry; - } - } - - # Cache user/group configuration - foreach my $group (keys %{$$config{'GROUP'}}) { - foreach my $user (@{$$config{'GROUP'}->{$group}->{'USER'}}) { - if (defined($seen_users{$user})) { - print "\t-> FATAL: Configuration invalid. User '$user' is in more ". - "than one group!\n"; - exit 1; - } - $used_users{$group}->{$user}++; - $seen_users{$user}++; - } - $used_users{$group} = \%empty if (!$used_users{$group}); - } - - # Cache device association configuration - foreach my $group (keys %{$$config{'ASSIGNMENT'}}) { - my %seen_luns; - - foreach my $device (@{$$config{'ASSIGNMENT'}->{$group}->{'DEVICE'}}) { - my($vname, $arg) = split(/\,/, $device, 2); - $vname = cleanupString($vname); - my($lun, $options) = split(/\,/, $arg); - if ($seen_luns{$lun}) { - print "\t-> FATAL: Configuration invalid. Group '$group' has multiple ". - "devices assigned to LUN $lun.\n"; - exit 1; - } - $used_assignments{$group}->{$vname} = $arg; - $seen_luns{$lun}++; - } - } - - # If -ForceConfig is used, check for configurations which we've deleted but are still active. - if ($force || $check) { - # Associations - foreach my $group (sort keys %ASSIGNMENTS) { - if (!defined($used_assignments{$group}) && (keys %{$ASSIGNMENTS{$group}})) { - print "\t-> WARNING: Group '$group' has no associations in saved configuration"; - - if (!$check) { - print ", clearing all associations.\n"; - if (clearDevices($group)) { - $errs++; - } else { - $changes++; - $assign_changes++; - } - } else { - print ".\n"; - $changes++; - } - } else { - my $_assignments = $ASSIGNMENTS{$group}; - - foreach my $device (sort keys %{$_assignments}) { - if (!defined($used_assignments{$group}->{$device}) || - ($$_assignments{$device} != $used_assignments{$group}->{$device})) { - if (defined($used_assignments{$group}->{$device}) && - ($$_assignments{$device} != $used_assignments{$group}->{$device})) { - print "\t-> WARNING: Device '$device' assigned to group '$group' ". - "is at LUN ".$used_assignments{$group}->{$device}. - " whereas working configuration reflects LUN ".$$_assignments{$device}; - } else { - print "\t-> WARNING: Device '$device' is not associated with group ". - "'$group' in saved configuration"; - } - - if (!$check) { - my $_lun = $$_assignments{$device}; - my $replace_dev = findAssignedLun($used_assignments{$group}, $_lun); - - if (defined($replace_dev) && ($replace_dev ne $device)) { - print ", replacing with device '$replace_dev'.\n"; - - if (replaceDevice($group, $replace_dev, $_lun)) { - $errs++; - } else { - $changes++; - $assign_changes++; - } - } else { - print ", releasing.\n"; - if (releaseDevice($group, $device)) { - $errs++; - } else { - $changes++; - $assign_changes++; - } - } - } else { - print ".\n"; - $changes++; - } - } - } - } - } - - # Users & Groups - foreach my $group (sort keys %USERS) { - next if ($group eq $_DEFAULT_GROUP_); - if (!defined($used_users{$group})) { - print "\t-> WARNING: Group '$group' does not exist in saved configuration"; - - if (!$check) { - print ", removing.\n"; - if (clearUsers($group)) { - $errs++; - } else { - $changes++; - } - - if (removeGroup($group)) { - $errs++; - } else { - $changes++; - } - } else { - print ".\n"; - $changes++; - } - } else { - foreach my $user (sort keys %{$USERS{$group}}) { - if (!defined($used_users{$group}->{$user})) { - print "\t-> WARNING: User '$user' is not defined as part of group '$group' ". - "in saved configuration"; - - if (!$check) { - # Are we moving this user to another group? - my $new_group = findUserGroup($user, $config); - if ($new_group && ($new_group ne $group)) { - print ", moving to group '$new_group'.\n"; - if (moveUser($group, $user, $new_group)) { - $errs++; - } else { - $changes++; - } - } else { - print ", removing.\n"; - if (removeUser($group, $user)) { - $errs++; - } else { - $changes++; - } - } - } else { - print ".\n"; - $changes++; - } - } - } - } - } - - # Devices - foreach my $device (sort keys %{$DEVICES}) { - if ($$DEVICES{$device} && !defined($used_devs{$device})) { - # Device gone, but is it still assigned to a group? - my $isAssigned = $FALSE; - foreach my $group (sort keys %used_assignments) { - if (defined($used_assignments{$group}->{$device})) { - print "\t-> WARNING: Device '$device' is not defined in saved configuration, ". - "however, it is still assigned to group '$group'! Ignoring removal.\n"; - $isAssigned = $TRUE; - } - } - - if (!$isAssigned && ($SCST->handlerType($$DEVICES{$device}) == $SCST::SCST::IOTYPE_VIRTUAL)) { - print "\t-> WARNING: Device '$device' is not defined in saved configuration"; - - if (!$check) { - print ", removing.\n"; - if (removeDevice($_REVERSE_MAP_{$$DEVICES{$device}}, $device)) { - $errs++; - } else { - $changes++; - } - } else { - print ".\n"; - $changes++; - } - } - } else { - # Handler change - if ($_HANDLER_MAP_{$used_devs{$device}} != $$DEVICES{$device}) { - my $handler = $used_devs{$device}; - - if ($HANDLERS{$_HANDLER_MAP_{$handler}}) { - print "\t-> WARNING: Device '$device' changes handler to '$handler'"; - - if (!$check) { - print ", changing.\n"; - if ($SCST->assignDeviceToHandler($device, - $_HANDLER_MAP_{$handler})) { - $errs++; - } else { - $changes++; - } - } else { - print ".\n"; - $changes++; - } - } - } - } - } - } - - print "\nApplying configuration additions..\n" if (!$check); - print "\n"; - - readWorkingConfig() if ($force); - - foreach my $_handler (sort keys %{$$config{'HANDLER'}}) { - if (!$HANDLERS{$_HANDLER_MAP_{$_handler}}) { - print "\t-> WARNING: Handler '$_handler' does not exist.\n"; - $errs += 1; - next; - } - - foreach my $device (@{$$config{'HANDLER'}->{$_handler}->{'DEVICE'}}) { - my($vname, $path, $options, $blocksize, $t10_id) = split(/\,/, $device); - $path = cleanupString($path); - $options =~ s/\s+//g; - - if (defined($$DEVICES{$vname}) && ($_HANDLER_MAP_{$_handler} == $$DEVICES{$vname})) { - next; - } elsif (defined($$DEVICES{$vname}) && ($_HANDLER_MAP_{$_handler} != $$DEVICES{$vname})) { - if ($HANDLERS{$_HANDLER_MAP_{$_handler}}) { - print "\t-> WARNING: Device '$vname' changes handler from '". - $_REVERSE_MAP_{$$DEVICES{$vname}}."' to '$_handler'.\n". - "\t Use -ForceConfig to change device handler.\n" if (!$force && !$check); - } - next; - } - - if ($check) { - print "\t-> New device '$_handler:$vname' at path '$path', options '$options', ". - "blocksize $blocksize.\n"; - $$DEVICES{$vname} = $_HANDLER_MAP_{$_handler}; - $changes++; - } else { - if (addDevice($_handler, $vname, $path, $options, $blocksize)) { - $errs++; - } else { - $changes++; - } - - if ($t10_id ne '') { - if (setT10DeviceId($_handler, $vname, $t10_id)) { - $errs++; - } else { - $changes++; - } - } - } - } - } - - # Create new groups and add users.. - foreach my $group (keys %used_users) { - if (!defined($USERS{$group})) { - if ($group =~ /^$_TGT_DEF_PREFIX_/) { - my $tmp_group = randomGroup(); - - if (!defined($tmp_group)) { - print "\t-> WARNING: Unable to find a free temporary group for '$group', ". - "using the original group name instead.\n"; - - } else { - print "\t-> Using temporary group '$tmp_group' for group '$group'.\n"; - - $rename_group{$tmp_group} = $group; - $used_users{$tmp_group} = $used_users{$group}; - $group = $tmp_group; - } - } - - if ($check) { - print "\t-> New group definition '$group.'\n"; - $GROUPS{$group}++; - $changes++; - } else { - if (addGroup($group)) { - $errs++; - } else { - $changes++; - } - } - } - - foreach my $user (keys %{$used_users{$group}}) { - if (!defined($USERS{$group}->{$user})) { - my $move_group = findUserGroupInCurrent($user); - if ($move_group) { - print "\t-> WARNING: Use -ForceConfig to move user '$user' ". - "from group '$move_group' to group '$group'.\n" if (!$force); - next; - } - - if ($check) { - print "\t-> New user definition '$user' for group '$group'.\n"; - $USERS{$group}->{$user}++; - $changes++; - } else { - if (addUser($group, $user)) { - $errs++; - } else { - $changes++; - } - } - } - } - } - - # Assign new devices to groups.. - foreach my $group (keys %used_assignments) { - if (!defined($GROUPS{$group})) { - # Looks like we're lacking a group. We'll create an empty one - - print "\t-> WARNING: Auto-creating an empty group '$group' since none was configured.\n"; - - if (addGroup($group)) { - $errs++; - } else { - $changes++; - } - } - - if (!defined($GROUPS{$group})) { - print "\t-> WARNING: Unable to assign to non-existent group '$group'.\n"; - $errs += 1; - next; - } - - foreach my $vname (keys %{$used_assignments{$group}}) { - my $arg = $used_assignments{$group}->{$vname}; - my($lun, $options) = split(/\,/, $arg); - my $_assignments = $ASSIGNMENTS{$group}; - - if (defined($$_assignments{$vname}) && ($$_assignments{$vname} == $lun)) { - next; - } elsif (defined($$_assignments{$vname}) && ($$_assignments{$vname} != $lun)) { - print "\t-> Device '$vname' assigned to group '$group' is at LUN ".$$_assignments{$vname}. - ", whereas the working configuration reflects LUN $lun.\n". - "\t Use -ForceConfig to force this LUN change.\n" if (!$force && !$check); - } else { - my $replace_dev = findAssignedLun($_assignments, $lun); - - if (defined($replace_dev) && ($vname ne $replace_dev)) { - print "\t-> WARNING: Use -ForceConfig to replace device '$replace_dev' ". - "with device '$vname' for group '$group'.\n" if (!$force); - next; - } - - if ($check) { - $lun = 'auto' if (!defined($lun)); - print "\t-> New device assignment for '$vname' to group '$group' at LUN $lun.\n"; - $changes++; - } else { - if (assignDevice($group, $vname, $lun, $options)) { - $errs++; - } else { - $changes++; - $assign_changes++; - } - } - } - } - } - - foreach my $tmp_group (keys %rename_group) { - my $group = $rename_group{$tmp_group}; - print "\t-> Processing temporary group '$tmp_group'.\n"; - - renameGroup($tmp_group, $group); - $changes++; - } - - # Enable/Disable configured targets - foreach my $type (keys %{$$config{'TARGETS'}}) { - my $enable; - - if ($type eq 'enable') { - $enable = $TRUE; - } elsif ($type eq 'disable') { - $enable = $FALSE; - } else { - print "\t-> WARNING: Ignoring invalid TARGETS specifier '$type'. ". - "Should be one of enable, disable.\n"; - next; - } - - foreach my $target (@{$$config{'TARGETS'}->{$type}->{'HOST'}}) { - my $i_target = unformatTarget($target); - - if (!defined($$TARGETS{$i_target})) { - print "\t-> WARNING: Target '$target' not found on system.\n"; - $errs += 1; - next; - } - - next if ($enable == targetEnabled($i_target)); - - if (!$enable && targetEnabled($target)) { - if ($force || $check) { - print "\t-> WARNING: Target mode for '$target' is currently enabled, ". - "however configuration file wants it disabled"; - - if (!$check) { - print ", disabling.\n"; - if (enableTarget($target, $enable)) { - $errs++; - } else { - $changes++; - $targets_changed = $TRUE; - } - } else { - print ".\n"; - $changes++; - } - } - } else { - print "\t-> Target '$target' is enabled in configuration file, ". - "however is currently disabled"; - - if (!$check) { - print ", enabling.\n"; - if (enableTarget($target, $enable)) { - $errs++; - } else { - $changes++; - $targets_changed = $TRUE; - } - } else { - print ".\n"; - $changes++; - } - } - } - } - - if ($issue_lip && $assign_changes && !$targets_changed) { - print "\nMaking initiators aware of assignment changes..\n\n"; - issueLIP(); - } - - print "\n\nEncountered $errs error(s) while processing.\n" if ($errs); - - if ($check) { - print "\nConfiguration checked, $changes difference(s) found with working configuration.\n"; - } else { - $changes = 0 if ($_DEBUG_); - print "\nConfiguration applied, $changes changes made.\n"; - } - - return $TRUE if ($errs); - return $FALSE; -} - -sub clearConfiguration { - my $noprompt = shift; - my $errs; - - if (!$noprompt) { - print "WARNING: This removes ALL applied SCST configuration and may result in data loss!\n"; - print "If this is not what you intend, press ctrl-c now. Waiting 10 seconds.\n\n"; - sleep 10; - } - - print "\nRemoving all users and groups:\n\n"; - foreach my $group (keys %GROUPS) { - $errs += removeGroup($group) if ($group ne $_DEFAULT_GROUP_); - } - - print "\nRemoving all handler devices:\n\n"; - foreach my $device (keys %{$DEVICES}) { - next if (!$$DEVICES{$device}); - next if ($SCST->handlerType($$DEVICES{$device}) != $SCST::SCST::IOTYPE_VIRTUAL); - $errs += removeDevice($_REVERSE_MAP_{$$DEVICES{$device}}, $device); - } - - print "\nEncountered $errs error(s) while processing.\n" if ($errs); - print "\nConfiguration cleared.\n"; - - return $TRUE if ($errs); - return $FALSE; -} - -sub showSessions { - my $sessions = $SCST->sessions(); - immediateExit($SCST->errorString()); - - print "\n\tTarget Name\tInitiator Name\t\t\tGroup Name\t\tCommand Count\n"; - - foreach my $target (keys %{$sessions}) { - foreach my $group (keys %{$$sessions{$target}}) { - foreach my $user (keys %{$$sessions{$target}->{$group}}) { - my $commands = $$sessions{$target}->{$group}->{$user}; - - print "\t$target\t$user\t\t$group\t\t$commands\n"; - } - } - } - - print "\n"; - - return $FALSE; -} - -sub addDevice { - my $handler = shift; - my $device = shift; - my $path = shift; - my $options = shift; - my $blocksize = shift; - - my $_handler = $_HANDLER_MAP_{$handler}; - my $htype = $SCST->handlerType($_handler); - - if (!$htype) { - print "WARNING: Internal error occurred: ".$SCST->errorString()."\n"; - return $TRUE; - } - - if ($htype != $SCST::SCST::IOTYPE_VIRTUAL) { - my $typeString = $_HANDLER_TYPE_MAP_{$htype}; - my $validType = $_HANDLER_TYPE_MAP_{$SCST::SCST::IOTYPE_VIRTUAL}; - print "WARNING: Handler $handler of type $typeString is incapable of ". - "opening/closing devices. Valid handlers are:\n". - validHandlerTypes($SCST::SCST::IOTYPE_VIRTUAL)."\n"; - return $TRUE; - } - - if (defined($$DEVICES{$device})) { - print "WARNING: Device '$device' already defined.\n"; - return $TRUE; - } - - print "\t-> Opening virtual device '$device' at path '$path' using handler '$handler'..\n"; - - if ($SCST->openDevice($_handler, $device, $path, $options, $blocksize)) { - print "WARNING: Failed to open virtual device '$device' at path '$path': ". - $SCST->errorString()."\n"; - return $TRUE; - } - - $$DEVICES{$device} = $_handler; - - return $FALSE; -} - -sub resyncDevice { - my $handler = shift; - my $device = shift; - - my $_handler = $_HANDLER_MAP_{$handler}; - my $htype = $SCST->handlerType($_handler); - - if (!defined($$DEVICES{$device})) { - print "WARNING: Device '$device' not defined.\n"; - return $TRUE; - } - - print "\t-> Resync'ing virtual device '$device'..\n"; - - if ($SCST->resyncDevice($_handler, $device)) { - print "WARNING: Failed to resync virtual device '$device': ". - $SCST->errorString()."\n"; - return $TRUE; - } - - return $FALSE; -} - -sub removeDevice { - my $handler = shift; - my $device = shift; - - my $_handler = $_HANDLER_MAP_{$handler}; - my $htype = $SCST->handlerType($_handler); - - if (!$htype) { - print "WARNING: Internal error occurred: ".$SCST->errorString()."\n"; - return $TRUE; - } - - if ($htype != $SCST::SCST::IOTYPE_VIRTUAL) { - my $typeString = $_HANDLER_TYPE_MAP_{$htype}; - my $validType = $_HANDLER_TYPE_MAP_{$SCST::SCST::IOTYPE_VIRTUAL}; - print "WARNING: Handler $handler of type $typeString is incapable of ". - "opening/closing devices. Valid handlers are:\n". - validHandlerTypes($SCST::SCST::IOTYPE_VIRTUAL)."\n"; - return $TRUE; - } - - if (!defined($$DEVICES{$device})) { - print "WARNING: Device '$device' not defined.\n"; - return $TRUE; - } - - print "\t-> Closing virtual device '$device'..\n"; - - if ($SCST->closeDevice($_handler, $device)) { - print "WARNING: Failed to close virtual device '$device': ". - $SCST->errorString()."\n"; - return $TRUE; - } - - undef $$DEVICES{$device}; - - return $FALSE; -} - -sub setT10DeviceId { - my $handler = shift; - my $device = shift; - my $t10_id = shift; - - my $_handler = $_HANDLER_MAP_{$handler}; - my $htype = $SCST->handlerType($_handler); - - if (!defined($$DEVICES{$device})) { - print "WARNING: Device '$device' not defined.\n"; - return $TRUE; - } - - print "\t-> Changing T10 Device ID of virtual device '$device' to '$t10_id'..\n"; - - if ($SCST->setT10DeviceId($_handler, $device, $t10_id)) { - print "WARNING: Failed to changing T10 Device ID of virtual device '$device': ". - $SCST->errorString()."\n"; - return $TRUE; - } - - return $FALSE; -} - -sub addGroup { - my $group = shift; - - if (defined($GROUPS{$group})) { - print "WARNING: Group '$group' already exists.\n"; - return $TRUE; - } - - print "\t-> Creating security group '$group'..\n"; - - if ($SCST->addGroup($group)) { - print "WARNING: Failed to create security group '$group': ". - $SCST->errorString()."\n"; - return $TRUE; - } - - $GROUPS{$group}++; - - return $FALSE; -} - -sub renameGroup { - my $group = shift; - my $toGroup = shift; - - if (defined($GROUPS{$toGroup})) { - print "WARNING: Group '$toGroup' already exists.\n"; - return $TRUE; - } - - print "\t-> Renaming security group '$group' to '$toGroup'..\n"; - - if ($SCST->renameGroup($group, $toGroup)) { - print "WARNING: Failed to rename security group '$group' to ". - "'$toGroup': ".$SCST->errorString()."\n"; - return $TRUE; - } - - delete $GROUPS{$group}; - $GROUPS{$toGroup}++; - - return $FALSE; -} - -sub removeGroup { - my $group = shift; - - return $FALSE if ($group eq $_DEFAULT_GROUP_); - - if (!defined($GROUPS{$group})) { - print "WARNING: Group '$group' does not exist.\n"; - return $TRUE; - } - - print "\t-> Removing security group '$group'..\n"; - - if ($SCST->removeGroup($group)) { - print "WARNING: Failed to remove security group '$group': ". - $SCST->errorString()."\n"; - return $TRUE; - } - - undef $GROUPS{$group}; - - return $FALSE; -} - -sub addUser { - my $group = shift; - my $user = shift; - - if (!defined($GROUPS{$group})) { - print "WARNING: Failed to add user '$user' to group '$group', group does not exist.\n"; - return $TRUE; - } - - if (defined($USERS{$group}->{$user})) { - print "WARNING: User '$user' already exists in security group '$group'.\n"; - return $TRUE; - } - - print "\t-> Adding user '$user' to security group '$group'..\n"; - - if ($SCST->addUser($user, $group)) { - print "WARNING: Failed to add user '$user' to security group '$group': ". - $SCST->errorString()."\n"; - return $TRUE; - } - - $USERS{$group}->{$user}++; - - return $FALSE; -} - -sub moveUser { - my $group = shift; - my $user = shift; - my $toGroup = shift; - - if (!defined($GROUPS{$group})) { - print "WARNING: Failed to move user '$user' from group '$group', group does not exist.\n"; - return $TRUE; - } - - if (defined($USERS{$toGroup}->{$user})) { - print "WARNING: User '$user' already exists in security group '$toGroup'.\n"; - return $TRUE; - } - - print "\t-> Moving user '$user' from security group '$group' to security group '$toGroup'..\n"; - - if ($SCST->moveUser($user, $group, $toGroup)) { - print "WARNING: Failed to move user '$user' from security group '$group' to ". - "security group '$toGroup': ".$SCST->errorString()."\n"; - return $TRUE; - } - - delete $USERS{$group}->{$user}; - $USERS{$toGroup}->{$user}++; - - return $FALSE; -} - -sub removeUser { - my $group = shift; - my $user = shift; - - if (!defined($GROUPS{$group})) { - print "WARNING: Failed to remove user '$user' from group '$group', group does not exist.\n"; - return $TRUE; - } - - if (!defined($USERS{$group}->{$user})) { - print "WARNING: User '$user' doesn\'t exist in security group '$group'.\n"; - return $TRUE; - } - - print "\t-> Removing user '$user' from security group '$group'..\n"; - - if ($SCST->removeUser($user, $group)) { - print "WARNING: Failed to remove user '$user' to security group '$group': ". - $SCST->errorString()."\n"; - return $TRUE; - } - - undef $USERS{$group}->{$user}; - - return $FALSE; -} - -sub clearUsers { - my $group = shift; - - if (!defined($GROUPS{$group})) { - print "WARNING: Failed to clear users from group '$group', group does not exist.\n"; - return $TRUE; - } - - print "\t-> Clearing users from security group '$group'..\n"; - - if ($SCST->clearUsers($group)) { - print "WARNING: Failed to clear users from security group '$group': ". - $SCST->errorString()."\n"; - return $TRUE; - } - - undef $USERS{$group}; - - return $FALSE; -} - -sub assignDevice { - my $group = shift; - my $device = shift; - my $lun = shift; - my $options = shift; - my %allLuns; - - # Put luns into something easier to parse.. - foreach my $_group (keys %ASSIGNMENTS) { - my $_gAssigns = $ASSIGNMENTS{$_group}; - - foreach my $_device (keys %{$_gAssigns}) { - @{$allLuns{$_group}}[$$_gAssigns{$_device}] = $_device; - } - } - - # Use the next available LUN if none specified - if ($lun !~ /\d+/) { - $lun = ($#{$allLuns{$group}} + 1); - if ($lun > $_MAX_LUNS_) { - print "ERROR: Unable to use next available LUN of $lun, lun out of range.\n"; - return $TRUE; - } - - print "\t-> Device '$device': Using next available LUN of $lun for group '$group'.\n"; - } - - if (($lun < 0) || ($lun > $_MAX_LUNS_)) { - print "ERROR: Unable to assign device '$device', lun '$lun' is out of range.\n"; - return $TRUE; - } - - if (!defined($$DEVICES{$device})) { - print "WARNING: Unable to assign non-existent device '$device' to group '$group'.\n"; - return $TRUE; - } - - if (@{$allLuns{$group}}[$lun]) { - print "ERROR: Device '$device': Lun '$lun' is already assigned to device '".@{$allLuns{$group}}[$lun]."'.\n"; - return $TRUE; - } - - print "\t-> Assign virtual device '$device' to group '$group' at LUN '$lun'..\n"; - - if ($SCST->assignDeviceToGroup($device, $group, $lun, $options)) { - print "WARNING: Failed to assign device '$device' to group '$group': ". - $SCST->errorString()."\n"; - return $TRUE; - } - - if (!defined($ASSIGNMENTS{$group})) { - my %assignments_t; - $ASSIGNMENTS{$group} = \%assignments_t; - } - - my $_assignments = $ASSIGNMENTS{$group}; - - $$_assignments{$device} = $lun; - - return $FALSE; -} - -sub replaceDevice { - my $group = shift; - my $newDevice = shift; - my $lun = shift; - my $options = shift; - my %allLuns; - - # Put luns into something easier to parse.. - foreach my $_group (keys %ASSIGNMENTS) { - my $_gAssigns = $ASSIGNMENTS{$_group}; - - foreach my $_device (keys %{$_gAssigns}) { - @{$allLuns{$_group}}[$$_gAssigns{$_device}] = $_device; - } - } - - if (!defined($$DEVICES{$newDevice})) { - print "WARNING: Unable to assign non-existent device '$newDevice' to group '$group'.\n"; - return $TRUE; - } - - if (${$allLuns{$group}}[$lun] eq $newDevice) { - print "ERROR: Device '$newDevice': Lun '$lun' is already assigned to device '$newDevice'.\n"; - return $TRUE; - } - - print "\t-> Replace device at LUN '$lun' in group '$group' with new device '$newDevice'..\n"; - - if ($SCST->replaceDeviceInGroup($newDevice, $group, $lun, $options)) { - print "WARNING: Failed to replace LUN '$lun' in group '$group' with new device '$newDevice': ". - $SCST->errorString()."\n"; - return $TRUE; - } - - if (!defined($ASSIGNMENTS{$group})) { - my %assignments_t; - $ASSIGNMENTS{$group} = \%assignments_t; - } - - my $_assignments = $ASSIGNMENTS{$group}; - - delete $$_assignments{${$allLuns{$group}}[$lun]}; - $$_assignments{$newDevice} = $lun; - - return $FALSE; -} - -sub releaseDevice { - my $group = shift; - my $device = shift; - - if (!defined($GROUPS{$group})) { - print "WARNING: Failed to release device '$device' from group '$group', group does not exist.\n"; - return $TRUE; - } - - if (!defined($$DEVICES{$device})) { - print "WARNING: Failed to release device '$device', device not defined.\n"; - return $TRUE; - } - - print "\t-> Release virtual device '$device' from group '$group'..\n"; - - if ($SCST->removeDeviceFromGroup($device, $group)) { - print "WARNING: Failed to release device '$device' from group '$group': ". - $SCST->errorString()."\n"; - return $TRUE; - } - - my $_assignments = $ASSIGNMENTS{$group}; - - undef $$_assignments{$device}; - - return $FALSE; -} - -sub clearDevices { - my $group = shift; - - if (!defined($GROUPS{$group})) { - print "WARNING: Failed to clear devices from group '$group', group does not exist.\n"; - return $TRUE; - } - - print "\t-> Clear virtual devices from group '$group'..\n"; - - if ($SCST->clearGroupDevices($group)) { - print "WARNING: Failed to clear devices from group '$group': ". - $SCST->errorString()."\n"; - return $TRUE; - } - - undef $ASSIGNMENTS{$group}; - - return $FALSE; -} - -sub targets { - my %targets; - my %fcards; - - my $root = new IO::Dir $_FC_CLASS_ if (-d $_FC_CLASS_); - - if ($root) { - while (my $entry = $root->read()) { - next if (($entry eq '.') || ($entry eq '..')); - - my $io = new IO::File "$_FC_CLASS_/$entry/port_name", O_RDONLY; - - if ($io) { - my $wwn = <$io>; - chomp $wwn; - close $io; - - $fcards{$entry} = $wwn; - } - } - } - - $root = new IO::Dir $_SCSI_CLASS_ if (-d $_SCSI_CLASS_); - - if ($root) { - while (my $entry = $root->read()) { - next if (($entry eq '.') || ($entry eq '..')); - - my $io = new IO::File "$_SCSI_CLASS_/$entry/target_mode_enabled", O_RDONLY; - - if ($io) { - my $enabled = <$io>; - chomp $enabled; - close $io; - - $targets{$entry}->{'path'} = "$_SCSI_CLASS_/$entry/target_mode_enabled"; - $targets{$entry}->{'enabled'} = $enabled; - $targets{$entry}->{'qla_isp'} = $FALSE; - - if ($fcards{$entry}) { - $targets{$fcards{$entry}}->{'enabled'} = $enabled; - $targets{$fcards{$entry}}->{'path'} = - "$_SCSI_CLASS_/$entry/target_mode_enabled"; - - if (-f "$_FC_CLASS_/$entry/issue_lip") { - $targets{$fcards{$entry}}->{'ilip'} = "$_FC_CLASS_/$entry/issue_lip"; - } - - $targets{$entry}->{'duplicate'} = $TRUE; - } else { - $targets{$entry}->{'duplicate'} = $FALSE; - } - } - } - } - - $root = new IO::Dir $_SCSI_ISP_ if (-d $_SCSI_ISP_); - - if ($root) { - while (my $entry = $root->read()) { - next if (($entry eq '.') || ($entry eq '..')); - - local $/; - my $io = new IO::File "$_SCSI_ISP_/$entry", O_RDONLY; - - if ($io) { - my $wwn; - my $fstr; - my $enabled2; - - $fstr = <$io>; - close $io; - - ($wwn) = ($fstr =~ '.*?Port WWN +([^\ ]+) .*'); - $fcards{$entry} = $wwn; - - $io = new IO::File "$_SCSITGT_QLAISP_/$entry", O_RDONLY; - if ($io) { - $fstr = <$io>; - close $io; - - ($enabled2) = ($fstr =~ '[^\n]+\n *\d *: *(\d)'); - $targets{$entry}->{'path'} = "$_SCSITGT_QLAISP_/$entry"; - $targets{$entry}->{'enabled'} = $enabled2; - $targets{$entry}->{'qla_isp'} = $TRUE; - - if ($fcards{$entry}) { - $targets{$fcards{$entry}}->{'enabled'} = $enabled2; - $targets{$fcards{$entry}}->{'path'} = "$_SCSITGT_QLAISP_/$entry"; - $targets{$fcards{$entry}}->{'qla_isp'} = $TRUE; - $targets{$entry}->{'duplicate'} = $TRUE; - } else { - $targets{$entry}->{'duplicate'} = $FALSE; - } - } - } - } - } - - return \%targets; -} - -sub targetEnabled { - my $target = shift; - - return undef if (!defined($$TARGETS{$target})); - return $$TARGETS{$target}->{'enabled'}; -} - -sub enableTarget { - my $target = shift; - my $enable = shift; - - $target = unformatTarget($target); - - return undef if (!defined($$TARGETS{$target})); - - my $io = new IO::File $$TARGETS{$target}->{'path'}, O_WRONLY; - return $TRUE if (!$io); - - print $enable ? "\t-> Enabling" : "\t-> Disabling"; - print " target mode for SCST host '$target'.\n"; - - if ($_DEBUG_) { - print "DBG($$): ".$$TARGETS{$target}->{'path'}." -> $enable\n\n"; - } else { - if ($$TARGETS{$target}->{'qla_isp'} == $FALSE) { - print $io $enable; - } else { - print $io $enable ? "enable all" : "disable all"; - } - } - - close $io; - - $$TARGETS{$target}->{'enabled'} = $enable; - - return $FALSE; -} - -sub issueLIP { - my $lip_issued; - - foreach my $target (keys %{$TARGETS}) { - next if ($$TARGETS{$target}->{'duplicate'}); - next if (!$$TARGETS{$target}->{'enabled'}); - - if (defined($$TARGETS{$target}->{'ilip'})) { - my $io = new IO::File $$TARGETS{$target}->{'ilip'}, O_WRONLY; - return $TRUE if (!$io); - - print "\t-> Issuing LIP for target '".formatTarget($target)."': "; - - if ($_DEBUG_) { - print "DBG($$): ".$$TARGETS{$target}->{'ilip'}." -> $TRUE\n\n"; - } else { - print $io $TRUE; - } - - print "done.\n"; - - $lip_issued = $TRUE; - } - } - - print "\t-> WARNING: This target driver does not support issuing LIPs.\n\n" - if (!$lip_issued); -} - -sub readConfig { - my $confile = shift; - my $ignoreError = shift; - my %config; - my $section; - my $last_section; - my $arg; - my $last_arg; - my %empty; - - my $io = new IO::File $confile, O_RDONLY; - - if (!$io) { - return undef if ($ignoreError); - - die("FATAL: Unable to open specified configuration file $confile: $!\n"); - } - - while (my $line = <$io>) { - ($line, undef) = split(/\#/, $line, 2); - $line = cleanupString($line); - - if ($line =~ /^\[(.*)\]$/) { - ($section, $arg) = split(/\s+/, $1, 2); - - $arg = 'default' if ($section eq 'OPTIONS'); - - if ($last_arg && ($last_arg ne $arg) && - !defined($config{$last_section}->{$last_arg})) { - $config{$last_section}->{$last_arg} = \%empty; - } - - $last_arg = $arg; - $last_section = $section; - } elsif ($section && $arg && $line) { - my($parameter, $value) = split(/\s+/, $line, 2); - - if ($section eq 'OPTIONS') { - $value = $TRUE if (($value == 1) || - ($value =~ /^TRUE$/i) || - ($value =~ /^YES$/i)); - $value = $FALSE if (($value == 0) || - ($value =~ /^FALSE$/i) || - ($value =~ /^NO$/i)); - } - - push @{$config{$section}->{$arg}->{$parameter}}, $value; - } - } - - close $io; - - return \%config; -} - -sub findUserGroup { - my $user = shift; - my $config = shift; - - foreach my $group (keys %{$$config{'GROUP'}}) { - foreach my $_user (@{$$config{'GROUP'}->{$group}->{'USER'}}) { - return $group if ($_user eq $user); - } - } - - return undef; -} - -sub findUserGroupInCurrent { - my $user = shift; - - foreach my $group (keys %USERS) { - foreach my $_user (keys %{$USERS{$group}}) { - return $group if ($_user eq $user); - } - } - - return undef; -} - -sub findAssignedLun { - my $associations = shift; - my $lun = shift; - - return undef if (!defined($lun)); - - foreach my $device (keys %{$associations}) { - if ($$associations{$device} == $lun) { - return $device; - } - } - - return undef; -} - -sub cleanupString { - my $string = shift; - - $string =~ s/^\s+//; - $string =~ s/\s+$//; - - return $string; -} - -sub formatTarget { - my $target = shift; - - if ($target =~ /^0x/) { - $target =~ s/^0x//; - my($o1, $o2, $o3, $o4, $o5, $o6, $o7, $o8) = unpack("A2A2A2A2A2A2A2A2", $target); - $target = "$o1:$o2:$o3:$o4:$o5:$o6:$o7:$o8"; - } - - $target =~ tr/A-Z/a-z/; - - return $target; -} - -sub unformatTarget { - my $target = shift; - - if ($target =~ /^.{2}\:.{2}\:.{2}\:.{2}\:.{2}\:.{2}\:.{2}\:.{2}/) { - $target =~ s/\://g; - $target = "0x$target"; - } - - $target =~ tr/A-Z/a-z/; - - return $target; -} - -sub validHandlerTypes { - my $type = shift; - my $buffer = "\n"; - - foreach my $handler (keys %_REVERSE_MAP_) { - $buffer .= "\t".$_REVERSE_MAP_{$handler}."\n" if ($SCST->handlerType($handler) == $type); - } - - return $buffer; -} - -sub randomGroup { - my $tmp_group; - my $retry = 0; - - while (($retry < 10000) && (!$tmp_group || $SCST->groupExists($tmp_group))) { - my $id = int(rand(10000)); - - $tmp_group = $_TGT_TMP_PREFIX_.$id; - - $retry++; - } - - return undef if ($SCST->groupExists($tmp_group)); - return $tmp_group; -} - -# If we have an unread error from SCST, exit immediately -sub immediateExit { - my $error = shift; - - return if (!$error); - - print "\n\nFATAL: Received the following error:\n\n\t"; - print "$error\n\n"; - - exit 1; -} - -# Hey! Stop that! -sub commitSuicide { - print "\n\nAborting immediately.\n"; - exit 1; -} diff --git a/usr/Makefile b/usr/Makefile index ce70ded88..7d58a24ec 100644 --- a/usr/Makefile +++ b/usr/Makefile @@ -63,16 +63,6 @@ extraclean: cd $(STPGD_DIR) && $(MAKE) $@ cd $(EVENTS_DIR) && $(MAKE) $@ -disable_proc: - cd $(FILEIO_DIR) && $(MAKE) $@ - cd $(STPGD_DIR) && $(MAKE) $@ - cd $(EVENTS_DIR) && $(MAKE) $@ - -enable_proc: - cd $(FILEIO_DIR) && $(MAKE) $@ - cd $(STPGD_DIR) && $(MAKE) $@ - cd $(EVENTS_DIR) && $(MAKE) $@ - help: @echo " all (the default) : make all" @echo " clean : clean files" @@ -84,4 +74,4 @@ help: @echo " - be sure to compile qla against the correct initiator" @echo " driver. Read its README for details." -.PHONY: all install uninstall clean extraclean help 2release 2debug 2perf disable_proc enable_proc +.PHONY: all install uninstall clean extraclean help 2release 2debug 2perf