On Wed, Nov 15, 2006 at 02:33:26AM +0000, Daniel P. Berrange wrote:
This is the main patch. It adds a new 'xm config file'
backend driver to
libvirt. This basically just scans /etc/xen for config files, reads them
and turns them into libvirt XML to create domains. Similarly it can accept
libvirt XML and create config files from it.
Haha, the whole point of the exercise :-)
Some important points
- It can override /etc/xen with LIBVIRT_XM_CONFIG_DIR env variable
- It only re-scans /etc/xen every X seconds & caches parsed config
files in-memory to avoid parsing / I/O overhead
- Automatically generates a UUID if the config file doesn;t have one
- Skips over a blacklist of files from /etc/xen which are known to
not be valid config files to avoid too many error messages
- Filters list of inactive domains to strip out any which are currently
running (acccording to XenD)
- Allows changing of VCPUS, memory & max memory config settings and
writes changes back out to disk
- Can start, create, delete domains from disk
+ /* This method is called by various methods to scan /etc/xen
+ (or whatever directory was set by LIBVIRT_XM_CONFIG_DIR
+ environment variable) and process any domain configs. It
+ has rate-limited so never rescans more frequently than
+ once every X seconds */
Right, I don't want to be chastanized publicly by Dave Jones again
at OLS 2007 :-)
+ static int xenXMConfigCacheRefresh(void) {
[...]
+ /* Skip anything which isn't a file (takes care of
scripts/ subdir */
+ if ((stat(path, &st) < 0) ||
+ !S_ISREG(st.st_mode)) {
I would put extra braces (!S_ISREG(st.st_mode)) ... paranoid as usual :-)
+ memset(info, 0, sizeof(virDomainInfo));
+ if (xenXMConfigGetInt(entry->conf, "memory", &mem) < 0 ||
+ mem < 0)
+ info->memory = 64 * 1024;
64 MB is a minimal memory limit that we are referencing in various places
in libvirt for Xen back-ends, maybe that ought to be isolated in internal.h
+ virBufferAdd(buf, "<domain
type='xen'>\n", -1);
+ virBufferVSprintf(buf, " <name>%s</name>\n", name);
Okay one of the things which scares me a bit here is encoding for the
strings. We generate XML files without any encoding information which means
it has to be UTF-8 (or UTF-16 but clearly it's not), it was more or less
fine to do those direct buffers write before because we were in a contained
environment, but now those strings come from external files, and well
a chinese person may genuinely want to use chinese name in his config file
and use BIG5 encoding for example, and in such case the config file generated
here would not be XML. I assume config files generated by virt-manager
when creating new domains are likely to use the strings returned from
Gnome widget, I wonder if it is UTF-8 or the encoding of the user's locale.
I guess the simplest and cleanest at this point would be to make sure
anything parsed by conf.[ch] is actually UTF-8, and maybe double check
virt-manager string generation.
+ virBufferVSprintf(buf, " <graphics
type='vnc' port='%d'/>\n", (5900+display));
Shouldn't the 5900 magic number be in a header too ?
+ /*
+ * Start a domain from an existing defined config file
+ */
+ int xenXMDomainCreate(virDomainPtr domain) {
+ char *xml;
+ char *sexpr;
+ int ret, xendConfigVersion;
+ unsigned char uuid[16];
+
+ if ((domain == NULL) || (domain->conn == NULL) || (domain->name == NULL)) {
+ xenXMError((domain ? domain->conn : NULL), VIR_ERR_INVALID_ARG,
+ __FUNCTION__);
+ return(-1);
+ }
+
+ if (domain->handle != -1)
+ return (-1);
+ if (domain->conn->flags & VIR_CONNECT_RO)
+ return (-1);
+
+ if (!(xml = xenXMDomainDumpXML(domain, 0)))
+ return (-1);
+
+ if ((xendConfigVersion = xend_get_config_version(domain->conn)) < 0) {
+ xenXMError(domain->conn, VIR_ERR_INTERNAL_ERROR, "cannot determine xend
config version");
+ return (-1);
+ }
+ printf("'%s'\n", xml);
+ if (!(sexpr = virDomainParseXMLDesc(xml, NULL, xendConfigVersion))) {
+ free(xml);
+ return (-1);
+ }
+ free(xml);
+ printf("'%s'\n", sexpr);
+ ret = xenDaemonDomainCreateLinux(domain->conn, sexpr);
+ free(sexpr);
+ if (ret != 0) {
+ fprintf(stderr, "Failed to create domain %s\n", domain->name);
+ return (-1);
+ }
+
+ ret = xend_wait_for_devices(domain->conn, domain->name);
+ if (ret != 0) {
+ fprintf(stderr, "Failed to get devices for domain %s\n",
domain->name);
+ return (-1);
+ }
+
+ if ((ret = xenDaemonDomainLookupByName_ids(domain->conn, domain->name, uuid))
< 0) {
+ return (-1);
+ }
+ domain->handle = ret;
+
+ ret = xenDaemonDomainResume(domain);
+ if (ret != 0) {
+ fprintf(stderr, "Failed to resume new domain %s\n",
domain->name);
+ xenDaemonDomainDestroy(domain);
+ domain->handle = -1;
+ return (-1);
+ }
+
+ return 0;
+ }
Good to finally have the bridge from config files to libvirt loading :-)
Very cool ! Push it :-)
Daniel
--
Red Hat Virtualization group
http://redhat.com/virtualization/
Daniel Veillard | virtualization library
http://libvirt.org/
veillard(a)redhat.com | libxml GNOME XML XSLT toolkit
http://xmlsoft.org/
http://veillard.com/ | Rpmfind RPM search engine
http://rpmfind.net/