forked from hpe-storage/common-host-libs
-
Notifications
You must be signed in to change notification settings - Fork 0
/
iscsi.go
142 lines (117 loc) · 4.97 KB
/
iscsi.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
// (c) Copyright 2019 Hewlett Packard Enterprise Development LP
package iscsi
import (
"github.com/hpe-storage/common-host-libs/chapi2/cerrors"
"github.com/hpe-storage/common-host-libs/chapi2/model"
log "github.com/hpe-storage/common-host-libs/logger"
)
const (
nimbleVendorProduct = "Nimble Server " // Nimble Server Vendor ID / Product ID
nimbleTargetScopeOffset = 0x2E // Offset in Inquiry page where target scope is stored
loginTimeout = 5 * 60 // Host has up to 5 minutes to make optimal iSCSI connections
)
const (
// Shared error messages
errorMessageConnectionFailed = "connection failed"
errorMessageEmptyIqnFound = "empty iqn found"
errorMessageFailedInquiry = "failed Inquiry with scsiStatus=%v, len(inquiryBuffer)=%v"
errorMessageInvalidConnectionType = `invalid connection type "%v"`
errorMessageInvalidTargetScope = "invalid target scope %v"
errorMessageIscsiPathNotFound = "%s not found to determine iscsi initiator name"
errorMessageLoginTimeout = "logins not completed in time"
errorMessageMissingIscsiAccessInfo = "missing IscsiAccessInfo object"
errorMessageMissingIscsiTargetName = "missing iscsi target name"
errorMessageNoAvailableConnections = "no available connections"
errorMessageNoActiveConnections = "no active connections on sessionId %x-%x"
errorMessageNoTargetScope = "no sessions could report the target scope"
errorMessageNonNimbleTarget = "non-Nimble target %v"
errorMessageTargetNotFound = "target not found"
)
// ITNexus - Initiator Port and Target Port
type ITNexus struct {
initiatorPort *model.Network
targetPort *model.TargetPortal
}
type IscsiPlugin struct {
}
func NewIscsiPlugin() *IscsiPlugin {
return &IscsiPlugin{}
}
func (plugin *IscsiPlugin) GetDiscoveredTargets() ([]*model.IscsiTarget, error) {
// TODO
return nil, nil
}
func (plugin *IscsiPlugin) GetAllLoggedInTargets() ([]*model.IscsiTarget, error) {
// TODO
return nil, nil
}
func (plugin *IscsiPlugin) GetTargetPortals(targetName string, ipv4Only bool) ([]*model.TargetPortal, error) {
log.Tracef(">>>>> GetTargetPortals, targetName=%v, ipv4Only=%v", targetName, ipv4Only)
defer log.Traceln("<<<<< GetTargetPortals")
return plugin.getTargetPortals(targetName, ipv4Only)
}
func (plugin *IscsiPlugin) GetSessionProperties(targetName string, sessionId string) (map[string]string, error) {
// TODO
return nil, nil
}
func (plugin *IscsiPlugin) DiscoverTargets(portal string) ([]*model.IscsiTarget, error) {
// TODO
return nil, nil
}
// LoginTarget ensures that the provided iSCSI device is logged into this host
func (plugin *IscsiPlugin) LoginTarget(blockDev model.BlockDeviceAccessInfo) (err error) {
log.Tracef(">>>>> LoginTarget, TargetName=%v", blockDev.TargetName)
defer log.Traceln("<<<<< LoginTarget")
// If the iSCSI iqn is not provided, fail the request
if blockDev.TargetName == "" {
err := cerrors.NewChapiError(cerrors.InvalidArgument, errorMessageMissingIscsiTargetName)
log.Error(err)
return err
}
// If the IscsiAccessInfo object is not provided, fail the request
if blockDev.IscsiAccessInfo == nil {
err := cerrors.NewChapiError(cerrors.InvalidArgument, errorMessageMissingIscsiAccessInfo)
log.Error(err)
return err
}
// Use the platform specific routine to login to the iSCSI target
err = plugin.loginTarget(blockDev)
// If there was an error logging into the iSCSI target, but connections remain, clean up
// after ourselves by logging out the target.
if err != nil {
if loggedIn, _ := plugin.IsTargetLoggedIn(blockDev.TargetName); loggedIn == true {
plugin.LogoutTarget(blockDev.TargetName)
}
return err
}
// Success!!!
return nil
}
// IsTargetLoggedIn checks to see if the given iSCSI target is already logged in
func (plugin *IscsiPlugin) IsTargetLoggedIn(targetName string) (bool, error) {
log.Tracef(">>>>> IsTargetLoggedIn, targetName=%v", targetName)
defer log.Traceln("<<<<< IsTargetLoggedIn")
// Call platform specific module
return plugin.isTargetLoggedIn(targetName)
}
// LogoutTarget logs out the given iSCSI target
func (plugin *IscsiPlugin) LogoutTarget(targetName string) error {
log.Tracef(">>>>> LogoutTarget, TargetName=%v", targetName)
defer log.Traceln("<<<<< LogoutTarget")
// Call platform specific module
return plugin.logoutTarget(targetName)
}
// GetIscsiInitiators returns the host's iSCSI initiator object
func (plugin *IscsiPlugin) GetIscsiInitiators() (*model.Initiator, error) {
return getIscsiInitiators()
}
// GetTargetScope returns the target's scope if known ("volume", "group", or empty string)
func (plugin *IscsiPlugin) GetTargetScope(targetName string) (string, error) {
return getTargetScope(targetName)
}
// RescanIscsiTarget rescans host ports for iSCSI devices
func (plugin *IscsiPlugin) RescanIscsiTarget(lunID string) error {
log.Tracef(">>>>> RescanIscsiTarget initiated for lunID %v", lunID)
defer log.Traceln("<<<<< RescanIscsiTarget")
return rescanIscsiTarget(lunID)
}