github.com/openebs/node-disk-manager@v1.9.1-0.20230225014141-4531f06ffa1e/pkg/udev/mockdata.go (about)

     1  /*
     2  Copyright 2018 OpenEBS Authors.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  // +build linux,cgo
    18  
    19  package udev
    20  
    21  /*
    22    #cgo LDFLAGS: -ludev
    23    #include <libudev.h>
    24  */
    25  import "C"
    26  import (
    27  	"bufio"
    28  	"io/ioutil"
    29  	"os"
    30  	"path"
    31  	"path/filepath"
    32  	"strings"
    33  
    34  	bd "github.com/openebs/node-disk-manager/blockdevice"
    35  	"github.com/openebs/node-disk-manager/pkg/mount"
    36  	"github.com/openebs/node-disk-manager/pkg/sysfs"
    37  )
    38  
    39  // MockOsDiskDetails struct contain different attribute of os disk.
    40  type MockOsDiskDetails struct {
    41  	OsDiskName     string
    42  	DevType        string
    43  	DevNode        string
    44  	Size           string
    45  	SysPath        string
    46  	Model          string
    47  	Serial         string
    48  	Vendor         string
    49  	Wwn            string
    50  	Uid            string
    51  	FileSystem     string
    52  	Mountpoint     string
    53  	PartTableType  string
    54  	PartTableUUID  string
    55  	IdType         string
    56  	ByIdDevLinks   []string
    57  	ByPathDevLinks []string
    58  	SymLinks       []string
    59  	Dependents     bd.DependentBlockDevices
    60  }
    61  
    62  // mockDataStructUdev returns C udev struct for unit test.
    63  func mockDataStructUdev() *C.struct_udev {
    64  	return C.udev_new()
    65  }
    66  
    67  // MockDiskDetails returns os disk details which is used in unit test.
    68  func MockDiskDetails() (MockOsDiskDetails, error) {
    69  	diskDetails := MockOsDiskDetails{}
    70  	osDiskName, osFilesystem, err := OsDiskName()
    71  	if err != nil {
    72  		return diskDetails, err
    73  	}
    74  	sysPath, err := getSyspathOfOsDisk(osDiskName)
    75  	if err != nil {
    76  		return diskDetails, err
    77  	}
    78  	size, err := getOsDiskSize(osDiskName)
    79  	if err != nil {
    80  		return diskDetails, err
    81  	}
    82  	device := getOsDiskUdevDevice(sysPath)
    83  	if device == nil {
    84  		return diskDetails, err
    85  	}
    86  	defer device.UdevDeviceUnref()
    87  	diskDetails.OsDiskName = osDiskName
    88  	diskDetails.DevType = "disk"
    89  	diskDetails.DevNode = "/dev/" + osDiskName
    90  	diskDetails.Size = size
    91  	diskDetails.SysPath = sysPath
    92  	diskDetails.Model = device.GetPropertyValue(UDEV_MODEL)
    93  	diskDetails.Serial = device.GetPropertyValue(UDEV_SERIAL)
    94  	diskDetails.Vendor = device.GetPropertyValue(UDEV_VENDOR)
    95  	diskDetails.Wwn = device.GetPropertyValue(UDEV_WWN)
    96  	diskDetails.FileSystem = osFilesystem
    97  	diskDetails.PartTableType = device.GetPropertyValue(UDEV_PARTITION_TABLE_TYPE)
    98  	diskDetails.PartTableUUID = device.GetPropertyValue(UDEV_PARTITION_TABLE_UUID)
    99  	diskDetails.IdType = device.GetPropertyValue(UDEV_TYPE)
   100  	dev, err := sysfs.NewSysFsDeviceFromDevPath(diskDetails.DevNode)
   101  	if err != nil {
   102  		return diskDetails, err
   103  	}
   104  	diskDetails.Dependents, err = dev.GetDependents()
   105  	if err != nil {
   106  		return diskDetails, err
   107  	}
   108  	diskDetails.Mountpoint = "/" // always take the disk mounted at /
   109  	devLinks := device.GetDevLinks()
   110  	diskDetails.ByIdDevLinks = devLinks[BY_ID_LINK]
   111  	diskDetails.ByPathDevLinks = devLinks[BY_PATH_LINK]
   112  	diskDetails.SymLinks = devLinks[SYMLINK]
   113  	return diskDetails, nil
   114  }
   115  
   116  // OsDiskName returns os disk name given by kernel
   117  func OsDiskName() (string, string, error) {
   118  	var osPartPath, osFileSystem string
   119  	// Read /proc/self/mounts file to get which partition is mounted on / path.
   120  	file, err := os.Open("/proc/self/mounts")
   121  	if err != nil {
   122  		return osPartPath, osFileSystem, err
   123  	}
   124  	defer file.Close()
   125  	scanner := bufio.NewScanner(file)
   126  	for scanner.Scan() {
   127  		line := scanner.Text()
   128  		parts := strings.Split(line, " ")
   129  		if parts[1] == "/" {
   130  			// Get dev path of the partition which is mounted on / path
   131  			osPartPath = parts[0]
   132  			osFileSystem = parts[2]
   133  			break
   134  		}
   135  	}
   136  
   137  	mountPointUtil := mount.NewMountUtil("/proc/self/mounts", "", "/")
   138  	disk, err := mountPointUtil.GetDiskPath()
   139  	if err != nil {
   140  		return osPartPath, osFileSystem, err
   141  	}
   142  	disk = strings.Replace(disk, "/dev/", "", 1)
   143  	return disk, osFileSystem, nil
   144  }
   145  
   146  // getSyspathOfOsDisk returns syspath of os disk in success
   147  func getSyspathOfOsDisk(osDiskName string) (string, error) {
   148  	data, err := ioutil.ReadFile(filepath.Clean(path.Join("/sys/class/block/", osDiskName, "dev")))
   149  	if err != nil {
   150  		return "", err
   151  	}
   152  	return "/sys/dev/block/" + strings.TrimSpace(string(data)), nil
   153  }
   154  
   155  // getOsDiskSize returns size of os disk in success
   156  func getOsDiskSize(osDiskName string) (string, error) {
   157  	sizeByte, err := ioutil.ReadFile(filepath.Clean(path.Join("/sys/class/block/", osDiskName, "size")))
   158  	if err != nil {
   159  		return "", err
   160  	}
   161  	return strings.TrimSpace(string(sizeByte)), nil
   162  }
   163  
   164  // getOsDiskUdevDevice UdevDevice struct of Os disk
   165  func getOsDiskUdevDevice(sysPath string) *UdevDevice {
   166  	udev, err := NewUdev()
   167  	if err != nil {
   168  		return nil
   169  	}
   170  	device, err := udev.NewDeviceFromSysPath(sysPath)
   171  	if err != nil {
   172  		return nil
   173  	}
   174  	return device
   175  }