XenStore Reference
About
This document describes the format of the entries in XenStore, how and what they're used for, and how third-party apps should use Xen
Store as a management interface. There are also code examples provided showing how to use the Xen
Store API. The xenstore is maintained by the Xenstored.
Overview
XenStore is a hierarchical namespace (similar to sysfs or Open Firmware) which is shared between domains. The interdomain communication primitives exposed by Xen are very low-level (virtual IRQ and shared memory). Xen
Store is implemented on top of these primitives and provides some higher level operations (read a key, write a key, enumerate a directory, notify when a key changes value).
XenStore is a database, hosted by domain 0, that supports transactions and atomic operations. It's accessible by either a Unix domain socket in Domain-0, a kernel-level API, or an ioctl interface via /proc/xen/xenbus. Xen
Store should always be accessed through the functions defined in <xs.h>. Xen
Store is used to store information about the domains during their execution and as a mechanism of creating and controlling Domain-U devices.
XenBus is the in-kernel API used by virtual I/O drivers to interact with Xen
Store.
Contents
Canonical information on the paths used within xenstore are contained in the xen.git documentation tree, see: http://xenbits.xen.org/docs/unstable/misc/xenstore-paths.html
Interacting with the XenStore
The XenStore interface provides transaction based reads and writes to points in the xenstore hierarchy. Watches can be set at points in the hierarchy and an individual watch will be triggered when anything at or below that point in the hierachy changes. A watch is registered with a callback function and a "token". The "token" can be a pointer to any piece of data. The callback function is invoked with the of the changed node and the "token".
The interface is centered around the idea of a central polling loop that reads watches, providing the path, callback, and token, and invoking the callback.
API Usage Examples
These code snippets should provide a helpful starting point.
C
#include <xenstore.h> // Prior to Xen 4.2.0 use xs.h // don't forget to link with -lxenstore struct xs_handle *xs; xs_transaction_t th; char *path; int fd; fd_set set; int er; struct timeval tv = {.tv_sec = 0, .tv_usec = 0 }; char **vec; unsigned int num_strings; char * buf; unsigned int len; /* Get a connection to the daemon */ xs = xs_daemon_open(); if ( xs == NULL ) error(); /* Get the local domain path */ path = xs_get_domain_path(xs, domid); // replace "domid" with a valid domain ID (or one which will become valid) if ( path == NULL ) error(); /* Make space for our node on the path */ path = realloc(path, strlen(path) + strlen("/mynode") + 1); if ( path == NULL ) error(); strcat(path, "/mynode"); /* Create a watch on /local/domain/%d/mynode. */ er = xs_watch(xs, path, "mytoken"); if ( er == 0 ) error(); /* We are notified of read availability on the watch via the * file descriptor. */ fd = xs_fileno(xs); while (1) { /* TODO (TimPost), show a simpler example with poll() * in a modular style, using a simple callback. Most * people think 'inotify' when they see 'watches'. */ FD_ZERO(&set); FD_SET(fd, &set); /* Poll for data. */ if ( select(fd + 1, &set, NULL, NULL, &tv) > 0 && FD_ISSET(fd, &set)) { /* num_strings will be set to the number of elements in vec * (typically, 2 - the watched path and the token) */ vec = xs_read_watch(xs, &num_strings); if ( !vec ) error(); printf("vec contents: %s|%s\n", vec[XS_WATCH_PATH], vec[XS_WATCH_TOKEN]); /* Prepare a transaction and do a read. */ th = xs_transaction_start(xs); buf = xs_read(xs, th, vec[XS_WATCH_PATH], &len); xs_transaction_end(xs, th, false); if ( buf ) { printf("buflen: %d\nbuf: %s\n", len, buf); } /* Prepare a transaction and do a write. */ th = xs_transaction_start(xs); er = xs_write(xs, th, path, "somestuff", strlen("somestuff")); xs_transaction_end(xs, th, false); if ( er == 0 ) error(); } } /* Cleanup */ close(fd); xs_daemon_close(xs); free(path);
Python
pyxs
The pyxs project provides a pure-Python interface to xenstore. It exposes the same functionality as libxenstore, plus some additional Python sugar.
See also http://pyxs.readthedocs.org/en/latest/
xen.lowlevel.xs
The xen.lowlevel.xs
module shipped by Xen provides a low-level binding over the C libxenstored.