FreeBSD下使用原生虚拟机管理器bhyve

hbyve简介

自 FreeBSD 10.0-RELEASE 起,BSD 许可的 bhyve 虚拟机管理器已成为底层系统不可或缺的一部分。bhyve 强大而灵活,支持多种客户机操作系统,涵盖 FreeBSD、OpenBSD 以及多个 Linux® 发行版。在默认配置下,bhyve 提供对串行控制台的直接访问,无需模拟图形化界面,从而为用户提供了简洁而高效的交互方式。

安装使用bhyve

官网文档:Chapter 24. Virtualization | FreeBSD Documentation Portal

中文文档:24.6.使用 FreeBSD 上的 bhyve 虚拟机 --- FreeBSD Handbook 2023.09.08 documentation (fiercex.github.io)

FreeBSD准备工作

若要支持bhyve,需要cpu支持,可以通过 /var/run/dmesg.boot 文件来查看,比如对AMD芯片需要支持POPCNT ,Inter芯片需要支持 EPTUG

bash 复制代码
cat /var/run/dmesg.boot

显示如下:

Features2=0x7dfafbbf<SSE3,PCLMULQDQ,DTES64,MON,DS_CPL,VMX,EST,TM2,SSSE3,SDBG,F

MA,CX16,xTPR,PDCM,PCID,SSE4.1,SSE4.2,x2APIC,MOVBE,POPCNT ,TSCDLT,XSAVE,OSXSAVE,AV

X,F16C,RDRAND>

AMD Features=0x2c100800<SYSCALL,NX,Page1GB,RDTSCP,LM>

AMD Features2=0x121<LAHF,ABM,Prefetch>

Structured Extended Features=0x21c27ab<FSGSBASE,TSCADJ,BMI1,AVX2,SMEP,BMI2,ERM

S,INVPCID,NFPUSG,RDSEED,ADX,SMAP,PROCTRACE>

XSAVE Features=0x1<XSAVEOPT>

VT-x: PAT,HLT,MTF,PAUSE,EPT,UG,VPID

可以看到cpu是支持POPCNT和EPT,UG

准备工作:加载 bhyve 内核模块

配置宿主机,首先,加载 bhyve 内核模块:

复制代码
# kldload vmm
kldload vmm
kldstat
Id Refs Address                Size Name
 1   27 0xffffffff80200000  1f370e8 kernel
 2    1 0xffffffff82138000     77d8 cryptodev.ko
 3    1 0xffffffff82140000   5cd4d8 zfs.ko
 4    1 0xffffffff831e5000     3250 ichsmb.ko
 5    1 0xffffffff831e9000     2178 smbus.ko
 6    1 0xffffffff83200000   33e438 vmm.ko

创建网络接口

然后,创建 tap 接口以供虚拟机中的网络设备进行连接。为了让该网络设备加入网络,另外创建一个桥接接口,其中包含 tap 接口和物理网络接口作为成员。在下面的例子中,物理网络接口为 igb0

# ifconfig tap0 create
# sysctl net.link.tap.up_on_open=1
net.link.tap.up_on_open: 0 -> 1
# ifconfig bridge0 create
# ifconfig bridge0 addm igb0 addm tap0
# ifconfig bridge0 up

一共5条指令:

ifconfig tap0 create

sysctl net.link.tap.up_on_open=1

ifconfig bridge0 create

ifconfig bridge0 addm igb0 addm tap0

ifconfig bridge0 up

做好这些准备工作,就可以开始配置客户机了。

创建一个FreeBSD客户机

可以创建一个单独的目录,比如~/bhyve ,将所有文件都放在这个目录里。

文档讲创建一个文件guest.img用作客户机的虚拟磁盘。指定这个虚拟磁盘的大小

复制代码
truncate -s 16G guest.img

我们这里创建一个较小的客户机,名字也改成freebsd.img

bash 复制代码
truncate -s 10G freebsd.img

下载 FreeBSD 的安装镜像:

到中科大FreeBSD镜像站下载iso安装盘

bash 复制代码
wget https://mirrors.ustc.edu.cn/freebsd/releases/ISO-IMAGES/14.1/FreeBSD-14.1-BETA3-amd64-bootonly.iso

启动脚本

