drivers.go 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206
  1. // Copyright 2019 Yunion
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. package drivers
  15. import (
  16. "fmt"
  17. "yunion.io/x/jsonutils"
  18. "yunion.io/x/log"
  19. "yunion.io/x/pkg/errors"
  20. api "yunion.io/x/onecloud/pkg/apis/compute"
  21. "yunion.io/x/onecloud/pkg/baremetal/utils/raid"
  22. _ "yunion.io/x/onecloud/pkg/baremetal/utils/raid/adaptec"
  23. _ "yunion.io/x/onecloud/pkg/baremetal/utils/raid/hpssactl"
  24. _ "yunion.io/x/onecloud/pkg/baremetal/utils/raid/mdadm"
  25. _ "yunion.io/x/onecloud/pkg/baremetal/utils/raid/megactl"
  26. _ "yunion.io/x/onecloud/pkg/baremetal/utils/raid/mvcli"
  27. _ "yunion.io/x/onecloud/pkg/baremetal/utils/raid/sas2iru"
  28. "yunion.io/x/onecloud/pkg/compute/baremetal"
  29. )
  30. func GetDriver(name string, term raid.IExecTerm) raid.IRaidDriver {
  31. factory := raid.RaidDrivers[name]
  32. if factory == nil {
  33. return nil
  34. }
  35. return factory(term)
  36. }
  37. func GetLocalDriver(name string) raid.IRaidDriver {
  38. factory := raid.RaidDrivers[name]
  39. if factory == nil {
  40. return nil
  41. }
  42. return factory(NewExecutor())
  43. }
  44. func GetDriverWithInit(name string, term raid.IExecTerm) (raid.IRaidDriver, error) {
  45. drv := GetDriver(name, term)
  46. if drv == nil {
  47. return nil, errors.Errorf("Not found raid driver %q", name)
  48. }
  49. return drv, drv.ParsePhyDevs()
  50. }
  51. func GetDriverByKernelModule(module string, term raid.IExecTerm) (raid.IRaidDriver, error) {
  52. name := ""
  53. switch module {
  54. case raid.MODULE_MEGARAID:
  55. name = baremetal.DISK_DRIVER_MEGARAID
  56. case raid.MODULE_HPSA:
  57. name = baremetal.DISK_DRIVER_HPSARAID
  58. case raid.MODULE_MPT2SAS, raid.MODULE_MPT3SAS:
  59. name = baremetal.DISK_DRIVER_MPT2SAS
  60. case raid.MODULE_AACRAID, raid.MODULE_SMARTPQI:
  61. name = baremetal.DISK_DRIVER_ADAPTECRAID
  62. }
  63. if name == "" {
  64. return nil, errors.Errorf("Not support module %q", module)
  65. }
  66. return GetDriverWithInit(name, term)
  67. }
  68. func GetDrivers(term raid.IExecTerm) []raid.IRaidDriver {
  69. ret := []raid.IRaidDriver{}
  70. for _, factory := range raid.RaidDrivers {
  71. ret = append(ret, factory(term))
  72. }
  73. return ret
  74. }
  75. func BuildRaid(driver raid.IRaidDriver, confs []*api.BaremetalDiskConfig, adapterIdx int) error {
  76. if err := driver.PreBuildRaid(confs, adapterIdx); err != nil {
  77. return fmt.Errorf("PreBuildRaid: %v", err)
  78. }
  79. var adapter raid.IRaidAdapter
  80. for _, tmp := range driver.GetAdapters() {
  81. if tmp.GetIndex() == adapterIdx {
  82. adapter = tmp
  83. break
  84. }
  85. }
  86. if adapter == nil {
  87. return fmt.Errorf("Not found adapter by index %d", adapterIdx)
  88. }
  89. if err := buildRaid(driver, adapter, confs); err != nil {
  90. return fmt.Errorf("Driver %s, adapter %d build raid: %v", driver.GetName(), adapterIdx, err)
  91. }
  92. return nil
  93. }
  94. func buildRaid(driver raid.IRaidDriver, adapter raid.IRaidAdapter, confs []*api.BaremetalDiskConfig) error {
  95. if err := adapter.PreBuildRaid(confs); err != nil {
  96. return fmt.Errorf("PreBuildRaid: %v", err)
  97. }
  98. if err := adapter.RemoveLogicVolumes(); err != nil {
  99. return fmt.Errorf("RemoveLogicVolumes: %v", err)
  100. }
  101. devs := adapter.GetDevices()
  102. if len(devs) == 0 {
  103. // no disk to build
  104. return nil
  105. }
  106. var selected []*baremetal.BaremetalStorage
  107. var nonDisks []*baremetal.BaremetalStorage
  108. var err error
  109. left := devs
  110. for _, conf := range confs {
  111. selected, left, err = baremetal.RetrieveStorages(conf, left)
  112. if len(selected) == 0 {
  113. return errors.Wrapf(err, "no enough disks for config %#v", conf)
  114. }
  115. var err error
  116. switch conf.Conf {
  117. case baremetal.DISK_CONF_RAID5:
  118. err = adapter.BuildRaid5(selected, conf)
  119. case baremetal.DISK_CONF_RAID10:
  120. err = adapter.BuildRaid10(selected, conf)
  121. case baremetal.DISK_CONF_NONE:
  122. nonDisks = append(nonDisks, selected...)
  123. case baremetal.DISK_CONF_RAID0:
  124. err = adapter.BuildRaid0(selected, conf)
  125. case baremetal.DISK_CONF_RAID1:
  126. err = adapter.BuildRaid1(selected, conf)
  127. default:
  128. return fmt.Errorf("Unknown raid config %s", conf.Conf)
  129. }
  130. if err != nil {
  131. return fmt.Errorf("Build raid %s: %v", conf.Conf, err)
  132. }
  133. log.Infof("Build %s:%d raid %s", driver.GetName(), adapter.GetIndex(), conf.Conf)
  134. }
  135. if len(nonDisks) > 0 {
  136. if err := adapter.BuildNoneRaid(nonDisks); err != nil {
  137. return fmt.Errorf("Build raw disks: %v", err)
  138. }
  139. }
  140. if err := adapter.PostBuildRaid(); err != nil {
  141. return errors.Wrap(err, "Post build raid")
  142. }
  143. return nil
  144. }
  145. func PostBuildRaid(driver raid.IRaidDriver, adapterIdx int) error {
  146. for _, a := range driver.GetAdapters() {
  147. if a.GetIndex() == adapterIdx {
  148. if err := a.PostBuildRaid(); err != nil {
  149. return errors.Wrap(err, "PostBuildRaid")
  150. }
  151. }
  152. }
  153. return nil
  154. }
  155. func GetFirstLogicalVolume(drv raid.IRaidDriver, adapterIdx int) (*raid.RaidLogicalVolume, error) {
  156. var adapter raid.IRaidAdapter = nil
  157. for _, ada := range drv.GetAdapters() {
  158. if ada.GetIndex() == adapterIdx {
  159. adapter = ada
  160. }
  161. }
  162. if adapter == nil {
  163. return nil, errors.Errorf("Not found raid %s adapter %d", drv.GetName(), adapterIdx)
  164. }
  165. lvs, err := adapter.GetLogicVolumes()
  166. if err != nil {
  167. return nil, errors.Wrapf(err, "Get adapter logical volume")
  168. }
  169. if len(lvs) == 0 {
  170. return nil, errors.Errorf("Adapter %d empty logical volume", adapterIdx)
  171. }
  172. return lvs[0], nil
  173. }
  174. func GetBlockDeviceLogicalVolume(drv raid.IRaidDriver, blockDev string) (*raid.RaidLogicalVolume, error) {
  175. lvs := make([]*raid.RaidLogicalVolume, 0)
  176. for _, ada := range drv.GetAdapters() {
  177. aLvs, err := ada.GetLogicVolumes()
  178. if err != nil {
  179. return nil, errors.Errorf("Get adapter %d logical volumes: %v", ada.GetIndex(), err)
  180. }
  181. lvs = append(lvs, aLvs...)
  182. }
  183. log.Debugf("Get logic volumes: %s", jsonutils.Marshal(lvs).String())
  184. for _, lv := range lvs {
  185. if lv.BlockDev == blockDev {
  186. return lv, nil
  187. }
  188. }
  189. return nil, errors.Errorf("Not found logical volume by block device %s", blockDev)
  190. }