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

Updated DrvCfgQuerySystems to fetch systems using drv_cfg #89

Merged
merged 3 commits into from
Nov 17, 2023
Merged
Show file tree
Hide file tree
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
70 changes: 15 additions & 55 deletions drv_cfg.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ package goscaleio
import (
"fmt"
"os"
"os/exec"
"regexp"
"strconv"
"strings"
"syscall"
Expand All @@ -34,6 +36,7 @@ const (
IOCTLDevice = "/dev/scini"
mockGUID = "9E56672F-2F4B-4A42-BFF4-88B6846FBFDA"
mockSystem = "14dbbf5617523654"
drvCfg = "/opt/emc/scaleio/sdc/bin/drv_cfg"
)

var (
Expand Down Expand Up @@ -124,25 +127,6 @@ func DrvCfgQueryRescan() (string, error) {
return rcCode, err
}

// internal, opaque to us, struct of IP addresses
type netAddress struct {
opaque [24]byte
}

type ioctlMdmInfo struct {
filler [4]byte
mdmIDL uint32
mdmIDH uint32
sdcIDL uint32
sdcIDH uint32
installIDL uint32
installIDH uint32
/*Total amount of socket addresses*/
numSockAddrs uint64
/*The MDM socket addresses*/
addresses [16]netAddress
}

// ConfiguredCluster contains configuration information for one connected system
type ConfiguredCluster struct {
// SystemID is the MDM cluster system ID
Expand All @@ -151,15 +135,6 @@ type ConfiguredCluster struct {
SdcID string
}

type ioctlQueryMDMs struct {
rc [8]byte
numMdms uint16

filler [4]byte //uint32
/*Variable array of MDM. Its size is determined by numMdms*/
mdms [20]ioctlMdmInfo
}

// DrvCfgQuerySystems will return the configured MDM endpoints for the locally installed SDC
func DrvCfgQuerySystems() (*[]ConfiguredCluster, error) {
clusters := make([]ConfiguredCluster, 0)
Expand All @@ -175,38 +150,23 @@ func DrvCfgQuerySystems() (*[]ConfiguredCluster, error) {
return &clusters, nil
}

f, err := os.Open(SDCDevice)
cmd := exec.Command("chroot", "/noderoot", drvCfg, "--query_mdm")
output, err := cmd.CombinedOutput()
if err != nil {
return nil, err
return nil, fmt.Errorf("DrvCfgQuerySystems: Request to query MDM failed : %v", err)
}

defer func() {
_ = f.Close()
}()

opCode := _IO(_IOCTLBase, _IOCTLQueryMDM)

buf := ioctlQueryMDMs{}

buf.numMdms = uint16(len(buf.mdms))

// #nosec CWE-242, validated buffer is large enough to hold data
err = ioctl(f.Fd(), opCode, uintptr(unsafe.Pointer(&buf)))

if err != nil {
return nil, fmt.Errorf("queryMDM error: %v", err)
}

rc, err := strconv.ParseInt(hex.EncodeToString(buf.rc[0:1]), 16, 64)
if rc != 65 {
return nil, fmt.Errorf("Request to query MDM failed, RC=%d", rc)
// Parse the output to extract MDM information
re := regexp.MustCompile(`MDM-ID ([a-f0-9]+) SDC ID ([a-f0-9]+)`)
matches := re.FindAllStringSubmatch(string(output), -1)
if len(matches) == 0 {
return nil, fmt.Errorf("no MDM information found in drv_cfg output")
}

for i := uint16(0); i < buf.numMdms; i++ {
systemID := fmt.Sprintf("%8.8x%8.8x",
buf.mdms[i].mdmIDH, buf.mdms[i].mdmIDL)
sdcID := fmt.Sprintf("%8.8x%8.8x",
buf.mdms[i].sdcIDH, buf.mdms[i].sdcIDL)
// Fetch the systemID and sdcID for each system
for _, match := range matches {
systemID := match[1]
sdcID := match[2]
aCluster := ConfiguredCluster{
SystemID: systemID,
SdcID: sdcID,
Expand Down
3 changes: 3 additions & 0 deletions inttests/drv_cfg_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,9 @@ func TestGetDrvCfgGUIDSDCNotInstalled(t *testing.T) {
// TestGetSrvCfgSystems will return the PowerFlex systems connected to tyhe local SDC
func TestGetDrvCfgSystems(t *testing.T) {
goscaleio.SDCDevice = goscaleio.IOCTLDevice
// Adding symlink in order to run query_mdm cmd on the host and fetch the systems
os.Symlink("/", "/noderoot")
defer os.Remove("/noderoot")
systems, err := goscaleio.DrvCfgQuerySystems()

// The response depends on the installation state of the SDC
Expand Down
Loading