Skip to content

Commit

Permalink
Merge pull request #20 from dell/bug-445-expandPowepathFS
Browse files Browse the repository at this point in the history
Re-read partition table for powerpath before resize
  • Loading branch information
boyamurthy authored Aug 26, 2022
2 parents dde6dd5 + df34843 commit 7e76776
Showing 1 changed file with 57 additions and 27 deletions.
84 changes: 57 additions & 27 deletions gofsutil_mount_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ const (
// procMountsRetries is number of times to retry for a consistent
// read of procMountsPath.
procMountsRetries = 30
powerpathtool = "powermt"
ppinqtool = "pp_inq"
)

var (
Expand Down Expand Up @@ -340,33 +340,44 @@ func (fs *FS) getNativeDevicesFromPpath(
ctx context.Context, ppath string) ([]string, error) {
log.Infof("powerpath - trying to find native devices for ppath: %s", ppath)
var devices []string
deviceName := fmt.Sprintf("dev=%s", ppath)
cmd := fmt.Sprintf("%s/%s", "/noderoot/usr/sbin", powerpathtool)
log.Debug("*** cmd:", cmd)
out, err := exec.Command(cmd, "display", deviceName).CombinedOutput()
var deviceWWN string

deviceName := fmt.Sprintf("/dev/%s", ppath)
cmd := fmt.Sprintf("%s/%s", "/noderoot/sbin", ppinqtool)
log.Debug("pp_inq cmd:", cmd)
args := []string{"-wwn", "-dev", deviceName}
out, err := exec.Command(cmd, args...).CombinedOutput()
if err != nil {
log.Errorf("Error powermt display %s: %v", deviceName, err)
return devices, err
}
op := strings.Split(string(out), "\n")
fmt.Printf("lines %+v \n", op)
/* Output for powermt display dev=ppath
L#0 Pseudo name=emcpowerc
L#1 Symmetrix ID=000197901586
L#10 ...
==============================================================================
3 lpfc sdbb FA 2d:04 active alive 0 0
3 lpfc sdba FA 1d:04 active alive 0 0
fmt.Printf("pp_inq output for %s %+v \n", ppath, op)
/* Output for pp_inq -wwn -dev /dev/ppath
L#1 Inquiry utility, Version V9.2-2602 (Rev 0.0)
----------------------------------------------------------------------------
DEVICE :VEND :PROD :WWN
----------------------------------------------------------------------------
L#7 /dev/emcpowerg :EMC :SYMMETRIX :60000970000120000549533030354435
*/
for _, line := range op {
if strings.Contains(line, "sd") {
if strings.Contains(line, "emcpower") {
tokens := strings.Fields(line)
devices = append(devices, tokens[2])
deviceWWN = strings.Replace(tokens[3], ":", "", 1)
log.Debugf("found device wwn %s", deviceWWN)
break
}
}
devices, err = GetSysBlockDevicesForVolumeWWN(ctx, deviceWWN)
if err != nil {
return nil, err
}
log.Debugf("found devices: %+v for ppath %s with WWN %s", devices, ppath, deviceWWN)
return devices, nil
}

// getMountInfoFromDevice gets mount info for the given device
// It first checks the existence of powerpath device, if not then checks for multipath, if not then checks for single device.
func (fs *FS) getMountInfoFromDevice(
ctx context.Context, devID string) (*DeviceMountInfo, error) {

Expand All @@ -381,49 +392,49 @@ func (fs *FS) getMountInfoFromDevice(
if err != nil {
return nil, err
}
log.Infof("device ID from getMountInfoFromDevice is %s", devID)
//check if devID has powerpath devices
/* #nosec G204 */
checkCmd := "lsblk -P | awk '/emcpower.+" + devID + "/ {print $0}'"
log.Infof("checkcommand values is %s", checkCmd)
log.Debugf("ppath checkcommand values is %s", checkCmd)
/* #nosec G204 */
buf, err := exec.Command("bash", "-c", checkCmd).Output()
if err != nil {
return nil, err
}
output = string(buf)
log.Infof("powerpath exec command output is : %+v", output)
if output == "" {
// output is nil, powerpath device not found, continuing for multipath or single device
log.Info("powerpath command output is nil, continuing for multipath or single device")
/* #nosec G204 */
checkCmd = "lsblk -P | awk '/mpath.+" + devID + "/ {print $0}'"
log.Infof("checkcommand values is %s", checkCmd)
log.Debugf("mpath checkcommand values is %s", checkCmd)

/* #nosec G204 */
buf, err = exec.Command("bash", "-c", checkCmd).Output()
if err != nil {
return nil, err
}
log.Infof("multipath exec command output is : %+v", buf)

output := string(buf)
fmt.Println("Check: " + checkCmd)
output = string(buf)
log.Debugf("multipath exec command output is : %+v", output)
if output != "" {
if lsblkNew {
cmd = "lsblk -Px MODE | awk '/" + devID + "/{if (a && a !~ /" + devID + "/) print a; print} {a=$0}'"
} else {
cmd = "lsblk -P | awk '/" + devID + "/{if (a && a !~ /" + devID + "/) print a; print} {a=$0}'"
}
} else {
// multipath device not found, continue as single device
/* #nosec G204 */
cmd = "lsblk -P | awk '/" + devID + "/ {print $0}'"
}
log.Infof("command output is %s", cmd)
fmt.Println(cmd)
log.Debugf("command value is %s", cmd)
/* #nosec G204 */
buf, err = exec.Command("bash", "-c", cmd).Output()
if err != nil {
return nil, err
}
output = string(buf)
log.Debugf("command output is : %+v", output)
}
if output == "" {
return nil, fmt.Errorf("Device not found")
Expand All @@ -442,14 +453,14 @@ func (fs *FS) getMountInfoFromDevice(
ppath := ppathDeviceRegx.FindString(output)
mountInfo := new(DeviceMountInfo)
mountInfo.MountPoint = strings.Split(mountPoint, "\"")[1]
log.Infof("ppath values is %s", ppath)
for _, device := range devices {
mountInfo.DeviceNames = append(mountInfo.DeviceNames, strings.Split(device, "\"")[1])
}
for _, device := range nvmeDevices {
mountInfo.DeviceNames = append(mountInfo.DeviceNames, strings.Split(device, "\"")[1])
}
if ppath != "" {
log.Infof("found ppath: %s", ppath)
mountInfo.PPathName = strings.Split(ppath, "\"")[1]
// find native devices for given ppath
mountInfo.DeviceNames, err = fs.getNativeDevicesFromPpath(ctx, mountInfo.PPathName)
Expand Down Expand Up @@ -520,9 +531,13 @@ func (fs *FS) resizeMultipath(ctx context.Context, deviceName string) error {
func (fs *FS) resizeFS(
ctx context.Context, mountpoint,
devicePath, ppathDevice, mpathDevice, fsType string) error {

if ppathDevice != "" {
devicePath = "/dev/" + ppathDevice
mountpoint = devicePath
err := reReadPartitionTable(ctx, devicePath)
if err != nil {
return err
}
}

if mpathDevice != "" {
Expand All @@ -543,6 +558,21 @@ func (fs *FS) resizeFS(
return err
}

// reReadPartitionTable re-read the partition table of the pseudo device.
func reReadPartitionTable(ctx context.Context, devicePath string) error {
path := filepath.Clean(devicePath)
if err := validatePath(path); err != nil {
return fmt.Errorf("Failed to validate path: %s error %v", devicePath, err)
}
args := []string{"--rereadpt", path}
_, err := exec.Command("blockdev", args...).CombinedOutput()
if err != nil {
log.Errorf("Failed to execute blockdev on %s: %v", devicePath, err)
return err
}
return nil
}

func (fs *FS) expandExtFs(devicePath string) error {
path := filepath.Clean(devicePath)
if err := validatePath(path); err != nil {
Expand Down

0 comments on commit 7e76776

Please sign in to comment.