diff --git a/gonvme_tcp.go b/gonvme_tcp.go index 74f5589..7d25d2a 100644 --- a/gonvme_tcp.go +++ b/gonvme_tcp.go @@ -307,6 +307,111 @@ func (nvme *NVMeTCP) nvmeDisonnect(target NVMeTarget) error { return err } +// ListNamespaceDevices returns the NVMe namespace Device Paths and each output content +func (nvme *NVMeTCP) ListNamespaceDevices() map[string][]string { + exe := nvme.buildNVMeCommand([]string{"nvme", "list", "-o", "json"}) + + /* nvme list -o json + { + "Devices" : [ + { + "NameSpace" : 9217, + "DevicePath" : "/dev/nvme0n1", + "Firmware" : "2.1.0.0", + "Index" : 0, + "ModelNumber" : "dellemc", + "SerialNumber" : "FP08RZ2", + "UsedBytes" : 0, + "MaximumLBA" : 10485760, + "PhysicalSize" : 5368709120, + "SectorSize" : 512 + }, + { + "NameSpace" : 9222, + "DevicePath" : "/dev/nvme0n2", + "Firmware" : "2.1.0.0", + "Index" : 0, + "ModelNumber" : "dellemc", + "SerialNumber" : "FP08RZ2", + "UsedBytes" : 0, + "MaximumLBA" : 10485760, + "PhysicalSize" : 5368709120, + "SectorSize" : 512 + } + ] + } + */ + cmd := exec.Command(exe[0], exe[1:]...) + + output, _ := cmd.Output() + str := string(output) + lines := strings.Split(str, "\n") + + var devicePaths []string + for _, line := range lines { + line = strings.ReplaceAll(strings.TrimSpace(line), ",", "") + + if strings.HasPrefix(line, "\"DevicePath\"") { + if len(strings.Split(line, ":")) >= 2 { + devicePath := strings.ReplaceAll(strings.TrimSpace(strings.Split(line, ":")[1]), "\"", "") + devicePaths = append(devicePaths, devicePath) + } + } + } + + namespaceDevices := make(map[string][]string) + + for _, devicePath := range devicePaths { + + exe := nvme.buildNVMeCommand([]string{"nvme", "list-ns", devicePath}) + /* nvme list-ns /dev/nvme0n1 + [ 0]:0x2401 + [ 1]:0x2406 + */ + cmd := exec.Command(exe[0], exe[1:]...) + output, _ := cmd.Output() + + str := string(output) + lines := strings.Split(str, "\n") + + var namespaceDevice []string + for _, line := range lines { + line = strings.TrimSpace(line) + if line != "" { + if len(strings.Split(line, ":")) >= 2 { + nsDevice := strings.Split(line, ":")[1] + namespaceDevice = append(namespaceDevice, nsDevice) + } + } + } + namespaceDevices[devicePath] = namespaceDevice + } + return namespaceDevices +} + +// GetNamespaceData returns the information of namespace specific to the namespace Id +func (nvme *NVMeTCP) GetNamespaceData(path string, namespaceID string) (string, error) { + + var nguid string + + exe := nvme.buildNVMeCommand([]string{"nvme", "id-ns", path, "--namespace", namespaceID}) + cmd := exec.Command(exe[0], exe[1:]...) + + output, error := cmd.Output() + str := string(output) + lines := strings.Split(str, "\n") + + for _, line := range lines { + if strings.HasPrefix(line, "nguid") { + if len(strings.Split(line, ":")) >= 2 { + nguid = strings.TrimSpace(strings.Split(line, ":")[1]) + } + return nguid, nil + } + } + return nguid, error +} + // GetSessions queries information about NVMe sessions func (nvme *NVMeTCP) GetSessions() ([]NVMESession, error) { exe := nvme.buildNVMeCommand([]string{"nvme", "list-subsys", "-o", "json"})