From 9bc9efb925e1c37a4a79b4e5aead530ba8c23193 Mon Sep 17 00:00:00 2001 From: ntap-arorar <49132604+ntap-arorar@users.noreply.github.com> Date: Thu, 16 Jul 2020 12:56:47 -0400 Subject: [PATCH] Add waitForDevice call before calling the blkid This PR addresses the issue of `blkid` being called in the event of device unavailability, as a result `blkid could throw exit status 2 error. Exit status 2 can be a result of an unformatted device or specified token not found. So, with the addition of `waitForDevice` call before calling the `blkid` would ensure the device availability when the `blkid` is called. Also as part of this PR, we are not allowing `fstype` discovery for the raw block volumes and would throw an error if any error other than exit status 2 is identified as a result of the `blkid` call. --- utils/osutils.go | 39 +++++++++++++++++++++++++++++---------- 1 file changed, 29 insertions(+), 10 deletions(-) diff --git a/utils/osutils.go b/utils/osutils.go index 882b8530e..2f3d04561 100644 --- a/utils/osutils.go +++ b/utils/osutils.go @@ -160,8 +160,10 @@ func AttachISCSIVolume(name, mountpoint string, publishInfo *VolumePublishInfo) return err } - // Lookup all the SCSI device information - deviceInfo, err := getDeviceInfoForLUN(lunID, targetIQN, true) + // Lookup all the SCSI device information, and include filesystem type only if not raw block volume + needFSType := fstype != fsRaw + + deviceInfo, err := getDeviceInfoForLUN(lunID, targetIQN, needFSType) if err != nil { return fmt.Errorf("error getting iSCSI device information: %v", err) } else if deviceInfo == nil { @@ -624,11 +626,14 @@ func getDeviceInfoForLUN(lunID int, iSCSINodeName string, needFSType bool) (*Scs fsType := "" if needFSType { + var devicePath string if multipathDevice != "" { - fsType, err = getFSType("/dev/" + multipathDevice) + devicePath = "/dev/" + multipathDevice } else { - fsType, err = getFSType("/dev/" + devices[0]) + devicePath = "/dev/" + devices[0] } + + fsType, err = getFSType(devicePath) if err != nil { return nil, err } @@ -1976,19 +1981,33 @@ func getFSType(device string) (string, error) { log.WithField("device", device).Debug(">>>> osutils.getFSType") defer log.Debug("<<<< osutils.getFSType") - fsType := "" + // blkid return status=2 both in case of an unformatted filesystem as well as for the case when it is + // unable to get the filesystem (e.g. IO error), therefore ensure device is available before calling blkid + if err := waitForDevice(device); err != nil { + return "", fmt.Errorf("could not find device before checking for the filesystem %v; %s", device, err) + } + out, err := execCommandWithTimeout("blkid", 5, device) if err != nil { if IsTimeoutError(err) { listAllISCSIDevices() - return fsType, err - } else { - // Do not fail when running fsType on a raw block device - log.WithField("device", device).Debug("Could not get FSType for device.") - return fsType, nil + return "", err + } else if exitErr, ok := err.(*exec.ExitError); ok && exitErr.ExitCode() == 2 { + // EITHER: Disk device is unformatted. + // OR: For 'blkid', if the specified token (TYPE/PTTYPE, etc) was + // not found, or no (specified) devices could be identified, an + // exit code of 2 is returned. + + log.WithField("device", device).Infof("Could not get FSType for device; err: %v", err) + return "", nil } + + log.WithField("device", device).Errorf("could not determine FSType for device; err: %v", err) + return "", err } + var fsType string + if strings.Contains(string(out), "TYPE=") { for _, v := range strings.Split(string(out), " ") { if strings.Contains(v, "TYPE=") {