管理下虚拟机如何? libvirt的一些基本用法

来源:互联网 发布:淘宝天猫商城入驻 编辑:程序博客网 时间:2024/06/03 08:02

See the brief introduction in:http://en.wikipedia.org/wiki/Libvirt

 

源自我们已经用KVM创建了一个虚拟机,这时你想再创建一个,这当然没有问题,但问题是如果你创建很多个虚拟机,你想对其中的一个进行停止操作,你需要PS下kvm进程,然后再处理,这样我们就想到事情能不能简单一点,谁帮我管理一下这几个破虚拟机好不好。

  先行者们也已经早就想到了,Libvirt就是开源的虚拟机管理程序,当然它支持qemu,xen....

   1. 安装

       ubuntu的世界,安装永远不是问题,apt-get install

   2. 导入我们之前创建的虚拟机

       virt-install --import --name demo3 --ram 512 --disk path=/media/kvm/winxp.img,format=qcow2 

       解释下:--import 是告诉这个工具,镜像我都做好系统了,用kvm启动他就行

                       --name xxx 告诉这个工具,以后这个镜像就叫这个名字了,你想对他做什么,告诉名字就可以

                       --raw 512 虚拟机内存啦

                       --disk path 镜像的地址

                                 format  镜像的格式(libvirt默认是raw,如果不是raw必须要显示指出,否则会报boot失败)

 

  3. 上面的操作就已经将这个虚拟机启动了,并且用virt-viewer打开了

   4. 想管理他是吧,有两个工具

      图形的virt-manager,这个不讲了,点点点

      文本交互的virsh

      virsh  -c kemu:///system

       virsh shutdown demo 关闭虚拟机

   5. Libvirt提供了多种语言绑定开发,C/java/python

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

 

一般而言,程序之中最最重要的是数据结构,故而我们从查找核心数据结构开始,但最初的表象切入点是libvirt的交互工具virsh。

 


 

 


  1. 存储池的核心数据结构

          

 

[cpp:showcolumns] view plaincopy
·········10········20········30········40········50········60········70········80········90········100·······110·······120·······130·······140·······150
  1. typedef struct _virStoragePoolObj virStoragePoolObj;  
  2. typedef virStoragePoolObj *virStoragePoolObjPtr;  
  3. struct _virStoragePoolObj {  
  4.     virMutex lock;                                                //线程异步锁  
  5.     char *configFile;                                            //XML文件路径  
  6.     char *autostartLink;                                       //软链接位置  
  7.     int active;                                                       //是否激活  
  8.     int autostart;                                                   //是否自动启用  
  9.     unsigned int asyncjobs;                                 //异步线程号  
  10.     virStoragePoolDefPtr def;                            //当前存储池属性  
  11.     virStoragePoolDefPtr newDef;                    //新存储池属性  
  12.     virStorageVolDefList volumes;                   //当前存储池中卷列表  
  13. };  

 

          其中的virStoragePoolDefPtr类型是存储池属性数据结构

          

 

[c-sharp] view plaincopy
  1. typedef struct _virStoragePoolDef virStoragePoolDef;  
  2. typedef virStoragePoolDef *virStoragePoolDefPtr;  
  3. struct _virStoragePoolDef {  
  4.     /* General metadata */  
  5.     char *name;                                                         //存储池的名字  
  6.     unsigned char uuid[VIR_UUID_BUFLEN];     //UUID  
  7.     int type; /* virStoragePoolType */                      //类型  
  8.     unsigned long long allocation;                            //使用容量大小  
  9.     unsigned long long capacity;                              //全部容量大小  
  10.     unsigned long long available;                             //可用容量大小  
  11.     virStoragePoolSource source;                            //原路径  
  12.     virStoragePoolTarget target;                              //目的路径  
  13. };  

 

 

          找到以上两个核心数据结构,就基本上能够了解到如何描述每一个存储池,但是libvirt需要管理的是多个存储池

          这时需要用到结构指针: 理解起来也简单,类似于一个数组, *p[1] 可以找到第二个结构变量

<细节>指针可以用malloc在堆上给他分配几个sizeof()的大小,存放几个结构变量,需要改数量时calloc堆上内存块的大小,根据调整变量的位置,通过memmove移动其他结构变量的位置。

 

          实际使用中,又引入了这个结构体,便于获得到结构指针指向内存区域中结构变量的总个数

          

 

