libvirt provides lots of tools to manage VM or virtual disk, let’s take a quick look about them.
VM management
virt-install: install VM etc
virsh: start, stop, destroy VM, monitor and collect stats of VM etc
virt-manager: GUI for manage VM
Virtual disk management(provided by libguestfs)
guestfish: interactive shell to manage disk(–verbose for debug)
guestmount/guestumount: mount/umount disk to host path(–verbose for debug)
virt-cat/virt-copy-in/virt-copy-out/virt-format/virt-xxx: commands to manage virtual disk(–berbose for debug)
ALL libvirt tools(included libguestfs tools) communicate with libvirt daemon to manage vm or disk by default, but you can direct with qemu if libvirt is not thre
# this will install libvirt-client(virsh) and libvirt-daemon(libvirtd) $ yum install -y libvirt
# install kvm and bios to start vm $ yum install -y kvm $ yum install -y seabios
$ libvirtd --version
$ virsh -v
# By default virsh will connect with local libvirt by unix socket # but can connect with remote libvirtd # ssh $ virsh --connect qemu+ssh://remote/system # plain tcp $ virsh --connect qemu+tcp://remote:port/system
# show the connection $ virsh uri
# create a vm, for QEMU and LXC, libvirtd stores vm XML to disk and in memory
# DO NOT edit the XML directly from disk at in that way, there is no validation!!! # if you edit the on-disk XML is a VM that simply vanishes the next time libvirtd is restarted after the edit. # The VM disappears from libvirt because the XML has become invalid, after which libvirt can't do anything with it
$ virsh dumpxml $domain
# change domain config from xml, restart it to make it work $ virsh shutdown $domain $ virsh edit $domain $ virsh start $domain
# delete a vm and related files $ virsh destroy $domain $ virsh undefine $domain -remove-all-storage
# attach/detach disk to a vm # --target is the device hit, it's a must option # NOTE: vdc may be not used by guest if it's not the first available device, say, if vdb is free, even you proivdes vdc, vdb is used # that means if you check the config, it shows vdc, but actually, vdb is used inside vm, hence --target should be the first available device if expected as set
# check existing device from xml, dev name may be not the name used inside guest $ virsh domblklist centos Target Source ------------------------------------------------ vda /home/data/tmp/vm100.qcow2 vdc /dev/loop0
# check the real dev name used inside guest, vda is used by /dev/loop0 while vdb is used for /home/data/tmp/vm100.qcow2 $ virsh qemu-agent-command vm100 '{"execute":"guest-exec","arguments":{"path":"lsblk","capture-output":true}}' {"return":{"pid":980}}
After enable this channel, on host a unix socket is created for the VM at /var/lib/libvirt/qemu/channel/target/domain-3-centos/org.qemu.guest_agent.0, you can also set the path of socket with path attribute in source tag like <source mode='bind' path='/var/lib/libvirt/test.agent.0'/> Inside the domain, a char device(/dev/virtio-ports/org.qemu.guest_agent.0) is exported to user by virtio, write/read to char dev inside guest OS, data is available at unix socket on host.
# open with read only $ virsh qemu-agent-command ${DOMAIN}'{"execute":"guest-file-open", "arguments":{"path":"/tmp/test.txt","mode":"r"}}' {"return":1000} # guest-file-read, you can call these several times to get the whole file data, then close it # this is probably used for large file $ virsh qemu-agent-command ${DOMAIN}'{"execute":"guest-file-read", "arguments":{"handle":1000}}' # read with large buffer $ virsh qemu-agent-command ${DOMAIN}'{"execute":"guest-file-read", "arguments":{"handle":1000, "count":1000000}}' # guest-file-close $ virsh qemu-agent-command ${DOMAIN}'{"execute":"guest-file-close", "arguments":{"handle":1000}}'
# run arbitrary command, run `any` command inside guest $ virsh qemu-agent-command ${DOMAIN}'{"execute":"guest-exec","arguments":{"path":"mkdir","arg":["-p","/root/.ssh"],"capture-output":true}}' {"return":{"pid":911}}
# get the content of a file, it opens the file then close it every time # if file is large, output is truncated!!!, so that you can only the first part of a larger file!!!! use guest-file-read instead for large file $ virsh qemu-agent-command ${DOMAIN}'{"execute":"guest-exec","arguments":{"path":"cat","arg":["/var/log/plugin.log"],"capture-output":true}}'
# response is encrypted base64 $ virsh qemu-agent-command ${DOMAIN}'{"execute":"guest-exec-status","arguments":{"pid":911}}'
libguestfs is a C library tool for creating, accessing and modifying virtual machine disk images. You can look inside the disk images, modify the files they contain, create them from scratch, resize them, and much more. yum install libguestfs libguestfs-tool libguestfs works with any disk image, including ones created in VMware, KVM, qemu, VirtualBox, Xen, and many other hypervisors
guestfish is an interactive shell that you can use from the command line or from shell scripts to access guest virtual machine file systems. All of the functionality of the libguestfs API is available from the shell, guestfish shell provides lots of built-in commands(600+) you can use to access guest file systems, it's a super-set of virt-xxx command below(--verbose for debug).
#===========================start a new vm permenantly, destroy it when quit the fish shell==== # two ways to run guestfish either by providing a disk image or domain name of libvirt # -i means inspect the image and mount the file systems(mount requires a vm started by guestfish) # 1. guestfish will start a new vm by libvirt and mount domain disk # --verbose to debug issue $ guestfish --ro -d $domain -i ><fs> df-h Filesystem Size Used Avail Use% Mounted on tmpfs 96M 112K 96M 1% /run /dev 237M 0 237M 0% /dev /dev/sda1 8.0G 1.2G 6.9G 14% /sysroot
# NOTE use TAB for command completion!!!
$ virsh list Id Name State ---------------------------------------------------- 4 guestfs-cmurc2zne6ot9rt8 running
# 2. from a disk image to start a new vm(this will call libvirt to start a new vm as well) $ guestfish -a /path/to/disk/image -i ><fs> df-h
#===========================start a new vm temporarily, destroy it when get the command result=== $ virt-filesystems -a CentOS-7-x86_64-GenericCloud-1503.qcow2 /dev/sda1 $ virt-filesystems -d $domain /dev/sda1
########################the new vm start by guest fish####################################### # vm100 has its disk /root/jason/vm/test/vm100.qcow2 $ guestfish --ro -d vm100 -i Welcome to guestfish, the guest filesystem shell for editing virtual machine filesystems and disk images.
Type: 'help'forhelp on commands 'man' to read the manual 'quit' to quit the shell
Operating system: CentOS Linux release 7.8.2003 (Core) /dev/sda1 mounted on /
# disk /tmp/libguestfsKuVs4B/overlay1 whoes backing file is /root/jason/vm/test/vm100.qcow2!!! $ file /tmp/libguestfsKuVs4B/overlay1 /tmp/libguestfsKuVs4B/overlay1: QEMU QCOW Image (v3), has backing file (path /root/jason/vm/test/vm100.qcow2), 8589934592 bytes
NOTE
The guest fish vm started by libvirt by default, you can LIBGUESTFS_BACKEND=direct to start it directly
libvirtd is not a must for guestfish, but if you use -d $domain option, you must start libvirtd as guest fish need to get the info(disk info) from libvirtd
virsh command groups
vm xml
Use virsh to edit VM XML
Virtual Networks: net-edit, net-dumpxml
Storage Pools: pool-edit, pool-dumpxml
Storage Volumes: vol-edit, vol-dumpxml
Interfaces: iface-edit, iface-dumpxml
Redefining the XML of a running machine will not change anything, the changes will take effect after the next VM start up
Command groups
Domain management
virsh console
virsh define (define a guest domain from xml file)
virsh destroy(immediately terminates a running vm)
virsh undefine(remove cfg for an inactive vm)
virsh domjobinfo(return info about jobs running on a domain)
virsh dumpxml(output current vm info /var/run/libvirt/qemu/$domain.xml to stdout)
virsh edit(edit the XML cfg for a vm located at /etc/libvirtd/qemu/$domain.xml, take affect at next virsh start)
shutdown/reboot gracefully from guest like type command from guest
destroy/reset forcely from outside like press power button
virsh setmem/setvcpus
virsh vcpuinfo/vcpucount/vcpupin
virsh domiflist
virsh attach-device (attach device from an XML file, device can be interface, disk etc)
Domain monitor
virsh domblkinfo / dominfo
virsh domblkstat /domifstat /dommemstat
virsh domstate
virsh list –all
Domain Snapshot
virsh snapshot-create
virsh snapshot-delete
virsh snapshot-list
virsh snapshot-revert
Host and Hypervisor
virsh capabilities
virsh nodeinfo
virsh uri
Network Interface
virsh iface-dumpxml
virsh iface-list / iface-name / iface-mac
virsh iface-define / iface-undefine
virsh iface-start / iface-destroy
virsh iface-edit
Network
virsh net-create / net-destroy
virsh net-edit / net-dumpxml
virsh net-define / net-undefine
virsh net-start
virsh net-info / net-list / net-name
Node device
virsh nodedev-create
virsh nodedev-reattach / nodedev-dettach
virsh nodedev-destroy
virsh nodedev-dumpxml
virsh nodedev-list
Storage pool
virsh pool-create / pool-destroy / pool-delete
virsh pool-define / pool-undefine
virsh pool-start
virsh pool-list / pool-dumpxml
virsh pool-edit / pool-info
Storage Volume
virsh vol-create / vol-delete
virsh vol-info /vol-list
event
libvirt supports several type events can be monitored by client, they are domain event, qemu monitor event, network event, storage pool event, nodedev event
virsh event(domain event)
virsh qemu-monitor-event
virsh net-event
virsh nodedev-event
virsh pool-event
virsh secret-event
blk
virsh domblklist centos10
virsh attach-disk /detach-disk
libvirtd supports three modes of attaching a disk to vm, --config, --live, --persistent by default it’s --live
--config, new disk setting only write to /etc/libvirt/qemu/$doman.xml, only take affect after virsh destroy then virsh start. virsh reset, virsh reboot is not sufficient.
--live, new disk setting only in memory of running vm, you can see it by virsh dumpxml $domain or /var/run/libvirt/qemu/$domain.xml, take affect immediately, no written to /etc/libvirt/qemu/$doman.xml, virsh reset and virsh reboot you still can see it, but if you virsh destroy and virsh start, the new disk is gone as it’s not written to that file, /var/run/libvirt/qemu/$domain.xml is deleted after virsh destroy, ``/etc/libvirt/qemu/$doman.xmlis used forvirsh start`.
--persistent == --config + --live, that means new disk setting is in memory(/var/run/libvirt/qemu/$domain.xml) and disk(/etc/libvirt/qemu/$doman.xml)
--current, If the VM is offline, use –config. If the VM is running, use –live.
# /etc/libvirt/libvirtd.conf: global conf of libvirtd # /etc/sysconfig/libvirtd: override libvirtd.conf # /usr/lib/systemd/system/libvirtd.service: systemd service # /etc/libvirt/qemu/networks/default.xml: default network
# /var/run/libvirt: runtime of daemon, like daemon socket/pid of each vm $ ls /var/run/libvirt/ hostdevmgr libvirt-admin-sock libvirt-sock libvirt-sock-ro lxc network qemu storage virtlockd-sock virtlogd-sock
# hostdevmgr network storage: setting for device, networking(rules), volume(pool, local disk) # libvirt-admin-sock libvirt-sock libvirt-sock-ro: sock for admin, readonly etc # lxc qemu: xml/pid of each instance, will go when boots # virtlockd-sock virtlogd-sock: sock of locked and virtlogd
$ ls /var/run/libvirt/qemu/ centos.pid centos.xml
# /var/log/libvirt: logs of VM from vm console and part logs from libvirtd $ ls /var/log/libvirt/qemu/ centos.log
# by default libvirtd writes logs to /var/log/message(centos) /var/log/syslog(ubuntu) # default: log_outputs="3:syslog:libvirtd" # change it to any file by editing /etc/libvirt/libvirtd.conf # 1: DEBUG # 2: INFO # 3: WARNING # 4: ERROR # only log of level large or equal to 2 are sent to file log_level = 1 log_outputs="2:file:/var/log/libvirt/libvirtd.log"
# /etc/libvirt: daemon conf and persistent XML of VMS located at qemu/ $ ls /etc/libvirt/ libvirt-admin.conf libvirtd.conf nwfilter/ qemu.conf virtlogd.conf libvirt.conf qemu/ virtlockd.conf
$ ls /var/lib/libvirt dnsmasq filesystems/ images/ network/ qemu/
# snapshot saves the xml of snapshot, data of snapshot is saved into image by default(internal snapshot)!! # save/ holds the managed save(cpu/memory) $ ls /var/lib/libvirt/qemu/ channel/ domain-1-centos save/ snapshot/
# socket of this Vm like qmp socket etc $ ls /var/lib/libvirt/qemu/domain-1-centos master-key.aes monitor.sock
# socket of this vm for QGA channel $ ls /var/lib/libvirt/qemu/channel/target/domain-1-centos/ org.qemu.guest_agent.0
Difference between qemu:///system and qemu:///session, Which one should I use?
All ‘system’ URIs (be it qemu, lxc, uml, …) connect to the libvirtd daemon running as root which is launched at system startup. Virtual machines created and run using 'system' are usually launched as root
All ‘session’ URIs launch a libvirtd instance as your local user, and all VMs are run with local user permissions. You will definitely want to use qemu:///system if your VMs are acting as servers. VM autostart on host boot only works for 'system', and the root libvirtd instance has necessary permissions to use proper networking via bridges or virtual networks
Migration
There are two primary types of migration with QEMU/KVM and libvirt:
Plain migration: The source host VM opens a direct unencrypted TCP connection to the destination host for sending the migration data. Unless a port is manually specified, libvirt will choose a migration port in the range 49152-49215, which will need to be open in the firewall on the remote host.
Tunneled migration: The source host libvirtd opens a direct connection to the destination host libvirtd for sending migration data. This allows the option of encrypting the data stream. This mode doesn’t require any extra firewall configuration, but is only supported with qemu 0.12.0 or later, and libvirt 0.7.2.
For all QEMU/KVM migrations, libvirtd must be running on the source and destination host.
For tunneled migration, no extra configuration should be required, you simply need to pass the –tunnelled flag to virsh migrate.
For plain unencrypted migration, the TCP port range 49152-49215 must be opened in the firewall on the destination host.
$ virt-install --name guest1-rhel7 --memory 2048 --vcpus 2 --disk /home/data/tmp/CentOS-7-x86_64-GenericCloud-1503.qcow2 --import --os-type linux --wait 0 --network default # OR $ virt-install --name guest1-rhel7 --memory 2048 --vcpus 2 --disk /home/data/tmp/CentOS-7-x86_64-GenericCloud-1503.qcow2 --import --os-type linux --wait 0 --network none # must set wait 0, otherwise, it will show 'Domain installation still in progress. Waiting for installation to complete'
How to install a VM from a terminal
Here we use image from remote by –location parameters
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
-l LOCATION , --location=LOCATION Distribution tree installtion source. virt-install can recognize certain distribution trees and fetches a bootable kernel/initrd pair to launch the install.
The "LOCATION" can take one of the following forms: DIRECTORY Path to a local directory containing an installable distribution image nfs:host:/path or nfs://host/path An NFS server location containing an installable distribution image http://host/path An HTTP server location containing an installable distribution image ftp://host/path An FTP server location containing an installable distribution image
ubuntu(different versions has different url) --location 'http://archive.ubuntu.com/ubuntu/dists/trusty/main/installer-amd64/' --location 'http://archive.ubuntu.com/ubuntu/dists/bionic/main/installer-amd64/'
virt-sysprep(only support linux!!!) can reset or unconfigure a virtual machine so that clones can be made from it. Steps in this process include removing SSH host keys, removing persistent network MAC configuration, and removing user accounts. virt-sysprep can also customize a virtual machine, for instance by adding SSH keys, users or logos. Each step can be enabled or disabled as required..
NOTE virt-sysprep modifies the guest or disk image in place
The virtual machine must be shut down before.
disk images must not be edited concurrently.
virt-sysprep depends on libvirt running by default
export LIBGUESTFS_BACKEND=direct virt-sysprep ..(start qemu without libvirtd)
1 2 3 4 5 6 7 8 9 10 11 12 13
# NO wildcards supported for below three # --copy SOURCE:DEST inside vm # --copy-in LOCALPATH:REMOTEDIR from host to guest # --move SOURCE:DEST inside vm
# --mkdir DIR # --delete PATH support wildcards
# --install PKG,PKG. use guest pkg manager and host network # --uninstall PKG,PKG use guest pkg manager
# This will start a temporary vm $ virt-sysprep --root-password password:$new --uninstall cloud-init --selinux-relabel -a CentOS-7-x86_64-GenericCloud.qcow2
# There are two ways to do this ##################Way 1################################################ # if qemu-ga is running, we can change it runtime, no need to restart vm # QGA: guest-set-user-password $virsh set-user-password vm100 root root
##################Way 2################################################ # if no qemu-ga or qemu-ga is not working use this way # shutdown it first $ virsh shutdown $domain
# generate your password $ openssl passwd -1 $yourpassword $6$FU5Nl9oxxxx
# mount the disk with read/write mode(--verbose for debugging) $ guestfish --rw -a /var/lib/libvirt/images/debian9-vm1.qcow2 -i
# oneshot mount $ guestmount -a disk.img -i /tmp/disk --verbose
><fs> vi /etc/shadow # modify password root:$6$FU5Nl9oxxxx:17572:0:99999:7:::
><fs> flush ><fs> quit
# OR you can do it with just one command who does simliar operation for you $ virt-sysprep --root-password password:$new -a CentOS-7-x86_64-GenericCloud.qcow2
By default the client library doesn’t produce any logs and usually usually it’s not very interesting on its own anyway. The library configuration of logging is through 3 environment variables allowing to control the logging behaviour:
LIBVIRT_DEBUG: it can take the four following values:
1 or “debug”: asking the library to log every message emitted, though the filters can be used to avoid filling up the output
2 or “info”: log all non-debugging information
3 or “warn”: log warnings and errors, that’s the default value
Input devices allow interaction with the graphical framebuffer in the guest virtual machine virtual machine. that means.
For Desktop, you should configure mouse input, otherwise, you can only use keyboard
For Server without GUI, mouse input can be disable, as it no effect at all.
reduce disk image file not disk size
As most of time, disk is thin-provisioned, disk file grows when needed, but after disk file grew, it can not be resize automatcially even you delete vm inside VM, lots of free space of this disk.
NOTE
The virtual machine must be shut down
disk images must not be edited concurrently.
1 2
# the new image is smaller(No snapshot is lost) $ qemu-img convert -O qcow2 centos7.img out.qcow2
run kvm machine from another vm
if you plan to run vm from vm by libvirt, make sure nested virtualization is enabled on host, otherwise, you will meet error from libvirtd.log like this invalid argument: could not find capabilities for arch=x86_64 domaintype=kvm, the pass nested virtualization to vm who will plan to start new vm.
# if you can run vm from another vm, check it by that vm # run this in virtual vm which plans to start another vm. $ virt-host-validate QEMU: Checking for hardware virtualization : PASS--->nested virtulization is enabled QEMU: Checking if device /dev/kvm exists : PASS QEMU: Checking if device /dev/kvm is accessible : PASS QEMU: Checking if device /dev/vhost-net exists : PASS QEMU: Checking if device /dev/net/tun exists : PASS QEMU: Checking for cgroup 'memory' controller support : PASS QEMU: Checking for cgroup 'memory' controller mount-point : PASS QEMU: Checking for cgroup 'cpu' controller support : PASS QEMU: Checking for cgroup 'cpu' controller mount-point : PASS QEMU: Checking for cgroup 'cpuacct' controller support : PASS QEMU: Checking for cgroup 'cpuacct' controller mount-point : PASS QEMU: Checking for cgroup 'cpuset' controller support : PASS QEMU: Checking for cgroup 'cpuset' controller mount-point : PASS QEMU: Checking for cgroup 'devices' controller support : PASS QEMU: Checking for cgroup 'devices' controller mount-point : PASS QEMU: Checking for cgroup 'blkio' controller support : PASS QEMU: Checking for cgroup 'blkio' controller mount-point : PASS QEMU: Checking for device assignment IOMMU support : WARN (No ACPI DMAR table found, IOMMU either disabled in BIOS or not supported by this hardware platform) LXC: Checking for Linux >= 2.6.26 : PASS LXC: Checking for namespace ipc : PASS LXC: Checking for namespace mnt : PASS LXC: Checking for namespace pid : PASS LXC: Checking for namespace uts : PASS LXC: Checking for namespace net : PASS LXC: Checking for namespace user : PASS LXC: Checking for cgroup 'memory' controller support : PASS LXC: Checking for cgroup 'memory' controller mount-point : PASS LXC: Checking for cgroup 'cpu' controller support : PASS LXC: Checking for cgroup 'cpu' controller mount-point : PASS LXC: Checking for cgroup 'cpuacct' controller support : PASS LXC: Checking for cgroup 'cpuacct' controller mount-point : PASS LXC: Checking for cgroup 'cpuset' controller support : PASS LXC: Checking for cgroup 'cpuset' controller mount-point : PASS LXC: Checking for cgroup 'devices' controller support : PASS LXC: Checking for cgroup 'devices' controller mount-point : PASS LXC: Checking for cgroup 'blkio' controller support : PASS LXC: Checking for cgroup 'blkio' controller mount-point : PASS
DESCRIPTION List event types, or waitfor domain events to occur
OPTIONS --domain <string> filter by domain name, id or uuid --event <string> which event type to waitfor --all waitfor all events instead of just one type --loop loop until timeout or interrupt, rather than one-shot --timeout <number> timeout seconds --list list valid event types --timestamp show timestamp for each printed event
# all events of all domains $ virsh event --all --loop --timestamp
# default remote port is 16509 $ virsh -c qemu+tcp://172.17.0.3/system event --event lifecycle --loop
$ virsh qemu-monitor-event --help NAME qemu-monitor-event - QEMU Monitor Events
OPTIONS --domain <string> filter by domain name, id or uuid --event <string> filter by event name --pretty pretty-print any JSON output --loop loop until timeout or interrupt, rather than one-shot --timeout <number> timeout seconds --regex treat event as a regex rather than literal filter --no-case treat event case-insensitively --timestamp show timestamp for each printed event
# all qemu monitor event of all domains $ virsh qemu-monitor-event --loop --timestamp
monitor performance of vm
Some platforms allow monitoring of performance of the virtual machine and the code executed inside. To enable the performance monitoring events you can either specify them in the perf element or enable them via virDomainSetPerfEvents API. The performance values are then retrieved using the virConnectGetAllDomainStats
# pluggable cpu and unpluggable cpu has different qom-paths!!! # pluggable cpu sits at /machine/peripheral { "return": [ { "arch": "x86", "thread-id": 17865, "props": { "core-id": 0, "thread-id": 0, "node-id": 0, "socket-id": 0 }, "qom-path": "/machine/unattached/device[0]", "cpu-index": 0, "target": "x86_64" }, { "arch": "x86", "thread-id": 18887, "props": { "core-id": 1, "thread-id": 0, "node-id": 0, "socket-id": 0 }, "qom-path": "/machine/peripheral/cpu-2", "cpu-index": 1, "target": "x86_64" } ], "id": "libvirt-28" }
# inside the guest, there are two cpu now!!!
memory deivce and share memory
without hotplugable memory device
1 2 3 4 5 6 7 8 9 10 11 12 13 14
<domain> <maxMemoryslots="4"unit="GiB">2</maxMemory> <cpu> <topologysockets="1"cores="2"threads="1"/> <numa> <cellid="0"cpus="0-1"memory="1024"unit="MiB"/> -----> no need to set <memory></memory>, it's auto calcualted from <numa></numa> if no <numa> must set it!!! </numa> </cpu>
libvirt auto generate xml /var/run/libvirt/qemu/$domain.xml
<domain> <maxMemoryslots="4"unit="GiB">2</maxMemory> <cpu> <topologysockets="1"cores="2"threads="1"/> <numa> <cellid="0"cpus="0-1"memory="1024"unit="MiB"/> -----> no need to set <memory></memory>, it's auto calcualted from <numa></numa> if no <numa> must set it!!! </numa> </cpu> <devices> <memorymodel="dimm"> <target> <sizeunit="MiB">256</size> <node>0</node> </target> </memory> </devices>
libvirt auto generate xml /var/run/libvirt/qemu/$domain.xml
<maxMemoryslots='4'unit='KiB'>4194304</maxMemory> <memoryunit='KiB'>1310720</memory> ---> ram(numa) + dimm <currentMemoryunit='KiB'>1310720</currentMemory>---> the memory you can see in guest with free = ram(numa + dimm)
<domain> <maxMemoryslots="4"unit="GiB">2</maxMemory> <cpu> <topologysockets="1"cores="2"threads="1"/> <numa> <cellid="0"cpus="0-1"memory="1024"unit="MiB"/> -----> no need to set <memory></memory>, it's auto calcualted from <numa></numa> if no <numa> must set it!!! </numa> </cpu> <devices> <memorymodel="dimm"> <target> <sizeunit="MiB">256</size> <node>0</node> </target> </memory> <memorymodel="nvdimm"> <source> <path>/tmp/nvdimm</path> </source> <target> <sizeunit="MiB">256</size> <node>0</node> </target> </memory> </devices>
libvirt auto generate xml /var/run/libvirt/qemu/$domain.xml
<maxMemoryslots='4'unit='KiB'>4194304</maxMemory> <memoryunit='KiB'>1572864</memory> ---->memory include ram(numa)+dimm+nvdimm <currentMemoryunit='KiB'>1310720</currentMemory> ---->currentMemory not include nvdimm, but include dimm, this is the value you can see with `lsmem -ab`
# kernel code used is not counted here $ free total used free shared buff/cache available Mem: 1210676 82836 1042392 12432 85448 1092196 Swap: 0 0 0 # total memory is 1.3G as well, nvdimm is not counted $ lsmem -a RANGE SIZE STATE REMOVABLE BLOCK 0x0000000000000000-0x0000000007ffffff 128M online no 0 0x0000000008000000-0x000000000fffffff 128M online yes 1 0x0000000010000000-0x0000000017ffffff 128M online yes 2 0x0000000018000000-0x000000001fffffff 128M online yes 3 0x0000000020000000-0x0000000027ffffff 128M online yes 4 0x0000000028000000-0x000000002fffffff 128M online no 5 0x0000000030000000-0x0000000037ffffff 128M online no 6 0x0000000038000000-0x000000003fffffff 128M online no 7 0x0000000100000000-0x0000000107ffffff 128M online no 32 0x0000000108000000-0x000000010fffffff 128M online no 33
Memory block size: 128M Total online memory: 1.3G Total offline memory: 0B
# nvdimm is seen as block by guest /dev/pmem0!!! $fdisk -l
$virsh qemu-monitor-command vm100 --pretty '{ "execute": "query-memory-devices"}' { "return": [ { "type": "dimm", "data": { "memdev": "/objects/memdimm0", "hotplugged": false, "addr": 4294967296, "hotpluggable": true, "size": 268435456, "slot": 0, "node": 0, "id": "dimm0" } }, { "type": "nvdimm", "data": { "memdev": "/objects/memnvdimm1", "hotplugged": false,-------->can NOT be removed from QMP as it is added from command line "addr": 4563402752, "hotpluggable": true, "size": 268435456, "slot": 1, "node": 0, "id": "nvdimm1" } }, { "type": "dimm", "data": { "memdev": "/objects/mem-dimm2", "hotplugged": true, ----->this can be removed from QMP command!!! "addr": 4831838208, "hotpluggable": true, "size": 268435456, "slot": 2, "node": 0, "id": "dm2" } } ], "id": "libvirt-23" }
# insde guest $ free total used free shared buff/cache available Mem: 1472816 94176 1292552 12440 86088 1339132 Swap: 0 0 0
# total memory is increased after add a memory device $ lsmem -a RANGE SIZE STATE REMOVABLE BLOCK 0x0000000000000000-0x0000000007ffffff 128M online no 0 0x0000000008000000-0x000000000fffffff 128M online yes 1 0x0000000010000000-0x0000000017ffffff 128M online yes 2 0x0000000018000000-0x000000001fffffff 128M online yes 3 0x0000000020000000-0x0000000027ffffff 128M online yes 4 0x0000000028000000-0x000000002fffffff 128M online no 5 0x0000000030000000-0x0000000037ffffff 128M online no 6 0x0000000038000000-0x000000003fffffff 128M online no 7 0x0000000100000000-0x0000000107ffffff 128M online no 32 0x0000000108000000-0x000000010fffffff 128M online no 33 0x0000000120000000-0x0000000127ffffff 128M online yes 36 0x0000000128000000-0x000000012fffffff 128M online yes 37
Memory block size: 128M Total online memory: 1.5G Total offline memory: 0B
move qemu-process launched outside to libvirtd control
1 2 3 4 5 6 7 8 9 10
# Attach an externally launched QEMU process to the libvirt QEMU driver. # The QEMU process must have been created with a monitor connection using the UNIX driver. # Ideally the process will also have had the '-name' argument specified.
# blkdeviotune - Set or query a block device I/O tuning parameters # OPTIONS # [--domain] <string> domain name, id or uuid # [--device] <string> block device # --total-bytes-sec <number> total throughput limit, as scaled integer (default bytes) # --read-bytes-sec <number> read throughput limit, as scaled integer (default bytes) # --write-bytes-sec <number> write throughput limit, as scaled integer (default bytes) # --total-iops-sec <number> total I/O operations limit per second # --read-iops-sec <number> read I/O operations limit per second # --write-iops-sec <number> write I/O operations limit per second # --total-bytes-sec-max <number> total max, as scaled integer (default bytes) # --read-bytes-sec-max <number> read max, as scaled integer (default bytes) # --write-bytes-sec-max <number> write max, as scaled integer (default bytes) # --total-iops-sec-max <number> total I/O operations max # --read-iops-sec-max <number> read I/O operations max # --write-iops-sec-max <number> write I/O operations max # --size-iops-sec <number> I/O size in bytes # --group-name <string> group name to share I/O quota between multiple drives # --total-bytes-sec-max-length <number> duration in seconds to allow total max bytes # --read-bytes-sec-max-length <number> duration in seconds to allow read max bytes # --write-bytes-sec-max-length <number> duration in seconds to allow write max bytes # --total-iops-sec-max-length <number> duration in seconds to allow total I/O operations max # --read-iops-sec-max-length <number> duration in seconds to allow read I/O operations max # --write-iops-sec-max-length <number> duration in seconds to allow write I/O operations max
# --config affect next boot # --live affect running domain # --current affect current domain
# If additional gettys are spawned during boot then we should make # sure that this is synchronized before getty.target, even though # getty.target didn't actually pull it in. Before=getty.target IgnoreOnIsolate=yes
# list all pci devices of host(we can passthrough these devices if iommus is enabled on host) $ virsh nodedev-list --cap pci pci_0000_00_00_0 pci_0000_00_01_0 pci_0000_00_02_0 pci_0000_00_03_0 pci_0000_00_04_0 pci_0000_00_1f_0 pci_0000_00_1f_2 ...