From 5acc5c525b027416dd2c3e8b734f8bc539280781 Mon Sep 17 00:00:00 2001 From: Kenjiro Nakayama Date: Sat, 3 Dec 2016 20:35:23 +0900 Subject: [PATCH 1/3] Return device with error --- device.go | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/device.go b/device.go index ad66e4f..909e639 100644 --- a/device.go +++ b/device.go @@ -63,15 +63,11 @@ func OpenTCMUDevice(devPath string, scsi *SCSIHandler) (*Device, error) { uioFd: -1, hbaDir: fmt.Sprintf(configDirFmt, scsi.HBA), } - err := d.Close() - if err != nil { - return nil, err - } if err := d.preEnableTcmu(); err != nil { - return nil, err + return d, err } if err := d.start(); err != nil { - return nil, err + return d, err } return d, d.postEnableTcmu() @@ -340,7 +336,7 @@ func (d *Device) teardown() error { for _, p := range pathsToRemove { err := remove(p) if err != nil { - return err + logrus.Errorf("Failed to remove: %v", err) } } From 3e3e0807d76bcc90b43158754af3c309cf21083a Mon Sep 17 00:00:00 2001 From: Kenjiro Nakayama Date: Sat, 3 Dec 2016 21:25:39 +0900 Subject: [PATCH 2/3] Introduce toClean map for removing only created device or directories --- device.go | 29 ++++++++++++++++++++++------- 1 file changed, 22 insertions(+), 7 deletions(-) diff --git a/device.go b/device.go index 909e639..b0c9907 100644 --- a/device.go +++ b/device.go @@ -24,6 +24,8 @@ const ( scsiDir = "/sys/kernel/config/target/loopback" ) +var toClean map[string]bool + type Device struct { scsi *SCSIHandler devPath string @@ -57,6 +59,7 @@ func (d *Device) Sizes() DataSizes { // OpenTCMUDevice creates the virtual device based on the details in the SCSIHandler, eventually creating a device under devPath (eg, "/dev") with the file name scsi.VolumeName. // The returned Device represents the open device connection to the kernel, and must be closed. func OpenTCMUDevice(devPath string, scsi *SCSIHandler) (*Device, error) { + toClean = make(map[string]bool) d := &Device{ scsi: scsi, devPath: devPath, @@ -122,24 +125,31 @@ func (d *Device) postEnableTcmu() error { logrus.Debugf("Creating directory: %s", lunPath) if err := os.MkdirAll(lunPath, 0755); err != nil && !os.IsExist(err) { return err + } else if err == nil { + toClean[lunPath] = true + toClean[path.Join(lunPath, d.scsi.VolumeName)] = true } logrus.Debugf("Linking: %s => %s", path.Join(lunPath, d.scsi.VolumeName), path.Join(d.hbaDir, d.scsi.VolumeName)) if err := os.Symlink(path.Join(d.hbaDir, d.scsi.VolumeName), path.Join(lunPath, d.scsi.VolumeName)); err != nil { return err } + toClean[path.Join(d.hbaDir, d.scsi.VolumeName)] = true return d.createDevEntry() } func (d *Device) createDevEntry() error { - os.MkdirAll(d.devPath, 0755) + if err := os.MkdirAll(d.devPath, 0755); err != nil && !os.IsExist(err) { + return err + } dev := filepath.Join(d.devPath, d.scsi.VolumeName) if _, err := os.Stat(dev); err == nil { return fmt.Errorf("Device %s already exists, can not create", dev) } + toClean[dev] = true tgt, _ := d.getSCSIPrefixAndWnn() @@ -213,6 +223,7 @@ func writeLines(target string, lines []string) error { if err := os.MkdirAll(dir, 0755); err != nil { return err } + toClean[dir] = true } else if !stat.IsDir() { return fmt.Errorf("%s is not a directory", dir) } @@ -334,17 +345,21 @@ func (d *Device) teardown() error { } for _, p := range pathsToRemove { - err := remove(p) - if err != nil { - logrus.Errorf("Failed to remove: %v", err) + if k, _ := toClean[p]; k { + err := remove(p) + if err != nil { + logrus.Errorf("Failed to remove: %v", err) + } } } // Should be cleaned up automatically, but if it isn't remove it if _, err := os.Stat(dev); err == nil { - err := remove(dev) - if err != nil { - return err + if k, _ := toClean[dev]; k { + err := remove(dev) + if err != nil { + return err + } } } From dc4ffba0190e46c22c856cff4928a14ffb28bee1 Mon Sep 17 00:00:00 2001 From: Kenjiro Nakayama Date: Sun, 4 Dec 2016 18:20:12 +0900 Subject: [PATCH 3/3] Move toClean map to device struct field --- device.go | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/device.go b/device.go index b0c9907..232a654 100644 --- a/device.go +++ b/device.go @@ -24,8 +24,6 @@ const ( scsiDir = "/sys/kernel/config/target/loopback" ) -var toClean map[string]bool - type Device struct { scsi *SCSIHandler devPath string @@ -39,6 +37,8 @@ type Device struct { cmdChan chan *SCSICmd respChan chan SCSIResponse cmdTail uint32 + + toClean map[string]bool } // WWN provides two WWNs, one for the device itself and one for the loopback @@ -59,12 +59,12 @@ func (d *Device) Sizes() DataSizes { // OpenTCMUDevice creates the virtual device based on the details in the SCSIHandler, eventually creating a device under devPath (eg, "/dev") with the file name scsi.VolumeName. // The returned Device represents the open device connection to the kernel, and must be closed. func OpenTCMUDevice(devPath string, scsi *SCSIHandler) (*Device, error) { - toClean = make(map[string]bool) d := &Device{ scsi: scsi, devPath: devPath, uioFd: -1, hbaDir: fmt.Sprintf(configDirFmt, scsi.HBA), + toClean: make(map[string]bool), } if err := d.preEnableTcmu(); err != nil { return d, err @@ -88,7 +88,7 @@ func (d *Device) Close() error { } func (d *Device) preEnableTcmu() error { - err := writeLines(path.Join(d.hbaDir, d.scsi.VolumeName, "control"), []string{ + err := d.writeLines(path.Join(d.hbaDir, d.scsi.VolumeName, "control"), []string{ fmt.Sprintf("dev_size=%d", d.scsi.DataSizes.VolumeSize), fmt.Sprintf("dev_config=%s", d.GetDevConfig()), fmt.Sprintf("hw_block_size=%d", d.scsi.DataSizes.BlockSize), @@ -98,7 +98,7 @@ func (d *Device) preEnableTcmu() error { return err } - return writeLines(path.Join(d.hbaDir, d.scsi.VolumeName, "enable"), []string{ + return d.writeLines(path.Join(d.hbaDir, d.scsi.VolumeName, "enable"), []string{ "1", }) } @@ -114,7 +114,7 @@ func (d *Device) getLunPath(prefix string) string { func (d *Device) postEnableTcmu() error { prefix, nexusWnn := d.getSCSIPrefixAndWnn() - err := writeLines(path.Join(prefix, "nexus"), []string{ + err := d.writeLines(path.Join(prefix, "nexus"), []string{ nexusWnn, }) if err != nil { @@ -126,15 +126,15 @@ func (d *Device) postEnableTcmu() error { if err := os.MkdirAll(lunPath, 0755); err != nil && !os.IsExist(err) { return err } else if err == nil { - toClean[lunPath] = true - toClean[path.Join(lunPath, d.scsi.VolumeName)] = true + d.toClean[lunPath] = true + d.toClean[path.Join(lunPath, d.scsi.VolumeName)] = true } logrus.Debugf("Linking: %s => %s", path.Join(lunPath, d.scsi.VolumeName), path.Join(d.hbaDir, d.scsi.VolumeName)) if err := os.Symlink(path.Join(d.hbaDir, d.scsi.VolumeName), path.Join(lunPath, d.scsi.VolumeName)); err != nil { return err } - toClean[path.Join(d.hbaDir, d.scsi.VolumeName)] = true + d.toClean[path.Join(d.hbaDir, d.scsi.VolumeName)] = true return d.createDevEntry() } @@ -149,7 +149,7 @@ func (d *Device) createDevEntry() error { if _, err := os.Stat(dev); err == nil { return fmt.Errorf("Device %s already exists, can not create", dev) } - toClean[dev] = true + d.toClean[dev] = true tgt, _ := d.getSCSIPrefixAndWnn() @@ -216,14 +216,14 @@ func mknod(device string, major, minor int) error { return syscall.Mknod(device, uint32(fileMode), dev) } -func writeLines(target string, lines []string) error { +func (d *Device) writeLines(target string, lines []string) error { dir := path.Dir(target) if stat, err := os.Stat(dir); os.IsNotExist(err) { logrus.Debugf("Creating directory: %s", dir) if err := os.MkdirAll(dir, 0755); err != nil { return err } - toClean[dir] = true + d.toClean[dir] = true } else if !stat.IsDir() { return fmt.Errorf("%s is not a directory", dir) } @@ -345,7 +345,7 @@ func (d *Device) teardown() error { } for _, p := range pathsToRemove { - if k, _ := toClean[p]; k { + if k, _ := d.toClean[p]; k { err := remove(p) if err != nil { logrus.Errorf("Failed to remove: %v", err) @@ -355,7 +355,7 @@ func (d *Device) teardown() error { // Should be cleaned up automatically, but if it isn't remove it if _, err := os.Stat(dev); err == nil { - if k, _ := toClean[dev]; k { + if k, _ := d.toClean[dev]; k { err := remove(dev) if err != nil { return err