<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
xmlns:content="http://purl.org/rss/1.0/modules/content/"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
xmlns:atom="http://www.w3.org/2005/Atom"
xmlns:wfw="http://wellformedweb.org/CommentAPI/">
<channel>
<title>dwt&#039;s life - libvirt</title>
<link>https://dwt.life/tag/libvirt/</link>
<atom:link href="https://dwt.life/feed/tag/libvirt/" rel="self" type="application/rss+xml" />
<language>zh-CN</language>
<description></description>
<lastBuildDate>Thu, 19 Aug 2021 02:00:00 +0800</lastBuildDate>
<pubDate>Thu, 19 Aug 2021 02:00:00 +0800</pubDate>
<item>
<title>libvirt禁止每次增加新DHCP IP时写入iptables</title>
<link>https://dwt.life/archives/125/</link>
<guid>https://dwt.life/archives/125/</guid>
<pubDate>Thu, 19 Aug 2021 02:00:00 +0800</pubDate>
<dc:creator>Ricky</dc:creator>
<description><![CDATA[每次增加DHCP IP的时候就会增加一条iptables规则,影响其他IP的正常使用,使用hooks直接恢复mkdir /etc/libvirt/hooksfor f in daemon qem...]]></description>
<content:encoded xml:lang="zh-CN"><![CDATA[
<p>每次增加DHCP IP的时候就会增加一条iptables规则,影响其他IP的正常使用,使用hooks直接恢复</p><pre><code class="lang-shell">mkdir /etc/libvirt/hooks
for f in daemon qemu lxc libxl network; do
  echo &#039;#!/bin/sh
iptables-restore &lt; /etc/sysconfig/iptables
iptables -I FORWARD -j ACCEPT&#039; &gt; &quot;/etc/libvirt/hooks/$f&quot;
  chmod +x &quot;/etc/libvirt/hooks/$f&quot;
done
service libvirtd restart</code></pre>
]]></content:encoded>
<slash:comments>0</slash:comments>
<comments>https://dwt.life/archives/125/#comments</comments>
<wfw:commentRss>https://dwt.life/feed/tag/libvirt/</wfw:commentRss>
</item>
<item>
<title>Libvirt设置防火墙规则重置</title>
<link>https://dwt.life/archives/121/</link>
<guid>https://dwt.life/archives/121/</guid>
<pubDate>Sat, 14 Aug 2021 03:52:04 +0800</pubDate>
<dc:creator>Ricky</dc:creator>
<description><![CDATA[mkdir /etc/libvirt/hooksfor f in daemon qemu lxc libxl network; do  echo &#039;#!/bin/shiptables-...]]></description>
<content:encoded xml:lang="zh-CN"><![CDATA[
<pre><code>mkdir /etc/libvirt/hooks
for f in daemon qemu lxc libxl network; do
  echo &#039;#!/bin/sh
iptables-restore &lt; /etc/sysconfig/iptables&#039; &gt; &quot;/etc/libvirt/hooks/$f&quot;
  chmod +x &quot;/etc/libvirt/hooks/$f&quot;
done
service libvirtd restart</code></pre>
]]></content:encoded>
<slash:comments>0</slash:comments>
<comments>https://dwt.life/archives/121/#comments</comments>
<wfw:commentRss>https://dwt.life/feed/tag/libvirt/</wfw:commentRss>
</item>
<item>
<title>KVM虚拟机克隆快照总结</title>
<link>https://dwt.life/archives/102/</link>
<guid>https://dwt.life/archives/102/</guid>
<pubDate>Sat, 07 Aug 2021 15:34:00 +0800</pubDate>
<dc:creator>Ricky</dc:creator>
<description><![CDATA[克隆方案# virsh-clone ＃ virt-clone --connect qemu:///system --original test2 --name testclone --file ...]]></description>
<content:encoded xml:lang="zh-CN"><![CDATA[
<h1>克隆方案</h1><pre><code class="lang-shell"># virsh-clone 
＃ virt-clone --connect qemu:///system --original test2 --name testclone --file /var/lib/libvirt/images/newdemo.img --file /var/lib/libvirt/images/newdata.img

virt-clone --connect qemu:///system -o test2 --n testclone -f /fine1fs/virtual/vm/node25/testclone

/fine1fs/virtual/vm/node25/34c0ac46-8052-11e9-a322-fcaa14a3eb62

## 连接克隆 
# os_disk img_type == file
qemu-img create -f qcow2 -b /fine1fs/virtual/vm/node25/34c0ac46-8052-11e9-a322-fcaa14a3eb62/34c0ac46-8052-11e9-a322-fcaa14a3eb62_os.qcow2 /fine1fs/virtual/vm/node25/teset12/test12.qcow2

virsh dumpxml test2 &gt; /fine1fs/virtual/vm/node25/teset12/test12.xml
vim /etc/libvirt/qemu/test12.xml #修改name、UUID
virsh define /etc/libvirt/qemu/test12.xml
# os_disk img_type == rbd
# rbd 使用快照
#创建一个快照
rbd snap create -p rbd_pool/foo@foo_snap

#查看快照
rbd snap list -p rbd_pool foo #注意是foo不是foo_snap

#在克隆之前，确保快照处于protected状态
rbd snap protect  rbd_pool/foo@foo_image

# 克隆 
rbd clone test_for_s3/node25_a55f772e-86a7-11e9-b731-fcaa14a3eb62_os@20190610152225.snap test_for_s3/node25_e3e0926c-8b52-11e9-abe3-fcaa14a3eb62_os

#创建一个新的pool1: 
ceph osd pool create pool1 8 8

#克隆到pool1：
rbd clone rbd_pool/foo@foo_snap pool1/newfoo

#查看快照的children: 
rbd children rbd_pool/foo@foo_snap
#pool1/newfoo

#扁平化可以断开父子间的依赖关系：
rbd flatten pool1/newfoo
虚拟机克隆
# 
rbd ls test_for_s3

# 创建快照
rbd snap create test_for_s3/node25_8c8c9228-8c0f-11e9-bc32-fcaa14a3eb62_os@20190610152226.snap



# 保护快照
rbd snap protect  test_for_s3/node25_a55f772e-86a7-11e9-b731-fcaa14a3eb62_os@20190610152226.snap

# 克隆 
rbd clonetest_for_s3/node25_8c8c9228-8c0f-11e9-bc32-fcaa14a3eb62_os@20190610152226.snap test_for_s3/node25_3be0e280-8c1d-11e9-8eaa-fcaa14a3eb62_os 2&gt;&amp;1 | tee e

rbd clone rbd clone %s/%s@%s %s/%s 2&gt;&amp;1 |tee %s %s

#查看快照的children: 
rbd children rbd_pool/foo@foo_snap
#pool1/newfoo

#扁平化可以断开父子间的依赖关系：
rbd flatten test_for_s3/node25_34c0ac46-8052-11e9-a322-fcaa14a3eb62_os

# 取消保护
rbd snap unprotect  test_for_s3/node25_a55f772e-86a7-11e9-b731-fcaa14a3eb62_os@20190610152226.snap

# 删除快照
rbd snap rm test_for_s3/node25_a55f772e-86a7-11e9-b731-fcaa14a3eb62_os@20190610152226.snap
</code></pre><h1>虚拟机快照</h1><h2>创建虚拟机快照</h2><p>kvm 环境 qcow2 支持快照</p><pre><code class="lang-shell"># 确认镜像格式
qemu-img info test.qcow2

# 创建虚拟机快照
qemu-img snapshot -c snapshot01 test.qcow2  

# 列出某个镜像的所有快照
qemu-img snapshot -l test.qcow2  

# 使用快照
qemu-img snapshot -a snapshot01 test.qcow2  

# 删除快照
qemu-img snapshot -d snapshot01 test.qcow2 </code></pre><h2>创建外部快照</h2><pre><code class="lang-python"># 取最后一个快照
last_snap_name = dom.snapshotListNames()

# 路径获取
import os
a = &quot;/fine1fs/virtual/vm/node25/c998baae-9199-11e9-891b-fcaa14a3eb62/c998baae-9199-11e9-891b-fcaa14a3eb62_os.snapshot2&quot;
print(os.path.splitext(a)[0])


if dom.isActive():
    dom.managedSave()
    
snap = dom.snapshotCreateXML(snapxml,flags=148)</code></pre><h2>磁盘快照和内存+磁盘快照</h2><pre><code class="lang-shell">#!/bin/bash
DOMAIN=&quot;test&quot;
TIMESTAMP=`date +%s`
SNAPSHOT_NAME=$TIMESTAMP

VM_FOLDER=&quot;/path/to/vms&quot;
SNAPSHOT_FOLDER=&quot;`echo $VM_FOLDER`/`echo $DOMAIN`/snapshots/`echo $TIMESTAMP`&quot;
mkdir -p $SNAPSHOT_FOLDER

MEM_FILE=&quot;`echo $SNAPSHOT_FOLDER`/mem.qcow2&quot;
DISK_FILE=&quot;`echo $SNAPSHOT_FOLDER`/disk.qcow2&quot;

# Find out if running or not
STATE=`virsh dominfo $DOMAIN | grep &quot;State&quot; | cut -d &quot; &quot; -f 11`

if [ &quot;$STATE&quot; = &quot;running&quot; ]; then

  virsh snapshot-create-as \
    --domain $DOMAIN $SNAPSHOT_NAME \
    --diskspec vda,file=$DISK_FILE,snapshot=external \
    --memspec file=$MEM_FILE,snapshot=external \
    --atomic

else

  virsh snapshot-create-as \
    --domain $DOMAIN $SNAPSHOT_NAME \
    --diskspec vda,file=$DISK_FILE,snapshot=external \
    --disk-only \
    --atomic

fi

virsh snapshot-create-as  --domain snaptest snapshot1 --diskspec file=&quot;/fine1fs/virtual/vm/node25/14e9948e-9199-11e9-8eb8-fcaa14a3eb62/14e9948e-9199-11e9-8eb8-fcaa14a3eb62_os.snapshot1&quot;,snapshot=external --memspec file=&quot;/fine1fs/virtual/vm/node25/14e9948e-9199-11e9-8eb8-fcaa14a3eb62/14e9948e-9199-11e9-8eb8-fcaa14a3eb62_os.memory&quot;,snapshot=external --atomic</code></pre><h2>虚拟机快照测试</h2><pre><code class="lang-python"># 虚拟机 running 
if dom.isActive():
    ret = dom.save(path)
    
    
dom.restore(path)


#ret = dom.snapshotCreateXML(memansp,flags=384)</code></pre><h1>修改要求</h1><p>1.虚拟机支持快照<br>  (1)已创建快照虚拟机不允许导出、克隆、迁移操作<br>  (2)磁盘快照使用外部快照，创建快照需要暂停虚拟机(是否需要手动暂停)或关闭虚拟机,支持raw和qcow2格式<br>  (3)只有虚拟机运行的时候，才允许创建内存快照</p><p>2.其他</p><pre><code>virsh start x                                 启动名字为x的非活动虚拟机

virsh create x.xml                      创建虚拟机（创建后，虚拟机立即执行，成为活动主机）

virsh suspend x                             暂停虚拟机

virsh resume x                             启动暂停的虚拟机

virsh shutdown x                    正常关闭虚拟机

virsh destroy x                              强制关闭虚拟机

virsh dominfo x                              显示虚拟机的基本信息

virsh domname 2                                   显示id号为2的虚拟机名

virsh domid x                                显示虚拟机id号

virsh domuuid x                             显示虚拟机的uuid

virsh domstate x                          显示虚拟机的当前状态
virsh blockcommit --domain snap –path --base /fine1fs/virtual/vm/node14/bab1f794-93d3-11e9-8c04-0cc47a6b577c/bab1f794-93d3-11e9-8c04-0cc47a6b577c_os.snapshot03 --top /fine1fs/virtual/vm/node14/bab1f794-93d3-11e9-8c04-0cc47a6b577c/bab1f794-93d3-11e9-8c04-0cc47a6b577c_os.snapshot04

virsh blockcommit --domain snap hda --base /fine1fs/virtual/vm/node14/bab1f794-93d3-11e9-8c04-0cc47a6b577c/bab1f794-93d3-11e9-8c04-0cc47a6b577c_os.snapshot01 --top /fine1fs/virtual/vm/node14/bab1f794-93d3-11e9-8c04-0cc47a6b577c/bab1f794-93d3-11e9-8c04-0cc47a6b577c_os.snapshot04 --wait --verbose
qemu-img rebase -u -b bab1f794-93d3-11e9-8c04-0cc47a6b577c_os.snapshot02 bab1f794-93d3-11e9-8c04-0cc47a6b577c_os.snapshot04</code></pre><h1>查看快照关系链</h1><p><code>qemu-img info --backing-chain bab1f794-93d3-11e9-8c04-0cc47a6b577c_os.snapshot05</code></p><h1>合并快照</h1><p><code>qemu-img rebase -u -b bab1f794-93d3-11e9-8c04-0cc47a6b577c_os.snapshot02 bab1f794-93d3-11e9-8c04-0cc47a6b577c_os.snapshot04</code></p>
]]></content:encoded>
<slash:comments>0</slash:comments>
<comments>https://dwt.life/archives/102/#comments</comments>
<wfw:commentRss>https://dwt.life/feed/tag/libvirt/</wfw:commentRss>
</item>
<item>
<title>KVM虚拟机快照研究（二）</title>
<link>https://dwt.life/archives/101/</link>
<guid>https://dwt.life/archives/101/</guid>
<pubDate>Sat, 07 Aug 2021 15:28:03 +0800</pubDate>
<dc:creator>Ricky</dc:creator>
<description><![CDATA[使用Python脚本操作快照上一篇中介绍了KVM虚拟机各种快照的原理和命令行操作方法，由于磁盘外部快照最实用，所以本篇主要讲怎么利用Libvirt api操作磁盘外部快照。其中会涉及一些Libv...]]></description>
<content:encoded xml:lang="zh-CN"><![CDATA[
<p>使用Python脚本操作快照</p><p>上一篇中介绍了KVM虚拟机各种快照的原理和命令行操作方法，由于磁盘外部快照最实用，所以本篇主要讲怎么利用Libvirt api操作磁盘外部快照。其中会涉及一些Libvirt api的基本用法，也会一起介绍。</p><h1>操作环境</h1><p>环境同上篇。Python与libvirt服务交互用的是libvirt模块；操作虚拟机的XML描述文件用的是xml.dom模块。</p><h1>创建快照</h1><p>我们要完成的功能是，给出一个虚拟机的名称，创建这个虚拟机的磁盘快照。</p><p>首先建立与libvirt服务的连接，然后根据虚拟机名称获取该domain对象：</p><pre><code>conn = libvirt.open(&quot;qemu:///system&quot;)

dom = conn.lookupByName(&#039;vm&#039;)</code></pre><p>domain对象的方法snapshotCreateXML()实现了通过一个XML描述文件创建快照的功能，该方法接收的参数是一个描述快照的XML字符串（不是文件）和标志位flags。快照的XML描述文件一般是下面这种格式：</p><pre><code class="lang-xml">  &lt;domainsnapshot&gt;

    &lt;name&gt;snapshot01&lt;/name&gt;

    &lt;description&gt;test api&lt;/description&gt;

    &lt;disks&gt;

      &lt;disk name=&#039;/path/diskname&#039;&gt;

      &lt;/disk&gt;

      &lt;disk name=&#039;/path/diskname&#039;&gt;

      &lt;/disk&gt;

    &lt;/disks&gt;

  &lt;/domainsnapshot&gt;</code></pre><p>可以看出，构建快照的XML描述文件需要首先获取到虚拟机的磁盘文件名，获取方法是读取并解析虚拟机的xml文件：</p><pre><code class="lang-python">xml = dom.XMLDesc(0)

doc = minidom.parseString(xml)

disks = doc.getElementsByTagName(&#039;disk&#039;)

for disk in disks:

    if disk.getAttribute(&#039;device&#039;) == &#039;disk&#039;:

    diskfile = disk.getElementsByTagName(&#039;source&#039;)[0].getAttribute(&#039;file&#039;)

    print diskfile</code></pre><p>这段代码的输出结果是：</p><pre><code class="lang-shell">[root@localhost snapshot]# python test.py

/data/vm.img

/data/data.img</code></pre><p>然后把磁盘文件的名字填到快照xml里，存放在文件snapshot01.xml中：</p><pre><code class="lang-xml">    &lt;domainsnapshot&gt;

      &lt;name&gt;snapshot01&lt;/name&gt;

      &lt;description&gt;test api&lt;/description&gt;

      &lt;disks&gt;

        &lt;disk name=&#039;/data/vm.img&#039;&gt;

        &lt;/disk&gt;

        &lt;disk name=&#039;/data/data.img&#039;&gt;

        &lt;/disk&gt;

      &lt;/disks&gt;

    &lt;/domainsnapshot&gt;</code></pre><h1>flags</h1><p>另一个参数是标志位flags，Libvirt定义了一系列标志位控制创建快照的行为，每一位的作用可以通过查看Libvirt官方文档得知。Libvirt官方文档只有C语言的api文档，Python api的用法基本跟C语言的一致，所以不影响我们参考。标志位的取值及含义如下：</p><pre><code class="lang-c">#Restore or alter metadata

VIR_DOMAIN_SNAPSHOT_CREATE_REDEFINE    =   1  

#With redefine, make snapshot current

VIR_DOMAIN_SNAPSHOT_CREATE_CURRENT =   2  

#Make snapshot without remembering it

VIR_DOMAIN_SNAPSHOT_CREATE_NO_METADATA =   4  

#Stop running guest after snapshot

VIR_DOMAIN_SNAPSHOT_CREATE_HALT =   8  

#disk snapshot, not system checkpoint

VIR_DOMAIN_SNAPSHOT_CREATE_DISK_ONLY   =   16 

#reuse any existing external files

VIR_DOMAIN_SNAPSHOT_CREATE_REUSE_EXT   =   32 

#use guest agent to quiesce all mounted file systems   within the domain

VIR_DOMAIN_SNAPSHOT_CREATE_QUIESCE =   64 

#atomically avoid partial changes

VIR_DOMAIN_SNAPSHOT_CREATE_ATOMIC  =   128

#create the snapshot while the guest is running

VIR_DOMAIN_SNAPSHOT_CREATE_LIVE =   256</code></pre><p>我们需要用到的标志有VIR_DOMAIN_SNAPSHOT_CREATE_NO_METADATA，VIR_DOMAIN_SNAPSHOT_CREATE_DISK_ONLY和VIR_DOMAIN_SNAPSHOT_CREATE_ATOMIC，分别对应virsh snapshot-create-as命令的参数--disk-only，--no-metadata和--atmotic。多个标志位叠加是通过二进制按位或操作，换算成十进制下的操作就是相加，所以flags的值为4+16+128=148。</p><pre><code class="lang-python">snapshotXML = open(&#039;snapshot01.xml&#039;,&#039;rb&#039;).read()

dom.snapshotCreateXML(snapshotXML,flags=148)</code></pre><h1>快照脚本内容</h1><p>汇总如下：</p><pre><code class="lang-python">#!/usr/bin/python

import libvirt

import sys

from xml.dom import minidom

 

def getDom(vm):

    try:

        conn = libvirt.open(&quot;qemu:///system&quot;)

        dom = conn.lookupByName(vm)

        return dom

    except Exception,e:

        print &quot;Get domain   object of vm %s failed: %s&quot; % (vm,str(e))

        sys.exit(1)

 

def getDiskfile(vm):

    dom = getDom(vm)

    xml = dom.XMLDesc(0)

    doc = minidom.parseString(xml)

    disks = doc.getElementsByTagName(&#039;disk&#039;)

    diskfiles = []

    for disk in disks:

        if disk.getAttribute(&#039;device&#039;) == &#039;disk&#039;:

              diskfile = disk.getElementsByTagName(&#039;source&#039;)[0].getAttribute(&#039;file&#039;)

              diskfiles.append(diskfile)

    return diskfiles

 

def createXML(vm):

    diskfiles = getDiskfile(vm)

    xml = &quot;&quot;&quot;&lt;domainsnapshot&gt;

      &lt;name&gt;snapshot01&lt;/name&gt;

      &lt;description&gt;test api&lt;/description&gt;

    &lt;disks&gt;

      &lt;disk   name=&#039;%s&#039;&gt;

        &lt;/disk&gt;

      &lt;disk   name=&#039;%s&#039;&gt;

        &lt;/disk&gt;

      &lt;/disks&gt;

    &lt;/domainsnapshot&gt;&quot;&quot;&quot; % (diskfiles[0],diskfiles[1])

    with open(&#039;snapshot01.xml&#039;,&#039;w&#039;) as f:

        f.write(xml)

 

def createSnapshot(vm):

    dom = getDom(vm)

    snapshotXML = open(&#039;snapshot01.xml&#039;,&#039;rb&#039;).read()

    dom.snapshotCreateXML(snapshotXML,flags=148)

 

if __name__ == &quot;__main__&quot;:

    createXML(&#039;vm&#039;)

    createSnapshot(&#039;vm&#039;)
</code></pre><h1>合并快照文件</h1><p>首先为虚拟机创建4个快照，现在磁盘文件形成了如下back chain（原理见上篇文章）：</p><p><code>base&lt;-snapshot01&lt;-snapshot02&lt;-snapshot03&lt;-snapshot04*</code></p><p>我们要通过api把snapshot03合并到snapshot02，用到的方法是blockCommit()，该方法有3个必须提供的参数disk，base和top，分别对应virsh blockcommit命令的参数--path，--base和--top。把命令virsh blockcommit --domain vm –path vda --base /data/vm.snapshot02 --top /data/vm.snapshot03翻译成Python代码就是：</p><pre><code>dom.blockCommit(&#039;vda&#039;,&#039;/data/vm.snapshot02&#039;,&#039;/data/vm.snapshot03&#039;)</code></pre><p>合并快照文件可能需要很长时间，但是blockCommit是异步的，执行完立即返回，如果我们想查看后台的这个合并任务，需要用blockJobInfo()方法查看合并任务是否已完成。</p><h1>合并脚本内容</h1><p>汇总如下：</p><pre><code class="lang-python">#!/usr/bin/python

import libvirt

import sys

 

def getDom(vm):

    try:

        conn = libvirt.open(&quot;qemu:///system&quot;)

        dom = conn.lookupByName(vm)

        return dom

    except Exception,e:

        print &quot;Get domain   object of vm %s failed: %s&quot; % (vm,str(e))

        sys.exit(1)

 

 

if __name__ == &quot;__main__&quot;:

    dom = getDom(&#039;vm&#039;)

  dom.blockCommit(&#039;vda&#039;,&#039;/data/vm.snapshot02&#039;,&#039;/data/vm.snapshot03&#039;)

    dom.blockCommit(&#039;vdb&#039;,&#039;/data/data.snapshot02&#039;,&#039;/data/data.snapshot03&#039;)</code></pre>
]]></content:encoded>
<slash:comments>0</slash:comments>
<comments>https://dwt.life/archives/101/#comments</comments>
<wfw:commentRss>https://dwt.life/feed/tag/libvirt/</wfw:commentRss>
</item>
<item>
<title>KVM虚拟机快照研究（一）</title>
<link>https://dwt.life/archives/100/</link>
<guid>https://dwt.life/archives/100/</guid>
<pubDate>Sat, 07 Aug 2021 15:24:00 +0800</pubDate>
<dc:creator>Ricky</dc:creator>
<description><![CDATA[KVM虚拟机的快照用来保存虚拟机在某个时间点的内存、磁盘或者设备状态，如果将来有需要可以把虚拟机的状态回滚到这个时间点。根据被做快照的对象不同，快照可以分为磁盘快照和内存快照，两者加起来构成了一...]]></description>
<content:encoded xml:lang="zh-CN"><![CDATA[
<p>KVM虚拟机的快照用来保存虚拟机在某个时间点的内存、磁盘或者设备状态，如果将来有需要可以把虚拟机的状态回滚到这个时间点。</p><p>根据被做快照的对象不同，快照可以分为磁盘快照和内存快照，两者加起来构成了一个系统还原点，记录虚拟机在某个时间点的全部状态；根据做快照时虚拟机是否在运行，快照又可以分为在线快照和离线快照。</p><p>磁盘快照根据存储方式的不同，又分为内部快照和外部快照：内部快照只支持qcow2格式的虚拟机镜像，把快照及后续变动都保存在原来的qcow2文件内；外部快照在创建时，快照被保存在单独一个文件中，创建快照时间点之后的数据被记录到一个新的qcow2文件中，原镜像文件成为新的qcow2文件的backing file（只读），在创建多个快照后，这些文件将形成一个链——backing chain。外部快照同时支持raw和qcow2格式的虚拟机镜像。</p><p>下文将分别具体介绍不同类型的KVM虚拟机快照。</p><p>操作环境：</p><ul><li><p>操作系统：</p><pre><code>[root@localhost ~]# cat   /etc/redhat-release
CentOS Linux release 7.4.1708 (Core)</code></pre></li><li><p>Libvirt版本：</p><pre><code>[root@localhost ~]# libvirtd --version
libvirtd (libvirt) 3.2.0</code></pre></li><li><p>qemu版本：</p><pre><code>[root@localhost ~]# rpm -qa|grep qemu-kvm
qemu-kvm-common-ev-2.3.0-29.1.el7.x86_64
qemu-kvm-ev-2.3.0-29.1.el7.x86_64</code></pre></li></ul><p>centos7.4的默认yum源中的qemu-kvm不支持在线创建外部快照，需要安装Redhat的qemu-kvm-ev，安装方法：</p><ol><li>配置yum源</li></ol><pre><code>[root@localhost ~]# cat   /etc/yum.repos.d/qemu-kvm-rhev.repo
[qemu-kvm-rhev]
name=oVirt rebuilds of qemu-kvm-rhev
baseurl=http://resources.ovirt.org/pub/ovirt-3.5/rpm/el7Server/
mirrorlist=http://resources.ovirt.org/pub/yum-repo/mirrorlist-ovirt-3.5-el7Server
enabled=1
skip_if_unavailable=1
gpgcheck=0</code></pre><ol start="2"><li>安装</li></ol><p><code>[root@localhost ~]# yum install qemu-kvm-rhev -y</code><br>测试机上有一台虚拟机</p><pre><code class="lang-shell">[root@localhost ~]# virsh list

 Id      Name                             State

----------------------------------------------------

10      vm                             running
</code></pre><p>虚拟机的磁盘文件为系统盘/data/vm.img，数据盘/data/data.img。</p><h2>内存快照</h2><ol><li>创建快照</li></ol><p>命令：virsh save vm vm.snapshot1</p><pre><code class="lang-shell">[root@localhost ~]# virsh save vm   vm.snapshot1

 

Domain vm saved to vm.snapshot1

 
创建完后虚拟机会关机：

[root@localhost ~]# virsh list --all

 Id      Name                             State

----------------------------------------------------

 -       vm                             shut off</code></pre><ol start="2"><li>回滚快照</li></ol><p>命令：virsh restore vm.snapshot1</p><pre><code class="lang-shell">[root@localhost ~]# virsh restore   vm.snapshot1

Domain restored from vm.snapshot1

 

[root@localhost ~]# virsh list

 Id      Name                             State

----------------------------------------------------

 11      vm                             running</code></pre><p>注：</p><ol><li>只能对关机状态的虚拟机进行回滚快照；</li><li>内存快照做完后，如果虚拟机磁盘文件发生修改，可能会导致corruption。</li></ol><h2>磁盘内部快照</h2><p>磁盘内部快照可以在虚拟机开机状态创建，但是创建过程中虚拟机处于paused状态，</p><ol><li>创建快照</li></ol><p>命令：virsh snapshot-create-as --domain vm --name vm1</p><p>这条命令执行后，虚拟机会变成paused状态</p><pre><code class="lang-shell">[root@localhost ~]# virsh list

 Id      Name                             State

----------------------------------------------------

 13      vm                             paused
</code></pre><p>等快照创建完成，会重新变回running。</p><ol start="2"><li>查看快照</li></ol><p>命令：virsh snapshot-list –domain vm</p><pre><code>[root@localhost ~]# virsh snapshot-list   --domain vm

 Name                 Creation Time             State

------------------------------------------------------------

 vm1                  2018-03-06 10:37:57 +0800   running
</code></pre><p>快照回滚：virsh snapshot-revert --domain vm --snapshotname vm1</p><p>快照删除：virsh snapshot-delete --domain vm --snapshotname vm1</p><p>磁盘内部快照有2个缺点：</p><ol><li>只支持qcow2格式的镜像文件；</li><li>创建快照虚拟机会paused，有停机时间，对于不能停机的线上业务来说是无法接受的。</li></ol><h1>磁盘外部快照</h1><h2>原理</h2><p>假设虚拟机磁盘镜像文件为base，创建一个外部快照snapshot1，这时候的镜像之间的关系backing chain如下：</p><p><code>base&lt;-snapshot1*</code></p><p>“*”表示目前active状态的镜像，base变为只读，snapshot1以base为backing file，虚拟机所有写入都发生在snapshot1，如果再创建一个外部快照snapshot2，backing chain会变成：</p><p><code>base&lt;-snapshot1&lt;-snapshot2*</code></p><p>snapshot2又以snapshot1为backing file，现在base和snapshot1都变成了只读。继续创建快照会加长这个backing chain：</p><p><code>base&lt;-snapshot1&lt;-snapshot2&lt;-snapshot3&lt;-snapshot4*</code></p><p>如果要回滚某个快照，就要把虚拟机使用的镜像指向该快照文件的backing file。例如，回滚到snapshot2，就要把虚拟机的镜像改为snapshot1；回滚到snapshot1，则要把虚拟机的镜像改为base。回滚到snapshot1会导致snapshot1之后的所有快照失效，因为他们在backing chain上游的backing file发生了变化（backing file只能是只读，如果数据发生变化，下游镜像也会失效）。</p><h2>缩短链</h2><p>随着快照数量变多，backing chain也会越来越长，变得难以维护。如果有些快照已经没用了可以进行删除。缩短这条链通常有两种思路：</p><ol><li>blockcommit，从top文件合并数据到base（下游镜像向backing file合并，称为“commit”）；</li><li>blockpull，从base文件合并数据到top（从backing file向下游镜像合并，称为“pull”）。截止目前只能将backing file合并至当前的active的镜像中，也就是说还不支持指定top的合并。</li></ol><h2>删除快照</h2><p>在上面的backing chain中，如果我们要删除snapshot2，方法如下：</p><ol><li>blockcommit：把snapshot2的数据合并到snapshot1，合并完后backing chain变成了</li></ol><p><code>base&lt;-snapshot1&lt;-snapshot2（内容为snapshot2+snapshot3）&lt;-snapshot4*</code></p><ol start="2"><li>blockpull：把snapshot2的数据合并到snapshot3，合并完后backing chain变成了</li></ol><p><code>base&lt;-snapshot1&lt;-snapshot3（内容为snapshot2+snapshot3）&lt;-snapshot4*</code></p><h1>具体操作</h1><h2>1. 创建外部快照</h2><p>命令：virsh snapshot-create-as --domain vm --name snapshot1 --disk-only --atomic --no-metadata</p><p>--disk-only 有这个参数，snapshot-create-as命令就会创建磁盘外部快照；</p><p>--atomic 如果虚拟机有多个磁盘，则把为虚拟机所有磁盘创建快照的操作当做一个原子操作，要么全部成功，要么全部失败；</p><p>--no-metadata 不让libvirt记录快照的元数据。这个参数不是必须的，但是强烈建议使用，目前libvirt对外部快照支持不完整，只能创建，不能删除和回滚，如果要删除一个有外部快照的虚拟机，会出现以下报错：</p><pre><code class="lang-shell">[root@localhost ~]# virsh undefine vm

error: Failed to undefine domain test

error: Requested operation is not valid:   cannot delete inactive domain with 1 snapshots</code></pre><p>加上这个参数后，libvirt不再管理外部快照，删除和回滚都不会受影响了。</p><p>快照创建成功后，在虚拟机磁盘文件目录下会多出2个新文件vm.snapshot1和data.snapshot1，分别是系统盘和数据盘的快照文件，查看镜像信息可以看出，它们分别以原镜像为backing file，与之前原理中分析的一致：</p><pre><code class="lang-shell">[root@localhost data]# qemu-img info   vm.snapshot1

image: vm.snapshot1

file format: qcow2

virtual size: 20G (21474836480 bytes)

disk size: 3.4M

cluster_size: 65536

backing file: /data/vm.img

backing file format: qcow2

Format specific information:

      compat: 1.1

      lazy refcounts: false

      refcount bits: 16

      corrupt: false

[root@localhost data]# qemu-img info   data.snapshot1

image: data.snapshot1

file format: qcow2

virtual size: 1.0G (1073741824 bytes)

disk size: 196K

cluster_size: 65536

backing file: /data/data.img

backing file format: qcow2

Format specific information:

      compat: 1.1

      lazy refcounts: false

      refcount bits: 16

corrupt: false</code></pre><p>创建完后，虚拟机xml文件中使用的磁盘文件会libvirt自动被改成这两个新文件，这两个新文件处于active状态，原镜像变为只读。</p><pre><code class="lang-xml">&lt;disk type=&#039;file&#039; device=&#039;disk&#039;&gt;

        &lt;driver name=&#039;qemu&#039; type=&#039;qcow2&#039; cache=&#039;none&#039; io=&#039;native&#039;/&gt;

        &lt;source file=&#039;/data/vm.snapshot1&#039;/&gt;

        &lt;target dev=&#039;vda&#039; bus=&#039;virtio&#039;/&gt;

        &lt;address type=&#039;pci&#039; domain=&#039;0x0000&#039; bus=&#039;0x00&#039; slot=&#039;0x04&#039;   function=&#039;0x0&#039;/&gt;

      &lt;/disk&gt;

      &lt;disk type=&#039;file&#039; device=&#039;disk&#039;&gt;

        &lt;driver name=&#039;qemu&#039; type=&#039;qcow2&#039; cache=&#039;none&#039; io=&#039;native&#039;/&gt;

        &lt;source file=&#039;/data/data.snapshot1&#039;/&gt;

        &lt;target dev=&#039;vdb&#039; bus=&#039;virtio&#039;/&gt;

        &lt;address type=&#039;pci&#039; domain=&#039;0x0000&#039; bus=&#039;0x00&#039; slot=&#039;0x07&#039;   function=&#039;0x0&#039;/&gt;

      &lt;/disk&gt;</code></pre><h2>2. 回滚快照</h2><p>Libvirt目前不支持回滚外部快照，只能纯手工操作。为了证明在回滚快照后虚拟机确实回到了快照记录的状态，我们在虚拟机中在/root下新建一个空文件test。然后关闭虚拟机并把虚拟机的磁盘改回vm.img和data.img，开机后会发现/root/test不见了，可以证明虚拟机文件系统回到了创建快照的时间点。</p><p>由上面的操作我们可以得出结论：回滚到某个快照，就是把虚拟机当前磁盘文件改为这个快照文件的backing file；快照名和快照文件名并不对应，例如创建snapshot1后产生的文件vm.snapshot1中记录的并不是快照snapshot1的内容，它的backing file才是。在下面介绍删除快照时，牢记这点尤其重要。</p><h2>3.删除快照</h2><p>在原理中已经介绍过，删除快照有blockcommit和blockpull两种思路，由于blockpull不支持指定top的合并，下面将只介绍blockcommit方式。我们先为虚拟机vm多创建几个快照，现在快照链为（以下操作都以系统盘为例，数据盘同理）：<br>`<br>base&lt;-snapshot1&lt;-snapshot2&lt;-snapshot3&lt;-snapshot4*<br>`<br>qemu-img命令也可以查看链关系：</p><pre><code class="lang-shell">[root@localhost   data]# qemu-img info --backing-chain vm.snapshot4

image:   vm.snapshot4

file format: qcow2

virtual size:   20G (21474836480 bytes)

disk size:   452K

cluster_size:   65536

backing file:   /data/vm.snapshot3

backing file   format: qcow2

Format   specific information:

    compat: 1.1

    lazy refcounts: false

    refcount bits: 16

    corrupt: false

 

image:   /data/vm.snapshot3

file format:   qcow2

virtual size:   20G (21474836480 bytes)

disk size:   196K

cluster_size:   65536

backing file:   /data/vm.snapshot2

backing file   format: qcow2

Format   specific information:

    compat: 1.1

    lazy refcounts: false

    refcount bits: 16

    corrupt: false

 

image:   /data/vm.snapshot2

file format:   qcow2

virtual size:   20G (21474836480 bytes)

disk size:   196K

cluster_size:   65536

backing file:   /data/vm.img

backing file   format: qcow2

Format   specific information:

    compat: 1.1

    lazy refcounts: false

    refcount bits: 16

    corrupt: false

 

image:   /data/vm.img

file format:   qcow2

virtual size:   20G (21474836480 bytes)

disk size:   1.5G

cluster_size:   65536

Format   specific information:

    compat: 0.10

    refcount bits: 16</code></pre><p>现在我们要删除snapshot2，根据回滚快照时得出的结论，要回滚到snapshot2就是把虚拟机磁盘指向vm.snapshot1，所以删除snapshot2就要在不影响backing chain中其他文件的前提下，把vm.snapshot2的内容合并到vm.snapshot1，vm.snapshot1的内容发生了改变，也就不能回滚到snapshot2了，达到了删除快照的目的。操作命令如下：</p><pre><code>virsh blockcommit --domain vm vda --base /data/vm.snapshot1 --top /data/vm.snapshot2 --wait –verbose

virsh blockcommit --domain vm vdb --base /data/data.snapshot1 --top /data/data.snapshot2 --wait –verbose</code></pre><p>合并完后，使用qemu-img命令再次查看文件信息可以发现，vm.snapshot2已经不在backing chain中了：</p><pre><code class="lang-shell">[root@localhost data]# qemu-img info --backing-chain vm.snapshot4

image: vm.snapshot4

file format: qcow2

virtual size: 20G (21474836480 bytes)

disk size: 1.1M

cluster_size: 65536

backing file: /data/vm.snapshot3

backing file format: qcow2

Format specific information:

    compat: 1.1

    lazy refcounts: false

    refcount bits: 16

    corrupt: false

 

image: /data/vm.snapshot3

file format: qcow2

virtual size: 20G (21474836480 bytes)

disk size: 388K

cluster_size: 65536

backing file: /data/vm.snapshot1

backing file format: qcow2

Format specific information:

    compat: 1.1

    lazy refcounts: false

    refcount bits: 16

    corrupt: false

 

image: /data/vm.snapshot1

file format: qcow2

virtual size: 20G (21474836480 bytes)

disk size: 1.5M

cluster_size: 65536

backing file: /data/vm.img

backing file format: qcow2

Format specific information:

    compat: 1.1

    lazy refcounts: false

    refcount bits: 16

    corrupt: false

 

image: /data/vm.img

file format: qcow2

virtual size: 20G (21474836480 bytes)

disk size: 1.5G

cluster_size: 65536

Format specific information:

    compat: 0.10

    refcount bits: 16</code></pre><h1>总结</h1><p>三种快照中，只有磁盘外部快照可以不停机创建，所以这种快照最符合我们平时的需求，后续研究也重点关注外部快照。不幸的是libvirt对外部快照的支持太弱，大部分操作需要我们人脑思考、手工操作。接下来研究的重点有以下几点：</p><ol><li>测试外部快照创建时是否真正零停机时间；</li><li>虚拟机运行时进行快照文件合并对性能有何影响；</li><li>利用Python脚本封装外部快照的操作。</li></ol>
]]></content:encoded>
<slash:comments>0</slash:comments>
<comments>https://dwt.life/archives/100/#comments</comments>
<wfw:commentRss>https://dwt.life/feed/tag/libvirt/</wfw:commentRss>
</item>
<item>
<title>通过libvirt使用ceph块设备</title>
<link>https://dwt.life/archives/99/</link>
<guid>https://dwt.life/archives/99/</guid>
<pubDate>Sat, 07 Aug 2021 14:51:00 +0800</pubDate>
<dc:creator>Ricky</dc:creator>
<description><![CDATA[1. 创建存储池[root@ceph1 ~]# ceph osd pool create libvirt-pool 128 128查看刚刚创建的存储池：[root@ceph1 ~]# ceph ...]]></description>
<content:encoded xml:lang="zh-CN"><![CDATA[
<h1>1. 创建存储池</h1><pre><code class="lang-shell">[root@ceph1 ~]# ceph osd pool create libvirt-pool 128 128</code></pre><p>查看刚刚创建的存储池：</p><pre><code class="lang-shell">[root@ceph1 ~]# ceph osd lspools

0 rbd,1 .rgw.root,2 default.rgw.control,3 default.rgw.meta,4 default.rgw.log,5 default.rgw.buckets.index,6 default.rgw.buckets.data,7 default.rgw.buckets.non-ec,8 libvirt-pool,</code></pre><h1>2. 创建ceph用户client.libvirt，权限限制到存储池libvirt-pool</h1><pre><code class="lang-shell">[root@ceph1 ~]# ceph auth get-or-create client.libvirt mon &#039;allow r&#039; osd &#039;allow class-read object_prefix rbd_children, allow rwx pool=libvirt-pool&#039;</code></pre><p>验证：</p><pre><code class="lang-shell">[root@ceph1 ~]# ceph auth list

...

client.libvirt

key: AQBblU1b9FECCRAA4tW8qaBYtxTsDlaNJybZSQ==

caps: [mon] allow r

    caps: [osd] allow class-read object_prefix rbd_children, allow rwx pool=libvirt-pool

   ...</code></pre><h1>3. 把虚拟机镜像文件centos6864.qcow2.img导入存储池libvirt-pool中</h1><p>[root@ceph1 ~]# qemu-img convert -f qcow2 -O raw centos6864.qcow2.img rbd:libvirt-pool/centos6864.qcow2.img</p><p>验证：</p><p>[root@ceph1 ~]# rbd -p libvirt-pool ls</p><p>centos6864.qcow2.img</p><h1>4. 在libvirt中配置ceph认证需要的密钥</h1><ul><li>定义密钥</li></ul><pre><code class="lang-shell">[root@localhost ~]# cat &gt; secret.xml &lt;&lt;EOF

&lt;secret ephemeral=&#039;no&#039; private=&#039;no&#039;&gt;

    &lt;usage type=&#039;ceph&#039;&gt;

        &lt;name&gt;client.libvirt secret&lt;/name&gt;

    &lt;/usage&gt;

&lt;/secret&gt;</code></pre><p><code>virsh secret-define --file secret.xml</code></p><ul><li>获取密钥uuid</li></ul><pre><code class="lang-shell">[root@localhost ~]# virsh secret-list

        UUID                                  Usage

--------------------------------------------------------------------------------

 fdcb5967-d3e5-4618-98f5-5919a723e414  ceph client.libvirt secret</code></pre><ul><li>设置密钥的值</li></ul><pre><code class="lang-shell">virsh secret-set-value --secret fdcb5967-d3e5-4618-98f5-5919a723e414 --base64 AQBblU1b9FECCRAA4tW8qaBYtxTsDlaNJybZSQ==</code></pre><p>其中“AQBblU1b9FECCRAA4tW8qaBYtxTsDlaNJybZSQ==”是从上面ceph auth list的client.libvirt的key字段中得到的</p><h1>5. 修改虚拟机xml文件的disk部分</h1><pre><code class="lang-shell">[root@localhost ~]# virsh edit test
&lt;disk type=&#039;network&#039; device=&#039;disk&#039;&gt;

      &lt;driver name=&#039;qemu&#039;/&gt;

      &lt;auth username=&#039;libvirt&#039;&gt;

        &lt;secret type=&#039;ceph&#039; uuid=&#039;fdcb5967-d3e5-4618-98f5-5919a723e414&#039;/&gt;

      &lt;/auth&gt;

      &lt;source protocol=&#039;rbd&#039; name=&#039;libvirt-pool/centos6864.qcow2.img&#039;&gt;

        &lt;host name=&#039;192.168.1.15&#039; port=&#039;6789&#039;/&gt;

        &lt;host name=&#039;192.168.1.16&#039; port=&#039;6789&#039;/&gt;

        &lt;host name=&#039;192.168.1.17&#039; port=&#039;6789&#039;/&gt;

      &lt;/source&gt;

      &lt;target dev=&#039;vda&#039; bus=&#039;virtio&#039;/&gt;

      &lt;address type=&#039;pci&#039; domain=&#039;0x0000&#039; bus=&#039;0x00&#039; slot=&#039;0x06&#039; function=&#039;0x0&#039;/&gt;

&lt;/disk&gt;
     ...</code></pre><p>其中secret的uuid就是上面创建密钥的uuid；host配置的是ceph monitor的ip和端口，有几个monitor就写几个。</p><h1>6. 开启虚拟机</h1><p><code>[root@localhost ~]# virsh start test</code></p>
]]></content:encoded>
<slash:comments>0</slash:comments>
<comments>https://dwt.life/archives/99/#comments</comments>
<wfw:commentRss>https://dwt.life/feed/tag/libvirt/</wfw:commentRss>
</item>
<item>
<title>虚拟机镜像管理工具-- Libguestfs</title>
<link>https://dwt.life/archives/97/</link>
<guid>https://dwt.life/archives/97/</guid>
<pubDate>Thu, 05 Aug 2021 22:42:00 +0800</pubDate>
<dc:creator>Ricky</dc:creator>
<description><![CDATA[libguestfs是一个用来访问和修改虚拟机磁盘镜像的一个工具集libguestfs 是一组 Linux 下的 C 语言的 API ，用来访问虚拟机的磁盘映像文件。该工具包内包含的工具有vir...]]></description>
<content:encoded xml:lang="zh-CN"><![CDATA[
<blockquote>libguestfs是一个用来访问和修改虚拟机磁盘镜像的一个工具集</blockquote><p>libguestfs 是一组 Linux 下的 C 语言的 API ，用来访问虚拟机的磁盘映像文件。该工具包内包含的工具有virt-cat、virt-df、virt-ls、virt-copy-in、virt-copy-out、virt-edit、guestfs、guestmount、virt-list-filesystems、virt-list-partitions等工具，具体用法也可以参看官网。该工具可以在不启动KVM guest主机的情况下，直接查看guest主机内的文内容，也可以直接向img镜像中写入文件和复制文件到外面的物理机，当然其也可以像mount一样，支持挂载操作。</p><h1>安装Libguestfs</h1><p><code>yum install libguestfs-tools</code></p><h1>实例</h1><h2>如何利用Libguestfs修复受损虚拟机？</h2><p>作为VMware虚拟化环境管理员，你肯定遇到过虚拟机无法启动的情况。实施排错时，你需要对虚拟机的内部进行检查。而Libguestfs Linux工具集可以在这种情况下为你提供帮助。Libguestfs允许在虚拟机上挂载任何类型的文件系统，以便修复启动故障。</p><h2>利用Libguestfs找出损坏的虚拟机文件</h2><p>使用Libguestfs，首先需要使用Libvirt。Libvirt是一个管理接口，可以和KVM、Xen和其他一些基于Liunx的虚拟机相互连接。Libguestfs的功能更加强大，可以打开Windows虚拟机上的文件。这意味着除了能够使用libguestfs，你还需要一些关于虚拟机操作系统内部架构的知识。但是首先你需要将虚拟机迁移到libguestfs可用的环境当中，也就是Linux环境。</p><h2>1. 使用guestfish操作虚拟机</h2><p>完成虚拟机磁盘镜像文件的复制之后，可以在libguestfs中使用guestfish这样的工具将其打开，这样就可以直接在vmdk文件上进行操作了。使用</p><p><code>guestfish -rw -a /path/to/windows.vmdk</code><br>命令来在虚拟机中创建一个连接到文件系统的交互式shell。在新出现的窗口中，你可以使用特定的命令来操作虚拟机文件。</p><p>第一个任务就是找到可用的文件系统：</p><pre><code>\&gt;&lt;fs&gt; run 
\&gt;&lt;fs&gt; list-filesystems 
/dev/sda1: ntfs 
/dev/sda2: ntfs </code></pre><p>当你使用guestfish shell找到可用文件系统类型之后，就可以进行挂载了。使用命令</p><p><code>mount /dev/sda2 / </code><br>来挂载二个分区的内容——在Linux中是/dev/sda2——到guestfish根目录下。在guestfish中，你不能像在其他shell环境中一样操作目录。挂载的分区就是根目录，你不能使用cd命令来切换目录，这意味着所有的路径必须是完全限定路径，从根目录开始。</p><p>在guestfish shell当中可以使用像vi、ls、cat、more、download这样的命令，来查看和下载文件以及目录，输入help可以看到完整的命令信息。</p><p>在完整所有操作之后可以使用exit来关闭guestfish shell。</p><h2>2. virt-rescue提供了直接访问方式</h2><p>在libguestfs工具中，还有许多其他可用的工具。</p><p>virt-rescue命令——是使用正常的Linux文件系统工具来实现ad-hoc变化的最佳命令——可以在安全shell中启动虚拟机。你可以在虚拟机中操作这些文件，就像对挂载的文件系统上进行操作一样，其提供了对虚拟机内容更加直接的访问方式。<br>为了在虚拟机上使用virt-rescue命令进行操作，使用</p><p><code>virt-rescure 虚拟机名</code><br>来打开virt-rescue shell，之后就进入了<br><code>&gt;&lt;rescue&gt;</code><br>模式。</p><p>如果需要在虚拟机中挂载系统文件，可以使用<br><code>fdisk -l /dev/sda</code><br>命令来查看虚拟机的分区情况，之后再使用命令</p><p><code>mount /dev/sda1 /sysroot</code><br>挂载你想要访问的分区。这样你就可以通过更改来修复虚拟机的内容了。<br>虚拟机修复之后，关闭virt-rescue shell，将虚拟机重新移动到ESXi服务器的数据存储当中。虚拟机返回原位置之后，如果之前的操作一切顺利，你就应该可以访问它了。</p><h1>其他命令：</h1><h2>virt-df</h2><blockquote>查看磁盘占用率</blockquote><pre><code>[root@localhost file]# virt-df centos.img
Filesystem                           1K-blocks       Used  Available  Use%
centos.img:/dev/sda1                    495844      31950     438294    7%
centos.img:/dev/VolGroup/lv_root      28423176     721504   26257832    3%</code></pre><h1>virt-ls</h1><blockquote>查看目录下文件</blockquote><pre><code>[root@localhost file]# virt-ls centos.img /
.autofsck
bin
boot
dev
etc
home
lib
lib64
lost+found
media
mnt
opt
proc
root
sbin
selinux
srv
sys
tmp
usr</code></pre><h2>virt-copy-out</h2><blockquote>将镜像里的文件拷贝出来</blockquote><p><code>virt-copy-out -d 虚拟机名 /etc/passwd /tmp/</code></p><h2>virt-filesystems</h2><h2>virt-list-filesystems</h2><h2>virt-list-partitions</h2><blockquote>查看分区相关信息</blockquote><pre><code>[root@localhost file]# virt-filesystems  -d 虚拟机名
/dev/sda1
/dev/VolGroup/lv_root

[root@localhost file]# virt-list-filesystems  /file/centos.img
/dev/VolGroup/lv_root
/dev/sda1

[root@localhost file]# virt-list-partitions  /file/centos.img
/dev/sda1
/dev/sda2</code></pre><h2>guestmount</h2><blockquote>分区挂载</blockquote><pre><code>[root@localhost ~]# guestmount -a /file/centos.qcow2  -m /dev/sda2  --rw /mnt
libguestfs: error: mount_options: /dev/sda2 on / (options: &#039;&#039;): mount: unknown filesystem type &#039;LVM2_member&#039;
guestmount: &#039;/dev/sda2&#039; could not be mounted.
guestmount: Did you mean to mount one of these filesystems?
guestmount:     /dev/sda1 (ext4)
guestmount:     /dev/VolGroup/lv_root (ext4)
guestmount:     /dev/VolGroup/lv_swap (swap)
[root@localhost ~]# guestmount -a /file/centos.qcow2  -m /dev/VolGroup/lv_root  --rw /mnt
fuse: mountpoint is not empty
fuse: if you are sure this is safe, use the &#039;nonempty&#039; mount option
libguestfs: error: fuse_mount: /mnt: Resource temporarily unavailable
[root@localhost ~]# ls /mnt/
bin  boot  dev  etc  home  lib  lib64  lost+found  media  mnt  opt  proc  root  sbin  selinux  srv  sys  tmp  usr  var
[root@localhost ~]# umount /mnt/

[root@localhost ~]# guestmount -a /file/centos.qcow2  -m /dev/VolGroup/lv_root  --rw /mnt
[root@localhost ~]# ls /mnt/
bin  boot  dev  etc  home  lib  lib64  lost+found  media  mnt  opt  proc  root  sbin  selinux  srv  sys  tmp  usr  var

[root@localhost ~]# umount /mnt/</code></pre><h2>使用libguestfs访问windows系统</h2><pre><code>[root@localhost opt]# virt-ls -a /file/win7.img c:
virt-ls: no operating system was found on this disk
If using guestfish &#039;-i&#039; option, remove this option and instead
use the commands &#039;run&#039; followed by &#039;list-filesystems&#039;.
You can then mount filesystems you want by hand using the
&#039;mount&#039; or &#039;mount-ro&#039; command.
If using guestmount &#039;-i&#039;, remove this option and choose the
filesystem(s) you want to see by manually adding &#039;-m&#039; option(s).
Use &#039;virt-filesystems&#039; to see what filesystems are available.
If using other virt tools, this disk image won&#039;t work
with these tools.  Use the guestfish equivalent commands
(see the virt tool manual page).
RHEL 6 notice
-------------
libguestfs will return this error for Microsoft Windows guests if the
separate &#039;libguestfs-winsupport&#039; package is not installed. If the
guest is running Microsoft Windows, please try again after installing
&#039;libguestfs-winsupport&#039;.</code></pre><p>需要注意的是，上面的用法中，有两个错误的地方，一处是linux查看C分区，后面不能直接跟C：，而应该换用/ ；第二个错误是由于没有安装<strong>libguestfs-winsupport</strong> 。该工具也可以看接通过yum安装 。安装完该包后，再进行查看：</p><pre><code>[root@localhost opt]# virt-ls -a /file/win7.img /
$Recycle.Bin
Documents and Settings
PerfLogs
Program Files
Program Files (x86)
ProgramData
Recovery
System Volume Information
Users
Windows
pagefile.sys</code></pre><h2>利用guestmount进行挂载</h2><pre><code>[root@localhost ~]# guestmount -a /file/win7.img  -m /dev/sda2  --rw /mnt
[root@localhost ~]# ls /mnt/
Documents and Settings  pagefile.sys  PerfLogs  ProgramData  Program Files</code></pre>
]]></content:encoded>
<slash:comments>0</slash:comments>
<comments>https://dwt.life/archives/97/#comments</comments>
<wfw:commentRss>https://dwt.life/feed/tag/libvirt/</wfw:commentRss>
</item>
<item>
<title>Go libvirt 虚拟机信息获取</title>
<link>https://dwt.life/archives/81/</link>
<guid>https://dwt.life/archives/81/</guid>
<pubDate>Tue, 20 Jul 2021 20:34:00 +0800</pubDate>
<dc:creator>Ricky</dc:creator>
<description><![CDATA[/*1.      虚拟cpu信息：a)    Extract information about virtual CPUs of domain。b)     https://libvirt.o...]]></description>
<content:encoded xml:lang="zh-CN"><![CDATA[
<pre><code class="lang-go">/*1.      虚拟cpu信息：
a)    Extract information about virtual CPUs of domain。
b)     https://libvirt.org/html/libvirt-libvirt-domain.html#virDomainGetVcpus */
type DomainVcpuInfo struct {
   Number  uint32
   State   int32
   CpuTime uint64
   Cpu     int32
   CpuMap  []bool
}
/*
2.    得到主机名：
a)    
b)    Get the public name for that domain.
c)     https://libvirt.org/html/libvirt-libvirt-domain.html#virDomainGetName */
func (d *Domain) GetName() (string, error) 
//3.    https://libvirt.org/html/libvirt-libvirt-domain.html#virDomainGetState  
func (d *Domain) GetState() (DomainState, int, error) 

//4.    得到主机Metadata信息：
//a)    
func (d *Domain) GetMetadata(tipus DomainMetadataType, uri string, flags DomainModificationImpact) (string, error)
//b)     https://libvirt.org/html/libvirt-libvirt-domain.html#virDomainGetMetadata 
//5.     https://libvirt.org/html/libvirt-libvirt-domain.html#virDomainGetVcpusFlags 
func (d *Domain) GetVcpusFlags(flags DomainVcpuFlags) (int32, error) 
//6.      虚拟机信息：
//https://libvirt.org/html/libvirt-libvirt-domain.html#virDomainGetInfo 
type DomainInfo struct {
   State     DomainState // 运行状态 
   MaxMem    uint64 // 允许的最大内存,KB
   Memory    uint64 // 主机内存,KB //TODO区别??
   NrVirtCpu uint // 虚机虚拟CPU个数
   CpuTime   uint64// CPU使用时间,ns
}

//7.     https://libvirt.org/html/libvirt-libvirt-domain.html#virDomainInterfaceAddresses 
 type DomainIPAddress struct {
   Type   int
   Addr   string
   Prefix uint
}

type DomainInterface struct {
   Name   string
   Hwaddr string
   Addrs  []DomainIPAddress
}
/*
8.    得到单个主机CPU使用相关的统计信息：
a)    Get statistics relating to CPU usage attributable to a single domain (in contrast to the statistics returned by virNodeGetCPUStats() for all processes on the host).
b)    https://libvirt.org/html/libvirt-libvirt-domain.html#virDomainGetCPUStats */
type DomainCPUStats struct {
   CpuTimeSet    bool
   CpuTime       uint64
   UserTimeSet   bool
   UserTime      uint64
   SystemTimeSet bool
   SystemTime    uint64
   VcpuTimeSet   bool
   VcpuTime      uint64
}

//9.     得到端口参数：
//https://libvirt.org/html/libvirt-libvirt-domain.html#virDomainGetInterfaceParameters 
type DomainInterfaceParameters struct {
   BandwidthInAverageSet  bool
   BandwidthInAverage     uint
   BandwidthInPeakSet     bool
   BandwidthInPeak        uint
   BandwidthInBurstSet    bool
   BandwidthInBurst       uint
   BandwidthInFloorSet    bool
   BandwidthInFloor       uint
   BandwidthOutAverageSet bool
   BandwidthOutAverage    uint
   BandwidthOutPeakSet    bool
   BandwidthOutPeak       uint
   BandwidthOutBurstSet   bool
   BandwidthOutBurst      uint
}

//10.    块设备状态：
// https://libvirt.org/html/libvirt-libvirt-domain.html#virDomainBlockStats 
type DomainBlockStats struct {
   RdBytesSet         bool
   RdBytes            int64 //读取字节数
   RdReqSet           bool
   RdReq              int64// 读取请求数
   RdTotalTimesSet    bool
   RdTotalTimes       int64 //读取花费总时间?
   WrBytesSet         bool
   WrBytes            int64 //写入字节数
   WrReqSet           bool
   WrReq              int64 //写入需求数
   WrTotalTimesSet    bool
   WrTotalTimes       int64 //写入花费总时间?
   FlushReqSet        bool
   FlushReq           int64 //刷新请求数
   FlushTotalTimesSet bool
   FlushTotalTimes    int64 //刷新花费总时间
   ErrsSet            bool
   Errs               int64 //出错次数
}

//11.     端口状态： https://libvirt.org/html/libvirt-libvirt-domain.html#virDomainInterfaceStats 
type DomainInterfaceStats struct {
   RxBytesSet   bool
   RxBytes      int64 // 接收字节数
   RxPacketsSet bool
   RxPackets    int64 //接收包数
   RxErrsSet    bool
   RxErrs       int64 //接收出错次数
   RxDropSet    bool
   RxDrop       int64 //接收丢弃包数
   TxBytesSet   bool
   TxBytes      int64 //传输字节数
   TxPacketsSet bool
   TxPackets    int64 //传输包数
   TxErrsSet    bool
   TxErrs       int64 //传输出错次数
   TxDropSet    bool
   TxDrop       int64 //传输丢弃包数
}

//12.    主机内存策略是啥???：
//a)    Api下方有多种内存策略： https://libvirt.org/html/libvirt-libvirt-domain.html#virDomainMemoryStats 
type DomainMemoryStat struct {
   Tag int32
   Val uint64
}

//13.    得到当前主机的快照：
// https://libvirt.org/html/libvirt-libvirt-domain-snapshot.html#virDomainSnapshotCurrent 
type DomainSnapshot struct {
   ptr C.virDomainSnapshotPtr
}

//14.     检查点？？？：
//https://libvirt.org/html/libvirt-libvirt-domain-checkpoint.html#virDomainCheckpointLookupByName 
type DomainCheckpoint struct {
   ptr C.virDomainCheckpointPtr
}

//15.     块备份。这个所有方法里全都是只作为输入，没有作为输出。
//https://libvirt.org/html/libvirt-libvirt-domain.html#virDomainBlockCopy 
type DomainBlockCopyParameters struct {
   BandwidthSet   bool
   Bandwidth      uint64
   GranularitySet bool
   Granularity    uint
   BufSizeSet     bool
   BufSize        uint64
}

//16.     这个所有方法里全都是只作为输入，没有作为输出。
//https://libvirt.org/html/libvirt-libvirt-domain.html#virDomainMigrate3 
type DomainMigrateParameters struct {
   URISet                    bool
   URI                       string
   DestNameSet               bool
   DestName                  string
   DestXMLSet                bool
   DestXML                   string
   PersistXMLSet             bool
   PersistXML                string
   BandwidthSet              bool
   Bandwidth                 uint64
   GraphicsURISet            bool
   GraphicsURI               string
   ListenAddressSet          bool
   ListenAddress             string
   MigrateDisksSet           bool
   MigrateDisks              []string
   DisksPortSet              bool
   DisksPort                 int
   CompressionSet            bool
   Compression               string
   CompressionMTLevelSet     bool
   CompressionMTLevel        int
   CompressionMTThreadsSet   bool
   CompressionMTThreads      int
   CompressionMTDThreadsSet  bool
   CompressionMTDThreads     int
   CompressionXBZRLECacheSet bool
   CompressionXBZRLECache    uint64
   AutoConvergeInitialSet    bool
   AutoConvergeInitial       int
   AutoConvergeIncrementSet  bool
   AutoConvergeIncrement     int
   ParallelConnectionsSet    bool
   ParallelConnections       int
}

//17.    Blkio参数？？？是啥：
// https://libvirt.org/html/libvirt-libvirt-domain.html#virDomainGetBlkioParameters 
type DomainBlkioParameters struct {
   WeightSet          bool
   Weight             uint
   DeviceWeightSet    bool
   DeviceWeight       string
   DeviceReadIopsSet  bool
   DeviceReadIops     string
   DeviceWriteIopsSet bool
   DeviceWriteIops    string
   DeviceReadBpsSet   bool
   DeviceReadBps      string
   DeviceWriteBpsSet  bool
   DeviceWriteBps     string
}

//18.     块IO可调参数？？？：
//https://libvirt.org/html/libvirt-libvirt-domain.html#virDomainGetBlockIoTune 
type DomainBlockIoTuneParameters struct {
   TotalBytesSecSet          bool
   TotalBytesSec             uint64
   ReadBytesSecSet           bool
   ReadBytesSec              uint64
   WriteBytesSecSet          bool
   WriteBytesSec             uint64
   TotalIopsSecSet           bool
   TotalIopsSec              uint64
   ReadIopsSecSet            bool
   ReadIopsSec               uint64
   WriteIopsSecSet           bool
   WriteIopsSec              uint64
   TotalBytesSecMaxSet       bool
   TotalBytesSecMax          uint64
   ReadBytesSecMaxSet        bool
   ReadBytesSecMax           uint64
   WriteBytesSecMaxSet       bool
   WriteBytesSecMax          uint64
   TotalIopsSecMaxSet        bool
   TotalIopsSecMax           uint64
   ReadIopsSecMaxSet         bool
   ReadIopsSecMax            uint64
   WriteIopsSecMaxSet        bool
   WriteIopsSecMax           uint64
   TotalBytesSecMaxLengthSet bool
   TotalBytesSecMaxLength    uint64
   ReadBytesSecMaxLengthSet  bool
   ReadBytesSecMaxLength     uint64
   WriteBytesSecMaxLengthSet bool
   WriteBytesSecMaxLength    uint64
   TotalIopsSecMaxLengthSet  bool
   TotalIopsSecMaxLength     uint64
   ReadIopsSecMaxLengthSet   bool
   ReadIopsSecMaxLength      uint64
   WriteIopsSecMaxLengthSet  bool
   WriteIopsSecMaxLength     uint64
   SizeIopsSecSet            bool
   SizeIopsSec               uint64
   GroupNameSet              bool
   GroupName                 string
}

//19.      请求给定磁盘的块作业信息：
//https://libvirt.org/html/libvirt-libvirt-domain.html#virDomainGetBlockJobInfo 
type DomainBlockJobInfo struct {
   Type      DomainBlockJobType
   Bandwidth uint64
   Cur       uint64
   End       uint64
}

//20.     主机控制接口当前状态的详细信息： 
//https://libvirt.org/html/libvirt-libvirt-domain.html#virDomainGetControlInfo 
type DomainControlInfo struct {
   State     DomainControlState //控制状态,api中可选
   Details   int // 状态详细,api中可选
   StateTime uint64 // 当前状态持续时间
}

//21.     主机后台作业进度信息： 
//https://libvirt.org/html/libvirt-libvirt-domain.html#virDomainGetJobInfo 
type DomainJobInfo struct {
   Type                      DomainJobType// Time is measured in milliseconds
   TimeElapsedSet            bool
   TimeElapsed               uint64 // Always set???
   TimeElapsedNetSet         bool
   TimeElapsedNet            uint64
   TimeRemainingSet          bool
   TimeRemaining             uint64 // 随type不同而不同
   DowntimeSet               bool
   Downtime                  uint64
   DowntimeNetSet            bool
   DowntimeNet               uint64
   SetupTimeSet              bool
   SetupTime                 uint64
   DataTotalSet              bool
   DataTotal                 uint64
   DataProcessedSet          bool
   DataProcessed             uint64
   DataRemainingSet          bool
   DataRemaining             uint64 //同time remaining,见api
   MemTotalSet               bool
   MemTotal                  uint64
   MemProcessedSet           bool
   MemProcessed              uint64
   MemRemainingSet           bool
   MemRemaining              uint64
   MemConstantSet            bool
   MemConstant               uint64
   MemNormalSet              bool
   MemNormal                 uint64
   MemNormalBytesSet         bool
   MemNormalBytes            uint64
   MemBpsSet                 bool
   MemBps                    uint64
   MemDirtyRateSet           bool
   MemDirtyRate              uint64
   MemPageSizeSet            bool
   MemPageSize               uint64
   MemIterationSet           bool
   MemIteration              uint64
   DiskTotalSet              bool
   DiskTotal                 uint64
   DiskProcessedSet          bool
   DiskProcessed             uint64
   DiskRemainingSet          bool
   DiskRemaining             uint64
   DiskBpsSet                bool
   DiskBps                   uint64
   CompressionCacheSet       bool
   CompressionCache          uint64
   CompressionBytesSet       bool
   CompressionBytes          uint64
   CompressionPagesSet       bool
   CompressionPages          uint64
   CompressionCacheMissesSet bool
   CompressionCacheMisses    uint64
   CompressionOverflowSet    bool
   CompressionOverflow       uint64
   AutoConvergeThrottleSet   bool
   AutoConvergeThrottle      int
   OperationSet              bool
   Operation                 DomainJobOperationType
   MemPostcopyReqsSet        bool
   MemPostcopyReqs           uint64
}
/*
22.     得到最大物理内存：func (d *Domain) GetMaxMemory() (uint64, error)
https://libvirt.org/html/libvirt-libvirt-domain.html#virDomainGetMaxMemory 
23.    客户机支持的最大虚拟cpu数量： func (d *Domain) GetMaxVcpus() (uint, error)
https://libvirt.org/html/libvirt-libvirt-domain.html#virDomainGetMaxVcpus 
24.     得到系统类型：func (d *Domain) GetOSType() (string, error)
https://libvirt.org/html/libvirt-libvirt-domain.html#virDomainGetOSType 
25.    得到内存参数？？：
 https://libvirt.org/html/libvirt-libvirt-domain.html#virDomainGetMemoryParameters */
type DomainMemoryParameters struct {
   HardLimitSet     bool
   HardLimit        uint64
   SoftLimitSet     bool
   SoftLimit        uint64
   MinGuaranteeSet  bool
   MinGuarantee     uint64
   SwapHardLimitSet bool
   SwapHardLimit    uint64
}

//26.     得到numa参数？？：
//https://libvirt.org/html/libvirt-libvirt-domain.html#virDomainGetNumaParameters 
type DomainNumaParameters struct {
   NodesetSet bool
   Nodeset    string
   ModeSet    bool
   Mode       DomainNumatuneMemMode
}

//27.     得到所有linux Perf事件：
//https://libvirt.org/html/libvirt-libvirt-domain.html#virDomainGetPerfEvents 
type DomainPerfEvents struct {
   CmtSet                   bool
   Cmt                      bool
   MbmtSet                  bool
   Mbmt                     bool
   MbmlSet                  bool
   Mbml                     bool
   CacheMissesSet           bool
   CacheMisses              bool
   CacheReferencesSet       bool
   CacheReferences          bool
   InstructionsSet          bool
   Instructions             bool
   CpuCyclesSet             bool
   CpuCycles                bool
   BranchInstructionsSet    bool
   BranchInstructions       bool
   BranchMissesSet          bool
   BranchMisses             bool
   BusCyclesSet             bool
   BusCycles                bool
   StalledCyclesFrontendSet bool
   StalledCyclesFrontend    bool
   StalledCyclesBackendSet  bool
   StalledCyclesBackend     bool
   RefCpuCyclesSet          bool
   RefCpuCycles             bool
   CpuClockSet              bool
   CpuClock                 bool
   TaskClockSet             bool
   TaskClock                bool
   PageFaultsSet            bool
   PageFaults               bool
   ContextSwitchesSet       bool
   ContextSwitches          bool
   CpuMigrationsSet         bool
   CpuMigrations            bool
   PageFaultsMinSet         bool
   PageFaultsMin            bool
   PageFaultsMajSet         bool
   PageFaultsMaj            bool
   AlignmentFaultsSet       bool
   AlignmentFaults          bool
   EmulationFaultsSet       bool
   EmulationFaults          bool
}

//28.     得到调度参数：
//https://libvirt.org/html/libvirt-libvirt-domain.html#virDomainGetSchedulerParameters 
type DomainSchedulerParameters struct {
   Type              string
   CpuSharesSet      bool
   CpuShares         uint64
   GlobalPeriodSet   bool
   GlobalPeriod      uint64
   GlobalQuotaSet    bool
   GlobalQuota       int64
   VcpuPeriodSet     bool
   VcpuPeriod        uint64
   VcpuQuotaSet      bool
   VcpuQuota         int64
   EmulatorPeriodSet bool
   EmulatorPeriod    uint64
   EmulatorQuotaSet  bool
   EmulatorQuota     int64
   IothreadPeriodSet bool
   IothreadPeriod    uint64
   IothreadQuotaSet  bool
   IothreadQuota     int64
   WeightSet         bool
   Weight            uint
   CapSet            bool
   Cap               uint
   ReservationSet    bool
   Reservation       int64
   LimitSet          bool
   Limit             int64
   SharesSet         bool
   Shares            int
}

//29.     得到安全标签：
//https://libvirt.org/html/libvirt-libvirt-domain.html#virDomainGetSecurityLabel 
type SecurityLabel struct {
   Label     string
   Enforcing bool
}
/*
30.     得到虚机系统时间： func (d *Domain) GetTime(flags uint32) (int64, uint, error)
https://libvirt.org/html/libvirt-libvirt-domain.html#virDomainGetTime 
31.     获取指定客户机和磁盘中每个装入的文件系统的映射信息列表：
https://libvirt.org/html/libvirt-libvirt-domain.html#virDomainGetFSInfo */
type DomainFSInfo struct {
   MountPoint string
   Name       string
   FSType     string
   DevAlias   []string
}
/*
32.     查询主机中所有仿真器线程的CPU关联设置，将其存储在cpumap中：
a)    Query the CPU affinity setting of all emulator threads of domain, store it in cpumap.
b)    func (d *Domain) GetEmulatorPinInfo(flags DomainModificationImpact) ([]bool, error)
c)    https://libvirt.org/html/libvirt-libvirt-domain.html#virDomainGetEmulatorPinInfo 
33.     获取活动主机的IO线程，包括cpumap信息，以确定iothread在哪个CPU上运行的关联性：
a)    Fetch IOThreads of an active domain including the cpumap information to determine on which CPU the IOThread has affinity to run
b)    https://libvirt.org/html/libvirt-libvirt-domain.html#virDomainGetIOThreadInfo */
type DomainIOThreadInfo struct {
   IOThreadID uint
   CpuMap     []bool
}
/*
34.     查询主机中所有虚拟CPU的CPU关联设置，将其存储在CPU映射中：
a)    Query the CPU affinity setting of all virtual CPUs of domain, store it in cpumaps.
b)    func (d *Domain) GetVcpuPinInfo(flags DomainModificationImpact) ([][]bool, error)
c)    https://libvirt.org/html/libvirt-libvirt-domain.html#virDomainGetVcpuPinInfo 
35.    从客户机的角度向客户机端查询有关VCPUS的状态和信息。报告的数据取决于客户机端实现。：
a)    Queries the guest agent for state and information regarding vCPUs from guest&#039;s perspective. The reported data depends on the guest agent implementation.
b)     https://libvirt.org/html/libvirt-libvirt-domain.html#virDomainGetGuestVcpus 
*/
type DomainGuestVcpus struct {
   VcpusSet      bool
   Vcpus         []bool
   OnlineSet     bool
   Online        []bool
   OfflinableSet bool
   Offlinable    []bool
}

//36.     得到安加载安全参数信息：
https://libvirt.org/html/libvirt-libvirt-domain.html#virDomainGetLaunchSecurityInfo 
type DomainLaunchSecurityParameters struct {
   SEVMeasurementSet bool
   SEVMeasurement    string
}</code></pre>
]]></content:encoded>
<slash:comments>0</slash:comments>
<comments>https://dwt.life/archives/81/#comments</comments>
<wfw:commentRss>https://dwt.life/feed/tag/libvirt/</wfw:commentRss>
</item>
</channel>
</rss>