下面是一个启动 bhyve 虚拟机的示例命令,vmrun.sh是一个脚本,这个脚本将会启动虚拟机并循环执行,所以可在其崩溃时自动重新启动。这个脚本可接受数个选项来配置虚拟机:-c 控制虚拟 CPU 的数量,-m 限制客户机的可用内存,-t 定义使用的 tap 设备,-d 指定其使用的磁盘镜像,-i 控制 bhyve 从 CD 镜像引导,而非从磁盘引导,-I 指定要使用的 CD 镜像。最后一个参数是虚拟机的名称,该名称将被用来追踪运行中的虚拟机。这个例子将在安装模式下启动虚拟机:

bash 复制代码
sh /usr/share/examples/bhyve/vmrun.sh -c 1 -m 1024M -t tap0 -d guest.img -i -I FreeBSD-13.1-RELEASE-amd64-bootonly.iso guestname
复制代码
具体我们的命令是:
sh /usr/share/examples/bhyve/vmrun.sh -c 4 -m 1024M -t tap0 -d freebsd.img -i -I FreeBSD-14.1-BETA3-amd64-bootonly.iso testfreebsd

然后命令行下面,就看到FreeBSD启动的画面了

好久没有用无头机(没有安装显示器)安装系统了,vt100真亲切啊:

Console type [vt100]

虚拟硬盘是:vtbd0 VirtIO Block Device

后面就是按部就班的安装FreeBSD。安装好后,重启,结果还是从光盘启动。

只好kill掉,当然bhyve还有专门的指令:

复制代码
bhyvectl --destroy --vm=testfreebsd

装机完成后再次开机

再次进入虚拟系统,这回就不挂载光盘了,手册命令:

bash 复制代码
sh /usr/share/examples/bhyve/vmrun.sh -c 4 -m 1024M -t tap0 -d guest.img guestname

实际执行命令:

复制代码
sh /usr/share/examples/bhyve/vmrun.sh -c 4 -m 1024M -t tap0 -d freebsd.img testfreebsd

启动后进入了该服务器看一下:

uname -a

FreeBSD fb_bhyve 14.1-BETA3 FreeBSD 14.1-BETA3 releng/14.1-n267636-2a964a7fc34e GENERIC amd64

果然FreeBSD下用原生bhyve虚拟主机系统真的是简单又方便啊!

创建一个Linux虚拟机

要引导进入 FreeBSD 以外的系统,必须先安装 sysutils/grub2-bhyve

bash 复制代码
pkg install grub2-bhyve

接下来,创建一个文件用作客户机的虚拟磁盘:

bash 复制代码
truncate -s 16G linux.img
复制代码
手册里讲创建 device.map 文件,让 grub 将虚拟设备映射到宿主机上的镜像文件,文件内容:
bash 复制代码
(hd0) ./linux.img
(cd0) ./ubuntu-18.04.6-server-amd64.iso

当然实际上为了简单方便,device.map文件内容如下:

bash 复制代码
(hd0) ./linux.img
(cd0) ./debian.iso

下载linux安装盘

可以选择自己喜欢的linux发行版,比如可以选择ubuntu和dibian。

下载linux ubuntu安装盘:

wget https://mirrors.ustc.edu.cn/ubuntu-cdimage/releases/18.04.6/release/ubuntu-18.04.6-server-amd64.iso

下载linux debian安装盘:

wget https://mirrors.tuna.tsinghua.edu.cn/debian-cd/current/amd64/iso-cd/debian-12.5.0-amd64-netinst.iso

为了方便建立一个文件链接:

bash 复制代码
ln -s debian-12.5.0-amd64-netinst.iso debian.iso

这样不管是device.map文件里面,还是后面命令行里面,都不需要使用那么长的文件名了。

加载linux内核

使用 sysutils/grub2-bhyve 从 ISO 文件中加载 Linux® 内核,如果没有可以pkg安装:

bash 复制代码
pkg install grub2-bhyve
复制代码
从 ISO 文件中加载 Linux® 内核
bash 复制代码
​​​​​​​grub-bhyve -m device.map -r cd0 -M 1024M linuxguest

执行后进入光盘安装debian的选择界面,但是选了之后回车就退出了。刚开始不知道为什么会退出,还以为出问题了,其实就应该是这样。

如果没有进入光盘启动界面,就需要自己手工在grub里面输入boot:

grub> ls

(hd0) (cd0) (cd0,msdos1) (host)

grub> ls (cd0)/isolinux

