diff --git a/pkg/image/models/image_subs.go b/pkg/image/models/image_subs.go index 354c64ae85..2857b4adb5 100644 --- a/pkg/image/models/image_subs.go +++ b/pkg/image/models/image_subs.go @@ -114,12 +114,12 @@ func (self *SImageSubformat) doConvert(image *SImage) error { log.Errorf("fail to convert image %s", err) return err } - err = self.SaveTorrent() - if err != nil { - log.Errorf("fail to convert image torrent %s", err) - return err - } if options.Options.EnableTorrentService { + err = self.SaveTorrent() + if err != nil { + log.Errorf("fail to convert image torrent %s", err) + return err + } err = self.seedTorrent(image.Id) if err != nil { log.Errorf("fail to seed torrent %s", err) diff --git a/pkg/util/qemuimg/qemuimg.go b/pkg/util/qemuimg/qemuimg.go index 100216b2f6..72d4786d70 100644 --- a/pkg/util/qemuimg/qemuimg.go +++ b/pkg/util/qemuimg/qemuimg.go @@ -240,6 +240,44 @@ func (info SConvertInfo) encrypted() bool { } func Convert(srcInfo, destInfo SConvertInfo, compact bool, workerOpions []string) error { + if srcInfo.Format == QCOW2 && destInfo.Format == QCOW2 { + return convertQcow2(srcInfo, destInfo, compact, workerOpions) + } else { + return convertOther(srcInfo, destInfo, compact, workerOpions) + } +} + +func convertOther(srcInfo, destInfo SConvertInfo, compact bool, workerOpions []string) error { + cmdline := []string{"-c", strconv.Itoa(int(srcInfo.IoLevel)), + qemutils.GetQemuImg(), "convert"} + if compact { + cmdline = append(cmdline, "-c") + } + if workerOpions == nil { + // https://bugzilla.redhat.com/show_bug.cgi?id=1969848 + // https://bugs.launchpad.net/qemu/+bug/1805256 + // qemu-img convert may hang on aarch64, fix: add -m 1 + cmdline = append(cmdline, "-m", "1") + } else { + cmdline = append(cmdline, workerOpions...) + } + if compact { + cmdline = append(cmdline, "-c") + } + cmdline = append(cmdline, "-f", srcInfo.Format.String(), "-O", destInfo.Format.String()) + cmdline = append(cmdline, srcInfo.Path, destInfo.Path) + log.Infof("XXXX qemu-img command: %s", cmdline) + cmd := procutils.NewRemoteCommandAsFarAsPossible("ionice", cmdline...) + output, err := cmd.Output() + if err != nil { + log.Errorf("qemu convert fail %s, output: %s", err, string(output)) + os.Remove(destInfo.Path) + return err + } + return nil +} + +func convertQcow2(srcInfo, destInfo SConvertInfo, compact bool, workerOpions []string) error { source, err := NewQemuImageWithIOLevel(srcInfo.Path, srcInfo.IoLevel) if err != nil { return errors.Wrapf(err, "NewQemuImage source %s", srcInfo.Path)