├── .gitignore ├── GITBOOK.md ├── Makefile ├── README ├── SUMMARY.md ├── book.json ├── conf ├── Makefile ├── examples │ ├── targets.conf.example │ ├── targets.conf.vtl.L700 │ └── targets.conf.vtl.MSL2024 └── targets.conf ├── debian ├── changelog ├── compat ├── control ├── copyright ├── gbp.conf ├── rules ├── source │ └── format ├── tests │ ├── admin │ ├── control │ ├── daemon │ └── storage ├── tgt-openvstorage.install ├── tgt-rbd.install ├── tgt.NEWS ├── tgt.bash-completion ├── tgt.docs ├── tgt.init ├── tgt.postinst ├── tgt.prerm ├── tgt.service └── watch ├── doc ├── Makefile ├── README.dvdjukebox ├── README.glfs ├── README.iscsi ├── README.iser ├── README.lu_configuration ├── README.mmc ├── README.passthrough ├── README.rbd ├── README.sbcjukebox ├── README.sheepdog ├── README.ssc ├── README.vtl ├── targets.conf.5.xml ├── tgt-admin.8.xml ├── tgt-setup-lun.8.xml ├── tgtadm.8.xml ├── tgtd.8.xml ├── tgtimg.8.xml └── tmf.txt ├── jenkins ├── centos │ ├── build_rpms.sh │ └── docker │ │ ├── Dockerfile │ │ ├── docker-entrypoint.sh │ │ └── supervisord.conf ├── ubuntu │ ├── build_debs.sh │ └── docker │ │ ├── Dockerfile │ │ ├── docker-entrypoint.sh │ │ └── supervisord.conf └── ubuntu1604 │ ├── build_debs.sh │ └── docker │ ├── Dockerfile │ ├── docker-entrypoint.sh │ └── supervisord.conf ├── rpm ├── SOURCES │ ├── 0001-redhatify-docs.patch │ ├── 0002-remove-check-for-xsltproc.patch │ ├── 0003-default-config.patch │ ├── sample.conf │ ├── sysconfig.tgtd │ ├── targets.conf │ ├── tgtd.conf │ └── tgtd.service └── SPECS │ └── scsi-target-utils.spec ├── scripts ├── Makefile ├── build-pkg.sh ├── checkarch.sh ├── checkpatch.pl ├── deb │ ├── changelog │ ├── compat │ ├── control │ ├── copyright │ ├── init │ ├── patches │ │ └── 0001-Use-local-docbook-for-generating-docs.patch │ ├── rules │ ├── source │ │ └── format │ └── tgt.bash-completion ├── initd.sample ├── tgt-admin ├── tgt-core-test ├── tgt-setup-lun ├── tgt.bashcomp.sh ├── tgtd.service └── tgtd.spec └── usr ├── Makefile ├── be_byteshift.h ├── bs.c ├── bs_aio.c ├── bs_aio.h ├── bs_glfs.c ├── bs_null.c ├── bs_openvstorage.c ├── bs_rbd.c ├── bs_rdwr.c ├── bs_sg.c ├── bs_sheepdog.c ├── bs_ssc.c ├── bs_ssc.h ├── bs_thread.h ├── bsg.h ├── concat_buf.c ├── crc32c.h ├── driver.c ├── driver.h ├── iscsi ├── chap.c ├── conn.c ├── iscsi_if.h ├── iscsi_proto.h ├── iscsi_tcp.c ├── iscsid.c ├── iscsid.h ├── iser.c ├── iser.h ├── iser_text.c ├── isns.c ├── isns_proto.h ├── md5.c ├── md5.h ├── param.c ├── param.h ├── session.c ├── sha1.c ├── sha1.h ├── target.c ├── transport.c └── transport.h ├── libcrc32c.c ├── libssc.c ├── libssc.h ├── list.h ├── log.c ├── log.h ├── media.h ├── mgmt.c ├── mmc.c ├── osd.c ├── parser.c ├── parser.h ├── sbc.c ├── scc.c ├── scsi.c ├── scsi.h ├── scsi_cmnd.h ├── smc.c ├── smc.h ├── spc.c ├── spc.h ├── ssc.c ├── ssc.h ├── target.c ├── target.h ├── tgtadm.c ├── tgtadm.h ├── tgtadm_error.h ├── tgtd.c ├── tgtd.h ├── tgtimg.c ├── util.c ├── util.h ├── work.c └── work.h /.gitignore: -------------------------------------------------------------------------------- 1 | # 2 | # Normal rules 3 | # 4 | .* 5 | *.o 6 | *.o.* 7 | *.a 8 | *.s 9 | *.ko 10 | *.so 11 | *.mod.c 12 | *.i 13 | *.lst 14 | *.symtypes 15 | *.d 16 | *.orig 17 | *.rej 18 | 19 | # 20 | # for GLOBAL 21 | # 22 | GTAGS 23 | GRTAGS 24 | GPATH 25 | GSYMS 26 | 27 | # 28 | # programs 29 | # 30 | usr/tgtd 31 | usr/tgtadm 32 | usr/tgtimg 33 | 34 | # cscope files 35 | cscope.* 36 | -------------------------------------------------------------------------------- /GITBOOK.md: -------------------------------------------------------------------------------- 1 | # TGT 2 | 3 | ## Building 4 | 5 | ### Ubuntu 14.04 6 | ``` 7 | mkdir WORK 8 | cd WORK 9 | 10 | ## manually fetch latest libovsvolumedriver + libovsvolumedriver-dev packages here 11 | 12 | git clone https://github.com/openvstorage/tgt 13 | 14 | docker build -t bldenv tgt/jenkins/ubuntu/docker 15 | 16 | docker run -d -v ${PWD}:/home/jenkins/workspace -e UID=${UID} --name builder -h builder bldenv 17 | docker exec -u jenkins -i -t builder /bin/bash -l 18 | 19 | cd ~/workspace 20 | ./tgt/jenkins/ubuntu/build_debs.sh 21 | 22 | exit 23 | docker stop builder && docker rm builder 24 | docker rmi bldenv 25 | ``` 26 | Resulting debian packages will be in WORK directory 27 | 28 | 29 | ### CentOS 30 | ``` 31 | 32 | mkdir WORK 33 | cd WORK 34 | 35 | git clone https://github.com/openvstorage/tgt 36 | 37 | docker build -t bldenv tgt/jenkins/centos/docker 38 | 39 | docker run -d -v ${PWD}:/home/jenkins/workspace -e UID=${UID} --name builder -h builder bldenv 40 | docker exec -u jenkins -i -t builder /bin/bash -l 41 | 42 | cd ~/workspace 43 | ./tgt/jenkins/centos/build_rpms.sh 44 | 45 | exit 46 | docker stop builder && docker rm builder 47 | docker rmi bldenv 48 | ``` 49 | 50 | Resulting rpm files will be in WORK/rpm/RPMS/x86_64 and WORK/rpm/SPMS 51 | 52 | ## Usage 53 | Open vStorage supports exposing vDisks as iSCSI disks through [TGT](http://stgt.sourceforge.net/). 54 | 55 | Install the Open vStorage TGT package. For ubuntu 56 | ``` 57 | sudo apt-get install tgt 58 | ``` 59 | 60 | Create a new target device 61 | ``` 62 | tgtadm --lld iscsi --mode target --op new --tid=1 --targetname iqn.2016-01.com.openvstorage:for.all 63 | ``` 64 | 65 | Add a logical unit (LUN) 66 | ``` 67 | tgtadm --lld iscsi --op new --bstype openvstorage --mode logicalunit --tid 1 --lun 1 -b volumeName 68 | ``` 69 | 70 | Enable the target to accept initiators: 71 | * Add IP wildcard to allow all initiators 72 | ``` 73 | tgtadm --lld iscsi --mode target --op bind --tid 1 -I ALL 74 | ``` 75 | 76 | * IP-based restrictions 77 | * If you've previously configured a target to accept ALL initiators, you need to remove that first. 78 | ``` 79 | tgtadm --lld iscsi --mode target --op unbind --tid 1 -I ALL 80 | ``` 81 | * Now, restrict access to a specific IP … 82 | ``` 83 | tgtadm --lld iscsi --mode target --op bind --tid 1 -I 1.2.3.4 84 | ``` 85 | * or restrict access to a specific IP subnet … 86 | ``` 87 | tgtadm --lld iscsi --mode target --op bind --tid 1 -I 1.2.3.0/24 88 | ``` -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | VERSION ?= 1.0.63 2 | 3 | CHECK_CC = cgcc 4 | CHECK_CC_FLAGS = '$(CHECK_CC) -Wbitwise -Wno-return-void -no-compile $(ARCH)' 5 | 6 | # Define a common prefix where binaries and docs install 7 | PREFIX ?= /usr 8 | 9 | # Export VERSION and PREFIX so sub-make knows about them 10 | export VERSION PREFIX 11 | 12 | # Export the feature switches so sub-make knows about them 13 | export ISCSI_RDMA 14 | export CEPH_RBD 15 | export GLFS_BD 16 | export OPENVSTORAGE 17 | export SD_NOTIFY 18 | 19 | .PHONY: all 20 | all: programs doc conf scripts 21 | 22 | # Targets for the /usr/sbin utilities 23 | .PHONY: programs install-programs clean-programs 24 | programs: 25 | $(MAKE) -C usr 26 | 27 | install-programs: 28 | $(MAKE) -C usr install 29 | 30 | clean-programs: 31 | $(MAKE) -C usr clean 32 | 33 | # Targets for man pages and other documentation 34 | .PHONY: doc install-doc clean-doc 35 | doc: 36 | $(MAKE) -C doc 37 | 38 | install-doc: 39 | $(MAKE) -C doc install 40 | 41 | clean-doc: 42 | $(MAKE) -C doc clean 43 | 44 | # Targets for scripts 45 | .PHONY: scripts install-scripts clean-scripts 46 | scripts: 47 | $(MAKE) -C scripts 48 | 49 | install-scripts: 50 | $(MAKE) -C scripts install 51 | 52 | clean-scripts: 53 | $(MAKE) -C scripts clean 54 | 55 | 56 | # Targets for configuration stubs 57 | .PHONY: conf install-conf clean-conf 58 | conf: 59 | $(MAKE) -C conf 60 | 61 | install-conf: 62 | $(MAKE) -C conf install 63 | 64 | clean-conf: 65 | $(MAKE) -C conf clean 66 | 67 | .PHONY: install 68 | install: install-programs install-doc install-conf install-scripts 69 | 70 | .PHONY: rpm 71 | rpm: 72 | @./scripts/build-pkg.sh rpm 73 | 74 | .PHONY: deb 75 | deb: 76 | @./scripts/build-pkg.sh deb 77 | 78 | .PHONY: clean 79 | clean-pkg: 80 | rm -fr pkg 81 | 82 | .PHONY: clean 83 | clean: clean-programs clean-doc clean-conf clean-scripts clean-pkg 84 | 85 | .PHONY:check 86 | check: ARCH=$(shell sh scripts/checkarch.sh) 87 | check: 88 | CC=$(CHECK_CC_FLAGS) $(MAKE) all 89 | 90 | .PHONY:check32 91 | check32: override ARCH=-m32 92 | check32: 93 | CC=$(CHECK_CC_FLAGS) $(MAKE) all 94 | 95 | .PHONY:check64 96 | check64: override ARCH=-m64 97 | check64: 98 | CC=$(CHECK_CC_FLAGS) $(MAKE) all 99 | 100 | cscope: 101 | find -name '*.[ch]' > cscope.files 102 | cscope -bq 103 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | How to use and build TGT with Open vStorage can be found here [https://openvstorage.gitbooks.io/tgt] 2 | 3 | 4 | TGT Introduction 5 | ------------- 6 | Linux target framework (tgt) aims to simplify various SCSI target 7 | driver (iSCSI, Fibre Channel, SRP, etc) creation and maintenance. 8 | 9 | Currently, tgt supports the following target drivers: 10 | 11 | - iSCSI software target driver for Ethernet NICs 12 | 13 | - iSER software target driver for Infiniband and RDMA NICs 14 | 15 | - IBM System p VIO server 16 | 17 | - FCoE software target driver for Ethernet NICs (in progress) 18 | 19 | - Qlogic qla2xxx FC target driver (in progress) 20 | 21 | Tgt consists of kernel modules, user-space daemon, and user-space 22 | tools. iSCSI, iSER, and FCoE target drivers use only user-space daemon 23 | and tools (i.e. they are just user-space applications. They don't need 24 | any kernel support). 25 | 26 | tgt can emulate the following device types: 27 | 28 | - SBC: a virtual disk drive that can use a file to store the content. 29 | 30 | - SMC: a virtual media jukebox that can be controlled by the "mtx" 31 | tool. 32 | 33 | - MMC: a virtual DVD drive that can read DVD-ROM iso files and create 34 | burnable DVD+R. It can be combined with SMC to provide a fully 35 | operational DVD jukebox. 36 | 37 | - SSC: a virtual tape device (aka VTL) that can use a file to store 38 | the content. 39 | 40 | - OSD: a virtual object-based storage device that can use a file to 41 | store the content (in progress). 42 | 43 | The code is under the GNU General Public License version 2. 44 | 45 | 46 | Preparation 47 | ------------- 48 | Linux kernel 2.6.22 or newer are recommended because tgt can get 49 | better performance with signalfd. 50 | 51 | Target drivers have their own ways to build, configure, etc. Please 52 | find an appropriate documentation in the doc directory. You might find 53 | other useful information on tgt's site: 54 | 55 | http://stgt.sourceforge.net/ 56 | 57 | 58 | Developer Notes 59 | ------------- 60 | The central resource for tgt development is the mailing list 61 | (stgt@vger.kernel.org). 62 | 63 | First, please read the following documents (in short, follow Linux 64 | kernel development rules): 65 | 66 | http://lxr.linux.no/source/Documentation/CodingStyle 67 | http://lxr.linux.no/source/Documentation/SubmittingPatches 68 | 69 | Then, check your patches with the patch style checker prior to 70 | submission (scripts/checkpatch.pl) like the following example. 71 | 72 | fujita@arbre:~/git/tgt$ ./scripts/checkpatch.pl ~/0001-add-bidi-support.patch 73 | Your patch has no obvious style problems and is ready for submission. 74 | -------------------------------------------------------------------------------- /SUMMARY.md: -------------------------------------------------------------------------------- 1 | # Summary 2 | 3 | 4 | -------------------------------------------------------------------------------- /book.json: -------------------------------------------------------------------------------- 1 | { 2 | "structure": { 3 | "readme": "GITBOOK.md" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /conf/Makefile: -------------------------------------------------------------------------------- 1 | sysconfdir ?= /etc 2 | 3 | EXAMPLES = targets.conf.example targets.conf.vtl.L700 targets.conf.vtl.MSL2024 4 | 5 | .PHONY: all 6 | all: 7 | 8 | .PHONY: install 9 | install: 10 | install -d -m 755 $(DESTDIR)$(sysconfdir)/tgt 11 | if [ ! -f $(DESTDIR)$(sysconfdir)/tgt/targets.conf ] ; then \ 12 | install -m 644 targets.conf $(DESTDIR)$(sysconfdir)/tgt ; \ 13 | fi 14 | install -d -m 755 $(DESTDIR)/usr/share/doc/tgt/examples 15 | for f in $(EXAMPLES) ; do \ 16 | install -m 644 examples/$$f $(DESTDIR)/usr/share/doc/tgt/examples ;\ 17 | done 18 | install -d $(DESTDIR)$(sysconfdir)/tgt/conf.d 19 | 20 | .PHONY: clean 21 | clean: 22 | 23 | -------------------------------------------------------------------------------- /conf/examples/targets.conf.vtl.L700: -------------------------------------------------------------------------------- 1 | # Virtual tape library example for a STK L700 tape library 2 | # 3 | # In this case, tapes are stored in the directory /root/tapes 4 | # size is in MB (1 GB in this case) 5 | # using the command "tgtimg --op=new --device-type=tape --barcode="A00000001" --size=10240 --type=data --file=A00000001" 6 | # 7 | # The tapes can be added after startup with 8 | # "tgtadm --lld iscsi --mode logicalunit --op update --tid 1 --lun 4 --params element_type=2,address=1000,barcode=A0000001,sides=1" 9 | # for slot 0 (is nr 1000) 10 | # 11 | 12 | include /etc/tgt/temp/*.conf 13 | 14 | default-driver iscsi 15 | 16 | 17 | allow-in-use yes 18 | # 19 | # For every drive We need a backing store, although the tape drive will be empty, 20 | # so we create a dummy tape "notape" in directory /root/tapes 21 | # with the command "tgtimg --op=new --device-type=tape --barcode="" --size=1 --type=clean --file=notape" 22 | # and create symbolic links for every drive (limitation of tgt) 23 | # link -s /root/tapes/notape /root/tapes/notape1 24 | # link -s /root/tapes/notape /root/tapes/notape2 25 | # link -s /root/tapes/notape /root/tapes/notape2 26 | # 27 | 28 | lun 1 29 | device-type tape 30 | removable 1 31 | vendor_id "HP" 32 | product_id "LTO3 ULTRIUM" 33 | product_rev "0001" 34 | scsi_sn "HUM1A00001" 35 | scsi_id "HP LTO3 ULTRIUM" 36 | 37 | 38 | lun 2 39 | device-type tape 40 | removable 1 41 | vendor_id "HP" 42 | product_id "LTO3 ULTRIUM" 43 | product_rev "0001" 44 | scsi_sn "HUM1A00002" 45 | scsi_id "HP LTO3 ULTRIUM" 46 | 47 | 48 | lun 3 49 | device-type tape 50 | removable 1 51 | vendor_id "HP" 52 | product_id "LTO3 ULTRIUM" 53 | product_rev "0001" 54 | scsi_sn "HUM1A00003" 55 | scsi_id "HP LTO3 ULTRIUM" 56 | 57 | 58 | lun 4 59 | device-type changer 60 | removable 1 61 | vendor_id "STK" 62 | product_id "L700" 63 | product_rev "0001" 64 | scsi_sn "123:456:789:000" 65 | # Dummy 'page 0' 66 | mode_page "0:0:0" 67 | # Page 0x02: Disconnect/Reconnect SPC-3 68 | mode_page "0x02:0:14:0x80:0x80:0:0xa:0:0:0:0:0:0:0:0:0:0" 69 | # Page 0x1a: Power Condition SPC-3 70 | mode_page "0x1a:0:18:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0" 71 | # Page 0x1c: Informational Exceptions Control SPC-3 72 | mode_page "0x1c:0:10:8:0:0:0:0:0:0:0:0:0" 73 | # Page 0x1d: Element Address Assignment SMC-3 7.3.4 74 | mode_page "0x1d:0:0x12:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0" 75 | # Page 0x1e: Transport Geometry Parameters SMC-3 7.3.5 76 | mode_page "0x1e:0:2:0:0" 77 | # Page 0x1f: Device Capabilities SMC-3 7.3.2 78 | # Page 0x1f/Subpage 0x41: Extended Device Capabilities SMC-3 7.3.3 79 | mode_page "0x1f:0:0x12:0x0f:7:0x0f:0x0f:0x0f:0x0f:0:0:0:0:0x0f:0x0f:0x0f:0x0f:0:0:0:0" 80 | # Type 1: Medium Transport Elements (robot arm/picker) 81 | params element_type=1,start_address=1,quantity=1,media_home=/root/tapes 82 | # Type 2: Storage Elements (tape slots) 83 | params element_type=2,start_address=1000,quantity=216,media_home=/root/tapes 84 | # Type 3: Import/Export Elements (CAP) 85 | params element_type=3,start_address=10,quantity=20,media_home=/root/tapes 86 | # Type 4: Add Data Transfer devices (drives) 87 | params element_type=4,start_address=500,quantity=3,media_home=/root/tapes 88 | params element_type=4,address=500,tid=1,lun=1 89 | params element_type=4,address=500,tid=1,lun=2 90 | params element_type=4,address=500,tid=1,lun=3 91 | 92 | 93 | -------------------------------------------------------------------------------- /conf/examples/targets.conf.vtl.MSL2024: -------------------------------------------------------------------------------- 1 | # Virtual tape library example for an HP MSL-2024 tape library 2 | # 3 | # In this case, tapes are stored in the directory /root/tapes 4 | # size is in MB (1 GB in this case) 5 | # using the command "tgtimg --op=new --device-type=tape --barcode="A00000001" --size=10240 --type=data --file=A00000001" 6 | # 7 | # The tapes can be added after startup with 8 | # "tgtadm --lld iscsi --mode logicalunit --op update --tid 1 --lun 4 --params element_type=2,address=1000,barcode=A0000001,sides=1" 9 | # for slot 0 (is nr 1000) 10 | # 11 | # Please note that an MSL-2024 has no IMPORT/EXPORT elements (type 3) 12 | 13 | include /etc/tgt/temp/*.conf 14 | 15 | default-driver iscsi 16 | 17 | 18 | allow-in-use yes 19 | # 20 | # We need a backing store, although the tape drive will be empty, 21 | # so we create a dummy tape "notape" in directory /root/tapes 22 | # with the command "tgtimg --op=new --device-type=tape --barcode="" --size=1 --type=clean --file=notape" 23 | # 24 | 25 | lun 1 26 | device-type tape 27 | removable 1 28 | vendor_id "HP " 29 | product_id "Ultrium 3-SCSI" 30 | product_rev "D21W" 31 | scsi_sn "HU012345AB" 32 | scsi_id "HP LTO3 ULTRIUM" 33 | 34 | # 35 | # For the tape changer we need also a backing store, this can be a file containing zeros, like this: 36 | # "dd if=/dev/zero of=$HOME/smc bs=1k count=1" 37 | # 38 | 39 | lun 4 40 | device-type changer 41 | removable 1 42 | vendor_id "HP " 43 | product_id "MSL G3 Series " 44 | product_rev "3.00" 45 | scsi_sn "ABC01234G3" 46 | # Dummy 'page 0' 47 | mode_page "0:0:0" 48 | # Page 0x02: Disconnect/Reconnect SPC-3 49 | mode_page "0x02:0:14:0x80:0x80:0:0xa:0:0:0:0:0:0:0:0:0:0" 50 | # Page 0x1a: Power Condition SPC-3 51 | mode_page "0x1a:0:18:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0" 52 | # Page 0x1c: Informational Exceptions Control SPC-3 53 | mode_page "0x1c:0:10:8:0:0:0:0:0:0:0:0:0" 54 | # Page 0x1d: Element Address Assignment SMC-3 7.3.4 55 | mode_page "0x1d:0:0x12:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0" 56 | # Page 0x1e: Transport Geometry Parameters SMC-3 7.3.5 57 | mode_page "0x1e:0:2:0:0" 58 | # Page 0x1f: Device Capabilities SMC-3 7.3.2 59 | # Page 0x1f/Subpage 0x41: Extended Device Capabilities SMC-3 7.3.3 60 | mode_page "0x1f:0:0x12:0x0f:7:0x0f:0x0f:0x0f:0x0f:0:0:0:0:0x0f:0x0f:0x0f:0x0f:0:0:0:0" 61 | # Type 1: Medium Transport Elements (robot arm/picker) 62 | params element_type=1,start_address=1,quantity=1,media_home=/root/tapes 63 | # Type 2: Storage Elements (tape slots) 64 | params element_type=2,start_address=1000,quantity=24,media_home=/root/tapes 65 | # Type 4: Add Data Transfer devices (drives) 66 | params element_type=4,start_address=2,quantity=1,media_home=/root/tapes 67 | params element_type=4,address=2,tid=1,lun=1 68 | 69 | 70 | -------------------------------------------------------------------------------- /conf/targets.conf: -------------------------------------------------------------------------------- 1 | # Empty targets configuration file -- please see the package 2 | # documentation directory for an example. 3 | # 4 | # You can drop individual config snippets into /etc/tgt/conf.d 5 | include /etc/tgt/conf.d/*.conf 6 | -------------------------------------------------------------------------------- /debian/compat: -------------------------------------------------------------------------------- 1 | 9 2 | -------------------------------------------------------------------------------- /debian/control: -------------------------------------------------------------------------------- 1 | Source: tgt 2 | Section: net 3 | Priority: optional 4 | Maintainer: Ubuntu Developers 5 | XSBC-Original-Maintainer: Apollon Oikonomopoulos 6 | Build-Depends: debhelper (>= 9), libibverbs-dev, librdmacm-dev (>= 1.0.16), 7 | xsltproc, docbook-xsl, dh-systemd (>= 1.5), librbd-dev, 8 | bash-completion, libsystemd-dev, libovsvolumedriver-dev 9 | Vcs-Git: https://anonscm.debian.org/git/collab-maint/tgt.git 10 | Vcs-Browser: https://anonscm.debian.org/gitweb?p=collab-maint/tgt.git;a=summary 11 | Standards-Version: 3.9.7 12 | Homepage: http://stgt.sourceforge.net/ 13 | 14 | Package: tgt 15 | Architecture: linux-any 16 | Depends: ${shlibs:Depends}, ${misc:Depends}, lsb-base, libconfig-general-perl, sg3-utils 17 | Suggests: tgt-rbd 18 | Description: Linux SCSI target user-space daemon and tools 19 | The Linux target framework (tgt) allows a Linux system to provide SCSI 20 | devices (targets) over networked SCSI transports. 21 | . 22 | tgt consists of a user-space daemon and user-space tools currently 23 | supporting the following transports: 24 | . 25 | - iSCSI (SCSI over IP) 26 | - iSER (iSCSI over RDMA, using Infiniband) 27 | . 28 | tgt also supports different storage types for use as backing stores for SCSI 29 | Logical Units: 30 | . 31 | - Plain files and block devices 32 | - Ceph/RADOS RBD volumes 33 | - GlusterFS volumes 34 | - OpenvStorage volumes 35 | . 36 | This package includes the daemon and user-space tools. 37 | 38 | #Package: tgt-rbd 39 | #Architecture: linux-any 40 | #Depends: tgt (= ${binary:Version}), ${shlibs:Depends}, ${misc:Depends} 41 | #Description: Linux SCSI target user-space daemon and tools - RBD support 42 | # The Linux target framework (tgt) allows a Linux system to provide SCSI 43 | # devices (targets) over networked SCSI transports. 44 | # . 45 | # tgt consists of a user-space daemon and user-space tools currently 46 | # supporting the following transports: 47 | # . 48 | # - iSCSI (SCSI over IP) 49 | # - iSER (iSCSI over RDMA, using Infiniband) 50 | # . 51 | # tgt also supports different storage types for use as backing stores for SCSI 52 | # Logical Units: 53 | # . 54 | # - Plain files and block devices 55 | # - Ceph/RADOS RBD volumes 56 | # - GlusterFS volumes 57 | # - OpenvStorage volumes 58 | # . 59 | # This package enables tgt to use Ceph/RADOS block devices (RBD) as backing 60 | # store for SCSI Logical Units. 61 | 62 | Package: tgt-openvstorage 63 | Architecture: linux-any 64 | Depends: tgt (= ${binary:Version}), ${shlibs:Depends}, ${misc:Depends} 65 | Description: Linux SCSI target user-space daemon and tools - OpenvStorage support 66 | The Linux target framework (tgt) allows a Linux system to provide SCSI 67 | devices (targets) over networked SCSI transports. 68 | . 69 | tgt consists of a user-space daemon and user-space tools currently 70 | supporting the following transports: 71 | . 72 | - iSCSI (SCSI over IP) 73 | - iSER (iSCSI over RDMA, using Infiniband) 74 | . 75 | tgt also supports different storage types for use as backing stores for SCSI 76 | Logical Units: 77 | . 78 | - Plain files and block devices 79 | - Ceph/RADOS RBD volumes 80 | - GlusterFS volumes 81 | - OpenvStorage volumes 82 | . 83 | This package enables tgt to use OpenvStorage volumes as backing 84 | store for SCSI Logical Units. 85 | 86 | Package: tgt-dbg 87 | Architecture: linux-any 88 | Section: debug 89 | Priority: extra 90 | Depends: tgt (= ${binary:Version}), ${shlibs:Depends}, ${misc:Depends} 91 | Description: Linux SCSI target user-space daemon and tools - debug symbols 92 | The Linux target framework (tgt) allows a Linux system to provide SCSI 93 | devices (targets) over networked SCSI transports. 94 | . 95 | tgt consists of a user-space daemon and user-space tools currently 96 | supporting the following transports: 97 | . 98 | - iSCSI (SCSI over IP) 99 | - iSER (iSCSI over RDMA, using Infiniband) 100 | . 101 | tgt also supports different storage types for use as backing stores for SCSI 102 | Logical Units: 103 | . 104 | - Plain files and block devices 105 | - Ceph/RADOS RBD volumes 106 | - GlusterFS volumes 107 | - OpenvStorage volumes 108 | . 109 | This package contains symbols used for debugging tgt. 110 | -------------------------------------------------------------------------------- /debian/gbp.conf: -------------------------------------------------------------------------------- 1 | [DEFAULT] 2 | upstream-branch = upstream-sid 3 | debian-branch = debian-sid 4 | 5 | [buildpackage] 6 | export-dir = ../build-area/ 7 | -------------------------------------------------------------------------------- /debian/rules: -------------------------------------------------------------------------------- 1 | #!/usr/bin/make -f 2 | #export DH_VERBOSE=1 3 | 4 | FEATURES = ISCSI_RDMA=1 SD_NOTIFY=1 OPENVSTORAGE=1 5 | 6 | %: 7 | dh $@ --parallel --with systemd,bash-completion 8 | 9 | override_dh_auto_build: 10 | $(MAKE) $(FEATURES) 11 | 12 | override_dh_auto_install: 13 | $(MAKE) $(FEATURES) DESTDIR=$(CURDIR)/debian/tgt install 14 | 15 | override_dh_installinit: 16 | dh_installinit --no-restart-on-upgrade 17 | 18 | override_dh_install: 19 | dh_install 20 | rm -rf $(CURDIR)/debian/tgt/usr/lib 21 | 22 | override_dh_strip: 23 | dh_strip --dbg-package=tgt-dbg 24 | 25 | .PHONY: override_dh_auto_build override_dh_auto_install \ 26 | override_dh_installinit override_dh_install \ 27 | override_dh_strip 28 | -------------------------------------------------------------------------------- /debian/source/format: -------------------------------------------------------------------------------- 1 | 3.0 (quilt) 2 | -------------------------------------------------------------------------------- /debian/tests/admin: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | #--------------- 3 | # Testing tgtadm 4 | #--------------- 5 | 6 | for cmd in tgtadm tgt-admin tgtimg; do 7 | /usr/sbin/$cmd --help > /dev/null 2>&1 8 | RET=$? 9 | 10 | if [ $RET -ne 0 ]; then 11 | echo "ERROR, failed to run ${cmd}" >&2 12 | exit $RET 13 | fi 14 | done 15 | -------------------------------------------------------------------------------- /debian/tests/control: -------------------------------------------------------------------------------- 1 | Tests: daemon admin 2 | Depends: tgt 3 | 4 | Tests: storage 5 | Depends: tgt, tgt-rbd 6 | Restrictions: needs-root isolation-container allow-stderr 7 | -------------------------------------------------------------------------------- /debian/tests/daemon: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | #------------ 3 | # Testing tgt 4 | #------------ 5 | DAEMON=tgtd 6 | 7 | if pidof -x $DAEMON > /dev/null; then 8 | echo "OK" 9 | else 10 | echo "ERROR: ${DAEMON} IS NOT RUNNING" 11 | exit 1 12 | fi 13 | -------------------------------------------------------------------------------- /debian/tests/storage: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # Restart tgtd to make sure modules are loaded 4 | invoke-rc.d tgt restart || echo "Failed to restart tgt" >&2 5 | 6 | # Test tgtd module usability 7 | supported_bs=$(tgtadm --mode sys --op show | \ 8 | awk ' 9 | BEGIN { p = 0 }; 10 | /^[a-zA-Z]/ { p = 0 }; 11 | /^Backing stores/ { p = 1; getline; }; 12 | { if (p) { gsub("^ +", ""); print }; 13 | }') 14 | ret=0 15 | 16 | for bs in rbd; do 17 | if echo "$supported_bs" | grep -q "\b$bs\b"; then 18 | echo "OK - $bs supported" 19 | else 20 | echo "ERROR - $bs not supported" >&2 21 | ret=1 22 | fi 23 | done 24 | 25 | exit $ret 26 | -------------------------------------------------------------------------------- /debian/tgt-openvstorage.install: -------------------------------------------------------------------------------- 1 | debian/tgt/usr/lib/tgt/backing-store/bs_openvstorage.so usr/lib/tgt/backing-store 2 | -------------------------------------------------------------------------------- /debian/tgt-rbd.install: -------------------------------------------------------------------------------- 1 | debian/tgt/usr/lib/tgt/backing-store/bs_rbd.so usr/lib/tgt/backing-store 2 | -------------------------------------------------------------------------------- /debian/tgt.NEWS: -------------------------------------------------------------------------------- 1 | tgt (1:1.0.46-1) unstable; urgency=medium 2 | 3 | As of 1.0.46-1, tgt in Debian supports using Ceph RBD and GlusterFS volumes 4 | as backing store. The support is provided by tgt-rbd and tgt-glusterfs 5 | respectively. 6 | 7 | Also note that as of 1.0.19, upstream has dropped (the experimental) FCoE 8 | target support from tgt. 9 | 10 | -- Apollon Oikonomopoulos Mon, 19 May 2014 15:47:45 +0300 11 | -------------------------------------------------------------------------------- /debian/tgt.bash-completion: -------------------------------------------------------------------------------- 1 | scripts/tgt.bashcomp.sh tgt 2 | -------------------------------------------------------------------------------- /debian/tgt.docs: -------------------------------------------------------------------------------- 1 | doc/README.* 2 | -------------------------------------------------------------------------------- /debian/tgt.init: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | ### BEGIN INIT INFO 3 | # Provides: tgtd tgt 4 | # Required-Start: $remote_fs $syslog 5 | # Required-Stop: $remote_fs $syslog 6 | # Should-Start: zfs 7 | # Should-Stop: zfs 8 | # Default-Start: 2 3 4 5 9 | # Default-Stop: 0 1 6 10 | # Short-Description: iscsi target daemon 11 | # Description: iscsi target daemon 12 | ### END INIT INFO 13 | 14 | DESC="target framework daemon" 15 | NAME=tgtd 16 | DAEMON=/usr/sbin/${NAME} 17 | PIDFILE=/run/${NAME}.pid 18 | 19 | TGTD_CONFIG=/etc/tgt/targets.conf 20 | 21 | . /lib/lsb/init-functions 22 | 23 | [ -x $DAEMON ] || exit 0 24 | 25 | start() 26 | { 27 | log_daemon_msg "Starting $DESC" "$NAME" 28 | # Start tgtd first. 29 | if ! start-stop-daemon --start --quiet --oknodo --pidfile $PIDFILE \ 30 | --make-pidfile --background --exec $DAEMON -- -f; then 31 | log_end_msg 1 32 | exit 1 33 | fi 34 | 35 | log_end_msg 0 36 | # Put tgtd into "offline" state until all the targets are configured. 37 | # We don't want initiators to (re)connect and fail the connection 38 | # if it's not ready. 39 | tgtadm --op update --mode sys --name State -v offline 40 | # Configure the targets. 41 | tgt-admin -e -c $TGTD_CONFIG 42 | # Put tgtd into "ready" state. 43 | tgtadm --op update --mode sys --name State -v ready 44 | } 45 | 46 | stop() 47 | { 48 | # NOTE: Forced shutdown of the iscsi target may cause data corruption 49 | # for initiators that are connected. 50 | log_daemon_msg "Force-stopping $DESC" "$NAME" 51 | # Offline everything first. May be needed if we're rebooting, but 52 | # expect the initiators to reconnect cleanly when we boot again 53 | # (i.e. we don't want them to reconnect to a tgtd which is still 54 | # working, but the target is gone). 55 | tgtadm --op update --mode sys --name State -v offline >/dev/null 2>&1 56 | RETVAL=$? 57 | if [ "$RETVAL" -eq 107 ] ; then 58 | # tgtd not running 59 | log_end_msg 0 60 | else 61 | tgt-admin --offline ALL 62 | # Remove all targets, even if they are still in use. 63 | tgt-admin --update ALL -c /dev/null -f 64 | # It will shut down tgtd only after all targets were removed. 65 | tgtadm --op delete --mode system 66 | RETVAL=$? 67 | if [ "$RETVAL" -ne 0 ] ; then 68 | log_end_msg 1 69 | echo "Failed to shutdown tgtd" 70 | exit 1 71 | fi 72 | log_end_msg 0 73 | rm -f $PIDFILE 74 | fi 75 | } 76 | 77 | reload() 78 | { 79 | log_daemon_msg "Reloading configuration of $DESC" "$NAME" 80 | # Update configuration for targets. Only targets which 81 | # are not in use will be updated. 82 | tgt-admin --update ALL -c $TGTD_CONFIG >/dev/null 2>&1 83 | RETVAL=$? 84 | if [ "$RETVAL" -eq 107 ] ; then 85 | log_end_msg 1 86 | echo "tgtd is not running" 87 | exit 1 88 | fi 89 | log_end_msg 0 90 | } 91 | 92 | forcedreload() 93 | { 94 | log_daemon_msg "Forced-reload configuration of $DESC" "$NAME" 95 | # Update configuration for targets, even those in use. 96 | tgt-admin --update ALL -f -c $TGTD_CONFIG >/dev/null 2>&1 97 | RETVAL=$? 98 | if [ "$RETVAL" -eq 107 ] ; then 99 | log_end_msg 1 100 | echo "tgtd is not running" 101 | exit 1 102 | else 103 | log_end_msg 0 104 | fi 105 | } 106 | 107 | case $1 in 108 | start) 109 | start 110 | ;; 111 | stop|forcedstop) 112 | stop 113 | ;; 114 | restart|forcedrestart) 115 | stop && start 116 | ;; 117 | reload) 118 | reload 119 | ;; 120 | force-reload) 121 | forcedreload 122 | ;; 123 | status) 124 | status_of_proc -p $PIDFILE /usr/sbin/tgtd tgtd 125 | exit $? 126 | ;; 127 | *) 128 | echo "Usage: $0 {start|stop|forcedstop|restart|forcedrestart|reload|force-reload|status}" 129 | exit 2 130 | ;; 131 | esac 132 | 133 | -------------------------------------------------------------------------------- /debian/tgt.postinst: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | 4 | # We may have been unable to stop tgtd during prerm, so at least create the 5 | # pidfile for the initscript to continue working. 6 | if [ ! -f /run/tgtd.pid ] && pidof /usr/sbin/tgtd >/dev/null; then 7 | pidof -s /usr/sbin/tgtd >/run/tgt.pid 8 | fi 9 | 10 | #DEBHELPER# 11 | -------------------------------------------------------------------------------- /debian/tgt.prerm: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | 4 | # Stop tgtd if no initiators are currently connected (package removal is 5 | # handled by dh below). This is a bit racey but simpler and more robust than 6 | # setting tgtd into and out of offline mode. 7 | if [ -x /etc/init.d/tgt ]; then 8 | if ! tgtadm --mode target --op show | grep -q Connection; then 9 | invoke-rc.d tgt stop 10 | fi 11 | fi 12 | 13 | #DEBHELPER# 14 | -------------------------------------------------------------------------------- /debian/tgt.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=(i)SCSI target daemon 3 | Documentation=man:tgtd(8) 4 | After=network.target 5 | 6 | [Service] 7 | Type=notify 8 | ExecStart=/usr/sbin/tgtd -f 9 | ExecStartPost=/usr/sbin/tgtadm --op update --mode sys --name State -v offline 10 | ExecStartPost=/usr/sbin/tgt-admin -e -c /etc/tgt/targets.conf 11 | ExecStartPost=/usr/sbin/tgtadm --op update --mode sys --name State -v ready 12 | 13 | ExecStop=/usr/sbin/tgtadm --op update --mode sys --name State -v offline 14 | ExecStop=/usr/sbin/tgt-admin --offline ALL 15 | ExecStop=/usr/sbin/tgt-admin --update ALL -c /dev/null -f 16 | ExecStop=/usr/sbin/tgtadm --op delete --mode system 17 | 18 | ExecReload=/usr/sbin/tgt-admin --update ALL -c /etc/tgt/targets.conf 19 | Restart=on-failure 20 | 21 | [Install] 22 | WantedBy=multi-user.target 23 | -------------------------------------------------------------------------------- /debian/watch: -------------------------------------------------------------------------------- 1 | version=3 2 | https://github.com/fujita/tgt/tags .*/archive/v([\d.]+)\.tar\.gz 3 | -------------------------------------------------------------------------------- /doc/Makefile: -------------------------------------------------------------------------------- 1 | mandir ?= $(PREFIX)/share/man 2 | docdir ?= $(PREFIX)/share/doc/tgt 3 | 4 | MANPAGES = manpages/tgtadm.8 manpages/tgt-admin.8 manpages/tgtimg.8 \ 5 | manpages/tgt-setup-lun.8 manpages/tgtd.8 6 | 7 | DOCS = README.iscsi README.iser \ 8 | README.lu_configuration README.mmc tmf.txt \ 9 | README.rbd 10 | 11 | XSLTPROC = /usr/bin/xsltproc 12 | XMLMAN = manpages/tgtd.8 manpages/tgtadm.8 manpages/tgtimg.8 \ 13 | manpages/tgt-admin.8 manpages/targets.conf.5 \ 14 | manpages/tgt-setup-lun.8 15 | XMLHTML = htmlpages/tgtd.8.html htmlpages/tgtadm.8.html \ 16 | htmlpages/tgtimg.8.html htmlpages/tgt-admin.8.html \ 17 | htmlpages/targets.conf.5.html htmlpages/tgt-setup-lun.8.html 18 | 19 | .PHONY:all 20 | all: xmlman 21 | 22 | .PHONY: install 23 | install: $(MANPAGES) $(DOCS) 24 | install -d -m 755 $(DESTDIR)$(mandir)/man8 25 | install -m 644 $(MANPAGES) $(DESTDIR)$(mandir)/man8 26 | install -d -m 755 $(DESTDIR)$(docdir) 27 | install -m 644 $(DOCS) $(DESTDIR)$(docdir) 28 | 29 | .PHONY: clean 30 | clean: 31 | rm -f $(XMLMAN) $(XMLHTML) 32 | -rm -f manpages htmlpages 33 | 34 | manpages/tgtd.8: tgtd.8.xml 35 | -test -z "$(XSLTPROC)" || $(XSLTPROC) -o $@ /usr/share/xml/docbook/stylesheet/docbook-xsl/manpages/docbook.xsl $< 36 | 37 | htmlpages/tgtd.8.html: tgtd.8.xml 38 | -test -z "$(XSLTPROC)" || $(XSLTPROC) -o $@ /usr/share/xml/docbook/stylesheet/docbook-xsl/html/docbook.xsl $< 39 | 40 | manpages/tgtadm.8: tgtadm.8.xml 41 | -test -z "$(XSLTPROC)" || $(XSLTPROC) -o $@ /usr/share/xml/docbook/stylesheet/docbook-xsl/manpages/docbook.xsl $< 42 | 43 | htmlpages/tgtadm.8.html: tgtadm.8.xml 44 | -test -z "$(XSLTPROC)" || $(XSLTPROC) -o $@ /usr/share/xml/docbook/stylesheet/docbook-xsl/html/docbook.xsl $< 45 | 46 | manpages/tgt-admin.8: tgt-admin.8.xml 47 | -test -z "$(XSLTPROC)" || $(XSLTPROC) -o $@ /usr/share/xml/docbook/stylesheet/docbook-xsl/manpages/docbook.xsl $< 48 | 49 | htmlpages/tgt-admin.8.html: tgt-admin.8.xml 50 | -test -z "$(XSLTPROC)" || $(XSLTPROC) -o $@ /usr/share/xml/docbook/stylesheet/docbook-xsl/html/docbook.xsl $< 51 | 52 | manpages/tgtimg.8: tgtimg.8.xml 53 | -test -z "$(XSLTPROC)" || $(XSLTPROC) -o $@ /usr/share/xml/docbook/stylesheet/docbook-xsl/manpages/docbook.xsl $< 54 | 55 | htmlpages/tgtimg.8.html: tgtimg.8.xml 56 | -test -z "$(XSLTPROC)" || $(XSLTPROC) -o $@ /usr/share/xml/docbook/stylesheet/docbook-xsl/html/docbook.xsl $< 57 | 58 | manpages/targets.conf.5: targets.conf.5.xml 59 | -test -z "$(XSLTPROC)" || $(XSLTPROC) -o $@ /usr/share/xml/docbook/stylesheet/docbook-xsl/manpages/docbook.xsl $< 60 | 61 | htmlpages/targets.conf.5.html: targets.conf.5.xml 62 | -test -z "$(XSLTPROC)" || $(XSLTPROC) -o $@ /usr/share/xml/docbook/stylesheet/docbook-xsl/html/docbook.xsl $< 63 | 64 | manpages/tgt-setup-lun.8: tgt-setup-lun.8.xml 65 | -test -z "$(XSLTPROC)" || $(XSLTPROC) -o $@ /usr/share/xml/docbook/stylesheet/docbook-xsl/manpages/docbook.xsl $< 66 | 67 | htmlpages/tgt-setup-lun.8.html: tgt-setup-lun.8.xml 68 | -test -z "$(XSLTPROC)" || $(XSLTPROC) -o $@ /usr/share/xml/docbook/stylesheet/docbook-xsl/html/docbook.xsl $< 69 | 70 | xmlman: $(XMLMAN) 71 | 72 | xmlhtml: $(XMLHTML) 73 | 74 | -------------------------------------------------------------------------------- /doc/README.dvdjukebox: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # This is a script to set up a SCSI DVD JUKEBOX for all your ISO images. 4 | # 5 | # This script should be run from a directory that contains ISO images 6 | # with the extension .iso . 7 | # When run, the script will create an iSCSI target containing one DVD drive 8 | # and one media changer. The DVD drive will not have a disk mounted but 9 | # the medium changer will have one slot for each ISO image found. 10 | # Use the 'mtx' tool to load/unload media. 11 | # 12 | # By default, any ISO images found will be populated with a barcode of the 13 | # form DVD_%04d and a volume_tag based on the filename. 14 | # 15 | # CON: This is the connection index for TGTD. This is needed if you run 16 | # multiple instances of TGTD on the same host. Each instance must use a unique 17 | # CON value. 18 | # 19 | # TARGETNAME: The iSCSI name to use for the target. 20 | # 21 | # TARGETPORT: The TCP port that this target will be hosted from. 22 | 23 | CON=1 24 | TARGETNAME=iqn.ronnie.iso:distros 25 | TARGETPORT=3261 26 | 27 | nc -z 127.0.0.1 $TARGETPORT || { 28 | echo "Starting iSCSI target on port $TARGETPORT" 29 | tgtd -C $CON --iscsi portal=0.0.0.0:$TARGETPORT 30 | sleep 3 31 | } 32 | 33 | tgtadm -C $CON --op delete --mode target --tid 1 --force 2>/dev/null 34 | tgtadm -C $CON --op new --mode target --tid 1 -T $TARGETNAME 35 | 36 | # Create a DVD drive 37 | tgtadm -C $CON --op new --mode logicalunit --tid 1 --lun 1 -Y cd 38 | tgtadm -C $CON --op update --mode logicalunit --tid 1 --lun 1 --params vendor_id=STGT_DVD,product_id=DVD101,product_rev=0010,scsi_sn=STGTDVD01,removable=1 39 | 40 | # We need a backend store file for the media changer 41 | SMC=`pwd`/smc-$CON 42 | if [ ! -f $SMC ]; then 43 | dd if=/dev/zero of=$SMC bs=1k count=1 44 | fi 45 | 46 | # Create the SMC device and give it a nice name 47 | tgtadm -C $CON --mode logicalunit --op new --tid 1 --lun 2 -b $SMC --device-type=changer 48 | tgtadm -C $CON --mode logicalunit --op update --tid 1 --lun 2 --params vendor_id=STK,product_id=L700,product_rev=0010,scsi_sn=XYZZY_0,removable=1 49 | 50 | # Add a Data Transfer devices (1 drive) 51 | tgtadm -C $CON --mode logicalunit --op update --tid 1 --lun 2 --params element_type=4,start_address=1,quantity=1 52 | 53 | # Specify that the DVD above (LUN 1) is the data transfer device we created 54 | tgtadm -C $CON --mode logicalunit --op update --tid 1 --lun 2 --params element_type=4,address=1,tid=1,lun=1 55 | 56 | # Medium Transport Elements (robot arm / picker) 57 | tgtadm -C $CON --mode logicalunit --op update --tid 1 --lun 2 --params element_type=1,start_address=16,quantity=1 58 | 59 | 60 | # define path to virtual media 61 | VTL=`pwd`/vtl 62 | mkdir -p ${VTL} 2>/dev/null 63 | rm ${VTL}/* 64 | tgtadm -C $CON --mode logicalunit --op update --tid 1 --lun 2 --params media_home=${VTL} 65 | 66 | NUM_ELEM=`ls *.iso | wc -l` 67 | echo "Creating $NUM_ELEM storage elements for media" 68 | 69 | # Storage Elements - starting at addr 1024 70 | tgtadm -C $CON --mode logicalunit --op update --tid 1 --lun 2 --params element_type=2,start_address=1024,quantity=$NUM_ELEM 71 | 72 | # Populate the slots 73 | SLOT=0 74 | ls *.iso | sed -e "s/.iso$//" | while read ISO; do 75 | BARCODE=`echo $SLOT | awk '{printf "DVD_%04d", $1}'` 76 | ln `pwd`/${ISO}.iso ${VTL}/${BARCODE} 77 | tgtadm -C $CON --mode logicalunit --op update --tid 1 --lun 2 --params element_type=2,address=`expr "1024" "+" "$SLOT"`,barcode="${BARCODE}",volume_tag="${ISO}",sides=1 78 | 79 | SLOT=`expr "$SLOT" "+" "1"` 80 | done 81 | 82 | tgtadm -C $CON --op bind --mode target --tid 1 -I ALL 83 | tgtadm -C $CON --op show --mode target 84 | -------------------------------------------------------------------------------- /doc/README.glfs: -------------------------------------------------------------------------------- 1 | The 'glfs' backing-store driver provides block access to a file within the 2 | gluster distributed file system (www.gluster.org). The file represents a 3 | LUN visible to the initiator (the file may be a regular file in gluster's 4 | underlying XFS filesystem, or a gluster "block device"). This configuration 5 | gives gluster support for any access method supported by the target driver, 6 | such as iSCSI. 7 | 8 | The backing-store driver uses the interfaces to gluster in libgfapi.so. 9 | This file is part of the glusterfs-api package which can be downloaded from 10 | www.gluster.org. 11 | 12 | To build the glfs backing store driver, set the GLFS_BS environment 13 | variable (export GLFS_BD=1) before running Make. 14 | 15 | When a LUN on a target is created with backing store of type glfs (--bstype 16 | glfs), a handle to gluster is created. The handle is destroyed when the 17 | target is closed. The handle represents a particular volume on a gluster 18 | server and a particular file representing the LUN. 19 | 20 | To set the gluster volume and file, --backing-store takes the form: 21 | volume@hostname:filename 22 | 23 | For example, if the volume name was vol1 , and the host gprfs010, and file 24 | name was "disk1", you would set --backing-store to: 25 | 26 | --backing-store="vol1@gprfs010:disk1" 27 | 28 | For each CDB, the driver issues an appropriate gluster api call against the 29 | handle. For example, WRITE_16 becomes glfs_pwrite(), SYNCHRONIZE_CACHE 30 | becomes glfs_fdatasync() and UNMAP becomes glfs_discard(). 31 | 32 | Each call is synchronous, meaning the thread will wait for a response from 33 | gluster before returning to the caller. The libgfapi interfaces support 34 | asynchronous calls, and an asynchronous version of the driver has been 35 | tested. For more information on the asynchronous version please contact 36 | dlambrig@redhat.com. 37 | 38 | If the backing store driver was not used, the linux target driver could 39 | still write data to gluster by loopback mounting the gluster file system. 40 | The backing-store would be a file within the file system. Gluster uses FUSE 41 | to forward I/O from the kernel to it's user space daemon. The overhead 42 | incured by FUSE and the kernel is removed when the backing store driver and 43 | libgfapi package is used. 44 | 45 | The libgfapi interfaces supports logs. You can use the --bsopts option to 46 | set the logfile and loglevel. 47 | 48 | --bsops="logfile=glfs.log;loglevel=3" 49 | 50 | 51 | -------------------------------------------------------------------------------- /doc/README.lu_configuration: -------------------------------------------------------------------------------- 1 | Preface 2 | -------------- 3 | This show a simple example to set up some logical units (lu). 4 | Please refer to README.iscsi on instructions to create logical unit(s). 5 | 6 | tgtadm options 7 | -------------- 8 | You are able to modify some logical unit parameters as well as 9 | modify behaviour of SCSI Sense op code. 10 | 11 | NOTE: It is not recommended to change these parameters after the 12 | target/logical unit has been enabled to accept initiators. 13 | 14 | It is currently possible to change/modify the following: 15 | 16 | Vendor Identification 17 | Product Identification 18 | Product Revision 19 | Format of returned 'sense data' 20 | Define if the lu is capable of supporting removable media 21 | Define/set if the lu is online / offline. 22 | Params are passed using the 'tgtadm' utility: 23 | 24 | Format of options are: 25 | vendor_id="string" 26 | product_id="string" 27 | product_rev="string" 28 | removable=<0|1> - 0 = non-removable, 1 = removable media 29 | sense_format=<0|1> - 0 = Clasic sense format, 1 = Support descriptor format 30 | online=<0|1> - 0 == Unit offline, 1 == Unit Online 31 | 32 | The options are passed to the logical unit via the "--params" switch to tgtadm 33 | 34 | e.g. 35 | tgtadm --lld iscsi --mode logicalunit --op update --tid --lun \ 36 | --params vendor_id=QUANTUM,product_id=HD100,product_rev=0010 37 | tgtadm --lld iscsi --mode logicalunit --op update --tid --lun \ 38 | --params removable=1,sense_format=1,online=1 39 | 40 | Or it can be performed in one go: 41 | tgtadm --lld iscsi --mode logicalunit --op update --tid --lun \ 42 | --params vendor_id=QUANTUM,product_id=HD100,product_rev=0010,scsi_sn=FRED00,removable=1,sense_format=0,online=1 43 | 44 | 45 | # sg_inq -v /dev/sg5 46 | inquiry cdb: 12 00 00 00 24 00 47 | standard INQUIRY: 48 | inquiry cdb: 12 00 00 00 42 00 49 | PQual=0 Device_type=0 RMB=1 version=0x05 [SPC-3] 50 | [AERC=0] [TrmTsk=1] NormACA=0 HiSUP=0 Resp_data_format=2 51 | SCCS=0 ACC=0 TGPS=0 3PC=0 Protect=0 BQue=0 52 | EncServ=0 MultiP=0 [MChngr=0] [ACKREQQ=0] Addr16=0 53 | [RelAdr=0] WBus16=0 Sync=0 Linked=0 [TranDis=0] CmdQue=1 54 | Clocking=0x0 QAS=0 IUS=0 55 | length=66 (0x42) Peripheral device type: disk 56 | Vendor identification: QUANTUM 57 | Product identification: HD100 58 | Product revision level: 0010 59 | inquiry cdb: 12 01 00 00 fc 00 60 | inquiry: requested 252 bytes but got 7 bytes 61 | inquiry cdb: 12 01 80 00 fc 00 62 | inquiry: requested 252 bytes but got 12 bytes 63 | Unit serial number: FRED00 64 | 65 | As can be seen from above 'sg_inq' output, the RMB (removable) bit is set to 1. 66 | The Unit serial number page updated with 'FRED00' 67 | 68 | Mode Page Creation 69 | ------------------ 70 | Create mode page '2', subpage 0 and 14 bytes of data. 71 | tgtadm --mode logicalunit --op update --tid 1 --lun 2 \ 72 | --params mode_page=2:0:14:0x80:0x80:0:0xa:0:0:0:0:0:0:0:0:0:0 73 | 74 | Create mode page '3', subpage 0 and 22 bytes of data. 75 | tgtadm --lld iscsi --mode logicalunit --op update --tid 1 --lun 2 \ 76 | --params mode_page=3:0:22:0:0:0:0:0:0:0:0:1:0:2:0:0:0:0:0:0:0:0:13:0:0 77 | 78 | Create mode page '10', subpage 0 and 10 bytes of data. 79 | tgtadm --lld iscsi --mode logicalunit --op update --tid 1 --lun 2 \ 80 | --params mode_page=10:0:10:2:0:0:0:0:0:0:0:2:0 81 | 82 | Create mode page '0x1c', subpage 0 and 10 bytes of data. 83 | tgtadm --lld iscsi --mode logicalunit --op update --tid 1 --lun 2 \ 84 | --params mode_page=0x1c:0:10:8:0:0:0:0:0:0:0:0:0 85 | 86 | 87 | SMC unique options 88 | ------------------ 89 | 90 | --params have several unique key=value pairs ontop of all other modules. 91 | - element_type=<1|2|3|4> 92 | - start_address=Number between 1 & 65535 93 | - quantity=Number between 1 & 65535 94 | - sides=1|2 95 | - address=Number between 1 & 65535 96 | - barcode="Char string up to 10 chars" 97 | - tid= 98 | - lun= 99 | - media_home=/path/to/virtual/media 100 | The 'barcode' of media is appended to this path specified in media_home and 101 | it is this file which is used for the backing store when reading/writing to 102 | DATA TRANSFER DEVICE at address 'tid=x lun=x' 103 | 104 | Several of these parameters 'work together' 105 | 106 | e.g. To add 'quantity' slots as 'element_type' starting at 'start_address' 107 | - element_type=<1|2|3|4> 108 | - start_address=Number between 1 & 65535 109 | - quantity=Number between 1 & 65535 110 | 111 | Note: start_address + quantity should not overlap with any other slots.. 112 | 113 | 114 | While 'configuring slot 'address' of 'element_type': 115 | - Set barcode of meda (occupy slot) 116 | - If element type is DATA TRANSFER DEVICE, then define TID & LUN of device. 117 | 118 | - element_type=<1|2|3|4> 119 | - address=Number between 1 & 65535 120 | - barcode="String up to 10 chars" 121 | - sides=<1|2> 122 | - tid= 123 | - lun= 124 | 125 | 126 | It is the responsibility of the user not to configure overlapping slots 127 | of differing types. 128 | 129 | Slot types: 130 | 1 -> Medium Transport (picker arm) 131 | 2 -> Storage Element 132 | 3 -> Import/Export Element 133 | 4 -> Data Transfer device (CD drive, tape drive, MO drive etc) 134 | 135 | Please refer to scripts/tgt-core-test for a working example. 136 | 137 | -------------------------------------------------------------------------------- /doc/README.rbd: -------------------------------------------------------------------------------- 1 | The 'rbd' backing-store driver provides access to Ceph (http://ceph.com) 2 | 'RADOS block devices (rbd)" through tgtd. 3 | 4 | Ceph is a distributed storage system that provides clustered redundant 5 | object storage; one of the ways to use such storage is through the 6 | abstraction of a "block device". rbd devices can be mapped through a 7 | kernel driver and show up as block devices directly, or they can be used 8 | through userland libraries to provide backing store for things like QEMU 9 | virtual disks. 10 | 11 | The bs_rbd backing-store driver allows tgtd to use rbd images as backing 12 | storage without requiring the 'rbd' kernel block device driver, and so 13 | avoids kernel version dependencies and the extra context switching between 14 | kernel and userland. It also allows for userland caching of block images, 15 | managed by librbd. 16 | 17 | To use bs_rbd, select --bstype rbd, and set --backing-store to an rbd 18 | image specifier. This is of the form 19 | 20 | [poolname/]imagename[@snapname] 21 | 22 | where poolname is the RADOS pool containing the rbd image (defaults to 23 | "rbd"), imagename is the image you want to export, and snapname is the 24 | optional (readonly) snapshot of the image imagename. (Obviously when 25 | a snapshot is exported, writes are not supported.) 26 | 27 | You may also want to use the --bsopts parameter to pass Ceph-specific 28 | parameters to bs_rbd. Accepted keywords are 29 | 30 | conf= 31 | 32 | This sets the path to the ceph.conf file for the cluster that 33 | stgt should connect to for this target/lun creation (luns may 34 | use different cluster connections). 35 | 36 | id= 37 | 38 | This sets the id portion of the ceph "client name" (which is 39 | "type.id"). Type is fixed at "client", and the default name is 40 | "client.admin", but you probably want this to set id to 41 | something like "tgt" so that the name of the ceph client is 42 | "client.tgt". This lets you control permissions differently 43 | for the tgt client compared to others, and sets the default log path, etc. 44 | See the Ceph documentation regarding client names. 45 | 46 | cluster= 47 | 48 | This sets the Ceph cluster name, if you have multiple clusters or 49 | if your cluster name is anything other than "ceph". 50 | This is in turn used by librados to find the conf file and key files. 51 | 52 | To specify multiple options, separate them with ';', and since you are, 53 | make sure to quote the option string to protect the semicolon from 54 | the shell: 55 | 56 | --bsopts "conf=/usr/local/ceph/ceph.conf;id=tgt" 57 | 58 | -------------------------------------------------------------------------------- /doc/README.sbcjukebox: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # EXAMPLE of sbc jukebox 3 | # 4 | # This is a simple script to create and drive a sbcjukebox that contains 5 | # the $NUMSLOT most recent snapshots of a production SBC LUN. 6 | # It requires that you store the LUN files on a filesystem that can create 7 | # file level cow snapshots using "cp --reflink". 8 | # On linux this is supported on BTRFS and possibly other filesystems too. 9 | # 10 | # It creates a new target with one SBC decice and a mediachanger. 11 | # 12 | # 13 | # TID is the target id to use 14 | # TNAME is the target iqn name to use 15 | # FILE is the backing store file for a production LUN. This file must reside on 16 | # a cow snapshot capable filesystem. 17 | # SNAPDIR is where we keep the SMC media file as well as where all snapshots are 18 | # kept. This must be the same filesystem as FILE 19 | # NUMSLOTS is how many old snapshots we want to keep. 20 | # READONLYSNAPS is whether or not the snapshot device is readonly or not 21 | 22 | # sbcjukebox.sh start 23 | # to create the target and populate the storage elements. 24 | # 25 | # sbcjukebox.sh list 26 | # to show which snapshots are available 27 | # 28 | # sbcjukebox.sh snapshot 29 | # to take a new snapshot of the production LUN 30 | # 31 | 32 | 33 | 34 | TID=2 35 | TNAME="iqn.ronnie.test-snapshot" 36 | FILE="/data/RHEL6/RHEL6-1.img" 37 | SNAPDIR="${FILE}.snapshots" 38 | NUMSLOTS=8 39 | READONLYSNAPS="yes" 40 | 41 | 42 | [ -d "$SNAPDIR" ] || mkdir "$SNAPDIR" 43 | 44 | usage() { 45 | echo "sbcjukebox {start|list|snapshot|usage}" 46 | } 47 | 48 | prune_old_snapshots() { 49 | ls $SNAPDIR | egrep -v "^smc$" | sort -n -r | tail -n +${NUMSLOTS} | while read OLD; do 50 | echo "Deleting old snapshot $OLD" 51 | rm -f ${SNAPDIR}/${OLD} 52 | done 53 | } 54 | 55 | populate_elements() { 56 | ELEMENT=1024 57 | SNAPSHOTS=`ls $SNAPDIR | egrep -v "^smc$" | sort -n | head -n ${NUMSLOTS}` 58 | for SNAP in $SNAPSHOTS; do 59 | tgtadm --mode logicalunit --op update --tid $TID --lun 2 --params element_type=2,address=$ELEMENT,barcode=$SNAP,sides=1 60 | ELEMENT=`expr "$ELEMENT" "+" "1"` 61 | done 62 | 63 | LAST=`expr "1024" "+" "$NUMSLOTS"` 64 | while [ $ELEMENT -lt $LAST ]; do 65 | tgtadm --mode logicalunit --op update --tid $TID --lun 2 --params element_type=2,address=$ELEMENT,clear_slot=1 66 | ELEMENT=`expr "$ELEMENT" "+" "1"` 67 | done 68 | 69 | tgtadm --mode logicalunit --op update --tid $TID --lun 2 --params element_type=2,address=`expr "$LAST" "-" "1"`,clear_slot=1 70 | } 71 | 72 | snapshot() { 73 | SNAP=`date +"%y%m%d%H%M"` 74 | 75 | echo Create snapshot $SNAP 76 | cp --reflink $FILE $SNAPDIR/$SNAP 77 | 78 | prune_old_snapshots 79 | populate_elements 80 | } 81 | 82 | list() { 83 | echo Snapshots: 84 | ls $SNAPDIR | egrep -v "^smc$" 85 | } 86 | 87 | start() { 88 | #create a target 89 | tgtadm --lld iscsi --op new --mode target --tid $TID -T $TNAME 90 | 91 | # create the data transfer device 92 | tgtadm --op new --mode logicalunit --tid $TID --lun 1 -Y disk 93 | tgtadm --op update --mode logicalunit --tid $TID --lun 1 --params vendor_id=STGT,product_id=SNAPSHOT_SBC,product_rev=0010 94 | 95 | [ "$READONLYSNAPS" != "yes" ] || { 96 | tgtadm --op update --mode logicalunit --tid $TID --lun 1 --params readonly=1 97 | } 98 | 99 | # create backing store for SMC 100 | [ -f "${SNAPDIR}/smc" ] || dd if=/dev/zero of="${SNAPDIR}/smc" bs=1k count=1 101 | 102 | # create the media changer 103 | tgtadm --op new --mode logicalunit --tid $TID --lun 2 -b "${SNAPDIR}/smc" --device-type=changer 104 | tgtadm --op update --mode logicalunit --tid $TID --lun 2 --params vendor_id=STGT,product_id=SNAPSHOT_SMC,product_rev=0010,removable=1 105 | 106 | # Add a Data Transfer devices (1 drive) 107 | tgtadm --op update --mode logicalunit --tid $TID --lun 2 --params element_type=4,start_address=1,quantity=1 108 | 109 | # Specify that the DISK above (LUN 1) is the data transfer device 110 | tgtadm --op update --mode logicalunit --tid $TID --lun 2 --params element_type=4,address=1,tid=$TID,lun=1 111 | 112 | # Medium Transport Elements (robot arm / picker) 113 | tgtadm --op update --mode logicalunit --tid $TID --lun 2 --params element_type=1,start_address=16,quantity=1 114 | 115 | # define path to virtual media 116 | tgtadm --op update --mode logicalunit --tid $TID --lun 2 --params media_home=${SNAPDIR} 117 | 118 | # create the storage elements 119 | tgtadm --op update --mode logicalunit --tid $TID --lun 2 --params element_type=2,start_address=1024,quantity=$NUMSLOTS 120 | 121 | prune_old_snapshots 122 | populate_elements 123 | 124 | tgtadm --lld iscsi --op bind --mode target --tid $TID -I ALL 125 | tgtadm --lld iscsi --op show --mode target 126 | } 127 | 128 | case "$1" in 129 | start) 130 | start 131 | ;; 132 | snapshot) 133 | snapshot 134 | ;; 135 | list) 136 | list 137 | ;; 138 | *) 139 | usage 140 | ;; 141 | esac 142 | 143 | -------------------------------------------------------------------------------- /doc/README.sheepdog: -------------------------------------------------------------------------------- 1 | Sheepdog is a distributed storage system for QEMU, iSCSI clients and 2 | RESTful services. It provides highly available block level storage 3 | volumes that can be attached to QEMU-based virtual machines. The 4 | volumes can also be attached to other virtual machines and operating 5 | systems run on baremetal hardware if they support iSCSI 6 | protocol. Sheepdog scales to several hundreds nodes, and supports 7 | advanced volume management features such as snapshot, cloning, and 8 | thin provisioning. Stuff like volumes, snapshots, QEMU's vm-state 9 | (from live snapshot), even ISO files can be stored in the Sheepdog 10 | cluster. 11 | 12 | With tgt, sheepdog's virtual disks can be used by iSCSI 13 | initiators. Below is a brief description of setup. 14 | 15 | 1. Install and launch tgt 16 | 17 | $ git clone https://github.com/fujita/tgt.git 18 | $ cd tgt 19 | $ make 20 | # make install 21 | 2. Create a sheepdog VDI 22 | 23 | There is no special procedures in this step. 24 | 25 | $ dog vdi create tgt0 100G 26 | Of course you can use existing VDIs as iSCSI logical units. 27 | 28 | 3. Setup iSCSI target provided by tgt 29 | 30 | One logical unit corresponds to one VDI of sheepdog. In this step, we 31 | create iSCSI target and logical unit which can be seen by iSCSI 32 | initiator. 33 | 34 | # tgtd 35 | # tgtadm --op new --mode target --tid 1 --lld iscsi --targetname iqn.2013-10.org.sheepdog-project 36 | # tgtadm --op new --mode lu --tid 1 --lun 2 --bstype sheepdog --backing-store unix:/sheep_store/sock:tgt0 37 | # tgtadm --lld iscsi --op bind --mode target --tid 1 -I ALL 38 | 39 | The most important parameter is --backing-store which is required by 40 | tgtadm when we create the logical unit in the target (the third line 41 | of the above commands). With this parameter, we tell the tgtd 42 | process how to connect to the sheep process, which VDI we use as the 43 | logical unit, which snapshot ID of the VDI we use. The form of the 44 | --backing-store option is like this: 45 | 46 | unix:path_of_unix_domain_socket:vdi 47 | unix:path_of_unix_domain_socket:vdi:tag 48 | unix:path_of_unix_domain_socket:vdi:snapid 49 | tcp:host:port:vdi 50 | tcp:host:port:vdi:tag 51 | tcp:host:port:vdi:snapid 52 | 53 | We use a special case of the first one in the above command 54 | sequence. It means "connect to sheep process via unix domain socket 55 | protocol, path of unix domain socket is /sheep_store/sock, use VDI 56 | named tgt0 as a backing store of newly created logical unit". 57 | 58 | You can also specify sheep which is running on remote host via 59 | TCP. But if tgtd process is running on a same host of sheep process, 60 | there is no benefit of using TCP. Unix domain socket can provide 61 | faster connection than TCP. 62 | 63 | You can also specify tag or ID of snapshots via suffix of the 64 | --backing-store option. 65 | 66 | 4. Setup iSCSI session (example of the open-iscsi initiator on Linux) 67 | 68 | After setting up iSCSI target, you can use the VDIs from any virtual 69 | machines and operating systems which supports iSCSI initiator. Many of 70 | popular hypervisors and operating systems support it (e.g. VMware ESX 71 | Family, Linux, Windows, etc). In this example, the way of Linux + 72 | open-iscsi is described. 73 | 74 | At first, you have to install open-iscsi ( http://www.open-iscsi.org/ 75 | ) and launch it. Major linux distros provide their open-iscsi 76 | package. Below is a way of installation in Debian and Ubuntu based 77 | systems. 78 | 79 | # apt-get install open-iscsi 80 | # /etc/init.d/open-iscsi start 81 | 82 | Next, we need to let iscsid discover and login to the target we've 83 | already created in the above sequence. If the initiator is running 84 | on different host from the target, you have to change the IP 85 | addresses in the below commands. 86 | 87 | # iscsiadm -m discovery -t st -p 127.0.0.1 88 | # iscsiadm -m node --targetname iqn.2013-10.org.sheepdog-project --portal 127.0.0.1:3260 --login 89 | 90 | New device files, e.g. /dev/sdb, will be created on your system after 91 | login completion. Now your system can use the speepdog VDIs like 92 | ordinal HDDs. 93 | 94 | ToDo 95 | 96 | Currently, iSCSI multipath is not supported by sheepdog. It will be 97 | implemented in v0.9.0. 98 | 99 | The latest version of this guide can be found here: 100 | https://github.com/sheepdog/sheepdog/wiki/General-protocol-support-%28iSCSI-and-NBD%29 101 | -------------------------------------------------------------------------------- /doc/README.ssc: -------------------------------------------------------------------------------- 1 | Introduction 2 | ------------- 3 | The SSC emulation in TGTD can emulate tape drives by using files. This 4 | virtualization technology is known as a virtual tape library (VTL). 5 | 6 | 7 | Solaris tips 8 | ------------- 9 | If one wants to get VTL working on a Solaris initiator (and this 10 | target of course under Linux) then it is rather simple to get a tape 11 | drive working. Getting the changer device working under Solaris 12 | (OpenSolaris) take a bit more effort. This file describes the way to 13 | do it. 14 | 15 | Although most of it is probably well know to Solaris fans, it took me 16 | a bit of time to figure out to get the VTL target working fine under 17 | OpenSolaris. For those who want to give it a try, here are the 18 | commands: 19 | 20 | For normal disk and cd targets no files have to be changed. All you 21 | need is the following: 22 | 23 | # svcadm enable iscsi_initiator 24 | 25 | and check if it is online: 26 | 27 | # svcs iscsi_initiator 28 | 29 | the state should be online. 30 | 31 | Now we add the discovery address to the initiator: 32 | 33 | # iscsiadm add discovery-address 34 | 35 | Now we configure the discovery mode to sendtargets: 36 | 37 | # iscsiadm modify discovery -t enable 38 | 39 | Check the target: 40 | 41 | # iscsiadm list target -S 42 | 43 | And create the device files: 44 | 45 | # devfsadm -i iscsi 46 | 47 | 48 | Tape devices will be shown properly, but not the changer device, this 49 | takes a bit more work. Two files need to be changed, and a reboot is 50 | needed to set things up properly. 51 | 52 | In the file /etc/driver_aliases the two lines 53 | 54 | sgen "scsa,08.bfcp" 55 | sgen "scsa,08.bvhci" 56 | 57 | need to be replaced with 58 | 59 | sgen "scsiclass,08" 60 | 61 | 62 | The file /kernel/drv/sgen.conf, which is basically all commented out 63 | needs to have the following lines: 64 | 65 | device-type-config-list="changer","sequential"; 66 | inquiry-config-list= "*", "*"; 67 | 68 | name="sgen" class="scsi" target=0 lun=4; 69 | name="sgen" class="scsi" target=1 lun=4; 70 | name="sgen" class="scsi" target=2 lun=4; 71 | name="sgen" class="scsi" target=3 lun=4; 72 | name="sgen" class="scsi" target=4 lun=4; 73 | name="sgen" class="scsi" target=5 lun=4; 74 | name="sgen" class="scsi" target=6 lun=4; 75 | name="sgen" class="scsi" target=7 lun=4; 76 | name="sgen" class="scsi" target=8 lun=4; 77 | name="sgen" class="scsi" target=9 lun=4; 78 | name="sgen" class="scsi" target=10 lun=4; 79 | name="sgen" class="scsi" target=11 lun=4; 80 | name="sgen" class="scsi" target=12 lun=4; 81 | name="sgen" class="scsi" target=13 lun=4; 82 | name="sgen" class="scsi" target=14 lun=4; 83 | name="sgen" class="scsi" target=15 lun=4; 84 | 85 | 86 | For the last bit it should be noted that my changer was set to lun 4, 87 | and since I don't know which target I put all target numbers in (0-15). 88 | 89 | After these modifications the best is to reboot the machine, and do 90 | the iscsi commands above, and he presto it works: 91 | 92 | In my case, three tape drives and one changer: 93 | 94 | root@solar:/kernel/drv# iscsiadm list target -S 95 | Target: iqn.2008-09.com.example:server.tape 96 | Alias: - 97 | TPGT: 1 98 | ISID: 4000002a0000 99 | Connections: 1 100 | LUN: 4 101 | Vendor: STK 102 | Product: L700 103 | OS Device Name: /dev/scsi/changer/c0t0d0 104 | LUN: 3 105 | Vendor: HP 106 | Product: LTO3 ULTRIUM 107 | OS Device Name: /dev/rmt/2n 108 | LUN: 2 109 | Vendor: HP 110 | Product: LTO3 ULTRIUM 111 | OS Device Name: /dev/rmt/1n 112 | LUN: 1 113 | Vendor: HP 114 | Product: LTO3 ULTRIUM 115 | OS Device Name: /dev/rmt/0n 116 | 117 | 118 | 119 | root@solar:/kernel/drv# mtx -f /dev/scsi/changer/c0t0d0 status 120 | Storage Changer /dev/scsi/changer/c0t0d0:3 Drives, 29 Slots ( 5 Import/Export ) 121 | Data Transfer Element 0:Empty 122 | Data Transfer Element 1:Empty 123 | Data Transfer Element 2:Empty 124 | Storage Element 1:Full :VolumeTag=A0000001 125 | Storage Element 2:Full :VolumeTag=A0000002 126 | Storage Element 3:Full :VolumeTag=A0000003 127 | Storage Element 4:Full :VolumeTag=A0000004 128 | Storage Element 5:Full :VolumeTag=A0000005 129 | Storage Element 6:Full :VolumeTag=A0000006 130 | Storage Element 7:Full :VolumeTag=A0000007 131 | Storage Element 8:Full :VolumeTag=A0000008 132 | Storage Element 9:Empty:VolumeTag= 133 | Storage Element 10:Empty:VolumeTag= 134 | Storage Element 11:Empty:VolumeTag= 135 | Storage Element 12:Empty:VolumeTag= 136 | Storage Element 13:Empty:VolumeTag= 137 | Storage Element 14:Empty:VolumeTag= 138 | Storage Element 15:Empty:VolumeTag= 139 | Storage Element 16:Empty:VolumeTag= 140 | Storage Element 17:Empty:VolumeTag= 141 | Storage Element 18:Empty:VolumeTag= 142 | Storage Element 19:Empty:VolumeTag= 143 | Storage Element 20:Empty:VolumeTag= 144 | Storage Element 21:Empty:VolumeTag= 145 | Storage Element 22:Empty:VolumeTag= 146 | Storage Element 23:Empty:VolumeTag= 147 | Storage Element 24:Full :VolumeTag=CLN00001 148 | Storage Element 25 IMPORT/EXPORT:Empty:VolumeTag= 149 | Storage Element 26 IMPORT/EXPORT:Empty:VolumeTag= 150 | Storage Element 27 IMPORT/EXPORT:Empty:VolumeTag= 151 | Storage Element 28 IMPORT/EXPORT:Empty:VolumeTag= 152 | Storage Element 29 IMPORT/EXPORT:Empty:VolumeTag= 153 | -------------------------------------------------------------------------------- /doc/README.vtl: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # This is a simple script to aid in setting up a virtual tape library 3 | # (VTL) using STGT 4 | # 5 | # You can tweak the settings for how many tape drives and how many 6 | # and how big tapes the library should have using the variables below 7 | 8 | 9 | # Connection number. You can use multiple concurrent TGTD instances as 10 | # long as you give them unique CN numbers and they listen on different 11 | # portals 12 | CN=1 13 | # Listen to port 3260 on wildcard for both ipv4 and ipv6 14 | PORTAL=:3260 15 | # iSCSI name for this target 16 | TARGET=iqn.2012-08.ronnie.vtl 17 | # Number of TAPE Drives for this virtual tape library 18 | NUM_DRIVES=2 19 | # Number of tapes 20 | NUM_TAPES=8 21 | # Tape size in MB 22 | TAPE_SIZE=1024 23 | # Directory where the tape library state and media will be stored 24 | VTLDIR=$HOME/vtl 25 | 26 | 27 | 28 | # Create the directory to store the tapes 29 | if [ ! -d $VTLDIR ]; then 30 | echo Creating directory for VTL : $VTLDIR 31 | mkdir -p $VTLDIR 32 | fi 33 | 34 | # make sure we have a backing store for the media changer 35 | if [ ! -f $VTLDIR/smc ]; then 36 | echo Creating a backing store for the media changer : $VTLDIR/smc 37 | dd if=/dev/zero of=$VTLDIR/smc bs=1k count=1 2>/dev/null 38 | fi 39 | 40 | # Create the tapes 41 | seq 1 $NUM_TAPES | while read IDX; do 42 | TAPE=`echo $IDX | awk '{printf "%08d", $1}'` 43 | if [ ! -f $VTLDIR/$TAPE ]; then 44 | echo Creating blank tape : $TAPE 45 | tgtimg --op new --device-type tape --barcode $TAPE --size $TAPE_SIZE --type data --file $VTLDIR/$TAPE 46 | fi 47 | done 48 | 49 | 50 | # Restart tgtd 51 | echo Restart TGTD 52 | tgt-admin -C $CN --update ALL -c /dev/null -f 53 | tgtadm -C $CN --op delete --mode system 54 | tgtd -C $CN --iscsi portal=$PORTAL 55 | sleep 1 56 | 57 | 58 | echo Create target 59 | tgtadm -C $CN --lld iscsi --op new --mode target --tid 1 -T $TARGET 60 | 61 | # Create the tape drives 62 | echo Create tape drives 63 | seq 1 $NUM_DRIVES | while read IDX; do 64 | TAPE=`echo $IDX | awk '{printf "%08d", $1}'` 65 | echo Create tape drive $IDX 66 | tgtadm -C $CN --lld iscsi --mode logicalunit --op new --tid 1 --lun $IDX -b $VTLDIR/$TAPE --device-type=tape 67 | tgtadm -C $CN --lld iscsi --mode logicalunit --op update --tid 1 --lun $IDX --params online=0 68 | done 69 | 70 | # Create the changer 71 | echo Create media changer device 72 | LUN=`expr "$NUM_DRIVES" "+" "1"` 73 | tgtadm -C $CN --lld iscsi --mode logicalunit --op new --tid 1 --lun $LUN -b $VTLDIR/smc --device-type=changer 74 | tgtadm -C $CN --lld iscsi --mode logicalunit --op update --tid 1 --lun $LUN --params media_home=$VTLDIR 75 | 76 | # Add data transfer devices (one for each tape drive) 77 | echo Adding data transfer devices 78 | tgtadm -C $CN --lld iscsi --mode logicalunit --op update --tid 1 --lun $LUN --params element_type=4,start_address=1,quantity=$NUM_DRIVES 79 | 80 | seq 1 $NUM_DRIVES | while read IDX; do 81 | echo Adding data transfer device for drive $IDX 82 | tgtadm -C $CN --lld iscsi --mode logicalunit --op update --tid 1 --lun $LUN --params element_type=4,address=$IDX,tid=1,lun=$IDX 83 | done 84 | 85 | # Add medium transport elements (robot arm / picker) 86 | echo Adding medium transport elements 87 | tgtadm -C $CN --lld iscsi --mode logicalunit --op update --tid 1 --lun $LUN --params element_type=1,start_address=$LUN,quantity=1 88 | 89 | 90 | # Storage elements 91 | echo Adding storage elements 92 | STORAGE=`expr "$LUN" "+" "1"` 93 | tgtadm -C $CN --lld iscsi --mode logicalunit --op update --tid 1 --lun $LUN --params element_type=2,start_address=$STORAGE,quantity=$NUM_TAPES 94 | 95 | # Add media to the storage slots 96 | seq 1 $NUM_TAPES | while read IDX; do 97 | TAPE=`echo $IDX | awk '{printf "%08d", $1}'` 98 | echo Loading $TAPE into storage slot $STORAGE 99 | tgtadm -C $CN --lld iscsi --mode logicalunit --op update --tid 1 --lun $LUN --params element_type=2,address=$STORAGE,barcode=$TAPE,sides=1 100 | STORAGE=`expr "$STORAGE" "+" "1"` 101 | done 102 | 103 | 104 | # Allow anyone to access this target and the VTL 105 | tgtadm -C $CN --lld iscsi --op bind --mode target --tid 1 -I ALL 106 | 107 | # show all our good work 108 | tgtadm -C $CN --lld iscsi --op show --mode target 109 | 110 | -------------------------------------------------------------------------------- /doc/tgt-setup-lun.8.xml: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openvstorage/tgt/ac17d18c39638138a25f6a0be12b3030fa0ce656/doc/tgt-setup-lun.8.xml -------------------------------------------------------------------------------- /doc/tgtimg.8.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | tgtimg 6 | 8 7 | 8 | 9 | 10 | 11 | tgtimg 12 | Linux SCSI Target Framework Image File Utility 13 | 14 | 15 | 16 | 17 | tgtimg 18 | -o --op <operation> 19 | -Y --device-type <device-type> 20 | -b --barcode <barcode> 21 | -s --size <size> 22 | -t --type <media-type> 23 | -f --file <path> 24 | -T --thin-provisioning 25 | 26 | 27 | tgtimg --help 28 | 29 | 30 | 31 | 32 | DESCRIPTION 33 | 34 | Tgtimg is a utility to create and manage the image files used by the 35 | TGTD device emulation. 36 | 37 | 38 | This command is used to initialize device image files with the additional 39 | metadata, such as barcode, list of blocks, total size, etc that 40 | the TGTD emulation needs. 41 | 42 | 43 | 44 | 45 | 46 | OPTIONS 47 | 48 | 49 | 50 | 51 | 52 | Show a help screen and exit. 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | Operation. Is either new to create a new image file or show to 61 | show the content of an existing image file. 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | This specifies the type of image file. 70 | 71 | 72 | 73 | 74 | Supported device types are : 75 | cd : to create media for a dvd device 76 | disk : to create media for a disk device 77 | tape : to create media for a tape device 78 | 79 | 80 | 81 | 82 | 83 | When creating a new image, this specifies the type of media to 84 | emulate. The available mediatypes depend on the type of the 85 | device. 86 | 87 | 88 | 89 | 90 | Supported media types for cd devices are : 91 | dvd+r : create a blank writeable DVD+R disk 92 | 93 | Supported media types for disk devices are : 94 | disk : create an empty disk 95 | 96 | Supported media types for tape devices are : 97 | data : create a normal data tape 98 | clean : create a cleaning tape 99 | worm : create a worm 100 | 101 | 102 | 103 | 104 | 105 | When creating a new image, this argument specifies the barcode 106 | to use with this image file. Backup application software often 107 | uses barcodes to identify specific tapes. When emulating a VTL, 108 | make sure that all tape images use unique barcodes. 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | When creating a new image, this specifies the size in megabytes 117 | for the virtual tape image. 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | The filename of the image file. 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | This argument makes the allocation of the image format use 134 | thin-provisioning. This means that the file created will be a 135 | sparse file that will allocate blocks from the filesystem on demand. 136 | 137 | 138 | Be careful when using thin-provisioning. If the filesystem 139 | fills up a iSCSI write to a thin-provisioned LUN 140 | can fail. Initiators generally do not handle "out of space" errors 141 | gracefully. 142 | 143 | 144 | Thin-provisioning uses FALLOC_FL_PUNCH_HOLE which is only available 145 | on some linux filesystems. Thin-provisioning can only be used for 146 | DISK images. 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | EXAMPLES 155 | 156 | To create a new 100MByte disk 157 | 158 | 159 | tgtimg --op new --device-type disk --type disk --size 100 --file /data/hd001.raw 160 | 161 | 162 | 163 | To create a new tape image 164 | 165 | 166 | tgtimg --op new --device-type tape --barcode 12345 --size 100 --type data --file /data/tape001.img 167 | 168 | 169 | 170 | To view the content of an existing image 171 | 172 | 173 | tgtimg --op show --device-type tape --file /data/tape001.img 174 | 175 | 176 | 177 | To create a new blank DVD+R image 178 | 179 | 180 | tgtimg --op new --device-type cd --type dvd+r --file /data/dvd001.iso 181 | 182 | 183 | 184 | 185 | 186 | SEE ALSO 187 | 188 | tgtd(8), tgtadm(8), tgt-admin(8), tgt-setup-lun(8). 189 | 190 | 191 | 192 | 193 | REPORTING BUGS 194 | 195 | Report bugs to <stgt@vger.kernel.org> 196 | 197 | 198 | 199 | 200 | -------------------------------------------------------------------------------- /doc/tmf.txt: -------------------------------------------------------------------------------- 1 | The tgt Task Management Functions (TMF) works in the followings: 2 | 3 | - When LLDs queue scsi commands to tgt (scsi_tgt_queue_command), they 4 | need to specify unique 'tag' for each command. 5 | 6 | - LLDs call 'int scsi_tgt_tsk_mgmt_request(struct Scsi_Host *host, int, 7 | u64 tag, struct scsi_lun *lun, void *data)'. 8 | 9 | - int (* tsk_mgmt_response)(u64 data, int result) is added to 10 | scsi_host_template. 11 | 12 | The tag arg in scsi_tgt_queue_command is used only for ABORT_TASK to 13 | identify a single command. Initiators send a command with a unique 14 | tag so LLDs simply call scsi_tgt_queue_command() with it. 15 | 16 | With FCP and iSCSI, tag is 32-bit, however, unfortunately, SRP uses 17 | 64-bit tag. So we need 64-bit for it. 18 | 19 | When an initiator sends a task management request, the LLD calls 20 | scsi_tgt_tsk_mgmt_request. the LLD can use whatever it wants for the 21 | data arg. The data arg is used later as the arg in the 22 | tsk_mgmt_response callback. 23 | 24 | tgt core just sends the task management request to user space 25 | (by using TGT_KEVENT_TSK_MGMT_REQ). 26 | 27 | In the case of ABORT_TASK, tgtd finds a single command to abort and 28 | sends TGT_UEVENT_CMD_RSP and TGT_UEVENT_TSK_MGMT_RSP events. 29 | 30 | tgt core calls eh_abort_handler for TGT_UEVENT_CMD_RSP and then 31 | tsk_mgmt_response for TGT_UEVENT_TSK_MGMT_RSP. 32 | 33 | If tgtd fails to find a command to abort, it sends only 34 | TGT_UEVENT_TSK_MGMT_RSP event (no TGT_UEVENT_CMD_RSP event). 35 | 36 | In the case of the rests task management functions (like 37 | ABORT_TASK_SET), tgt needs to abort multiple commands. Thus, tgtd 38 | finds multiple commands to abort and sends multiple TGT_UEVENT_CMD_RSP 39 | events and a single TGT_UEVENT_TSK_MGMT_RSP event. tgt core calls 40 | eh_abort_handler multiple times and tsk_mgmt_response once. 41 | 42 | eh_abort_handler enables LLDs to safely free resource related with a 43 | command to abort. 44 | 45 | Note that when tgtd finds that a TGT_KEVENT_TSK_MGMT_REQ event tries 46 | to abort commands between in TGT_UEVENT_CMD_RSP and 47 | TGT_KEVENT_CMD_DONE states (that is, tgt calls something like 48 | bio_map_user for the commands), tgtd gives up. After all, we cannot 49 | abort such commands. For example, possibly, The commands already touch 50 | page cache. In this case, tgtd waits for the completion of the commands 51 | (TGT_KEVENT_CMD_DONE) and sends TGT_UEVENT_TSK_MGMT_RSP event with an 52 | appropriate result value. 53 | -------------------------------------------------------------------------------- /jenkins/centos/build_rpms.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e 4 | 5 | SPEC_FILE="scsi-target-utils.spec" 6 | 7 | # add openvstorage repo for dependencies of volumedriver packages 8 | echo '[openvstorage] 9 | name=Open vStorage repo 10 | baseurl=http://yum.openvstorage.org/CentOS/7/x86_64/dists/unstable 11 | enabled=1 12 | gpgcheck=0' | sudo tee /etc/yum.repos.d/openvstorage.repo 13 | 14 | sudo yum install -y epel-release 15 | sudo yum install -y wget gcc make yum-utils rpm-build rpmdevtools redhat-rpm-config 16 | 17 | ## if jenkins copied in volumedriver packages install them, 18 | ## else use the packages from the openvstorage repo 19 | P=$(ls -d libovsvolumedriver*.rpm 2>/dev/null || true) 20 | if [ -n "$P" ] 21 | then 22 | sudo yum install -y libovsvolumedriver*.rpm 23 | else 24 | sudo yum install -y libovsvolumedriver-devel 25 | fi 26 | 27 | ## prepare the build env 28 | chown -R jenkins:jenkins tgt 29 | mkdir -p ./tgt/rpm/{BUILD,RPMS,SOURCES,SPECS,SRPMS} 30 | 31 | ## create patch of our sources for rpmbuild 32 | 33 | cd tgt/rpm 34 | 35 | echo '>>> GET OPENVSTORAGE PATCH FROM GITHUB <<<' 36 | rm -f SOURCES/openvstorage_tgt.patch 37 | wget -q -nc -O SOURCES/openvstorage_tgt.patch https://github.com/openvstorage/tgt/compare/upstream...master.patch 38 | 39 | echo '>>> FETCHING UPSTREAM SOURCES <<<' 40 | spectool -g -C SOURCES SPECS/${SPEC_FILE} 41 | 42 | echo '>>> INSTALL BUILD DEPENDENCIES <<<' 43 | sudo yum-builddep -y SPECS/${SPEC_FILE} 44 | 45 | echo '>>> BUILD RPMS <<<' 46 | rpmbuild -ba --define "_topdir ${PWD}" SPECS/${SPEC_FILE} 47 | -------------------------------------------------------------------------------- /jenkins/centos/docker/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM centos:7 2 | 3 | # last update: 20160303 10:00 4 | # -- change previous line to trigger rebuild of docker image on jenkins; eg. when docker-entrypoint.sh changes 5 | 6 | RUN echo '%_install_langs C' >> /etc/rpm/macros && \ 7 | yum -y install epel-release && \ 8 | yum -y update && \ 9 | yum -y install sudo wget iproute supervisor \ 10 | rpm-build git yum-utils rpmdevtools redhat-rpm-config && \ 11 | yum clean all && \ 12 | rm -rf /usr/share/doc/* 13 | 14 | # add jenkins user -- this is required for git to work 15 | # note: jenkins has uid 1001 & gid 1002 on our build hosts, this needs to be reflected in here! 16 | 17 | ENV UID 1001 18 | 19 | RUN groupadd -g 1002 jenkins && \ 20 | useradd jenkins -s /bin/bash -g jenkins -m -u ${UID} -g 1002 -d /home/jenkins && \ 21 | echo "jenkins ALL=NOPASSWD: ALL" >/etc/sudoers.d/jenkins 22 | 23 | RUN echo 'BatchMode yes' >>/etc/ssh/ssh_config && \ 24 | echo 'StrictHostKeyChecking no' >>/etc/ssh/ssh_config 25 | 26 | # /etc/lsb-release is not present any more; 27 | # systemd provides /etc/os-release but internal names have changed, 28 | # add a hardcoded one for now 29 | 30 | RUN echo -e "DISTRIB_ID=CentOS\nDISTRIB_RELEASE=7" > /etc/lsb-release 31 | 32 | ADD supervisord.conf /etc/supervisord.conf 33 | ADD docker-entrypoint.sh /sbin/docker-entrypoint.sh 34 | 35 | ENTRYPOINT ["/sbin/docker-entrypoint.sh"] 36 | 37 | CMD [ "/usr/bin/supervisord" ] 38 | -------------------------------------------------------------------------------- /jenkins/centos/docker/docker-entrypoint.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # this script is executed at each startup of the container 4 | # NOTE: for jenkins, make sure to trigger a rebuild of the docker image 5 | # when making changes to this file! (md5sum of Dockerfile should change) 6 | 7 | set -e 8 | set -x 9 | 10 | # hack to make sure we have access to files in the jenkins home directory 11 | # the UID of jenkins in the container should match our UID on the host 12 | 13 | if [ ${UID} -ne 1001 ] 14 | then 15 | sed -i "s/x:1001:/x:${UID}:/" /etc/passwd 16 | chown ${UID} /home/jenkins 17 | [ -d /home/jenkins/.ssh ] && chown ${UID} /home/jenkins/.ssh 18 | fi 19 | 20 | # finally execute the command the user requested 21 | exec "$@" 22 | -------------------------------------------------------------------------------- /jenkins/centos/docker/supervisord.conf: -------------------------------------------------------------------------------- 1 | [supervisord] 2 | nodaemon=true 3 | 4 | #[program:rpcbind] 5 | #command=/sbin/rpcbind -f 6 | 7 | #[program:redis] 8 | #command=bash -c "/usr/bin/redis-server /etc/redis/redis.conf" 9 | 10 | #[program:omniNames] 11 | #command=bash -c "/usr/bin/omniNames -start -errlog /var/log/omniorb-nameserver.log || /usr/bin/omniNames -errlog /var/log/omniorb-nameserver.log" 12 | -------------------------------------------------------------------------------- /jenkins/ubuntu/build_debs.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | SRCDIR="$1" 4 | 5 | set -eux 6 | 7 | if [ $# -ne 1 ] 8 | then 9 | echo "Usage: $0 " 10 | exit 1 11 | fi 12 | 13 | if [ ! -d "${SRCDIR}" ] 14 | then 15 | echo "Sourcedir ${SRCDIR} not found?! Aborting build..." 16 | exit 1 17 | fi 18 | 19 | set -e 20 | 21 | # the OVS apt repo hosts dependencies that are not yet available in Ubuntu 22 | echo "deb http://apt.openvstorage.org unstable main" | sudo tee /etc/apt/sources.list.d/ovsaptrepo.list 23 | 24 | echo 'debconf debconf/frontend select Noninteractive' | sudo debconf-set-selections 25 | sudo apt-get update -qq 26 | 27 | ## we know we depend on the libovsvolumedriver-dev package, and we want latest greatest, so install from artifact 28 | for p in libovsvolumedriver_*_amd64.deb libovsvolumedriver-dev_*_amd64.deb 29 | do 30 | echo -n "Installing $p..." 31 | sudo dpkg -i $p || sudo apt-get install --allow-unauthenticated -qq -y -f 32 | [ $? -ne 0 ] && echo 'FAILED' || echo 'OK' 33 | done 34 | 35 | cd ${SRCDIR} 36 | 37 | echo ">>> INSTALLING BUILD DEPENDENCIES <<<" 38 | sudo apt-get install -y $(dpkg-checkbuilddeps 2>&1 | sed -e 's/.*dependencies://' -e 's/ ([^)]*)/ /g') 39 | 40 | echo ">>> BUILDING DEBIAN PACKAGES <<<" 41 | dpkg-buildpackage -us -uc -b 42 | 43 | ## .deb && *.ddeb packages should be available now 44 | -------------------------------------------------------------------------------- /jenkins/ubuntu/docker/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM ubuntu:14.04 2 | 3 | # last update: 20151203 4 | # -- change previous line to trigger rebuild of docker image on jenkins; eg. when docker-entrypoint.sh changes 5 | 6 | # add jenkins user -- this is required for git to work 7 | # note: jenkins has uid 1001 & gid 1002 on our build hosts, this needs to be reflected in here! 8 | 9 | ENV UID 1001 10 | 11 | RUN groupadd -g 1002 jenkins && \ 12 | useradd jenkins -s /bin/bash -g jenkins -m -u ${UID} -g 1002 -d /home/jenkins && \ 13 | echo "jenkins ALL=NOPASSWD: ALL" >/etc/sudoers.d/jenkins 14 | 15 | # add required packages 16 | 17 | ENV DEBIAN_FRONTEND noninteractive 18 | 19 | RUN apt-get update && \ 20 | apt-get upgrade -y && \ 21 | apt-get dist-upgrade -y && \ 22 | apt-get install -y software-properties-common && \ 23 | add-apt-repository -y ppa:ubuntu-toolchain-r/test && \ 24 | add-apt-repository -y ppa:afrank/boost && \ 25 | apt-get update && \ 26 | apt-get install -y gcc-4.9 g++-4.9 libstdc++-4.9-dev \ 27 | libboost1.57-all-dev \ 28 | build-essential \ 29 | libc6-dbg pkg-create-dbgsym elfutils \ 30 | wget git supervisor rpcbind && \ 31 | apt-get -y autoremove --purge && apt-get clean && \ 32 | update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-4.9 99 && \ 33 | update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-4.9 99 34 | 35 | RUN echo 'BatchMode yes' >>/etc/ssh/ssh_config && \ 36 | echo 'StrictHostKeyChecking no' >>/etc/ssh/ssh_config 37 | 38 | RUN usermod -a -G sudo jenkins && \ 39 | usermod -a -G adm jenkins 40 | 41 | ADD supervisord.conf /etc/supervisor/supervisord.conf 42 | ADD docker-entrypoint.sh /sbin/docker-entrypoint.sh 43 | 44 | ENTRYPOINT ["/sbin/docker-entrypoint.sh"] 45 | 46 | CMD [ "/usr/bin/supervisord" ] 47 | -------------------------------------------------------------------------------- /jenkins/ubuntu/docker/docker-entrypoint.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # this script is executed at each startup of the container 4 | # NOTE: for jenkins, make sure to trigger a rebuild of the docker image 5 | # when making changes to this file! (md5sum of Dockerfile should change) 6 | 7 | set -e 8 | set -x 9 | 10 | # hack to make sure we have access to files in the jenkins home directory 11 | # the UID of jenkins in the container should match our UID on the host 12 | 13 | if [ ${UID} -ne 1001 ] 14 | then 15 | sed -i "s/x:1001:/x:${UID}:/" /etc/passwd 16 | chown ${UID} /home/jenkins 17 | [ -d /home/jenkins/.ssh ] && chown ${UID} /home/jenkins/.ssh 18 | fi 19 | 20 | # finally execute the command the user requested 21 | exec "$@" 22 | -------------------------------------------------------------------------------- /jenkins/ubuntu/docker/supervisord.conf: -------------------------------------------------------------------------------- 1 | [supervisord] 2 | nodaemon=true 3 | 4 | [program:rpcbind] 5 | command=/sbin/rpcbind -f 6 | 7 | #[program:redis] 8 | #command=bash -c "/usr/bin/redis-server /etc/redis/redis.conf" 9 | 10 | #[program:omniNames] 11 | #command=bash -c "/usr/bin/omniNames -start -errlog /var/log/omniorb-nameserver.log || /usr/bin/omniNames -errlog /var/log/omniorb-nameserver.log" 12 | -------------------------------------------------------------------------------- /jenkins/ubuntu1604/build_debs.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | SRCDIR="$1" 4 | 5 | set -eux 6 | 7 | if [ $# -ne 1 ] 8 | then 9 | echo "Usage: $0 " 10 | exit 1 11 | fi 12 | 13 | if [ ! -d "${SRCDIR}" ] 14 | then 15 | echo "Sourcedir ${SRCDIR} not found?! Aborting build..." 16 | exit 1 17 | fi 18 | 19 | set -e 20 | 21 | # the OVS apt repo hosts dependencies that are not yet available in Ubuntu 22 | echo "deb http://apt.openvstorage.com unstable main" | sudo tee /etc/apt/sources.list.d/ovsaptrepo.list 23 | 24 | echo 'debconf debconf/frontend select Noninteractive' | sudo debconf-set-selections 25 | sudo apt-get update -qq 26 | 27 | ## we know we depend on the libovsvolumedriver-dev package, and we want latest greatest, so install from artifact 28 | for p in libovsvolumedriver_*_amd64.deb libovsvolumedriver-dev_*_amd64.deb 29 | do 30 | echo -n "Installing $p..." 31 | sudo dpkg -i $p || sudo apt-get install --allow-unauthenticated -qq -y -f 32 | [ $? -ne 0 ] && echo 'FAILED' || echo 'OK' 33 | done 34 | 35 | cd ${SRCDIR} 36 | 37 | echo ">>> INSTALLING BUILD DEPENDENCIES <<<" 38 | sudo apt-get install -y $(dpkg-checkbuilddeps 2>&1 | sed -e 's/.*dependencies://' -e 's/ ([^)]*)/ /g') 39 | 40 | echo ">>> BUILDING DEBIAN PACKAGES <<<" 41 | dpkg-buildpackage -us -uc -b 42 | 43 | ## .deb && *.ddeb packages should be available now 44 | -------------------------------------------------------------------------------- /jenkins/ubuntu1604/docker/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM ubuntu:16.04 2 | 3 | # last update: 20151203 4 | # -- change previous line to trigger rebuild of docker image on jenkins; eg. when docker-entrypoint.sh changes 5 | 6 | # add jenkins user -- this is required for git to work 7 | # note: jenkins has uid 1001 & gid 1002 on our build hosts, this needs to be reflected in here! 8 | 9 | ENV UID 1001 10 | 11 | # add required packages 12 | 13 | ENV DEBIAN_FRONTEND noninteractive 14 | 15 | RUN apt-get update && \ 16 | apt-get upgrade -y && \ 17 | apt-get dist-upgrade -y && \ 18 | apt-get install -y software-properties-common && \ 19 | apt-get update && \ 20 | apt-get install -y sudo gcc g++ \ 21 | libboost1.58-all-dev \ 22 | build-essential \ 23 | libc6-dbg pkg-create-dbgsym elfutils \ 24 | wget git supervisor rpcbind && \ 25 | apt-get -y autoremove --purge && apt-get clean 26 | 27 | RUN echo 'BatchMode yes' >>/etc/ssh/ssh_config && \ 28 | echo 'StrictHostKeyChecking no' >>/etc/ssh/ssh_config 29 | 30 | RUN groupadd -g 1002 jenkins && \ 31 | useradd jenkins -s /bin/bash -g jenkins -m -u ${UID} -g 1002 -d /home/jenkins && \ 32 | echo "jenkins ALL=NOPASSWD: ALL" >/etc/sudoers.d/jenkins 33 | 34 | RUN usermod -a -G sudo jenkins && \ 35 | usermod -a -G adm jenkins 36 | 37 | ADD supervisord.conf /etc/supervisor/supervisord.conf 38 | ADD docker-entrypoint.sh /sbin/docker-entrypoint.sh 39 | 40 | ENTRYPOINT ["/sbin/docker-entrypoint.sh"] 41 | 42 | CMD [ "/usr/bin/supervisord" ] 43 | -------------------------------------------------------------------------------- /jenkins/ubuntu1604/docker/docker-entrypoint.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # this script is executed at each startup of the container 4 | # NOTE: for jenkins, make sure to trigger a rebuild of the docker image 5 | # when making changes to this file! (md5sum of Dockerfile should change) 6 | 7 | set -e 8 | set -x 9 | 10 | # hack to make sure we have access to files in the jenkins home directory 11 | # the UID of jenkins in the container should match our UID on the host 12 | 13 | if [ ${UID} -ne 1001 ] 14 | then 15 | sed -i "s/x:1001:/x:${UID}:/" /etc/passwd 16 | chown ${UID} /home/jenkins 17 | [ -d /home/jenkins/.ssh ] && chown ${UID} /home/jenkins/.ssh 18 | fi 19 | 20 | # finally execute the command the user requested 21 | exec "$@" 22 | -------------------------------------------------------------------------------- /jenkins/ubuntu1604/docker/supervisord.conf: -------------------------------------------------------------------------------- 1 | [supervisord] 2 | nodaemon=true 3 | 4 | [program:rpcbind] 5 | command=/sbin/rpcbind -f 6 | 7 | #[program:redis] 8 | #command=bash -c "/usr/bin/redis-server /etc/redis/redis.conf" 9 | 10 | #[program:omniNames] 11 | #command=bash -c "/usr/bin/omniNames -start -errlog /var/log/omniorb-nameserver.log || /usr/bin/omniNames -errlog /var/log/omniorb-nameserver.log" 12 | -------------------------------------------------------------------------------- /rpm/SOURCES/0001-redhatify-docs.patch: -------------------------------------------------------------------------------- 1 | From 0861a02865e8bb6d5960fc1bee2f94baa633c950 Mon Sep 17 00:00:00 2001 2 | From: Andy Grover 3 | Date: Tue, 4 Oct 2011 11:32:38 -0700 4 | Subject: [PATCH 1/5] redhatify-docs 5 | 6 | --- 7 | README | 23 --------------------- 8 | doc/README.iscsi | 17 +++++++++------ 9 | doc/README.iser | 57 ++++++++++++++++++------------------------------------ 10 | 3 files changed, 29 insertions(+), 68 deletions(-) 11 | 12 | diff --git a/README b/README 13 | index c3f505c..42d81a2 100644 14 | --- a/README 15 | +++ b/README 16 | @@ -9,17 +9,6 @@ Currently, tgt supports the following target drivers: 17 | 18 | - iSER software target driver for Infiniband and RDMA NICs 19 | 20 | -- IBM System p VIO server 21 | - 22 | -- FCoE software target driver for Ethernet NICs (in progress) 23 | - 24 | -- Qlogic qla2xxx FC target driver (in progress) 25 | - 26 | -Tgt consists of kernel modules, user-space daemon, and user-space 27 | -tools. iSCSI, iSER, and FCoE target drivers use only user-space daemon 28 | -and tools (i.e. they are just user-space applications. They don't need 29 | -any kernel support). 30 | - 31 | tgt can emulate the following device types: 32 | 33 | - SBC: a virtual disk drive that can use a file to store the content. 34 | @@ -40,18 +29,6 @@ store the content (in progress). 35 | The code is under the GNU General Public License version 2. 36 | 37 | 38 | -Preparation 39 | -------------- 40 | -Linux kernel 2.6.22 or newer are recommended because tgt can get 41 | -better performance with signalfd. 42 | - 43 | -Target drivers have their own ways to build, configure, etc. Please 44 | -find an appropriate documentation in the doc directory. You might find 45 | -other useful information on tgt's site: 46 | - 47 | -http://stgt.sourceforge.net/ 48 | - 49 | - 50 | Developer Notes 51 | ------------- 52 | The central resource for tgt development is the mailing list 53 | diff --git a/doc/README.iscsi b/doc/README.iscsi 54 | index 4ff3028..b74a73a 100644 55 | --- a/doc/README.iscsi 56 | +++ b/doc/README.iscsi 57 | @@ -1,25 +1,28 @@ 58 | Preface 59 | ------------- 60 | -This show a simple example to set up some targets. 61 | +This shows a simple example to set up some targets. 62 | + 63 | +See man tgt-admin and the example /etc/tgt/targets.conf 64 | +file for how to setup a persistent configuration that is 65 | +started when the tgtd service is started (when "service tgtd start" 66 | +is run). 67 | 68 | 69 | Starting the daemon 70 | ------------- 71 | The iSCSI target driver works with the 2.6.X kernels. 72 | 73 | -First, you need to compile the source code: 74 | - 75 | -host:~/tgt/usr$ make 76 | - 77 | Try the following commands: 78 | 79 | host:~/tgt$ su 80 | -host:~/tgt# ./usr/tgtd 81 | +host:~/tgt# service tgtd start 82 | 83 | 84 | Configuration 85 | ------------- 86 | -Everyting is configured via the tgtadm management tool. 87 | +When started, the tgtd service will setup targets defined in 88 | +/etc/tgt/targets.conf. To manually configure a target tgtadm 89 | +or tgt-admin can be used. 90 | 91 | The following example creates a target with id 1 (the iqn is 92 | iqn.2001-04.com.example:storage.disk2.amiens.sys1.xyz) and adds a 93 | diff --git a/doc/README.iser b/doc/README.iser 94 | index 0f5fafd..7603d3c 100644 95 | --- a/doc/README.iser 96 | +++ b/doc/README.iser 97 | @@ -1,5 +1,21 @@ 98 | *** iSCSI Extensions for RDMA (iSER) in tgt *** 99 | 100 | +This is an detailed description of the iSER tgtd target. It 101 | +covers issues from the design to how to manually set it up. 102 | + 103 | +NOTE: 104 | +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 105 | +To run this iSER target you must have installed the libiverbs 106 | +and librdma rpms on your system. They will not get brought in 107 | +automatically when installing this rpm. 108 | +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 109 | + 110 | +See man tgt-admin and the example /etc/tgt/targets.conf 111 | +file for how to setup a persistent configuration that is 112 | +started when the tgtd service is started (when "service tgtd start" 113 | +is run). 114 | + 115 | + 116 | Copyright (C) 2007 Pete Wyckoff 117 | Copyright (C) 2011 Alexander Nezhinsky 118 | 119 | @@ -235,42 +251,7 @@ add padding either. 120 | 121 | 3. Using iSER 122 | 123 | -3.1. Building tgtd 124 | - 125 | -Compile tgtd with: 126 | - 127 | - make ISCSI_RDMA=1 128 | - 129 | -As iSCSI support is compiled in by default, there is no need to specify 130 | -additional symbols for it. 131 | - 132 | -For build purposes, you'll need to have two libraries installed 133 | -on your system: libibverbs-devel and librdmacm-devel. 134 | - 135 | -To run iser, you'lll need the binary form of these libraries, 136 | -libibverbs.so and librdmacm.so along with device specific user 137 | -space library such as libmlx4 for Mellanox ConnectX HCAs. 138 | - 139 | -If they are installed in the normal system paths (/usr/include and 140 | -/usr/lib or /usr/lib64), they will be found automatically. Otherwise, 141 | -edit CFLAGS and LIBS in usr/Makefile under ISER to specify the paths 142 | -by hand, e.g., for a /usr/local install, it should look like: 143 | - 144 | - ifneq ($(ISCSI_RDMA),) 145 | - CFLAGS += -DISCSI_RDMA -I/usr/local/include 146 | - TGTD_OBJS += iscsi/iser.o 147 | - LIBS += -L/usr/local/lib -libverbs -lrdmacm 148 | - endif 149 | - 150 | -If these libraries are not in the normal system paths, you may 151 | -possibly also have to set, e.g., LD_LIBRARY_PATH=/usr/local/lib in 152 | -your environment to find the shared libraries at runtime. 153 | - 154 | -The libraries mentioned is this section have pre-set packages provided 155 | -the by various distributions, e.g RPMs for Fedora, RedHat and Suse, 156 | -or DEBs for Debian and Ubuntu. 157 | - 158 | -3.2. Running tgtd 159 | +3.1. Running tgtd 160 | 161 | Start the daemon (as root): 162 | 163 | @@ -294,7 +275,7 @@ It's recommended to use the rping tool provided by librdmacm-utils 164 | for quick RDMA connectivity testing between the initiator and the 165 | target nodes. 166 | 167 | -3.3. Configuring tgtd 168 | +3.2. Configuring tgtd 169 | 170 | Configure the running target with one or more devices, using the 171 | tgtadm program you just built (also as root). Full information is 172 | @@ -312,7 +293,7 @@ Here is a quick-start example: 173 | --bstype rdwr 174 | 175 | 176 | -3.4. Initiator side 177 | +3.3. Initiator side 178 | 179 | To make your initiator use RDMA, make sure the "ib_iser" module is 180 | loaded in your kernel. Then do discovery as usual, over TCP: 181 | -- 182 | 1.7.1 183 | 184 | -------------------------------------------------------------------------------- /rpm/SOURCES/0002-remove-check-for-xsltproc.patch: -------------------------------------------------------------------------------- 1 | From c80e525b213883ba0a6b21c27089cd18c4cf05d1 Mon Sep 17 00:00:00 2001 2 | From: Andy Grover 3 | Date: Wed, 2 Nov 2011 22:15:32 -0700 4 | Subject: [PATCH 2/5] remove check for xsltproc 5 | 6 | It should always be there, since we added libxslt as a BuildRequires. 7 | 8 | Use local stylesheet. 9 | 10 | Signed-off-by: Andy Grover 11 | --- 12 | doc/Makefile | 23 +++++++++++++---------- 13 | 1 files changed, 13 insertions(+), 10 deletions(-) 14 | 15 | diff --git a/doc/Makefile b/doc/Makefile 16 | index 0516dc8..91a51f6 100644 17 | --- a/doc/Makefile 18 | +++ b/doc/Makefile 19 | @@ -33,35 +33,38 @@ clean: 20 | rm -f $(XMLMAN) $(XMLHTML) 21 | -rm -f manpages htmlpages 22 | 23 | +STYLEMAN = /usr/share/sgml/docbook/xsl-stylesheets/manpages/docbook.xsl 24 | +STYLEHTML = /usr/share/sgml/docbook/xsl-stylesheets/html/docbook.xsl 25 | + 26 | manpages/tgtd.8: tgtd.8.xml 27 | - -test -z "$(XSLTPROC)" || $(XSLTPROC) -o $@ http://docbook.sourceforge.net/release/xsl/current/manpages/docbook.xsl $< 28 | + $(XSLTPROC) -o $@ $(STYLEMAN) $< 29 | 30 | htmlpages/tgtd.8.html: tgtd.8.xml 31 | - -test -z "$(XSLTPROC)" || $(XSLTPROC) -o $@ http://docbook.sourceforge.net/release/xsl/current/html/docbook.xsl $< 32 | + $(XSLTPROC) -o $@ $(STYLEHTML) $< 33 | 34 | manpages/tgtadm.8: tgtadm.8.xml 35 | - -test -z "$(XSLTPROC)" || $(XSLTPROC) -o $@ http://docbook.sourceforge.net/release/xsl/current/manpages/docbook.xsl $< 36 | + $(XSLTPROC) -o $@ $(STYLEMAN) $< 37 | 38 | htmlpages/tgtadm.8.html: tgtadm.8.xml 39 | - -test -z "$(XSLTPROC)" || $(XSLTPROC) -o $@ http://docbook.sourceforge.net/release/xsl/current/html/docbook.xsl $< 40 | + $(XSLTPROC) -o $@ $(STYLEHTML) $< 41 | 42 | manpages/tgt-admin.8: tgt-admin.8.xml 43 | - -test -z "$(XSLTPROC)" || $(XSLTPROC) -o $@ http://docbook.sourceforge.net/release/xsl/current/manpages/docbook.xsl $< 44 | + $(XSLTPROC) -o $@ $(STYLEMAN) $< 45 | 46 | htmlpages/tgt-admin.8.html: tgt-admin.8.xml 47 | - -test -z "$(XSLTPROC)" || $(XSLTPROC) -o $@ http://docbook.sourceforge.net/release/xsl/current/html/docbook.xsl $< 48 | + $(XSLTPROC) -o $@ $(STYLEHTML) $< 49 | 50 | manpages/tgtimg.8: tgtimg.8.xml 51 | - -test -z "$(XSLTPROC)" || $(XSLTPROC) -o $@ http://docbook.sourceforge.net/release/xsl/current/manpages/docbook.xsl $< 52 | + $(XSLTPROC) -o $@ $(STYLEMAN) $< 53 | 54 | htmlpages/tgtimg.8.html: tgtimg.8.xml 55 | - -test -z "$(XSLTPROC)" || $(XSLTPROC) -o $@ http://docbook.sourceforge.net/release/xsl/current/html/docbook.xsl $< 56 | + $(XSLTPROC) -o $@ $(STYLEHTML) $< 57 | 58 | manpages/targets.conf.5: targets.conf.5.xml 59 | - -test -z "$(XSLTPROC)" || $(XSLTPROC) -o $@ http://docbook.sourceforge.net/release/xsl/current/manpages/docbook.xsl $< 60 | + $(XSLTPROC) -o $@ $(STYLEMAN) $< 61 | 62 | htmlpages/targets.conf.5.html: targets.conf.5.xml 63 | - -test -z "$(XSLTPROC)" || $(XSLTPROC) -o $@ http://docbook.sourceforge.net/release/xsl/current/html/docbook.xsl $< 64 | + $(XSLTPROC) -o $@ $(STYLEHTML) $< 65 | 66 | manpages/tgt-setup-lun.8: tgt-setup-lun.8.xml 67 | -test -z "$(XSLTPROC)" || $(XSLTPROC) -o $@ http://docbook.sourceforge.net/release/xsl/current/manpages/docbook.xsl $< 68 | -- 69 | 1.7.1 70 | 71 | -------------------------------------------------------------------------------- /rpm/SOURCES/0003-default-config.patch: -------------------------------------------------------------------------------- 1 | From ae49713dabee9befd1e8c43036c369a416099793 Mon Sep 17 00:00:00 2001 2 | From: Andy Grover 3 | Date: Tue, 18 Jun 2013 13:43:22 -0700 4 | Subject: [PATCH 3/5] default-config 5 | 6 | --- 7 | scripts/initd.sample | 2 +- 8 | scripts/tgt-admin | 4 ++-- 9 | 2 files changed, 3 insertions(+), 3 deletions(-) 10 | 11 | diff --git a/scripts/initd.sample b/scripts/initd.sample 12 | index 9ca86ce..7b67722 100755 13 | --- a/scripts/initd.sample 14 | +++ b/scripts/initd.sample 15 | @@ -13,7 +13,7 @@ 16 | # Description: tgtd provides the SCSI and software transport target state machine daemon. 17 | ### END INIT INFO 18 | 19 | -TGTD_CONFIG=/etc/tgt/targets.conf 20 | +TGTD_CONFIG=/etc/tgt/tgtd.conf 21 | 22 | TASK=$1 23 | 24 | diff --git a/scripts/tgt-admin b/scripts/tgt-admin 25 | index d374172..bbae0dd 100755 26 | --- a/scripts/tgt-admin 27 | +++ b/scripts/tgt-admin 28 | @@ -1,6 +1,6 @@ 29 | #!/usr/bin/perl 30 | # 31 | -# This tools parses /etc/tgt/targets.conf file and configures tgt 32 | +# This tools parses /etc/tgt/tgtd.conf file and configures tgt 33 | # 34 | # Author: Tomasz Chmielewski 35 | # License: GPLv2 36 | @@ -11,7 +11,7 @@ use Config::General qw(ParseConfig); 37 | use Getopt::Long; 38 | 39 | # Our config file 40 | -my $configfile = "/etc/tgt/targets.conf"; 41 | +my $configfile = "/etc/tgt/tgtd.conf"; 42 | 43 | sub usage { 44 | print < 4 | # 5 | 6 | TARGET=$1 7 | 8 | usage() { 9 | echo "Usage: `basename $0` [rpm|deb]" 10 | exit 1 11 | } 12 | 13 | if [ "$TARGET" != "rpm" -a "$TARGET" != "deb" ]; then 14 | usage 15 | fi 16 | 17 | DIR=$(cd `dirname $0`; pwd) 18 | BASE=`cd $DIR/.. ; pwd` 19 | _TOP="$BASE/pkg" 20 | SPEC="tgtd.spec" 21 | LOG=/tmp/`basename $0`-$$.log 22 | 23 | # get branch name 24 | branch=`git branch | grep '^*' | sed 's/^..\(.*\)/\1/'` 25 | # get version tag 26 | version=`git describe --tags --abbrev=0 | sed "s/^v//g"` 27 | # release is number of commits since the version tag 28 | release=`git describe --tags | cut -d- -f2 | tr - _` 29 | 30 | if [ "$version" = "$release" ]; then 31 | # no commits and release can't be empty 32 | release=0 33 | fi 34 | 35 | if [ "$branch" != "master" ]; then 36 | # if not under master branch include hash tag 37 | hash=`git rev-parse HEAD | cut -c 1-6` 38 | release="$release.$hash" 39 | fi 40 | 41 | echo "Building version: $version-$release" 42 | 43 | 44 | cp_src() { 45 | local dest=$1 46 | cp -a conf $dest 47 | cp -a doc $dest 48 | cp -a scripts $dest 49 | cp -a usr $dest 50 | cp -a README $dest 51 | cp -a Makefile $dest 52 | } 53 | 54 | check() { 55 | local rc=$? 56 | local msg="$1" 57 | if (( rc )) ; then 58 | echo $msg 59 | exit 1 60 | fi 61 | } 62 | 63 | build_rpm() { 64 | name=scsi-target-utils-$version-$release 65 | TARBALL=$name.tgz 66 | SRPM=$_TOP/SRPMS/$name.src.rpm 67 | 68 | echo "Creating rpm build dirs under $_TOP" 69 | mkdir -p $_TOP/{RPMS,SRPMS,SOURCES,BUILD,SPECS,tmp} 70 | mkdir -p $_TOP/tmp/$name 71 | 72 | cp_src $_TOP/tmp/$name 73 | 74 | echo "Creating tgz $TARBALL" 75 | tar -czf $_TOP/SOURCES/$TARBALL -C $_TOP/tmp $name 76 | 77 | echo "Creating rpm" 78 | sed -r "s/^Version:(\s*).*/Version:\1$version/;s/^Release:(\s*).*/Release:\1$release/" scripts/$SPEC > $_TOP/SPECS/$SPEC 79 | rpmbuild -bs --define="_topdir $_TOP" $_TOP/SPECS/$SPEC 80 | check "Failed to create source rpm." 81 | 82 | rpmbuild -bb --define="_topdir $_TOP" $_TOP/SPECS/$SPEC > $LOG 2>&1 83 | check "Failed to build rpm. LOG: $LOG" 84 | # display created rpm files 85 | grep ^Wrote $LOG 86 | 87 | rm -fr $LOG 88 | } 89 | 90 | build_deb() { 91 | if ! which debuild >/dev/null 2>&1 ; then 92 | echo "Missing debuild. Please install devscripts package." 93 | exit 1 94 | fi 95 | name=tgt_$version 96 | TARBALL=$name.orig.tar.gz 97 | 98 | echo "Building under $_TOP/$name" 99 | mkdir -p $_TOP/$name 100 | cp_src $_TOP/$name 101 | tar -czf $_TOP/$TARBALL -C $_TOP $name 102 | 103 | mkdir -p $_TOP/$name/debian 104 | cp -a scripts/deb/* $_TOP/$name/debian 105 | cd $_TOP/$name 106 | sed -i -r "s/^tgt \(([0-9.-]+)\) (.*)/tgt \($version-$release\) \2/" debian/changelog 107 | debuild -uc -us 108 | check "Failed building deb package." 109 | cd ../.. 110 | ls -l $_TOP/$name*.deb 111 | } 112 | 113 | cd $BASE 114 | build_$TARGET 115 | echo "Done." 116 | -------------------------------------------------------------------------------- /scripts/checkarch.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | arch=`gcc -dumpmachine` 3 | 4 | case $arch in 5 | `echo $arch | grep x86_64`) 6 | echo -m64 7 | ;; 8 | `echo $arch | grep "i[3-6]86"`) 9 | echo -m32 10 | ;; 11 | *) 12 | echo ' 13 | Failed to parse your architecture. 14 | Please run 15 | 16 | $ make check32 17 | 18 | or 19 | 20 | $ make check64 21 | 22 | manually. 23 | ' 24 | exit 1 25 | ;; 26 | esac 27 | -------------------------------------------------------------------------------- /scripts/deb/changelog: -------------------------------------------------------------------------------- 1 | tgt (1.0.37-1) UNRELEASED; urgency=low 2 | * Non-maintainer upload. 3 | * 4 | * Initial release. (Closes: #XXXXXX) 5 | 6 | -- Roi Dayan Thu, 18 Jul 2013 09:31:00 +0300 7 | -------------------------------------------------------------------------------- /scripts/deb/compat: -------------------------------------------------------------------------------- 1 | 8 2 | -------------------------------------------------------------------------------- /scripts/deb/control: -------------------------------------------------------------------------------- 1 | Source: tgt 2 | Maintainer: FUJITA Tomonori 3 | Section: net 4 | Priority: optional 5 | Standards-Version: 3.9.1 6 | Build-Depends: debhelper (>= 8), dpkg-dev (>= 1.13.19), bash-completion, 7 | librdmacm-dev, libibverbs-dev, xsltproc, docbook-xsl 8 | Homepage: http://stgt.berlios.de/ 9 | 10 | Package: tgt 11 | Architecture: any 12 | Depends: ${shlibs:Depends}, ${misc:Depends}, librdmacm1, libconfig-general-perl 13 | Description: The SCSI target daemon and utility programs 14 | The SCSI target package contains the daemon and tools to setup a SCSI targets. 15 | Currently, software iSCSI targets are supported. 16 | -------------------------------------------------------------------------------- /scripts/deb/copyright: -------------------------------------------------------------------------------- 1 | License: 2 | 3 | This program is free software; you can redistribute it and/or modify 4 | it under the terms of the GNU General Public License as published by 5 | the Free Software Foundation; either version 2 of the License, or (at 6 | your option) any later version. 7 | 8 | This program is distributed in the hope that it will be useful, but 9 | WITHOUT ANY WARRANTY; without even the implied warranty of 10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 11 | General Public License for more details. 12 | 13 | You should have received a copy of the GNU General Public License 14 | along with this program; if not, see http://www.gnu.org/licenses/. 15 | -------------------------------------------------------------------------------- /scripts/deb/init: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # This is an example init.d script for stopping/starting/reconfiguring tgtd. 3 | 4 | ### BEGIN INIT INFO 5 | # Provides: tgtd 6 | # Required-Start: $network 7 | # Required-Stop: $network 8 | # Default-Start: 2 3 4 5 9 | # Default-Stop: 0 1 6 10 | # Short-Description: Starts and stops the generic storage target daemon 11 | # Description: tgtd provides the SCSI and software transport target state machine daemon. 12 | ### END INIT INFO 13 | 14 | TGTD_CONFIG=/etc/tgt/targets.conf 15 | 16 | TASK=$1 17 | 18 | start() 19 | { 20 | echo "Starting target framework daemon" 21 | # Start tgtd first. 22 | tgtd &>/dev/null 23 | RETVAL=$? 24 | if [ "$RETVAL" -ne 0 ] ; then 25 | echo "Could not start tgtd (is tgtd already running?)" 26 | exit 1 27 | fi 28 | sleep 1 29 | # Put tgtd into "offline" state until all the targets are configured. 30 | # We don't want initiators to (re)connect and fail the connection 31 | # if it's not ready. 32 | tgtadm --op update --mode sys --name State -v offline 33 | # Configure the targets. 34 | tgt-admin -e -c $TGTD_CONFIG 35 | # Put tgtd into "ready" state. 36 | tgtadm --op update --mode sys --name State -v ready 37 | } 38 | 39 | stop() 40 | { 41 | if [ -n "$RUNLEVEL" ] && [ "$RUNLEVEL" -eq 0 -o "$RUNLEVEL" -eq 6 ] ; then 42 | forcedstop 43 | fi 44 | echo "Stopping target framework daemon" 45 | # Remove all targets. It only removes targets which are not in use. 46 | tgt-admin --update ALL -c /dev/null &>/dev/null 47 | # tgtd will exit if all targets were removed 48 | tgtadm --op delete --mode system &>/dev/null 49 | RETVAL=$? 50 | if [ "$RETVAL" -eq 107 ] ; then 51 | echo "tgtd is not running" 52 | [ "$TASK" != "restart" ] && exit 1 53 | elif [ "$RETVAL" -ne 0 ] ; then 54 | echo "Some initiators are still connected - could not stop tgtd" 55 | exit 2 56 | fi 57 | echo -n 58 | } 59 | 60 | forcedstop() 61 | { 62 | # NOTE: Forced shutdown of the iscsi target may cause data corruption 63 | # for initiators that are connected. 64 | echo "Force-stopping target framework daemon" 65 | # Offline everything first. May be needed if we're rebooting, but 66 | # expect the initiators to reconnect cleanly when we boot again 67 | # (i.e. we don't want them to reconnect to a tgtd which is still 68 | # working, but the target is gone). 69 | tgtadm --op update --mode sys --name State -v offline &>/dev/null 70 | RETVAL=$? 71 | if [ "$RETVAL" -eq 107 ] ; then 72 | echo "tgtd is not running" 73 | [ "$TASK" != "restart" ] && exit 1 74 | else 75 | tgt-admin --offline ALL 76 | # Remove all targets, even if they are still in use. 77 | tgt-admin --update ALL -c /dev/null -f 78 | # It will shut down tgtd only after all targets were removed. 79 | tgtadm --op delete --mode system 80 | RETVAL=$? 81 | if [ "$RETVAL" -ne 0 ] ; then 82 | echo "Failed to shutdown tgtd" 83 | exit 1 84 | fi 85 | fi 86 | echo -n 87 | } 88 | 89 | reload() 90 | { 91 | echo "Updating target framework daemon configuration" 92 | # Update configuration for targets. Only targets which 93 | # are not in use will be updated. 94 | tgt-admin --update ALL -c $TGTD_CONFIG &>/dev/null 95 | RETVAL=$? 96 | if [ "$RETVAL" -eq 107 ] ; then 97 | echo "tgtd is not running" 98 | exit 1 99 | fi 100 | } 101 | 102 | forcedreload() 103 | { 104 | echo "Force-updating target framework daemon configuration" 105 | # Update configuration for targets, even those in use. 106 | tgt-admin --update ALL -f -c $TGTD_CONFIG &>/dev/null 107 | RETVAL=$? 108 | if [ "$RETVAL" -eq 107 ] ; then 109 | echo "tgtd is not running" 110 | exit 1 111 | fi 112 | } 113 | 114 | status() 115 | { 116 | # Don't name this script "tgtd"... 117 | TGTD_PROC=$(ps -C tgtd | grep -c tgtd) 118 | if [ "$TGTD_PROC" -eq 2 ] ; then 119 | echo "tgtd is running. Run 'tgt-admin -s' to see detailed target info." 120 | else 121 | echo "tgtd is NOT running." 122 | fi 123 | } 124 | 125 | case $1 in 126 | start) 127 | start 128 | ;; 129 | stop) 130 | stop 131 | ;; 132 | forcedstop) 133 | forcedstop 134 | ;; 135 | restart) 136 | TASK=restart 137 | stop && start 138 | ;; 139 | forcedrestart) 140 | TASK=restart 141 | forcedstop && start 142 | ;; 143 | reload) 144 | reload 145 | ;; 146 | force-reload) 147 | forcedreload 148 | ;; 149 | status) 150 | status 151 | ;; 152 | *) 153 | echo "Usage: $0 {start|stop|forcedstop|restart|forcedrestart|reload|forcedreload|status}" 154 | exit 2 155 | ;; 156 | esac 157 | 158 | -------------------------------------------------------------------------------- /scripts/deb/patches/0001-Use-local-docbook-for-generating-docs.patch: -------------------------------------------------------------------------------- 1 | From 1edc4f6428dfdbd86a2d47177148e12fd617c3b1 Mon Sep 17 00:00:00 2001 2 | From: Roi Dayan 3 | Date: Thu, 10 Apr 2014 17:36:45 +0300 4 | Subject: [PATCH] Use local docbook for generating docs 5 | 6 | Signed-off-by: Roi Dayan 7 | --- 8 | doc/Makefile | 24 ++++++++++++------------ 9 | 1 file changed, 12 insertions(+), 12 deletions(-) 10 | 11 | diff --git a/doc/Makefile b/doc/Makefile 12 | index 0516dc8..e56695d 100644 13 | --- a/doc/Makefile 14 | +++ b/doc/Makefile 15 | @@ -34,40 +34,40 @@ clean: 16 | -rm -f manpages htmlpages 17 | 18 | manpages/tgtd.8: tgtd.8.xml 19 | - -test -z "$(XSLTPROC)" || $(XSLTPROC) -o $@ http://docbook.sourceforge.net/release/xsl/current/manpages/docbook.xsl $< 20 | + -test -z "$(XSLTPROC)" || $(XSLTPROC) -o $@ /usr/share/xml/docbook/stylesheet/docbook-xsl/manpages/docbook.xsl $< 21 | 22 | htmlpages/tgtd.8.html: tgtd.8.xml 23 | - -test -z "$(XSLTPROC)" || $(XSLTPROC) -o $@ http://docbook.sourceforge.net/release/xsl/current/html/docbook.xsl $< 24 | + -test -z "$(XSLTPROC)" || $(XSLTPROC) -o $@ /usr/share/xml/docbook/stylesheet/docbook-xsl/html/docbook.xsl $< 25 | 26 | manpages/tgtadm.8: tgtadm.8.xml 27 | - -test -z "$(XSLTPROC)" || $(XSLTPROC) -o $@ http://docbook.sourceforge.net/release/xsl/current/manpages/docbook.xsl $< 28 | + -test -z "$(XSLTPROC)" || $(XSLTPROC) -o $@ /usr/share/xml/docbook/stylesheet/docbook-xsl/manpages/docbook.xsl $< 29 | 30 | htmlpages/tgtadm.8.html: tgtadm.8.xml 31 | - -test -z "$(XSLTPROC)" || $(XSLTPROC) -o $@ http://docbook.sourceforge.net/release/xsl/current/html/docbook.xsl $< 32 | + -test -z "$(XSLTPROC)" || $(XSLTPROC) -o $@ /usr/share/xml/docbook/stylesheet/docbook-xsl/html/docbook.xsl $< 33 | 34 | manpages/tgt-admin.8: tgt-admin.8.xml 35 | - -test -z "$(XSLTPROC)" || $(XSLTPROC) -o $@ http://docbook.sourceforge.net/release/xsl/current/manpages/docbook.xsl $< 36 | + -test -z "$(XSLTPROC)" || $(XSLTPROC) -o $@ /usr/share/xml/docbook/stylesheet/docbook-xsl/manpages/docbook.xsl $< 37 | 38 | htmlpages/tgt-admin.8.html: tgt-admin.8.xml 39 | - -test -z "$(XSLTPROC)" || $(XSLTPROC) -o $@ http://docbook.sourceforge.net/release/xsl/current/html/docbook.xsl $< 40 | + -test -z "$(XSLTPROC)" || $(XSLTPROC) -o $@ /usr/share/xml/docbook/stylesheet/docbook-xsl/html/docbook.xsl $< 41 | 42 | manpages/tgtimg.8: tgtimg.8.xml 43 | - -test -z "$(XSLTPROC)" || $(XSLTPROC) -o $@ http://docbook.sourceforge.net/release/xsl/current/manpages/docbook.xsl $< 44 | + -test -z "$(XSLTPROC)" || $(XSLTPROC) -o $@ /usr/share/xml/docbook/stylesheet/docbook-xsl/manpages/docbook.xsl $< 45 | 46 | htmlpages/tgtimg.8.html: tgtimg.8.xml 47 | - -test -z "$(XSLTPROC)" || $(XSLTPROC) -o $@ http://docbook.sourceforge.net/release/xsl/current/html/docbook.xsl $< 48 | + -test -z "$(XSLTPROC)" || $(XSLTPROC) -o $@ /usr/share/xml/docbook/stylesheet/docbook-xsl/html/docbook.xsl $< 49 | 50 | manpages/targets.conf.5: targets.conf.5.xml 51 | - -test -z "$(XSLTPROC)" || $(XSLTPROC) -o $@ http://docbook.sourceforge.net/release/xsl/current/manpages/docbook.xsl $< 52 | + -test -z "$(XSLTPROC)" || $(XSLTPROC) -o $@ /usr/share/xml/docbook/stylesheet/docbook-xsl/manpages/docbook.xsl $< 53 | 54 | htmlpages/targets.conf.5.html: targets.conf.5.xml 55 | - -test -z "$(XSLTPROC)" || $(XSLTPROC) -o $@ http://docbook.sourceforge.net/release/xsl/current/html/docbook.xsl $< 56 | + -test -z "$(XSLTPROC)" || $(XSLTPROC) -o $@ /usr/share/xml/docbook/stylesheet/docbook-xsl/html/docbook.xsl $< 57 | 58 | manpages/tgt-setup-lun.8: tgt-setup-lun.8.xml 59 | - -test -z "$(XSLTPROC)" || $(XSLTPROC) -o $@ http://docbook.sourceforge.net/release/xsl/current/manpages/docbook.xsl $< 60 | + -test -z "$(XSLTPROC)" || $(XSLTPROC) -o $@ /usr/share/xml/docbook/stylesheet/docbook-xsl/manpages/docbook.xsl $< 61 | 62 | htmlpages/tgt-setup-lun.8.html: tgt-setup-lun.8.xml 63 | - -test -z "$(XSLTPROC)" || $(XSLTPROC) -o $@ http://docbook.sourceforge.net/release/xsl/current/html/docbook.xsl $< 64 | + -test -z "$(XSLTPROC)" || $(XSLTPROC) -o $@ /usr/share/xml/docbook/stylesheet/docbook-xsl/html/docbook.xsl $< 65 | 66 | xmlman: $(XMLMAN) 67 | 68 | -- 69 | 1.8.1.2 70 | 71 | -------------------------------------------------------------------------------- /scripts/deb/rules: -------------------------------------------------------------------------------- 1 | #!/usr/bin/make -f 2 | 3 | DEB_MAKE_ENVVARS += ISCSI_RDMA=1 4 | 5 | %: 6 | dh $@ --with bash-completion 7 | 8 | override_dh_auto_build: 9 | dh_auto_build -- $(DEB_MAKE_ENVVARS) 10 | 11 | override_dh_auto_install: 12 | dh_auto_install -- $(DEB_MAKE_ENVVARS) 13 | -------------------------------------------------------------------------------- /scripts/deb/source/format: -------------------------------------------------------------------------------- 1 | 3.0 (quilt) 2 | -------------------------------------------------------------------------------- /scripts/deb/tgt.bash-completion: -------------------------------------------------------------------------------- 1 | scripts/tgt.bashcomp.sh tgt -------------------------------------------------------------------------------- /scripts/initd.sample: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # This is an example init.d script for stopping/starting/reconfiguring tgtd. 3 | 4 | # chkconfig: 345 20 80 5 | # 6 | ### BEGIN INIT INFO 7 | # Provides: tgtd 8 | # Required-Start: $network 9 | # Required-Stop: $network 10 | # Default-Start: 3 4 5 11 | # Default-Stop: 0 1 2 6 12 | # Short-Description: Starts and stops the generic storage target daemon 13 | # Description: tgtd provides the SCSI and software transport target state machine daemon. 14 | ### END INIT INFO 15 | 16 | TGTD_CONFIG=/etc/tgt/targets.conf 17 | 18 | TASK=$1 19 | 20 | start() 21 | { 22 | echo "Starting target framework daemon" 23 | # Start tgtd first. 24 | tgtd &>/dev/null 25 | RETVAL=$? 26 | if [ "$RETVAL" -ne 0 ] ; then 27 | echo "Could not start tgtd (is tgtd already running?)" 28 | exit 1 29 | fi 30 | # Put tgtd into "offline" state until all the targets are configured. 31 | # We don't want initiators to (re)connect and fail the connection 32 | # if it's not ready. 33 | tgtadm --op update --mode sys --name State -v offline 34 | # Configure the targets. 35 | tgt-admin -e -c $TGTD_CONFIG 36 | # Put tgtd into "ready" state. 37 | tgtadm --op update --mode sys --name State -v ready 38 | } 39 | 40 | stop() 41 | { 42 | if [ "$RUNLEVEL" == 0 -o "$RUNLEVEL" == 6 ] ; then 43 | forcedstop 44 | fi 45 | echo "Stopping target framework daemon" 46 | # Remove all targets. It only removes targets which are not in use. 47 | tgt-admin --update ALL -c /dev/null &>/dev/null 48 | # tgtd will exit if all targets were removed 49 | tgtadm --op delete --mode system &>/dev/null 50 | RETVAL=$? 51 | if [ "$RETVAL" -eq 107 ] ; then 52 | echo "tgtd is not running" 53 | [ "$TASK" != "restart" ] && exit 1 54 | elif [ "$RETVAL" -ne 0 ] ; then 55 | echo "Some initiators are still connected - could not stop tgtd" 56 | exit 2 57 | fi 58 | echo -n 59 | } 60 | 61 | forcedstop() 62 | { 63 | # NOTE: Forced shutdown of the iscsi target may cause data corruption 64 | # for initiators that are connected. 65 | echo "Force-stopping target framework daemon" 66 | # Offline everything first. May be needed if we're rebooting, but 67 | # expect the initiators to reconnect cleanly when we boot again 68 | # (i.e. we don't want them to reconnect to a tgtd which is still 69 | # working, but the target is gone). 70 | tgtadm --op update --mode sys --name State -v offline &>/dev/null 71 | RETVAL=$? 72 | if [ "$RETVAL" -eq 107 ] ; then 73 | echo "tgtd is not running" 74 | [ "$TASK" != "restart" ] && exit 1 75 | else 76 | tgt-admin --offline ALL 77 | # Remove all targets, even if they are still in use. 78 | tgt-admin --update ALL -c /dev/null -f 79 | # It will shut down tgtd only after all targets were removed. 80 | tgtadm --op delete --mode system 81 | RETVAL=$? 82 | if [ "$RETVAL" -ne 0 ] ; then 83 | echo "Failed to shutdown tgtd" 84 | exit 1 85 | fi 86 | fi 87 | echo -n 88 | } 89 | 90 | reload() 91 | { 92 | echo "Updating target framework daemon configuration" 93 | # Update configuration for targets. Only targets which 94 | # are not in use will be updated. 95 | tgt-admin --update ALL -c $TGTD_CONFIG &>/dev/null 96 | RETVAL=$? 97 | if [ "$RETVAL" -eq 107 ] ; then 98 | echo "tgtd is not running" 99 | exit 1 100 | fi 101 | } 102 | 103 | forcedreload() 104 | { 105 | echo "Force-updating target framework daemon configuration" 106 | # Update configuration for targets, even those in use. 107 | tgt-admin --update ALL -f -c $TGTD_CONFIG &>/dev/null 108 | RETVAL=$? 109 | if [ "$RETVAL" -eq 107 ] ; then 110 | echo "tgtd is not running" 111 | exit 1 112 | fi 113 | } 114 | 115 | status() 116 | { 117 | # Don't name this script "tgtd"... 118 | TGTD_PROC=$(ps -C tgtd | grep -c tgtd) 119 | if [ "$TGTD_PROC" -eq 2 ] ; then 120 | echo "tgtd is running. Run 'tgt-admin -s' to see detailed target info." 121 | else 122 | echo "tgtd is NOT running." 123 | fi 124 | } 125 | 126 | case $1 in 127 | start) 128 | start 129 | ;; 130 | stop) 131 | stop 132 | ;; 133 | forcedstop) 134 | forcedstop 135 | ;; 136 | restart) 137 | TASK=restart 138 | stop && start 139 | ;; 140 | forcedrestart) 141 | TASK=restart 142 | forcedstop && start 143 | ;; 144 | reload) 145 | reload 146 | ;; 147 | forcedreload) 148 | forcedreload 149 | ;; 150 | status) 151 | status 152 | ;; 153 | *) 154 | echo "Usage: $0 {start|stop|forcedstop|restart|forcedrestart|reload|forcedreload|status}" 155 | exit 2 156 | ;; 157 | esac 158 | 159 | -------------------------------------------------------------------------------- /scripts/tgtd.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=iSCSI target framework daemon 3 | Documentation=man: tgtd(8) 4 | After=network.target 5 | 6 | # On systems without virtual consoles, don't start any getty. Note 7 | # that serial gettys are covered by serial-getty@.service, not this 8 | # unit. 9 | ConditionPathExists=/etc/tgt/targets.conf 10 | 11 | [Service] 12 | Type=forking 13 | Environment=TGTD_CONFIG=/etc/tgt/targets.conf 14 | 15 | ExecStart=/usr/sbin/tgtd 16 | ExecStartPost=/usr/sbin/tgtadm --op update --mode sys --name State -v offline 17 | ExecStartPost=/usr/sbin/tgtadm --op update --mode sys --name State -v ready 18 | ExecStartPost=/usr/sbin/tgt-admin -e -c ${TGTD_CONFIG} 19 | 20 | ExecReload=/usr/sbin/tgt-admin --update ALL -f -c ${TGTD_CONFIG} 21 | 22 | ExecStop=/usr/sbin/tgtadm --op update --mode sys --name State -v offline 23 | ExecStop=/usr/sbin/tgt-admin --offline ALL 24 | ExecStop=/usr/sbin/tgt-admin --update ALL -c /dev/null -f 25 | ExecStop=/usr/sbin/tgtadm --op delete --mode system 26 | 27 | # Exit code: 107 tgtd not running 28 | 29 | 30 | [Install] 31 | WantedBy=multi-user.target 32 | -------------------------------------------------------------------------------- /scripts/tgtd.spec: -------------------------------------------------------------------------------- 1 | Name: scsi-target-utils 2 | Version: 1.0.24 3 | Release: 2%{?dist} 4 | Summary: The SCSI target daemon and utility programs 5 | Packager: Roi Dayan 6 | Group: System Environment/Daemons 7 | License: GPLv2 8 | URL: http://stgt.sourceforge.net/ 9 | Source0: %{name}-%{version}-%{release}.tgz 10 | BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) 11 | BuildRequires: pkgconfig libibverbs-devel librdmacm-devel libxslt libaio-devel 12 | %if %{defined suse_version} 13 | BuildRequires: docbook-xsl-stylesheets 14 | Requires: aaa_base 15 | %else 16 | BuildRequires: docbook-style-xsl 17 | Requires(post): chkconfig 18 | Requires(preun): chkconfig 19 | Requires(preun): initscripts 20 | %endif 21 | Requires: lsof sg3_utils 22 | ExcludeArch: s390 s390x 23 | 24 | %description 25 | The SCSI target package contains the daemon and tools to setup a SCSI targets. 26 | Currently, software iSCSI targets are supported. 27 | 28 | 29 | %prep 30 | %setup -q -n %{name}-%{version}-%{release} 31 | 32 | 33 | %build 34 | %{__make} %{?_smp_mflags} ISCSI_RDMA=1 35 | 36 | 37 | %install 38 | %{__rm} -rf %{buildroot} 39 | %{__install} -d %{buildroot}%{_sbindir} 40 | %{__install} -d %{buildroot}%{_mandir}/man5 41 | %{__install} -d %{buildroot}%{_mandir}/man8 42 | %{__install} -d %{buildroot}%{_initrddir} 43 | %{__install} -d %{buildroot}/etc/bash_completion.d 44 | %{__install} -d %{buildroot}/etc/tgt 45 | 46 | %{__install} -p -m 0755 scripts/tgt-setup-lun %{buildroot}%{_sbindir} 47 | %{__install} -p -m 0755 scripts/initd.sample %{buildroot}%{_initrddir}/tgtd 48 | %{__install} -p -m 0755 scripts/tgt-admin %{buildroot}/%{_sbindir}/tgt-admin 49 | %{__install} -p -m 0644 scripts/tgt.bashcomp.sh %{buildroot}/etc/bash_completion.d/tgt 50 | %{__install} -p -m 0644 doc/manpages/targets.conf.5 %{buildroot}/%{_mandir}/man5 51 | %{__install} -p -m 0644 doc/manpages/tgtadm.8 %{buildroot}/%{_mandir}/man8 52 | %{__install} -p -m 0644 doc/manpages/tgt-admin.8 %{buildroot}/%{_mandir}/man8 53 | %{__install} -p -m 0644 doc/manpages/tgt-setup-lun.8 %{buildroot}/%{_mandir}/man8 54 | %{__install} -p -m 0644 doc/manpages/tgtimg.8 %{buildroot}/%{_mandir}/man8 55 | %{__install} -p -m 0600 conf/targets.conf %{buildroot}/etc/tgt 56 | 57 | pushd usr 58 | %{__make} install DESTDIR=%{buildroot} sbindir=%{_sbindir} 59 | 60 | 61 | %post 62 | /sbin/chkconfig --add tgtd 63 | 64 | %postun 65 | if [ "$1" = "1" ] ; then 66 | /sbin/service tgtd condrestart > /dev/null 2>&1 || : 67 | fi 68 | 69 | %preun 70 | if [ "$1" = "0" ] ; then 71 | /sbin/chkconfig tgtd stop > /dev/null 2>&1 72 | /sbin/chkconfig --del tgtd 73 | fi 74 | 75 | 76 | %clean 77 | %{__rm} -rf %{buildroot} 78 | 79 | 80 | %files 81 | %defattr(-, root, root, -) 82 | %doc README doc/README.iscsi doc/README.iser doc/README.lu_configuration doc/README.mmc 83 | %{_sbindir}/tgtd 84 | %{_sbindir}/tgtadm 85 | %{_sbindir}/tgt-setup-lun 86 | %{_sbindir}/tgt-admin 87 | %{_sbindir}/tgtimg 88 | %{_mandir}/man5/* 89 | %{_mandir}/man8/* 90 | %{_initrddir}/tgtd 91 | /etc/bash_completion.d/tgt 92 | %attr(0600,root,root) %config(noreplace) /etc/tgt/targets.conf 93 | -------------------------------------------------------------------------------- /usr/Makefile: -------------------------------------------------------------------------------- 1 | sbindir ?= $(PREFIX)/sbin 2 | libdir ?= $(PREFIX)/lib/tgt 3 | 4 | ifneq ($(shell test -e /usr/include/linux/signalfd.h && echo 1),) 5 | CFLAGS += -DUSE_SIGNALFD 6 | endif 7 | 8 | ifneq ($(shell test -e /usr/include/sys/timerfd.h && echo 1),) 9 | CFLAGS += -DUSE_TIMERFD 10 | endif 11 | 12 | TGTD_OBJS += $(addprefix iscsi/, conn.o param.o session.o \ 13 | iscsid.o target.o chap.o sha1.o md5.o transport.o iscsi_tcp.o \ 14 | isns.o) 15 | 16 | ifneq ($(CEPH_RBD),) 17 | MODULES += bs_rbd.so 18 | endif 19 | 20 | ifneq ($(OPENVSTORAGE),) 21 | MODULES += bs_openvstorage.so 22 | endif 23 | 24 | ifneq ($(GLFS_BD),) 25 | MODULES += bs_glfs.so 26 | endif 27 | 28 | ifneq ($(SD_NOTIFY),) 29 | CFLAGS += -DUSE_SYSTEMD 30 | endif 31 | 32 | ifneq ($(shell test -e /usr/include/$(DEB_HOST_MULTIARCH)/sys/eventfd.h && test -e /usr/include/libaio.h && echo 1),) 33 | CFLAGS += -DUSE_EVENTFD 34 | TGTD_OBJS += bs_aio.o 35 | LIBS += -laio 36 | endif 37 | 38 | ifneq ($(ISCSI_RDMA),) 39 | TGTD_OBJS += iscsi/iser.o iscsi/iser_text.o 40 | LIBS += -libverbs -lrdmacm 41 | endif 42 | 43 | INCLUDES += -I. 44 | 45 | CFLAGS += -D_GNU_SOURCE 46 | CFLAGS += $(INCLUDES) 47 | ifneq ($(DEBUG),) 48 | CFLAGS += -g -O0 -ggdb -rdynamic 49 | else 50 | CFLAGS += -g -O2 -fno-strict-aliasing 51 | endif 52 | CFLAGS += -Wall -Wstrict-prototypes -fPIC 53 | CFLAGS += -DTGT_VERSION=\"$(VERSION)$(EXTRAVERSION)\" 54 | CFLAGS += -DBSDIR=\"$(DESTDIR)$(libdir)/backing-store\" 55 | 56 | LIBS += -lpthread -ldl 57 | 58 | ifneq ($(SD_NOTIFY),) 59 | LIBS += -lsystemd 60 | endif 61 | 62 | PROGRAMS += tgtd tgtadm tgtimg 63 | TGTD_OBJS += tgtd.o mgmt.o target.o scsi.o log.o driver.o util.o work.o \ 64 | concat_buf.o parser.o spc.o sbc.o mmc.o osd.o scc.o smc.o \ 65 | ssc.o libssc.o bs_rdwr.o bs_ssc.o \ 66 | bs_null.o bs_sg.o bs.o libcrc32c.o bs_sheepdog.o 67 | 68 | TGTD_DEP = $(TGTD_OBJS:.o=.d) 69 | 70 | TGTD_LDFLAGS = $(LDFLAGS) 71 | TGTD_LDFLAGS += -Wl,-E,-rpath=$(libdir) 72 | 73 | .PHONY:all 74 | all: $(PROGRAMS) $(MODULES) 75 | 76 | tgtd: $(TGTD_OBJS) 77 | echo $(CC) $^ -o $@ $(LIBS) 78 | $(CC) $^ -o $@ $(TGTD_LDFLAGS) $(LIBS) 79 | 80 | -include $(TGTD_DEP) 81 | 82 | TGTADM_OBJS = tgtadm.o concat_buf.o 83 | TGTADM_DEP = $(TGTADM_OBJS:.o=.d) 84 | 85 | tgtadm: $(TGTADM_OBJS) 86 | $(CC) $^ -o $@ $(LDFLAGS) 87 | 88 | -include $(TGTADM_DEP) 89 | 90 | TGTIMG_OBJS = tgtimg.o libssc.o libcrc32c.o 91 | TGTIMG_DEP = $(TGTIMG_OBJS:.o=.d) 92 | 93 | tgtimg: $(TGTIMG_OBJS) 94 | $(CC) $^ -o $@ $(LDFLAGS) 95 | 96 | -include $(TGTIMG_DEP) 97 | 98 | %.o: %.c 99 | $(CC) $(CPPFLAGS) -c $(CFLAGS) $*.c -o $*.o 100 | @$(CC) -MM $(CFLAGS) -MF $*.d -MT $*.o $*.c 101 | 102 | %.so: %.c 103 | $(CC) $(CPPFLAGS) -shared $(CFLAGS) $*.c -o $*.so 104 | 105 | bs_rbd.so: bs_rbd.c 106 | $(CC) $(CPPFLAGS) -shared $(CFLAGS) bs_rbd.c -o bs_rbd.so \ 107 | -lrados -lrbd $(LDFLAGS) 108 | 109 | bs_openvstorage.so: bs_openvstorage.c 110 | $(CC) $(CPPFLAGS) -shared $(CFLAGS) bs_openvstorage.c -o bs_openvstorage.so \ 111 | -lovsvolumedriver -L/usr/lib/openvstorage $(LDFLAGS) 112 | 113 | bs_glfs.so: bs_glfs.c 114 | $(CC) $(CPPFLAGS) -I/usr/include/glusterfs/api \ 115 | -shared $(CFLAGS) bs_glfs.c -o bs_glfs.so \ 116 | -lgfapi $(LDFLAGS) 117 | 118 | .PHONY: install 119 | install: $(PROGRAMS) $(MODULES) 120 | install -d -m 755 $(DESTDIR)$(sbindir) 121 | install -m 755 $(PROGRAMS) $(DESTDIR)$(sbindir) 122 | ifneq ($(MODULES),) 123 | install -d -m 755 $(DESTDIR)$(libdir)/backing-store 124 | install -m 755 $(MODULES) $(DESTDIR)$(libdir)/backing-store 125 | endif 126 | 127 | .PHONY: clean 128 | clean: 129 | rm -f *.[od] *.so $(PROGRAMS) iscsi/*.[od] ibmvio/*.[od] fc/*.[od] 130 | -------------------------------------------------------------------------------- /usr/be_byteshift.h: -------------------------------------------------------------------------------- 1 | #ifndef _LINUX_UNALIGNED_BE_BYTESHIFT_H 2 | #define _LINUX_UNALIGNED_BE_BYTESHIFT_H 3 | 4 | static inline uint16_t __get_unaligned_be16(const uint8_t *p) 5 | { 6 | return p[0] << 8 | p[1]; 7 | } 8 | 9 | static inline uint32_t __get_unaligned_be32(const uint8_t *p) 10 | { 11 | return p[0] << 24 | p[1] << 16 | p[2] << 8 | p[3]; 12 | } 13 | 14 | static inline uint64_t __get_unaligned_be64(const uint8_t *p) 15 | { 16 | return (uint64_t)__get_unaligned_be32(p) << 32 | 17 | __get_unaligned_be32(p + 4); 18 | } 19 | 20 | static inline void __put_unaligned_be16(uint16_t val, uint8_t *p) 21 | { 22 | *p++ = val >> 8; 23 | *p++ = val; 24 | } 25 | 26 | static inline void __put_unaligned_be32(uint32_t val, uint8_t *p) 27 | { 28 | __put_unaligned_be16(val >> 16, p); 29 | __put_unaligned_be16(val, p + 2); 30 | } 31 | 32 | static inline void __put_unaligned_be64(uint64_t val, uint8_t *p) 33 | { 34 | __put_unaligned_be32(val >> 32, p); 35 | __put_unaligned_be32(val, p + 4); 36 | } 37 | 38 | static inline uint16_t get_unaligned_be16(const void *p) 39 | { 40 | return __get_unaligned_be16((const uint8_t *)p); 41 | } 42 | 43 | static inline uint32_t get_unaligned_be24(const uint8_t *p) 44 | { 45 | return p[0] << 16 | p[1] << 8 | p[2]; 46 | } 47 | 48 | static inline uint32_t get_unaligned_be32(const void *p) 49 | { 50 | return __get_unaligned_be32((const uint8_t *)p); 51 | } 52 | 53 | static inline uint64_t get_unaligned_be64(const void *p) 54 | { 55 | return __get_unaligned_be64((const uint8_t *)p); 56 | } 57 | 58 | static inline void put_unaligned_be16(uint16_t val, void *p) 59 | { 60 | __put_unaligned_be16(val, p); 61 | } 62 | 63 | static inline void put_unaligned_be24(uint32_t val, void *p) 64 | { 65 | ((uint8_t *)p)[0] = (val >> 16) & 0xff; 66 | ((uint8_t *)p)[1] = (val >> 8) & 0xff; 67 | ((uint8_t *)p)[2] = val & 0xff; 68 | } 69 | 70 | static inline void put_unaligned_be32(uint32_t val, void *p) 71 | { 72 | __put_unaligned_be32(val, p); 73 | } 74 | 75 | static inline void put_unaligned_be64(uint64_t val, void *p) 76 | { 77 | __put_unaligned_be64(val, p); 78 | } 79 | 80 | #endif /* _LINUX_UNALIGNED_BE_BYTESHIFT_H */ 81 | -------------------------------------------------------------------------------- /usr/bs_aio.h: -------------------------------------------------------------------------------- 1 | #ifndef __BS_AIO_H 2 | #define __BS_AIO_H 3 | 4 | /* this file is a workaround */ 5 | 6 | /* 7 | * eventfd-aio-test by Davide Libenzi (test app for eventfd hooked into KAIO) 8 | * Copyright (C) 2007 Davide Libenzi 9 | * 10 | * This program is free software; you can redistribute it and/or modify 11 | * it under the terms of the GNU General Public License as published by 12 | * the Free Software Foundation; either version 2 of the License, or 13 | * (at your option) any later version. 14 | * 15 | * This program is distributed in the hope that it will be useful, 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | * GNU General Public License for more details. 19 | * 20 | * You should have received a copy of the GNU General Public License 21 | * along with this program; if not, write to the Free Software 22 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 23 | * 24 | * Davide Libenzi 25 | * 26 | */ 27 | 28 | enum { 29 | IOCB_CMD_PREAD = 0, 30 | IOCB_CMD_PWRITE = 1, 31 | IOCB_CMD_FSYNC = 2, 32 | IOCB_CMD_FDSYNC = 3, 33 | /* These two are experimental. 34 | * IOCB_CMD_PREADX = 4, 35 | * IOCB_CMD_POLL = 5, 36 | */ 37 | IOCB_CMD_NOOP = 6, 38 | IOCB_CMD_PREADV = 7, 39 | IOCB_CMD_PWRITEV = 8, 40 | }; 41 | 42 | #define IOCB_FLAG_RESFD (1 << 0) 43 | 44 | #if defined(__LITTLE_ENDIAN) 45 | #define PADDED(x, y) x, y 46 | #elif defined(__BIG_ENDIAN) 47 | #define PADDED(x, y) y, x 48 | #else 49 | #error edit for your odd byteorder. 50 | #endif 51 | 52 | typedef unsigned long io_context_t; 53 | 54 | struct io_event { 55 | uint64_t data; /* the data field from the iocb */ 56 | uint64_t obj; /* what iocb this event came from */ 57 | int64_t res; /* result code for this event */ 58 | int64_t res2; /* secondary result */ 59 | }; 60 | 61 | struct iocb { 62 | /* these are internal to the kernel/libc. */ 63 | uint64_t aio_data; /* data to be returned in event's data */ 64 | int32_t PADDED(aio_key, aio_reserved1); 65 | /* the kernel sets aio_key to the req # */ 66 | 67 | /* common fields */ 68 | uint16_t aio_lio_opcode; /* see IOCB_CMD_ above */ 69 | int16_t aio_reqprio; 70 | int32_t aio_fildes; 71 | 72 | uint64_t aio_buf; 73 | uint64_t aio_nbytes; 74 | int64_t aio_offset; 75 | 76 | /* extra parameters */ 77 | uint64_t aio_reserved2; /* TODO: use this for a (struct sigevent *) */ 78 | 79 | /* flags for the "struct iocb" */ 80 | int32_t aio_flags; 81 | 82 | /* 83 | * if the IOCB_FLAG_RESFD flag of "aio_flags" is set, this is an 84 | * eventfd to signal AIO readiness to 85 | */ 86 | int32_t aio_resfd; 87 | }; /* 64 bytes */ 88 | 89 | static inline int io_setup(unsigned nr_reqs, io_context_t *ctx) 90 | { 91 | return syscall(__NR_io_setup, nr_reqs, ctx); 92 | } 93 | 94 | static inline long io_destroy(io_context_t ctx) 95 | { 96 | return syscall(__NR_io_destroy, ctx); 97 | } 98 | 99 | static inline int io_submit(io_context_t ctx, long n, struct iocb **paiocb) 100 | { 101 | return syscall(__NR_io_submit, ctx, n, paiocb); 102 | } 103 | 104 | static inline long io_cancel(io_context_t ctx, struct iocb *aiocb, 105 | struct io_event *res) 106 | { 107 | return syscall(__NR_io_cancel, ctx, aiocb, res); 108 | } 109 | 110 | static inline long io_getevents(io_context_t ctx, long min_nr, long nr, 111 | struct io_event *events, struct timespec *tmo) 112 | { 113 | return syscall(__NR_io_getevents, ctx, min_nr, nr, events, tmo); 114 | } 115 | 116 | static inline int eventfd(int count) 117 | { 118 | return syscall(__NR_eventfd, count); 119 | } 120 | 121 | #endif 122 | -------------------------------------------------------------------------------- /usr/bs_null.c: -------------------------------------------------------------------------------- 1 | /* 2 | * NULL I/O backing store routine 3 | * 4 | * Copyright (C) 2008 Alexander Nezhinsky 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU General Public License as 8 | * published by the Free Software Foundation, version 2 of the 9 | * License. 10 | * 11 | * This program is distributed in the hope that it will be useful, but 12 | * WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program; if not, write to the Free Software 18 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 19 | * 02110-1301 USA 20 | */ 21 | 22 | #include 23 | #include 24 | #include 25 | #include 26 | 27 | #include "list.h" 28 | #include "tgtd.h" 29 | #include "scsi.h" 30 | 31 | #define NULL_BS_DEV_SIZE (1ULL << 40) 32 | 33 | int bs_null_cmd_submit(struct scsi_cmd *cmd) 34 | { 35 | scsi_set_result(cmd, SAM_STAT_GOOD); 36 | return 0; 37 | } 38 | 39 | static int bs_null_open(struct scsi_lu *lu, char *path, 40 | int *fd, uint64_t *size) 41 | { 42 | *size = NULL_BS_DEV_SIZE; 43 | dprintf("NULL backing store open, size: %" PRIu64 "\n", *size); 44 | return 0; 45 | } 46 | 47 | static void bs_null_close(struct scsi_lu *lu) 48 | { 49 | } 50 | 51 | static struct backingstore_template null_bst = { 52 | .bs_name = "null", 53 | .bs_datasize = 0, 54 | .bs_open = bs_null_open, 55 | .bs_close = bs_null_close, 56 | .bs_cmd_submit = bs_null_cmd_submit, 57 | }; 58 | 59 | __attribute__((constructor)) static void bs_null_constructor(void) 60 | { 61 | register_backingstore_template(&null_bst); 62 | } 63 | -------------------------------------------------------------------------------- /usr/bs_ssc.h: -------------------------------------------------------------------------------- 1 | #ifndef __BS_SSC_H 2 | #define __BS_SSC_H 3 | 4 | /* 5 | * structure of a 'poor mans double linked list' on disk. 6 | */ 7 | 8 | /** 9 | * Block type definitations 10 | * 11 | * @BLK_NOOP: No Operation.. Dummy value 12 | * @BLK_UNCOMPRESS_DATA: If true, data block is uncompressed 13 | * @BLK_ENCRYPTED_DATA: If true, data block is encrypted 14 | * @BLK_FILEMARK: Represents a filemark 15 | * @BLK_SETMARK: Represents a setmark 16 | * @BLK_BOT: Represents a Beginning of Tape marker 17 | * @BLK_EOD: Represents an End of Data marker 18 | * 19 | * Defines for types of SSC data blocks 20 | */ 21 | #define BLK_NOOP 0x00000000 22 | #define BLK_COMPRESSED_DATA 0x00000001 23 | #define BLK_UNCOMPRESS_DATA 0x00000002 24 | #define BLK_ENCRYPTED_DATA 0x00000004 25 | #define BLK_BOT 0x00000010 26 | #define BLK_EOD 0x00000020 27 | #define BLK_FILEMARK 0x00000040 28 | #define BLK_SETMARK 0x00000080 29 | 30 | #define TGT_TAPE_VERSION 2 31 | 32 | #define SSC_BLK_HDR_SIZE (sizeof(struct blk_header)) 33 | 34 | struct blk_header { 35 | uint8_t h_csum[4]; 36 | uint32_t ondisk_sz; 37 | uint32_t blk_sz; 38 | uint32_t blk_type; 39 | uint64_t blk_num; 40 | uint64_t prev; 41 | uint64_t curr; 42 | uint64_t next; 43 | }; 44 | 45 | /* 46 | * MAM (media access memory) structure based from IBM Ultrium SCSI 47 | * Reference WB1109-02 48 | */ 49 | struct MAM { 50 | uint32_t tape_fmt_version; 51 | uint32_t __pad1; 52 | 53 | uint64_t remaining_capacity; 54 | uint64_t max_capacity; 55 | uint64_t TapeAlert; 56 | uint64_t load_count; 57 | uint64_t MAM_space_remaining; 58 | 59 | uint8_t assigning_organization_1[8]; 60 | uint8_t formatted_density_code; 61 | uint8_t __pad2[5]; 62 | uint8_t initialization_count[2]; 63 | uint8_t dev_make_serial_last_load[4][40]; 64 | 65 | uint64_t written_in_medium_life; 66 | uint64_t read_in_medium_life; 67 | uint64_t written_in_last_load; 68 | uint64_t read_in_last_load; 69 | 70 | uint8_t medium_manufacturer[8]; 71 | uint8_t medium_serial_number[32]; 72 | uint32_t medium_length; 73 | uint32_t medium_width; 74 | uint8_t assigning_organization_2[8]; 75 | uint8_t medium_density_code; 76 | uint8_t __pad3[7]; 77 | uint8_t medium_manufacture_date[8]; 78 | uint64_t MAM_capacity; 79 | uint8_t medium_type; 80 | uint8_t __pad4; 81 | uint16_t medium_type_information; 82 | uint8_t __pad5[4]; 83 | 84 | uint8_t application_vendor[8]; 85 | uint8_t application_name[32]; 86 | uint8_t application_version[8]; 87 | uint8_t user_medium_text_label[160]; 88 | uint8_t date_time_last_written[12]; 89 | uint8_t __pad6[3]; 90 | uint8_t localization_identifier; 91 | uint8_t barcode[32]; 92 | uint8_t owning_host_textual_name[80]; 93 | uint8_t media_pool[160]; 94 | 95 | uint8_t vendor_unique[256]; 96 | 97 | uint8_t dirty; 98 | uint8_t __reserved[7]; 99 | }; 100 | 101 | #endif 102 | -------------------------------------------------------------------------------- /usr/bs_thread.h: -------------------------------------------------------------------------------- 1 | typedef void (request_func_t) (struct scsi_cmd *); 2 | 3 | struct bs_thread_info { 4 | pthread_t *worker_thread; 5 | int nr_worker_threads; 6 | 7 | /* wokers sleep on this and signaled by tgtd */ 8 | pthread_cond_t pending_cond; 9 | /* locked by tgtd and workers */ 10 | pthread_mutex_t pending_lock; 11 | /* protected by pending_lock */ 12 | struct list_head pending_list; 13 | 14 | request_func_t *request_fn; 15 | }; 16 | 17 | static inline struct bs_thread_info *BS_THREAD_I(struct scsi_lu *lu) 18 | { 19 | return (struct bs_thread_info *) ((char *)lu + sizeof(*lu)); 20 | } 21 | 22 | extern tgtadm_err bs_thread_open(struct bs_thread_info *info, request_func_t *rfn, 23 | int nr_threads); 24 | extern void bs_thread_close(struct bs_thread_info *info); 25 | extern int bs_thread_cmd_submit(struct scsi_cmd *cmd); 26 | extern int nr_iothreads; 27 | -------------------------------------------------------------------------------- /usr/bsg.h: -------------------------------------------------------------------------------- 1 | #ifndef BSG_H 2 | #define BSG_H 3 | 4 | #include 5 | 6 | #define BSG_PROTOCOL_SCSI 0 7 | 8 | #define BSG_SUB_PROTOCOL_SCSI_CMD 0 9 | #define BSG_SUB_PROTOCOL_SCSI_TMF 1 10 | #define BSG_SUB_PROTOCOL_SCSI_TRANSPORT 2 11 | 12 | /* 13 | * For flags member below 14 | * sg.h sg_io_hdr also has bits defined for it's flags member. However 15 | * none of these bits are implemented/used by bsg. The bits below are 16 | * allocated to not conflict with sg.h ones anyway. 17 | */ 18 | #define BSG_FLAG_Q_AT_TAIL 0x10 /* default, == 0 at this bit, is Q_AT_HEAD */ 19 | 20 | struct sg_io_v4 { 21 | __s32 guard; /* [i] 'Q' to differentiate from v3 */ 22 | __u32 protocol; /* [i] 0 -> SCSI , .... */ 23 | __u32 subprotocol; /* [i] 0 -> SCSI command, 1 -> SCSI task 24 | management function, .... */ 25 | 26 | __u32 request_len; /* [i] in bytes */ 27 | __u64 request; /* [i], [*i] {SCSI: cdb} */ 28 | __u64 request_tag; /* [i] {SCSI: task tag (only if flagged)} */ 29 | __u32 request_attr; /* [i] {SCSI: task attribute} */ 30 | __u32 request_priority; /* [i] {SCSI: task priority} */ 31 | __u32 request_extra; /* [i] {spare, for padding} */ 32 | __u32 max_response_len; /* [i] in bytes */ 33 | __u64 response; /* [i], [*o] {SCSI: (auto)sense data} */ 34 | 35 | /* "dout_": data out (to device); "din_": data in (from device) */ 36 | __u32 dout_iovec_count; /* [i] 0 -> "flat" dout transfer else 37 | dout_xfer points to array of iovec */ 38 | __u32 dout_xfer_len; /* [i] bytes to be transferred to device */ 39 | __u32 din_iovec_count; /* [i] 0 -> "flat" din transfer */ 40 | __u32 din_xfer_len; /* [i] bytes to be transferred from device */ 41 | __u64 dout_xferp; /* [i], [*i] */ 42 | __u64 din_xferp; /* [i], [*o] */ 43 | 44 | __u32 timeout; /* [i] units: millisecond */ 45 | __u32 flags; /* [i] bit mask */ 46 | __u64 usr_ptr; /* [i->o] unused internally */ 47 | __u32 spare_in; /* [i] */ 48 | 49 | __u32 driver_status; /* [o] 0 -> ok */ 50 | __u32 transport_status; /* [o] 0 -> ok */ 51 | __u32 device_status; /* [o] {SCSI: command completion status} */ 52 | __u32 retry_delay; /* [o] {SCSI: status auxiliary information} */ 53 | __u32 info; /* [o] additional information */ 54 | __u32 duration; /* [o] time to complete, in milliseconds */ 55 | __u32 response_len; /* [o] bytes of response actually written */ 56 | __s32 din_resid; /* [o] din_xfer_len - actual_din_xfer_len */ 57 | __s32 dout_resid; /* [o] dout_xfer_len - actual_dout_xfer_len */ 58 | __u64 generated_tag; /* [o] {SCSI: transport generated task tag} */ 59 | __u32 spare_out; /* [o] */ 60 | 61 | __u32 padding; 62 | }; 63 | 64 | #ifdef __KERNEL__ 65 | 66 | #if defined(CONFIG_BLK_DEV_BSG) 67 | struct bsg_class_device { 68 | struct device *class_dev; 69 | struct device *parent; 70 | int minor; 71 | struct request_queue *queue; 72 | struct kref ref; 73 | void (*release)(struct device *); 74 | }; 75 | 76 | extern int bsg_register_queue(struct request_queue *q, 77 | struct device *parent, const char *name, 78 | void (*release)(struct device *)); 79 | extern void bsg_unregister_queue(struct request_queue *); 80 | #else 81 | static inline int bsg_register_queue(struct request_queue *q, 82 | struct device *parent, const char *name, 83 | void (*release)(struct device *)) 84 | { 85 | return 0; 86 | } 87 | static inline void bsg_unregister_queue(struct request_queue *q) 88 | { 89 | } 90 | #endif 91 | 92 | #endif /* __KERNEL__ */ 93 | 94 | #endif 95 | -------------------------------------------------------------------------------- /usr/concat_buf.c: -------------------------------------------------------------------------------- 1 | /* 2 | * concat_buf functions 3 | * appending formatted output to dynamically grown strings 4 | * 5 | * Copyright (C) 2011 Alexander Nezhinsky 6 | * 7 | * This program is free software; you can redistribute it and/or 8 | * modify it under the terms of the GNU General Public License as 9 | * published by the Free Software Foundation, version 2 of the 10 | * License. 11 | * 12 | * This program is distributed in the hope that it will be useful, but 13 | * WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | * General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program; if not, write to the Free Software 19 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 20 | * 02110-1301 USA 21 | */ 22 | 23 | #include 24 | #include 25 | #include 26 | 27 | #include "log.h" 28 | #include "util.h" 29 | 30 | void concat_buf_init(struct concat_buf *b) 31 | { 32 | b->streamf = open_memstream(&b->buf, &b->size); 33 | b->err = b->streamf ? 0 : errno; 34 | b->used = 0; 35 | } 36 | 37 | int concat_printf(struct concat_buf *b, const char *format, ...) 38 | { 39 | va_list args; 40 | int nprinted; 41 | 42 | if (!b->err) { 43 | va_start(args, format); 44 | nprinted = vfprintf(b->streamf, format, args); 45 | if (nprinted >= 0) 46 | b->used += nprinted; 47 | else { 48 | b->err = nprinted; 49 | fclose(b->streamf); 50 | b->streamf = NULL; 51 | } 52 | va_end(args); 53 | } 54 | return b->err; 55 | } 56 | 57 | const char *concat_delim(struct concat_buf *b, const char *delim) 58 | { 59 | return !b->used ? "" : delim; 60 | } 61 | 62 | int concat_buf_finish(struct concat_buf *b) 63 | { 64 | if (b->streamf) { 65 | fclose(b->streamf); 66 | b->streamf = NULL; 67 | if (b->size) 68 | b->size++; /* account for trailing NULL char */ 69 | } 70 | return b->err; 71 | } 72 | 73 | int concat_write(struct concat_buf *b, int fd, int offset) 74 | { 75 | concat_buf_finish(b); 76 | 77 | if (b->err) { 78 | errno = b->err; 79 | return -1; 80 | } 81 | 82 | if (b->size - offset > 0) 83 | return write(fd, b->buf + offset, b->size - offset); 84 | else { 85 | errno = EINVAL; 86 | return -1; 87 | } 88 | } 89 | 90 | void concat_buf_release(struct concat_buf *b) 91 | { 92 | concat_buf_finish(b); 93 | if (b->buf) { 94 | free(b->buf); 95 | memset(b, 0, sizeof(*b)); 96 | } 97 | } 98 | 99 | -------------------------------------------------------------------------------- /usr/crc32c.h: -------------------------------------------------------------------------------- 1 | #ifndef _LINUX_CRC32C_H 2 | #define _LINUX_CRC32C_H 3 | 4 | #include 5 | #include 6 | 7 | extern uint32_t crc32c_le(uint32_t crc, unsigned char const *address, size_t length); 8 | extern uint32_t crc32c_be(uint32_t crc, unsigned char const *address, size_t length); 9 | 10 | #define crc32c(seed, data, length) crc32c_le(seed, (unsigned char const *)data, length) 11 | 12 | #endif /* _LINUX_CRC32C_H */ 13 | -------------------------------------------------------------------------------- /usr/driver.c: -------------------------------------------------------------------------------- 1 | /* 2 | * driver routine 3 | * 4 | * Copyright (C) 2007 FUJITA Tomonori 5 | * Copyright (C) 2007 Mike Christie 6 | * 7 | * This program is free software; you can redistribute it and/or 8 | * modify it under the terms of the GNU General Public License as 9 | * published by the Free Software Foundation, version 2 of the 10 | * License. 11 | * 12 | * This program is distributed in the hope that it will be useful, but 13 | * WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | * General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program; if not, write to the Free Software 19 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 20 | * 02110-1301 USA 21 | */ 22 | #include 23 | #include 24 | #include 25 | 26 | #include "list.h" 27 | #include "util.h" 28 | #include "tgtd.h" 29 | #include "driver.h" 30 | 31 | #define MAX_NR_DRIVERS 32 32 | 33 | struct tgt_driver *tgt_drivers[MAX_NR_DRIVERS] = { 34 | }; 35 | 36 | int get_driver_index(char *name) 37 | { 38 | int i; 39 | 40 | for (i = 0; tgt_drivers[i]; i++) { 41 | if (!strcmp(name, tgt_drivers[i]->name)) 42 | return i; 43 | } 44 | 45 | return -ENOENT; 46 | } 47 | 48 | int register_driver(struct tgt_driver *drv) 49 | { 50 | int i; 51 | 52 | for (i = 0; i < ARRAY_SIZE(tgt_drivers); i++) 53 | if (!tgt_drivers[i]) { 54 | drv->drv_state = DRIVER_REGD; 55 | tgt_drivers[i] = drv; 56 | return 0; 57 | } 58 | 59 | return -1; 60 | } 61 | 62 | const char *driver_state_name(struct tgt_driver *drv) 63 | { 64 | switch (drv->drv_state) { 65 | case DRIVER_REGD: 66 | return "uninitialized"; 67 | case DRIVER_INIT: 68 | return "ready"; 69 | case DRIVER_ERR: 70 | return "error"; 71 | case DRIVER_EXIT: 72 | return "stopped"; 73 | default: 74 | return "unsupported"; 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /usr/driver.h: -------------------------------------------------------------------------------- 1 | #ifndef __DRIVER_H__ 2 | #define __DRIVER_H__ 3 | 4 | #include "tgtadm_error.h" 5 | 6 | enum tgt_driver_state { 7 | DRIVER_REGD = 0, /* just registered */ 8 | DRIVER_INIT, /* initialized ok */ 9 | DRIVER_ERR, /* failed to initialize */ 10 | DRIVER_EXIT /* exited */ 11 | }; 12 | 13 | struct tgt_driver { 14 | const char *name; 15 | enum tgt_driver_state drv_state; 16 | 17 | int (*init)(int, char *); 18 | void (*exit)(void); 19 | 20 | int (*target_create)(struct target *); 21 | void (*target_destroy)(int, int); 22 | 23 | int (*portal_create)(char *); 24 | int (*portal_destroy)(char *); 25 | 26 | int (*lu_create)(struct scsi_lu *); 27 | 28 | tgtadm_err (*update)(int, int, int ,uint64_t, uint64_t, uint32_t, char *); 29 | tgtadm_err (*show)(int, int, uint64_t, uint32_t, uint64_t, struct concat_buf *); 30 | tgtadm_err (*stat)(int, int, uint64_t, uint32_t, uint64_t, struct concat_buf *); 31 | 32 | uint64_t (*scsi_get_lun)(uint8_t *); 33 | 34 | int (*cmd_end_notify)(uint64_t nid, int result, struct scsi_cmd *); 35 | int (*mgmt_end_notify)(struct mgmt_req *); 36 | 37 | int (*transportid)(int, uint64_t, char *, int); 38 | 39 | const char *default_bst; 40 | 41 | struct list_head target_list; 42 | }; 43 | 44 | extern struct tgt_driver *tgt_drivers[]; 45 | extern int get_driver_index(char *name); 46 | extern int register_driver(struct tgt_driver *drv); 47 | extern const char *driver_state_name(struct tgt_driver *drv); 48 | 49 | #endif /* __DRIVER_H__ */ 50 | -------------------------------------------------------------------------------- /usr/iscsi/md5.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This is the header file for the MD5 message-digest algorithm. 3 | * The algorithm is due to Ron Rivest. This code was 4 | * written by Colin Plumb in 1993, no copyright is claimed. 5 | * This code is in the public domain; do with it what you wish. 6 | * 7 | * Equivalent code is available from RSA Data Security, Inc. 8 | * This code has been tested against that, and is equivalent, 9 | * except that you don't need to include two pages of legalese 10 | * with every copy. 11 | * 12 | * To compute the message digest of a chunk of bytes, declare an 13 | * MD5Context structure, pass it to MD5Init, call MD5Update as 14 | * needed on buffers full of bytes, and then call MD5Final, which 15 | * will fill a supplied 16-byte array with the digest. 16 | * 17 | * Changed so as no longer to depend on Colin Plumb's `usual.h' 18 | * header definitions; now uses stuff from dpkg's config.h 19 | * - Ian Jackson . 20 | * Still in the public domain. 21 | */ 22 | 23 | #ifndef MD5_H 24 | #define MD5_H 25 | 26 | #include 27 | #include 28 | #include 29 | #include 30 | #if (__BYTE_ORDER == __BIG_ENDIAN) 31 | # define WORDS_BIGENDIAN 1 32 | #endif 33 | 34 | typedef uint32_t UWORD32; 35 | 36 | 37 | #ifdef __cplusplus 38 | extern "C" { 39 | #endif 40 | 41 | 42 | #define md5byte unsigned char 43 | 44 | struct MD5Context { 45 | UWORD32 buf[4]; 46 | UWORD32 bytes[2]; 47 | UWORD32 in[16]; 48 | }; 49 | 50 | void MD5Init(struct MD5Context *context); 51 | void MD5Update(struct MD5Context *context, md5byte const *buf, unsigned len); 52 | void MD5Final(unsigned char digest[16], struct MD5Context *context); 53 | void MD5Transform(UWORD32 buf[4], UWORD32 const in[16]); 54 | 55 | 56 | #ifdef __cplusplus 57 | } 58 | #endif 59 | 60 | #endif /* !MD5_H */ 61 | -------------------------------------------------------------------------------- /usr/iscsi/param.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2005-2007 FUJITA Tomonori 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU General Public License as 6 | * published by the Free Software Foundation, version 2 of the 7 | * License. 8 | * 9 | * This program is distributed in the hope that it will be useful, but 10 | * WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program; if not, write to the Free Software 16 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 17 | * 02110-1301 USA 18 | */ 19 | #ifndef PARAMS_H 20 | #define PARAMS_H 21 | 22 | struct iscsi_key; 23 | 24 | struct param { 25 | int state; 26 | unsigned int val; 27 | }; 28 | 29 | #define KEY_STATE_START 0 30 | #define KEY_STATE_REQUEST 1 31 | #define KEY_STATE_DONE 2 32 | 33 | struct iscsi_key_ops { 34 | int (*val_to_str)(unsigned int, char *); 35 | int (*str_to_val)(char *, unsigned int *); 36 | int (*check_val)(struct iscsi_key *, unsigned int *); 37 | void (*set_val)(struct param *, int, unsigned int *); 38 | }; 39 | 40 | struct iscsi_key { 41 | char *name; 42 | unsigned int def; 43 | unsigned int min; 44 | unsigned int max; 45 | struct iscsi_key_ops *ops; 46 | }; 47 | 48 | extern struct iscsi_key session_keys[]; 49 | 50 | extern void param_set_defaults(struct param *, struct iscsi_key *); 51 | extern int param_index_by_name(char *, struct iscsi_key *); 52 | extern int param_val_to_str(struct iscsi_key *, int, unsigned int, char *); 53 | extern int param_str_to_val(struct iscsi_key *, int, char *, unsigned int *); 54 | extern int param_check_val(struct iscsi_key *, int, unsigned int *); 55 | extern void param_set_val(struct iscsi_key *, struct param *, int, unsigned int *); 56 | 57 | #endif 58 | -------------------------------------------------------------------------------- /usr/iscsi/session.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2002-2003 Ardis Technolgies 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU General Public License as 6 | * published by the Free Software Foundation, version 2 of the 7 | * License. 8 | * 9 | * This program is distributed in the hope that it will be useful, but 10 | * WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program; if not, write to the Free Software 16 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 17 | * 02110-1301 USA 18 | */ 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | 26 | #include 27 | #include 28 | 29 | #include "iscsid.h" 30 | #include "tgtd.h" 31 | #include "util.h" 32 | 33 | static LIST_HEAD(sessions_list); 34 | 35 | struct iscsi_session *session_find_name(int tid, const char *iname, uint8_t *isid) 36 | { 37 | struct iscsi_session *session; 38 | struct iscsi_target *target; 39 | 40 | target = target_find_by_id(tid); 41 | if (!target) 42 | return NULL; 43 | 44 | dprintf("session_find_name: %s %x %x %x %x %x %x\n", iname, 45 | isid[0], isid[1], isid[2], isid[3], isid[4], isid[5]); 46 | list_for_each_entry(session, &target->sessions_list, slist) { 47 | if (!memcmp(isid, session->isid, sizeof(session->isid)) && 48 | !strcmp(iname, session->initiator)) 49 | return session; 50 | } 51 | 52 | return NULL; 53 | } 54 | 55 | struct iscsi_session *session_lookup_by_tsih(uint16_t tsih) 56 | { 57 | struct iscsi_session *session; 58 | list_for_each_entry(session, &sessions_list, hlist) { 59 | if (session->tsih == tsih) 60 | return session; 61 | } 62 | return NULL; 63 | } 64 | 65 | int session_create(struct iscsi_connection *conn) 66 | { 67 | int err; 68 | struct iscsi_session *session = NULL; 69 | static uint16_t tsih, last_tsih = 0; 70 | struct iscsi_target *target; 71 | char addr[128]; 72 | 73 | 74 | target = target_find_by_id(conn->tid); 75 | if (!target) 76 | return -EINVAL; 77 | 78 | for (tsih = last_tsih + 1; tsih != last_tsih; tsih++) { 79 | if (!tsih) 80 | continue; 81 | session = session_lookup_by_tsih(tsih); 82 | if (!session) 83 | break; 84 | } 85 | if (session) 86 | return -EINVAL; 87 | 88 | session = zalloc(sizeof(*session)); 89 | if (!session) 90 | return -ENOMEM; 91 | 92 | session->initiator = strdup(conn->initiator); 93 | if (!session->initiator) { 94 | free(session); 95 | return -ENOMEM; 96 | } 97 | 98 | if (conn->initiator_alias) { 99 | session->initiator_alias = strdup(conn->initiator_alias); 100 | if (!session->initiator_alias) { 101 | free(session); 102 | return -ENOMEM; 103 | } 104 | } 105 | 106 | session->info = zalloc(1024); 107 | if (!session->info) { 108 | free(session->initiator); 109 | free(session->initiator_alias); 110 | free(session); 111 | return -ENOMEM; 112 | } 113 | 114 | memset(addr, 0, sizeof(addr)); 115 | conn->tp->ep_show(conn, addr, sizeof(addr)); 116 | 117 | snprintf(session->info, 1024, _TAB3 "Initiator: %s alias: %s\n" 118 | _TAB3 "Connection: %u\n" 119 | _TAB4 "%s\n", session->initiator, 120 | session->initiator_alias ? session->initiator_alias : "none", 121 | conn->cid, addr); 122 | 123 | err = it_nexus_create(target->tid, tsih, 0, session->info); 124 | if (err) { 125 | free(session->initiator); 126 | free(session->initiator_alias); 127 | free(session->info); 128 | free(session); 129 | return err; 130 | } 131 | 132 | session->target = target; 133 | INIT_LIST_HEAD(&session->slist); 134 | list_add(&session->slist, &target->sessions_list); 135 | 136 | INIT_LIST_HEAD(&session->conn_list); 137 | INIT_LIST_HEAD(&session->cmd_list); 138 | INIT_LIST_HEAD(&session->pending_cmd_list); 139 | 140 | memcpy(session->isid, conn->isid, sizeof(session->isid)); 141 | session->tsih = last_tsih = tsih; 142 | 143 | session->rdma = conn->tp->rdma; 144 | 145 | conn_add_to_session(conn, session); 146 | 147 | dprintf("session_create: %#" PRIx64 "\n", sid64(conn->isid, session->tsih)); 148 | 149 | list_add(&session->hlist, &sessions_list); 150 | session->exp_cmd_sn = conn->exp_cmd_sn; 151 | 152 | memcpy(session->session_param, conn->session_param, 153 | sizeof(session->session_param)); 154 | 155 | session->max_queue_cmd = 156 | session->session_param[ISCSI_PARAM_MAX_QUEUE_CMD].val; 157 | 158 | return 0; 159 | } 160 | 161 | static void session_destroy(struct iscsi_session *session) 162 | { 163 | if (!list_empty(&session->conn_list)) { 164 | eprintf("%d conn_list is not null\n", session->tsih); 165 | return; 166 | } 167 | 168 | if (session->target) { 169 | list_del(&session->slist); 170 | /* session->target->nr_sessions--; */ 171 | it_nexus_destroy(session->target->tid, session->tsih); 172 | } 173 | 174 | list_del(&session->hlist); 175 | 176 | free(session->initiator); 177 | free(session->initiator_alias); 178 | free(session->info); 179 | free(session); 180 | } 181 | 182 | void session_get(struct iscsi_session *session) 183 | { 184 | session->refcount++; 185 | } 186 | 187 | void session_put(struct iscsi_session *session) 188 | { 189 | if (!--session->refcount) 190 | session_destroy(session); 191 | } 192 | -------------------------------------------------------------------------------- /usr/iscsi/sha1.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Cryptographic API. 3 | * 4 | * SHA1 Secure Hash Algorithm. 5 | * 6 | * Derived from cryptoapi implementation, adapted for in-place 7 | * scatterlist interface. Originally based on the public domain 8 | * implementation written by Steve Reid. 9 | * 10 | * Copyright (c) Alan Smithee. 11 | * Copyright (c) Andrew McDonald 12 | * Copyright (c) Jean-Francois Dive 13 | * 14 | * This program is free software; you can redistribute it and/or modify it 15 | * under the terms of the GNU General Public License as published by the Free 16 | * Software Foundation; either version 2 of the License, or (at your option) 17 | * any later version. 18 | * 19 | */ 20 | #include 21 | #include "sha1.h" 22 | 23 | #define SHA1_DIGEST_SIZE 20 24 | #define SHA1_HMAC_BLOCK_SIZE 64 25 | 26 | static inline uint32_t rol(uint32_t value, uint32_t bits) 27 | { 28 | return (((value) << (bits)) | ((value) >> (32 - (bits)))); 29 | } 30 | 31 | /* blk0() and blk() perform the initial expand. */ 32 | /* I got the idea of expanding during the round function from SSLeay */ 33 | # define blk0(i) block32[i] 34 | 35 | #define blk(i) (block32[i&15] = rol(block32[(i+13)&15]^block32[(i+8)&15] \ 36 | ^block32[(i+2)&15]^block32[i&15],1)) 37 | 38 | /* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */ 39 | #define R0(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk0(i)+0x5A827999+rol(v,5); \ 40 | w=rol(w,30); 41 | #define R1(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk(i)+0x5A827999+rol(v,5); \ 42 | w=rol(w,30); 43 | #define R2(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0x6ED9EBA1+rol(v,5);w=rol(w,30); 44 | #define R3(v,w,x,y,z,i) z+=(((w|x)&y)|(w&x))+blk(i)+0x8F1BBCDC+rol(v,5); \ 45 | w=rol(w,30); 46 | #define R4(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0xCA62C1D6+rol(v,5);w=rol(w,30); 47 | 48 | /* Hash a single 512-bit block. This is the core of the algorithm. */ 49 | static void sha1_transform(uint32_t *state, const uint8_t *in) 50 | { 51 | uint32_t a, b, c, d, e; 52 | uint32_t block32[16]; 53 | 54 | /* convert/copy data to workspace */ 55 | for (a = 0; a < sizeof(block32)/sizeof(uint32_t); a++) 56 | block32[a] = ntohl (((const uint32_t *)in)[a]); 57 | 58 | /* Copy context->state[] to working vars */ 59 | a = state[0]; 60 | b = state[1]; 61 | c = state[2]; 62 | d = state[3]; 63 | e = state[4]; 64 | 65 | /* 4 rounds of 20 operations each. Loop unrolled. */ 66 | R0(a,b,c,d,e, 0); R0(e,a,b,c,d, 1); R0(d,e,a,b,c, 2); R0(c,d,e,a,b, 3); 67 | R0(b,c,d,e,a, 4); R0(a,b,c,d,e, 5); R0(e,a,b,c,d, 6); R0(d,e,a,b,c, 7); 68 | R0(c,d,e,a,b, 8); R0(b,c,d,e,a, 9); R0(a,b,c,d,e,10); R0(e,a,b,c,d,11); 69 | R0(d,e,a,b,c,12); R0(c,d,e,a,b,13); R0(b,c,d,e,a,14); R0(a,b,c,d,e,15); 70 | R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19); 71 | R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23); 72 | R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27); 73 | R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31); 74 | R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35); 75 | R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39); 76 | R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43); 77 | R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47); 78 | R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51); 79 | R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55); 80 | R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59); 81 | R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63); 82 | R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67); 83 | R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71); 84 | R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75); 85 | R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79); 86 | /* Add the working vars back into context.state[] */ 87 | state[0] += a; 88 | state[1] += b; 89 | state[2] += c; 90 | state[3] += d; 91 | state[4] += e; 92 | /* Wipe variables */ 93 | a = b = c = d = e = 0; 94 | memset (block32, 0x00, sizeof block32); 95 | } 96 | 97 | void sha1_init(void *ctx) 98 | { 99 | struct sha1_ctx *sctx = ctx; 100 | static const struct sha1_ctx initstate = { 101 | 0, 102 | { 0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476, 0xC3D2E1F0 }, 103 | { 0, } 104 | }; 105 | 106 | *sctx = initstate; 107 | } 108 | 109 | void sha1_update(void *ctx, const uint8_t *data, unsigned int len) 110 | { 111 | struct sha1_ctx *sctx = ctx; 112 | unsigned int i, j; 113 | 114 | j = (sctx->count >> 3) & 0x3f; 115 | sctx->count += len << 3; 116 | 117 | if ((j + len) > 63) { 118 | memcpy(&sctx->buffer[j], data, (i = 64-j)); 119 | sha1_transform(sctx->state, sctx->buffer); 120 | for ( ; i + 63 < len; i += 64) { 121 | sha1_transform(sctx->state, &data[i]); 122 | } 123 | j = 0; 124 | } 125 | else i = 0; 126 | memcpy(&sctx->buffer[j], &data[i], len - i); 127 | } 128 | 129 | 130 | /* Add padding and return the message digest. */ 131 | void sha1_final(void* ctx, uint8_t *out) 132 | { 133 | struct sha1_ctx *sctx = ctx; 134 | uint32_t i, j, index, padlen; 135 | uint64_t t; 136 | uint8_t bits[8] = { 0, }; 137 | static const uint8_t padding[64] = { 0x80, }; 138 | 139 | t = sctx->count; 140 | bits[7] = 0xff & t; t>>=8; 141 | bits[6] = 0xff & t; t>>=8; 142 | bits[5] = 0xff & t; t>>=8; 143 | bits[4] = 0xff & t; t>>=8; 144 | bits[3] = 0xff & t; t>>=8; 145 | bits[2] = 0xff & t; t>>=8; 146 | bits[1] = 0xff & t; t>>=8; 147 | bits[0] = 0xff & t; 148 | 149 | /* Pad out to 56 mod 64 */ 150 | index = (sctx->count >> 3) & 0x3f; 151 | padlen = (index < 56) ? (56 - index) : ((64+56) - index); 152 | sha1_update(sctx, padding, padlen); 153 | 154 | /* Append length */ 155 | sha1_update(sctx, bits, sizeof bits); 156 | 157 | /* Store state in digest */ 158 | for (i = j = 0; i < 5; i++, j += 4) { 159 | uint32_t t2 = sctx->state[i]; 160 | out[j+3] = t2 & 0xff; t2>>=8; 161 | out[j+2] = t2 & 0xff; t2>>=8; 162 | out[j+1] = t2 & 0xff; t2>>=8; 163 | out[j ] = t2 & 0xff; 164 | } 165 | 166 | /* Wipe context */ 167 | memset(sctx, 0, sizeof *sctx); 168 | } 169 | -------------------------------------------------------------------------------- /usr/iscsi/sha1.h: -------------------------------------------------------------------------------- 1 | /* 2 | * sha1.h - SHA1 Secure Hash Algorithm used for CHAP authentication. 3 | * copied from the Linux kernel's Cryptographic API and slightly adjusted to 4 | * fit IET's needs 5 | * 6 | * This file is (c) 2004 Xiranet Communications GmbH 7 | * and licensed under the GPL. 8 | */ 9 | 10 | #ifndef SHA1_H 11 | #define SHA1_H 12 | 13 | #include 14 | #include 15 | #include 16 | 17 | struct sha1_ctx { 18 | uint64_t count; 19 | uint32_t state[5]; 20 | uint8_t buffer[64]; 21 | }; 22 | 23 | void sha1_init(void *ctx); 24 | void sha1_update(void *ctx, const uint8_t *data, unsigned int len); 25 | void sha1_final(void* ctx, uint8_t *out); 26 | 27 | #endif 28 | -------------------------------------------------------------------------------- /usr/iscsi/transport.c: -------------------------------------------------------------------------------- 1 | /* 2 | * iSCSI transport functions 3 | * 4 | * Copyright (C) 2007 FUJITA Tomonori 5 | * Copyright (C) 2007 Mike Christie 6 | * 7 | * This program is free software; you can redistribute it and/or 8 | * modify it under the terms of the GNU General Public License as 9 | * published by the Free Software Foundation, version 2 of the 10 | * License. 11 | * 12 | * This program is distributed in the hope that it will be useful, but 13 | * WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | * General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program; if not, write to the Free Software 19 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 20 | * 02110-1301 USA 21 | */ 22 | #include 23 | #include 24 | #include 25 | #include 26 | 27 | #include "iscsid.h" 28 | #include "transport.h" 29 | 30 | static LIST_HEAD(iscsi_transport_list); 31 | 32 | int lld_index; 33 | 34 | int iscsi_init(int index, char *args) 35 | { 36 | int err, nr = 0; 37 | struct iscsi_transport *t; 38 | 39 | lld_index = index; 40 | 41 | list_for_each_entry(t, &iscsi_transport_list, 42 | iscsi_transport_siblings) { 43 | err = t->ep_init(); 44 | if (!err) 45 | nr++; 46 | } 47 | 48 | return !nr; 49 | } 50 | 51 | void iscsi_exit(void) 52 | { 53 | struct iscsi_transport *t; 54 | 55 | list_for_each_entry(t, &iscsi_transport_list, 56 | iscsi_transport_siblings) 57 | if (t->ep_exit) 58 | t->ep_exit(); 59 | } 60 | 61 | int iscsi_transport_register(struct iscsi_transport *t) 62 | { 63 | list_add_tail(&t->iscsi_transport_siblings, &iscsi_transport_list); 64 | return 0; 65 | } 66 | -------------------------------------------------------------------------------- /usr/iscsi/transport.h: -------------------------------------------------------------------------------- 1 | #ifndef __TRANSPORT_H 2 | #define __TRANSPORT_H 3 | 4 | #include 5 | #include "list.h" 6 | 7 | struct iscsi_connection; 8 | struct iscsi_task; 9 | 10 | struct iscsi_transport { 11 | struct list_head iscsi_transport_siblings; 12 | 13 | const char *name; 14 | int rdma; 15 | int data_padding; 16 | 17 | int (*ep_init) (void); 18 | void (*ep_exit) (void); 19 | int (*ep_login_complete)(struct iscsi_connection *conn); 20 | struct iscsi_task *(*alloc_task)(struct iscsi_connection *conn, 21 | size_t ext_len); 22 | void (*free_task)(struct iscsi_task *task); 23 | size_t (*ep_read)(struct iscsi_connection *conn, void *buf, 24 | size_t nbytes); 25 | size_t (*ep_write_begin)(struct iscsi_connection *conn, void *buf, 26 | size_t nbytes); 27 | void (*ep_write_end)(struct iscsi_connection *conn); 28 | int (*ep_rdma_read)(struct iscsi_connection *conn); 29 | int (*ep_rdma_write)(struct iscsi_connection *conn); 30 | size_t (*ep_close)(struct iscsi_connection *conn); 31 | void (*ep_force_close)(struct iscsi_connection *conn); 32 | void (*ep_release)(struct iscsi_connection *conn); 33 | 34 | int (*ep_show)(struct iscsi_connection *conn, char *buf, int rest); 35 | void (*ep_event_modify)(struct iscsi_connection *conn, int events); 36 | void *(*alloc_data_buf)(struct iscsi_connection *conn, size_t sz); 37 | void (*free_data_buf)(struct iscsi_connection *conn, void *buf); 38 | int (*ep_getsockname)(struct iscsi_connection *conn, 39 | struct sockaddr *sa, socklen_t *len); 40 | int (*ep_getpeername)(struct iscsi_connection *conn, 41 | struct sockaddr *sa, socklen_t *len); 42 | void (*ep_nop_reply) (long ttt); 43 | }; 44 | 45 | extern int iscsi_transport_register(struct iscsi_transport *); 46 | 47 | #endif 48 | -------------------------------------------------------------------------------- /usr/libssc.h: -------------------------------------------------------------------------------- 1 | #ifndef __LIBSSC_H 2 | #define __LIBSSC_H 3 | 4 | extern int ssc_read_mam_info(int fd, struct MAM_info *i); 5 | extern int ssc_write_mam_info(int fd, struct MAM_info *i); 6 | extern int ssc_read_blkhdr(int fd, struct blk_header_info *h, loff_t offset); 7 | extern int ssc_write_blkhdr(int fd, struct blk_header_info *h, loff_t offset); 8 | 9 | #endif 10 | -------------------------------------------------------------------------------- /usr/list.h: -------------------------------------------------------------------------------- 1 | #ifndef __LIST_H__ 2 | #define __LIST_H__ 3 | 4 | /* taken from linux kernel */ 5 | 6 | #undef offsetof 7 | #ifdef __compiler_offsetof 8 | #define offsetof(TYPE,MEMBER) __compiler_offsetof(TYPE,MEMBER) 9 | #else 10 | #define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER) 11 | #endif 12 | 13 | #define container_of(ptr, type, member) ({ \ 14 | const typeof( ((type *)0)->member ) *__mptr = (ptr); \ 15 | (type *)( (char *)__mptr - offsetof(type,member) );}) 16 | 17 | struct list_head { 18 | struct list_head *next, *prev; 19 | }; 20 | 21 | #define LIST_HEAD_INIT(name) { &(name), &(name) } 22 | 23 | #define LIST_HEAD(name) \ 24 | struct list_head name = LIST_HEAD_INIT(name) 25 | 26 | static inline void INIT_LIST_HEAD(struct list_head *list) 27 | { 28 | list->next = list; 29 | list->prev = list; 30 | } 31 | 32 | #define list_first_entry(ptr, type, member) \ 33 | list_entry((ptr)->next, type, member) 34 | 35 | static inline int list_empty(const struct list_head *head) 36 | { 37 | return head->next == head; 38 | } 39 | 40 | #define list_entry(ptr, type, member) \ 41 | container_of(ptr, type, member) 42 | 43 | #define list_for_each(pos, head) \ 44 | for (pos = (head)->next; pos != (head); pos = pos->next) 45 | 46 | #define list_for_each_prev(pos, head) \ 47 | for (pos = (head)->prev; pos != (head); pos = pos->prev) 48 | 49 | #define list_for_each_entry(pos, head, member) \ 50 | for (pos = list_entry((head)->next, typeof(*pos), member); \ 51 | &pos->member != (head); \ 52 | pos = list_entry(pos->member.next, typeof(*pos), member)) 53 | 54 | #define list_for_each_entry_safe(pos, n, head, member) \ 55 | for (pos = list_entry((head)->next, typeof(*pos), member), \ 56 | n = list_entry(pos->member.next, typeof(*pos), member); \ 57 | &pos->member != (head); \ 58 | pos = n, n = list_entry(n->member.next, typeof(*n), member)) 59 | 60 | static inline void __list_add(struct list_head *new, 61 | struct list_head *prev, 62 | struct list_head *next) 63 | { 64 | next->prev = new; 65 | new->next = next; 66 | new->prev = prev; 67 | prev->next = new; 68 | } 69 | 70 | static inline void list_add(struct list_head *new, struct list_head *head) 71 | { 72 | __list_add(new, head, head->next); 73 | } 74 | 75 | static inline void list_add_tail(struct list_head *new, struct list_head *head) 76 | { 77 | __list_add(new, head->prev, head); 78 | } 79 | 80 | static inline void __list_del(struct list_head * prev, struct list_head * next) 81 | { 82 | next->prev = prev; 83 | prev->next = next; 84 | } 85 | 86 | static inline void list_del(struct list_head *entry) 87 | { 88 | __list_del(entry->prev, entry->next); 89 | entry->next = entry->prev = NULL; 90 | } 91 | 92 | static inline void list_del_init(struct list_head *entry) 93 | { 94 | __list_del(entry->prev, entry->next); 95 | INIT_LIST_HEAD(entry); 96 | } 97 | 98 | static inline void __list_splice(const struct list_head *list, 99 | struct list_head *prev, 100 | struct list_head *next) 101 | { 102 | struct list_head *first = list->next; 103 | struct list_head *last = list->prev; 104 | 105 | first->prev = prev; 106 | prev->next = first; 107 | 108 | last->next = next; 109 | next->prev = last; 110 | } 111 | 112 | static inline void list_splice_init(struct list_head *list, 113 | struct list_head *head) 114 | { 115 | if (!list_empty(list)) { 116 | __list_splice(list, head, head->next); 117 | INIT_LIST_HEAD(list); 118 | } 119 | } 120 | 121 | #endif 122 | -------------------------------------------------------------------------------- /usr/log.h: -------------------------------------------------------------------------------- 1 | /* 2 | * iSCSI Safe Logging and Tracing Library 3 | * 4 | * Copyright (C) 2004 Dmitry Yusupov, Alex Aizman 5 | * maintained by open-iscsi@googlegroups.com 6 | * 7 | * circular buffer code based on log.c from dm-multipath project 8 | * 9 | * heavily based on code from log.c: 10 | * Copyright (C) 2002-2003 Ardis Technolgies , 11 | * licensed under the terms of the GNU GPL v2.0, 12 | * 13 | * This program is free software; you can redistribute it and/or modify 14 | * it under the terms of the GNU General Public License as published 15 | * by the Free Software Foundation; either version 2 of the License, or 16 | * (at your option) any later version. 17 | * 18 | * This program is distributed in the hope that it will be useful, but 19 | * WITHOUT ANY WARRANTY; without even the implied warranty of 20 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 21 | * General Public License for more details. 22 | * 23 | * See the file COPYING included with this distribution for more details. 24 | */ 25 | 26 | #ifndef LOG_H 27 | #define LOG_H 28 | 29 | #include 30 | 31 | #define likely(x) __builtin_expect(!!(x), 1) 32 | #define unlikely(x) __builtin_expect(!!(x), 0) 33 | 34 | union semun { 35 | int val; 36 | struct semid_ds *buf; 37 | unsigned short int *array; 38 | struct seminfo *__buf; 39 | }; 40 | 41 | #define LOG_SPACE_SIZE 16384 42 | #define MAX_MSG_SIZE 256 43 | 44 | extern int log_daemon; 45 | extern int log_level; 46 | 47 | struct logmsg { 48 | short int prio; 49 | void *next; 50 | char *str; 51 | }; 52 | 53 | struct logarea { 54 | int empty; 55 | int active; 56 | void *head; 57 | void *tail; 58 | void *start; 59 | void *end; 60 | char *buff; 61 | int semid; 62 | union semun semarg; 63 | }; 64 | 65 | extern int log_init (char * progname, int size, int daemon, int debug); 66 | extern void log_close (void); 67 | extern void dump_logmsg (void *); 68 | extern void log_warning(const char *fmt, ...) 69 | __attribute__ ((format (printf, 1, 2))); 70 | extern void log_error(const char *fmt, ...) 71 | __attribute__ ((format (printf, 1, 2))); 72 | extern void log_debug(const char *fmt, ...) 73 | __attribute__ ((format (printf, 1, 2))); 74 | 75 | #ifdef NO_LOGGING 76 | #define eprintf(fmt, args...) \ 77 | do { \ 78 | fprintf(stderr, "%s: " fmt, program_name, ##args); \ 79 | } while (0) 80 | 81 | #define dprintf(fmt, args...) \ 82 | do { \ 83 | if (debug) \ 84 | fprintf(stderr, "%s %d: " fmt, \ 85 | __FUNCTION__, __LINE__, ##args); \ 86 | } while (0) 87 | #else 88 | #define eprintf(fmt, args...) \ 89 | do { \ 90 | log_error("%s(%d) " fmt, __FUNCTION__, __LINE__, ##args); \ 91 | } while (0) 92 | 93 | #define dprintf(fmt, args...) \ 94 | do { \ 95 | if (unlikely(is_debug)) \ 96 | log_debug("%s(%d) " fmt, __FUNCTION__, __LINE__, ##args); \ 97 | } while (0) 98 | #endif 99 | 100 | #endif /* LOG_H */ 101 | -------------------------------------------------------------------------------- /usr/media.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This program is free software; you can redistribute it and/or modify 3 | * it under the terms of the GNU General Public License as published by 4 | * the Free Software Foundation; version 2 of the License. 5 | * 6 | * This program is distributed in the hope that it will be useful, 7 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 8 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 9 | * GNU General Public License for more details. 10 | * 11 | * You should have received a copy of the GNU General Public License 12 | * along with this program; if not, write to the Free Software 13 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 14 | */ 15 | #ifndef _MEDIA_H_ 16 | #define _MEDIA_H_ 17 | 18 | enum c_type { /* Cartridge Types - Ref: smc3r06 - Table 20, page 37 */ 19 | CART_UNSPECIFIED, 20 | CART_DATA, 21 | CART_CLEAN, 22 | CART_DIAGNOSTICS, 23 | CART_WORM, 24 | CART_MICROCODE, 25 | }; 26 | 27 | #endif /* _MEDIA_H_ */ 28 | 29 | -------------------------------------------------------------------------------- /usr/osd.c: -------------------------------------------------------------------------------- 1 | /* 2 | * SCSI object storage device command processing 3 | * 4 | * Copyright (C) 2006-2007 Pete Wyckoff 5 | * Copyright (C) 2007 FUJITA Tomonori 6 | * Copyright (C) 2007 Mike Christie 7 | * 8 | * This program is free software; you can redistribute it and/or 9 | * modify it under the terms of the GNU General Public License as 10 | * published by the Free Software Foundation, version 2 of the 11 | * License. 12 | * 13 | * This program is distributed in the hope that it will be useful, but 14 | * WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 | * General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program; if not, write to the Free Software 20 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 21 | * 02110-1301 USA 22 | */ 23 | #include 24 | #include 25 | 26 | #include "list.h" 27 | #include "tgtd.h" 28 | #include "scsi.h" 29 | #include "spc.h" 30 | #include "tgtadm_error.h" 31 | 32 | static int osd_varlen_cdb(int host_no, struct scsi_cmd *cmd) 33 | { 34 | return cmd->dev->bst->bs_cmd_submit(cmd); 35 | } 36 | 37 | /* 38 | * XXX: missing support for b0 and b1, in page 0 and in inquiry code. 39 | * Figure out how to make spc_inquiry handle extra mode pages. 40 | */ 41 | static tgtadm_err osd_lu_init(struct scsi_lu *lu) 42 | { 43 | if (spc_lu_init(lu)) 44 | return TGTADM_NOMEM; 45 | 46 | strncpy(lu->attrs.product_id, "OSD", sizeof(lu->attrs.product_id)); 47 | lu->attrs.sense_format = 1; 48 | lu->attrs.version_desc[0] = 0x0340; /* OSD */ 49 | lu->attrs.version_desc[1] = 0x0960; /* iSCSI */ 50 | lu->attrs.version_desc[2] = 0x0300; /* SPC-3 */ 51 | 52 | return TGTADM_SUCCESS; 53 | } 54 | 55 | static struct device_type_template osd_template = { 56 | .type = TYPE_OSD, 57 | .lu_init = osd_lu_init, 58 | .lu_config = spc_lu_config, 59 | .lu_online = spc_lu_online, 60 | .lu_offline = spc_lu_offline, 61 | .lu_exit = spc_lu_exit, 62 | .ops = { 63 | /* 0x00 */ 64 | {spc_test_unit,}, 65 | {spc_illegal_op,}, 66 | {spc_illegal_op,}, 67 | {spc_request_sense,}, 68 | {spc_illegal_op,}, 69 | {spc_illegal_op,}, 70 | {spc_illegal_op,}, 71 | {spc_illegal_op,}, 72 | 73 | {spc_illegal_op,}, 74 | {spc_illegal_op,}, 75 | {spc_illegal_op,}, 76 | {spc_illegal_op,}, 77 | {spc_illegal_op,}, 78 | {spc_illegal_op,}, 79 | {spc_illegal_op,}, 80 | {spc_illegal_op,}, 81 | 82 | /* 0x10 */ 83 | {spc_illegal_op,}, 84 | {spc_illegal_op,}, 85 | {spc_inquiry,}, 86 | {spc_illegal_op,}, 87 | {spc_illegal_op,}, 88 | {spc_illegal_op,}, 89 | {spc_illegal_op,}, 90 | {spc_illegal_op,}, 91 | 92 | {spc_illegal_op,}, 93 | {spc_illegal_op,}, 94 | {spc_illegal_op,}, 95 | {spc_illegal_op,}, 96 | {spc_illegal_op,}, 97 | {spc_illegal_op,}, 98 | {spc_illegal_op,}, 99 | {spc_illegal_op,}, 100 | 101 | [0x20 ... 0x6f] = {spc_illegal_op}, 102 | 103 | /* 0x70 */ 104 | {spc_illegal_op,}, 105 | {spc_illegal_op,}, 106 | {spc_illegal_op,}, 107 | {spc_illegal_op,}, 108 | {spc_illegal_op,}, 109 | {spc_illegal_op,}, 110 | {spc_illegal_op,}, 111 | {spc_illegal_op,}, 112 | 113 | {spc_illegal_op,}, 114 | {spc_illegal_op,}, 115 | {spc_illegal_op,}, 116 | {spc_illegal_op,}, 117 | {spc_illegal_op,}, 118 | {spc_illegal_op,}, 119 | {spc_illegal_op,}, 120 | {osd_varlen_cdb,}, 121 | 122 | [0x80 ... 0x9f] = {spc_illegal_op}, 123 | 124 | /* 0xA0 */ 125 | {spc_report_luns,}, 126 | {spc_illegal_op,}, 127 | {spc_illegal_op,}, 128 | {spc_illegal_op,}, 129 | {spc_illegal_op,}, 130 | {spc_illegal_op,}, 131 | {spc_illegal_op,}, 132 | {spc_illegal_op,}, 133 | 134 | {spc_illegal_op,}, 135 | {spc_illegal_op,}, 136 | {spc_illegal_op,}, 137 | {spc_illegal_op,}, 138 | {spc_illegal_op,}, 139 | {spc_illegal_op,}, 140 | {spc_illegal_op,}, 141 | {spc_illegal_op,}, 142 | 143 | [0xb0 ... 0xff] = {spc_illegal_op}, 144 | } 145 | }; 146 | 147 | __attribute__((constructor)) static void osd_init(void) 148 | { 149 | device_type_register(&osd_template); 150 | } 151 | -------------------------------------------------------------------------------- /usr/parser.h: -------------------------------------------------------------------------------- 1 | /* 2 | * linux/include/linux/parser.h 3 | * 4 | * Header for lib/parser.c 5 | * Intended use of these functions is parsing filesystem argument lists, 6 | * but could potentially be used anywhere else that simple option=arg 7 | * parsing is required. 8 | */ 9 | 10 | 11 | /* associates an integer enumerator with a pattern string. */ 12 | struct match_token { 13 | int token; 14 | char *pattern; 15 | }; 16 | 17 | typedef struct match_token match_table_t[]; 18 | 19 | /* Maximum number of arguments that match_token will find in a pattern */ 20 | enum {MAX_OPT_ARGS = 3}; 21 | 22 | /* Describe the location within a string of a substring */ 23 | typedef struct { 24 | char *from; 25 | char *to; 26 | } substring_t; 27 | 28 | int match_token(char *, match_table_t table, substring_t args[]); 29 | int match_int(substring_t *, int *result); 30 | int match_octal(substring_t *, int *result); 31 | int match_hex(substring_t *, int *result); 32 | char *match_strncpy(char *, substring_t *, size_t); 33 | char *match_strdup(substring_t *); 34 | -------------------------------------------------------------------------------- /usr/scc.c: -------------------------------------------------------------------------------- 1 | /* 2 | * SCSI Controller command processing 3 | * 4 | * Copyright (C) 2007 FUJITA Tomonori 5 | * Copyright (C) 2007 Mike Christie 6 | * 7 | * This program is free software; you can redistribute it and/or 8 | * modify it under the terms of the GNU General Public License as 9 | * published by the Free Software Foundation, version 2 of the 10 | * License. 11 | * 12 | * This program is distributed in the hope that it will be useful, but 13 | * WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | * General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program; if not, write to the Free Software 19 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 20 | * 02110-1301 USA 21 | */ 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | 30 | #include "list.h" 31 | #include "util.h" 32 | #include "tgtd.h" 33 | #include "target.h" 34 | #include "driver.h" 35 | #include "scsi.h" 36 | #include "tgtadm_error.h" 37 | #include "spc.h" 38 | 39 | static tgtadm_err scc_lu_init(struct scsi_lu *lu) 40 | { 41 | if (spc_lu_init(lu)) 42 | return TGTADM_NOMEM; 43 | 44 | strncpy(lu->attrs.product_id, "Controller", 45 | sizeof(lu->attrs.product_id)); 46 | lu->attrs.version_desc[0] = 0x04C0; /* SBC-3 no version claimed */ 47 | lu->attrs.version_desc[1] = 0x0960; /* iSCSI */ 48 | lu->attrs.version_desc[2] = 0x01fb; /* SCC-2 */ 49 | 50 | lu->dev_type_template.lu_online(lu); 51 | 52 | return TGTADM_SUCCESS; 53 | } 54 | 55 | static struct device_type_template scc_template = { 56 | .type = TYPE_RAID, 57 | .lu_init = scc_lu_init, 58 | .lu_config = spc_lu_config, 59 | .lu_online = spc_lu_online, 60 | .lu_offline = spc_lu_offline, 61 | .lu_exit = spc_lu_exit, 62 | .ops = { 63 | {spc_test_unit,}, 64 | {spc_illegal_op,}, 65 | {spc_illegal_op,}, 66 | {spc_request_sense,}, 67 | {spc_illegal_op,}, 68 | {spc_illegal_op,}, 69 | {spc_illegal_op,}, 70 | {spc_illegal_op,}, 71 | 72 | {spc_illegal_op,}, 73 | {spc_illegal_op,}, 74 | {spc_illegal_op,}, 75 | {spc_illegal_op,}, 76 | {spc_illegal_op,}, 77 | {spc_illegal_op,}, 78 | {spc_illegal_op,}, 79 | {spc_illegal_op,}, 80 | 81 | /* 0x10 */ 82 | {spc_illegal_op,}, 83 | {spc_illegal_op,}, 84 | {spc_inquiry,}, 85 | {spc_illegal_op,}, 86 | {spc_illegal_op,}, 87 | {spc_illegal_op,}, 88 | {spc_illegal_op,}, 89 | {spc_illegal_op,}, 90 | 91 | {spc_illegal_op,}, 92 | {spc_illegal_op,}, 93 | {spc_illegal_op,}, 94 | {spc_illegal_op,}, 95 | {spc_illegal_op,}, 96 | {spc_illegal_op,}, 97 | {spc_illegal_op,}, 98 | {spc_illegal_op,}, 99 | 100 | /* 0x20 */ 101 | {spc_illegal_op,}, 102 | {spc_illegal_op,}, 103 | {spc_illegal_op,}, 104 | {spc_illegal_op,}, 105 | {spc_illegal_op,}, 106 | {spc_illegal_op,}, 107 | {spc_illegal_op,}, 108 | {spc_illegal_op,}, 109 | 110 | {spc_illegal_op,}, 111 | {spc_illegal_op,}, 112 | {spc_illegal_op,}, 113 | {spc_illegal_op,}, 114 | {spc_illegal_op,}, 115 | {spc_illegal_op,}, 116 | {spc_illegal_op,}, 117 | {spc_test_unit}, 118 | 119 | [0x30 ... 0x7f] = {spc_illegal_op,}, 120 | 121 | /* 0x80 */ 122 | {spc_illegal_op,}, 123 | {spc_illegal_op,}, 124 | {spc_illegal_op,}, 125 | {spc_illegal_op,}, 126 | {spc_illegal_op,}, 127 | {spc_illegal_op,}, 128 | {spc_illegal_op,}, 129 | {spc_illegal_op,}, 130 | 131 | {spc_illegal_op,}, 132 | {spc_illegal_op,}, 133 | {spc_illegal_op,}, 134 | {spc_illegal_op,}, 135 | {spc_illegal_op,}, 136 | {spc_illegal_op,}, 137 | {spc_illegal_op,}, 138 | {spc_test_unit}, 139 | 140 | [0x90 ... 0x9f] = {spc_illegal_op,}, 141 | 142 | /* 0xA0 */ 143 | {spc_report_luns,}, 144 | {spc_illegal_op,}, 145 | {spc_illegal_op,}, 146 | {spc_service_action, maint_in_service_actions,}, 147 | {spc_illegal_op,}, 148 | {spc_illegal_op,}, 149 | {spc_illegal_op,}, 150 | {spc_illegal_op,}, 151 | 152 | {spc_illegal_op,}, 153 | {spc_illegal_op,}, 154 | {spc_illegal_op,}, 155 | {spc_illegal_op,}, 156 | {spc_illegal_op,}, 157 | {spc_illegal_op,}, 158 | {spc_illegal_op,}, 159 | {spc_test_unit,}, 160 | 161 | [0xb0 ... 0xff] = {spc_illegal_op}, 162 | } 163 | }; 164 | 165 | __attribute__((constructor)) static void scc_init(void) 166 | { 167 | device_type_register(&scc_template); 168 | } 169 | -------------------------------------------------------------------------------- /usr/scsi_cmnd.h: -------------------------------------------------------------------------------- 1 | struct target; 2 | struct mgmt_req; 3 | 4 | /* needs to move somewhere else */ 5 | #define SCSI_SENSE_BUFFERSIZE 252 6 | 7 | enum data_direction { 8 | DATA_NONE = 0, 9 | DATA_WRITE = 1, 10 | DATA_READ = 2, 11 | DATA_BIDIRECTIONAL = 3, 12 | }; 13 | 14 | struct scsi_data_buffer { 15 | uint64_t buffer; 16 | uint32_t length; 17 | uint32_t transfer_len; 18 | int32_t resid; 19 | }; 20 | 21 | struct scsi_cmd { 22 | struct target *c_target; 23 | /* linked it_nexus->cmd_hash_list */ 24 | struct list_head c_hlist; 25 | struct list_head qlist; 26 | 27 | uint64_t dev_id; 28 | 29 | struct scsi_lu *dev; 30 | unsigned long state; 31 | 32 | enum data_direction data_dir; 33 | struct scsi_data_buffer in_sdb; 34 | struct scsi_data_buffer out_sdb; 35 | 36 | uint64_t cmd_itn_id; 37 | uint64_t offset; 38 | uint32_t tl; 39 | uint8_t *scb; 40 | int scb_len; 41 | uint8_t lun[8]; 42 | int attribute; 43 | uint64_t tag; 44 | int result; 45 | struct mgmt_req *mreq; 46 | 47 | unsigned char sense_buffer[SCSI_SENSE_BUFFERSIZE]; 48 | int sense_len; 49 | 50 | struct list_head bs_list; 51 | 52 | struct it_nexus *it_nexus; 53 | struct it_nexus_lu_info *itn_lu_info; 54 | }; 55 | 56 | #define scsi_cmnd_accessor(field, type) \ 57 | static inline void scsi_set_##field(struct scsi_cmd *scmd, type val) \ 58 | { \ 59 | scmd->field = val; \ 60 | } \ 61 | static inline type scsi_get_##field(struct scsi_cmd *scmd) \ 62 | { \ 63 | return scmd->field; \ 64 | } 65 | 66 | scsi_cmnd_accessor(result, int); 67 | scsi_cmnd_accessor(data_dir, enum data_direction); 68 | 69 | 70 | #define scsi_data_buffer_accessor(field, type, set_cast, get_cast) \ 71 | scsi_data_buffer_function(in, field, type, set_cast, get_cast) \ 72 | scsi_data_buffer_function(out, field, type, set_cast, get_cast) 73 | 74 | #define scsi_data_buffer_function(dir, field, type, set_cast, get_cast) \ 75 | static inline void scsi_set_##dir##_##field(struct scsi_cmd *scmd, type val) \ 76 | { \ 77 | scmd->dir##_sdb.field = set_cast (val); \ 78 | } \ 79 | static inline type scsi_get_##dir##_##field(struct scsi_cmd *scmd) \ 80 | { \ 81 | return get_cast (scmd->dir##_sdb.field); \ 82 | } 83 | 84 | scsi_data_buffer_accessor(length, uint32_t, ,); 85 | scsi_data_buffer_accessor(transfer_len, uint32_t, ,); 86 | scsi_data_buffer_accessor(resid, int32_t, ,); 87 | scsi_data_buffer_accessor(buffer, void *, (unsigned long), (void *)(unsigned long)); 88 | 89 | static inline void scsi_set_in_resid_by_actual(struct scsi_cmd *scmd, 90 | uint32_t transfer_len) 91 | { 92 | uint32_t expected_len = scsi_get_in_length(scmd); 93 | int32_t resid; 94 | 95 | if (transfer_len <= expected_len) 96 | resid = expected_len - transfer_len; 97 | else { 98 | resid = -(int32_t)(transfer_len - expected_len); 99 | transfer_len = expected_len; 100 | } 101 | scsi_set_in_transfer_len(scmd, transfer_len); 102 | scsi_set_in_resid(scmd, resid); 103 | } 104 | 105 | static inline void scsi_set_out_resid_by_actual(struct scsi_cmd *scmd, 106 | uint32_t transfer_len) 107 | { 108 | uint32_t expected_len = scsi_get_out_length(scmd); 109 | int32_t resid; 110 | 111 | if (transfer_len <= expected_len) 112 | resid = expected_len - transfer_len; 113 | else { 114 | resid = -(int32_t)(transfer_len - expected_len); 115 | transfer_len = expected_len; 116 | } 117 | scsi_set_out_transfer_len(scmd, transfer_len); 118 | scsi_set_out_resid(scmd, resid); 119 | } 120 | 121 | enum { 122 | TGT_CMD_QUEUED, 123 | TGT_CMD_PROCESSED, 124 | TGT_CMD_ASYNC, 125 | TGT_CMD_NOT_LAST, 126 | }; 127 | 128 | #define CMD_FNS(bit, name) \ 129 | static inline void set_cmd_##name(struct scsi_cmd *c) \ 130 | { \ 131 | (c)->state |= (1UL << TGT_CMD_##bit); \ 132 | } \ 133 | static inline void clear_cmd_##name(struct scsi_cmd *c) \ 134 | { \ 135 | (c)->state &= ~(1UL << TGT_CMD_##bit); \ 136 | } \ 137 | static inline int cmd_##name(const struct scsi_cmd *c) \ 138 | { \ 139 | return ((c)->state & (1UL << TGT_CMD_##bit)); \ 140 | } 141 | 142 | CMD_FNS(QUEUED, queued) 143 | CMD_FNS(PROCESSED, processed) 144 | CMD_FNS(ASYNC, async) 145 | CMD_FNS(NOT_LAST, not_last) 146 | -------------------------------------------------------------------------------- /usr/smc.h: -------------------------------------------------------------------------------- 1 | /* 2 | * SCSI Medium Changer Command 3 | * 4 | * Copyright (C) 2007 Mark Harvey 5 | * 6 | * This program is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; version 2 of the License. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program; if not, write to the Free Software 17 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 18 | */ 19 | 20 | #ifndef _SMC_H_ 21 | #define _SMC_H_ 22 | 23 | #define LOAD 1 24 | #define UNLOAD 0 25 | 26 | /** 27 | * Define for ELEMENT TYPE 28 | */ 29 | #define ELEMENT_ANY 0 30 | #define ELEMENT_MEDIUM_TRANSPORT 1 31 | #define ELEMENT_STORAGE 2 32 | #define ELEMENT_MAP 3 33 | #define ELEMENT_DATA_TRANSFER 4 34 | 35 | /** 36 | * struct slot - Virtual Library element 37 | * 38 | * @slot_addr: Slot address - number between 0 & 65535 39 | * @last_addr: Last slot address where media came from 40 | * @asc: ASC/ASCQ for this slot 41 | * @element_type: 1 = Medium Transport, 2 = Storage, 3 = MAP, 4 = drive 42 | * @cart_type: Type of media in this slot 43 | * @status: Different bits used depending on element_type 44 | * @sides: If media is single or double sided 45 | * @barcode: Barcode of media ID 46 | * @drive_tid: TID of DATA TRANSFER DEVICE configured at this slot address. 47 | * @drive_lun: LUN of DATA TRANSFER DEVICE configured at this slot address. 48 | * 49 | * A linked list of slots describing each element within the virtual library 50 | */ 51 | struct slot { 52 | struct list_head slot_siblings; 53 | uint16_t slot_addr; 54 | uint16_t last_addr; 55 | uint16_t asc; 56 | uint8_t element_type; 57 | uint8_t cart_type; 58 | uint8_t status; 59 | uint8_t sides; 60 | char barcode[11]; 61 | uint8_t drive_tid; 62 | uint64_t drive_lun; 63 | char volume_tag[32]; 64 | }; 65 | 66 | /** 67 | * struct smc_info - Data structure for SMC device 68 | * @media_home: Home directory for virtual media 69 | * @slots: Linked list of 'slots' within the virtual library 70 | * 71 | */ 72 | struct smc_info { 73 | char *media_home; 74 | struct list_head slots; 75 | }; 76 | 77 | enum { 78 | Opt_element_type, Opt_start_address, 79 | Opt_quantity, Opt_sides, Opt_clear_slot, 80 | Opt_address, Opt_barcode, 81 | Opt_tid, Opt_lun, 82 | Opt_type, Opt_dump, 83 | Opt_media_home, 84 | Opt_err, Opt_volumetag, 85 | }; 86 | 87 | static match_table_t tokens = { 88 | {Opt_element_type, "element_type=%s"}, 89 | {Opt_start_address, "start_address=%s"}, 90 | {Opt_quantity, "quantity=%s"}, 91 | {Opt_sides, "sides=%s"}, 92 | {Opt_clear_slot, "clear_slot=%s"}, 93 | {Opt_address, "address=%s"}, 94 | {Opt_barcode, "barcode=%s"}, 95 | {Opt_tid, "tid=%s"}, 96 | {Opt_lun, "lun=%s"}, 97 | {Opt_type, "type=%s"}, 98 | {Opt_dump, "dump=%s"}, 99 | {Opt_media_home, "media_home=%s"}, 100 | {Opt_volumetag, "volume_tag=%s"}, 101 | {Opt_err, NULL}, 102 | }; 103 | 104 | /** 105 | * struct tmp_param{} -- temporary storage of param values from user 106 | * 107 | * As param parsing is stateless, several params need to be collected 108 | * before we know if we are attempting to configure a slot or adding 109 | * a number of new slots. This is just a temporary holder for all 110 | * possible valid params before processing. 111 | */ 112 | struct tmp_param { 113 | int operation; 114 | int element_type; 115 | int start_addr; 116 | int quantity; 117 | int address; 118 | int tid; 119 | uint64_t lun; 120 | char barcode[20]; 121 | int sides; 122 | int clear_slot; 123 | char volume_tag[32]; 124 | } sv_param; 125 | 126 | #endif // _SMC_H_ 127 | -------------------------------------------------------------------------------- /usr/spc.h: -------------------------------------------------------------------------------- 1 | #ifndef __SPC_H 2 | #define __SPC_H 3 | 4 | extern struct service_action maint_in_service_actions[], 5 | persistent_reserve_in_actions[], persistent_reserve_out_actions[]; 6 | 7 | extern int spc_service_action(int host_no, struct scsi_cmd *cmd); 8 | extern int spc_inquiry(int host_no, struct scsi_cmd *cmd); 9 | extern int spc_report_luns(int host_no, struct scsi_cmd *cmd); 10 | extern int spc_start_stop(int host_no, struct scsi_cmd *cmd); 11 | extern int spc_test_unit(int host_no, struct scsi_cmd *cmd); 12 | extern int spc_request_sense(int host_no, struct scsi_cmd *cmd); 13 | extern int spc_prevent_allow_media_removal(int host_no, struct scsi_cmd *cmd); 14 | extern int spc_illegal_op(int host_no, struct scsi_cmd *cmd); 15 | extern int spc_lu_init(struct scsi_lu *lu); 16 | extern int spc_send_diagnostics(int host_no, struct scsi_cmd *cmd); 17 | 18 | typedef tgtadm_err (match_fn_t)(struct scsi_lu *lu, char *params); 19 | extern tgtadm_err lu_config(struct scsi_lu *lu, char *params, match_fn_t *); 20 | extern tgtadm_err spc_lu_config(struct scsi_lu *lu, char *params); 21 | extern void spc_lu_exit(struct scsi_lu *lu); 22 | extern void dump_cdb(struct scsi_cmd *cmd); 23 | extern int spc_mode_sense(int host_no, struct scsi_cmd *cmd); 24 | extern tgtadm_err add_mode_page(struct scsi_lu *lu, char *params); 25 | extern int set_mode_page_changeable_mask(struct scsi_lu *lu, uint8_t pcode, 26 | uint8_t subpcode, uint8_t *mask); 27 | extern struct mode_pg *find_mode_page(struct scsi_lu *lu, 28 | uint8_t pcode, uint8_t subpcode); 29 | extern int spc_mode_select(int host_no, struct scsi_cmd *cmd, 30 | int (*update)(struct scsi_cmd *, uint8_t *, int *)); 31 | extern struct vpd *alloc_vpd(uint16_t size); 32 | extern tgtadm_err spc_lu_online(struct scsi_lu *lu); 33 | extern tgtadm_err spc_lu_offline(struct scsi_lu *lu); 34 | 35 | extern int spc_access_check(struct scsi_cmd *cmd); 36 | #endif 37 | -------------------------------------------------------------------------------- /usr/ssc.h: -------------------------------------------------------------------------------- 1 | /* 2 | * SCSI Streaming specific header 3 | */ 4 | 5 | #ifndef _SSC_H_ 6 | #define _SSC_H_ 7 | 8 | struct blk_header_info { 9 | uint32_t ondisk_sz; 10 | uint32_t blk_sz; 11 | uint32_t blk_type; 12 | uint64_t blk_num; 13 | uint64_t prev; 14 | uint64_t curr; 15 | uint64_t next; 16 | }; 17 | 18 | /* 19 | * MAM structure based from IBM Ultrium SCSI Reference WB1109-02 20 | */ 21 | struct MAM_info { 22 | uint32_t tape_fmt_version; 23 | 24 | uint64_t remaining_capacity; 25 | uint64_t max_capacity; 26 | uint64_t TapeAlert; 27 | uint64_t load_count; 28 | uint64_t MAM_space_remaining; 29 | 30 | uint8_t assigning_organization_1[8]; 31 | uint8_t formatted_density_code; 32 | uint8_t initialization_count[2]; 33 | uint8_t dev_make_serial_last_load[4][40]; 34 | 35 | uint64_t written_in_medium_life; 36 | uint64_t read_in_medium_life; 37 | uint64_t written_in_last_load; 38 | uint64_t read_in_last_load; 39 | 40 | uint8_t medium_manufacturer[8]; 41 | uint8_t medium_serial_number[32]; 42 | uint32_t medium_length; 43 | uint32_t medium_width; 44 | uint8_t assigning_organization_2[8]; 45 | uint8_t medium_density_code; 46 | uint8_t medium_manufacture_date[8]; 47 | uint64_t MAM_capacity; 48 | uint8_t medium_type; 49 | uint16_t medium_type_information; 50 | 51 | uint8_t application_vendor[8]; 52 | uint8_t application_name[32]; 53 | uint8_t application_version[8]; 54 | uint8_t user_medium_text_label[160]; 55 | uint8_t date_time_last_written[12]; 56 | uint8_t localization_identifier; 57 | uint8_t barcode[32]; 58 | uint8_t owning_host_textual_name[80]; 59 | uint8_t media_pool[160]; 60 | 61 | uint8_t vendor_unique[256]; 62 | 63 | uint8_t dirty; 64 | }; 65 | 66 | struct ssc_info { 67 | uint64_t bytes_read; /* Bytes read this load */ 68 | uint64_t bytes_written; /* Bytes written this load */ 69 | 70 | struct MAM_info mam; 71 | 72 | struct blk_header_info c_blk; /* Current block header */ 73 | }; 74 | 75 | #endif 76 | 77 | -------------------------------------------------------------------------------- /usr/target.h: -------------------------------------------------------------------------------- 1 | #ifndef __TARGET_H__ 2 | #define __TARGET_H__ 3 | 4 | #include 5 | 6 | struct acl_entry { 7 | char *address; 8 | struct list_head aclent_list; 9 | }; 10 | 11 | struct iqn_acl_entry { 12 | char *name; 13 | struct list_head iqn_aclent_list; 14 | }; 15 | 16 | struct tgt_account { 17 | int out_aid; 18 | int nr_inaccount; 19 | int max_inaccount; 20 | int *in_aids; 21 | }; 22 | 23 | struct target { 24 | char *name; 25 | 26 | int tid; 27 | int lid; 28 | 29 | enum scsi_target_state target_state; 30 | 31 | struct list_head target_siblings; 32 | 33 | struct list_head device_list; 34 | 35 | struct list_head it_nexus_list; 36 | 37 | struct backingstore_template *bst; 38 | 39 | struct list_head acl_list; 40 | 41 | struct list_head iqn_acl_list; 42 | 43 | struct tgt_account account; 44 | 45 | struct list_head lld_siblings; 46 | }; 47 | 48 | struct it_nexus { 49 | uint64_t itn_id; 50 | long ctime; 51 | 52 | struct list_head cmd_list; 53 | 54 | struct target *nexus_target; 55 | 56 | /* the list of i_t_nexus belonging to a target */ 57 | struct list_head nexus_siblings; 58 | 59 | /* dirty hack for IBMVIO */ 60 | int host_no; 61 | 62 | struct list_head itn_itl_info_list; 63 | 64 | /* only used for show operation */ 65 | char *info; 66 | }; 67 | 68 | enum { 69 | TGT_QUEUE_BLOCKED, 70 | TGT_QUEUE_DELETED, 71 | }; 72 | 73 | #define QUEUE_FNS(bit, name) \ 74 | static inline void set_queue_##name(struct tgt_cmd_queue *q) \ 75 | { \ 76 | (q)->state |= (1UL << TGT_QUEUE_##bit); \ 77 | } \ 78 | static inline void clear_queue_##name(struct tgt_cmd_queue *q) \ 79 | { \ 80 | (q)->state &= ~(1UL << TGT_QUEUE_##bit); \ 81 | } \ 82 | static inline int queue_##name(const struct tgt_cmd_queue *q) \ 83 | { \ 84 | return ((q)->state & (1UL << TGT_QUEUE_##bit)); \ 85 | } 86 | 87 | static inline int queue_active(const struct tgt_cmd_queue *q) \ 88 | { \ 89 | return ((q)->active_cmd); \ 90 | } 91 | 92 | QUEUE_FNS(BLOCKED, blocked) 93 | QUEUE_FNS(DELETED, deleted) 94 | 95 | #endif 96 | -------------------------------------------------------------------------------- /usr/tgtadm.h: -------------------------------------------------------------------------------- 1 | #ifndef TGTADM_H 2 | #define TGTADM_H 3 | 4 | #define TGT_IPC_DIR "/var/run/tgtd" 5 | #define TGT_IPC_NAMESPACE TGT_IPC_DIR"/socket" 6 | #define TGT_LLD_NAME_LEN 64 7 | 8 | #define GLOBAL_TID (~0U) 9 | 10 | #include "tgtadm_error.h" 11 | 12 | enum tgtadm_op { 13 | OP_NEW, 14 | OP_DELETE, 15 | OP_SHOW, 16 | OP_BIND, 17 | OP_UNBIND, 18 | OP_UPDATE, 19 | OP_STATS, 20 | OP_START, 21 | OP_STOP, 22 | }; 23 | 24 | enum tgtadm_mode { 25 | MODE_SYSTEM, 26 | MODE_TARGET, 27 | MODE_DEVICE, 28 | MODE_PORTAL, 29 | MODE_LLD, 30 | 31 | MODE_SESSION, 32 | MODE_CONNECTION, 33 | MODE_ACCOUNT, 34 | }; 35 | 36 | enum tgtadm_account_dir { 37 | ACCOUNT_TYPE_INCOMING, 38 | ACCOUNT_TYPE_OUTGOING, 39 | }; 40 | 41 | struct tgtadm_req { 42 | enum tgtadm_mode mode; 43 | enum tgtadm_op op; 44 | char lld[TGT_LLD_NAME_LEN]; 45 | uint32_t len; 46 | int32_t tid; 47 | uint64_t sid; 48 | uint64_t lun; 49 | uint32_t cid; 50 | uint32_t host_no; 51 | uint32_t device_type; 52 | uint32_t ac_dir; 53 | uint32_t pack; 54 | uint32_t force; 55 | }; 56 | 57 | struct tgtadm_rsp { 58 | uint32_t err; 59 | uint32_t len; 60 | }; 61 | 62 | #endif 63 | -------------------------------------------------------------------------------- /usr/tgtadm_error.h: -------------------------------------------------------------------------------- 1 | #ifndef TGTADM_ERROR_H 2 | #define TGTADM_ERROR_H 3 | 4 | enum tgtadm_errno { 5 | TGTADM_SUCCESS, 6 | TGTADM_UNKNOWN_ERR, 7 | TGTADM_NOMEM, 8 | TGTADM_NO_DRIVER, 9 | TGTADM_NO_TARGET, 10 | 11 | TGTADM_NO_LUN, 12 | TGTADM_NO_SESSION, 13 | TGTADM_NO_CONNECTION, 14 | TGTADM_NO_BINDING, 15 | TGTADM_TARGET_EXIST, 16 | TGTADM_LUN_EXIST, 17 | TGTADM_BINDING_EXIST, 18 | 19 | TGTADM_ACL_EXIST, 20 | TGTADM_ACL_NOEXIST, 21 | TGTADM_USER_EXIST, 22 | TGTADM_NO_USER, 23 | TGTADM_TOO_MANY_USER, 24 | TGTADM_INVALID_REQUEST, 25 | 26 | TGTADM_OUTACCOUNT_EXIST, 27 | TGTADM_TARGET_ACTIVE, 28 | TGTADM_LUN_ACTIVE, 29 | TGTADM_DRIVER_ACTIVE, 30 | TGTADM_UNSUPPORTED_OPERATION, 31 | TGTADM_UNKNOWN_PARAM, 32 | 33 | TGTADM_PREVENT_REMOVAL, 34 | }; 35 | 36 | typedef enum tgtadm_errno tgtadm_err; 37 | 38 | #endif 39 | -------------------------------------------------------------------------------- /usr/util.c: -------------------------------------------------------------------------------- 1 | /* 2 | * common utility functions 3 | * 4 | * Copyright (C) 2007 FUJITA Tomonori 5 | * Copyright (C) 2007 Mike Christie 6 | * 7 | * This program is free software; you can redistribute it and/or 8 | * modify it under the terms of the GNU General Public License as 9 | * published by the Free Software Foundation, version 2 of the 10 | * License. 11 | * 12 | * This program is distributed in the hope that it will be useful, but 13 | * WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | * General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program; if not, write to the Free Software 19 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 20 | * 02110-1301 USA 21 | */ 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | 34 | #include "log.h" 35 | #include "util.h" 36 | 37 | int chrdev_open(char *modname, char *devpath, uint8_t minor, int *fd) 38 | { 39 | FILE *fp; 40 | char name[256], buf[256]; 41 | int err, major; 42 | 43 | fp = fopen("/proc/devices", "r"); 44 | if (!fp) { 45 | eprintf("Cannot open /proc/devices, %m\n"); 46 | return -1; 47 | } 48 | 49 | major = 0; 50 | while (!feof(fp)) { 51 | if (!fgets(buf, sizeof (buf), fp)) 52 | break; 53 | 54 | if (sscanf(buf, "%d %s", &major, name) != 2) 55 | continue; 56 | 57 | if (!strcmp(name, modname)) 58 | break; 59 | major = 0; 60 | } 61 | fclose(fp); 62 | 63 | if (!major) { 64 | eprintf("cannot find %s in /proc/devices - " 65 | "make sure the module is loaded\n", modname); 66 | return -1; 67 | } 68 | 69 | unlink(devpath); 70 | err = mknod(devpath, (S_IFCHR | 0600), makedev(major, minor)); 71 | if (err) { 72 | eprintf("cannot create %s, %m\n", devpath); 73 | return -errno; 74 | } 75 | 76 | *fd = open(devpath, O_RDWR); 77 | if (*fd < 0) { 78 | eprintf("cannot open %s, %m\n", devpath); 79 | return -errno; 80 | } 81 | 82 | return 0; 83 | } 84 | 85 | int backed_file_open(char *path, int oflag, uint64_t *size, uint32_t *blksize) 86 | { 87 | int fd, err; 88 | struct stat64 st; 89 | 90 | fd = open(path, oflag); 91 | if (fd < 0) { 92 | eprintf("Could not open %s, %m\n", path); 93 | return fd; 94 | } 95 | 96 | err = fstat64(fd, &st); 97 | if (err < 0) { 98 | eprintf("Cannot get stat %d, %m\n", fd); 99 | goto close_fd; 100 | } 101 | 102 | if (S_ISREG(st.st_mode)) { 103 | *size = st.st_size; 104 | if (blksize) 105 | *blksize = st.st_blksize; 106 | } else if (S_ISBLK(st.st_mode)) { 107 | err = ioctl(fd, BLKGETSIZE64, size); 108 | if (err < 0) { 109 | eprintf("Cannot get size, %m\n"); 110 | goto close_fd; 111 | } 112 | } else { 113 | eprintf("Cannot use this mode %x\n", st.st_mode); 114 | err = -EINVAL; 115 | goto close_fd; 116 | } 117 | 118 | return fd; 119 | 120 | close_fd: 121 | close(fd); 122 | return err; 123 | } 124 | 125 | int set_non_blocking(int fd) 126 | { 127 | int err; 128 | 129 | err = fcntl(fd, F_GETFL); 130 | if (err < 0) { 131 | eprintf("unable to get fd flags, %m\n"); 132 | } else { 133 | err = fcntl(fd, F_SETFL, err | O_NONBLOCK); 134 | if (err == -1) 135 | eprintf("unable to set fd flags, %m\n"); 136 | else 137 | err = 0; 138 | } 139 | return err; 140 | } 141 | 142 | int str_to_open_flags(char *buf) 143 | { 144 | char *bsoflags_tok = NULL; 145 | int open_flags = 0; 146 | 147 | bsoflags_tok = strtok(buf, ":\0"); 148 | while (bsoflags_tok != NULL) { 149 | while (*bsoflags_tok == ' ') 150 | bsoflags_tok++; 151 | if (!strncmp(bsoflags_tok, "sync", 4)) 152 | open_flags |= O_SYNC; 153 | else if (!strncmp(bsoflags_tok, "direct", 6)) 154 | open_flags |= O_DIRECT; 155 | else { 156 | eprintf("bsoflag option %s not supported\n", 157 | bsoflags_tok); 158 | return -1; 159 | } 160 | 161 | bsoflags_tok = strtok(NULL, ":"); 162 | } 163 | 164 | return open_flags; 165 | } 166 | 167 | char *open_flags_to_str(char *dest, int flags) 168 | { 169 | *dest = '\0'; 170 | 171 | if (flags & O_SYNC) 172 | strcat(dest, "sync"); 173 | if (flags & O_DIRECT) { 174 | if (*dest) 175 | strcat(dest, ":"); 176 | strcat(dest, "direct"); 177 | } 178 | return dest; 179 | } 180 | 181 | int get_blk_shift(unsigned int size) 182 | { 183 | int shift = 0; 184 | 185 | if (!size) 186 | return -1; 187 | 188 | /* find the first non-zero bit */ 189 | while ((size & (1 << shift)) == 0) 190 | shift++; 191 | 192 | /* if more non-zero bits, then size is not a power of 2 */ 193 | if (size > (1 << shift)) 194 | return -1; 195 | 196 | return shift; 197 | } 198 | 199 | /* 200 | * memory copy for spc-style scsi commands. 201 | * Copy up to src_len bytes from src, 202 | * not exceeding *dst_remain_len bytes available at dst. 203 | * Reflect decreased space in *dst_remain_len. 204 | * Return actually copied length. 205 | */ 206 | int spc_memcpy(uint8_t *dst, uint32_t *dst_remain_len, 207 | uint8_t *src, uint32_t src_len) 208 | { 209 | int copy_len = min_t(uint32_t, *dst_remain_len, src_len); 210 | 211 | if (copy_len) { 212 | memcpy(dst, src, copy_len); 213 | *dst_remain_len -= copy_len; 214 | } 215 | return copy_len; 216 | } 217 | -------------------------------------------------------------------------------- /usr/work.c: -------------------------------------------------------------------------------- 1 | /* 2 | * work scheduler, loosely timer-based 3 | * 4 | * Copyright (C) 2006-2007 FUJITA Tomonori 5 | * Copyright (C) 2006-2007 Mike Christie 6 | * Copyright (C) 2011 Alexander Nezhinsky 7 | * 8 | * This program is free software; you can redistribute it and/or 9 | * modify it under the terms of the GNU General Public License as 10 | * published by the Free Software Foundation, version 2 of the 11 | * License. 12 | * 13 | * This program is distributed in the hope that it will be useful, but 14 | * WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 | * General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program; if not, write to the Free Software 20 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 21 | * 02110-1301 USA 22 | */ 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | 29 | #include "list.h" 30 | #include "util.h" 31 | #include "log.h" 32 | #include "work.h" 33 | #include "tgtd.h" 34 | 35 | #define WORK_TIMER_INT_MSEC 500 36 | #define WORK_TIMER_INT_USEC (WORK_TIMER_INT_MSEC * 1000) 37 | 38 | static struct itimerval work_timer = { 39 | {0, WORK_TIMER_INT_USEC}, 40 | {0, WORK_TIMER_INT_USEC} 41 | }; 42 | 43 | static unsigned int elapsed_msecs; 44 | static int timer_pending; 45 | static int timer_fd[2] = {-1, -1}; 46 | 47 | static LIST_HEAD(active_work_list); 48 | static LIST_HEAD(inactive_work_list); 49 | 50 | static void execute_work(void); 51 | 52 | static inline unsigned int timeval_to_msecs(struct timeval t) 53 | { 54 | return t.tv_sec * 1000 + t.tv_usec / 1000; 55 | } 56 | 57 | static void work_timer_schedule_evt(void) 58 | { 59 | unsigned int n = 0; 60 | int err; 61 | 62 | if (timer_pending) 63 | return; 64 | 65 | timer_pending = 1; 66 | 67 | err = write(timer_fd[1], &n, sizeof(n)); 68 | if (err < 0) 69 | eprintf("Failed to write to pipe, %m\n"); 70 | } 71 | 72 | static void work_timer_sig_handler(int data) 73 | { 74 | work_timer_schedule_evt(); 75 | } 76 | 77 | static void work_timer_evt_handler(int fd, int events, void *data) 78 | { 79 | int err; 80 | static int first = 1; 81 | 82 | if (timer_fd[1] == -1) { 83 | unsigned long long s; 84 | struct timeval cur_time; 85 | 86 | err = read(timer_fd[0], &s, sizeof(s)); 87 | if (err < 0) { 88 | if (err != -EAGAIN) 89 | eprintf("failed to read from timerfd, %m\n"); 90 | return; 91 | } 92 | 93 | if (first) { 94 | first = 0; 95 | err = gettimeofday(&cur_time, NULL); 96 | if (err) { 97 | eprintf("gettimeofday failed, %m\n"); 98 | exit(1); 99 | } 100 | elapsed_msecs = timeval_to_msecs(cur_time); 101 | return; 102 | } 103 | 104 | elapsed_msecs += (unsigned int)s * WORK_TIMER_INT_MSEC; 105 | } else { 106 | unsigned int n; 107 | struct timeval cur_time; 108 | 109 | err = read(timer_fd[0], &n, sizeof(n)); 110 | if (err < 0) { 111 | eprintf("Failed to read from pipe, %m\n"); 112 | return; 113 | } 114 | 115 | timer_pending = 0; 116 | 117 | err = gettimeofday(&cur_time, NULL); 118 | if (err) { 119 | eprintf("gettimeofday failed, %m\n"); 120 | exit(1); 121 | } 122 | 123 | elapsed_msecs = timeval_to_msecs(cur_time); 124 | } 125 | 126 | execute_work(); 127 | } 128 | 129 | int work_timer_start(void) 130 | { 131 | struct timeval t; 132 | int err; 133 | 134 | if (elapsed_msecs) 135 | return 0; 136 | 137 | err = gettimeofday(&t, NULL); 138 | if (err) { 139 | eprintf("gettimeofday failed, %m\n"); 140 | exit(1); 141 | } 142 | elapsed_msecs = timeval_to_msecs(t); 143 | 144 | timer_fd[0] = __timerfd_create(WORK_TIMER_INT_USEC); 145 | if (timer_fd[0] >= 0) 146 | eprintf("use timer_fd based scheduler\n"); 147 | else { 148 | struct sigaction s; 149 | 150 | eprintf("use signal based scheduler\n"); 151 | 152 | sigemptyset(&s.sa_mask); 153 | sigaddset(&s.sa_mask, SIGALRM); 154 | s.sa_flags = 0; 155 | s.sa_handler = work_timer_sig_handler; 156 | err = sigaction(SIGALRM, &s, NULL); 157 | if (err) { 158 | eprintf("Failed to setup timer handler\n"); 159 | goto timer_err; 160 | } 161 | 162 | err = setitimer(ITIMER_REAL, &work_timer, 0); 163 | if (err) { 164 | eprintf("Failed to set timer\n"); 165 | goto timer_err; 166 | } 167 | 168 | err = pipe(timer_fd); 169 | if (err) { 170 | eprintf("Failed to open timer pipe\n"); 171 | goto timer_err; 172 | } 173 | } 174 | 175 | err = tgt_event_add(timer_fd[0], EPOLLIN, work_timer_evt_handler, NULL); 176 | if (err) { 177 | eprintf("failed to add timer event, fd:%d\n", timer_fd[0]); 178 | goto timer_err; 179 | } 180 | 181 | dprintf("started, timeout: %d msec\n", WORK_TIMER_INT_MSEC); 182 | return 0; 183 | 184 | timer_err: 185 | work_timer_stop(); 186 | return err; 187 | } 188 | 189 | void work_timer_stop(void) 190 | { 191 | if (!elapsed_msecs) 192 | return; 193 | 194 | elapsed_msecs = 0; 195 | 196 | tgt_event_del(timer_fd[0]); 197 | 198 | if (timer_fd[0] > 0) 199 | close(timer_fd[0]); 200 | 201 | if (timer_fd[1] > 0) { 202 | int ret; 203 | close(timer_fd[1]); 204 | 205 | ret = setitimer(ITIMER_REAL, 0, 0); 206 | if (ret) 207 | eprintf("Failed to stop timer\n"); 208 | else 209 | dprintf("Timer stopped\n"); 210 | } 211 | } 212 | 213 | void add_work(struct tgt_work *work, unsigned int second) 214 | { 215 | struct tgt_work *ent; 216 | struct timeval t; 217 | int err; 218 | 219 | if (second) { 220 | err = gettimeofday(&t, NULL); 221 | if (err) { 222 | eprintf("gettimeofday failed, %m\n"); 223 | exit(1); 224 | } 225 | work->when = timeval_to_msecs(t) + second * 1000; 226 | 227 | list_for_each_entry(ent, &inactive_work_list, entry) { 228 | if (before(work->when, ent->when)) 229 | break; 230 | } 231 | 232 | list_add_tail(&work->entry, &ent->entry); 233 | } else { 234 | list_add_tail(&work->entry, &active_work_list); 235 | work_timer_schedule_evt(); 236 | } 237 | } 238 | 239 | void del_work(struct tgt_work *work) 240 | { 241 | list_del_init(&work->entry); 242 | } 243 | 244 | static void execute_work() 245 | { 246 | struct tgt_work *work, *n; 247 | 248 | list_for_each_entry_safe(work, n, &inactive_work_list, entry) { 249 | if (before(elapsed_msecs, work->when)) 250 | break; 251 | 252 | list_del(&work->entry); 253 | list_add_tail(&work->entry, &active_work_list); 254 | } 255 | 256 | while (!list_empty(&active_work_list)) { 257 | work = list_first_entry(&active_work_list, 258 | struct tgt_work, entry); 259 | list_del_init(&work->entry); 260 | work->func(work->data); 261 | } 262 | } 263 | -------------------------------------------------------------------------------- /usr/work.h: -------------------------------------------------------------------------------- 1 | #ifndef __SCHED_H 2 | #define __SCHED_H 3 | 4 | #if defined(__NR_timerfd_create) && defined(USE_TIMERFD) 5 | 6 | #include 7 | 8 | static inline int __timerfd_create(unsigned int usec) 9 | { 10 | struct itimerspec new_t, old_t; 11 | int fd, err; 12 | 13 | fd = timerfd_create(CLOCK_REALTIME, TFD_NONBLOCK); 14 | if (fd < 0) 15 | return -1; 16 | 17 | new_t.it_value.tv_sec = 0; 18 | new_t.it_value.tv_nsec = 1; 19 | 20 | new_t.it_interval.tv_sec = 0; 21 | new_t.it_interval.tv_nsec = usec * 1000; 22 | 23 | err = timerfd_settime(fd, TFD_TIMER_ABSTIME, &new_t, &old_t); 24 | if (err < 0) { 25 | close(fd); 26 | return -1; 27 | } 28 | return fd; 29 | } 30 | 31 | #else 32 | #define __timerfd_create(usec) (-1) 33 | #endif 34 | 35 | struct tgt_work { 36 | struct list_head entry; 37 | void (*func)(void *); 38 | void *data; 39 | unsigned int when; 40 | }; 41 | 42 | extern int work_timer_start(void); 43 | extern void work_timer_stop(void); 44 | 45 | extern void add_work(struct tgt_work *work, unsigned int second); 46 | extern void del_work(struct tgt_work *work); 47 | 48 | #endif 49 | --------------------------------------------------------------------------------