boot.cat boot.msg grub.conf initrd.img isolinux.bin isolinux.cfg memtest

splash.jpg TRANS.TBL vesamenu.c32 vmlinuz

grub> linux (cd0)/isolinux/vmlinuz

grub> initrd (cd0)/isolinux/initrd.img

grub> boot

安装ubuntu linux

现在 Linux® 内核就加载完毕了,可以启动客户机,启动ubuntu安装:

bash 复制代码
bhyve -A -H -P -s 0:0,hostbridge -s 1:0,lpc -s 2:0,virtio-net,tap0 -s 3:0,virtio-blk,./linux.img -s 4:0,ahci-cd,./ubuntu-18.04.6-server-amd64.iso -l com1,stdio -c 4 -m 1024M linuxguest

当然最终我们是选择了安装dibian:

安装debian linux

bash 复制代码
bhyve -A -H -P -s 0:0,hostbridge -s 1:0,lpc -s 2:0,virtio-net,tap0 -s 3:0,virtio-blk,./linux.img -s 4:0,ahci-cd,./debian.iso -l com1,stdio -c 2 -m 1024M linuxguest

后面就是按部就班的安装过程了。

安装的时候可以设置软件包下载镜像,镜像源选了华为云。

mirrors.huaweicloud.com

安装debian完成后,选择重启机器,就会退出虚拟系统。

启动debian linux

每次启动之前,都要先加载内核:

bash 复制代码
grub-bhyve -m device.map -r hd0,msdos1 -M 1024M linuxguest

然后引导进入虚拟机:

bash 复制代码
bhyve -A -H -P -s 0:0,hostbridge -s 1:0,lpc -s 2:0,virtio-net,tap0 -s 3:0,virtio-blk,./linux.img -l com1,stdio -c 4 -m 1024M linuxguest

启动真是简洁明快啊,也就1-2秒就进入登录界面了:

bash 复制代码
rdmsr to register 0xcd on vcpu 0
wrmsr to register 0x140(0) on vcpu 0
wrmsr to register 0x140(0) on vcpu 1
wrmsr to register 0x140(0) on vcpu 2
wrmsr to register 0x140(0) on vcpu 3
rdmsr to register 0x34 on vcpu 1
rdmsr to register 0xc0011029 on vcpu 3
Unhandled ps2 mouse command 0xe1
/dev/vda1: clean, 36301/987360 files, 505236/3943936 blocks
Unhandled ps2 mouse command 0x88
rdmsr to register 0x64d on vcpu 0

Debian GNU/Linux 12 debian ttyS0

debian login: xxxx
Password: 
Linux debian 6.1.0-21-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.1.90-1 (2024-05-03) x86_64

The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.

这样就可以进入debian愉快的玩耍拉!

持久化配置

要配置系统在启动时运行 bhyve 虚拟机,请对相应文件进行如下配置:

  1. /etc/sysctl.conf

    复制代码
    net.link.tap.up_on_open=1
  2. /etc/rc.conf

    复制代码
    cloned_interfaces="bridge0 tap0"
    ifconfig_bridge0="addm igb0 addm tap0"
    kld_list="nmdm vmm"

安装bvm管理bhyve

为了更好的管理hbyve,我们可以安装bvm管理软件。bvm ,是FreeBSD下的一个开源的虚拟机监控器 (hypervisor),它使用FreeBSD的Capsicum沙箱框架提供安全性。

bash 复制代码
pkg install bvm

在第一次运行bvm --ls 的时候,会提示做哪些操作:

bash 复制代码
# bvm can't run, you need to add the following lines to /boot/loader.conf
vmm_load="YES"
if_bridge_load="YES"
if_tap_load="YES"
# In order to help you solve the NAT reflow problem, 
# you need to add the following line to /boot/loader.conf
ipfw_load="YES"
ipfw_nat_load="YES"
libalias_load="YES"
net.inet.ip.fw.default_to_accept=1
# please edit '/usr/local/etc/bvm/bvm.conf' first
vmdir=/your/vm/dir/path/

也就是最主要的是先编辑/usr/local/etc/bvm/bvm.conf文件,加入vmdir目录配置。然后再将上面配置语句写入/boot/loader.conf文件中。

使用bvm创建虚拟机

bash 复制代码
bvm --create Node-1

会问很多问题,就用数字回答就行

