local_driver.go 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  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 qemu_kvm
  15. import (
  16. "fmt"
  17. "strings"
  18. "time"
  19. "yunion.io/x/log"
  20. "yunion.io/x/pkg/errors"
  21. "yunion.io/x/onecloud/pkg/hostman/diskutils/fsutils"
  22. "yunion.io/x/onecloud/pkg/hostman/diskutils/fsutils/driver"
  23. "yunion.io/x/onecloud/pkg/hostman/guestfs/fsdriver"
  24. "yunion.io/x/onecloud/pkg/hostman/guestfs/kvmpart"
  25. "yunion.io/x/onecloud/pkg/hostman/hostdeployer/apis"
  26. "yunion.io/x/onecloud/pkg/util/procutils"
  27. "yunion.io/x/onecloud/pkg/util/stringutils2"
  28. )
  29. type LocalDiskDriver struct {
  30. partitions []fsdriver.IDiskPartition
  31. lvmPartitions []fsdriver.IDiskPartition
  32. }
  33. func NewLocalDiskDriver() *LocalDiskDriver {
  34. return &LocalDiskDriver{
  35. partitions: make([]fsdriver.IDiskPartition, 0),
  36. lvmPartitions: make([]fsdriver.IDiskPartition, 0),
  37. }
  38. }
  39. func (d *LocalDiskDriver) Connect(desc *apis.GuestDesc, diskId string) error {
  40. out, err := procutils.NewCommand("sh", "-c", "cat /proc/partitions | grep -v name | awk '{print $4}'").Output()
  41. if err != nil {
  42. return errors.Wrap(err, "cat proc partitions")
  43. }
  44. lines := strings.Split(string(out), "\n")
  45. partDevs := make([]string, 0)
  46. for _, line := range lines {
  47. line = strings.TrimSpace(line)
  48. if strings.HasPrefix(line, "sd") {
  49. partDevs = append(partDevs, line)
  50. }
  51. }
  52. sortPartDevs := stringutils2.NewSortedStrings(partDevs)
  53. for _, partDev := range sortPartDevs {
  54. part := kvmpart.NewKVMGuestDiskPartition(fmt.Sprintf("/dev/%s", partDev), "", false)
  55. d.partitions = append(d.partitions, part)
  56. log.Infof("found part dev %s", part.GetPartDev())
  57. }
  58. d.setupLVMS()
  59. if len(d.lvmPartitions) > 0 {
  60. d.partitions = append(d.partitions, d.lvmPartitions...)
  61. }
  62. return nil
  63. }
  64. func (d *LocalDiskDriver) Disconnect() error {
  65. return nil
  66. }
  67. func (d *LocalDiskDriver) GetPartitions() []fsdriver.IDiskPartition {
  68. return d.partitions
  69. }
  70. func (d *LocalDiskDriver) IsLVMPartition() bool {
  71. return len(d.lvmPartitions) > 0
  72. }
  73. func (d *LocalDiskDriver) Zerofree() {
  74. startTime := time.Now()
  75. for _, part := range d.partitions {
  76. part.Zerofree()
  77. }
  78. log.Infof("Zerofree %d partitions takes %f seconds", len(d.partitions), time.Now().Sub(startTime).Seconds())
  79. }
  80. func (d *LocalDiskDriver) ResizePartition(diskId string, rootPartDev string) error {
  81. fsutilDriver := fsutils.NewFsutilDriver(driver.NewProcDriver())
  82. log.Infof("ResizePartition disk id %s", diskId)
  83. if len(diskId) > 0 {
  84. return fsutilDriver.ResizeDiskWithDiskId(diskId, rootPartDev, false)
  85. }
  86. return fsutilDriver.ResizeDiskFs("/dev/sda", 0, false)
  87. }
  88. func (d *LocalDiskDriver) FormatPartition(fs, uuid string, features *apis.FsFeatures) error {
  89. return fsutils.FormatPartition("/dev/sda1", fs, uuid, features)
  90. }
  91. func (d *LocalDiskDriver) MakePartition(fs string) error {
  92. return fsutils.Mkpartition("/dev/sda", fs)
  93. }
  94. func (d *LocalDiskDriver) DetectIsUEFISupport(rootfs fsdriver.IRootFsDriver) bool {
  95. return fsutils.DetectIsUEFISupport(rootfs, d.GetPartitions())
  96. }
  97. func (d *LocalDiskDriver) DetectIsBIOSSupport(rootfs fsdriver.IRootFsDriver) bool {
  98. return fsutils.DetectIsBIOSSupport("/dev/sda", rootfs)
  99. }
  100. func (d *LocalDiskDriver) MountRootfs(readonly bool) (fsdriver.IRootFsDriver, error) {
  101. return fsutils.MountRootfs(readonly, d.GetPartitions())
  102. }
  103. func (d *LocalDiskDriver) UmountRootfs(fd fsdriver.IRootFsDriver) error {
  104. if part := fd.GetPartition(); part != nil {
  105. return part.Umount()
  106. }
  107. return nil
  108. }
  109. func (d *LocalDiskDriver) DeployGuestfs(req *apis.DeployParams) (res *apis.DeployGuestFsResponse, err error) {
  110. return fsutils.DeployGuestfs(d, req)
  111. }
  112. func (d *LocalDiskDriver) ResizeFs(req *apis.ResizeFsParams) (*apis.Empty, error) {
  113. var diskId string
  114. if req.DiskInfo != nil {
  115. diskId = req.DiskInfo.DiskId
  116. }
  117. return fsutils.ResizeFs(d, diskId)
  118. }
  119. func (d *LocalDiskDriver) SaveToGlance(req *apis.SaveToGlanceParams) (*apis.SaveToGlanceResponse, error) {
  120. return fsutils.SaveToGlance(d, req)
  121. }
  122. func (d *LocalDiskDriver) FormatFs(req *apis.FormatFsParams) (*apis.Empty, error) {
  123. return fsutils.FormatFs(d, req)
  124. }
  125. func (d *LocalDiskDriver) ProbeImageInfo(req *apis.ProbeImageInfoPramas) (*apis.ImageInfo, error) {
  126. return fsutils.ProbeImageInfo(d)
  127. }
  128. func (d *LocalDiskDriver) setupLVMS() {
  129. fsutilDriver := fsutils.NewFsutilDriver(driver.NewProcDriver())
  130. for _, part := range d.partitions {
  131. vg, err := fsutils.FindVg(part.GetPartDev())
  132. if err != nil {
  133. log.Infof("failed find vg %s", err)
  134. continue
  135. }
  136. if vg == nil {
  137. continue
  138. }
  139. log.Infof("found vg %s from %s", vg.VgName, part.GetPartDev())
  140. err = fsutils.VgActive(vg.VgName)
  141. if err != nil {
  142. log.Infof("failed active vg %s: %s", vg.VgName, err)
  143. continue
  144. }
  145. lvs, err := fsutilDriver.GetVgLvs(vg.VgName)
  146. if err != nil {
  147. log.Infof("failed get vg lvs %s: %s", vg.VgName, err)
  148. continue
  149. }
  150. log.Infof("found lvs %v from vg %s", lvs, vg.VgName)
  151. for _, lv := range lvs {
  152. lvmpart := kvmpart.NewKVMGuestDiskPartition(lv.LvPath, "", true)
  153. d.lvmPartitions = append(d.lvmPartitions, lvmpart)
  154. log.Infof("found lvm part dev %v", lvmpart.GetPartDev())
  155. }
  156. }
  157. }