From d9a2c291b554922b95001e7aca5052915d3dc549 Mon Sep 17 00:00:00 2001 From: Qiu Jian Date: Wed, 26 Jan 2022 13:45:10 +0800 Subject: [PATCH] fix: support qemu 4.2.0 --- pkg/hostman/diskutils/nbd/driver.go | 22 +++++++++ pkg/hostman/guestman/qemu/qemu.go | 1 + pkg/hostman/guestman/qemu/v4_2_0.go | 70 +++++++++++++++++++++++++++++ 3 files changed, 93 insertions(+) create mode 100644 pkg/hostman/guestman/qemu/v4_2_0.go diff --git a/pkg/hostman/diskutils/nbd/driver.go b/pkg/hostman/diskutils/nbd/driver.go index 40ad198627..6044e451f1 100644 --- a/pkg/hostman/diskutils/nbd/driver.go +++ b/pkg/hostman/diskutils/nbd/driver.go @@ -32,6 +32,7 @@ import ( "yunion.io/x/onecloud/pkg/util/procutils" "yunion.io/x/onecloud/pkg/util/qemuimg" "yunion.io/x/onecloud/pkg/util/qemutils" + "yunion.io/x/onecloud/pkg/util/version" ) const MAX_TRIES = 3 @@ -271,7 +272,25 @@ func (d *NBDDriver) IsLVMPartition() bool { return len(d.lvms) > 0 } +func getQemuNbdVersion() (string, error) { + output, err := procutils.NewRemoteCommandAsFarAsPossible(qemutils.GetQemuNbd(), "--version").Output() + if err != nil { + log.Errorf("qemu-nbd version failed %s %s", output, err.Error()) + return "", errors.Wrapf(err, "qemu-nbd version failed %s", output) + } + lines := strings.Split(strings.TrimSpace(string(output)), "\n") + if len(lines) > 0 { + parts := strings.Split(lines[0], " ") + return parts[1], nil + } + return "", errors.Error("empty version output") +} + func QemuNbdConnect(imagePath, nbddev string) error { + nbdVer, err := getQemuNbdVersion() + if err != nil { + return errors.Wrap(err, "getQemuNbdVersion") + } var cmd []string if strings.HasPrefix(imagePath, "rbd:") || getImageFormat(imagePath) == "raw" { //qemu-nbd 连接ceph时 /etc/ceph/ceph.conf 必须存在 @@ -294,6 +313,9 @@ func QemuNbdConnect(imagePath, nbddev string) error { } else { cmd = []string{qemutils.GetQemuNbd(), "-c", nbddev, imagePath} } + if version.GE(nbdVer, "4.0.0") { + cmd = append(cmd, "--fork") + } output, err := procutils.NewRemoteCommandAsFarAsPossible(cmd[0], cmd[1:]...).Output() if err != nil { log.Errorf("qemu-nbd connect failed %s %s", output, err.Error()) diff --git a/pkg/hostman/guestman/qemu/qemu.go b/pkg/hostman/guestman/qemu/qemu.go index 7dde6ed8f9..f7238923cc 100644 --- a/pkg/hostman/guestman/qemu/qemu.go +++ b/pkg/hostman/guestman/qemu/qemu.go @@ -28,6 +28,7 @@ import ( type Version string const ( + Version_4_2_0 Version = "4.2.0" Version_4_0_1 Version = "4.0.1" Version_2_12_1 Version = "2.12.1" ) diff --git a/pkg/hostman/guestman/qemu/v4_2_0.go b/pkg/hostman/guestman/qemu/v4_2_0.go new file mode 100644 index 0000000000..e4577bf411 --- /dev/null +++ b/pkg/hostman/guestman/qemu/v4_2_0.go @@ -0,0 +1,70 @@ +// Copyright 2019 Yunion +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package qemu + +func init() { + RegisterCmd( + newCmd_4_2_0_x86_64(), + newCmd_4_2_0_aarch64(), + ) +} + +func newCmd_4_2_0_x86_64() QemuCommand { + return newBaseCommand( + Version_4_2_0, + Arch_x86_64, + newOpt_4_2_0_x86_64()) +} + +type opt_420_x86_64 struct { + *baseOptions_x86_64 +} + +func newOpt_4_2_0_x86_64() QemuOptions { + return &opt_420_x86_64{ + baseOptions_x86_64: newBaseOptions_x86_64(), + } +} + +func (o opt_420_x86_64) Nodefconfig() string { + return "-no-user-config" +} + +func (o opt_420_x86_64) NoKVMPitReinjection() string { + // https://www.qemu.org/docs/master/about/removed-features.html#no-kvm-pit-reinjection-removed-in-3-0 + // -no-kvm-pit-reinjection (removed in 3.0) + return "" +} + +func newCmd_4_2_0_aarch64() QemuCommand { + return newBaseCommand( + Version_4_2_0, + Arch_aarch64, + newOpt_4_2_0_aarch64()) +} + +type opt_420_aarch64 struct { + *baseOptions_aarch64 +} + +func newOpt_4_2_0_aarch64() QemuOptions { + return &opt_420_aarch64{ + baseOptions_aarch64: newBaseOptions_aarch64(), + } +} + +func (o opt_420_aarch64) Nodefconfig() string { + return "-no-user-config" +}