[c-sharp] view plaincopy
  1. typedef struct _virStoragePoolObjList virStoragePoolObjList;  
  2. typedef virStoragePoolObjList *virStoragePoolObjListPtr;  
  3. struct _virStoragePoolObjList {  
  4.     unsigned int count;  
  5.     virStoragePoolObjPtr *objs;  
  6. }  

 

          libvirt.c中conn->storageDriver->pools 就是这个类型的

 

2. 核心业务流程

        表象 -> 细节

        virsh的命令行 -> tools/virsh.c代码 -> src/libvirt.c -> src/storage/storage_dirver.c -> src/storage/storage_backend_XX.c

 

3. 新建存储池类操作

        表象: 支持DIR,FS,NetFS,Logical,Disk,IScsi,Scsi,multipath  (我们实际上只关=心DIR,FS,NetFs,Iscsi)

        细节: DIR,FS,NetFS的卷的一些poolcreate,poolstart等需要实际跟操作系统打交道的功能是走的storage_backend_fs.c这个后端

                     同样的Logical,Disk,Iscsi,Scsi,mpath都有各自的后端

 

       <一> pool-define              virsh命令之一,用于按照提供的XML描述的内容,在存储池列表中新加入一个存储池,只加入不起用

                                                 XML描述格式,我们只关心DIR,Fs,NetFs,Iscsi几种

                                                 DIR:

                                                

 

[c-sharp] view plaincopy
  1. <pool type="dir">  
  2.     <name>virtimages</name>  
  3.     <target>  
  4.         <path>/var/lib/virt/images</path>  
  5.     </target>  
  6. </pool>  

 

                                                 Fs:

                                                

 

[c-sharp] view plaincopy
  1. <pool type="fs">  
  2.     <name>virtimages</name>  
  3.     <source>  
  4.         <device path="/dev/VolGroup00/VirtImages"/>  
  5.     </source>  
  6.     <target>  
  7.         <path>/var/lib/virt/images</path>  
  8.     </target>  
  9. </pool>  

 

                 NetFs:

                                                

 

[c-sharp] view plaincopy
  1. <pool type="netfs">  
  2.     <name>virtimages</name>  
  3.     <source>  
  4.         <host name="nfs.example.com"/>  
  5.         <dir path="/var/lib/virt/images"/>  
  6.     </source>  
  7.     <target>  
  8.         <path>/var/lib/virt/images</path>  
  9.     </target>  
  10. </pool>  

 

                                                 Iscsi:  这里path不指明一个固定的块设备,是因为物理机硬盘数的不确定性

                                                

 

[c-sharp] view plaincopy
  1. <pool type="iscsi">  
  2.     <name>virtimages</name>  
  3.     <source>  
  4.         <host name="iscsi.example.com"/>  
  5.         <device path="demo-target"/>  
  6.     </source>  
  7.     <target>  
  8.         <path>/dev/disk/by-path</path>  
  9.     </target>  
  10. </pool>  

 

                           命令使用:

                                virsh> pool-define /tmp/default.xml


                          <细节> pool-define 只是把你要加入到存储池大家庭的这个存储池介绍给libvirt认识,他只看到的你的外表而已,不追究你的内在存不存在,但是你在libvirt那里已经挂上号了,pool-list --all 就能看到你,你是inactive的

                                        代码:src/storage/storage_driver.cstoragePoolDefine函数中做以下几个事情:

                                                     * 读入xml信息 --virStoragePoolDefParseString

                                                     * 按读入的xmlnameuuid 信息判断是否在driver-pools重复存在 --virStoragePoolObjIsDuplicate

                                                     * 按读入的xmltype 判断类型写入dep->type --virStorageBackendForType

                                                     * 扩展分配结构指针的的大小 calloc +1 并且driver->pools->count +1

