driver.go 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  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 megactl
  15. import (
  16. "yunion.io/x/log"
  17. "yunion.io/x/pkg/errors"
  18. "yunion.io/x/onecloud/pkg/apis/compute"
  19. "yunion.io/x/onecloud/pkg/baremetal/options"
  20. "yunion.io/x/onecloud/pkg/baremetal/utils/raid"
  21. "yunion.io/x/onecloud/pkg/compute/baremetal"
  22. )
  23. func init() {
  24. raid.RegisterDriver(baremetal.DISK_DRIVER_MEGARAID, newRaid)
  25. }
  26. type iDriver interface {
  27. GetName() string
  28. GetAdapterConstructCmd() string
  29. NewAdaptor(term raid.IExecTerm) iAdaptor
  30. ClearForeignState(term raid.IExecTerm) error
  31. }
  32. type iAdaptor interface {
  33. ParseLine(line string)
  34. IsComplete() bool
  35. Key() string
  36. GetPhyDevs() ([]*MegaRaidPhyDev, error)
  37. ClearJBODDisks(devs []*MegaRaidPhyDev)
  38. GetIndex() int
  39. GetLogicVolumes() ([]*raid.RaidLogicalVolume, error)
  40. RemoveLogicVolumes() error
  41. BuildRaid0(devs []*baremetal.BaremetalStorage, conf *compute.BaremetalDiskConfig) error
  42. BuildRaid1(devs []*baremetal.BaremetalStorage, conf *compute.BaremetalDiskConfig) error
  43. BuildRaid5(devs []*baremetal.BaremetalStorage, conf *compute.BaremetalDiskConfig) error
  44. BuildRaid10(devs []*baremetal.BaremetalStorage, conf *compute.BaremetalDiskConfig) error
  45. BuildNoneRaid(devs []*baremetal.BaremetalStorage) error
  46. }
  47. type sRaid struct {
  48. driver iDriver
  49. term raid.IExecTerm
  50. adaptors []*sRaidAdaptor
  51. phyDevsCnt int
  52. }
  53. func newRaid(term raid.IExecTerm) raid.IRaidDriver {
  54. if options.Options.UseMegaRaidPerccli {
  55. perccliDrv := &sRaid{
  56. driver: newPerccliDriver(),
  57. term: term,
  58. adaptors: make([]*sRaidAdaptor, 0),
  59. }
  60. if err := perccliDrv.ParsePhyDevs(); err == nil && perccliDrv.phyDevsCnt > 0 {
  61. log.Infof("Use perccli driver, found %d pds", perccliDrv.phyDevsCnt)
  62. return perccliDrv
  63. } else {
  64. log.Warningf("perccli driver parse physical devices error: %v, %d pds, fallback to old megactl and storcli driver", err, perccliDrv.phyDevsCnt)
  65. return NewMegaRaid(term)
  66. }
  67. }
  68. log.Infof("Not use perccli, use legacy megaraid driver")
  69. return NewMegaRaid(term)
  70. }
  71. func (r *sRaid) GetName() string {
  72. return baremetal.DISK_DRIVER_MEGARAID
  73. }
  74. type sRaidAdaptor struct {
  75. iAdaptor
  76. raid *sRaid
  77. devs []*MegaRaidPhyDev
  78. sn string
  79. name string
  80. busNumber string
  81. deviceNumber string
  82. funcNumber string
  83. // used by sg_map
  84. hostNum int
  85. //channelNum int
  86. }
  87. func newRaidAdaptor(baseAda iAdaptor, raid *sRaid) *sRaidAdaptor {
  88. return &sRaidAdaptor{
  89. iAdaptor: baseAda,
  90. raid: raid,
  91. devs: make([]*MegaRaidPhyDev, 0),
  92. }
  93. }
  94. func (a *sRaidAdaptor) AddPhyDev(dev *MegaRaidPhyDev) {
  95. a.devs = append(a.devs, dev)
  96. }
  97. func (r *sRaid) ParsePhyDevs() error {
  98. adaptors, _, err := r.getAdaptor()
  99. r.phyDevsCnt = 0
  100. if err != nil {
  101. return errors.Wrapf(err, "Get %q adaptor", r.driver.GetName())
  102. }
  103. r.adaptors = make([]*sRaidAdaptor, 0)
  104. for _, ada := range adaptors {
  105. devs, err := ada.GetPhyDevs()
  106. if err != nil {
  107. return errors.Wrap(err, "Get %q adaptor physical devices")
  108. }
  109. nAda := newRaidAdaptor(ada, r)
  110. for i := range devs {
  111. nAda.AddPhyDev(devs[i])
  112. r.phyDevsCnt++
  113. }
  114. r.adaptors = append(r.adaptors, nAda)
  115. }
  116. return nil
  117. }
  118. func (r *sRaid) getAdaptor() ([]iAdaptor, map[string]iAdaptor, error) {
  119. ret := make(map[string]iAdaptor)
  120. cmd := r.driver.GetAdapterConstructCmd()
  121. lines, err := r.term.Run(cmd)
  122. if err != nil {
  123. return nil, nil, errors.Wrap(err, "Get storcli adapter")
  124. }
  125. adaptor := r.driver.NewAdaptor(r.term)
  126. list := make([]iAdaptor, 0)
  127. for _, l := range lines {
  128. adaptor.ParseLine(l)
  129. if adaptor.IsComplete() {
  130. ret[adaptor.Key()] = adaptor
  131. list = append(list, adaptor)
  132. adaptor = r.driver.NewAdaptor(r.term)
  133. }
  134. }
  135. return list, ret, nil
  136. }
  137. func (r *sRaid) PreBuildRaid(_ []*compute.BaremetalDiskConfig, _ int) error {
  138. return r.driver.ClearForeignState(r.term)
  139. }
  140. func (r *sRaid) GetAdapters() []raid.IRaidAdapter {
  141. ret := make([]raid.IRaidAdapter, len(r.adaptors))
  142. for i := range r.adaptors {
  143. ret[i] = r.adaptors[i]
  144. }
  145. return ret
  146. }
  147. func (r *sRaidAdaptor) PreBuildRaid(_ []*compute.BaremetalDiskConfig) error {
  148. r.ClearJBODDisks()
  149. return nil
  150. }
  151. func (r *sRaidAdaptor) PostBuildRaid() error {
  152. return nil
  153. }
  154. func (r *sRaidAdaptor) ClearJBODDisks() {
  155. r.iAdaptor.ClearJBODDisks(r.devs)
  156. }
  157. func (r *sRaidAdaptor) GetDevices() []*baremetal.BaremetalStorage {
  158. ret := []*baremetal.BaremetalStorage{}
  159. for idx, dev := range r.devs {
  160. ret = append(ret, dev.ToBaremetalStorage(idx))
  161. }
  162. return ret
  163. }
  164. func (r *sRaid) CleanRaid() error {
  165. for _, ada := range r.adaptors {
  166. ada.ClearJBODDisks()
  167. ada.RemoveLogicVolumes()
  168. }
  169. return nil
  170. }