bash 复制代码
Welcome to Bhyve Vm Manager
---------------------------
Enter os type: 
[0]. FreeBSD
[1]. OpenBSD
[2]. NetBSD
[3]. Debian
[4]. Debian_LVM
[5]. Ubuntu
[6]. Kali
[7]. CentOS
[8]. openSUSE
[9]. openSUSE_LVM
[a]. Gentoo
[b]. Fedora
[c]. TrueOS
[d]. Windows10
[e]. WinServer2016
[f]. pfSense
[g]. OPNsense
[h]. Other
Enter os type: 5
Enter vm CPUs: 2
Enter vm RAM (e.g. 512m): 512M
Enter cd status: 
[0]. on
[1]. off
Enter cd status: 0
Enter iso path for CD-ROM: /root/bhyve
Enter a iso file: 
[0]. debian.iso
[1]. ubuntu.iso
[2]. FreeBSD-14.1-BETA3-amd64-bootonly.iso
[3]. ubuntu-18.04.6-server-amd64.iso
[4]. debian-12.5.0-amd64-netinst.iso
Enter a iso file: 1
Enter boot from: 
[0]. cd0
[1]. hd0
Enter boot from: 0
Enter uefi type: 
[0]. none
[1]. uefi
[2]. uefi_csm
Enter uefi type: 0
Enter hostbridge: 
[0]. hostbridge
[1]. amd_hostbridge
Enter hostbridge: 0
Enter auto booting: 
[0]. no
[1]. yes
Enter auto booting: yes
input invalid
[0]. no
[1]. yes
Enter auto booting: 1
Enter booting sequence index (1~1000): 10
Enter booting estimate time (1~1000 secs.): 10
[0]. name          : Node-1
[1]. os            : Ubuntu
[2]. cpus          : 2
[3]. ram           : 512m
[4]. CD            : on
[5]. iso path      : /root/bhyve/ubuntu.iso
[6]. boot from     : cd0
[7]. uefi type     : none
[8]. hostbridge    : hostbridge
[9]. auto boot     : yes
[a]. boot index    : 10
[b]. boot time     : 10
[c]. disk config   
[d]. network config
[e]. cancel        

Enter an number to edit or 'ok' to complet: c
Enter vm number of disks: 1
Enter vm disk(0) size (e.g. 5g): 10g
Enter ZFS support: 
[0]. on
[1]. off
Enter ZFS support: on
input invalid
[0]. on
[1]. off
Enter ZFS support: 0
Enter zpool: 
[0]. zroot/ROOT/default
[1]. zroot/tmp
[2]. zroot/home
[3]. zroot/usr/src
[4]. zroot/usr/ports
[5]. zroot/var/log
[6]. zroot
[7]. zroot/var/audit
[8]. zroot/var/crash
[9]. zroot/home/skywalk
[a]. zroot/var/mail
[b]. zroot/var/tmp
Enter zpool: 0
Enter storage interface: 
[0]. SATA hard-drive [ahci-hd]
[1]. Virtio block storage interface [virtio-blk]
Enter storage interface: 1
[0]. disk number  : 1
[1]. disk(0) size : 10g
[2]. ZFS support  : on
[3]. ZFS pool     : zroot/ROOT/default
[4]. interface    : virtio-blk
[5]. go back      
Enter an number: 5
---------------------------
[0]. name          : Node-1
[1]. os            : Ubuntu
[2]. cpus          : 2
[3]. ram           : 512m
[4]. CD            : on
[5]. iso path      : /root/bhyve/ubuntu.iso
[6]. boot from     : cd0
[7]. uefi type     : none
[8]. hostbridge    : hostbridge
[9]. auto boot     : yes
[a]. boot index    : 10
[b]. boot time     : 10
[c]. disk config   
[d]. network config
[e]. cancel        

