iscsinl

package module
v0.0.0-...-3190215 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jan 21, 2020 License: BSD-3-Clause Imports: 18 Imported by: 0

README

iscsinl

Go iSCSI netlink library

Documentation

Overview

Package iscsinl acts as an initiator for bootstrapping an iscsi connection Partial implementation of RFC3720 login and NETLINK_ISCSI, just enough to get a connection going.

Index

Constants

View Source
const (
	ISCSI_OP_LOGIN     = 0x03
	ISCSI_OP_LOGIN_RSP = 0x23
	ISCSI_OP_IMMEDIATE = 0x40

	ISCSI_VERSION = 0x00

	ISCSI_FLAG_LOGIN_TRANSIT  = 0x80
	ISCSI_FLAG_LOGIN_CONTINUE = 0x40
)

Login constants

View Source
const (
	ISCSI_SECURITY_NEGOTIATION_STAGE IscsiLoginStage = 0
	ISCSI_OP_PARMS_NEGOTIATION_STAGE                 = 1
	ISCSI_FULL_FEATURE_PHASE                         = 3
)

Login stages

View Source
const (
	UEVENT_BASE                  IscsiEvent = 10
	KEVENT_BASE                             = 100
	ISCSI_UEVENT_CREATE_SESSION             = UEVENT_BASE + 1
	ISCSI_UEVENT_DESTROY_SESSION            = UEVENT_BASE + 2
	ISCSI_UEVENT_CREATE_CONN                = UEVENT_BASE + 3
	ISCSI_UEVENT_DESTROY_CONN               = UEVENT_BASE + 4
	ISCSI_UEVENT_BIND_CONN                  = UEVENT_BASE + 5
	ISCSI_UEVENT_SET_PARAM                  = UEVENT_BASE + 6
	ISCSI_UEVENT_START_CONN                 = UEVENT_BASE + 7
	ISCSI_UEVENT_STOP_CONN                  = UEVENT_BASE + 8
	ISCSI_UEVENT_SEND_PDU                   = UEVENT_BASE + 9

	ISCSI_KEVENT_RECV_PDU       = KEVENT_BASE + 1
	ISCSI_KEVENT_CONN_ERROR     = KEVENT_BASE + 2
	ISCSI_KEVENT_IF_ERROR       = KEVENT_BASE + 3
	ISCSI_KEVENT_CREATE_SESSION = KEVENT_BASE + 6
)

IscsiEvents that we use

View Source
const (
	ISCSI_OK                      IscsiErr = 0
	ISCSI_ERR_BASE                         = 1000
	ISCSI_ERR_DATASN                       = ISCSI_ERR_BASE + 1
	ISCSI_ERR_DATA_OFFSET                  = ISCSI_ERR_BASE + 2
	ISCSI_ERR_MAX_CMDSN                    = ISCSI_ERR_BASE + 3
	ISCSI_ERR_EXP_CMDSN                    = ISCSI_ERR_BASE + 4
	ISCSI_ERR_BAD_OPCODE                   = ISCSI_ERR_BASE + 5
	ISCSI_ERR_DATALEN                      = ISCSI_ERR_BASE + 6
	ISCSI_ERR_AHSLEN                       = ISCSI_ERR_BASE + 7
	ISCSI_ERR_PROTO                        = ISCSI_ERR_BASE + 8
	ISCSI_ERR_LUN                          = ISCSI_ERR_BASE + 9
	ISCSI_ERR_BAD_ITT                      = ISCSI_ERR_BASE + 10
	ISCSI_ERR_CONN_FAILED                  = ISCSI_ERR_BASE + 11
	ISCSI_ERR_R2TSN                        = ISCSI_ERR_BASE + 12
	ISCSI_ERR_SESSION_FAILED               = ISCSI_ERR_BASE + 13
	ISCSI_ERR_HDR_DGST                     = ISCSI_ERR_BASE + 14
	ISCSI_ERR_DATA_DGST                    = ISCSI_ERR_BASE + 15
	ISCSI_ERR_PARAM_NOT_FOUND              = ISCSI_ERR_BASE + 16
	ISCSI_ERR_NO_SCSI_CMD                  = ISCSI_ERR_BASE + 17
	ISCSI_ERR_INVALID_HOST                 = ISCSI_ERR_BASE + 18
	ISCSI_ERR_XMIT_FAILED                  = ISCSI_ERR_BASE + 19
	ISCSI_ERR_TCP_CONN_CLOSE               = ISCSI_ERR_BASE + 20
	ISCSI_ERR_SCSI_EH_SESSION_RST          = ISCSI_ERR_BASE + 21
	ISCSI_ERR_NOP_TIMEDOUT                 = ISCSI_ERR_BASE + 22
)

