Currently, libvirtd will start a dnsmasq process for the virtual network, but (aside from killing the dnsmasq process and replacing it), there's no way to define tftp boot options. This change introduces a 'netboot' tag to the dhcp configuration: <network> <name>default</name> <bridge name="virbr%d" /> <forward/> <ip address="192.168.122.1" netmask="255.255.255.0"> <dhcp> <range start="192.168.122.2" end="192.168.122.254" /> <netboot root="/srv/tftp" file="pxeboot.img"/> </dhcp> </ip> </network> When root= and file= attributes are present, these are passed to the arguments to dnsmasq: dnsmasq [...] --enable-tftp --tftp-root /srv/tftp --dhcp-boot pxeboot.img At present, only local tftp servers are supported (ie, dnsmasq runs as the tftp server), but we could improve this in future by adding a server= attribute. Signed-off-by: Jeremy Kerr <jk@xxxxxxxxxx> --- docs/formatnetwork.html.in | 6 ++++++ docs/schemas/network.rng | 6 ++++++ src/network_conf.c | 28 ++++++++++++++++++++++++++++ src/network_conf.h | 9 +++++++++ src/network_driver.c | 10 ++++++++++ 5 files changed, 59 insertions(+) diff --git a/docs/formatnetwork.html.in b/docs/formatnetwork.html.in index fd68430..3186498 100644 --- a/docs/formatnetwork.html.in +++ b/docs/formatnetwork.html.in @@ -138,6 +138,12 @@ name to be given that host by the DHCP server (via the <code>name</code> attribute). <span class="since">Since 0.4.5</span> </dd> + <dt><code>netboot</code></dt> + <dd>The optional <code>netboot</code> element specified network boot + options to be provided by the DHCP server. Two attributes are + required: <code>root</code> (the root path of the TFTP server), and + <code>file</code> (the file to be used for the boot image). + </dd> </dl> <h2><a name="examples">Example configuration</a></h2> diff --git a/docs/schemas/network.rng b/docs/schemas/network.rng index a4281a5..571e916 100644 --- a/docs/schemas/network.rng +++ b/docs/schemas/network.rng @@ -76,6 +76,12 @@ <attribute name="ip"><text/></attribute> </element> </zeroOrMore> + <optional> + <element name="netboot"> + <attribute name="root"><text/></attribute> + <attribute name="file"><text/></attribute> + </element> + </optional> </element> </element> </optional> diff --git a/src/network_conf.c b/src/network_conf.c index 3764bb4..87bb5e4 100644 --- a/src/network_conf.c +++ b/src/network_conf.c @@ -115,6 +115,9 @@ void virNetworkDefFree(virNetworkDefPtr def) } VIR_FREE(def->hosts); + VIR_FREE(def->tftproot); + VIR_FREE(def->bootfile); + VIR_FREE(def); } @@ -299,6 +302,24 @@ virNetworkDHCPRangeDefParseXML(virConnectPtr conn, def->hosts[def->nhosts].name = (char *)name; def->hosts[def->nhosts].ip = (char *)ip; def->nhosts++; + + } else if (cur->type == XML_ELEMENT_NODE && + xmlStrEqual(cur->name, BAD_CAST "netboot")) { + xmlChar *root, *file; + + if (!(root = xmlGetProp(cur, BAD_CAST "root"))) { + cur = cur->next; + continue; + } + + if (!(file = xmlGetProp(cur, BAD_CAST "file"))) { + cur = cur->next; + xmlFree(root); + continue; + } + + def->tftproot = (char *)root; + def->bootfile = (char *)file; } cur = cur->next; @@ -621,6 +642,13 @@ char *virNetworkDefFormat(virConnectPtr conn, virBufferVSprintf(&buf, "ip='%s' ", def->hosts[i].ip); virBufferAddLit(&buf, "/>\n"); } + if (virNetworkDefProvidesNetboot(def)) { + virBufferAddLit(&buf, " <netboot"); + virBufferEscapeString(&buf, " root='%s'", def->tftproot); + virBufferEscapeString(&buf, " file='%s'", def->bootfile); + virBufferAddLit(&buf, " />\n"); + } + virBufferAddLit(&buf, " </dhcp>\n"); } diff --git a/src/network_conf.h b/src/network_conf.h index 4076f9a..f6f7c1e 100644 --- a/src/network_conf.h +++ b/src/network_conf.h @@ -78,8 +78,17 @@ struct _virNetworkDef { unsigned int nhosts; /* Zero or more dhcp hosts */ virNetworkDHCPHostDefPtr hosts; + + char *tftproot; + char *bootfile; }; +static inline int +virNetworkDefProvidesNetboot(const virNetworkDefPtr def) +{ + return def->tftproot && def->bootfile; +} + typedef struct _virNetworkObj virNetworkObj; typedef virNetworkObj *virNetworkObjPtr; struct _virNetworkObj { diff --git a/src/network_driver.c b/src/network_driver.c index 49855bf..cf462f2 100644 --- a/src/network_driver.c +++ b/src/network_driver.c @@ -400,6 +400,8 @@ networkBuildDnsmasqArgv(virConnectPtr conn, (2 * network->def->nranges) + /* --dhcp-range 10.0.0.2,10.0.0.254 */ /* --dhcp-host 01:23:45:67:89:0a,hostname,10.0.0.3 */ (2 * network->def->nhosts) + + /* --enable-tftp --tftp-root /srv/tftp --dhcp-boot pxeboot.img */ + (virNetworkDefProvidesNetboot(network->def) ? 5 : 0) + 1; /* NULL */ if (VIR_ALLOC_N(*argv, len) < 0) @@ -478,6 +480,14 @@ networkBuildDnsmasqArgv(virConnectPtr conn, APPEND_ARG(*argv, i++, buf); } + if (virNetworkDefProvidesNetboot(network->def)) { + APPEND_ARG(*argv, i++, "--enable-tftp"); + APPEND_ARG(*argv, i++, "--tftp-root"); + APPEND_ARG(*argv, i++, network->def->tftproot); + APPEND_ARG(*argv, i++, "--dhcp-boot"); + APPEND_ARG(*argv, i++, network->def->bootfile); + } + #undef APPEND_ARG return 0; -- Libvir-list mailing list Libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list