feat(region,host,host-deployer): container disk support resize (#21398)

This commit is contained in:
wanyaoqi
2024-10-12 09:58:28 +08:00
committed by GitHub
parent ce050ca562
commit 00b9afcbce
12 changed files with 113 additions and 35 deletions
+8 -5
View File
@@ -635,12 +635,15 @@ func (self *SKVMGuestDriver) GetDeployStatus() ([]string, error) {
}
func (self *SKVMGuestDriver) ValidateResizeDisk(guest *models.SGuest, disk *models.SDisk, storage *models.SStorage) error {
if guest.GetDiskIndex(disk.Id) <= 0 && guest.Status == api.VM_RUNNING {
return fmt.Errorf("Cann't online resize root disk")
}
if guest.Status == api.VM_RUNNING && storage.StorageType == api.STORAGE_SLVM {
return fmt.Errorf("shared lvm storage cann't online resize")
if guest.Hypervisor == api.HYPERVISOR_KVM {
if guest.GetDiskIndex(disk.Id) <= 0 && guest.Status == api.VM_RUNNING {
return fmt.Errorf("Cann't online resize root disk")
}
if guest.Status == api.VM_RUNNING && storage.StorageType == api.STORAGE_SLVM {
return fmt.Errorf("shared lvm storage cann't online resize")
}
}
if !utils.IsInStringArray(guest.Status, []string{api.VM_READY, api.VM_RUNNING}) {
return fmt.Errorf("Cannot resize disk when guest in status %s", guest.Status)
}
+23 -21
View File
@@ -131,7 +131,7 @@ func GetDevSector512Count(dev string) int {
return size
}
func ResizeDiskFs(diskPath string, sizeMb int) error {
func ResizeDiskFs(diskPath string, sizeMb int, mounted bool) error {
var cmds = []string{"parted", "-a", "none", "-s", diskPath, "--", "unit", "s", "print"}
lines, err := procutils.NewCommand(cmds[0], cmds[1:]...).Output()
if err != nil {
@@ -205,7 +205,7 @@ func ResizeDiskFs(diskPath string, sizeMb int) error {
if err != nil {
return errors.Wrapf(err, "growpart failed %s", output)
}
err, _ = ResizePartitionFs(part[7], part[6], false)
err, _ = ResizePartitionFs(part[7], part[6], false, mounted)
if err != nil {
return errors.Wrapf(err, "resize fs %s", part[6])
}
@@ -225,7 +225,7 @@ func IsSupportResizeFs(fs string) bool {
return false
}
func ResizePartitionFs(fpath, fs string, raiseError bool) (error, bool) {
func ResizePartitionFs(fpath, fs string, raiseError, mounted bool) (error, bool) {
if len(fs) == 0 {
return nil, false
}
@@ -240,13 +240,16 @@ func ResizePartitionFs(fpath, fs string, raiseError bool) (error, bool) {
cmds = [][]string{{"mkswap", fpath}}
}
} else if strings.HasPrefix(fs, "ext") {
if !FsckExtFs(fpath) {
if raiseError {
return fmt.Errorf("Failed to fsck ext fs %s", fpath), false
} else {
return nil, false
if !mounted {
if !FsckExtFs(fpath) {
if raiseError {
return fmt.Errorf("Failed to fsck ext fs %s", fpath), false
} else {
return nil, false
}
}
}
cmds = [][]string{{"resize2fs", fpath}}
} else if fs == "xfs" {
var tmpPoint = fmt.Sprintf("/tmp/%s", strings.Replace(fpath, "/", "_", -1))
@@ -297,23 +300,22 @@ func ResizePartitionFs(fpath, fs string, raiseError bool) (error, bool) {
func FsckExtFs(fpath string) bool {
log.Debugf("Exec command: %v", []string{"e2fsck", "-f", "-p", fpath})
cmd := procutils.NewCommand("e2fsck", "-f", "-p", fpath)
if err := cmd.Start(); err != nil {
log.Errorf("e2fsck start failed: %s", err)
return false
} else {
err = cmd.Wait()
if err != nil {
if status, ok := cmd.GetExitStatus(err); ok {
if status < 4 {
return true
}
out, err := cmd.Output()
if err != nil {
log.Errorf("e2fsck failed %s: %s", err, out)
if status, ok := cmd.GetExitStatus(err); ok {
log.Errorf("e2fsck exit status %d", status)
if status < 4 {
return true
} else {
return false
}
log.Errorln(err)
return false
} else {
return true
return false
}
}
return true
}
// https://bugs.launchpad.net/ubuntu/+source/xfsprogs/+bug/1718244
+1 -1
View File
@@ -214,7 +214,7 @@ func (d *SLibguestfsDriver) ResizePartition() error {
// do not try to resize LVM partition
return nil
}
return fsutils.ResizeDiskFs(d.nbddev, 0)
return fsutils.ResizeDiskFs(d.nbddev, 0, false)
}
func (d *SLibguestfsDriver) FormatPartition(fs, uuid string) error {
+1 -1
View File
@@ -248,7 +248,7 @@ func (d *NBDDriver) ResizePartition() error {
// do not resize LVM partition
return nil
}
return fsutils.ResizeDiskFs(d.nbdDev, 0)
return fsutils.ResizeDiskFs(d.nbdDev, 0, false)
}
func (d *NBDDriver) Zerofree() {
@@ -93,7 +93,7 @@ func (d *LocalDiskDriver) ResizePartition() error {
// do not resize LVM partition
return nil
}
return fsutils.ResizeDiskFs("/dev/sda", 0)
return fsutils.ResizeDiskFs("/dev/sda", 0, false)
}
func (d *LocalDiskDriver) FormatPartition(fs, uuid string) error {
+2 -2
View File
@@ -1443,12 +1443,12 @@ func (m *SGuestManager) Resume(ctx context.Context, sid string, isLiveMigrate bo
}
func (m *SGuestManager) OnlineResizeDisk(ctx context.Context, sid string, disk storageman.IDisk, sizeMb int64) (jsonutils.JSONObject, error) {
guest, ok := m.GetKVMServer(sid)
guest, ok := m.GetServer(sid)
if !ok {
return nil, httperrors.NewNotFoundError("guest %s not found", sid)
}
if guest.IsRunning() {
guest.onlineResizeDisk(ctx, disk, sizeMb)
guest.OnlineResizeDisk(ctx, disk, sizeMb)
return nil, nil
} else {
return nil, httperrors.NewInvalidStatusError("guest is not runnign")
+36
View File
@@ -2190,6 +2190,42 @@ func (s *sPodGuestInstance) DeleteSnapshot(ctx context.Context, params *SDeleteD
return res, nil
}
func (s *sPodGuestInstance) doOnlineResizeDisk(ctx context.Context, disk storageman.IDisk, sizeMB int64) {
drv, err := disk.GetContainerStorageDriver()
if err != nil {
hostutils.TaskFailed(ctx, fmt.Sprintf("get disk storage driver %s", err))
return
}
partDev, found, err := drv.CheckConnect(disk.GetPath())
if err != nil {
hostutils.TaskFailed(ctx, fmt.Sprintf("disk check connect %s", err))
return
}
if !found {
hostutils.TaskFailed(ctx, fmt.Sprintf("online resize but loop device not connected"))
return
}
if err := disk.PreResize(ctx, sizeMB); err != nil {
hostutils.TaskFailed(ctx, fmt.Sprintf("PreResize failed %s", err))
return
}
params := jsonutils.NewDict()
params.Set("size", jsonutils.NewInt(sizeMB))
params.Set("loop_part_dev", jsonutils.NewString(partDev))
res, err := disk.Resize(ctx, params)
if err != nil {
hostutils.TaskFailed(ctx, fmt.Sprintf("PreResize failed %s", err))
return
}
hostutils.TaskComplete(ctx, res)
}
func (s *sPodGuestInstance) OnlineResizeDisk(ctx context.Context, disk storageman.IDisk, sizeMB int64) {
go s.doOnlineResizeDisk(ctx, disk, sizeMB)
}
func (s *sPodGuestInstance) ContainerExecSync(ctx context.Context, userCred mcclient.TokenCredential, ctrId string, input *computeapi.ContainerExecSyncInput) (jsonutils.JSONObject, error) {
ctrCriId, err := s.getContainerCRIId(ctrId)
if err != nil {
+1 -1
View File
@@ -3278,7 +3278,7 @@ func (s *SKVMGuestInstance) prepareNicsForVolatileGuestResume() error {
return nil
}
func (s *SKVMGuestInstance) onlineResizeDisk(ctx context.Context, disk storageman.IDisk, sizeMB int64) {
func (s *SKVMGuestInstance) OnlineResizeDisk(ctx context.Context, disk storageman.IDisk, sizeMB int64) {
task := NewGuestOnlineResizeDiskTask(ctx, s, disk, sizeMB)
task.Start()
}
+2
View File
@@ -28,6 +28,7 @@ import (
"yunion.io/x/onecloud/pkg/hostman/guestman/desc"
deployapi "yunion.io/x/onecloud/pkg/hostman/hostdeployer/apis"
"yunion.io/x/onecloud/pkg/hostman/options"
"yunion.io/x/onecloud/pkg/hostman/storageman"
"yunion.io/x/onecloud/pkg/mcclient"
"yunion.io/x/onecloud/pkg/util/cgrouputils/cpuset"
"yunion.io/x/onecloud/pkg/util/fileutils2"
@@ -70,6 +71,7 @@ type GuestRuntimeInstance interface {
SyncConfig(ctx context.Context, guestDesc *desc.SGuestDesc, fwOnly bool) (jsonutils.JSONObject, error)
DoSnapshot(ctx context.Context, params *SDiskSnapshot) (jsonutils.JSONObject, error)
DeleteSnapshot(ctx context.Context, params *SDeleteDiskSnapshot) (jsonutils.JSONObject, error)
OnlineResizeDisk(ctx context.Context, disk storageman.IDisk, sizeMB int64)
}
type sBaseGuestInstance struct {
@@ -129,6 +129,15 @@ func (*DeployerServer) ResizeFs(ctx context.Context, req *deployapi.ResizeFsPara
}
}()
log.Infof("********* Resize fs on %#v", apiDiskInfo(req.DiskInfo))
if strings.HasPrefix(req.DiskInfo.Path, "/dev/loop") {
// HACK: container loop device, do resize locally
if err := fsutils.ResizeDiskFs(req.DiskInfo.Path, 0, true); err != nil {
return new(deployapi.Empty), errors.Wrap(err, "fsutils.ResizeDiskFs")
}
return new(deployapi.Empty), nil
}
disk, err := diskutils.GetIDisk(diskutils.DiskParams{
Hypervisor: req.Hypervisor,
DiskInfo: apiDiskInfo(req.GetDiskInfo()),
+24 -3
View File
@@ -41,6 +41,7 @@ import (
"yunion.io/x/onecloud/pkg/mcclient/auth"
"yunion.io/x/onecloud/pkg/util/fileutils2"
"yunion.io/x/onecloud/pkg/util/fuseutils"
"yunion.io/x/onecloud/pkg/util/losetup"
"yunion.io/x/onecloud/pkg/util/procutils"
"yunion.io/x/onecloud/pkg/util/qemuimg"
"yunion.io/x/onecloud/pkg/util/seclib2"
@@ -155,6 +156,15 @@ func (d *SLocalDisk) OnRebuildRoot(ctx context.Context, params api.DiskAllocateI
return err
}
func (d *SLocalDisk) ResizeLoopDevice(partDev string) (string, error) {
loopDevice := strings.TrimSuffix(partDev, "p1")
err := losetup.ResizeLoopDevice(loopDevice)
if err != nil {
return "", errors.Wrap(err, "ResizeLoopDevice")
}
return loopDevice, nil
}
func (d *SLocalDisk) Resize(ctx context.Context, params interface{}) (jsonutils.JSONObject, error) {
diskInfo, ok := params.(*jsonutils.JSONDict)
if !ok {
@@ -170,6 +180,7 @@ func (d *SLocalDisk) Resize(ctx context.Context, params interface{}) (jsonutils.
resizeFsInfo := &deployapi.DiskInfo{
Path: d.GetPath(),
}
if diskInfo.Contains("encrypt_info") {
var encryptInfo apis.SEncryptInfo
err := diskInfo.Unmarshal(&encryptInfo, "encrypt_info")
@@ -187,10 +198,20 @@ func (d *SLocalDisk) Resize(ctx context.Context, params interface{}) (jsonutils.
return nil, err
}
}
if options.HostOptions.EnableFallocateDisk {
err := d.fallocate()
if diskInfo.Contains("loop_part_dev") {
partDev, _ := diskInfo.GetString("loop_part_dev")
loopDev, err := d.ResizeLoopDevice(partDev)
if err != nil {
log.Errorf("fallocate fail %s", err)
return nil, err
}
resizeFsInfo.Path = loopDev
} else {
if options.HostOptions.EnableFallocateDisk {
err := d.fallocate()
if err != nil {
log.Errorf("fallocate fail %s", err)
}
}
}
+5
View File
@@ -207,3 +207,8 @@ func DetachDeviceByFile(filePath string) error {
_, err = NewLosetupCommand().AddArgs("-d", dev.Name).Run()
return err
}
func ResizeLoopDevice(loopDev string) error {
_, err := NewLosetupCommand().AddArgs("-c", loopDev).Run()
return err
}