IscsiErr iscsi_if.h:enum iscsi_err

View Source
const STOP_CONN_RECOVER = 0x3

STOP_CONN_RECOVER - when stopping connection clean up I/O on that connection

Variables

This section is empty.

Functions

func FillNetlink(request *nl.NetlinkRequest, data ...interface{}) error

FillNetlink aids attaching binary data to netlink request

func MountIscsi

func MountIscsi(opts ...Option) (string, error)

MountIscsi connects to the given iscsi target and mounts it, returning the device name on success

func ReReadPartitionTable

func ReReadPartitionTable(devname string) error

ReReadPartitionTable opens the given file and reads partition table from it

func TearDownIscsi

func TearDownIscsi(sid uint32, cid uint32) error

TearDownIscsi tears down the specified session

Types

type IscsiErr

type IscsiErr uint32

IscsiErr iscsi_if.h:enum iscsi_err

func (IscsiErr) String

func (e IscsiErr) String() string

type IscsiEvent

type IscsiEvent uint32

IscsiEvent iscsi_if.h:enum iscsi_uevent_e

type IscsiIpcConn

type IscsiIpcConn struct {
	Conn            *nl.NetlinkSocket
	TransportHandle uint64
	// contains filtered or unexported fields
}

IscsiIpcConn is a single netlink connection

func ConnectNetlink() (*IscsiIpcConn, error)

ConnectNetlink connects to the iscsi netlink socket, and if successful returns an IscsiIpcConn ready to accept commands.

func (*IscsiIpcConn) BindConnection

func (c *IscsiIpcConn) BindConnection(sid uint32, cid uint32, fd int) error

BindConnection binds a TCP socket to the given kernel connection. fd must be the current program's fd for the TCP socket.

func (*IscsiIpcConn) CreateConnection

func (c *IscsiIpcConn) CreateConnection(sid uint32) (cid uint32, err error)

CreateConnection creates a new iSCSI connection for an existing session, returning the connection id on success

func (*IscsiIpcConn) CreateSession

func (c *IscsiIpcConn) CreateSession(cmdsMax uint16, queueDepth uint16) (sid uint32, hostID uint32, err error)

CreateSession creates a new kernel iSCSI session, returning the new iscsi_session id and scsi_host id

func (*IscsiIpcConn) DestroyConnection

func (c *IscsiIpcConn) DestroyConnection(sid uint32, cid uint32) error

DestroyConnection attempts to destroy the identified connection. May fail if connection is still running

func (*IscsiIpcConn) DestroySession

func (c *IscsiIpcConn) DestroySession(sid uint32) error

DestroySession attempts to destroy the identified session. May fail if connections are still active

func (c *IscsiIpcConn) DoNetlink(ueventP unsafe.Pointer, data ...interface{}) error

DoNetlink send netlink and listen to response ueventP *must* be a pointer to iSCSIUEvent

func (*IscsiIpcConn) RecvPDU

func (c *IscsiIpcConn) RecvPDU(sid uint32, cid uint32) ([]byte, error)

RecvPDU waits for a PDU for the given connection, and returns the raw PDU with header on success. RecvPDU assumes a single iSCSI connection, and will error if a different connection receives a PDU

func (*IscsiIpcConn) SendPDU

func (c *IscsiIpcConn) SendPDU(sid uint32, cid uint32, pdu PduLike) error

SendPDU sends the given PDU on the given connection

func (*IscsiIpcConn) SetParam

func (c *IscsiIpcConn) SetParam(sid uint32, cid uint32, param IscsiParam, value string) error

SetParam sets a single parameter for the given connection. value will be null terminated and must not contain null bytes

func (*IscsiIpcConn) StartConnection

func (c *IscsiIpcConn) StartConnection(sid uint32, cid uint32) error

StartConnection starts the given connection. The connection should be bound and logged in.

func (*IscsiIpcConn) StopConnection

