fix: glance image convert consume too much IO, use ionice -c idle to

reduce its IO impact
This commit is contained in:
Qiu Jian
2019-03-05 02:29:27 +08:00
parent 6e5aa39836
commit 068ad7b141
2 changed files with 36 additions and 10 deletions
+5 -2
View File
@@ -533,7 +533,10 @@ func (self *SImage) CustomizeDelete(ctx context.Context, userCred mcclient.Token
overridePendingDelete = jsonutils.QueryBoolean(query, "override_pending_delete", false)
purge = jsonutils.QueryBoolean(query, "purge", false)
}
if self.Status != IMAGE_STATUS_ACTIVE && self.Status != IMAGE_STATUS_CONVERTING {
if utils.IsInStringArray(self.Status, []string{
IMAGE_STATUS_KILLED,
IMAGE_STATUS_QUEUED,
}) {
overridePendingDelete = true
}
return self.startDeleteImageTask(ctx, userCred, "", purge, overridePendingDelete)
@@ -868,7 +871,7 @@ func (self *SImage) getLocalLocation() string {
}
func (self *SImage) getQemuImage() (*qemuimg.SQemuImage, error) {
return qemuimg.NewQemuImage(self.getLocalLocation())
return qemuimg.NewQemuImageWithIOLevel(self.getLocalLocation(), qemuimg.IONiceIdle)
}
func (self *SImage) StopTorrents() {
+31 -8
View File
@@ -23,6 +23,16 @@ var (
ErrUnsupportedFormat = errors.New("unsupported format")
)
type TIONiceLevel int
const (
// The scheduling class. 0 for none, 1 for real time, 2 for best-effort, 3 for idle.
IONiceNone = TIONiceLevel(0)
IONiceRealTime = TIONiceLevel(1)
IONiceBestEffort = TIONiceLevel(2)
IONiceIdle = TIONiceLevel(3)
)
type SQemuImage struct {
Path string
Password string
@@ -34,14 +44,23 @@ type SQemuImage struct {
Compat string
Encryption bool
Subformat string
IoLevel TIONiceLevel
}
func NewQemuImage(path string) (*SQemuImage, error) {
return NewEncryptedQemuImage(path, "")
}
func NewQemuImageWithIOLevel(path string, ioLevel TIONiceLevel) (*SQemuImage, error) {
return NewEncryptedQemuImageWithIOLevel(path, "", IONiceNone)
}
func NewEncryptedQemuImage(path string, password string) (*SQemuImage, error) {
qemuImg := SQemuImage{Path: path, Password: password}
return NewEncryptedQemuImageWithIOLevel(path, password, IONiceNone)
}
func NewEncryptedQemuImageWithIOLevel(path string, password string, ioLevel TIONiceLevel) (*SQemuImage, error) {
qemuImg := SQemuImage{Path: path, Password: password, IoLevel: ioLevel}
err := qemuImg.parse()
if err != nil {
return nil, err
@@ -154,7 +173,8 @@ func (img *SQemuImage) doConvert(name string, format TImageFormat, options []str
if !img.IsValid() {
return fmt.Errorf("self is not valid")
}
cmdline := []string{"convert"}
cmdline := []string{"-c", strconv.Itoa(int(img.IoLevel)),
qemutils.GetQemuImg(), "convert"}
if compact {
cmdline = append(cmdline, "-c")
}
@@ -170,7 +190,7 @@ func (img *SQemuImage) doConvert(name string, format TImageFormat, options []str
}
cmdline = append(cmdline, img.Path, name)
log.Infof("XXXX qemu-img command: %s", cmdline)
cmd := exec.Command(qemutils.GetQemuImg(), cmdline...)
cmd := exec.Command("ionice", cmdline...)
if len(img.Password) > 0 || len(password) > 0 {
input := ""
if len(img.Password) > 0 {
@@ -335,7 +355,8 @@ func (img *SQemuImage) create(sizeMB int, format TImageFormat, options []string)
if img.IsValid() {
return fmt.Errorf("create: the image is valid??? %s", img.Format)
}
args := []string{"create", "-f", format.String()}
args := []string{"-c", strconv.Itoa(int(img.IoLevel)),
qemutils.GetQemuImg(), "create", "-f", format.String()}
if len(options) > 0 {
args = append(args, "-o", strings.Join(options, ","))
}
@@ -343,7 +364,7 @@ func (img *SQemuImage) create(sizeMB int, format TImageFormat, options []string)
if sizeMB > 0 {
args = append(args, fmt.Sprintf("%dM", sizeMB))
}
cmd := exec.Command(qemutils.GetQemuImg(), args...)
cmd := exec.Command("ionice", args...)
err := cmd.Run()
if err != nil {
log.Errorf("create error %s", err)
@@ -390,7 +411,8 @@ func (img *SQemuImage) Resize(sizeMB int) error {
if !img.IsValid() {
return fmt.Errorf("self is not valid")
}
cmd := exec.Command(qemutils.GetQemuImg(), "resize", img.Path, fmt.Sprintf("%dM", sizeMB))
cmd := exec.Command("ionice", "-c", strconv.Itoa(int(img.IoLevel)),
qemutils.GetQemuImg(), "resize", img.Path, fmt.Sprintf("%dM", sizeMB))
err := cmd.Run()
if err != nil {
log.Errorf("resize fail %s", err)
@@ -403,12 +425,13 @@ func (img *SQemuImage) Rebase(backPath string, force bool) error {
if !img.IsValid() {
return fmt.Errorf("self is not valid")
}
args := []string{"rebase"}
args := []string{"-c", strconv.Itoa(int(img.IoLevel)),
qemutils.GetQemuImg(), "rebase"}
if force {
args = append(args, "-u")
}
args = append(args, "-b", backPath, img.Path)
cmd := exec.Command(qemutils.GetQemuImg(), args...)
cmd := exec.Command("ionice", args...)
err := cmd.Run()
if err != nil {
log.Errorf("rebase fail %s", err)