From nobody Wed May 14 10:47:52 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) client-ip=209.132.183.28; envelope-from=libvir-list-bounces@redhat.com; helo=mx1.redhat.com; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=fail(p=none dis=none) header.from=gmail.com Return-Path: Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by mx.zohomail.com with SMTPS id 1526901116706340.010687759211; Mon, 21 May 2018 04:11:56 -0700 (PDT) Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.phx2.redhat.com [10.5.11.22]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id CD44530D7E6C; Mon, 21 May 2018 11:11:54 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.20]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 72057104C44D; Mon, 21 May 2018 11:11:54 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by colo-mx.corp.redhat.com (Postfix) with ESMTP id 0233C180B536; Mon, 21 May 2018 11:11:53 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id w4LBBTvU015666 for ; Mon, 21 May 2018 07:11:29 -0400 Received: by smtp.corp.redhat.com (Postfix) id D1C465D759; Mon, 21 May 2018 11:11:29 +0000 (UTC) Received: from mx1.redhat.com (ext-mx20.extmail.prod.ext.phx2.redhat.com [10.5.110.49]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 8E7815D750; Mon, 21 May 2018 11:11:26 +0000 (UTC) Received: from mail-pg0-f46.google.com (mail-pg0-f46.google.com [74.125.83.46]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id E793B314FC14; Mon, 21 May 2018 11:11:13 +0000 (UTC) Received: by mail-pg0-f46.google.com with SMTP id 11-v6so4594588pge.2; Mon, 21 May 2018 04:11:13 -0700 (PDT) Received: from ps-f25-dev.eng.nutanix.com ([205.209.132.2]) by smtp.gmail.com with ESMTPSA id t68-v6sm25104896pfe.17.2018.05.21.04.11.11 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 21 May 2018 04:11:11 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=U2CT9eAOl5xn2wN/FBD8h+z9KWuHk/YvJWo1WKd7nNo=; b=NzvgWGW64YSnbzqSp4SKGP4f8s6I/pzHZOpw5cMD6S4mo3bPVmIxGT1YZRRcZfYutD UNvgkeDTH5hsWjk788xl2YWbFriRHQPW7uKjmDGi/kVZ7LMnI9/RRZTJsrx96UsMSNLY o6qtXhjCVf6jDJu75P2bZ3hdN53YX3HXeekHkxBw9edOei94OJ8J6wyvYEafQ4ZqRbzO x6O2TX8ja5rbJpv12Sn7UjmmGQPhkwqdR3qYg8Adw073ApZ3TM5FeysBFbZLYADi/CWl V5VlgLuY31f3IycbbdFUaVcTKOmfqJXTCINLta5GMDHgEc64zvprvwvzwy8SDAz4bjcb r3Rg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=U2CT9eAOl5xn2wN/FBD8h+z9KWuHk/YvJWo1WKd7nNo=; b=WLsyN5BYol15vrXvn3oR2qKy0XrRvX2wZWsKNie+pUSi35OgT8VTxT6IEYIpkfs7EY Lz1TwZwD8ABvxsHuWwiL5AeghFYMK7mIaLLR51SkScjxA8IHvhXyTtCvoQh7nONoaoiH mENGglf+1v0/Ml3vtHtCeQrmYsgEIBPeFJeoxoz128XrvqB2gAd8B7j9Yf2Uk2s0x4t7 shsiYsNhsIh8D4DRp+YOdbd5lCcSHKDDmrWjnQU8TN/i8uDPbjrFdYihYo5fOw5aUv4v MLFXnE5j2yf9jyLTOI84jAUmlakQbpWr7/K0/s88pYYnKuzr6a+v9xPFIpmFO/qWIc3W 3k7w== X-Gm-Message-State: ALKqPwftZtCH7/Gfn2HBBw0pB+J7PqoM9boVgFYGsLlTA7/7qyH1Xjih w3eGjeKaBIdUWy3xGDlPkkra8g== X-Google-Smtp-Source: AB8JxZqBGlPJGXWpLw9HXNoi3oF7KT2bb2wosb1cHD/smx8htO0mlYoDXfy7EYvUz7Sg1evlL2X48A== X-Received: by 2002:a65:4188:: with SMTP id a8-v6mr15440858pgq.118.1526901072306; Mon, 21 May 2018 04:11:12 -0700 (PDT) From: Prerna Saxena To: libvir-list@redhat.com Date: Mon, 21 May 2018 04:10:48 -0700 Message-Id: <20180521111050.10084-3-saxenap.ltc@gmail.com> In-Reply-To: <20180521111050.10084-1-saxenap.ltc@gmail.com> References: <20180521111050.10084-1-saxenap.ltc@gmail.com> X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.49]); Mon, 21 May 2018 11:11:14 +0000 (UTC) X-Greylist: inspected by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.49]); Mon, 21 May 2018 11:11:14 +0000 (UTC) for IP:'74.125.83.46' DOMAIN:'mail-pg0-f46.google.com' HELO:'mail-pg0-f46.google.com' FROM:'saxenap.ltc@gmail.com' RCPT:'' X-RedHat-Spam-Score: 1.281 * (DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED, FREEMAIL_FROM, NML_ADSP_CUSTOM_MED, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL, SPF_PASS, T_DKIM_INVALID) 74.125.83.46 mail-pg0-f46.google.com 74.125.83.46 mail-pg0-f46.google.com X-Scanned-By: MIMEDefang 2.84 on 10.5.110.49 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 X-loop: libvir-list@redhat.com Cc: pkrempa@redhat.com, mprivozn@redhat.com Subject: [libvirt] [ v3 2/4] 1) Loader: Add a more elaborate definition. X-BeenThere: libvir-list@redhat.com X-Mailman-Version: 2.1.12 Precedence: junk List-Id: Development discussions about the libvirt library & tools List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Sender: libvir-list-bounces@redhat.com Errors-To: libvir-list-bounces@redhat.com X-Scanned-By: MIMEDefang 2.84 on 10.5.11.22 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.46]); Mon, 21 May 2018 11:11:55 +0000 (UTC) X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZohoMail: RDKM_2 RSF_0 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" Augment definition to include virStorageSourcePtr that more comprehensively describes the nature of backing element. Also include flags for annotating if input XML definition is old-style or new-style. 2) Parse domain XML to generate virDomainLoaderDef & virDomainNvramDef. This patch is used to interpret domain XML and store the Loader & Nvram's backing definitions as virStorageSource. It also identifies if input XML used old or new-style declaration. (This will later be used by the formatter). 3) Format the loader source appropriately. If the initial XML used the old-style declaration as follows: /path/to/file we format it as was read. However, if it used new-style declaration: The formatter identifies that this is a new-style format and renders it likewise. 4) Plumb the loader source into generation of QEMU command line. Given that nvram & loader elements can now be backed by a non-local source too, adjust all steps leading to generation of QEMU command line. 5) Fix the domain def inference logic to correctly account for network-back= ed pflash devices. 6) Bhyve: Fix command line generation to correctly pick up local loader pat= h. 7) virt-aa-helper: Adjust references to loader & nvram elements to correctly parse the virStorageSource types. 8) Vbox: Adjust references to 'loader' and 'nvram' elements given that these are now represented by virStorageSourcePtr. 9)Xen: Adjust all references to loader & nvram elements given that they are= now backed by virStorageSourcePtr --- src/bhyve/bhyve_command.c | 6 +- src/conf/domain_conf.c | 250 ++++++++++++++++++++++++++++++++++++= +--- src/conf/domain_conf.h | 11 +- src/qemu/qemu_cgroup.c | 13 ++- src/qemu/qemu_command.c | 21 +++- src/qemu/qemu_domain.c | 31 +++-- src/qemu/qemu_driver.c | 7 +- src/qemu/qemu_parse_command.c | 30 ++++- src/qemu/qemu_process.c | 54 ++++++--- src/security/security_dac.c | 6 +- src/security/security_selinux.c | 6 +- src/security/virt-aa-helper.c | 14 ++- src/vbox/vbox_common.c | 11 +- src/xenapi/xenapi_driver.c | 4 +- src/xenconfig/xen_sxpr.c | 19 +-- src/xenconfig/xen_xm.c | 9 +- 16 files changed, 409 insertions(+), 83 deletions(-) diff --git a/src/bhyve/bhyve_command.c b/src/bhyve/bhyve_command.c index e3f7ded..9e53f40 100644 --- a/src/bhyve/bhyve_command.c +++ b/src/bhyve/bhyve_command.c @@ -521,10 +521,12 @@ virBhyveProcessBuildBhyveCmd(virConnectPtr conn, virCommandAddArgList(cmd, "-s", "0:0,hostbridge", NULL); =20 if (def->os.bootloader =3D=3D NULL && - def->os.loader) { + def->os.loader && + def->os.loader->src && + def->os.loader->src->type =3D=3D VIR_STORAGE_TYPE_FILE) { if ((bhyveDriverGetCaps(conn) & BHYVE_CAP_LPC_BOOTROM)) { virCommandAddArg(cmd, "-l"); - virCommandAddArgFormat(cmd, "bootrom,%s", def->os.loader->path= ); + virCommandAddArgFormat(cmd, "bootrom,%s", def->os.loader->src-= >path); add_lpc =3D true; } else { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 3689ac0..df2ed3a 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -2884,8 +2884,8 @@ virDomainLoaderDefFree(virDomainLoaderDefPtr loader) if (!loader) return; =20 - VIR_FREE(loader->path); - VIR_FREE(loader->nvram); + virStorageSourceFree(loader->src); + virStorageSourceFree(loader->nvram); VIR_FREE(loader->templt); VIR_FREE(loader); } @@ -18087,30 +18087,81 @@ virDomainDefMaybeAddHostdevSCSIcontroller(virDoma= inDefPtr def) =20 static int virDomainLoaderDefParseXML(xmlNodePtr node, + xmlXPathContextPtr ctxt, virDomainLoaderDefPtr loader) { int ret =3D -1; char *readonly_str =3D NULL; char *secure_str =3D NULL; char *type_str =3D NULL; + char *tmp =3D NULL; + char *lpath =3D NULL; + xmlNodePtr cur; + xmlXPathContextPtr cur_ctxt =3D ctxt; + + if (VIR_ALLOC(loader->src) < 0) + goto error; + + loader->src->type =3D VIR_STORAGE_TYPE_LAST; + loader->oldStyleLoader =3D false; =20 readonly_str =3D virXMLPropString(node, "readonly"); secure_str =3D virXMLPropString(node, "secure"); type_str =3D virXMLPropString(node, "type"); - loader->path =3D (char *) xmlNodeGetContent(node); + + if ((tmp =3D virXMLPropString(node, "backing")) && + (loader->src->type =3D virStorageTypeFromString(tmp)) <=3D 0) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("unknown loader type '%s'"), tmp); + VIR_FREE(tmp); + goto error; + } + VIR_FREE(tmp); + + for (cur =3D node->children; cur !=3D NULL; cur =3D cur->next) { + if (cur->type !=3D XML_ELEMENT_NODE) + continue; + + if (virXMLNodeNameEqual(cur, "source")) { + /* new-style declaration found */ + if (virDomainStorageSourceParse(cur, cur_ctxt, loader->src, 0)= < 0) { + virReportError(VIR_ERR_XML_DETAIL, "%s", + _("Error parsing Loader source element")); + goto error; + } + break; + } + } + + /* Old-style absolute path found ? */ + if (loader->src->type =3D=3D VIR_STORAGE_TYPE_LAST) { + lpath =3D (char *) xmlNodeGetContent(node); + if (virStringIsEmpty(lpath)) { + virReportError(VIR_ERR_XML_ERROR, "%s", + _("missing loader source")); + VIR_FREE(lpath); + goto error; + } + + loader->src->type =3D VIR_STORAGE_TYPE_FILE; + if (VIR_STRDUP(loader->src->path, lpath) < 0) + goto error; + VIR_FREE(lpath); + loader->oldStyleLoader =3D true; + } =20 if (readonly_str && (loader->readonly =3D virTristateBoolTypeFromString(readonly_str))= <=3D 0) { virReportError(VIR_ERR_XML_DETAIL, _("unknown readonly value: %s"), readonly_str); - goto cleanup; + goto error; } =20 if (secure_str && (loader->secure =3D virTristateBoolTypeFromString(secure_str)) <= =3D 0) { virReportError(VIR_ERR_XML_DETAIL, _("unknown secure value: %s"), secure_str); - goto cleanup; + goto error; } =20 if (type_str) { @@ -18118,19 +18169,97 @@ virDomainLoaderDefParseXML(xmlNodePtr node, if ((type =3D virDomainLoaderTypeFromString(type_str)) < 0) { virReportError(VIR_ERR_XML_DETAIL, _("unknown type value: %s"), type_str); - goto cleanup; + goto error; } loader->type =3D type; } =20 ret =3D 0; - cleanup: + + exit: VIR_FREE(readonly_str); VIR_FREE(secure_str); VIR_FREE(type_str); + return ret; + error: + virStorageSourceFree(loader->src); + VIR_FREE(lpath); + loader->src =3D NULL; + goto exit; } =20 +static int +virDomainLoaderNvramDefParseXML(xmlNodePtr node, + xmlXPathContextPtr ctxt, + virDomainLoaderDefPtr loader) +{ + int ret =3D -1; + char *tmp =3D NULL; + char *npath =3D NULL; + xmlNodePtr cur; + + if (VIR_ALLOC(loader->nvram) < 0) + goto error; + + loader->nvram->type =3D VIR_STORAGE_TYPE_LAST; + loader->oldStyleNvram =3D false; + + if ((tmp =3D virXMLPropString(node, "backing")) && + (loader->nvram->type =3D virStorageTypeFromString(tmp)) <=3D 0) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("unknown nvram type '%s'"), tmp); + VIR_FREE(tmp); + goto error; + } + VIR_FREE(tmp); + + loader->templt =3D virXMLPropString(node, "template"); + + for (cur =3D node->children; cur !=3D NULL; cur =3D cur->next) { + if (cur->type !=3D XML_ELEMENT_NODE) + continue; + + if (virXMLNodeNameEqual(cur, "source")) { + if (virDomainStorageSourceParse(cur, ctxt, loader->nvram, 0) <= 0) { + virReportError(VIR_ERR_XML_DETAIL, "%s", + _("Error parsing nvram source element")); + goto error; + } + ret =3D 0; + break; + } + } + + /* Old-style declaration found */ + if (loader->nvram->type =3D=3D VIR_STORAGE_TYPE_LAST) { + npath =3D (char *) xmlNodeGetContent(node); + + /* Suppress failures from lack of NVRAM, + * it will eventually be generated from template*/ + if (virStringIsEmpty(npath)) { + virStorageSourceFree(loader->nvram); + loader->nvram =3D NULL; + VIR_FREE(npath); + return 0; + } + + if (VIR_STRDUP(loader->nvram->path, npath) < 0) + goto error; + VIR_FREE(npath); + loader->nvram->type =3D VIR_STORAGE_TYPE_FILE; + loader->oldStyleNvram =3D true; + ret =3D 0; + } + return ret; + + error: + virStorageSourceFree(loader->nvram); + loader->nvram =3D NULL; + VIR_FREE(npath); + VIR_FREE(loader->templt); + return ret; +} =20 static virBitmapPtr virDomainSchedulerParse(xmlNodePtr node, @@ -18523,11 +18652,13 @@ virDomainDefParseBootOptions(virDomainDefPtr def, if (VIR_ALLOC(def->os.loader) < 0) goto error; =20 - if (virDomainLoaderDefParseXML(loader_node, def->os.loader) < = 0) + if (virDomainLoaderDefParseXML(loader_node, ctxt, def->os.load= er) < 0) goto error; =20 - def->os.loader->nvram =3D virXPathString("string(./os/nvram[1]= )", ctxt); - def->os.loader->templt =3D virXPathString("string(./os/nvram[1= ]/@template)", ctxt); + if ((loader_node =3D virXPathNode("./os/nvram[1]", ctxt)) && + (virDomainLoaderNvramDefParseXML(loader_node, ctxt, + def->os.loader) < 0)) + goto error; } } =20 @@ -26217,11 +26348,19 @@ virDomainHugepagesFormat(virBufferPtr buf, =20 static void virDomainLoaderDefFormat(virBufferPtr buf, - virDomainLoaderDefPtr loader) + virDomainLoaderDefPtr loader, + unsigned int flags) { const char *readonly =3D virTristateBoolTypeToString(loader->readonly); const char *secure =3D virTristateBoolTypeToString(loader->secure); const char *type =3D virDomainLoaderTypeToString(loader->type); + const char *backing =3D NULL; + + virBuffer attrBuf =3D VIR_BUFFER_INITIALIZER; + virBuffer childBuf =3D VIR_BUFFER_INITIALIZER; + + virBufferSetChildIndent(&childBuf, buf); + =20 virBufferAddLit(buf, "secure) virBufferAsprintf(buf, " secure=3D'%s'", secure); =20 - virBufferAsprintf(buf, " type=3D'%s'>", type); + virBufferAsprintf(buf, " type=3D'%s'", type); + if (loader->src && + loader->src->type < VIR_STORAGE_TYPE_LAST) { + if (!loader->oldStyleLoader) { + /* Format this in the new style, using the + * sub-element */ + + if (virDomainStorageSourceFormat(&attrBuf, &childBuf, loader->= src, + flags, 0) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("Cannot format loader source")); + goto error; + } + + backing =3D virStorageTypeToString(loader->src->type); + virBufferAsprintf(buf, " backing=3D'%s'>", backing); + virBufferAdjustIndent(buf, 2); + + if (virXMLFormatElement(buf, "source", &attrBuf, &childBuf) < = 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("Cannot format loader source")); + goto error; + } + + virBufferAdjustIndent(buf, -2); + + } else { + /* Format this in the old-style, using absolute paths directly= . */ + virBufferAsprintf(buf, ">%s", loader->src->path); + } + } else { + virBufferAddLit(buf, ">\n"); + } + + virBufferAddLit(buf, "\n"); =20 - virBufferEscapeString(buf, "%s\n", loader->path); if (loader->nvram || loader->templt) { + ignore_value(virBufferContentAndReset(&attrBuf)); + ignore_value(virBufferContentAndReset(&childBuf)); + virBufferSetChildIndent(&childBuf, buf); + virBufferAddLit(buf, "templt); - if (loader->nvram) - virBufferEscapeString(buf, ">%s\n", loader->nvram); - else - virBufferAddLit(buf, "/>\n"); + + if (loader->templt) + virBufferEscapeString(buf, " template=3D'%s'", loader->templt); + + if (loader->nvram) { + backing =3D virStorageTypeToString(loader->nvram->type); + if (!loader->oldStyleNvram) { + + if (virDomainStorageSourceFormat(&attrBuf, &childBuf, + loader->nvram, flags, 0) < 0)= { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("Cannot format NVRAM source")); + virBufferAddLit(buf, ">"); + goto error; + } + + virBufferEscapeString(buf, " backing=3D'%s'>\n", backing); + virBufferAdjustIndent(buf, 2); + + if (virXMLFormatElement(buf, "source", &attrBuf, &childBuf= ) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("Cannot format NVRAM source")); + virBufferAddLit(buf, ""); + goto error; + } + + virBufferAdjustIndent(buf, -2); + + } else { + /* old-style NVRAM declaration found */ + virBufferAsprintf(buf, ">%s", loader->nvram->path); + } + } else { + virBufferAddLit(buf, ">\n"); + } + + virBufferAddLit(buf, "\n"); } + error: + virBufferFreeAndReset(&attrBuf); + virBufferFreeAndReset(&childBuf); + return; } =20 static void @@ -26918,7 +27130,7 @@ virDomainDefFormatInternal(virDomainDefPtr def, virBufferAsprintf(buf, "%s\n", def->os.init= group); =20 if (def->os.loader) - virDomainLoaderDefFormat(buf, def->os.loader); + virDomainLoaderDefFormat(buf, def->os.loader, flags); virBufferEscapeString(buf, "%s\n", def->os.kernel); virBufferEscapeString(buf, "%s\n", diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index a78fdee..fb44a90 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -1856,15 +1856,22 @@ typedef enum { =20 VIR_ENUM_DECL(virDomainLoader) =20 +struct _virStorageSource; +typedef struct _virStorageSource *virStorageSourcePtr; + typedef struct _virDomainLoaderDef virDomainLoaderDef; typedef virDomainLoaderDef *virDomainLoaderDefPtr; struct _virDomainLoaderDef { - char *path; + virStorageSourcePtr src; int readonly; /* enum virTristateBool */ virDomainLoader type; int secure; /* enum virTristateBool */ - char *nvram; /* path to non-volatile RAM */ + virStorageSourcePtr nvram; /* path to non-voliatile RAM */ char *templt; /* user override of path to master nvram */ + bool oldStyleLoader; /* is this an old-style XML formatting, + * ie, absolute path is directly specified? */ + bool oldStyleNvram; /* is this an old-style XML formatting, + * ie, absolute path is directly specified? */ }; =20 void virDomainLoaderDefFree(virDomainLoaderDefPtr loader); diff --git a/src/qemu/qemu_cgroup.c b/src/qemu/qemu_cgroup.c index 546a4c8..5c16a48 100644 --- a/src/qemu/qemu_cgroup.c +++ b/src/qemu/qemu_cgroup.c @@ -607,16 +607,21 @@ qemuSetupMemoryCgroup(virDomainObjPtr vm) static int qemuSetupFirmwareCgroup(virDomainObjPtr vm) { + virStorageSourcePtr src =3D NULL; + if (!vm->def->os.loader) return 0; =20 - if (vm->def->os.loader->path && - qemuSetupImagePathCgroup(vm, vm->def->os.loader->path, - vm->def->os.loader->readonly =3D=3D VIR_T= RISTATE_BOOL_YES) < 0) + src =3D vm->def->os.loader->src; + + if (src->type =3D=3D VIR_STORAGE_TYPE_FILE && + qemuSetupImagePathCgroup(vm, src->path, + src->readonly =3D=3D VIR_TRISTATE_BOOL_YE= S) < 0) return -1; =20 if (vm->def->os.loader->nvram && - qemuSetupImagePathCgroup(vm, vm->def->os.loader->nvram, false) < 0) + vm->def->os.loader->nvram->type =3D=3D VIR_STORAGE_TYPE_FILE && + qemuSetupImagePathCgroup(vm, vm->def->os.loader->nvram->path, fals= e) < 0) return -1; =20 return 0; diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 9da2d60..ba5283f 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -9320,6 +9320,7 @@ qemuBuildDomainLoaderCommandLine(virCommandPtr cmd, virDomainLoaderDefPtr loader =3D def->os.loader; virBuffer buf =3D VIR_BUFFER_INITIALIZER; int unit =3D 0; + char *source =3D NULL; =20 if (!loader) return; @@ -9327,7 +9328,7 @@ qemuBuildDomainLoaderCommandLine(virCommandPtr cmd, switch ((virDomainLoader) loader->type) { case VIR_DOMAIN_LOADER_TYPE_ROM: virCommandAddArg(cmd, "-bios"); - virCommandAddArg(cmd, loader->path); + virCommandAddArg(cmd, loader->src->path); break; =20 case VIR_DOMAIN_LOADER_TYPE_PFLASH: @@ -9339,9 +9340,14 @@ qemuBuildDomainLoaderCommandLine(virCommandPtr cmd, NULL); } =20 + if (qemuGetDriveSourceString(loader->src, NULL, &source) < 0) + break; + virBufferAddLit(&buf, "file=3D"); - virQEMUBuildBufferEscapeComma(&buf, loader->path); - virBufferAsprintf(&buf, ",if=3Dpflash,format=3Draw,unit=3D%d", uni= t); + virQEMUBuildBufferEscapeComma(&buf, source); + VIR_FREE(source); + virBufferAsprintf(&buf, ",if=3Dpflash,format=3Draw,unit=3D%d", + unit); unit++; =20 if (loader->readonly) { @@ -9354,9 +9360,14 @@ qemuBuildDomainLoaderCommandLine(virCommandPtr cmd, =20 if (loader->nvram) { virBufferFreeAndReset(&buf); + if (qemuGetDriveSourceString(loader->nvram, NULL, &source) < 0) + break; + virBufferAddLit(&buf, "file=3D"); - virQEMUBuildBufferEscapeComma(&buf, loader->nvram); - virBufferAsprintf(&buf, ",if=3Dpflash,format=3Draw,unit=3D%d",= unit); + virQEMUBuildBufferEscapeComma(&buf, source); + virBufferAsprintf(&buf, ",if=3Dpflash,format=3Draw,unit=3D%d", + unit); + unit++; =20 virCommandAddArg(cmd, "-drive"); virCommandAddArgBuffer(cmd, &buf); diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index d3beee5..5b73a6e 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -3346,6 +3346,9 @@ qemuDomainDefPostParse(virDomainDefPtr def, * function shall not fail in that case. It will be re-run on VM start= up * with the capabilities populated. */ virQEMUCapsPtr qemuCaps =3D parseOpaque; + virDomainLoaderDefPtr ldr =3D NULL; + char *nvramPath =3D NULL; + int ret =3D -1; =20 if (def->os.bootloader || def->os.bootloaderArgs) { @@ -3360,13 +3363,20 @@ qemuDomainDefPostParse(virDomainDefPtr def, goto cleanup; } =20 - if (def->os.loader && - def->os.loader->type =3D=3D VIR_DOMAIN_LOADER_TYPE_PFLASH && - def->os.loader->readonly =3D=3D VIR_TRISTATE_SWITCH_ON && - !def->os.loader->nvram) { - if (virAsprintf(&def->os.loader->nvram, "%s/%s_VARS.fd", + ldr =3D def->os.loader; + if (ldr && + ldr->type =3D=3D VIR_DOMAIN_LOADER_TYPE_PFLASH && + ldr->readonly =3D=3D VIR_TRISTATE_SWITCH_ON && + !ldr->nvram) { + if (virAsprintf(&nvramPath, "%s/%s_VARS.fd", cfg->nvramDir, def->name) < 0) goto cleanup; + ldr->nvram =3D virStorageSourceNewFromBackingAbsolute(nvramPath); + if (!ldr->nvram) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Unable to add NVRAM drive %s"), nvramPath); + goto cleanup; + } } =20 if (qemuDomainDefAddDefaultDevices(def, qemuCaps) < 0) @@ -10547,19 +10557,22 @@ qemuDomainSetupLoader(virQEMUDriverConfigPtr cfg = ATTRIBUTE_UNUSED, =20 VIR_DEBUG("Setting up loader"); =20 - if (loader) { + if (loader && loader->src) { switch ((virDomainLoader) loader->type) { case VIR_DOMAIN_LOADER_TYPE_ROM: - if (qemuDomainCreateDevice(loader->path, data, false) < 0) + if (loader->src->type =3D=3D VIR_STORAGE_TYPE_FILE && + qemuDomainCreateDevice(loader->src->path, data, false) < 0) goto cleanup; break; =20 case VIR_DOMAIN_LOADER_TYPE_PFLASH: - if (qemuDomainCreateDevice(loader->path, data, false) < 0) + if (loader->src->type =3D=3D VIR_STORAGE_TYPE_FILE && + qemuDomainCreateDevice(loader->src->path, data, false) < 0) goto cleanup; =20 if (loader->nvram && - qemuDomainCreateDevice(loader->nvram, data, false) < 0) + loader->nvram->type =3D=3D VIR_STORAGE_TYPE_FILE && + qemuDomainCreateDevice(loader->nvram->path, data, false) <= 0) goto cleanup; break; =20 diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index e61af23..a056bc4 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -7526,12 +7526,13 @@ qemuDomainUndefineFlags(virDomainPtr dom, =20 if (vm->def->os.loader && vm->def->os.loader->nvram && - virFileExists(vm->def->os.loader->nvram)) { + vm->def->os.loader->nvram->type =3D=3D VIR_STORAGE_TYPE_FILE && + virFileExists(vm->def->os.loader->nvram->path)) { if ((flags & VIR_DOMAIN_UNDEFINE_NVRAM)) { - if (unlink(vm->def->os.loader->nvram) < 0) { + if (unlink(vm->def->os.loader->nvram->path) < 0) { virReportSystemError(errno, _("failed to remove nvram: %s"), - vm->def->os.loader->nvram); + vm->def->os.loader->nvram->path); goto endjob; } } else if (!(flags & VIR_DOMAIN_UNDEFINE_KEEP_NVRAM)) { diff --git a/src/qemu/qemu_parse_command.c b/src/qemu/qemu_parse_command.c index 351425f..9b1a86e 100644 --- a/src/qemu/qemu_parse_command.c +++ b/src/qemu/qemu_parse_command.c @@ -650,6 +650,7 @@ qemuParseCommandLineDisk(virDomainXMLOptionPtr xmlopt, int idx =3D -1; int busid =3D -1; int unitid =3D -1; + bool is_firmware =3D false; =20 if (qemuParseKeywords(val, &keywords, @@ -772,6 +773,9 @@ qemuParseCommandLineDisk(virDomainXMLOptionPtr xmlopt, def->bus =3D VIR_DOMAIN_DISK_BUS_VIRTIO; } else if (STREQ(values[i], "xen")) { def->bus =3D VIR_DOMAIN_DISK_BUS_XEN; + } else if (STREQ(values[i], "pflash")) { + def->bus =3D VIR_DOMAIN_DISK_BUS_LAST; + is_firmware =3D true; } else if (STREQ(values[i], "sd")) { def->bus =3D VIR_DOMAIN_DISK_BUS_SD; } @@ -943,8 +947,25 @@ qemuParseCommandLineDisk(virDomainXMLOptionPtr xmlopt, ignore_value(VIR_STRDUP(def->dst, "hda")); } =20 - if (!def->dst) - goto error; + if (!def->dst) { + if (is_firmware && def->bus =3D=3D VIR_DOMAIN_DISK_BUS_LAST) { + if (!dom->os.loader && (VIR_ALLOC(dom->os.loader) < 0)) + goto error; + if (def->src->readonly) { + /* Loader spec */ + dom->os.loader->src =3D def->src; + dom->os.loader->type =3D VIR_DOMAIN_LOADER_TYPE_PFLASH; + } else { + /* NVRAM Spec */ + if (!dom->os.loader->nvram && (VIR_ALLOC(dom->os.loader->n= vram) < 0)) + goto error; + dom->os.loader->nvram =3D def->src; + } + } else { + goto error; + } + } + if (STREQ(def->dst, "xvda")) def->dst[3] =3D 'a' + idx; else @@ -2215,8 +2236,11 @@ qemuParseCommandLine(virCapsPtr caps, } else if (STREQ(arg, "-bios")) { WANT_VALUE(); if (VIR_ALLOC(def->os.loader) < 0 || - VIR_STRDUP(def->os.loader->path, val) < 0) + VIR_ALLOC(def->os.loader->src) < 0 || + VIR_STRDUP(def->os.loader->src->path, val) < 0) goto error; + def->os.loader->src->type =3D VIR_STORAGE_TYPE_FILE; + def->os.loader->type =3D VIR_DOMAIN_LOADER_TYPE_ROM; } else if (STREQ(arg, "-initrd")) { WANT_VALUE(); if (VIR_STRDUP(def->os.initrd, val) < 0) diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c index 5b73a61..5d406ef 100644 --- a/src/qemu/qemu_process.c +++ b/src/qemu/qemu_process.c @@ -4187,25 +4187,53 @@ qemuPrepareNVRAM(virQEMUDriverConfigPtr cfg, const char *master_nvram_path; ssize_t r; =20 - if (!loader || !loader->nvram || virFileExists(loader->nvram)) + /* This function is used to prepare a pristine local + * NVRAM file based on an existing template. + * The template could be explicitly specified in domain XML + * or inferred from absolute firmware path. + * + * Return early in the following cases: + * (1) loader or NVRAM is not specified. + * (2) loader is not of type 'pflash'. + * (3) NVRAM is already described as 'network-backed' + * (4) NVRAM is file-backed but file already exists. + * (5) Loader is network-backed, and hence impossible to + * infer firmware. + * (6) NVRAM is network-backed, + * hence not easy to customize. + */ + if (!loader || !loader->src || !loader->nvram || + loader->type !=3D VIR_DOMAIN_LOADER_TYPE_PFLASH || + loader->src->type =3D=3D VIR_STORAGE_TYPE_NETWORK || + loader->nvram->type =3D=3D VIR_STORAGE_TYPE_NETWORK) + return 0; + + if (loader->nvram->type =3D=3D VIR_STORAGE_TYPE_FILE && + virFileExists(loader->nvram->path)) return 0; =20 master_nvram_path =3D loader->templt; - if (!loader->templt) { + /* Even if a template is not specified, we associate "known" EFI firmw= are + * to their NVRAM templates. + * Ofcourse this only applies to local firmware paths, as it is diffcu= lt + * for libvirt to parse all network paths. + */ + if (!loader->templt && loader->src->type =3D=3D VIR_STORAGE_TYPE_FILE)= { size_t i; for (i =3D 0; i < cfg->nfirmwares; i++) { - if (STREQ(cfg->firmwares[i]->name, loader->path)) { + if (STREQ(cfg->firmwares[i]->name, loader->src->path)) { master_nvram_path =3D cfg->firmwares[i]->nvram; break; } } } =20 - if (!master_nvram_path) { - virReportError(VIR_ERR_OPERATION_FAILED, - _("unable to find any master var store for " - "loader: %s"), loader->path); - goto cleanup; + if (!master_nvram_path && loader->nvram) { + /* There is no template description, but an NVRAM spec + * has already been provided. + * Trust the client to have generated the right spec here + */ + return 0; } =20 if ((srcFD =3D virFileOpenAs(master_nvram_path, O_RDONLY, @@ -4215,13 +4243,13 @@ qemuPrepareNVRAM(virQEMUDriverConfigPtr cfg, master_nvram_path); goto cleanup; } - if ((dstFD =3D virFileOpenAs(loader->nvram, + if ((dstFD =3D virFileOpenAs(loader->nvram->path, O_WRONLY | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR, cfg->user, cfg->group, 0)) < 0) { virReportSystemError(-dstFD, _("Failed to create file '%s'"), - loader->nvram); + loader->nvram->path); goto cleanup; } created =3D true; @@ -4239,7 +4267,7 @@ qemuPrepareNVRAM(virQEMUDriverConfigPtr cfg, if (safewrite(dstFD, buf, r) < 0) { virReportSystemError(errno, _("Unable to write to file '%s'"), - loader->nvram); + loader->nvram->path); goto cleanup; } } while (r); @@ -4253,7 +4281,7 @@ qemuPrepareNVRAM(virQEMUDriverConfigPtr cfg, if (VIR_CLOSE(dstFD) < 0) { virReportSystemError(errno, _("Unable to close file '%s'"), - loader->nvram); + loader->nvram->path); goto cleanup; } =20 @@ -4263,7 +4291,7 @@ qemuPrepareNVRAM(virQEMUDriverConfigPtr cfg, * copy the file content. Roll back. */ if (ret < 0) { if (created) - unlink(loader->nvram); + unlink(loader->nvram->path); } =20 VIR_FORCE_CLOSE(srcFD); diff --git a/src/security/security_dac.c b/src/security/security_dac.c index 8938e2d..3febea6 100644 --- a/src/security/security_dac.c +++ b/src/security/security_dac.c @@ -1604,7 +1604,8 @@ virSecurityDACRestoreAllLabel(virSecurityManagerPtr m= gr, } =20 if (def->os.loader && def->os.loader->nvram && - virSecurityDACRestoreFileLabel(priv, def->os.loader->nvram) < 0) + def->os.loader->nvram->type =3D=3D VIR_STORAGE_TYPE_FILE && + virSecurityDACRestoreFileLabel(priv, def->os.loader->nvram->path) = < 0) rc =3D -1; =20 return rc; @@ -1732,8 +1733,9 @@ virSecurityDACSetAllLabel(virSecurityManagerPtr mgr, return -1; =20 if (def->os.loader && def->os.loader->nvram && + def->os.loader->nvram->type =3D=3D VIR_STORAGE_TYPE_FILE && virSecurityDACSetOwnership(priv, NULL, - def->os.loader->nvram, user, group) < 0) + def->os.loader->nvram->path, user, grou= p) < 0) return -1; =20 if (def->os.kernel && diff --git a/src/security/security_selinux.c b/src/security/security_selinu= x.c index 5f74ef7..bcda939 100644 --- a/src/security/security_selinux.c +++ b/src/security/security_selinux.c @@ -2459,7 +2459,8 @@ virSecuritySELinuxRestoreAllLabel(virSecurityManagerP= tr mgr, rc =3D -1; =20 if (def->os.loader && def->os.loader->nvram && - virSecuritySELinuxRestoreFileLabel(mgr, def->os.loader->nvram) < 0) + def->os.loader->nvram->type =3D=3D VIR_STORAGE_TYPE_FILE && + virSecuritySELinuxRestoreFileLabel(mgr, def->os.loader->nvram->pat= h) < 0) rc =3D -1; =20 return rc; @@ -2851,8 +2852,9 @@ virSecuritySELinuxSetAllLabel(virSecurityManagerPtr m= gr, /* This is different than kernel or initrd. The nvram store * is really a disk, qemu can read and write to it. */ if (def->os.loader && def->os.loader->nvram && + def->os.loader->nvram->type =3D=3D VIR_STORAGE_TYPE_FILE && secdef && secdef->imagelabel && - virSecuritySELinuxSetFilecon(mgr, def->os.loader->nvram, + virSecuritySELinuxSetFilecon(mgr, def->os.loader->nvram->path, secdef->imagelabel) < 0) return -1; =20 diff --git a/src/security/virt-aa-helper.c b/src/security/virt-aa-helper.c index d0f9876..8217d67 100644 --- a/src/security/virt-aa-helper.c +++ b/src/security/virt-aa-helper.c @@ -1063,12 +1063,18 @@ get_files(vahControl * ctl) if (vah_add_file(&buf, ctl->def->os.slic_table, "r") !=3D 0) goto cleanup; =20 - if (ctl->def->os.loader && ctl->def->os.loader->path) - if (vah_add_file(&buf, ctl->def->os.loader->path, "rk") !=3D 0) + if (ctl->def->os.loader && + ctl->def->os.loader->src && + ctl->def->os.loader->src->type =3D=3D VIR_STORAGE_TYPE_FILE && + ctl->def->os.loader->src->path) + if (vah_add_file(&buf, ctl->def->os.loader->src->path, "rk") !=3D = 0) goto cleanup; =20 - if (ctl->def->os.loader && ctl->def->os.loader->nvram) - if (vah_add_file(&buf, ctl->def->os.loader->nvram, "rwk") !=3D 0) + if (ctl->def->os.loader && + ctl->def->os.loader->nvram && + ctl->def->os.loader->nvram->type =3D=3D VIR_STORAGE_TYPE_FILE && + ctl->def->os.loader->nvram->path) + if (vah_add_file(&buf, ctl->def->os.loader->nvram->path, "rwk") != =3D 0) goto cleanup; =20 for (i =3D 0; i < ctl->def->ngraphics; i++) { diff --git a/src/vbox/vbox_common.c b/src/vbox/vbox_common.c index 72a24a3..60451a3 100644 --- a/src/vbox/vbox_common.c +++ b/src/vbox/vbox_common.c @@ -998,11 +998,16 @@ vboxSetBootDeviceOrder(virDomainDefPtr def, vboxDrive= rPtr data, VIR_DEBUG("def->os.initrd %s", def->os.initrd); VIR_DEBUG("def->os.cmdline %s", def->os.cmdline); VIR_DEBUG("def->os.root %s", def->os.root); - if (def->os.loader) { - VIR_DEBUG("def->os.loader->path %s", def->os.loader->path); + if (def->os.loader && + def->os.loader->src && + def->os.loader->src->type =3D=3D VIR_STORAGE_TYPE_FILE) { + + VIR_DEBUG("def->os.loader->src->path %s", def->os.loader->src-= >path); VIR_DEBUG("def->os.loader->readonly %d", def->os.loader->readonly); VIR_DEBUG("def->os.loader->type %d", def->os.loader->type); - VIR_DEBUG("def->os.loader->nvram %s", def->os.loader->nvram); + if (def->os.loader->nvram && + def->os.loader->nvram->type =3D=3D VIR_STORAGE_TYPE_FILE) + VIR_DEBUG("def->os.loader->nvram->path %s", def->os.loader-= >nvram->path); } VIR_DEBUG("def->os.bootloader %s", def->os.bootloader); VIR_DEBUG("def->os.bootloaderArgs %s", def->os.bootloaderArgs); diff --git a/src/xenapi/xenapi_driver.c b/src/xenapi/xenapi_driver.c index 42b305d..4070660 100644 --- a/src/xenapi/xenapi_driver.c +++ b/src/xenapi/xenapi_driver.c @@ -1444,10 +1444,12 @@ xenapiDomainGetXMLDesc(virDomainPtr dom, unsigned i= nt flags) char *value =3D NULL; defPtr->os.type =3D VIR_DOMAIN_OSTYPE_XEN; if (VIR_ALLOC(defPtr->os.loader) < 0 || - VIR_STRDUP(defPtr->os.loader->path, "pygrub") < 0) { + VIR_ALLOC(defPtr->os.loader->src) < 0 || + VIR_STRDUP(defPtr->os.loader->src->path, "pygrub") < 0) { VIR_FREE(boot_policy); goto error; } + defPtr->os.loader->src->type =3D VIR_STORAGE_TYPE_FILE; xen_vm_get_pv_kernel(session, &value, vm); if (STRNEQ(value, "")) { if (VIR_STRDUP(defPtr->os.kernel, value) < 0) { diff --git a/src/xenconfig/xen_sxpr.c b/src/xenconfig/xen_sxpr.c index e868c05..fd3165c 100644 --- a/src/xenconfig/xen_sxpr.c +++ b/src/xenconfig/xen_sxpr.c @@ -87,15 +87,17 @@ xenParseSxprOS(const struct sexpr *node, int hvm) { if (hvm) { - if (VIR_ALLOC(def->os.loader) < 0) + if ((VIR_ALLOC(def->os.loader) < 0) || + (VIR_ALLOC(def->os.loader->src) < 0)) goto error; - if (sexpr_node_copy(node, "domain/image/hvm/loader", &def->os.load= er->path) < 0) + def->os.loader->src->type =3D VIR_STORAGE_TYPE_FILE; + if (sexpr_node_copy(node, "domain/image/hvm/loader", &def->os.load= er->src->path) < 0) goto error; - if (def->os.loader->path =3D=3D NULL) { - if (sexpr_node_copy(node, "domain/image/hvm/kernel", &def->os.= loader->path) < 0) + if (def->os.loader->src->path =3D=3D NULL) { + if (sexpr_node_copy(node, "domain/image/hvm/kernel", &def->os.= loader->src->path) < 0) goto error; =20 - if (def->os.loader->path =3D=3D NULL) { + if (def->os.loader->src->path =3D=3D NULL) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("domain information incomplete, mis= sing HVM loader")); return -1; @@ -124,7 +126,8 @@ xenParseSxprOS(const struct sexpr *node, /* If HVM kenrel =3D=3D loader, then old xend, so kill off kernel */ if (hvm && def->os.kernel && - STREQ(def->os.kernel, def->os.loader->path)) { + def->os.loader->src && + STREQ(def->os.kernel, def->os.loader->src->path)) { VIR_FREE(def->os.kernel); } /* Drop kernel argument that has no value */ @@ -2259,9 +2262,9 @@ xenFormatSxpr(virConnectPtr conn, virDomainDefPtr def) if (hvm) { char bootorder[VIR_DOMAIN_BOOT_LAST+1]; if (def->os.kernel) - virBufferEscapeSexpr(&buf, "(loader '%s')", def->os.loader= ->path); + virBufferEscapeSexpr(&buf, "(loader '%s')", def->os.loader= ->src->path); else - virBufferEscapeSexpr(&buf, "(kernel '%s')", def->os.loader= ->path); + virBufferEscapeSexpr(&buf, "(kernel '%s')", def->os.loader= ->src->path); =20 virBufferAsprintf(&buf, "(vcpus %u)", virDomainDefGetVcpusMax(= def)); if (virDomainDefHasVcpusOffline(def)) diff --git a/src/xenconfig/xen_xm.c b/src/xenconfig/xen_xm.c index 4becb40..408b7b8 100644 --- a/src/xenconfig/xen_xm.c +++ b/src/xenconfig/xen_xm.c @@ -47,8 +47,10 @@ xenParseXMOS(virConfPtr conf, virDomainDefPtr def) const char *boot; =20 if (VIR_ALLOC(def->os.loader) < 0 || - xenConfigCopyString(conf, "kernel", &def->os.loader->path) < 0) + VIR_ALLOC(def->os.loader->src) < 0 || + xenConfigCopyString(conf, "kernel", &def->os.loader->src->path= ) < 0) return -1; + def->os.loader->src->type =3D VIR_STORAGE_TYPE_FILE; =20 if (xenConfigGetString(conf, "boot", &boot, "c") < 0) return -1; @@ -484,9 +486,10 @@ xenFormatXMOS(virConfPtr conf, virDomainDefPtr def) if (xenConfigSetString(conf, "builder", "hvm") < 0) return -1; =20 - if (def->os.loader && def->os.loader->path && - xenConfigSetString(conf, "kernel", def->os.loader->path) < 0) + if (def->os.loader && def->os.loader->src && + xenConfigSetString(conf, "kernel", def->os.loader->src->path) = < 0) return -1; + def->os.loader->src->type =3D VIR_STORAGE_TYPE_FILE; =20 for (i =3D 0; i < def->os.nBootDevs; i++) { switch (def->os.bootDevs[i]) { --=20 1.8.1.2 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list