Enter an number to edit or 'ok' to complet: d
Enter vm number of nics: 1
Enter nic-0 network mode: 
[0]. Bridged
[1]. NAT
Enter nic-0 network mode: 0
Select the binding device: 
[0]. igb0
[1]. switch0  10.0.1.0/24
[2]. switch1  10.0.2.0/24
[3]. switch2  10.0.3.0/24
[4]. switch3  
[5]. switch4  
[6]. switch5  
[7]. switch6  
[8]. switch7  
Select the binding device: 0
Enter IP-Address: 
[0]. none
[1]. dhcp
[2]. static
Enter IP-Address: 1
Enter network interface: 
[0]. Intel e82545 network interface [e1000]
[1]. Virtio network interface [virtio-net]
Enter network interface: 1
[0]. NIC numbers   : 1
[1]. nic-0 mode    : Bridged
[2]. nic-0 bind    : igb0
[3]. nic-0 ip      : dhcp
[4]. interface     : virtio-net
[5]. add a nic     
[6]. go back       
Enter an number: 6
---------------------------
[0]. name          : Node-1
[1]. os            : Ubuntu
[2]. cpus          : 2
[3]. ram           : 512m
[4]. CD            : on
[5]. iso path      : /root/bhyve/ubuntu.iso
[6]. boot from     : cd0
[7]. uefi type     : none
[8]. hostbridge    : hostbridge
[9]. auto boot     : yes
[a]. boot index    : 10
[b]. boot time     : 10
[c]. disk config   
[d]. network config
[e]. cancel        

Enter an number to edit or 'ok' to complet: ok

创建好就可以启动了

开始启动bvm虚拟机

bash 复制代码
bvm --start Node-1

启动之后,可以用bvm --ls 看到状态信息:

bvm --ls
NAME		GUEST		CPU	MEMORY	DISK		STATE
Node-1		Ubuntu		2	512M	[1]10G		on

可以使用bvm --login 登录虚拟机

bvm --login Node-1

然后就可以在命令行下开始装机拉!

其它bvm指令

关机命令:

bvm --poweroff Node-1

复制虚拟机,使用

bvm --clone Node-1 Node-2

如果虚拟机被关机挂住,可以ps找到进程kill掉

ps -aux |grep bvm
root    8525   0.0  0.0  13184  2696  0  I+   09:48       0:00.00 bvm --login Node-1
root    9117   0.0  0.0  12808  2384  1  S+   10:09       0:00.00 grep bvm
root    8430   0.0  0.0  13184  2700  2  Is+  09:47       0:00.01 bvmb Node-1
root    9020   0.0  0.0  13184  2708  3  Ss+  10:08       0:00.01 bvmb Node-2
root@fbhost:~/bhyve # kill 8430

总结

FreeBSD原生的bhyve虚拟机管理系统兼容性好、高效稳定、自动化程度高,全部操作都可以在命令行下搞定,非常适合大规模云计算环境使用。同时也非常适合配置较低的机器使用。比如这台服务器是j9000芯片+8G内存+32G Mini 硬盘,却可以同时开3个虚拟机,如果用ESxi虚拟的话,这个配置可能都达不到ESXi的安装需求,更不要说开虚拟机了。

bvm拥有直观的交互界面,即使完全不懂bhyve的初学者也能轻松上手,很快就创建出虚拟机子系统。bvm还有克隆功能,可以快速创建多个虚拟机系统。

调试

linux ubuntu客户端grub-bhyve启动安装之后退出

使用 sysutils/grub2-bhyve 从 ISO 文件中加载 Linux® 内核:

复制代码
grub-bhyve -m device.map -r cd0 -M 1024M linuxguest

可以看到出来选择界面了:

+--------------------------------------------------------------------+

|Install Ubuntu Server |

|OEM install (for manufacturers) |

|Install MAAS Region Controller |

|Install MAAS Rack Controller |

|Check disc for defects |

|Rescue a broken system |

|Boot and Install with the HWE kernel |

但是选了选项之后就会退出。

想明白了,这里就应该退出啊,退出之后就可以下一步启动虚拟机了啊

有的设备grub-bhyve启动后进入grub没有光盘

grub> ls

(hd0) (host)

原来是device.map文件里面的光盘路径写错了

设置grub-bhyve启动设置更多内存报错

grub-bhyve -m device.map -r cd0 -M 2024M linuxguest

Could not setup memory for VM

Error in initializing VM

发现只能设为1024,设为其它值就报错。

原来是grub-bhyve设置一次后,后面再设为其它数值就会报错。要启动一次虚拟机之后,才能重新设置。

bhyve启动linux虚拟报错No such file or directory

bhyve -A -H -P -s 0:0,hostbridge -s 1:0,lpc -s 2:0,virtio-net,tap0 -s 3:0,virtio-blk,./linux.img \ > -s 4:0,ahci-cd,./debian-12.5.0-amd64-netinst.iso -l com1,stdio -c 4 -m 1024M linuxguest bhyve: Could not open backing file: ./debian-12.5.0-amd64-netinst.iso : No such file or directory Device emulation initialization error: No such file or directory root@fbhost:~/bhyve # sh: turning off NDELAY mode

