0. 前言
编译需要用到高版本python(>=3.8),参考附录查看教程,我使用的python3.11,所有后文的python3都是它的链接。
1. 源码安装qemu
1.1 源码安装
apt install gtk+-3.0 # 后面qemu编译依赖用的到
wget https://download.qemu.org/qemu-9.1.0-rc2.tar.xz
tar xvJf qemu-9.1.0-rc2.tar.xz
cd qemu-9.1.0-rc2
mkdir -p build
cd build
# if you want the x86 target too you can add "x86-softmmu" in the target list
../configure --target-list=aarch64-linux-user,loongarch64-linux-user,mips64-linux-user,x86_64-linux-user,aarch64-softmmu,loongarch64-softmmu,mips64-softmmu,x86_64-softmmu --enable-debug --enable-gtk --enable-gtk-clipboard -Dbuildtype=release -Doptimization=s --disable-debug-info
make -j16
make install
--enable-debug
:使能qemu的debug功能--enable-gtk
:如果不指定,当系统没有相应gtk包时,编译过程不会提示,安装使用后,启动虚拟机将看不到图像,所以请务必显式指定。--enable-gtk-clipboard
:可以直接将复制的内容粘贴到虚拟机。-Dmesonoptname=val
:传递给meson的选项,qemu实际上是使用meson构建的,configure只是个套壳,meson configure
可以查看当前构建选项和说明,例如,-Doptimization=s
:开启速度优先优化。--disable-debug-info
:关闭qemu的调试信息--target-list
如果不指定,会编译所有架构虚拟机,很慢。xxx-softmmu
表示的是模拟整个物理机,使用qemu-system-xxx
命令。xxx-linux-user
仅模拟用户应用程序,使用qemu-xxx
命令。
1.2 命令行启动测试
安装镜像
qemu-img create -f qcow2 /tmp/vm-disk.qcow2 40G
qemu-system-x86_64 -cpu host -enable-kvm -hda /tmp/vm-disk.qcow2 -cdrom /path/to/centos.iso
注意:-enable-kvm
或accel=kvm
一定要加上,利用kvm实现硬件加速,速率块很多,OS的CPU指令不用再经过Qemu转译,直接运行。
1.3 测试qemu监控器控制台
可以在qemu的UI界面,通过view->compatmonitor打开控制态。注意只有通过命令行(qemu-system-ARCH)启动虚拟机时才会有该选项。
qemu-system-x86_64 -m 4096 -smp 4 -hda /var/lib/libvirt/images/generic -cpu host -enable-kvm
如果是通过libvird启动的虚拟机(例如virt-manager工具),它是通过vnc或spice会话,和虚拟机的输出连接的,这样是不能直接访问qemu的监控器的,但是可以通过virsh这个工具,向qemu发送命令来进入。
1.4 可能遇到的问题
- 问题:
gtk initialization failed
- 原因:大概率是因为你用root身份(和环境)运行qemu,qemu-system-xxx会调用gtk的sdk,其中一个接口是gtk_init_check,它会检测当前环境变量是否有DISPLAY,而root的环境默认是没有这个环境变量的。
- 解决:使用图形用户(即你桌面用户)来运行qemu-system-xxx,或者将桌面用户的DISPLAY变量拷贝给root。
virsh qemu-monitor-command COMMAND
2. 源码安装libvirt
2.1 编译安装
meson setup build -Dsystem=true -Ddriver_libvirtd=enabled -Ddriver_remote=enabled -Dsystem=true -Ddriver_qemu=enabled -Ddocs=disabled
ninja -C build
ninja -C build test
ninja -C build install
2.2 启动服务
上安装完成后,相应服务文件会安装到指定目录,需要手动开启服务
systemctl enable libvirtd virtlogd # 设定开机启动该服务
systemctl start libvirtd virtlogd # 立即启动该服务
systemctl status libvirtd virtlogd # 查看启动状态
2.3 可能遇到的问题
- 问题:
systemctl status libvirtd
报错
apabilities for /usr/local/bin/qemu-system-x86_64: internal error: Failed to start QEMU binary /usr/local/bin/qemu-system-x86_64 for probing: libvirt: error : 权限不够
-
原因:
/usr/local/bin/qemu-system-x86_64
是源码安装qemu时的默认安装路径,如果历史上,通过apt安装过libvirtd包,安装包时,会对libvirtd生成apparmor的策略文件(不同打包应用不同,有可能也没有该逻辑),限制其访问范围,其中可访问的范围包括/usr/bin /usr/sbin
,但是不包括/usr/local
,因此如果你的环境开启了apparmor,且之前通过源安装过libvirtd,则大概率会报该错。 -
解决:很简单,取消apparmor对libvirtd的限制即可,
aa-disable /usr/sbin/libvirtd
-
问题:
'Failed to connect socket to '/var/run/libvirt/virtlogd-sock': 没有那个文件或目录'
,查看systemctl status libvirtd
日志Failed to connect socket to '/var/run/libvirt/virtlogd-sock': 拒绝连接
,尝试手动启动virtlogd
,systemclt start virtlogd
报错:Reason: Unit virtlogd.service is masked.
,查看/etc/systemd/system/virtlogd.service
,被链接到了/dev/null
。同样的还有目录/var/lib/systemd/deb-systemd-helper-masked/
下virt
相关的sock
文件 -
原因:猜测是因为我之前使用apt安装过libvirtd,之后把它卸载,导致它被链接到空。
-
解决:删除它重新使能、启动服务即可。
3. 源码安装virt-manager
3.1 源码安装
tar xf virt-manager-4.1.0.tar.gz
cd virt-manager-4.1.0
python3 setup.py build
python3 setup.py install
3.2 可能遇到的问题
- 问题:编译报错
subprocess.CalledProcessError: Command '['/usr/bin/rst2man', '--strict', 'man/virt-manager.rst']' returned non-zero exit status 1.
- 解决:
pip3 install docutils
- 问题:运行 virt-manager 报错
pygobject3 3.31.3 or later is required.
# or
ModuleNotFoundError: No module named 'gi'
- 解决:
pip3 install PyGObject
-
问题:
ERROR: Failed building wheel for pycairo
-
解决:
apt install libcairo-dev
-
问题:
../meson.build:29:9: ERROR: Dependency 'gobject-introspection-1.0' is required but not found.
-
解决:
apt install libgirepository1.0-dev
-
问题:
Dependency gobject-introspection-1.0 found: NO. Found 1.58.3 but need: '>= 1.64.0'
-
解决:更新gobject-introspection-1.0,README没有写编译方法,参考官网。
meson setup _build
cd _build
# To see the build options run "meson configure"
meson compile
-
问题:
meson.build:1:0: ERROR: Meson version is 0.61.2 but project requires >= 1.2.0
-
解决:
python3 -m pip install meson
-
问题:
meson.build:25:2: ERROR: Problem encountered: Requires Python >=3.8, 3.7 found.
-
问题:
meson.build:29:8: ERROR: python3 is missing modules: setuptools
-
解决:
python3 -m pip install setuptools
-
问题:
Run-time dependency glib-2.0 found: NO (tried pkgconfig and cmake)
-
解决:
apt install gir1.2-glib-2.0
-
问题:
Run-time dependency libpcre2-8 found: NO (tried pkgconfig and cmake)git
-
解决:apt install libpcre2-dev
-
问题:
fatal: unable to access 'https://gitlab.gnome.org/GNOME/gvdb.git/'
-
解决:
vim ./subprojects/gvdb.wrap # 编辑url如下
url=https://github.com/GNOME/gvdb.git
- 问题:
ValueError: Namespace Gdk not available
- 解决:
$ python3 -m pip install Gdk
$ apt-get install libgtk-3-dev
$ export GI_TYPELIB_PATH=/usr/lib/x86_64-linux-gnu/girepository-1.0
$ echo 'export GI_TYPELIB_PATH=/usr/lib/x86_64-linux-gnu/girepository-1.0' >> ~/.bashrc
- 问题:
ModuleNotFoundError: No module named 'libvirt'
- 解决:
pip3 install libvirt-python
如果安装失败,则只能手动源码安装了
tar xf libvirt-python-10.6.0.tar.gz
cd libvirt-python-10.6.0
pip3 install build # 也可手动装
export PKG_CONFIG_PATH=/usr/lib64/pkgconfig/
python3 -m build
python3 -m pip install .
- 问题:
ModuleNotFoundError: No module named 'libxml2'
- 解决:
pip3 install libxml2
,大概率找不到包,手动去官网下源码安装。
tar xf libxml2-python3-2.9.5.tar.gz
cd libxml2-python3-2.9.5
python3 setup.py build # 大概率会报错,参考后文修改
python3 setup.py install
python3 setup
截止2024/4/19,libxml2-python3的源码直接使用python3.12编译会报错
/usr/include/python3.12/object.h:971:41: error: expected ‘(’ before ‘PyType_HasFeature’
#define PyType_FastSubclass(type, flag) PyType_HasFeature((type), (flag))
^~~~~~~~~~~~~~~~~
/usr/include/python3.12/unicodeobject.h:115:5: note: in expansion of macro ‘PyType_FastSubclass’
PyType_FastSubclass(Py_TYPE(op), Py_TPFLAGS_UNICODE_SUBCLASS)
^~~~~~~~~~~~~~~~~~~
libxml.c:297:15: note: in expansion of macro ‘PyUnicode_Check’
} else if PyUnicode_Check (ret) {
^~~~~~~~~~~~~~~
libxml.c:297:37: error: expected ‘;’ before ‘{’ token
} else if PyUnicode_Check (ret) {
源码有些地方需要修改(很少),修改内容如下(格式为git补丁,直接补丁应用,参考后文,也可手动修改)
From: leifeng <leifeng@leifeng.com>
Date: Mon, 19 Aug 2024 17:20:23 +0800
Subject: [PATCH] fix python3.12 compiling err
---
libxml.c | 4 ++--
types.c | 12 ++++++------
2 files changed, 8 insertions(+), 8 deletions(-)
diff --git a/libxml.c b/libxml.c
index 5b1ff6e..c18a9d1 100644
--- a/libxml.c
+++ b/libxml.c
@@ -294,7 +294,7 @@ xmlPythonFileReadRaw (void * context, char * buffer, int len) {
lenread = PyBytes_Size(ret);
data = PyBytes_AsString(ret);
#ifdef PyUnicode_Check
- } else if PyUnicode_Check (ret) {
+ } else if (PyUnicode_Check(ret)){
#if PY_VERSION_HEX >= 0x03030000
Py_ssize_t size;
const char *tmp;
@@ -359,7 +359,7 @@ xmlPythonFileRead (void * context, char * buffer, int len) {
lenread = PyBytes_Size(ret);
data = PyBytes_AsString(ret);
#ifdef PyUnicode_Check
- } else if PyUnicode_Check (ret) {
+ } else if (PyUnicode_Check(ret)) {
#if PY_VERSION_HEX >= 0x03030000
Py_ssize_t size;
const char *tmp;
diff --git a/types.c b/types.c
index 124af56..f5c99ad 100644
--- a/types.c
+++ b/types.c
@@ -602,16 +602,16 @@ libxml_xmlXPathObjectPtrConvert(PyObject *obj)
if (obj == NULL) {
return (NULL);
}
- if PyFloat_Check (obj) {
+ if (PyFloat_Check(obj)) {
ret = xmlXPathNewFloat((double) PyFloat_AS_DOUBLE(obj));
- } else if PyLong_Check(obj) {
+ } else if (PyLong_Check(obj)) {
#ifdef PyLong_AS_LONG
ret = xmlXPathNewFloat((double) PyLong_AS_LONG(obj));
#else
ret = xmlXPathNewFloat((double) PyInt_AS_LONG(obj));
#endif
#ifdef PyBool_Check
- } else if PyBool_Check (obj) {
+ } else if (PyBool_Check(obj)) {
if (obj == Py_True) {
ret = xmlXPathNewBoolean(1);
@@ -620,14 +620,14 @@ libxml_xmlXPathObjectPtrConvert(PyObject *obj)
ret = xmlXPathNewBoolean(0);
}
#endif
- } else if PyBytes_Check (obj) {
+ } else if (PyBytes_Check(obj)) {
xmlChar *str;
str = xmlStrndup((const xmlChar *) PyBytes_AS_STRING(obj),
PyBytes_GET_SIZE(obj));
ret = xmlXPathWrapString(str);
#ifdef PyUnicode_Check
- } else if PyUnicode_Check (obj) {
+ } else if (PyUnicode_Check(obj)) {
#if PY_VERSION_HEX >= 0x03030000
xmlChar *str;
const char *tmp;
@@ -650,7 +650,7 @@ libxml_xmlXPathObjectPtrConvert(PyObject *obj)
ret = xmlXPathWrapString(str);
#endif
#endif
- } else if PyList_Check (obj) {
+ } else if (PyList_Check(obj)) {
int i;
PyObject *node;
xmlNodePtr cur;
--
2.20.1
将上面内容拷贝到本地xxx.patch
tar xf libvirt-python-10.6.0.tar.gz
cd libvirt-python-10.6.0
git init
git add .
git commit -m 'init'
git am ../xxx.patch
- 问题:
ModuleNotFoundError: No module named 'requests'
- 解决:
python3 -m pip install requests
,阿里源有这个包
3.3 到这virt-manager可以运行
但是点击创建虚拟机图标,没有弹窗,无反应,尝试以调试模式启动virt-manager查看报错
virt-manager --debug
可能依次看到如下报错:
-
问题:
ValueError: Namespace GtkSource not available
-
解决:
apt install gir1.2-gtksource-3.0
-
问题:
ValueError: Namespace Vte not available
-
解决:
apt install vte-2.91
-
问题:
ValueError: Namespace GtkVnc not available
-
解决:
apt install gir1.2-gtk-vnc-2.0
-
问题:
cannot open display
-
解决:同前文
gtk initialization failed
的解决办法 -
问题:
TypeError: iter() returned non-iterator of type 'xmlCoreDepthFirstItertor'
-
原因:
libxml2-python3-3.9.5
的bug,参考这里修改 -
解决:回到前面libxml2-python3编译环节,参考其中一个问题修复方式,打完如下补丁(可手动修改),重新编译安装即可。
From eddab8afdcd6d2e10cc2b7a0ad843881b5ba1a2a Mon Sep 17 00:00:00 2001
From: leifeng <leifeng@leifeng.com>
Date: Tue, 20 Aug 2024 16:31:48 +0800
Subject: [PATCH] fix: python3.12 TypeError: iter() returned non-iterator of
type 'xmlCoreDepthFirstItertor'
---
libxml2.py | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/libxml2.py b/libxml2.py
index 9712d16..f359360 100644
--- a/libxml2.py
+++ b/libxml2.py
@@ -530,7 +530,7 @@ class xmlCoreDepthFirstItertor:
self.parents = []
def __iter__(self):
return self
- def next(self):
+ def __next__(self):
while 1:
if self.node:
ret = self.node
@@ -542,6 +542,7 @@ class xmlCoreDepthFirstItertor:
except IndexError:
raise StopIteration
self.node = parent.next
+ next = __next__
#
# implements the breadth-first iterator for libxml2 DOM tree
@@ -552,7 +553,7 @@ class xmlCoreBreadthFirstItertor:
self.parents = []
def __iter__(self):
return self
- def next(self):
+ def __next__(self):
while 1:
if self.node:
ret = self.node
@@ -564,6 +565,7 @@ class xmlCoreBreadthFirstItertor:
except IndexError:
raise StopIteration
self.node = parent.children
+ next = __next__
#
# converters to present a nicer view of the XPath returns
--
2.20.1
4. 附录
4.1 源码安装python3.11
qemu-9.x,virt-manager-4.1需要用到3.8以上的python,这里我安装的python3.11
后续编译请注意python版本,不要混用。通过修改软链接可手动切换python3版本
ln -sf python3.7 /bin/python3
ln -sf python3.11 /bin/python3
4.2 配置python国内代理镜像站
下面选择一个执行就可以了
# 清华源
pip3 config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple
# 阿里源
pip3 config set global.index-url https://mirrors.aliyun.com/pypi/simple/
# 腾讯源
pip3 config set global.index-url https://mirrors.cloud.tencent.com/pypi/simple
# 豆瓣源
pip3 config set global.index-url https://pypi.douban.com/simple/
4.3 配置pip代理
root@PC:~# cat /root/.config/pip/pip.conf
[global]
proxy=http://127.0.0.1:8000 # 你自己的代理
标签:obj,virt,ret,libvirt,源码,install,qemu,Check,python3
From: https://blog.csdn.net/qq_26962739/article/details/141217381