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.
view plain copy to clipboard print ?
-
-
-
-
-
-
-
-
-
-
- #include <sys/types.h>
- #include <xs.h>
- #include <stdio.h>
- #include <string.h>
- #include <malloc.h>
- #include <sys/stat.h> // for lstat()
- #include <stdlib.h> // for exit()
- #define DOM0 0
- #define DOMU 1
- int dom = 999;
-
-
-
-
-
- check_dom()
- {
- FILE *file = NULL;
- char *filePath;
- struct stat linkAttrs;
- char buf[100] = "" ;
- filePath = "/proc/xen/capabilities" ;
- if ((lstat(filePath, &linkAttrs)) != 0) {
- perror("lstat" );
- return ;
- }
- if ((file = fopen( "/proc/xen/capabilities" , "r" )) == NULL) {
- perror("fopen" );
- return ;
- }
- if (!fgets(buf, sizeof (buf), file)) {
-
- printf("/n Surely in DOMU, since capabilities is empty" );
- dom = DOMU;
- return ;
- } else {
-
- printf("/n Probably in DOM0, since capabilities has some data" );
- dom = DOM0;
- }
-
-
- if ((strstr(buf, "control_d" )) == NULL) {
-
- printf("/n We are in DOMU" );
- dom = DOMU;
- } else {
-
- printf("/n We are in DOM0" );
- dom = DOM0;
- }
- return ;
- }
-
-
- write_to_xenstore (struct xs_handle *xs, char * path) {
- char somedata[8] = { "2200000" };
- xs_transaction_t trans;
- bool err;
- printf("/nWriting data %s of len %d to %s" ,
- somedata, strlen(somedata), path);
-
-
-
- err = xs_write(xs, XBT_NULL, path, &somedata[0],
- strlen(somedata));
- if (!err) {
- printf("/n Could'nt write var in xenstore" );
- }
- xs_daemon_close(xs);
- free(path);
- exit(0);
- }
- int main( int argc, char *argv[]) {
- struct xs_handle *xs;
- xs_transaction_t trans;
- char *path;
- int fd;
- fd_set set;
- bool err;
- struct timeval tv = {.tv_sec = 0, .tv_usec = 0};
- char **vec;
- unsigned int num;
- char *buf;
- char **buf2;
- unsigned int len, i;
- unsigned int domid;
-
- check_dom();
-
-
-
-
-
-
-
-
-
- if (dom == DOMU) {
- xs = xs_domain_open();
- if (xs == NULL) error();
- buf = xs_read(xs, XBT_NULL, "domid" , &len);
- if (!buf) {
- printf("/n Could not read domid" );
- return ;
- }
- domid = atoi(buf);
- printf("/n Retrieved Dom ID = %d/n" , domid);
- } else {
- xs = xs_daemon_open();
- if (xs == NULL) error();
- trans = xs_transaction_start(xs);
- if (trans == 0) {
- printf("/n Could not start xaction with XS" ); return ;
- }
-
-
- buf2 = xs_directory(xs, trans, "/local/domain" , &len);
- if (!buf2) {
- printf("/n Could not read XS dir /local/domain" ); return ;
- }
- xs_transaction_end(xs, trans, true );
- if (trans == 0) {
- printf("/n Could not end xaction with XS" ); return ;
- }
- printf("/n Len of Dir /local/domain is %d" , len);
- printf("/n Dir Contents: " );
- for (i=0; i<len;i++) { printf( "%s " , buf2[i]); }
- if (len == 1) {
-
- domid = atoi(buf2[0]);
- } else if (len == 2) {
- domid = atoi(buf2[1]);
- }
-
- domid = 0;
- printf("/n Setting Dom ID = %d/n" , domid);
- }
-
- path = xs_get_domain_path(xs, domid);
- if (path == NULL) {
- printf("/n Dom Path in Xenstore not found" );
- error(); return ;
- }
-
-
-
- if (dom == DOM0) {
- path = realloc(path, strlen(path) + strlen("/memory/target" ) + 1);
- if (path == NULL) {
- error(); return ;
- }
- strcat(path, "/memory/target" );
- } else {
- strcpy(path, "memory/target" );
- }
-
- printf("/nPath = %s" , path);
-
-
-
-
- #ifdef WRITE
- write_to_xenstore(xs, path);
- #endif
-
- err = xs_watch(xs, path, "mytoken" );
- if (err == 0) {
- printf("/n Error in setting watch on mytoken in %s" , path);
- error(); return ;
- }
-
- fd = xs_fileno(xs);
- while (1) {
- FD_ZERO(&set);
- FD_SET(fd, &set);
- printf("!-" );
- fflush(stdout);
- struct timeval tv = {.tv_sec = 5, .tv_usec = 0};
- if (select(fd+1, &set, NULL, NULL, &tv) > 0
- && FD_ISSET(fd, &set)) {
- printf("@" );
-
-
-
- vec = xs_read_watch(xs, &num);
- if (!vec) {
- printf("Error on watch firing" );
- error(); return ;
- }
-
-
- printf("/nvec contents: %s|%s/n" , vec[XS_WATCH_PATH],
- vec[XS_WATCH_TOKEN]);
-
- trans = xs_transaction_start(xs);
- if (trans == 0) {
- printf("/n Could'nt start xaction xenstore" );
- return ;
- }
- buf = xs_read(xs, trans, vec[XS_WATCH_PATH], &len);
- if (!buf) {
- printf("/n Could'nt read watch var in vec" );
- return ;
- }
- xs_transaction_end(xs, trans, true );
- if (trans == 0) {
- printf("/n Could not end xaction xenstore" );
- return ;
- }
- if (buf) {
- printf("/n buflen: %d, buf: %s" , len, buf);
- }
- }
- }
- printf("/n" );
-
- close(fd);
- xs_daemon_close(xs);
- free(path);
- return ;
- }