现在的位置: 首页 > 综合 > 正文

xenstore2

2018年04月12日 ⁄ 综合 ⁄ 共 9650字 ⁄ 字号 评论关闭

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. }  

抱歉!评论已关闭.