func (c *IscsiIpcConn) StopConnection(sid uint32, cid uint32) error

StopConnection attempts to stop the identified connection.

func (*IscsiIpcConn) WaitFor

func (c *IscsiIpcConn) WaitFor(Type IscsiEvent) (*syscall.NetlinkMessage, error)

WaitFor reads ipcs until event of type Type is received, discarding others. (This presumes we're the only ones using netlink on this host, and we only have one outstanding request we're waiting for...)

type IscsiLoginPdu

type IscsiLoginPdu struct {
	Header       LoginHdr
	TextSegments bytes.Buffer
}

IscsiLoginPdu is an iSCSI Login Request PDU

func (*IscsiLoginPdu) AddParam

func (l *IscsiLoginPdu) AddParam(keyvalue string)

AddParam the key=value string to the login payload and adds null terminator

func (*IscsiLoginPdu) DataLen

func (l *IscsiLoginPdu) DataLen() uint32

DataLen gives the length of all data segements for this PDU

func (*IscsiLoginPdu) HeaderLen

func (l *IscsiLoginPdu) HeaderLen() uint32

HeaderLen gives the length of the PDU header

func (*IscsiLoginPdu) Serialize

func (l *IscsiLoginPdu) Serialize() []byte

Serialize to network order bytes

type IscsiLoginStage

type IscsiLoginStage uint8

IscsiLoginStage corresponds to iSCSI login stage

type IscsiOptions

type IscsiOptions struct {
	Address string
	Volume  string

	// See RFC7143 Section 13 for these.
	// Max data per single incoming iSCSI packet
	MaxRecvDLength int
	// Max data per single outgoing iSCSI packet
	MaxXmitDLength int
	// Max unsolicited data per iSCSI command sequence
	FirstBurstLength int
	// Max data per iSCSI command sequence
	MaxBurstLength int
	// CRC32C or None
	HeaderDigest string
	// CRC32C or None
	DataDigest string
	// Seconds to wait for heartbeat response before declaring the connection dead
	PingTimeout int32
	// Seconds to wait on an idle connection before sending a heartbeat
	RecvTimeout int32
	// Max iSCSI commands outstanding
	CmdsMax uint16
	// Max IOs outstanding
	QueueDepth uint16
	// Require initial Ready To Transfer (R2T) (false enables unsolicited data)
	InitialR2T bool
	// Enable iSCSI Immediate Data
	ImmediateData bool
	// Require iSCSI data sequence to be sent order by offset
	DataPDUInOrder bool
	// Require packets in an iSCSI data sequence to be sent in order by sequence number
	DataSequenceInOrder bool

	// Scheduler to configure for the blockdev
	Scheduler string
}

IscsiOptions configures iSCSI session.

type IscsiParam

type IscsiParam uint32

IscsiParam iscsi_if.h:enum iscsi_param

const (
	ISCSI_PARAM_MAX_RECV_DLENGTH IscsiParam = iota
	ISCSI_PARAM_MAX_XMIT_DLENGTH
	ISCSI_PARAM_HDRDGST_EN
	ISCSI_PARAM_DATADGST_EN
	ISCSI_PARAM_INITIAL_R2T_EN
	ISCSI_PARAM_MAX_R2T
	ISCSI_PARAM_IMM_DATA_EN
	ISCSI_PARAM_FIRST_BURST
	ISCSI_PARAM_MAX_BURST
	ISCSI_PARAM_PDU_INORDER_EN
	ISCSI_PARAM_DATASEQ_INORDER_EN
	ISCSI_PARAM_ERL
	ISCSI_PARAM_IFMARKER_EN
	ISCSI_PARAM_OFMARKER_EN
	ISCSI_PARAM_EXP_STATSN
	ISCSI_PARAM_TARGET_NAME
	ISCSI_PARAM_TPGT
	ISCSI_PARAM_PERSISTENT_ADDRESS
	ISCSI_PARAM_PERSISTENT_PORT
	ISCSI_PARAM_SESS_RECOVERY_TMO
	ISCSI_PARAM_CONN_PORT
	ISCSI_PARAM_CONN_ADDRESS
	ISCSI_PARAM_USERNAME
	ISCSI_PARAM_USERNAME_IN
	ISCSI_PARAM_PASSWORD
	ISCSI_PARAM_PASSWORD_IN
	ISCSI_PARAM_FAST_ABORT
	ISCSI_PARAM_ABORT_TMO
	ISCSI_PARAM_LU_RESET_TMO
	ISCSI_PARAM_HOST_RESET_TMO
	ISCSI_PARAM_PING_TMO
	ISCSI_PARAM_RECV_TMO
	ISCSI_PARAM_IFACE_NAME
	ISCSI_PARAM_ISID
	ISCSI_PARAM_INITIATOR_NAME
)

