Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Re-read partition table for powerpath before resize #20

Merged
merged 1 commit into from
Aug 26, 2022
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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