Kiarie Kahurani wrote: > Introduce a xen xl parser > > This parser allows for users to convert the new xl disk format and > spice graphics config to libvirt xml format and vice versa.Regarding > the spice graphics config, the code is pretty much straight forward > For the disk {formating, parsing} this parser takes care of the new > xl format which include positional parameters and key/value parameters > In xl format disk config a <diskspec> consists of parameters separated by > commas.If the parameters do not contain an '=' they are automatically > assigned to certain options following the order below > > target, format, vdev, access > > The above are the only mandatory parameters in the <diskspec> but there > are many more disk config options.This options can be specified as > key=value pairs This takes care of the rest of the options such as > > devtype, backend, backendtype, script, direct-io-safe, > > The positional paramters can also be specified in key/value form > for example > > /dev/vg/guest-volume,,hda > /dev/vg/guest-volume,raw,hda,rw > format=raw, vdev=hda, access=rw, target=/dev/vg/guest-volume > > are interpleted to one config > > In xm format a config equivalent to the one about would have been > > raw:/dev/vg/guest-volume,hda,w > > As of this commit, libvirt can not convert xl disk config such as > > /dev/vg/guest-volume,,hda > > to libvirt xml > > <disk type='block' device='disk'> > <driver name='qemu' type='raw'/> > <source file=/dev/vg/guest-volume/> > <target dev='hdc' bus='ide'/> > </disk> > > Signed-off-by: Kiarie Kahurani <davidkiarie4@xxxxxxxxx> > --- > configure.ac | 5 +- > src/Makefile.am | 21 +- > src/libvirt_xenconfig.syms | 4 + > src/xenconfig/libxlu_disk_i.h | 28 +++ > src/xenconfig/libxlu_disk_l.l | 292 ++++++++++++++++++++++++++ > src/xenconfig/xen_common.c | 3 +- > src/xenconfig/xen_xl.c | 476 ++++++++++++++++++++++++++++++++++++++++++ > src/xenconfig/xen_xl.h | 29 +++ > 8 files changed, 852 insertions(+), 6 deletions(-) > create mode 100644 src/xenconfig/libxlu_disk_i.h > create mode 100644 src/xenconfig/libxlu_disk_l.l > create mode 100644 src/xenconfig/xen_xl.c > create mode 100644 src/xenconfig/xen_xl.h > > diff --git a/configure.ac b/configure.ac > index f93c6c2..a60d0ad 100644 > --- a/configure.ac > +++ b/configure.ac > @@ -2176,7 +2176,10 @@ AC_PATH_PROG([PERL], [perl]) > if test -z "$PERL"; then > AC_MSG_ERROR([Failed to find perl.]) > fi > - > +AC_PATH_PROG([FLEX], [flex]) > +if test -z "$FLEX"; then > + AC_MSG_ERROR([failed to find flex.]) > +fi > According to the automake manual [1], AM_PROG_FLEX is recommended in configure.ac "If a |lex| source file is seen, then your configure.ac must define the variable |LEX|. You can use |AC_PROG_LEX| to do this (see Particular Program Checks in The Autoconf Manual), but using |AM_PROG_LEX| macro (see Macros) is recommended." > AC_ARG_WITH([test-suite], > [AS_HELP_STRING([--with-test-suite], > [build test suite by default @<:@default=check@:>@])], > diff --git a/src/Makefile.am b/src/Makefile.am > index 46e411e..38560ce 100644 > --- a/src/Makefile.am > +++ b/src/Makefile.am > @@ -35,7 +35,6 @@ INCLUDES = -I../gnulib/lib \ > $(GETTEXT_CPPFLAGS) > > AM_CFLAGS = $(LIBXML_CFLAGS) \ > - $(WARN_CFLAGS) \ > Hmm, that won't fly. I assume you made this change to squelch warnings when compiling the generated file? > $(LOCK_CHECKING_CFLAGS) \ > $(WIN32_EXTRA_CFLAGS) \ > $(COVERAGE_CFLAGS) > @@ -964,11 +963,25 @@ CPU_SOURCES = \ > VMX_SOURCES = \ > vmx/vmx.c vmx/vmx.h > > +XENCONFIG_GENERATED = \ > + xenconfig/libxlu_disk_l.c \ > + xenconfig/libxlu_disk_l.h > + > +$(XENCONFIG_GENERATED): $(srcdir)/xenconfig/libxlu_disk_l.l \ > + $(srcdir)/xenconfig/libxlu_disk_i.h Makefile.am > + $(AM_V_GEN)$(FLEX) --outfile=$(srcdir)/xenconfig/libxlu_disk_l.c \ > + --header-file=$(srcdir)/xenconfig/libxlu_disk_l.h \ > + $(srcdir)/xenconfig/libxlu_disk_l.l > + > +CLEANFILES += $(XENCONFIG_GENERATED) > I suppose this is one way to generate the files with flex, but according to the manual it should be something like BUILT_SOURCES += xenconfig/libxlu_disk_l.h xenconfig/libxlu_disk_l.c XENCONFIG_SOURCES = \ xenconfig/xenxs_private.h \ xenconfig/xen_common.c xenconfig/xen_common.h \ xenconfig/xen_sxpr.c xenconfig/xen_sxpr.h \ xenconfig/xen_xm.c xenconfig/xen_xm.h \ xenconfig/xen_xl.c xenconfig/xen_xl.h \ xenconfig/libxlu_disk_l.l However, I can't nudge flex to generate the header file with this approach. I tried adding 'AM_LFLAGS = --header-file' after BUILT_SOURCES, but still no header is generated. I haven't had much luck searching for an example doing this in the automake framework. Eric has a lot of expertise in this area and might have suggestions. Regards, Jim [1] http://www.gnu.org/software/automake/manual/html_node/Yacc-and-Lex.html > + > XENCONFIG_SOURCES = \ > xenconfig/xenxs_private.h \ > - xenconfig/xen_common.c xenconfig/xen_common.h \ > - xenconfig/xen_sxpr.c xenconfig/xen_sxpr.h \ > - xenconfig/xen_xm.c xenconfig/xen_xm.h > + xenconfig/xen_common.c xenconfig/xen_common.h \ > + xenconfig/xen_sxpr.c xenconfig/xen_sxpr.h \ > + xenconfig/xen_xm.c xenconfig/xen_xm.h \ > + xenconfig/xen_xl.c xenconfig/xen_xl.h \ > + $(XENCONFIG_GENERATED) > > pkgdata_DATA = cpu/cpu_map.xml > > diff --git a/src/libvirt_xenconfig.syms b/src/libvirt_xenconfig.syms > index 6541685..3e2e5d6 100644 > --- a/src/libvirt_xenconfig.syms > +++ b/src/libvirt_xenconfig.syms > @@ -16,6 +16,10 @@ xenParseSxprChar; > xenParseSxprSound; > xenParseSxprString; > > +#xenconfig/xen_xl.h > +xenFormatXL; > +xenParseXL; > + > # xenconfig/xen_xm.h > xenFormatXM; > xenParseXM; > diff --git a/src/xenconfig/libxlu_disk_i.h b/src/xenconfig/libxlu_disk_i.h > new file mode 100644 > index 0000000..911ea42 > --- /dev/null > +++ b/src/xenconfig/libxlu_disk_i.h > @@ -0,0 +1,28 @@ > +#ifndef LIBXLU_DISK_I_H > +#define LIBXLU_DISK_I_H > + > +#include "../util/virconf.h" > + > +typedef struct { > + virConfPtr conf; > + int err; > + void *scanner; > + YY_BUFFER_STATE buf; > + virDomainDiskDefPtr disk; > + int access_set, had_depr_prefix; > + const char *spec; > +} DiskParseContext; > + > +void xlu__disk_err(DiskParseContext *dpc, const char *erroneous, > + const char *message); > + > + > +#endif /*LIBXLU_DISK_I_H*/ > + > +/* > + * Local variables: > + * mode: C > + * c-basic-offset: 4 > + * indent-tabs-mode: nil > + * End: > + */ > diff --git a/src/xenconfig/libxlu_disk_l.l b/src/xenconfig/libxlu_disk_l.l > new file mode 100644 > index 0000000..7b6893b > --- /dev/null > +++ b/src/xenconfig/libxlu_disk_l.l > @@ -0,0 +1,292 @@ > +/* -*- fundamental -*- */ > +/* > + * libxlu_disk_l.l - parser for disk specification strings > + * > + * Copyright (C) 2011 Citrix Ltd. > + * Author Ian Jackson <ian.jackson@xxxxxxxxxxxxx> > + * > + * This program is free software; you can redistribute it and/or modify > + * it under the terms of the GNU Lesser General Public License as published > + * by the Free Software Foundation; version 2.1 only. with the special > + * exception on linking described in file LICENSE. > + * > + * This program is distributed in the hope that it will be useful, > + * but WITHOUT ANY WARRANTY; without even the implied warranty of > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > + * GNU Lesser General Public License for more details. > + */ > + > +/* > + * Parsing the old xm/xend/xl-4.1 disk specs is a tricky problem, > + * because the target string might in theory contain "," which is the > + * delimiter we use for stripping off things on the RHS, and ":", > + * which is the delimiter we use for stripping off things on the LHS. > + * > + * In this parser we do not support such target strings in the old > + * syntax; if the target string has to contain "," or ":" the new > + * syntax's "target=" should be used. > + */ > +%{ > +# include <config.h> > +# include <stdio.h> > +# include <stdarg.h> > +# include "virstring.h" > +# include "virstoragefile.h" > +# include "viralloc.h" > +# include "virconf.h" > +# include "domain_conf.h" > +# include "viralloc.h" > +# include "virstring.h" > +# include "xen_xl.h" > +# include "libxlu_disk_i.h" > +# include "libxlu_disk_i.h" > + > +#define YY_NO_INPUT > +#define VIR_FROM_THIS VIR_FROM_NONE > + > +/* Some versions of flex have a bug (Fedora bugzilla 612465) which causes > + * it to fail to declare these functions, which it defines. So declare > + * them ourselves. Hopefully we won't have to simultaneously support > + * a flex version which declares these differently somehow. */ > +int xlu__disk_yyget_column(yyscan_t yyscanner); > +void xlu__disk_yyset_column(int column_no, yyscan_t yyscanner); > + > + > +/*----- useful macros and functions used in actions ----- > + * we use macros in the actual rules to keep the actions short > + * and particularly to avoid repeating boilerplate values such as > + * DPC->disk, yytext, etc. */ > + > +/* For actions whose patterns contain '=', finds the start of the value */ > +#define FROMEQUALS (strchr(yytext,'=')+1) > + > +/* Chops the delimiter off, modifying yytext and yyleng. */ > +#define STRIP(delim) do{ \ > + if (yyleng>0 && yytext[yyleng-1]==(delim)) \ > + yytext[--yyleng] = 0; \ > + }while(0) > + > +/* Sets a string value, checking it hasn't been set already. */ > +#define SAVESTRING(what,loc,val) do{ \ > + savestring(DPC, what " respecified", &DPC->disk->loc, (val)); \ > + }while(0) > + > +int > +asprintf(char **ret, const char *format, ...) > +{ > + va_list ap; > + > + *ret = NULL; /* Ensure value can be passed to free() */ > + > + va_start(ap, format); > + int count = vsnprintf(NULL, 0, format, ap); > + va_end(ap); > + > + if (count >= 0) > + { > + char* buffer = malloc(count + 1); > + if (buffer == NULL) > + return -1; > + > + va_start(ap, format); > + count = vsnprintf(buffer, count + 1, format, ap); > + va_end(ap); > + > + if (count < 0) > + { > + free(buffer); > + return count; > + } > + *ret = buffer; > + } > + > + return count; > +} > + > + > +static void > +savestring(DiskParseContext *dpc, > + const char *what_respecified, > + char **update, > + const char *value) > +{ > + if (*update) { > + if (**update) { > + xlu__disk_err(dpc, value, what_respecified); > + return; > + } > + > + free(*update); /* do not complain about overwriting empty strings */ > + } > + > + *update = strdup(value); > +} > + > +#define DPC dpc /* our convention in lexer helper functions */ > + > +/* Sets ->readwrite from the string. This ought to be an enum, perhaps. */ > +static void > +setaccess(DiskParseContext *dpc, const char *str) > +{ > + if (STREQ(str, "r") || STREQ(str, "ro")) { > + dpc->disk->src->readonly = 1; > + } else if (STREQ(str, "w!") || STREQ(str, "!")) { > + dpc->disk->src->shared = 1; > + } else { > + xlu__disk_err(dpc,str,"unknown value for access"); > + } > +} > + > +/* Sets ->format from the string. IDL should provide something for this. */ > +static void > +setformat(DiskParseContext *dpc, const char *str) > +{ > + if (STREQ(str, "")) > + virDomainDiskSetFormat(dpc->disk, VIR_STORAGE_FILE_RAW); > + else if (STREQ(str, "raw")) > + virDomainDiskSetFormat(dpc->disk, VIR_STORAGE_FILE_RAW); > + else if (STREQ(str, "qcow")) > + virDomainDiskSetFormat(dpc->disk, VIR_STORAGE_FILE_QCOW); > + else if (STREQ(str, "qcow2")) > + virDomainDiskSetFormat(dpc->disk, VIR_STORAGE_FILE_QCOW2); > + else if (STREQ(str, "vhd")) > + virDomainDiskSetFormat(dpc->disk, VIR_STORAGE_FILE_VHD); > + else xlu__disk_err(dpc, str, "unknown value for format"); > +} > + > + > +/* Sets ->backend from the string. IDL should provide something for this. */ > +static void > +setdrivertype(DiskParseContext *dpc, const char *str) > +{ > + if (STREQ(str, "phy")) > + ignore_value(virDomainDiskSetDriver(dpc->disk, "phy")); > + else if (STREQ(str, "tap")) > + ignore_value(virDomainDiskSetDriver(dpc->disk, "tap")); > + else if (STREQ(str, "qdisk")) > + ignore_value(virDomainDiskSetDriver(dpc->disk, "qemu")); > + else if (STREQ(str, "")) > + ignore_value(virDomainDiskSetDriver(dpc->disk, "phy")); > + else > + xlu__disk_err(dpc, str, "unknown value for backendtype"); > +} > + > + > +/* Handles a vdev positional parameter which includes a devtype. */ > +static int > +vdev_and_devtype(DiskParseContext *dpc, char *str) > +{ > + /* returns 1 if it was <vdev>:<devtype>, 0 (doing nothing) otherwise */ > + char *colon = strrchr(str, ':'); > + if (!colon) > + return 0; > + > + *colon++ = 0; > + SAVESTRING("vdev", dst, str); > + > + if (STREQ(colon,"cdrom")) { > + DPC->disk->device = VIR_DOMAIN_DISK_DEVICE_CDROM; > + } else if (STREQ(colon, "disk")) { > + DPC->disk->device = VIR_DOMAIN_DISK_DEVICE_DISK; > + } else { > + xlu__disk_err(DPC, colon, "unknown deprecated type"); > + } > + return 1; > +} > + > +#undef DPC /* needs to be defined differently the actual lexer */ > +#define DPC ((DiskParseContext*)yyextra) > + > +%} > + > +%option warn > +%option nodefault > +%option batch > +%option 8bit > +%option noyywrap > +%option reentrant > +%option prefix="xlu__disk_yy" > +%option nounput > + > +%x LEXERR > + > +%% > + > + /*----- the scanner rules which do the parsing -----*/ > + > +[ \t\n]+/([^ \t\n].*)? { /* ignore whitespace before parameters */ } > + > + /* ordinary parameters setting enums or strings */ > + > +format=[^,]*,? { STRIP(','); setformat(DPC, FROMEQUALS); } > + > +cdrom,? { DPC->disk->device = VIR_DOMAIN_DISK_DEVICE_CDROM; } > +devtype=cdrom,? { DPC->disk->device = VIR_DOMAIN_DISK_DEVICE_CDROM; } > +devtype=disk,? { DPC->disk->device = VIR_DOMAIN_DISK_DEVICE_DISK; } > +devtype=[^,]*,? { xlu__disk_err(DPC, yytext,"unknown value for type"); } > + > +access=[^,]*,? { STRIP(','); setaccess(DPC, FROMEQUALS); } > +backendtype=[^,]*,? { STRIP(','); setdrivertype(DPC, FROMEQUALS); } > + > +vdev=[^,]*,? { STRIP(','); SAVESTRING("vdev", dst, FROMEQUALS); } > + > + /* the target magic parameter, eats the rest of the string */ > + > +target=.* { STRIP(','); SAVESTRING("target", src->path, FROMEQUALS); } > + > + /* unknown parameters */ > + > +[a-z][-a-z0-9]*=[^,],? { xlu__disk_err(DPC, yytext, "unknown parameter"); } > + > + /* the "/.*" in these patterns ensures that they count as if they > + * matched the whole string, so these patterns take precedence */ > + > +(raw|qcow2?|vhd):/.* { > + STRIP(':'); > + DPC->had_depr_prefix=1; > + setformat(DPC, yytext); > + } > + > +tapdisk:/.* { DPC->had_depr_prefix=1; } > +tap2?:/.* { DPC->had_depr_prefix=1; } > +aio:/.* { DPC->had_depr_prefix=1; } > +ioemu:/.* { DPC->had_depr_prefix=1; } > +file:/.* { DPC->had_depr_prefix=1; } > +phy:/.* { DPC->had_depr_prefix=1; } > +[a-z][a-z0-9]*:/([^a-z0-9].*)? { > + xlu__disk_err(DPC, yytext, "unknown deprecated disk prefix"); > + return 0; > + } > + > + /* positional parameters */ > + > +[^=,]*,|[^=,]+,? { > + STRIP(','); > + > + if (DPC->err) { > + /* previous errors may just lead to subsequent ones */ > + } else if (!DPC->disk->src->path) { > + SAVESTRING("target", src->path, yytext); > + } else if (DPC->disk->src->format == VIR_STORAGE_FILE_LAST){ > + setformat(DPC, yytext); > + } > + else if (!DPC->disk->dst) { > + if (!vdev_and_devtype(DPC, yytext)) > + SAVESTRING("vdev", dst, yytext); > + } else if (!DPC->access_set) { > + DPC->access_set = 1; > + setaccess(DPC, yytext); > + } else { > + xlu__disk_err(DPC, yytext, "too many positional parameters"); > + return 0; /* don't print any more errors */ > + } > +} > + > +. { > + BEGIN(LEXERR); > + yymore(); > +} > +<LEXERR>.* { > + xlu__disk_err(DPC, yytext, "bad disk syntax"); > + return 0; > +} > diff --git a/src/xenconfig/xen_common.c b/src/xenconfig/xen_common.c > index d71dd07..3949b37 100644 > --- a/src/xenconfig/xen_common.c > +++ b/src/xenconfig/xen_common.c > @@ -1804,7 +1804,8 @@ xenFormatVfb(virConfPtr conf, virDomainDefPtr def, int xendConfigVersion) > { > int hvm = STREQ(def->os.type, "hvm") ? 1 : 0; > > - if (def->ngraphics == 1) { > + if (def->ngraphics == 1 && > + def->graphics[0]->type == VIR_DOMAIN_GRAPHICS_TYPE_SPICE) { > if (hvm || (xendConfigVersion < XEND_CONFIG_MIN_VERS_PVFB_NEWCONF)) { > if (def->graphics[0]->type == VIR_DOMAIN_GRAPHICS_TYPE_SDL) { > if (xenConfigSetInt(conf, "sdl", 1) < 0) > diff --git a/src/xenconfig/xen_xl.c b/src/xenconfig/xen_xl.c > new file mode 100644 > index 0000000..f491958 > --- /dev/null > +++ b/src/xenconfig/xen_xl.c > @@ -0,0 +1,476 @@ > +/* > + * xen_xl.c: Xen XL parsing functions > + * > + * This library is free software; you can redistribute it and/or > + * modify it under the terms of the GNU Lesser General Public > + * License as published by the Free Software Foundation; either > + * version 2.1 of the License, or (at your option) any later version. > + * > + * This library is distributed in the hope that it will be useful, > + * but WITHOUT ANY WARRANTY; without even the implied warranty of > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU > + * Lesser General Public License for more details. > + * > + * You should have received a copy of the GNU Lesser General Public > + * License along with this library. If not, see > + * <http://www.gnu.org/licenses/>. > + * > + * Author: Kiarie Kahurani <davidkiarie4@xxxxxxxxx> > + */ > +#include <config.h> > +#include <assert.h> > +#include "virconf.h" > +#include "virerror.h" > +#include "domain_conf.h" > +#include "viralloc.h" > +#include "virstring.h" > +#include "xen_xl.h" > +#include "libxlu_disk_l.h" > +#include "libxlu_disk_i.h" > + > +#define VIR_FROM_THIS VIR_FROM_NONE > + > +static int > +xenParseXLSpice(virConfPtr conf, virDomainDefPtr def) > +{ > + virDomainGraphicsDefPtr graphics = NULL; > + unsigned long port; > + char *listenAddr = NULL; > + int val; > + > + if (STREQ(def->os.type, "hvm")) { > + if (xenConfigGetBool(conf, "spice", &val, 0) < 0) > + return -1; > + > + if (val) { > + if (VIR_ALLOC(graphics) < 0) > + return -1; > + > + graphics->type = VIR_DOMAIN_GRAPHICS_TYPE_SPICE; > + if (xenConfigCopyStringOpt(conf, "spicehost", &listenAddr) < 0) > + goto cleanup; > + if (listenAddr && > + virDomainGraphicsListenSetAddress(graphics, 0, listenAddr, > + -1, true) < 0) { > + goto cleanup; > + } > + VIR_FREE(listenAddr); > + > + if (xenConfigGetULong(conf, "spicetls_port", &port, 0) < 0) > + goto cleanup; > + graphics->data.spice.tlsPort = (int)port; > + > + if (xenConfigGetULong(conf, "spiceport", &port, 0) < 0) > + goto cleanup; > + > + graphics->data.spice.port = (int)port; > + > + if (!graphics->data.spice.tlsPort && > + !graphics->data.spice.port) > + graphics->data.spice.autoport = 1; > + > + if (xenConfigGetBool(conf, "spicedisable_ticketing", &val, 0) < 0) > + goto cleanup; > + if (val) { > + if (xenConfigCopyStringOpt(conf, "spicepasswd", > + &graphics->data.spice.auth.passwd) < 0) > + goto cleanup; > + } > + > + if (xenConfigGetBool(conf, "spiceagent_mouse", > + &graphics->data.spice.mousemode, 0) < 0) > + goto cleanup; > + if (xenConfigGetBool(conf, "spicedvagent", &val, 0) < 0) > + goto cleanup; > + if (val) { > + if (xenConfigGetBool(conf, "spice_clipboard_sharing", > + &graphics->data.spice.copypaste, > + 0) < 0) > + goto cleanup; > + } > + > + if (VIR_ALLOC_N(def->graphics, 1) < 0) > + goto cleanup; > + def->graphics[0] = graphics; > + def->ngraphics = 1; > + } > + } > + > + return 0; > + > + cleanup: > + virDomainGraphicsDefFree(graphics); > + return -1; > +} > + > + > + > +void > +xlu__disk_err(DiskParseContext *dpc, > + const char *erroneous, > + const char *message) > +{ > + /*virReportError(VIR_ERR_INTERNAL_ERROR, > + "%s: config parsing error in disk specification: %s" > + "%s%s" > + " in `%s'\n", > + message, > + erroneous?": near `":"", erroneous?erroneous:"", erroneous?"'":"", > + dpc->spec); > + if (!dpc->err) > + dpc->err= EINVAL; > + */ > +} > + > + > +static int > +dpc_prep(DiskParseContext *dpc, const char *spec) > +{ > + int e; > + dpc->spec = spec; > + > + e = xlu__disk_yylex_init_extra(dpc, &dpc->scanner); > + if (e) > + goto fail; > + > + dpc->buf = xlu__disk_yy_scan_bytes(spec, strlen(spec), dpc->scanner); > + if (!dpc->buf) { > + e = ENOMEM; > + goto fail; > + } > + > + return 0; > + > + fail: > + virReportError(VIR_ERR_INTERNAL_ERROR, "cannot init disk scanner: %s\n", > + strerror(errno)); > + return e; > +} > + > + > +static void > +dpc_dispose(DiskParseContext *dpc) > +{ > + virDomainDiskDefFree(dpc->disk); > + > + if (dpc->buf) { > + xlu__disk_yy_delete_buffer(dpc->buf, dpc->scanner); > + dpc->buf = 0; > + } > + if (dpc->scanner) { > + xlu__disk_yylex_destroy(dpc->scanner); > + dpc->scanner = 0; > + } > +} > + > +/* > + * positional parameters > + * (If the <diskspec> strings are not separated by "=" > + * the string is split following ',' and assigned to > + * the following options in the following order) > + * target,format,vdev,access > + * ================================================================ > + * > + * The parameters below cannot be specified as positional parameters: > + * > + * other parameters > + * devtype = <devtype> > + * backendtype = <backend-type> > + * parameters not taken care of > + * backend = <domain-name> > + * script = <script> > + * direct-io-safe > + * > + * ================================================================ > + * The parser does not take any deprecated parameters > + * > + * For more information refer to /xen/docs/misc/xl-disk-configuration.txt > + */ > +static int > +xenParseXLDisk(virConfPtr conf, virDomainDefPtr def) > +{ > + int e; > + DiskParseContext dpc; > + > + virConfValuePtr list = virConfGetValue(conf, "disk"); > + dpc.conf = conf; > + dpc.scanner = 0; > + memset(&dpc, 0, sizeof(dpc)); > + > + if (list && list->type == VIR_CONF_LIST) { > + list = list->list; > + while (list) { > + char *specs = list->str; > + dpc.spec = specs; > + > + if ((list->type != VIR_CONF_STRING) || (list->str == NULL)) > + goto skipdisk; > + > + if (!(dpc.disk = virDomainDiskDefNew())) > + return -1; > + dpc.disk->src->readonly = 0; > + dpc.disk->src->format = VIR_STORAGE_FILE_LAST; > + > + e = dpc_prep(&dpc, specs); > + if (e) { > + dpc.err = e; > + } > + xlu__disk_yylex(dpc.scanner); > + > + if (dpc.err) { > + dpc_dispose(&dpc); > + } > + if (dpc.disk->src->format == VIR_STORAGE_FILE_LAST) { > + dpc.disk->src->format = VIR_STORAGE_FILE_RAW; > + } > + > + if (dpc.disk->device == VIR_DOMAIN_DISK_DEVICE_CDROM) { > + dpc.disk->removable = true; > + dpc.disk->src->readonly = true; > + if (!dpc.disk->src->path || STREQ(dpc.disk->src->path, "")) > + dpc.disk->src->format = VIR_STORAGE_FILE_NONE; > + } > + > + if (STRPREFIX(dpc.disk->dst, "xvd") || !STREQ(def->os.type, "hvm")) { > + dpc.disk->bus = VIR_DOMAIN_DISK_BUS_XEN; > + } else if (STRPREFIX(dpc.disk->dst, "sd")) { > + dpc.disk->bus = VIR_DOMAIN_DISK_BUS_SCSI; > + } else { > + dpc.disk->bus = VIR_DOMAIN_DISK_BUS_IDE; > + } > + > + virDomainDiskSetType(dpc.disk, STREQ(virDomainDiskGetDriver(dpc.disk), "phy") ? > + VIR_STORAGE_TYPE_BLOCK : > + VIR_STORAGE_TYPE_FILE); > + if (VIR_APPEND_ELEMENT(def->disks, def->ndisks, dpc.disk) < 0) > + return -1; > +skipdisk: > + list = list->next; > + virDomainDiskDefFree(dpc.disk); > + dpc.disk = NULL; > + } > + > + } > + return 0; > +} > + > + > +virDomainDefPtr > +xenParseXL(virConfPtr conf, virCapsPtr caps, > + int xendConfigVersion) > +{ > + virDomainDefPtr def = NULL; > + > + if (VIR_ALLOC(def) < 0) > + return NULL; > + > + def->virtType = VIR_DOMAIN_VIRT_XEN; > + def->id = -1; > + > + if (xenParseConfigCommon(conf, def, caps, xendConfigVersion) < 0) > + goto cleanup; > + > + if (xenParseXLDisk(conf, def) < 0) > + goto cleanup; > + > + if (xenParseXLSpice(conf, def) < 0) > + goto cleanup; > + > + return def; > + > + cleanup: > + virDomainDefFree(def); > + return NULL; > +} > + > + > +static int > +xenFormatXLDisk(virConfValuePtr list, virDomainDiskDefPtr disk) > +{ > + virBuffer buf = VIR_BUFFER_INITIALIZER; > + virConfValuePtr val, tmp; > + const char *src = virDomainDiskGetSource(disk); > + int format = virDomainDiskGetFormat(disk); > + > + /* target */ > + virBufferAsprintf(&buf, "%s,", src); > + /* format */ > + switch (format) { > + case VIR_STORAGE_FILE_RAW: > + virBufferAddLit(&buf, "raw,"); > + break; > + case VIR_STORAGE_FILE_VHD: > + virBufferAddLit(&buf, "xvhd,"); > + break; > + case VIR_STORAGE_FILE_QCOW: > + virBufferAddLit(&buf, "qcow,"); > + break; > + case VIR_STORAGE_FILE_QCOW2: > + virBufferAddLit(&buf, "qcow2,"); > + break; > + /* set default */ > + default: > + virBufferAddLit(&buf, "raw,"); > + } > + > + /* device */ > + virBufferAdd(&buf, disk->dst, -1); > + > + virBufferAddLit(&buf, ","); > + > + if (disk->src->readonly) > + virBufferAddLit(&buf, "r,"); > + else if (disk->src->shared) > + virBufferAddLit(&buf, "!,"); > + else > + virBufferAddLit(&buf, "w,"); > + if (disk->transient) { > + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", > + _("transient disks not supported yet")); > + goto cleanup; > + } > + > + if (disk->device == VIR_DOMAIN_DISK_DEVICE_CDROM) > + virBufferAddLit(&buf, "cdrom"); > + > + if (virBufferCheckError(&buf) < 0) > + goto cleanup; > + > + if (VIR_ALLOC(val) < 0) > + goto cleanup; > + > + val->type = VIR_CONF_STRING; > + val->str = virBufferContentAndReset(&buf); > + tmp = list->list; > + while (tmp && tmp->next) > + tmp = tmp->next; > + if (tmp) > + tmp->next = val; > + else > + list->list = val; > + return 0; > + > + cleanup: > + virBufferFreeAndReset(&buf); > + return -1; > +} > + > + > +static int > +xenFormatXLDomainDisks(virConfPtr conf, virDomainDefPtr def) > +{ > + virConfValuePtr diskVal = NULL; > + size_t i = 0; > + > + if (VIR_ALLOC(diskVal) < 0) > + return -1; > + > + diskVal->type = VIR_CONF_LIST; > + diskVal->list = NULL; > + > + for (i = 0; i < def->ndisks; i++) { > + if (def->disks[i]->device == VIR_DOMAIN_DISK_DEVICE_FLOPPY) > + continue; > + if (xenFormatXLDisk(diskVal, def->disks[i]) < 0) > + > + goto cleanup; > + } > + > + if (diskVal->list != NULL) { > + int ret = virConfSetValue(conf, "disk", diskVal); > + diskVal = NULL; > + if (ret < 0) > + goto cleanup; > + } > + > + return 0; > + > + cleanup: > + virConfFreeValue(diskVal); > + return 0; > +} > + > + > +static int > +xenFormatXLSpice(virConfPtr conf, virDomainDefPtr def) > +{ > + const char *listenAddr = NULL; > + > + if (STREQ(def->os.type, "hvm")) { /*save's CPU :-) */ > + if (def->graphics[0]->type == VIR_DOMAIN_GRAPHICS_TYPE_SPICE) { > + /* set others to false but may not be necessary */ > + if (xenConfigSetInt(conf, "sdl", 0) < 0) > + return -1; > + > + if (xenConfigSetInt(conf, "vnc", 0) < 0) > + return -1; > + > + if (xenConfigSetInt(conf, "spice", 1) < 0) > + return -1; > + > + if (xenConfigSetInt(conf, "spiceport", > + def->graphics[0]->data.spice.port) < 0) > + return -1; > + > + if (xenConfigSetInt(conf, "spicetls_port", > + def->graphics[0]->data.spice.tlsPort) < 0) > + return -1; > + > + if (def->graphics[0]->data.spice.auth.passwd) { > + if (xenConfigSetInt(conf, "spicedisable_ticketing", 1) < 0) > + return -1; > + > + if (def->graphics[0]->data.spice.auth.passwd && > + xenConfigSetString(conf, "spicepasswd", > + def->graphics[0]->data.spice.auth.passwd) < 0) > + return -1; > + } > + > + listenAddr = virDomainGraphicsListenGetAddress(def->graphics[0], 0); > + if (listenAddr && > + xenConfigSetString(conf, "spicehost", listenAddr) < 0) { > + return -1; > + } > + > + if (xenConfigSetInt(conf, "spice_mouse_agent", > + def->graphics[0]->data.spice.mousemode) < 0) > + return -1; > + if (def->graphics[0]->data.spice.copypaste) { > + if (xenConfigSetInt(conf, "spicedvagent", 1) < 0) > + return -1; > + if (xenConfigSetInt(conf, "spice_clipboard_sharing", > + def->graphics[0]->data.spice.copypaste) < 0) > + return -1; > + } > + } > + } > + > + return 0; > +} > + > + > +virConfPtr > +xenFormatXL(virDomainDefPtr def, virConnectPtr conn, > + int xendConfigVersion) > +{ > + virConfPtr conf = NULL; > + > + if (!(conf = virConfNew())) > + goto cleanup; > + > + if (xenFormatConfigCommon(conf, def, conn, xendConfigVersion) < 0) > + goto cleanup; > + > + if (xenFormatXLDomainDisks(conf, def) < 0) > + goto cleanup; > + > + if (xenFormatXLSpice(conf, def) < 0) > + goto cleanup; > + > + return conf; > + > + cleanup: > + if (conf) > + virConfFree(conf); > + return NULL; > +} > diff --git a/src/xenconfig/xen_xl.h b/src/xenconfig/xen_xl.h > new file mode 100644 > index 0000000..d60fe5e > --- /dev/null > +++ b/src/xenconfig/xen_xl.h > @@ -0,0 +1,29 @@ > +/* > + * xen_xl.h: Xen XL parsing functions > + * > + * This library is free software; you can redistribute it and/or > + * modify it under the terms of the GNU Lesser General Public > + * License as published by the Free Software Foundation; either > + * version 2.1 of the License, or (at your option) any later version. > + * > + * This library is distributed in the hope that it will be useful, > + * but WITHOUT ANY WARRANTY; without even the implied warranty of > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU > + * Lesser General Public License for more details. > + * > + * You should have received a copy of the GNU Lesser General Public > + * License along with this library. If not, see > + * <http://www.gnu.org/licenses/>. > + * > + * Author: Kiarie Kahurani<davidkiarie4@xxxxxxxxx> > + */ > +#ifndef _XEN_XL_H_ > +# define _XEN_XL_H_ > + > +# include "xen_common.h" > + > +virDomainDefPtr xenParseXL(virConfPtr conn, virCapsPtr caps, > + int xendConfigVersion); > +virConfPtr xenFormatXL(virDomainDefPtr def, > + virConnectPtr, int xendConfigVersion); > +#endif /* _XEN_XL_H_ */ > -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list