dirver->pools->obj[dirver->pools->count] = pool (这个是传入的xml构建的) --virStoragePoolObjAssignDef

                                                     * 将存储池信息保存到指定配置文件位置,如果autostart==1,做软连接存储信息均为0 -virStoragePoolDefFormat 构建xml --virStoragePoolObjSaveDef 保存xml

                                                    * hypervisor connection注册存储池,加入到HashTable里 --virGetStoragePool


      <二> pool-define-as          virsh命令之一,pool-define的变种,不需要实现准备XML描述文件,把参数按照固定格式传入即可

                                                    他有个重要的选项 --print-xml 可以看到你输入的参数构成的XML,对照出那个参数传入的不对应。

                           命令使用: virsh> pool-define-as test, 0,0,0,0,/tmp/test                       


      <三> pool-build                 virsh命令之一,针对dir,fs,netfs,logical,disk几种类型,如果pool-define时<path>参数指定的文件夹不存在的话,他会调用Linux基本文件操作函数创建这个目录,如果存在,他回修改文件夹的属性为可写

                           命令使用: virsh> pool-build test


      <四> pool-start                  virsh命令之一,针对与处在inactive 状态的存储池有效,pool-list 可以看到状态为active,也可以在创建卷时使用这个存储池了。

                          命令使用:virsh> pool-start test


                           <细节>          一方面修改核心数据结构中变量的active参数,另一方面做一些二道贩子的事,如

                                                  dir/fs/netfs类型 脚本执行 mount/mount.nfs

                                                  iscsi  脚本执行iscsiadm XXXXX --login

                                                  执行上面命令后,回调用refresh_pool的函数,获取pool的容量信息,并存入核心数据结构变量中

                           

      <五> pool-create             virsh命令之一,根据传入的XML描述文件,在存储池列表中新加入一个存储池,并且挂载启用它,代码是集pool-define和pool-start于一体,故而如果传入的XML描述文件的path指定文件夹不存在,则操作汇报错

                          命令使用:virsh>pool-create /tmp/example.xml


     <六> pool-create-as        virsh命令之一,pool-create的变种,不需要实现准备XML描述文件,把参数按照固定格式传入即可


                                                    他有个重要的选项 --print-xml 可以看到你输入的参数构成的XML,对照出那个参数传入的不对应。

                         命令使用:virsh>pool-create-as test, 0,0,0,0,/tmp/test


4. 删除/停止存储池类操作

     <七> pool-destory    virsh命令之一,停止正在工作的存储卷,pool-list 会看到变为inactive,但不改变其中内容

                        命令使用: virsh>pool-destory test

                        <细节>        改变核心数据结构变量的active的值为0

                                             后端处理不同 fs,netfs 分别执行 umount / umount.nfs

                                                                      iscsi来说就是iscsiadm xxxxx --logout

     

     <八> pool-delete     virsh命令之一,将非激活的存储卷中的内容清空,针对fs,netfs,dir,logical类型有效

                       命令使用:virsh>pool-delete test

                       <细节>         后端调用 rm -f 这个脚本命令


     <九> pool-undefine  virsh命令之一,将非激活的存储卷从存储卷列表中清除

                       命令使用; virsh>pool-undefine test

                       <细节>         src/storage/storage_driver.c storagePoolUndefine函数,做了这么几件事

                                             * 判断pool是否存在于关键数据结构列表中

                                             * 判断是否为inactive

                                             * 判断是否没有异步线程

                                             *  unlink(ConfigureFile),删除xml文件 --virStoragePoolObjDeleteDef

                                             * 不论是否为autostart,删除软连接 --unlink

                                             *  释放结构指针多余内存,count -1,调整结构指针大小 --virStoragePoolObjRemove


5. 修改存储池类操作

     <十> pool-edit             virsh命令之一,修改存储池属性,修改内容保存在结构体的newDef中,重启libvirt服务生效

                       命令使用: virsh>pool-edit test


6. 查询存储池类操作

     <十一> virsh pool-dumpxml  virsh命令之一,查看存储池的XML描述文件内容

                       命令使用: virsh>pool-dumpxml test

                       <细节>        virStoragePoolDefFormat函数


     <十二> pool-list          virsh命令之一, --all/--inactive/--details 可以看到全部/非激活/细节

                       命令使用: virsh>pool-list --all

                       <细节>        先通过pools->count 得到总数量,根据条件遍历出active 数量

                                           再遍历pools,得到name等的数组,按字母顺序排序


     <十三> pool-info        virsh命令之一,获得存储池的信息

激活的显示name,uuid,state,autostart,presistent和容量信息

非激活的显示 name,uuid,state,autostart,presistent信息

                        命令使用: virsh>pool-info test

                        <细节>        virStoragePoolGetInfo函数得到信息


     <十四> pool-refresh  virsh命令之一,刷新存储池,是个异步任务,先清空当前volumes列表,后端执行refreshPool 更新volumes列表,更新pool的容量信息

                         命令使用: pool-refresh

 

 

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

Libvirt 编译与安装:http://www.docin.com/p-379569057.html

 

原创粉丝点击