分类目录归档:技术笔记

Perl 面向对象之基类(use base)

use base somemodule;

# 相当于以下两句的结合:

BEGIN{
    use somemodule ();
    push @ISA, qw(somemodule);
}

# 也可以同时 use base 两个或者两个以上的模块,即多继承,例如:

use base qw(Foo Bar);

BEGIN {
    use Foo ();
    use Bar ();
    push @ISA, qw(Foo Bar);
}
  • Perl 里 类方法通过 @ISA 数组继承,这个数组里面包含其他包(类)的名字,变量的继承必须明确设定。
  • 多继承就是这个 @ISA 数组包含多个类(包)名字。
  • 通过 @ISA 只能继承方法不能继承数据

参考文献

Perl 模块路径指定(调试环境)

在调试 Perl 测试程序时,常常需要在测试路劲执行 Perl 脚本,相应的 .pm 模块测试程序也需并不在 Perl 默认的模块路径下,使用以下语句即可指定模块检索路径。

#!/usr/bin/perl
use lib './';
use Person;
# Person 包模块与当前脚本同级,可用上面两行代码指定包位置
...

参考文献

QEMU 编译报错 undefined reference to g_app_info_launch_default_for_uri_finish 解决过程

编译 QEMU 时报如下错误:

/usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../lib64/libgtk-3.so: undefined reference to `g_app_info_launch_default_for_uri_finish'
/usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../lib64/libgtk-3.so: undefined reference to `g_type_check_instance_is_fundamentally_a'
/usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../lib64/libgtk-3.so: undefined reference to `g_app_info_launch_default_for_uri_async'
/usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../lib64/libgtk-3.so: undefined reference to `g_strv_contains'
/usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../lib64/libgtk-3.so: undefined reference to `g_list_model_get_type'
/usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../lib64/libgtk-3.so: undefined reference to `g_drive_is_removable'
/usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../lib64/libgtk-3.so: undefined reference to `g_application_get_resource_base_path'
/usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../lib64/libgtk-3.so: undefined reference to `g_log_structured_standard'
/usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../lib64/libgtk-3.so: undefined reference to `g_type_get_instance_count'
/usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../lib64/libgtk-3.so: undefined reference to `g_list_model_get_n_items'
/usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../lib64/libgtk-3.so: undefined reference to `g_file_enumerator_iterate'
/usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../lib64/libgtk-3.so: undefined reference to `g_param_spec_get_name_quark'
/usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../lib64/libgtk-3.so: undefined reference to `g_list_model_get_item'
collect2: error: ld returned 1 exit status
make[1]: *** [qemu-system-x86_64] Error 1
make: *** [subdir-x86_64-softmmu] Error 2

先看一下报错的动态链接库依赖了哪些库:

$ ldd /lib64/libgtk-3.so       
        linux-vdso.so.1 =>  (0x00007ffc89762000)
        libgdk-3.so.0 => /lib64/libgdk-3.so.0 (0x00007f19938ab000)
        libgmodule-2.0.so.0 => /lib64/libgmodule-2.0.so.0 (0x00007f19936a7000)
        libpangocairo-1.0.so.0 => /lib64/libpangocairo-1.0.so.0 (0x00007f1993499000)
        libX11.so.6 => /lib64/libX11.so.6 (0x00007f199315b000)
        libXi.so.6 => /lib64/libXi.so.6 (0x00007f1992f4b000)
        libXfixes.so.3 => /lib64/libXfixes.so.3 (0x00007f1992d45000)
        libcairo-gobject.so.2 => /lib64/libcairo-gobject.so.2 (0x00007f1992b3c000)
        libcairo.so.2 => /lib64/libcairo.so.2 (0x00007f1992805000)
        libgdk_pixbuf-2.0.so.0 => /lib64/libgdk_pixbuf-2.0.so.0 (0x00007f19925dd000)
        libatk-1.0.so.0 => /lib64/libatk-1.0.so.0 (0x00007f19923b7000)
        libatk-bridge-2.0.so.0 => /lib64/libatk-bridge-2.0.so.0 (0x00007f1992188000)
        libwayland-client.so.0 => /lib64/libwayland-client.so.0 (0x00007f1991f79000)
        libepoxy.so.0 => /lib64/libepoxy.so.0 (0x00007f1991c4d000)
        libpangoft2-1.0.so.0 => /lib64/libpangoft2-1.0.so.0 (0x00007f1991a37000)
        libpango-1.0.so.0 => /lib64/libpango-1.0.so.0 (0x00007f19917f1000)
        libfontconfig.so.1 => /lib64/libfontconfig.so.1 (0x00007f19915af000)
        libgio-2.0.so.0 => /lib64/libgio-2.0.so.0 (0x00007f199120f000)
        libgobject-2.0.so.0 => /lib64/libgobject-2.0.so.0 (0x00007f1990fbe000)
        libglib-2.0.so.0 => /lib64/libglib-2.0.so.0 (0x00007f1990ca8000)
        libm.so.6 => /lib64/libm.so.6 (0x00007f19909a6000)
        libpthread.so.0 => /lib64/libpthread.so.0 (0x00007f199078a000)
        libc.so.6 => /lib64/libc.so.6 (0x00007f19903bc000)
        libXinerama.so.1 => /lib64/libXinerama.so.1 (0x00007f19901b9000)
        libXrandr.so.2 => /lib64/libXrandr.so.2 (0x00007f198ffae000)
        libXcursor.so.1 => /lib64/libXcursor.so.1 (0x00007f198fda3000)
        libXcomposite.so.1 => /lib64/libXcomposite.so.1 (0x00007f198fba0000)
        libXdamage.so.1 => /lib64/libXdamage.so.1 (0x00007f198f99d000)
        libxkbcommon.so.0 => /lib64/libxkbcommon.so.0 (0x00007f198f75d000)
        libwayland-cursor.so.0 => /lib64/libwayland-cursor.so.0 (0x00007f198f555000)
        libwayland-egl.so.1 => /lib64/libwayland-egl.so.1 (0x00007f198f353000)
        libXext.so.6 => /lib64/libXext.so.6 (0x00007f198f141000)
        librt.so.1 => /lib64/librt.so.1 (0x00007f198ef39000)
        libdl.so.2 => /lib64/libdl.so.2 (0x00007f198ed35000)
        libpcre.so.1 => /lib64/libpcre.so.1 (0x00007f198ead3000)
        libfreetype.so.6 => /lib64/libfreetype.so.6 (0x00007f198e814000)
        libxcb.so.1 => /lib64/libxcb.so.1 (0x00007f198e5ec000)
        libpixman-1.so.0 => /lib64/libpixman-1.so.0 (0x00007f198e343000)
        libEGL.so.1 => /lib64/libEGL.so.1 (0x00007f198e12f000)
        libpng15.so.15 => /lib64/libpng15.so.15 (0x00007f198df04000)
        libxcb-shm.so.0 => /lib64/libxcb-shm.so.0 (0x00007f198dd00000)
        libxcb-render.so.0 => /lib64/libxcb-render.so.0 (0x00007f198daf2000)
        libXrender.so.1 => /lib64/libXrender.so.1 (0x00007f198d8e7000)
        libz.so.1 => /lib64/libz.so.1 (0x00007f198d6d1000)
        libGL.so.1 => /lib64/libGL.so.1 (0x00007f198d445000)
        libatspi.so.0 => /lib64/libatspi.so.0 (0x00007f198d214000)
        libdbus-1.so.3 => /lib64/libdbus-1.so.3 (0x00007f198cfc4000)
        libffi.so.6 => /lib64/libffi.so.6 (0x00007f198cdbc000)
        libharfbuzz.so.0 => /lib64/libharfbuzz.so.0 (0x00007f198cb1f000)
        libthai.so.0 => /lib64/libthai.so.0 (0x00007f198c913000)
        libfribidi.so.0 => /lib64/libfribidi.so.0 (0x00007f198c6f7000)
        libexpat.so.1 => /lib64/libexpat.so.1 (0x00007f198c4cd000)
        libuuid.so.1 => /lib64/libuuid.so.1 (0x00007f198c2c8000)
        libselinux.so.1 => /lib64/libselinux.so.1 (0x00007f198c0a1000)
        libresolv.so.2 => /lib64/libresolv.so.2 (0x00007f198be87000)
        libmount.so.1 => /lib64/libmount.so.1 (0x00007f198bc44000)
        libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00007f198ba2e000)
        /lib64/ld-linux-x86-64.so.2 (0x00007f199449d000)
        libbz2.so.1 => /lib64/libbz2.so.1 (0x00007f198b81e000)
        libXau.so.6 => /lib64/libXau.so.6 (0x00007f198b61a000)
        libGLdispatch.so.0 => /lib64/libGLdispatch.so.0 (0x00007f198b364000)
        libGLX.so.0 => /lib64/libGLX.so.0 (0x00007f198b132000)
        libsystemd.so.0 => /lib64/libsystemd.so.0 (0x00007f198af01000)
        libgraphite2.so.3 => /lib64/libgraphite2.so.3 (0x00007f198acd3000)
        libblkid.so.1 => /lib64/libblkid.so.1 (0x00007f198aa93000)
        libcap.so.2 => /lib64/libcap.so.2 (0x00007f198a88e000)
        liblzma.so.5 => /lib64/liblzma.so.5 (0x00007f198a668000)
        liblz4.so.1 => /lib64/liblz4.so.1 (0x00007f198a459000)
        libgcrypt.so.11 => /lib64/libgcrypt.so.11 (0x00007f198a1d8000)
        libgpg-error.so.0 => /lib64/libgpg-error.so.0 (0x00007f1989fd3000)
        libdw.so.1 => /lib64/libdw.so.1 (0x00007f1989d82000)
        libattr.so.1 => /lib64/libattr.so.1 (0x00007f1989b7d000)
        libelf.so.1 => /lib64/libelf.so.1 (0x00007f1989965000)

观察输出,所有依赖的动态链接库都有指向一个内存地址,说明所依赖的链接库都已经被加载入内存,排除了链接库不存在情况,下面就有可能是某个链接库有问题了,接下来做两件事:

  • 使用 objdump -T <lib name and path> |grep <funcname> 命令检索报错函数属于哪一个链接库;
  • 使用 find / -name <lib name> 命令查找是否有哪一个报错链接库在系统的动态链接库搜索目录中有多个;

经过一番检索,发现 [libgio-2.0.so](http://libgio-2.0.so) 在系统so检索目录有两个,分别是 /usr/local/lib/libgio-2.0.so/lib64/libgio-2.0.so ,其中 /lib64 为系统默认链接库存放位置,而 /usr/local 为编译安装库的默认安装位置,移除/usr/local/lib/libgio-2.0.so 之后再次尝试编译发现报错减少了。

此时发现系统曾编译安装了 glib ,可能是那时引入了一些错误的 so 库,因此进入编译目录 make uninstall 移除此前安装的错误的库,再次尝试编译发现编译通过。

总结

本次编译错误排查了很久,最后在大佬的协助下终于解决,此类缺少依赖错误排查错误思路可以总结为 检查链接库是否存在 -> 检查是否存在重复链接库 -> 移除错误链接库

参考文献

鲲鹏ARM环境编译升级虚拟化组件(QEMU+libvirt)

在 鲲鹏 arm 环境下可以直接使用 yum 安装相关虚拟化组件(以 centos 为例):

yum -y install qemu* libvirt* AAVMF virt-install

但是软件库中的虚拟化组件版本较老,不支持 spice 等,而且对端口有限制,无法使用 virt-manager ,也无法对接 openstack 使用,因此需要分别升级 QEMU, libvirt。

(本文内容主要来自华为鲲鹏支持官网文档

鲲鹏 ARM 编译升级 QEMU(带有 OpenStack 相关组件)

安装依赖包。

yum -y install glib2-devel zlib-devel pixman-devel libaio-devel glib libffi-devel gcc gcc-c++ automake libtool bzip2-devel libuuid-devel spice-protocol spice-server-devel usbredir-devel gtk3-devel  SDL2-devel libjpeg-turbo-devel crudini librbd-devel snappy-devel

编译安装

说明:QEMU 默认安装在“/usr/local”下,源码包的下载请参见获取软件包。 使用的是 qemu-4.0.0 版本。该 arm 版本暂不支持虚拟机热迁移功能(支持冷迁移),若有虚拟机热迁移需求,可根据 openEuler 中的 patch 包进行补丁升级,链接如下:https://gitee.com/src-openeuler/qemu/tree/openEuler-20.03-LTS/

wget https://download.qemu.org/qemu-4.0.0.tar.xz

1, 解压并进入 QEMU 目录。

tar -xvf qemu-4.0.0.tar.xz
cd qemu-4.0.0

2, 配置安装,若需对接 openstack 请包含相关依赖:

## 普通配置安装
./configure --target-list=aarch64-softmmu  --enable-linux-aio

## 配置安装,同时带有 openstack 相关依赖
../configure --prefix=/usr --target-list="aarch64-softmmu" \
      --enable-rbd --enable-debug --enable-vnc --enable-vnc-jpeg --enable-vnc-png \
      --enable-kvm --enable-spice --enable-curl --enable-snappy --enable-tools --enable-spice --enable-libusb \
      --enable-usb-redir --enable-linux-aio

编译安装

# 多线程编译
make -j64 
make install

# 链接 qemu-kvm ,若链接存在请先删除
ln -s /usr/bin/qemu-system-aarch64 /usr/bin/qemu-kvm
ln -s /usr/bin/qemu-system-aarch64 /usr/libexec/qemu-kvm

3, 添加 lib 库。

添加 lib 库路径。

vim /etc/ld.so.conf
include /usr/local/lib

使 lib 库更改生效。

ldconfig

4, 检验 QEMU 版本。

qemu-img --version

鲲鹏 ARM 环境编译升级 libvirtd

说明:

官方提供的 src.rpm 包在编译时,有一定几率会失败,需多次尝试。

安装 edk2

  • 在线安装

执行如下命令在线安装 edk2

wget https://www.kraxel.org/repos/firmware.repo -O /etc/yum.repos.d/firmware.repo
yum -y install edk2.git-aarch64
  • 离线安装

在有外网的环境下访问https://www.kraxel.org/repos/jenkins/edk2/,获取 rpm 包并拷贝至目标服务器系统相应位置。执行如下命令离线安装 edk2,如图2所示。

rpm -ivh edk2.git-aarch64*.rpm

安装依赖包

说明:本章节的操作需要外网可用或已配置本地源。

yum -y install libxml2-devel readline-devel ncurses-devel libtasn1-devel gnutls-devel libattr-devel libblkid-devel augeas systemd-devel libpciaccess-devel yajl-devel sanlock-devel libpcap-devel libnl3-devel libselinux-devel dnsmasq radvd cyrus-sasl-devel libacl-devel parted-devel device-mapper-devel xfsprogs-devel librados2-devel librbd1-devel glusterfs-api-devel glusterfs-devel numactl-devel libcap-ng-devel fuse-devel netcf-devel libcurl-devel audit-libs-devel systemtap-sdt-devel nfs-utils dbus-devel scrub numad

编译安装

说明:源码包的下载请参见获取软件包,本章以 libvirt-5.6.0 为例。该 Arm 版本暂不支持虚拟机热迁移功能(支持冷迁移),若有虚拟机热迁移需求,可根据 openEuler 中的 patch 包进行补丁升级,链接如下:https://gitee.com/src-openeuler/libvirt/tree/openEuler-20.03-LTS/

1, 安装 src.rpm 源码包。

rpm -i libvirt-5.6.0-1.fc30.src.rpm

2, 生成 rpm 包。

cd /root/rpmbuild/SPECS/
rpmbuild -ba libvirt.spec

说明: 官方提供的 src.rpm 包在编译时,有一定几率会失败,需多次尝试。

3, 安装 rpm 包。

cd /root/rpmbuild/RPMS/aarch64/yum -y install *.rpm

4, 修改配置文件。

打开 qemu.conf 文件。

vim /etc/libvirt/qemu.conf

添加如下配置。

nvram = ["/usr/share/edk2.git/aarch64/QEMU_EFI-pflash.raw:/usr/share/edk2.git/aarch64/vars-template-pflash.raw"]

5, 重启 libvirtd 服务。

service libvirtd restart
systemctl restart libvirtd

6, 关闭 SELinux。

setenforce 0

参考文献

一键修改Windows远程桌面(RDP)端口号

本文主要内容来微软官方文档,命令未 PowerShell 命令,管理员权限运行,最后给出链接。

若要查看当前 RDP 端口,可使用以下 PowerShell 命令:

Get-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp' -name "PortNumber"

若要修改 RDP 端口,可使用以下命令(以3390为例):

Set-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Control\Terminal Server\W

若要添加新的 RDP 监听端口,可以这样(未验证):

inStations\RDP-Tcp' -name "PortNumber" -Value 3390
New-NetFirewallRule -DisplayName 'RDPPORTLatest' -Profile 'Public' -Direction Inbound -Action Allow -Protocol TCP -LocalPort 3390

重启生效!

参考文献

Mac 下解决 zsh: no matches found: postcss@^7

mac开发引入 tailwindcss 库时遇到如下错误:

zsh: no matches found: postcss@^7

可以这样解决:

# 官网给出的命令如下
npm install -D tailwindcss@npm:@tailwindcss/postcss7-compat postcss@\^7 autoprefixer@\^9

# mac的zsh中需要这样,因为错误的 ^ 解析
npm install -D tailwindcss@npm:@tailwindcss/postcss7-compat postcss@^7 autoprefixer@^9

参考文献

解决OpenVPN证书过期问题

使用 Synology 提供的 VPN Server 一阵子,突然用不了了,大意是说 SSL 证书过期了,但是不知道如何解决,网络搜索也没有结果,试过了重置套件,无法解决。

最后查阅文档发现,VPN Server 是依赖了群晖设置中的证书。

https://imagehost-cdn.frytea.com/images/2021/08/01/2021-08-01-11.33.18a374cf098b06dd85.png

随便选择一个进入设置,发现 VPN server 就是配置了过期的证书。

https://imagehost-cdn.frytea.com/images/2021/08/01/2021-08-01-11.34.442fd77679cad71819.png

解决方法很简单,选择一个没过期的证书即可,保存后 VPN Server 会自动重启,之后重新导出配置文件,重连即可。

virt-manager 启动提示 virt qemu-sock no such file or directory

检查后应该是 virtqemud 服务没起来导致的,编译安装默认生成的服务路径在 /usr/local/* 下,而我们指定了安装在默认位置 /usr ,参考 systemd 无法启动的解决方法即可解决该问题。

首先看一下 /usr/sbin/virtqemud 这个文件是存在的,下面继续操作,首先使能该服务。

$ systemctl enable virtqemud
Created symlink from /etc/systemd/system/multi-user.target.wants/virtqemud.service to /usr/local/lib/systemd/system/virtqemud.service.
Created symlink from /etc/systemd/system/sockets.target.wants/virtqemud.socket to /usr/local/lib/systemd/system/virtqemud.socket.
Created symlink from /etc/systemd/system/sockets.target.wants/virtqemud-ro.socket to /usr/local/lib/systemd/system/virtqemud-ro.socket.
Created symlink from /etc/systemd/system/sockets.target.wants/virtqemud-admin.socket to /usr/local/lib/systemd

创建了改服务的软连接,宣告自启,此时服务配置有问题,直接修改该软连接指定的文件

vim /usr/local/lib/systemd/system/virtqemud.service

# 类比 libvirtd 的修改这两行,指定正确服务位置

[Service]
...
EnvironmentFile=-/etc/sysconfig/virtqemud
ExecStart=/usr/sbin/virtqemud $VIRTQEMUD_ARGS

之后重新加载服务,再启动

systemctl daemon-reload
systemctl reload virtqemud
systemctl start virtqemud

不出意外的话就能启动了,若有问题请留言。

本文截取自,前一篇文章,详细内容及上下文请查看原文

Centos7.6 下编译安装 Libvirt 7.5

libvirt 是目前使用最为广泛的对KVM虚拟机进行管理的工具和 APILibvirtd 是一个 daemon 进程,可以被本地的 virsh 调用,也可以被远程的 virsh 调用, Libvirtd 调用 qemu-kvm 操作虚拟机。下面介绍 Centos7.6 下编译安装 Libvirt 7.5 的方法。

环境准备

yum install -y meson
yum install -y gcc
yum install qemu-kvm

编译步骤-7.5

首先下载源码文件:

# Compiling a release tarball
wget https://libvirt.org/sources/libvirt-7.5.0.tar.xz
tar -xvf libvirt-7.5.0.tar.xz
cd libvirt-7.5.0

编译前可以查看一下当前系统下 virsh 的安装位置

[root@compute-01 stl]# find / -name "virsh"
/usr/bin/virsh

可以看到是安装在 .usr/bin 这个 PATH 路径下,因此在编译安装时,可使用如下命令指定安装位置(默认安装在 /usr/local/bin 目录下):

$ meson build --prefix=/usr
$ ninja -C build
$ sudo ninja -C build install

下面是官网给出的几种安装模式,包括直接使用 release 包安装,安装到您的个人目录下,或是根据系统自动安装到相应位置,可以按需选择。


# Compiling a release tarball
$ xz -dc libvirt-x.x.x.tar.xz | tar xvf -
$ cd libvirt-x.x.x
$ meson build

$ meson build [possible options]
$ ninja -C build
$ sudo ninja -C build install

# build & install libvirt to your home directory
$ meson build --prefix=$HOME/usr
$ ninja -C build
$ sudo ninja -C build install

# To produce a build that is compatible with normal OS vendor prefixes, use
$ meson build -Dsystem=true
$ ninja -C build

编译步骤-6.0

这里给出简单的 6.0 版本编译方法。

wget https://libvirt.org/sources/libvirt-6.0.0.tar.xz
tar -xvf

cd libvirt-6.0.0
mkdir build
cd build
../autogen.sh --system
$ make
$ sudo make install

疑难解决

  • ERROR: Program ‘rpcgen portable-rpcgen’ not found
wget https://github.com/thkukuk/rpcsvc-proto/releases/download/v1.4.2/rpcsvc-proto-1.4.2.tar.xz
./configure --sysconfdir=/etc &&
make
make install
  • Program ‘rst2html5 rst2html5.py rst2html5-3′ not found
$ yum install python -y
$ pip install rst2html5
  • Dependency “glib-2.0” not found, tried pkgconfig and cmake
yum install glib2-devel
  • Dependency “gnutls” not found, tried pkgconfig and cmake
yum install gnutls-devel
  • Dependency “libxml-2.0” not found, tried pkgconfig and cmake
yum install libxml2-devel -y
  • 致命错误:rpc/rpc.h:没有那个文件或目录
yum -y install libtirpc-devel
# 修改生成的编译配置文件
find / -name "rpc.h"
vim meson.build
# 在 headers 增加 rpc 头文件绝对路径

headers = [
  ...
  '/usr/include/tirpc/rpc/rpc.h',
]
  • parser error : Double hyphen within comment: <!-- This file is auto-generated from keymaps.csv

解决方法:找到报错的 *.html.in 文件报错行出,将报错的 -- 改为 - 即可。

  • 编译后没有 vir-install 命令
yum install virt-install
  • systemd 无法启动

libvirtd.service 存在于 /usr/lib/systemd/system/ 文件夹下,而在 /etc/systemd/system/ 文件夹下有该文件的软连接,表明这是自动启动的。

尝试启动该服务时会报错,因为其中指定环境变量有问题,其中的大部分内容不需要改动,就是下面的文件的路径需要改,因为手动编译安装的libvirt安装路径在 /usr/local/sbin/libvirtd 或是 /usr/sbin/libvirtd ,修改以下两处:

[Service]
...
EnvironmentFile=/etc/sysconfig/libvirtd
ExecStart=/usr/sbin/libvirtd $LIBVIRTD_ARGS
...

需根据您系统中实际位置查找到对应位置,如果按照本文建议流程则路径同上,否则需自行查找,之后再次尝试启动即可,有可能需要重新加载一下服务。

systemctl daemon-reload
systemctl reload libvirtd
systemctl start libvirtd

即可启动成功,若不成功请留言。

  • virt-manager 启动提示 virt qemu-sock no such file or directory

检查后应该是 virtqemud 服务没起来导致的,编译安装默认生成的服务路径在 /usr/local/* 下,而我们指定了安装在默认位置 /usr ,参考 systemd 无法启动的解决方法即可解决该问题。

首先看一下 /usr/sbin/virtqemud 这个文件是存在的,下面继续操作,首先使能该服务。

$ systemctl enable virtqemud
Created symlink from /etc/systemd/system/multi-user.target.wants/virtqemud.service to /usr/local/lib/systemd/system/virtqemud.service.
Created symlink from /etc/systemd/system/sockets.target.wants/virtqemud.socket to /usr/local/lib/systemd/system/virtqemud.socket.
Created symlink from /etc/systemd/system/sockets.target.wants/virtqemud-ro.socket to /usr/local/lib/systemd/system/virtqemud-ro.socket.
Created symlink from /etc/systemd/system/sockets.target.wants/virtqemud-admin.socket to /usr/local/lib/systemd

创建了改服务的软连接,宣告自启,此时服务配置有问题,直接修改该软连接指定的文件

vim /usr/local/lib/systemd/system/virtqemud.service

# 类比 libvirtd 的修改这两行,指定正确服务位置

[Service]
...
EnvironmentFile=-/etc/sysconfig/virtqemud
ExecStart=/usr/sbin/virtqemud $VIRTQEMUD_ARGS

之后重新加载服务,再启动

systemctl daemon-reload
systemctl reload virtqemud
systemctl start virtqemud

不出意外的话就能启动了,若有问题请留言。

参考文献

C实现不用临时变量交换两个数的值(一行代码)

最近看到一个问题感觉很有意思:

“如何在不申请临时变量的情况下交换两个数的值?”

思考许久没有思路,查阅一番发现方法不少,在这里介绍四种方法:

方法一

void swap(int *p, int *q)
{
    *a = *a ^ *b;
    *b = *b ^ *a;
    *a = *a ^ *b;
}

提示:异或运算符 ^ 也称 XOR 运算符,它的规则是若参加运算的两个二进位同号,则结果为 (假);异号为 1(真)。即 0 ^ 0 = 0 , 0 ^ 1 = 1 , 1 ^ 0 = 1 , 1 ^ 1 = 0

计算实例:

a = 3 -> 0000 0011
b = 4 -> 0000 0100

step1:
    a = a ^ b
    ->  0000 0011
     ^  0000 0100
      = 0000 0111 -> 7

step2:
    b = b ^ a
    ->  0000 0100
     ^  0000 0111
      = 0000 0011 -> 3

step3:
    a = a ^ b
    ->  0000 0111
     ^  0000 0011
      = 0000 0100 -> 4

方法二

void swap(int *p, int *q)
{
    *a = *a + *b;
    *b = *a - *b;
    *a = *a - *b;
}

方法三

void swap(int *p, int *q)
{
    *a = *a + *b - (*b = *a);
}

C/C++ 中 ( A = B ) 返回得到是赋值号( = )的左面的值

计算实例:

a = 3;
b = 4;

a = 3 + 4 - (b = 3)
  = 3 + 4 - 3
  = 4;

-> a = 4;
-> b = 3;

方法四

void swap(int *p, int *q)
{
    *a ^= *b ^= *a ^= *b;
}
计算实例:

a = 3;
b = 4;

a = 3 ^ 4 = 7;
b = 4 ^ 7 = 3;
a = 7 ^ 3 = 4;

-> a = 4;
-> b = 3;

参考文献