github.com/openebs/node-disk-manager@v1.9.1-0.20230225014141-4531f06ffa1e/pkg/smart/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  package smart
    18  
    19  import "github.com/openebs/node-disk-manager/pkg/udev"
    20  
    21  //MockOsDiskDetails struct contains the basic details of the disk
    22  type MockOsDiskDetails struct {
    23  	Compliance       string
    24  	FirmwareRevision string
    25  	Capacity         uint64
    26  	LBSize           uint32
    27  	DevPath          string
    28  }
    29  
    30  type mockDev interface {
    31  	Open() error
    32  	Close() error
    33  	mockDiskDetailsBySmart() (MockOsDiskDetails, error)
    34  	getCommonSCSIDetails(cDetail MockOsDiskDetails) (MockOsDiskDetails, error)
    35  }
    36  
    37  var (
    38  	diskDetails MockOsDiskDetails
    39  )
    40  
    41  func (d *SCSIDev) getCommonSCSIDetails(cDetail MockOsDiskDetails) (MockOsDiskDetails, error) {
    42  	InqRes, err := d.scsiInquiry()
    43  	if err != nil {
    44  		return cDetail, err
    45  	}
    46  	cDetail.Compliance = InqRes.getValue()[Compliance]
    47  	cDetail.FirmwareRevision = InqRes.getValue()[FirmwareRev]
    48  
    49  	// Scsi readDeviceCapacity command to get the capacity of a disk
    50  	capacity, err := d.readDeviceCapacity()
    51  	if err != nil {
    52  		return cDetail, err
    53  	}
    54  	cDetail.Capacity = capacity
    55  
    56  	devPath, _ := getDevPath()
    57  	cDetail.DevPath = devPath
    58  
    59  	return cDetail, nil
    60  }
    61  
    62  func (d *SATA) mockDiskDetailsBySmart() (MockOsDiskDetails, error) {
    63  
    64  	diskDetails, err := d.getCommonSCSIDetails(diskDetails)
    65  	if err != nil {
    66  		return diskDetails, err
    67  	}
    68  	identifyBuf, err := d.ataIdentify()
    69  	if err != nil {
    70  		return diskDetails, err
    71  	}
    72  	LBSize, _ := identifyBuf.getSectorSize()
    73  	diskDetails.LBSize = LBSize
    74  
    75  	return diskDetails, nil
    76  
    77  }
    78  
    79  func (d *SCSIDev) mockDiskDetailsBySmart() (MockOsDiskDetails, error) {
    80  
    81  	diskDetails, err := d.getCommonSCSIDetails(diskDetails)
    82  	if err != nil {
    83  		return diskDetails, err
    84  	}
    85  
    86  	LBSize, err := d.getLBSize()
    87  	if err != nil {
    88  		return diskDetails, err
    89  	}
    90  	diskDetails.LBSize = LBSize
    91  
    92  	return diskDetails, nil
    93  
    94  }
    95  
    96  // MockScsiBasicDiskInfo is used to fetch basic disk details for a scsi disk
    97  func MockScsiBasicDiskInfo() (MockOsDiskDetails, error) {
    98  
    99  	osname, _, err := udev.OsDiskName()
   100  	if err != nil {
   101  		return diskDetails, err
   102  	}
   103  	devPath := "/dev/" + osname
   104  	// Before getting disk details, check if the necessary conditions to get
   105  	// disk details are fulfilled or not such as device path is given or not,
   106  	// binary permissions are set or not, bus type is supported or not, etc
   107  	if err := isConditionSatisfied(devPath); err != nil {
   108  		return diskDetails, err
   109  	}
   110  	// Check the type of SCSI device, if it is ATA or something else..
   111  	// based on which the dev interface is returned
   112  	d, err := mockdetectSCSIType(devPath)
   113  	if err != nil {
   114  		return diskDetails, err
   115  	}
   116  	defer d.Close()
   117  
   118  	// Get all the available disk details in the form of struct and errors if any (in form of map)
   119  	diskDetails, err = d.mockDiskDetailsBySmart()
   120  	return diskDetails, err
   121  }
   122  
   123  func mockdetectSCSIType(name string) (mockDev, error) {
   124  	device := SCSIDev{DevName: name}
   125  	if err := device.Open(); err != nil {
   126  		return nil, err
   127  	}
   128  	// send a scsi inquiry command to the given device
   129  	SCSIInquiry, err := device.scsiInquiry()
   130  	if err != nil {
   131  		return nil, err
   132  	}
   133  	// Check if device is an ATA device (For an ATA device VendorIdentification value should be equal to ATA)
   134  	// For ATA, return pointer to SATA device else return pointer to SCSI device interface
   135  	if SCSIInquiry.VendorID == [8]byte{0x41, 0x54, 0x41, 0x20, 0x20, 0x20, 0x20, 0x20} {
   136  		return &SATA{device}, nil
   137  	}
   138  
   139  	return &device, nil
   140  }
   141  
   142  func getDevPath() (string, error) {
   143  	osname, _, err := udev.OsDiskName()
   144  	if err != nil {
   145  		return "", err
   146  	}
   147  	devPath := "/dev/" + osname
   148  
   149  	return devPath, nil
   150  }