IscsiParams up until INITIATOR_NAME

type IscsiTargetSession

type IscsiTargetSession struct {
	// contains filtered or unexported fields
}

IscsiTargetSession represents an iSCSI session and a single connection to a target

func NewSession

func NewSession(netlink *IscsiIpcConn, opts ...Option) *IscsiTargetSession

NewSession constructs an IscsiTargetSession

func (*IscsiTargetSession) ConfigureBlockDev

func (s *IscsiTargetSession) ConfigureBlockDev() (string, error)

ConfigureBlockDev will set blockdev params for this iSCSI session, and returns blockdev name

func (*IscsiTargetSession) Connect

func (s *IscsiTargetSession) Connect() error

Connect creates a kernel iSCSI session and connection, connects to the target, and binds the connection to the kernel session.

func (*IscsiTargetSession) Login

func (s *IscsiTargetSession) Login(hostname string) error

Login - RFC iSCSI login https://www.ietf.org/rfc/rfc3720.txt For now "negotiates" no auth security.

func (*IscsiTargetSession) ReScan

func (s *IscsiTargetSession) ReScan() error

ReScan triggers a scsi host scan so the kernel creates a block device for the newly attached session, then waits for the block device to be created

func (*IscsiTargetSession) SetParams

func (s *IscsiTargetSession) SetParams() error

SetParams sets some desired parameters for the kernel session

func (*IscsiTargetSession) Start

func (s *IscsiTargetSession) Start() error

Start starts the kernel iSCSI session. Call this after successfully logging in and setting all desired parameters.

func (*IscsiTargetSession) TearDown

func (s *IscsiTargetSession) TearDown() error

TearDown stops and destroys the connection & session in case of partially created session, stopping connections/destroying connections won't work, so try it all

type LoginHdr

type LoginHdr struct {
	Opcode     uint8
	Flags      uint8
	MaxVersion uint8
	MinVersion uint8
	HLength    uint8
	DLength    [3]uint8
	Isid       [6]uint8
	Tsih       uint16
	Itt        uint32
	Cid        uint16
	Rsvd3      uint16
	CmdSN      uint32
	ExpStatSN  uint32
	Rsvd5      [16]uint8
}

LoginHdr is the header for ISCSI_OP_LOGIN See: RFC3720 10.12.

type LoginRspHdr

type LoginRspHdr struct {
	Opcode        uint8
	Flags         uint8
	MaxVersion    uint8
	ActiveVersion uint8
	HLength       uint8
	DLength       [3]uint8
	Isid          [6]uint8
	Tsih          uint16
	Itt           uint32
	Rsvd3         uint32
	StatSN        uint32
	ExpCmdSN      uint32
	MaxCmdSN      uint32
	StatusClass   uint8
	StatusDetail  uint8
	Rsvd5         [10]uint8
}

LoginRspHdr is the header for ISCSI_OP_LOGIN_RSP See: RFC3720 10.13.

type Option

type Option func(i *IscsiOptions)

Option is a functional API for setting optional configuration.

func WithCmdsMax

func WithCmdsMax(n uint16) Option

WithCmdsMax sets the maximum number of outstanding iSCSI commands.

func WithQueueDepth

func WithQueueDepth(n uint16) Option

WithQueueDepth sets the maximum number of outstanding IOs.

func WithScheduler

func WithScheduler(sched string) Option

WithScheduler sets the block device scheduler.

func WithTarget

func WithTarget(addr, volume string) Option

WithTarget adds the target address and volume to the config.

type PduLike

type PduLike interface {
	// Length of the PDU header (iscsi_hdr/etc.)
	HeaderLen() uint32
	// Length of the PDU data
	DataLen() uint32
	// Header + Data
	Serialize() []byte
}

PduLike interface for sending PDUs

Directories

Path Synopsis
cmd

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL