[SLOF] [PATCH v2 06/11] libnet: Add functions for downloading and parsing pxelinux.cfg files
Thomas Huth
thuth at redhat.com
Fri May 25 16:58:11 AEST 2018
On 25.05.2018 08:45, Alexey Kardashevskiy wrote:
> On 19/5/18 1:45 am, Thomas Huth wrote:
>> Booting a kernel via pxelinux.cfg files is common on x86 and also with
>> ppc64 bootloaders like petitboot, so it would be nice to support this
>> in SLOF, too. This patch adds functions for downloading and parsing
>> such pxelinux.cfg files. See this URL for more details on pxelinux.cfg:
>> https://www.syslinux.org/wiki/index.php?title=PXELINUX
>>
>> Signed-off-by: Thomas Huth <thuth at redhat.com>
>> ---
>> lib/libnet/Makefile | 2 +-
>> lib/libnet/pxelinux.c | 209 ++++++++++++++++++++++++++++++++++++++++++++++++++
>> lib/libnet/pxelinux.h | 33 ++++++++
>> 3 files changed, 243 insertions(+), 1 deletion(-)
>> create mode 100644 lib/libnet/pxelinux.c
>> create mode 100644 lib/libnet/pxelinux.h
>>
>> diff --git a/lib/libnet/Makefile b/lib/libnet/Makefile
>> index dfefea9..a2a6570 100644
>> --- a/lib/libnet/Makefile
>> +++ b/lib/libnet/Makefile
>> @@ -19,7 +19,7 @@ include $(TOP)/make.rules
>> CFLAGS += -I. -I.. -I../libc/include -I$(TOP)/include $(FLAG)
>>
>> SRCS = ethernet.c ipv4.c udp.c tcp.c dns.c bootp.c dhcp.c tftp.c \
>> - ipv6.c dhcpv6.c icmpv6.c ndp.c netload.c ping.c args.c
>> + ipv6.c dhcpv6.c icmpv6.c ndp.c netload.c ping.c args.c pxelinux.c
>>
>> OBJS = $(SRCS:%.c=%.o)
>>
>> diff --git a/lib/libnet/pxelinux.c b/lib/libnet/pxelinux.c
>> new file mode 100644
>> index 0000000..0c0b42e
>> --- /dev/null
>> +++ b/lib/libnet/pxelinux.c
>> @@ -0,0 +1,209 @@
>> +/*****************************************************************************
>> + * pxelinux.cfg-style config file support.
>> + *
>> + * See https://www.syslinux.org/wiki/index.php?title=PXELINUX for information
>> + * about the pxelinux config file layout.
>> + *
>> + * Copyright 2018 Red Hat, Inc.
>> + *
>> + * This program and the accompanying materials are made available under the
>> + * terms of the BSD License which accompanies this distribution, and is
>> + * available at http://www.opensource.org/licenses/bsd-license.php
>> + *
>> + * Contributors:
>> + * Thomas Huth, Red Hat Inc. - initial implementation
>> + *****************************************************************************/
>> +
>> +#include <stdio.h>
>> +#include <string.h>
>> +#include "tftp.h"
>> +#include "pxelinux.h"
>> +
>> +/**
>> + * Call tftp() and report errors (excet "file-not-found" errors)
>> + */
>> +static int pxelinux_tftp_load(filename_ip_t *fnip, void *buffer, int len)
>> +{
>> + tftp_err_t tftp_err;
>> + int rc;
>> +
>> + rc = tftp(fnip, buffer, len, &tftp_err);
>> +
>> + if (rc > 0) {
>> + printf("\r TFTP: Received %s (%d bytes)\n",
>> + fnip->filename, rc);
>> + } else if (rc == -3) {
>> + /* Ignore file-not-found (since we are probing the files)
>> + * and simply erase the "Receiving data: 0 KBytes" string */
>> + printf("\r \r");
>> + } else {
>> + const char *errstr = NULL;
>> + rc = tftp_get_error_info(fnip, &tftp_err, rc, &errstr, NULL);
>> + if (errstr)
>> + printf("\r TFTP error: %s\n", errstr);
>> + }
>> +
>> + return rc;
>> +}
>> +
>> +/**
>> + * Try to load a pxelinux.cfg file by probing the possible file names.
>> + */
>> +static int pxelinux_load_cfg(filename_ip_t *fn_ip, uint8_t *mac, uint8_t *uuid,
>> + char *cfgbuf, int cfgbufsize)
>> +{
>> + int rc, idx;
>> + char basedir[sizeof(fn_ip->filename) - 40];
>> + char *slash;
>> +
>> + cfgbuf[cfgbufsize - 1] = 0; /* Make sure it is NUL-terminated */
>> +
>> + /* Did we get a usable base directory via DHCP? */
>> + slash = strrchr(fn_ip->filename, '/');
>> + if (slash && slash - fn_ip->filename < sizeof(basedir) - 1) {
>> + slash[1] = 0;
>> + strcpy(basedir, fn_ip->filename);
>> + } else {
>> + strcpy(basedir, "pxelinux.cfg/");
>> + }
>> +
>> + printf("Trying pxelinux.cfg files...\n");
>> +
>> + /* Try to load config file with name based on the VM UUID */
>> + if (uuid) {
>> + sprintf(fn_ip->filename, "%s%02x%02x%02x%02x-%02x%02x-"
>> + "%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x", basedir,
>> + uuid[0], uuid[1], uuid[2], uuid[3], uuid[4], uuid[5],
>> + uuid[6], uuid[7], uuid[8], uuid[9], uuid[10], uuid[11],
>> + uuid[12], uuid[13], uuid[14], uuid[15]);
>> + rc = pxelinux_tftp_load(fn_ip, cfgbuf, cfgbufsize - 1);
>> + if (rc > 0) {
>> + return rc;
>> + }
>> + }
>
>
> This belongs to 11/11. Also, this UUID comes from QEMU's system-id DT
> property which is formatted as xxxx-xx-xx-xx-xxxxxx (UUID_FMT in QEMU)
> which is exactly the same as above, cannot you just use the plain string
> from the property and avoid parsing/sprintf?
Again, the answer is the s390-ccw bios: There you get the UUID in binary
form, not in string form. But ok, I can also convert the binary UUID to
a string in the s390-ccw bios already and always use a string in
pxelinux.c, so I'll try to do that in the next version of the patch.
Thomas
More information about the SLOF
mailing list