github.com/openebs/api@v1.12.0/pkg/internalapis/apis/cstor/cstorpool_topology.go (about)

     1  /*
     2  Copyright 2020 The 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 cstor
    18  
    19  import (
    20  	"encoding/json"
    21  	"strings"
    22  
    23  	"github.com/openebs/api/pkg/util"
    24  )
    25  
    26  /*
    27  * enum maintaing in cstor data plane side
    28  * typedef enum dsl_scan_state {
    29  *        DSS_NONE,
    30  *        DSS_SCANNING,
    31  *        DSS_FINISHED,
    32  *        DSS_CANCELED,
    33  *        DSS_NUM_STATES
    34  *} dsl_scan_state_t;
    35   */
    36  
    37  //TODO: Improve comments during review process
    38  
    39  //PoolScanState states various pool scan states
    40  type PoolScanState uint64
    41  
    42  const (
    43  	// PoolScanNone represents pool scanning is not yet started
    44  	PoolScanNone PoolScanState = iota
    45  	// PoolScanScanning represents pool is undergoing scanning
    46  	PoolScanScanning
    47  	// PoolScanFinished represents pool scanning is finished
    48  	PoolScanFinished
    49  	// PoolScanCanceled represents pool scan is aborted
    50  	PoolScanCanceled
    51  	// PoolScanNumOfStates holds value 4
    52  	PoolScanNumOfStates
    53  )
    54  
    55  // PoolScanFunc holds various scanning functions
    56  type PoolScanFunc uint64
    57  
    58  const (
    59  	// PoolScanFuncNone holds value 0
    60  	PoolScanFuncNone PoolScanFunc = iota
    61  	// PoolScanFuncScrub holds value 1
    62  	PoolScanFuncScrub
    63  	// PoolScanFuncResilver holds value 2 which states device under went resilvering
    64  	PoolScanFuncResilver
    65  	// PoolScanFuncStates holds value 3
    66  	PoolScanFuncStates
    67  )
    68  
    69  // NOTE: 1. VdevState represent the state of the vdev/disk in pool.
    70  //       2. VdevAux represents gives the reason why disk/vdev are in that state.
    71  
    72  // VdevState represent various device/disk states
    73  type VdevState uint64
    74  
    75  /*
    76   * vdev states are ordered from least to most healthy.
    77   * Link: https://github.com/openebs/cstor/blob/f0896898a0be2102e2865cf44b16b88c91f6bb91/include/sys/fs/zfs.h#L723
    78   */
    79  const (
    80  	// VdevStateUnknown represents uninitialized vdev
    81  	VdevStateUnknown VdevState = iota
    82  	// VdevStateClosed represents vdev currently not opened
    83  	VdevStateClosed
    84  	// VdevStateOffline represents vdev not allowed to open
    85  	VdevStateOffline
    86  	// VdevStateRemoved represents vdev explicitly removed from system
    87  	VdevStateRemoved
    88  	// VdevStateCantOpen represents tried to open, but failed
    89  	VdevStateCantOpen
    90  	// VdevStateFaulted represents external request to fault device
    91  	VdevStateFaulted
    92  	// VdevStateDegraded represents Replicated vdev with unhealthy kids
    93  	VdevStateDegraded
    94  	// VdevStateHealthy represents vdev is presumed good
    95  	VdevStateHealthy
    96  )
    97  
    98  // VdevAux represents reasons why vdev can't open
    99  type VdevAux uint64
   100  
   101  /*
   102   * vdev aux states.  When a vdev is in the CANT_OPEN state, the aux field
   103   * of the vdev stats structure uses these constants to distinguish why.
   104   */
   105  // NOTE: Added only required enums for more information please have look at
   106  // https://github.com/openebs/cstor/blob/f0896898a0be2102e2865cf44b16b88c91f6bb91/include/sys/fs/zfs.h#L740
   107  const (
   108  	VdevAuxNone            VdevAux = iota /* no error */
   109  	VdevAuxOpenFailed                     /* ldi_open_*() or vn_open() failed  */
   110  	VdevAuxCorruptData                    /* bad label or disk contents           */
   111  	VdevAuxNoReplicas                     /* insufficient number of replicas      */
   112  	VdevAuxBadGUIDSum                     /* vdev guid sum doesn't match          */
   113  	VdevAuxTooSmall                       /* vdev size is too small               */
   114  	VdevAuxBadLabel                       /* the label is OK but invalid          */
   115  	VdevAuxVersionNewer                   /* on-disk version is too new           */
   116  	VdevAuxVersionOlder                   /* on-disk version is too old           */
   117  	VdevAuxUnSupFeat                      /* unsupported features                 */
   118  	VdevAuxSpared                         /* hot spare used in another pool       */
   119  	VdevAuxErrExceeded                    /* too many errors                      */
   120  	VdevAuxIOFailure                      /* experienced I/O failure              */
   121  	VdevAuxBadLog                         /* cannot read log chain(s)             */
   122  	VdevAuxExternal                       /* external diagnosis or forced fault   */
   123  	VdevAuxSplitPool                      /* vdev was split off into another pool */
   124  	VdevAuxBadAShift                      /* vdev ashift is invalid               */
   125  	VdevAuxExternalPersist                /* persistent forced fault      */
   126  	VdevAuxActive                         /* vdev active on a different host      */
   127  )
   128  
   129  const (
   130  	// PoolOperator is the name of the tool that makes pool-related operations.
   131  	PoolOperator = "zpool"
   132  	// VdevScanProcessedIndex is index of scaned bytes on disk
   133  	VdevScanProcessedIndex = 25
   134  	// VdevScanStatsStateIndex represents the index of dataset scan state
   135  	VdevScanStatsStateIndex = 1
   136  	// VdevScanStatsScanFuncIndex point to index which inform whether device
   137  	// under went resilvering or not
   138  	VdevScanStatsScanFuncIndex = 0
   139  	// VdevStateIndex represents the device state information
   140  	VdevStateIndex = 1
   141  	// VdevAuxIndex represents vdev aux states. When a vdev is
   142  	// in the CANT_OPEN state, the aux field of the vdev stats
   143  	// structure uses these constants to distinguish why
   144  	VdevAuxIndex = 2
   145  )
   146  
   147  // Topology contains the topology strucure of disks used in backend
   148  type Topology struct {
   149  	// Number of top-level children in topology (doesnt include spare/l2cache)
   150  	ChildrenCount int `json:"vdev_children,omitempty"`
   151  
   152  	// Root of vdev topology
   153  	VdevTree VdevTree `json:"vdev_tree,omitempty"`
   154  }
   155  
   156  // VdevTree contains the tree strucure of disks used in backend
   157  type VdevTree struct {
   158  	// root for Root vdev, Raid type in case of non-level 0 vdev,
   159  	// and file/disk in case of level-0 vdev
   160  	VdevType string `json:"type,omitempty"`
   161  
   162  	// top-level vdev topology
   163  	Topvdev []Vdev `json:"children,omitempty"`
   164  
   165  	// list of read-cache devices
   166  	Readcache []Vdev `json:"l2cache,omitempty"`
   167  
   168  	// list of spare devices
   169  	Spares []Vdev `json:"spares,omitempty"`
   170  
   171  	// vdev indetailed statistics
   172  	VdevStats []uint64 `json:"vdev_stats,omitempty"`
   173  
   174  	// ScanStats states replaced device scan state
   175  	ScanStats []uint64 `json:"scan_stats,omitempty"`
   176  }
   177  
   178  // Vdev relates to a logical or physical disk in backend
   179  type Vdev struct {
   180  	// root for Root vdev, Raid type in case of non-level 0 vdev,
   181  	// and file/disk in case of level-0 vdev
   182  	VdevType string `json:"type,omitempty"`
   183  
   184  	// Path of the disk or sparse file
   185  	Path string `json:"path,omitempty"`
   186  
   187  	// 0 means not write-cache device, 1 means write-cache device
   188  	IsLog int `json:"is_log,omitempty"`
   189  
   190  	// 0 means not spare device, 1 means spare device
   191  	IsSpare int `json:"is_spare,omitempty"`
   192  
   193  	// 0 means partitioned disk, 1 means whole disk
   194  	IsWholeDisk int `json:"whole_disk,omitempty"`
   195  
   196  	// Capacity represents the size of the disk used in pool
   197  	Capacity uint64 `json:"asize,omitempty"`
   198  
   199  	// vdev indetailed statistics
   200  	VdevStats []uint64 `json:"vdev_stats,omitempty"`
   201  
   202  	ScanStats []uint64 `json:"scan_stats,omitempty"`
   203  
   204  	// child vdevs of the logical disk or null for physical disk/sparse
   205  	Children []Vdev `json:"children,omitempty"`
   206  }
   207  
   208  // VdevList is alias of list of Vdevs
   209  type VdevList []Vdev
   210  
   211  // Dump runs 'zpool dump' command and unmarshal the output in above schema
   212  func Dump() (Topology, error) {
   213  	var t Topology
   214  	runnerVar := util.RealRunner{}
   215  	out, err := runnerVar.RunCombinedOutput(PoolOperator, "dump")
   216  	if err != nil {
   217  		return t, err
   218  	}
   219  	err = json.Unmarshal(out, &t)
   220  	return t, err
   221  }
   222  
   223  // GetVdevFromPath returns vdev if provided path exists in vdev topology
   224  func (l VdevList) GetVdevFromPath(path string) (Vdev, bool) {
   225  	for _, v := range l {
   226  		if strings.EqualFold(path, v.Path) {
   227  			return v, true
   228  		}
   229  		for _, p := range v.Children {
   230  			if strings.EqualFold(path, p.Path) {
   231  				return p, true
   232  			}
   233  			if vdev, r := VdevList(p.Children).GetVdevFromPath(path); r {
   234  				return vdev, true
   235  			}
   236  		}
   237  	}
   238  	return Vdev{}, false
   239  }
   240  
   241  // GetVdevState returns current state of Vdev
   242  // NOTE: Below function is taken from openebs/cstor
   243  // https://github.com/openebs/cstor/blob/f0896898a0be2102e2865cf44b16b88c91f6bb91/lib/libzfs/libzfs_pool.c#L183<Paste>
   244  func (v Vdev) GetVdevState() string {
   245  	state := v.VdevStats[VdevStateIndex]
   246  	aux := v.VdevStats[VdevAuxIndex]
   247  	switch state {
   248  	case uint64(VdevStateClosed):
   249  		fallthrough
   250  	case uint64(VdevStateOffline):
   251  		return "OFFLINE"
   252  	case uint64(VdevStateRemoved):
   253  		return "REMOVED"
   254  	case uint64(VdevStateCantOpen):
   255  		if aux == uint64(VdevAuxCorruptData) || aux == uint64(VdevAuxBadLog) {
   256  			return "FAULTED"
   257  		} else if aux == uint64(VdevAuxSplitPool) {
   258  			return "SPLIT"
   259  		} else {
   260  			return "UNAVAILABLE"
   261  		}
   262  	case uint64(VdevStateFaulted):
   263  		return "FAULTED"
   264  	case uint64(VdevStateDegraded):
   265  		return "DEGRADED"
   266  	case uint64(VdevStateHealthy):
   267  		return "ONLINE"
   268  	}
   269  	return "UNKNOWN"
   270  }