diff --git a/cmd/climc/shell/compute/serverdisks.go b/cmd/climc/shell/compute/serverdisks.go index 41152b84e6..b318726440 100644 --- a/cmd/climc/shell/compute/serverdisks.go +++ b/cmd/climc/shell/compute/serverdisks.go @@ -77,18 +77,10 @@ func init() { type ServerDiskUpdateOptions struct { SERVER string `help:"ID or Name of server"` DISK string `help:"ID or Name of Disk"` - Cache string `help:"Cache mode of vDisk" choices:"writethrough|none|writeback|directsync"` - Aio string `help:"Asynchronous IO mode of vDisk" choices:"native|threads"` Index int64 `help:"Index of vDisk" default:"-1"` } R(&ServerDiskUpdateOptions{}, "server-disk-update", "Update details of a virtual disk of a virtual server", func(s *mcclient.ClientSession, args *ServerDiskUpdateOptions) error { params := jsonutils.NewDict() - if len(args.Cache) > 0 { - params.Add(jsonutils.NewString(args.Cache), "cache_mode") - } - if len(args.Aio) > 0 { - params.Add(jsonutils.NewString(args.Aio), "aio_mode") - } if args.Index >= 0 { params.Add(jsonutils.NewInt(args.Index), "index") } diff --git a/pkg/apis/compute/disk_const.go b/pkg/apis/compute/disk_const.go index 684b6097d4..f9d4d5ba6d 100644 --- a/pkg/apis/compute/disk_const.go +++ b/pkg/apis/compute/disk_const.go @@ -97,3 +97,15 @@ const ( DISK_DRIVER_SATA = "sata" DISK_DRIVER_VFIO = "vfio-pci" ) + +const ( + DISK_CACHE_MODE_WRITETHROGH = "writethrough" + DISK_CACHE_MODE_NONE = "none" + DISK_CACHE_MODE_WRITEBACK = "writeback" + DISK_CACHE_MODE_DIRECTSYNC = "directsync" +) + +const ( + DISK_AIO_MODE_NATIVE = "native" + DISK_AIO_MOD_THREADS = "threads" +) diff --git a/pkg/apis/compute/guest_disk.go b/pkg/apis/compute/guest_disk.go index ae555f7af3..8f1740b6a0 100644 --- a/pkg/apis/compute/guest_disk.go +++ b/pkg/apis/compute/guest_disk.go @@ -56,11 +56,11 @@ type GuestdiskListInput struct { type GuestdiskUpdateInput struct { GuestJointBaseUpdateInput - Driver string `json:"driver"` - - CacheMode string `json:"cache_mode"` - - AioMode string `json:"aio_mode"` + //Driver string `json:"driver"` + // + //CacheMode string `json:"cache_mode"` + // + //AioMode string `json:"aio_mode"` Iops *int `json:"iops"` diff --git a/pkg/apis/compute/guests.go b/pkg/apis/compute/guests.go index 78d71b8266..b9b72e4115 100644 --- a/pkg/apis/compute/guests.go +++ b/pkg/apis/compute/guests.go @@ -1066,8 +1066,10 @@ type ServerChangeDiskStorageInput struct { } type ServerChangeDiskDriverInput struct { - DiskId string `json:"disk_id"` - Driver string `json:"driver"` + DiskId string `json:"disk_id"` + Driver string `json:"driver"` + CacheMode string `json:"cache_mode"` + AioMode string `json:"aio_mode"` } type ServerChangeDiskStorageInternalInput struct { diff --git a/pkg/compute/models/guest_actions.go b/pkg/compute/models/guest_actions.go index 52b882248f..715d76eaf1 100644 --- a/pkg/compute/models/guest_actions.go +++ b/pkg/compute/models/guest_actions.go @@ -6663,20 +6663,52 @@ func (self *SGuest) PerformChangeDiskDriver(ctx context.Context, userCred mcclie if gd == nil { return nil, httperrors.NewBadRequestError("failed get guest disk by disk id %s", input.DiskId) } - if input.Driver == gd.Driver { - return nil, nil + var driverChanged = false + if input.Driver != "" { + if input.Driver != gd.Driver { + driverChanged = true + } + if !utils.IsInStringArray(input.Driver, []string{api.DISK_DRIVER_VIRTIO, api.DISK_DRIVER_PVSCSI, api.DISK_DRIVER_IDE, api.DISK_DRIVER_SCSI}) { + return nil, httperrors.NewInputParameterError("unknown driver %s", input.Driver) + } } - if !utils.IsInStringArray(input.Driver, []string{api.DISK_DRIVER_VIRTIO, api.DISK_DRIVER_PVSCSI, api.DISK_DRIVER_IDE, api.DISK_DRIVER_SCSI}) { - return nil, httperrors.NewInputParameterError("unknown driver %s", input.Driver) + if input.CacheMode != "" && gd.CacheMode != input.CacheMode { + if input.CacheMode != "none" { + input.AioMode = "threads" + } + if !utils.IsInStringArray(input.CacheMode, []string{api.DISK_CACHE_MODE_WRITETHROGH, api.DISK_CACHE_MODE_DIRECTSYNC, api.DISK_CACHE_MODE_WRITEBACK, api.DISK_CACHE_MODE_NONE}) { + return nil, httperrors.NewInputParameterError("unknown cache_mode %s", input.CacheMode) + } } + if input.AioMode != "" && gd.AioMode != input.AioMode { + if !utils.IsInStringArray(input.AioMode, []string{api.DISK_AIO_MODE_NATIVE, api.DISK_AIO_MOD_THREADS}) { + return nil, httperrors.NewInputParameterError("unknown aio_mode %s", input.AioMode) + } + cacheMode := gd.CacheMode + if input.CacheMode != "" { + cacheMode = input.CacheMode + } + if input.AioMode == "native" && cacheMode != "none" { + return nil, httperrors.NewBadRequestError("AIO mode %s with cache mode %s is not supported", input.AioMode, cacheMode) + } + } + _, err := db.Update(gd, func() error { - gd.Driver = input.Driver + if input.Driver != "" { + gd.Driver = input.Driver + } + if input.AioMode != "" { + gd.AioMode = input.AioMode + } + if input.CacheMode != "" { + gd.CacheMode = input.CacheMode + } return nil }) if err != nil { return nil, errors.Wrap(err, "failed update disk driver") } - if self.Bios == api.VM_BOOT_MODE_UEFI { + if driverChanged && self.Bios == api.VM_BOOT_MODE_UEFI { drv, err := self.GetDriver() if err != nil { return nil, err diff --git a/pkg/compute/models/guestdisks.go b/pkg/compute/models/guestdisks.go index 9f3d98755a..f34e461498 100644 --- a/pkg/compute/models/guestdisks.go +++ b/pkg/compute/models/guestdisks.go @@ -65,9 +65,9 @@ type SGuestdisk struct { ImagePath string `width:"256" charset:"ascii" nullable:"false" get:"user" create:"required"` // Column(VARCHAR(256, charset='ascii'), nullable=False) - Driver string `width:"32" charset:"ascii" nullable:"true" list:"user"` // Column(VARCHAR(32, charset='ascii'), nullable=True) - CacheMode string `width:"32" charset:"ascii" nullable:"true" list:"user" update:"user"` // Column(VARCHAR(32, charset='ascii'), nullable=True) - AioMode string `width:"32" charset:"ascii" nullable:"true" get:"user" update:"user"` // Column(VARCHAR(32, charset='ascii'), nullable=True) + Driver string `width:"32" charset:"ascii" nullable:"true" list:"user"` // Column(VARCHAR(32, charset='ascii'), nullable=True) + CacheMode string `width:"32" charset:"ascii" nullable:"true" list:"user"` // Column(VARCHAR(32, charset='ascii'), nullable=True) + AioMode string `width:"32" charset:"ascii" nullable:"true" get:"user"` // Column(VARCHAR(32, charset='ascii'), nullable=True) Iops int `nullable:"true" default:"0" list:"user" update:"user"` Bps int `nullable:"true" default:"0" list:"user" update:"user"` // Mb @@ -95,20 +95,6 @@ func (self *SGuestdisk) ValidateUpdateData(ctx context.Context, userCred mcclien return input, httperrors.NewInputParameterError("DISK Index %d has been occupied", index) } } - if self.CacheMode != input.CacheMode { - if input.CacheMode != "none" { - input.AioMode = "threads" - } - } - if self.AioMode != input.AioMode { - cacheMode := self.CacheMode - if input.CacheMode != "" { - cacheMode = input.CacheMode - } - if input.AioMode == "native" && cacheMode != "none" { - return input, httperrors.NewBadRequestError("AIO mode %s with cache mode %s is not supported", input.AioMode, cacheMode) - } - } var err error input.GuestJointBaseUpdateInput, err = self.SGuestJointsBase.ValidateUpdateData(ctx, userCred, query, input.GuestJointBaseUpdateInput) diff --git a/pkg/mcclient/options/compute/servers.go b/pkg/mcclient/options/compute/servers.go index bd0cb633de..cf24607d0f 100644 --- a/pkg/mcclient/options/compute/servers.go +++ b/pkg/mcclient/options/compute/servers.go @@ -1656,7 +1656,9 @@ func (o *ServerScreenDumpOptions) Params() (jsonutils.JSONObject, error) { type ServerChangeDiskDriverOptions struct { ServerIdOptions DISK_ID string - DRIVER string `help:"Driver of vDisk" choices:"virtio|ide|sata|scsi|pvscsi"` + Driver string `help:"Driver of vDisk" choices:"virtio|ide|sata|scsi|pvscsi"` + Cache string `help:"Cache mode of vDisk" choices:"writethrough|none|writeback|directsync"` + Aio string `help:"Asynchronous IO mode of vDisk" choices:"native|threads"` } func (o *ServerChangeDiskDriverOptions) Params() (jsonutils.JSONObject, error) {