xenstore2

XenStore 是一个类似于数据库的文件系统, 包含了domain间的共享信息. 有domain配置和状态信息.XenStore 提供了一种发现设备信息的简便方法. 它作为数据库在 /var/lib/xenstore/tdb, 在用户空间的 daemon 称为 "xenstored".这个逻辑文件树有三个主要的路径:

/vm - /vm/uuid 存储配置信息,例如虚拟CPU数和内存分配数.

/local/domain - 包含了正在运行的domain信息, 由domid标识.

/tool - 存储多种工具信息.

应用程序向这个数据库的 key 写信息, 配置驱动; 驱动在key上设置watch并对改变做出回应.

详细介绍请参考: http://wiki.xensource.com/xenwiki/XenStoreReference

访问xenstore

在guest kernel启动时xenstore经过start_info页而被访问到, 作为共享页的机器页帧号和event channel使用.Dom0工具使用UNIX domain socket /var/run/xenstored/socket 或 /var/run/xenstoed/socket_ro; Dom0工具使用proce接口/proc/xen/xenbus, 内核代码使用xenbus API.

命令

xenstore-read, xenstore-exists, xenstore-list, xenstor-, xsls, 用于和xenstored daemon数据库通信.
e.g. - #xenstore-list /local/domain/0

Domain 标识

1) 通用唯一标识符(UUID)是标识domain的数字, 即使guest迁移也保持相同.

2) domain 标识(DOMID) 标识一个正在运行的实例, 当guest 迁移到另一台机器后DOMID改变.

什么是Xenbus

Xenbus是Xenstore的一个接口, 它也是在Xenstore之上写的设备驱动的连接协议. Xenbus是一个虚拟设备的mgmt bus. Xen PV "backend" 设备出现在xenbus上, 而且能被DomU使用PV "fronted"设备驱动访问到. 这些虚拟后端设备的状态由xenbus管理. 这些状态被存储到xenstore, 并且一直被Dom0和DomU的xenbus驱动程序监测.XenStore 指供了一个domain如何将前端设备与后端提供的服务联系起来的方法, (实际这部分是由XenBus承载的, 一种建立在XenStore顶层的协议). 后端与前端通信使用共享event channel 和 ring buffer通信. 所有规范的xen虚拟设备驱动在初始化时向XenBus注册自己. 这是通过传递xenbus_driver 结构体给
xenbus_register_devide()函数.

代码

以下代码创建两个可执行的, xenstore-read 和 xenstore-write 程序.

在一个Dom中运行xenstore-read - 从 /loca/doman/X/memory/target 读取Domx的memory/target值.依赖于你运行这个程序所在的Dom.

