Skip to content

Commit bddc22f

Browse files
authored
Merge pull request #7 from Seagate/fix/multipath
fix: refresh dm paths, increase attempts, 10s delay plus debug
2 parents 61c966f + 4fb6a1f commit bddc22f

File tree

2 files changed

+50
-30
lines changed

2 files changed

+50
-30
lines changed

iscsi/iscsi.go

Lines changed: 43 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,11 @@ import (
1616
"time"
1717
)
1818

19-
const defaultPort = "3260"
19+
const (
20+
defaultPort = "3260"
21+
maxMultipathAttempts = 10
22+
multipathDelay = 10
23+
)
2024

2125
var (
2226
debug *log.Logger
@@ -158,7 +162,7 @@ func waitForPathToExistImpl(devicePath *string, maxRetries, intervalSeconds int,
158162
err = nil
159163
if deviceTransport == "tcp" {
160164
_, err = osStat(*devicePath)
161-
debug.Printf("os stat device: exist %v device %v", !os.IsNotExist(err), *devicePath)
165+
debug.Printf("[%d] os stat device: exist %v device %v", i, !os.IsNotExist(err), *devicePath)
162166
if err != nil && !os.IsNotExist(err) {
163167
debug.Printf("Error attempting to stat device: %s", err.Error())
164168
return false, err
@@ -167,7 +171,7 @@ func waitForPathToExistImpl(devicePath *string, maxRetries, intervalSeconds int,
167171
}
168172

169173
} else {
170-
debug.Printf("filepathGlob: %s", *devicePath)
174+
debug.Printf("[%d] filepathGlob: %s", i, *devicePath)
171175
fpath, _ := filepathGlob(*devicePath)
172176
if fpath == nil {
173177
err = os.ErrNotExist
@@ -187,6 +191,7 @@ func waitForPathToExistImpl(devicePath *string, maxRetries, intervalSeconds int,
187191
}
188192
time.Sleep(time.Second * time.Duration(intervalSeconds))
189193
}
194+
debug.Printf("device does NOT exist [%d*%ds] (%v)", maxRetries, intervalSeconds, *devicePath)
190195
return false, err
191196
}
192197

@@ -211,37 +216,42 @@ func getMultipathDisk(path string) (string, error) {
211216
// check to see if any have an entry under /sys/block/dm-*/slaves matching
212217
// the device the symlink was pointing at
213218
attempts := 1
214-
dmPaths, err := filepath.Glob("/sys/block/dm-*")
215-
for attempts < 4 {
216-
debug.Printf("[%d] dmPaths=%v", attempts, dmPaths)
217-
if err != nil {
218-
debug.Printf("Glob error: %s", err)
219-
return "", err
220-
}
221-
if len(dmPaths) > 0 {
222-
break
223-
}
224-
time.Sleep(1 * time.Second)
225-
attempts++
219+
var dmPaths []string
220+
221+
for attempts < (maxMultipathAttempts + 1) {
222+
var err error
226223
dmPaths, err = filepath.Glob("/sys/block/dm-*")
227-
}
228-
for _, dmPath := range dmPaths {
229-
sdevices, err := filepath.Glob(filepath.Join(dmPath, "slaves", "*"))
230-
debug.Printf("dmPath=%v/slaves/*, sdevices=%v", dmPath, sdevices)
224+
debug.Printf("[%d] refresh dmPaths [%d] %v", attempts, len(dmPaths), dmPaths)
231225
if err != nil {
232226
debug.Printf("Glob error: %s", err)
227+
return "", err
233228
}
234-
for _, spath := range sdevices {
235-
s := filepath.Base(spath)
236-
debug.Printf("Basepath: %s", s)
237-
if sdevice == s {
238-
// We've found a matching entry, return the path for the
239-
// dm-* device it was found under
240-
p := filepath.Join("/dev", filepath.Base(dmPath))
241-
debug.Printf("Found matching multipath device (%s) under dm-* device path (%s), (%v)", sdevice, dmPath, p)
242-
return p, nil
229+
230+
for _, dmPath := range dmPaths {
231+
sdevices, err := filepath.Glob(filepath.Join(dmPath, "slaves", "*"))
232+
// debug.Printf(".. dmPath=%v, sdevices=[%d]%v", dmPath, len(sdevices), sdevices)
233+
if err != nil {
234+
debug.Printf("Glob error: %s", err)
235+
}
236+
for _, spath := range sdevices {
237+
s := filepath.Base(spath)
238+
// debug.Printf(".. Basepath: %s", s)
239+
if sdevice == s {
240+
// We've found a matching entry, return the path for the
241+
// dm-* device it was found under
242+
p := filepath.Join("/dev", filepath.Base(dmPath))
243+
debug.Printf("Found matching multipath device (%s) under dm-* device path (%s) p (%v)", sdevice, dmPath, p)
244+
return p, nil
245+
}
243246
}
244247
}
248+
249+
// Force a reload of all existing multipath maps
250+
output, err := execCommand("multipath", "-r").CombinedOutput()
251+
debug.Printf("## multipath -r: output=%v, err=%v", output, err)
252+
253+
time.Sleep(multipathDelay * time.Second)
254+
attempts++
245255
}
246256
debug.Printf("Couldn't find dm-* path for path: %s, found non dm-* path: %s", path, devicePath)
247257
return "", fmt.Errorf("couldn't find dm-* path for path: %s, found non dm-* path: %s", path, devicePath)
@@ -350,7 +360,7 @@ func Connect(c *Connector) (string, error) {
350360
}
351361

352362
if lastErr != nil {
353-
debug.Printf("Last error occured during iscsi init: \n%v", lastErr)
363+
debug.Printf("Last error occurred during iscsi init: \n%v", lastErr)
354364
}
355365

356366
for i, path := range devicePaths {
@@ -465,11 +475,14 @@ func PersistConnector(c *Connector, filePath string) error {
465475
//file := path.Join("mnt", c.VolumeName+".json")
466476
f, err := os.Create(filePath)
467477
if err != nil {
478+
debug.Printf("ERROR: creating iscsi persistence file %s: %s\n", filePath, err)
468479
return fmt.Errorf("error creating iscsi persistence file %s: %s", filePath, err)
469480
}
470481
defer f.Close()
471482
encoder := json.NewEncoder(f)
483+
debug.Printf("ConnectorFromFile (write): file=%v, c=%+v\n", filePath, c)
472484
if err = encoder.Encode(c); err != nil {
485+
debug.Printf("ERROR: error encoding connector: %v\n", err)
473486
return fmt.Errorf("error encoding connector: %v", err)
474487
}
475488
return nil
@@ -490,7 +503,7 @@ func GetConnectorFromFile(filePath string) (*Connector, error) {
490503
return &Connector{}, err
491504
}
492505

493-
debug.Printf("data: %+v\n", data)
506+
debug.Printf("ConnectorFromFile (read): file=%s, %+v\n", filePath, data)
494507

495508
return &data, nil
496509

iscsi/multipath.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,14 +108,21 @@ func RemoveAndClear(device string) error {
108108
debug.Printf("Remove and clear multipath device (%s)\n", device)
109109

110110
// Remove device-mapper logical device
111+
debug.Printf("dmsetup remove -f %s\n", device)
111112
if output, err := execCommand("dmsetup", "remove", "-f", device).CombinedOutput(); err != nil {
113+
exitErr, ok := err.(*exec.ExitError)
114+
if ok && exitErr.ExitCode() != 0 {
115+
debug.Printf("ERROR: dmsetup remove -f ExitCode: %d, err=%v\n", exitErr.ExitCode(), err)
116+
}
117+
112118
return fmt.Errorf("device-mapper could not remove device: %s (%v)", output, err)
113119
}
114120

115121
// Clear out device-mapper logical device if it still exists
116122
if _, e := os.Stat(device); os.IsNotExist(e) {
117123
debug.Printf("device-mapper logical device %q was removed\n", device)
118124
} else {
125+
debug.Printf("dmsetup clear %s\n", device)
119126
if output, err := execCommand("dmsetup", "clear", device).CombinedOutput(); err != nil {
120127
return fmt.Errorf("device-mapper could not clear device: %s (%v)", output, err)
121128
}

0 commit comments

Comments
 (0)