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;
- }
参考:
1] The Definitive Guide to the Xen Hypervisor David Chisnall
2] http://www.cs.uic.edu/~spopuri/minios.html
3] http://wiki.xensource.com/xenwiki/XenStoreReference
4] http://wiki.xensource.com/xenwiki/XenBus
5] http://lists.xensource.com/archives/html/xen-devel/2005-12/msg00151.html
6] http://wiki.xensource.com/xenwiki/XenBus
7] http://knol.google.com/k/learning-xenstore