在一个Dom中运行xenstore-wirte - 写一个memory/target值到这个程序所运行的Dom.

  1. // Example taken from wiki.xensource.com/xenwiki/XenStoreReference and some code added   
  2. //   
  3. // Compiled using   
  4. //        gcc -g xenstore.c -DREAD=1 -lxenstore -o xenstore-read   
  5. //        gcc -g xenstore.c -DWRITE=1 -lxenstore -o xenstore-write   
  6. //   
  7. // To change permissions on /local/domain/0, use   
  8. // xenstore-chod -r /local/domain/0 b  - for r and w   
  9. // xenstore-chod -r /local/domain/0 w  - for w   
  10. //   
  11. #include <sys/types.h>   
  12. #include <xs.h>   
  13. #include <stdio.h>   
  14. #include <string.h>   
  15. #include <malloc.h>   
  16. #include <sys/stat.h> // for lstat()   
  17. #include <stdlib.h> // for exit()   
  18. #define DOM0 0   
  19. #define DOMU 1   
  20. int  dom = 999;  
  21. // This function checks if the app is in domU or dom0. The /proc/xen/capabilities   
  22. // contains the string "control_d" if the app is in a dom0   
  23. //   
  24. // /sys/hypervisor/type can be checked too, to see if we are running on a xen   
  25. // hyervisor   
  26. check_dom()  
  27. {  
  28.     FILE  *file = NULL;  
  29.     char  *filePath;  
  30.     struct  stat linkAttrs;  
  31.     char  buf[100] =  "" ;  
  32.     filePath = "/proc/xen/capabilities" ;  
  33.     if  ((lstat(filePath, &linkAttrs)) != 0) {  
  34.         perror("lstat" );  
  35.         return ;  
  36.     }  
  37.     if  ((file = fopen( "/proc/xen/capabilities""r" )) == NULL) {  
  38.         perror("fopen" );  
  39.         return ;  
  40.     }     
  41.     if  (!fgets(buf,  sizeof (buf), file)) {  
  42.         // we are in DomU, since the buffer is empty   
  43.         printf("/n Surely in DOMU, since capabilities is empty" );  
  44.         dom = DOMU;  
  45.         return ;  
  46.     } else  {  
  47.         // we are probably in Dom0   
  48.         printf("/n Probably in DOM0, since capabilities has some data" );  
  49.         dom = DOM0;  
  50.     }  
  51.     // the following is in case they change the capabilities to have some   
  52.     // data in a DomU   
  53.     if  ((strstr(buf,  "control_d" )) == NULL) {  
  54.         // we are in DomU   
  55.         printf("/n We are in DOMU" );  
  56.         dom = DOMU;  
  57.     } else  {  
  58.         // we are in Dom0   
  59.         printf("/n We are in DOM0" );  
  60.         dom = DOM0;  
  61.     }  
  62.     return ;  
  63. }  
  64. // xs_write is written outside a transaction. Else it does not work for me. Pass   
  65. // a XBT_NULL as a 2nd param to xs_write().   
  66. write_to_xenstore (struct  xs_handle *xs,  char * path) {  
  67.     char             somedata[8] = { "2200000" };  
  68.     xs_transaction_t    trans;  
  69.     bool             err;  
  70.     printf("/nWriting data %s of len %d to %s" ,  
  71.             somedata, strlen(somedata), path);  
  72.     // xs_write() -> xs_talkv()   
  73.     //    -> xs_write_all() -> write() - sys_write()   
  74.     //    -> xs_read_reply()   
  75.     err = xs_write(xs, XBT_NULL, path, &somedata[0],  
  76.                 strlen(somedata));  
  77.     if  (!err) {  
  78.         printf("/n Could'nt write var in xenstore" );  
  79.     }  
  80.     xs_daemon_close(xs);  
  81.     free(path);  
  82.     exit(0);  
  83. }  
  84. int  main( int  argc,  char  *argv[]) {  
  85.     struct  xs_handle    *xs;     // handle to xenstore   
  86.     xs_transaction_t    trans;  
  87.     char             *path;  
  88.     int             fd;  
  89.     fd_set            set;  
  90.     bool             err;  
  91.     struct  timeval tv = {.tv_sec = 0, .tv_usec = 0};  
  92.     char              **vec;  
  93.     unsigned int          num;  
  94.     char             *buf;  
  95.     char             **buf2;  
  96.     unsigned int         len, i;  
  97.     unsigned int         domid;  
  98.     // check if we are in Dom0 or DomU   
  99.     check_dom();  
  100.     // Connect to XenStore. From Dom0 we call xs_daemon_open,   
  101.     // and from DomU, we call xs_domain_open().    
  102.     // xs_daemon_open() -> get_handle(xs_daemon_socket()).   
  103.     // xs_daemon_socket()->xs_daemon_path() which returns   
  104.     // XENSTORED_PATH/socket. A get_handle() on the above path generates   
  105.     // a socket (PF_UNIX, SOCK_STREAM, 0) and connects to above socket.   
  106.     // For domU, connect to XenStore via xs_domain_open().   
  107.     // xs_domain_dev() returns path to /proc/xen/xenbus, and a   
  108.     // get_handle() on this returns a 'fd' to this file.   
  109.     if  (dom == DOMU) {  
  110.         xs = xs_domain_open(); // DomU   
  111.         if  (xs == NULL) error();  
  112.         buf = xs_read(xs, XBT_NULL, "domid" , &len);  
  113.         if  (!buf) {  
  114.             printf("/n Could not read domid" );  
  115.             return ;  
  116.         }  
  117.         domid = atoi(buf);  
  118.         printf("/n Retrieved Dom ID = %d/n" , domid);  
  119.     } else  {  
  120.         xs = xs_daemon_open();  // Dom0   
  121.         if  (xs == NULL) error();  
  122.         trans = xs_transaction_start(xs);  
  123.         if  (trans == 0) {  
  124.             printf("/n Could not start xaction with XS" );  return ;  
  125.         }  
  126.         // Get contents of a directory. Need to call free after use,   
  127.         // since the API mallocs memory   
  128.         buf2 = xs_directory(xs, trans, "/local/domain" , &len);  
  129.         if  (!buf2) {  
  130.             printf("/n Could not read XS dir /local/domain" );  return ;  
  131.         }  
  132.         xs_transaction_end(xs, trans, true );  
  133.         if  (trans == 0) {  
  134.             printf("/n Could not end xaction with XS" );  return ;  
  135.         }  
  136.         printf("/n Len of Dir /local/domain is %d" , len);  
  137.         printf("/n Dir Contents: " );  
  138.         for  (i=0; i<len;i++) { printf( "%s " , buf2[i]); }  
  139.         if  (len == 1) {  
  140.             // we have only 1 Dom running, i.e. Dom0   
  141.             domid = atoi(buf2[0]);  
  142.         } else   if  (len == 2) {  
  143.             domid = atoi(buf2[1]);  
  144.         }  
  145.         // Set domid to 0, since Dom0 is always id 0   
  146.         domid = 0;  
  147.         printf("/n Setting Dom ID = %d/n" , domid);  
  148.     }  
  149.     // Get the local Domain path in xenstore   
  150.     path = xs_get_domain_path(xs, domid);  
  151.     if  (path == NULL) {  
  152.         printf("/n Dom Path in Xenstore not found" );  
  153.         error(); return ;  
  154.     }  
  155.     // xs_directory has an implicit root at /local/domain/<domid> in DomU   
  156.     // and thus need to just pass "memory/target" if we are running this   
  157.     // from a DomU to read the directory's contents   
  158.     if  (dom == DOM0) {  
  159.         path = realloc(path, strlen(path) + strlen("/memory/target" ) + 1);  
  160.         if  (path == NULL) {  
  161.             error(); return ;  
  162.         }  
  163.         strcat(path, "/memory/target" );  
  164.     } else  {  
  165.         strcpy(path, "memory/target" );  
  166.     }  
  167.          
  168.     printf("/nPath = %s" , path);  
  169.      
  170.     // If we are doing a write to the xenstore, branch off here and   
  171.     // then exit from the program. Else for read, cary on, and do a   
  172.     // select() to wait for a change in watched values   
  173. #ifdef WRITE   
  174.     write_to_xenstore(xs, path);  
  175. #endif   
  176.     // Create a watch on the path   
  177.     err = xs_watch(xs, path, "mytoken" );  
  178.     if  (err == 0) {  
  179.         printf("/n Error in setting watch on mytoken in %s" , path);  
  180.         error(); return ;  
  181.     }  
  182.     // Watches are notified via a File Descriptor. We can POLL on this.   
  183.     fd = xs_fileno(xs);  
  184.     while  (1) {  
  185.         FD_ZERO(&set);  
  186.         FD_SET(fd, &set);  
  187.         printf("!-" );  
  188.         fflush(stdout);  
  189.         struct  timeval tv = {.tv_sec = 5, .tv_usec = 0};  
  190.         if  (select(fd+1, &set, NULL, NULL, &tv) > 0  
  191.             && FD_ISSET(fd, &set)) {  
  192.             printf("@" );  
  193.             // This blocks is nothing is pending. Returns an array   
  194.             // containing path and token. Use Xs_WATCH_* to   
  195.             // access these elements. Call free after use.   
  196.             vec = xs_read_watch(xs, &num);  
  197.             if  (!vec) {  
  198.                 printf("Error on watch firing" );  
  199.                 error(); return ;  
  200.             }  
  201.             // In our example code, the following will print out   
  202.             // /local/domain/0/memory/target|mytoken   
  203.             printf("/nvec contents: %s|%s/n" , vec[XS_WATCH_PATH],  
  204.                     vec[XS_WATCH_TOKEN]);  
  205.             // Prepare a transacation to do a read   
  206.             trans = xs_transaction_start(xs);  
  207.             if  (trans == 0) {  
  208.                 printf("/n Could'nt start xaction xenstore" );  
  209.                 return ;  
  210.             }  
  211.             buf = xs_read(xs, trans, vec[XS_WATCH_PATH], &len);  
  212.             if  (!buf) {  
  213.                 printf("/n Could'nt read watch var in vec" );  
  214.                 return ;  
  215.             }  
  216.             xs_transaction_end(xs, trans, true );  
  217.             if  (trans == 0) {  
  218.                 printf("/n Could not end xaction xenstore" );  
  219.                 return ;  
  220.             }  
  221.             if  (buf) {  
  222.                 printf("/n buflen: %d, buf: %s" , len, buf);  
  223.             }  
  224.         } // end of select   
  225.     } // end while(1)   
  226.     printf("/n" );  
  227.     // cleanup   
  228.     close(fd);  
  229.     xs_daemon_close(xs);  
  230.     free(path);  
  231.     return ;  
  232. }  

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值