问题是文件在的啊

把命令里面的空格以及不该有的字符都重新处理一下,问题解决

原来/debian-12.5.0-amd64-netinst.iso后面多了一些字符导致的,从手册cp过来的时候有个 \ 换行符,在删掉换行符的时候留多了空格或tab等其它字符(试了空格不会影响,应该是手册里命令带的tab符号的干扰)。

bhyve启动linux虚拟报错could not activate CPU 0: Device busy

执行命令:

bhyve -A -H -P -s 0:0,hostbridge -s 1:0,lpc -s 2:0,virtio-net,tap0 -s 3:0,virtio-blk,./linux.img -s 4:0,ahci-cd,./ubuntu-18.04.6-server-amd64.iso -l com1,stdio -c 4 -m 1024M linuxguest

报错改了,变成:bhyve: could not activate CPU 0: Device busy

从网上搜索,没有搜到类似的问题。cpu0被占用,真的找不到解决方法,曾一度怀疑是j1900cpu的问题。后来才知道,可能是前面实验的时候占用了cpu,用命令清一下即可:

bhyvectl --destroy --vm=linuxguest

加载linux内核报错Could not reinit VM linuxguest

grub-bhyve -m devicedebian.map -r cd0 -M 1024M linuxguest

Could not reinit VM linuxguest

Error in initializing VM

这就证明加载成功了,不能再重复加载了。

报错linux虚拟机报Abort trap

~/bhyve # bhyve -A -H -P -s 0:0,hostbridge -s 1:0,lpc -s 2:0,virtio-net,tap0 -s 3:0,virtio-blk,./linux.img -s 4:0,ahci-cd,./debian.iso -l com1,stdio -c 2 -m 1024M linuxguest

vm exit[0]

reason VMX

rip 0x0000000000000000

inst_length 0

status 0

exit_reason 33 (VM-entry failure due to invalid guest state)

qualification 0x0000000000000000

inst_type 0

inst_error 0

Abort trap

不明白什么原因,反正只要前面步骤对,bhyve就不会出这些乱七八糟的报错。

bvm启动报错can't create Bridged

bvm --start Node-1

can't create Bridged

原来是创建Bridge的时候,错选了实体0号网卡。需要选择虚拟的1-3号网卡。

bvm --config Node-1 进入配置后,重新设置使用1号网卡,在启动,就正常了

bvm启动报错duplicate session: Node-1

bvm --start Node-1

duplicate session: Node-1

ps发现有个bvm的进程,kill掉就好了

root@fbhost:~/bhyve # ps -aux |grep bvm

root 8381 0.0 0.0 12808 2372 0 S+ 09:47 0:00.00 grep bvm

root 5625 0.0 0.0 13184 2692 3 Is+ 23:20 0:00.01 bvmb Node-1

kill 5625

相关推荐
深情的小陈同学2 小时前
Linux —— udp实现群聊代码
linux·运维·服务器
啵一杯5 小时前
leetcode621. 任务调度器
服务器·前端·数据结构·算法·c#
KookeeyLena85 小时前
提取出来的ip与我原本的ip是在同一个区吗
服务器·网络协议·tcp/ip
鼠鼠龙年发大财7 小时前
【tbNick专享】虚拟机域控、成员服务器、降级等管理
运维·服务器
Lilixxs7 小时前
MobaXterm基本使用 -- 服务器状态、批量操作、显示/切换中文字体、修复zsh按键失灵
运维·服务器·前端
醉颜凉8 小时前
银河麒麟桌面操作系统如何添加WPS字体
运维·服务器·kylin·wps·麒麟·wps添加字体
江凡心8 小时前
Qt 每日面试题 -5
服务器·数据库·qt·学习·面试
EterNity_TiMe_8 小时前
【Linux基础IO】深入解析Linux基础IO缓冲区机制:提升文件操作效率的关键
linux·运维·服务器·开发语言·学习·性能优化·学习方法
苏湘涵9 小时前
进程的那些事--实现shell
linux·运维·服务器
宝哈9 小时前
认识 Linux操作系统
linux·运维·服务器·开发语言·c++·算法