All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH v2 0/4] pc-bios/s390-ccw: Network boot improvements
@ 2018-04-23  7:58 Thomas Huth
  2018-04-23  7:58 ` [Qemu-devel] [PATCH v2 1/4] pc-bios/s390-ccw/net: Split up net_load() into init, load and uninit parts Thomas Huth
                   ` (4 more replies)
  0 siblings, 5 replies; 11+ messages in thread
From: Thomas Huth @ 2018-04-23  7:58 UTC (permalink / raw)
  To: Christian Borntraeger, qemu-s390x, Viktor Mihajlovski
  Cc: Cornelia Huck, qemu-devel, Collin Walling, Farhan Ali

Some patches to improve the network boot experience on s390x:

First patch is just a minor code refactoring which should not have
any visible impact, but makes the following patches easier.

Patch 2 and 3 add support for loading kernels via configuration files,
pxelinux-style and .INS-file style. This way you don't have to manually
glue your ramdisk to your kernel anymore, so this should be quite a
relieve for all users who want to boot Linux via the network.

The last patch makes sure that we leave the machine in a sane state
before jumping into the Linux kernel - i.e. the netboot firmware now
resets the machine with diag308, too, just like the main s390-ccw
is doing it already.

v2:
 - Replaced the patch to shut down virtio-net with the diag308 patch
 - Slightly changed the logic that probes for pxelinux config files:
   The user can now supply a base folder where config files reside
   (the DHCP bootfile name then must end with a slash), and the
   firmware will then only look in that folder for config files
   instead of always probing the "pxelinux.cfg" folder. This way
   we avoid a potential clash with x86 pxelinux.cfg files.
 - Some clean-ups here and there.

Thomas Huth (4):
  pc-bios/s390-ccw/net: Split up net_load() into init, load and uninit
    parts
  pc-bios/s390-ccw/net: Add support for pxelinux-style config files
  pc-bios/s390-ccw/net: Add support for .INS config files
  pc-bios/s390-ccw/net: Use diag308 to reset machine before jumping to
    the OS

 pc-bios/s390-ccw/Makefile    |   4 +-
 pc-bios/s390-ccw/bootmap.c   |  63 +-------
 pc-bios/s390-ccw/bootmap.h   |   4 -
 pc-bios/s390-ccw/jump2ipl.c  |  81 ++++++++++
 pc-bios/s390-ccw/netboot.mak |   8 +-
 pc-bios/s390-ccw/netmain.c   | 344 +++++++++++++++++++++++++++++++++++++++----
 pc-bios/s390-ccw/s390-ccw.h  |   4 +
 7 files changed, 408 insertions(+), 100 deletions(-)
 create mode 100644 pc-bios/s390-ccw/jump2ipl.c

-- 
1.8.3.1

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [Qemu-devel] [PATCH v2 1/4] pc-bios/s390-ccw/net: Split up net_load() into init, load and uninit parts
  2018-04-23  7:58 [Qemu-devel] [PATCH v2 0/4] pc-bios/s390-ccw: Network boot improvements Thomas Huth
@ 2018-04-23  7:58 ` Thomas Huth
  2018-04-23  7:58 ` [Qemu-devel] [PATCH v2 2/4] pc-bios/s390-ccw/net: Add support for pxelinux-style config files Thomas Huth
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 11+ messages in thread
From: Thomas Huth @ 2018-04-23  7:58 UTC (permalink / raw)
  To: Christian Borntraeger, qemu-s390x, Viktor Mihajlovski
  Cc: Cornelia Huck, qemu-devel, Collin Walling, Farhan Ali

When we want to support pxelinux-style network booting later, we've got
to do several TFTP transfers - and we do not want to apply for a new IP
address via DHCP each time. So split up net_load into three parts:

1. net_init(), which initializes virtio-net, gets an IP address via DHCP
   and prints out the related information.

2. The tftp_load call is now moved directly into the main() function

3. A new net_release() function which should tear down the network stack
   before we are done in the firmware.

This will make it easier to extend the code in the next patches.

Signed-off-by: Thomas Huth <thuth@redhat.com>
---
 pc-bios/s390-ccw/netmain.c | 63 +++++++++++++++++++++++++++-------------------
 1 file changed, 37 insertions(+), 26 deletions(-)

diff --git a/pc-bios/s390-ccw/netmain.c b/pc-bios/s390-ccw/netmain.c
index d86d46b..8fa9e6c 100644
--- a/pc-bios/s390-ccw/netmain.c
+++ b/pc-bios/s390-ccw/netmain.c
@@ -128,13 +128,13 @@ static void seed_rng(uint8_t mac[])
     srand(seed);
 }
 
-static int tftp_load(filename_ip_t *fnip, void *buffer, int len,
-                     unsigned int retries, int ip_vers)
+static int tftp_load(filename_ip_t *fnip, void *buffer, int len)
 {
     tftp_err_t tftp_err;
     int rc;
 
-    rc = tftp(fnip, buffer, len, retries, &tftp_err, 1, 1428, ip_vers);
+    rc = tftp(fnip, buffer, len, DEFAULT_TFTP_RETRIES, &tftp_err, 1, 1428,
+              ip_version);
 
     if (rc > 0) {
         printf("  TFTP: Received %s (%d KBytes)\n", fnip->filename,
@@ -199,20 +199,19 @@ static int tftp_load(filename_ip_t *fnip, void *buffer, int len,
     return rc;
 }
 
-static int net_load(char *buffer, int len)
+static int net_init(filename_ip_t *fn_ip)
 {
-    filename_ip_t fn_ip;
     uint8_t mac[6];
     int rc;
 
-    memset(&fn_ip, 0, sizeof(filename_ip_t));
+    memset(fn_ip, 0, sizeof(filename_ip_t));
 
     rc = virtio_net_init(mac);
     if (rc < 0) {
         puts("Could not initialize network device");
         return -101;
     }
-    fn_ip.fd = rc;
+    fn_ip->fd = rc;
 
     printf("  Using MAC address: %02x:%02x:%02x:%02x:%02x:%02x\n",
            mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
@@ -220,10 +219,10 @@ static int net_load(char *buffer, int len)
     set_mac_address(mac);    /* init ethernet layer */
     seed_rng(mac);
 
-    rc = dhcp(&fn_ip, DEFAULT_BOOT_RETRIES);
+    rc = dhcp(fn_ip, DEFAULT_BOOT_RETRIES);
     if (rc >= 0) {
         if (ip_version == 4) {
-            set_ipv4_address(fn_ip.own_ip);
+            set_ipv4_address(fn_ip->own_ip);
         }
     } else {
         puts("Could not get IP address");
@@ -232,18 +231,18 @@ static int net_load(char *buffer, int len)
 
     if (ip_version == 4) {
         printf("  Using IPv4 address: %d.%d.%d.%d\n",
-              (fn_ip.own_ip >> 24) & 0xFF, (fn_ip.own_ip >> 16) & 0xFF,
-              (fn_ip.own_ip >>  8) & 0xFF, fn_ip.own_ip & 0xFF);
+              (fn_ip->own_ip >> 24) & 0xFF, (fn_ip->own_ip >> 16) & 0xFF,
+              (fn_ip->own_ip >>  8) & 0xFF, fn_ip->own_ip & 0xFF);
     } else if (ip_version == 6) {
         char ip6_str[40];
-        ipv6_to_str(fn_ip.own_ip6.addr, ip6_str);
+        ipv6_to_str(fn_ip->own_ip6.addr, ip6_str);
         printf("  Using IPv6 address: %s\n", ip6_str);
     }
 
     if (rc == -2) {
         printf("ARP request to TFTP server (%d.%d.%d.%d) failed\n",
-               (fn_ip.server_ip >> 24) & 0xFF, (fn_ip.server_ip >> 16) & 0xFF,
-               (fn_ip.server_ip >>  8) & 0xFF, fn_ip.server_ip & 0xFF);
+               (fn_ip->server_ip >> 24) & 0xFF, (fn_ip->server_ip >> 16) & 0xFF,
+               (fn_ip->server_ip >>  8) & 0xFF, fn_ip->server_ip & 0xFF);
         return -102;
     }
     if (rc == -4 || rc == -3) {
@@ -251,28 +250,31 @@ static int net_load(char *buffer, int len)
         return -107;
     }
 
+    printf("  Using TFTP server: ");
     if (ip_version == 4) {
-        printf("  Requesting file \"%s\" via TFTP from %d.%d.%d.%d\n",
-               fn_ip.filename,
-               (fn_ip.server_ip >> 24) & 0xFF, (fn_ip.server_ip >> 16) & 0xFF,
-               (fn_ip.server_ip >>  8) & 0xFF, fn_ip.server_ip & 0xFF);
+        printf("%d.%d.%d.%d\n",
+               (fn_ip->server_ip >> 24) & 0xFF, (fn_ip->server_ip >> 16) & 0xFF,
+               (fn_ip->server_ip >>  8) & 0xFF, fn_ip->server_ip & 0xFF);
     } else if (ip_version == 6) {
         char ip6_str[40];
-        printf("  Requesting file \"%s\" via TFTP from ", fn_ip.filename);
-        ipv6_to_str(fn_ip.server_ip6.addr, ip6_str);
+        ipv6_to_str(fn_ip->server_ip6.addr, ip6_str);
         printf("%s\n", ip6_str);
     }
 
-    /* Do the TFTP load and print error message if necessary */
-    rc = tftp_load(&fn_ip, buffer, len, DEFAULT_TFTP_RETRIES, ip_version);
-
-    if (ip_version == 4) {
-        dhcp_send_release(fn_ip.fd);
+    if (strlen((char *)fn_ip->filename) > 0) {
+        printf("  Bootfile name: '%s'\n", fn_ip->filename);
     }
 
     return rc;
 }
 
+static void net_release(filename_ip_t *fn_ip)
+{
+    if (ip_version == 4) {
+        dhcp_send_release(fn_ip->fd);
+    }
+}
+
 void panic(const char *string)
 {
     sclp_print(string);
@@ -344,6 +346,7 @@ static void virtio_setup(void)
 
 void main(void)
 {
+    filename_ip_t fn_ip;
     int rc;
 
     sclp_setup();
@@ -351,7 +354,15 @@ void main(void)
 
     virtio_setup();
 
-    rc = net_load(NULL, (long)_start);
+    rc = net_init(&fn_ip);
+    if (rc) {
+        panic("Network initialization failed. Halting.\n");
+    }
+
+    rc = tftp_load(&fn_ip, NULL, (long)_start);
+
+    net_release(&fn_ip);
+
     if (rc > 0) {
         sclp_print("Network loading done, starting kernel...\n");
         asm volatile (" lpsw 0(%0) " : : "r"(0) : "memory");
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [Qemu-devel] [PATCH v2 2/4] pc-bios/s390-ccw/net: Add support for pxelinux-style config files
  2018-04-23  7:58 [Qemu-devel] [PATCH v2 0/4] pc-bios/s390-ccw: Network boot improvements Thomas Huth
  2018-04-23  7:58 ` [Qemu-devel] [PATCH v2 1/4] pc-bios/s390-ccw/net: Split up net_load() into init, load and uninit parts Thomas Huth
@ 2018-04-23  7:58 ` Thomas Huth
  2018-04-24 11:07   ` Viktor VM Mihajlovski
  2018-04-24 13:41   ` Viktor VM Mihajlovski
  2018-04-23  7:58 ` [Qemu-devel] [PATCH v2 3/4] pc-bios/s390-ccw/net: Add support for .INS " Thomas Huth
                   ` (2 subsequent siblings)
  4 siblings, 2 replies; 11+ messages in thread
From: Thomas Huth @ 2018-04-23  7:58 UTC (permalink / raw)
  To: Christian Borntraeger, qemu-s390x, Viktor Mihajlovski
  Cc: Cornelia Huck, qemu-devel, Collin Walling, Farhan Ali

Since it is quite cumbersome to manually create a combined kernel with
initrd image for network booting, we now support loading via pxelinux
configuration files, too. In these files, the kernel, initrd and command
line parameters can be specified seperately, and the firmware then takes
care of glueing everything together in memory after the files have been
downloaded.

The user can either specify a config file directly as bootfile via DHCP
(but in this case, the file has to start either with "default" or a "#"
comment so we can distinguish it from binary kernels), or a folder (i.e.
the bootfile name must end with "/") where the firmware should look for
the typical pxelinux.cfg file names based on MAC or IP address. If no
direct file or folder has been specified, we still look for certain
files in the default "pxelinux.cfg/" folder, but omit some of the file
names to avoid to download x86 config files here by mistake.

Signed-off-by: Thomas Huth <thuth@redhat.com>
---
 pc-bios/s390-ccw/netboot.mak |   5 +-
 pc-bios/s390-ccw/netmain.c   | 225 +++++++++++++++++++++++++++++++++++++++++--
 2 files changed, 222 insertions(+), 8 deletions(-)

diff --git a/pc-bios/s390-ccw/netboot.mak b/pc-bios/s390-ccw/netboot.mak
index a25d238..8db9573 100644
--- a/pc-bios/s390-ccw/netboot.mak
+++ b/pc-bios/s390-ccw/netboot.mak
@@ -24,8 +24,9 @@ CTYPE_OBJS = isdigit.o isxdigit.o toupper.o
 %.o : $(SLOF_DIR)/lib/libc/ctype/%.c
 	$(call quiet-command,$(CC) $(LIBC_CFLAGS) -c -o $@ $<,"CC","$(TARGET_DIR)$@")
 
-STRING_OBJS = strcat.o strchr.o strcmp.o strcpy.o strlen.o strncmp.o strncpy.o \
-	      strstr.o memset.o memcpy.o memmove.o memcmp.o
+STRING_OBJS = strcasecmp.o strcat.o strchr.o strcmp.o strcpy.o strlen.o \
+	      strncasecmp.o strncmp.o strncpy.o strstr.o \
+	      memset.o memcpy.o memmove.o memcmp.o
 %.o : $(SLOF_DIR)/lib/libc/string/%.c
 	$(call quiet-command,$(CC) $(LIBC_CFLAGS) -c -o $@ $<,"CC","$(TARGET_DIR)$@")
 
diff --git a/pc-bios/s390-ccw/netmain.c b/pc-bios/s390-ccw/netmain.c
index 8fa9e6c..129f009 100644
--- a/pc-bios/s390-ccw/netmain.c
+++ b/pc-bios/s390-ccw/netmain.c
@@ -39,11 +39,17 @@
 
 extern char _start[];
 
+#define KERNEL_ADDR             ((void *)0L)
+#define KERNEL_MAX_SIZE         ((long)_start)
+#define ARCH_COMMAND_LINE_SIZE  896              /* Taken from Linux kernel */
+
 char stack[PAGE_SIZE * 8] __attribute__((aligned(PAGE_SIZE)));
 IplParameterBlock iplb __attribute__((aligned(PAGE_SIZE)));
+static char cfgbuf[2048];
 
 static SubChannelId net_schid = { .one = 1 };
 static int ip_version = 4;
+static uint8_t mac[6];
 static uint64_t dest_timer;
 
 static uint64_t get_timer_ms(void)
@@ -136,9 +142,15 @@ static int tftp_load(filename_ip_t *fnip, void *buffer, int len)
     rc = tftp(fnip, buffer, len, DEFAULT_TFTP_RETRIES, &tftp_err, 1, 1428,
               ip_version);
 
-    if (rc > 0) {
-        printf("  TFTP: Received %s (%d KBytes)\n", fnip->filename,
-               rc / 1024);
+    if (rc < 0) {
+        /* Make sure that error messages are put into a new line */
+        printf("\n  ");
+    }
+
+    if (rc > 1024) {
+        printf("  TFTP: Received %s (%d KBytes)\n", fnip->filename, rc / 1024);
+    } else if (rc > 0) {
+        printf("  TFTP: Received %s (%d Bytes)\n", fnip->filename, rc);
     } else if (rc == -1) {
         puts("unknown TFTP error");
     } else if (rc == -2) {
@@ -201,7 +213,6 @@ static int tftp_load(filename_ip_t *fnip, void *buffer, int len)
 
 static int net_init(filename_ip_t *fn_ip)
 {
-    uint8_t mac[6];
     int rc;
 
     memset(fn_ip, 0, sizeof(filename_ip_t));
@@ -275,6 +286,202 @@ static void net_release(filename_ip_t *fn_ip)
     }
 }
 
+/* This structure holds the data from one pxelinux.cfg file entry */
+struct lkia {
+    const char *label;
+    const char *kernel;
+    const char *initrd;
+    const char *append;
+};
+
+static int load_kernel_with_initrd(filename_ip_t *fn_ip, struct lkia *kia)
+{
+    int rc;
+
+    printf("Loading pxelinux.cfg entry '%s'\n", kia->label);
+
+    if (!kia->kernel) {
+        printf("Kernel entry is missing!\n");
+        return -1;
+    }
+
+    strncpy((char *)&fn_ip->filename, kia->kernel, sizeof(fn_ip->filename));
+    rc = tftp_load(fn_ip, KERNEL_ADDR, KERNEL_MAX_SIZE);
+    if (rc < 0) {
+        return rc;
+    }
+
+    if (kia->initrd) {
+        uint64_t iaddr = (rc + 0xfff) & ~0xfffUL;
+
+        strncpy((char *)&fn_ip->filename, kia->initrd, sizeof(fn_ip->filename));
+        rc = tftp_load(fn_ip, (void *)iaddr, KERNEL_MAX_SIZE - iaddr);
+        if (rc < 0) {
+            return rc;
+        }
+        /* Patch location and size: */
+        *(uint64_t *)0x10408 = iaddr;
+        *(uint64_t *)0x10410 = rc;
+        rc += iaddr;
+    }
+
+    if (kia->append) {
+        strncpy((char *)0x10480, kia->append, ARCH_COMMAND_LINE_SIZE);
+    }
+
+    return rc;
+}
+
+#define MAX_PXELINUX_ENTRIES 16
+
+/**
+ * Parse a pxelinux-style configuration file.
+ * See the following URL for more inforation about the config file syntax:
+ * https://www.syslinux.org/wiki/index.php?title=PXELINUX
+ */
+static int handle_pxelinux_cfg(filename_ip_t *fn_ip, char *cfg, int cfgsize)
+{
+    struct lkia entries[MAX_PXELINUX_ENTRIES];
+    int num_entries = 0;
+    char *ptr = cfg, *eol, *arg;
+    char *defaultlabel = NULL;
+    int def_ent = 0;
+
+    while (ptr < cfg + cfgsize && num_entries < MAX_PXELINUX_ENTRIES) {
+        eol = strchr(ptr, '\n');
+        if (!eol) {
+            eol = cfg + cfgsize;
+        }
+        if (eol > ptr && *(eol - 1) == '\r') {
+            *(eol - 1) = 0;
+        }
+        *eol = '\0';
+        while (*ptr == ' ' || *ptr == '\t') {
+            ptr++;
+        }
+        if (*ptr == 0 || *ptr == '#') {   /* Ignore comments and empty lines */
+            goto nextline;
+        }
+        arg = strchr(ptr, ' ');    /* Look for space between command and arg */
+        if (!arg) {
+            arg = strchr(ptr, '\t');
+        }
+        if (!arg) {
+            printf("Failed to parse the following line:\n %s\n", ptr);
+            goto nextline;
+        }
+        *arg++ = 0;
+        while (*arg == ' ' || *arg == '\t') {
+            arg++;
+        }
+        if (!strcasecmp("default", ptr)) {
+            defaultlabel = arg;
+        } else if (!strcasecmp("label", ptr)) {
+            entries[num_entries].label = arg;
+            if (defaultlabel && !strcmp(arg, defaultlabel)) {
+                def_ent = num_entries;
+            }
+            num_entries++;
+        } else if (!strcasecmp("kernel", ptr) && num_entries > 0) {
+            entries[num_entries - 1].kernel = arg;
+        } else if (!strcasecmp("initrd", ptr) && num_entries > 0) {
+            entries[num_entries - 1].initrd = arg;
+        } else if (!strcasecmp("append", ptr) && num_entries > 0) {
+            entries[num_entries - 1].append = arg;
+        } else {
+            printf("Command '%s' is not supported.\n", ptr);
+        }
+nextline:
+        ptr = eol + 1;
+    }
+
+    return load_kernel_with_initrd(fn_ip, &entries[def_ent]);
+}
+
+static int net_try_pxelinux_cfgs(filename_ip_t *fn_ip)
+{
+    int rc, idx;
+    char basedir[256];
+    int has_basedir;
+
+    cfgbuf[sizeof(cfgbuf) - 1] = 0;   /* Make sure that it is NUL-terminated */
+
+    /* Did we get a usable base directory via DHCP? */
+    idx = strlen((char *)fn_ip->filename);
+    if (idx > 0 && idx < sizeof(basedir) - 40 &&
+        fn_ip->filename[idx - 1] == '/') {
+        has_basedir = true;
+        strcpy(basedir, (char *)fn_ip->filename);
+    } else {
+        has_basedir = false;
+        strcpy(basedir, "pxelinux.cfg/");
+    }
+
+    printf("Trying pxelinux.cfg files...\n");
+
+    /* Look for config file with MAC address in its name */
+    sprintf((char *)fn_ip->filename, "%s%02x-%02x-%02x-%02x-%02x-%02x",
+            basedir, mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
+    rc = tftp_load(fn_ip, cfgbuf, sizeof(cfgbuf) - 1);
+    if (rc > 0) {
+        return handle_pxelinux_cfg(fn_ip, cfgbuf, sizeof(cfgbuf));
+    }
+
+    /* Look for config file with IP address in its name */
+    if (ip_version == 4) {
+        for (idx = 0; (has_basedir && idx <= 7) || idx < 1; idx++) {
+            sprintf((char *)fn_ip->filename, "%s%02X%02X%02X%02X", basedir,
+                    (fn_ip->own_ip >> 24) & 0xff, (fn_ip->own_ip >> 16) & 0xff,
+                    (fn_ip->own_ip >> 8) & 0xff, fn_ip->own_ip & 0xff);
+            fn_ip->filename[strlen((char *)fn_ip->filename) - idx] = 0;
+            rc = tftp_load(fn_ip, cfgbuf, sizeof(cfgbuf) - 1);
+            if (rc > 0) {
+                return handle_pxelinux_cfg(fn_ip, cfgbuf, sizeof(cfgbuf));
+            }
+        }
+    }
+
+    /* Try "default" config file */
+    if (has_basedir) {
+        sprintf((char *)fn_ip->filename, "%sdefault", basedir);
+        rc = tftp_load(fn_ip, cfgbuf, sizeof(cfgbuf) - 1);
+        if (rc > 0) {
+            return handle_pxelinux_cfg(fn_ip, cfgbuf, sizeof(cfgbuf));
+        }
+    }
+
+    return -1;
+}
+
+static int net_try_direct_tftp_load(filename_ip_t *fn_ip)
+{
+    int rc;
+    void *baseaddr = (void *)0x2000;  /* Load right after the low-core */
+
+    rc = tftp_load(fn_ip, baseaddr, KERNEL_MAX_SIZE - (long)baseaddr);
+    if (rc < 0) {
+        return rc;
+    } else if (rc < 8) {
+        printf("'%s' is too small (%i bytes only).\n", fn_ip->filename, rc);
+        return -1;
+    }
+
+    /* Check whether it is a configuration file instead of a kernel */
+    if (rc < sizeof(cfgbuf) - 1) {
+        memcpy(cfgbuf, baseaddr, rc);
+        cfgbuf[rc] = 0;    /* Make sure that it is NUL-terminated */
+        if (!strncasecmp("default", cfgbuf, 7) || !strncmp("# ", cfgbuf, 2)) {
+            /* Looks like it is a pxelinux.cfg */
+            return handle_pxelinux_cfg(fn_ip, cfgbuf, rc);
+        }
+    }
+
+    /* Move kernel to right location */
+    memmove(KERNEL_ADDR, baseaddr, rc);
+
+    return rc;
+}
+
 void panic(const char *string)
 {
     sclp_print(string);
@@ -347,7 +554,7 @@ static void virtio_setup(void)
 void main(void)
 {
     filename_ip_t fn_ip;
-    int rc;
+    int rc, fnlen;
 
     sclp_setup();
     sclp_print("Network boot starting...\n");
@@ -359,7 +566,13 @@ void main(void)
         panic("Network initialization failed. Halting.\n");
     }
 
-    rc = tftp_load(&fn_ip, NULL, (long)_start);
+    fnlen = strlen((char *)fn_ip.filename);
+    if (fnlen > 0 && fn_ip.filename[fnlen - 1] != '/') {
+        rc = net_try_direct_tftp_load(&fn_ip);
+    }
+    if (rc <= 0) {
+        rc = net_try_pxelinux_cfgs(&fn_ip);
+    }
 
     net_release(&fn_ip);
 
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [Qemu-devel] [PATCH v2 3/4] pc-bios/s390-ccw/net: Add support for .INS config files
  2018-04-23  7:58 [Qemu-devel] [PATCH v2 0/4] pc-bios/s390-ccw: Network boot improvements Thomas Huth
  2018-04-23  7:58 ` [Qemu-devel] [PATCH v2 1/4] pc-bios/s390-ccw/net: Split up net_load() into init, load and uninit parts Thomas Huth
  2018-04-23  7:58 ` [Qemu-devel] [PATCH v2 2/4] pc-bios/s390-ccw/net: Add support for pxelinux-style config files Thomas Huth
@ 2018-04-23  7:58 ` Thomas Huth
  2018-04-23  7:58 ` [Qemu-devel] [PATCH v2 4/4] pc-bios/s390-ccw/net: Use diag308 to reset machine before jumping to the OS Thomas Huth
  2018-04-23 14:55 ` [Qemu-devel] [PATCH v2 5/4] pc-bios/s390-ccw/net: Try to load pxelinux.cfg file accoring to the UUID Thomas Huth
  4 siblings, 0 replies; 11+ messages in thread
From: Thomas Huth @ 2018-04-23  7:58 UTC (permalink / raw)
  To: Christian Borntraeger, qemu-s390x, Viktor Mihajlovski
  Cc: Cornelia Huck, qemu-devel, Collin Walling, Farhan Ali

The .INS config files can normally be found on CD-ROM ISO images,
so by supporting these files, it is now possible to boot directly
when the TFTP server is set up with the contents of such an CD-ROM
image.

Signed-off-by: Thomas Huth <thuth@redhat.com>
---
 pc-bios/s390-ccw/netmain.c | 51 ++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 51 insertions(+)

diff --git a/pc-bios/s390-ccw/netmain.c b/pc-bios/s390-ccw/netmain.c
index 129f009..e5418a9 100644
--- a/pc-bios/s390-ccw/netmain.c
+++ b/pc-bios/s390-ccw/netmain.c
@@ -453,6 +453,55 @@ static int net_try_pxelinux_cfgs(filename_ip_t *fn_ip)
     return -1;
 }
 
+/**
+ * Load via information from a .INS file (which can be found on CD-ROMs
+ * for example)
+ */
+static int handle_ins_cfg(filename_ip_t *fn_ip, char *cfg, int cfgsize)
+{
+    char *ptr;
+    int rc = -1, llen;
+    void *destaddr;
+    char *insbuf = cfg;
+
+    ptr = strchr(insbuf, '\n');
+    if (!ptr) {
+        puts("Does not seem to be a valid .INS file");
+        return -1;
+    }
+
+    *ptr = 0;
+    printf("\nParsing .INS file:\n %s\n", &insbuf[2]);
+
+    insbuf = ptr + 1;
+    while (*insbuf && insbuf < cfg + cfgsize) {
+        ptr = strchr(insbuf, '\n');
+        if (ptr) {
+            *ptr = 0;
+        }
+        llen = strlen(insbuf);
+        if (!llen) {
+            insbuf = ptr + 1;
+            continue;
+        }
+        ptr = strchr(insbuf, ' ');
+        if (!ptr) {
+            puts("Missing space separator in .INS file");
+            return -1;
+        }
+        *ptr = 0;
+        strncpy((char *)fn_ip->filename, insbuf, sizeof(fn_ip->filename));
+        destaddr = (char *)atol(ptr + 1);
+        rc = tftp_load(fn_ip, destaddr, (long)_start - (long)destaddr);
+        if (rc <= 0) {
+            break;
+        }
+        insbuf += llen + 1;
+    }
+
+    return rc;
+}
+
 static int net_try_direct_tftp_load(filename_ip_t *fn_ip)
 {
     int rc;
@@ -473,6 +522,8 @@ static int net_try_direct_tftp_load(filename_ip_t *fn_ip)
         if (!strncasecmp("default", cfgbuf, 7) || !strncmp("# ", cfgbuf, 2)) {
             /* Looks like it is a pxelinux.cfg */
             return handle_pxelinux_cfg(fn_ip, cfgbuf, rc);
+        } else if (!strncmp("* ", cfgbuf, 2)) {
+            return handle_ins_cfg(fn_ip, cfgbuf, rc);
         }
     }
 
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [Qemu-devel] [PATCH v2 4/4] pc-bios/s390-ccw/net: Use diag308 to reset machine before jumping to the OS
  2018-04-23  7:58 [Qemu-devel] [PATCH v2 0/4] pc-bios/s390-ccw: Network boot improvements Thomas Huth
                   ` (2 preceding siblings ...)
  2018-04-23  7:58 ` [Qemu-devel] [PATCH v2 3/4] pc-bios/s390-ccw/net: Add support for .INS " Thomas Huth
@ 2018-04-23  7:58 ` Thomas Huth
  2018-04-23 14:55 ` [Qemu-devel] [PATCH v2 5/4] pc-bios/s390-ccw/net: Try to load pxelinux.cfg file accoring to the UUID Thomas Huth
  4 siblings, 0 replies; 11+ messages in thread
From: Thomas Huth @ 2018-04-23  7:58 UTC (permalink / raw)
  To: Christian Borntraeger, qemu-s390x, Viktor Mihajlovski
  Cc: Cornelia Huck, qemu-devel, Collin Walling, Farhan Ali

The netboot firmware so far simply jumped directly into the OS kernel
after the download has been completed. This, however, bears the risk
that the virtio-net device still might be active in the background and
incoming packets are still placed into the buffers - which could destroy
memory of the now-running Linux kernel in case it did not take over the
device fast enough. Also the SCLP console is not put into a well-defined
state here. We should hand over the system in a clean state when jumping
into the kernel, so let's use the same mechanism as it's done in the
main s390-ccw firmware and reset the machine with diag308 into a clean
state before jumping into the OS kernel code. To be able to share the
code with the main s390-ccw firmware, the related functions are now
extracted from bootmap.c into a new file called jump2ipl.c.

Signed-off-by: Thomas Huth <thuth@redhat.com>
---
 pc-bios/s390-ccw/Makefile    |  4 ++-
 pc-bios/s390-ccw/bootmap.c   | 63 +---------------------------------
 pc-bios/s390-ccw/bootmap.h   |  4 ---
 pc-bios/s390-ccw/jump2ipl.c  | 81 ++++++++++++++++++++++++++++++++++++++++++++
 pc-bios/s390-ccw/netboot.mak |  3 +-
 pc-bios/s390-ccw/netmain.c   | 11 +++++-
 pc-bios/s390-ccw/s390-ccw.h  |  4 +++
 7 files changed, 101 insertions(+), 69 deletions(-)
 create mode 100644 pc-bios/s390-ccw/jump2ipl.c

diff --git a/pc-bios/s390-ccw/Makefile b/pc-bios/s390-ccw/Makefile
index 1712c2d..439e3cc 100644
--- a/pc-bios/s390-ccw/Makefile
+++ b/pc-bios/s390-ccw/Makefile
@@ -9,7 +9,9 @@ $(call set-vpath, $(SRC_PATH)/pc-bios/s390-ccw)
 
 .PHONY : all clean build-all
 
-OBJECTS = start.o main.o bootmap.o sclp.o virtio.o virtio-scsi.o virtio-blkdev.o libc.o menu.o
+OBJECTS = start.o main.o bootmap.o jump2ipl.o sclp.o menu.o \
+	  virtio.o virtio-scsi.o virtio-blkdev.o libc.o
+
 QEMU_CFLAGS := $(filter -W%, $(QEMU_CFLAGS))
 QEMU_CFLAGS += -ffreestanding -fno-delete-null-pointer-checks -msoft-float
 QEMU_CFLAGS += -march=z900 -fPIE -fno-strict-aliasing
diff --git a/pc-bios/s390-ccw/bootmap.c b/pc-bios/s390-ccw/bootmap.c
index 9287b7a..7e63e6b 100644
--- a/pc-bios/s390-ccw/bootmap.c
+++ b/pc-bios/s390-ccw/bootmap.c
@@ -29,14 +29,6 @@
 /* Scratch space */
 static uint8_t sec[MAX_SECTOR_SIZE*4] __attribute__((__aligned__(PAGE_SIZE)));
 
-typedef struct ResetInfo {
-    uint32_t ipl_mask;
-    uint32_t ipl_addr;
-    uint32_t ipl_continue;
-} ResetInfo;
-
-static ResetInfo save;
-
 const uint8_t el_torito_magic[] = "EL TORITO SPECIFICATION"
                                   "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0";
 
@@ -57,53 +49,6 @@ static inline bool is_iso_vd_valid(IsoVolDesc *vd)
            vd->type <= VOL_DESC_TYPE_PARTITION;
 }
 
-static void jump_to_IPL_2(void)
-{
-    ResetInfo *current = 0;
-
-    void (*ipl)(void) = (void *) (uint64_t) current->ipl_continue;
-    *current = save;
-    ipl(); /* should not return */
-}
-
-static void jump_to_IPL_code(uint64_t address)
-{
-    /* store the subsystem information _after_ the bootmap was loaded */
-    write_subsystem_identification();
-
-    /* prevent unknown IPL types in the guest */
-    if (iplb.pbt == S390_IPL_TYPE_QEMU_SCSI) {
-        iplb.pbt = S390_IPL_TYPE_CCW;
-        set_iplb(&iplb);
-    }
-
-    /*
-     * The IPL PSW is at address 0. We also must not overwrite the
-     * content of non-BIOS memory after we loaded the guest, so we
-     * save the original content and restore it in jump_to_IPL_2.
-     */
-    ResetInfo *current = 0;
-
-    save = *current;
-    current->ipl_addr = (uint32_t) (uint64_t) &jump_to_IPL_2;
-    current->ipl_continue = address & 0x7fffffff;
-
-    debug_print_int("set IPL addr to", current->ipl_continue);
-
-    /* Ensure the guest output starts fresh */
-    sclp_print("\n");
-
-    /*
-     * HACK ALERT.
-     * We use the load normal reset to keep r15 unchanged. jump_to_IPL_2
-     * can then use r15 as its stack pointer.
-     */
-    asm volatile("lghi 1,1\n\t"
-                 "diag 1,1,0x308\n\t"
-                 : : : "1", "memory");
-    panic("\n! IPL returns !\n");
-}
-
 /***********************************************************************
  * IPL an ECKD DASD (CDL or LDL/CMS format)
  */
@@ -727,13 +672,7 @@ static void load_iso_bc_entry(IsoBcSection *load)
                         (void *)((uint64_t)bswap16(s.load_segment)),
                         blks_to_load);
 
-    /* Trying to get PSW at zero address */
-    if (*((uint64_t *)0) & IPL_PSW_MASK) {
-        jump_to_IPL_code((*((uint64_t *)0)) & 0x7fffffff);
-    }
-
-    /* Try default linux start address */
-    jump_to_IPL_code(KERN_IMAGE_START);
+    jump_to_low_kernel();
 }
 
 static uint32_t find_iso_bc(void)
diff --git a/pc-bios/s390-ccw/bootmap.h b/pc-bios/s390-ccw/bootmap.h
index 07eb600..bef81ff 100644
--- a/pc-bios/s390-ccw/bootmap.h
+++ b/pc-bios/s390-ccw/bootmap.h
@@ -355,10 +355,6 @@ static inline uint32_t iso_733_to_u32(uint64_t x)
 #define ISO_SECTOR_SIZE 2048
 /* El Torito specifies boot image size in 512 byte blocks */
 #define ET_SECTOR_SHIFT 2
-#define KERN_IMAGE_START 0x010000UL
-#define PSW_MASK_64 0x0000000100000000ULL
-#define PSW_MASK_32 0x0000000080000000ULL
-#define IPL_PSW_MASK (PSW_MASK_32 | PSW_MASK_64)
 
 #define ISO_PRIMARY_VD_SECTOR 16
 
diff --git a/pc-bios/s390-ccw/jump2ipl.c b/pc-bios/s390-ccw/jump2ipl.c
new file mode 100644
index 0000000..21b25d8
--- /dev/null
+++ b/pc-bios/s390-ccw/jump2ipl.c
@@ -0,0 +1,81 @@
+/*
+ * QEMU s390-ccw firmware - jump to IPL code
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or (at
+ * your option) any later version. See the COPYING file in the top-level
+ * directory.
+ */
+
+#include "libc.h"
+#include "s390-ccw.h"
+
+#define KERN_IMAGE_START 0x010000UL
+#define PSW_MASK_64 0x0000000100000000ULL
+#define PSW_MASK_32 0x0000000080000000ULL
+#define IPL_PSW_MASK (PSW_MASK_32 | PSW_MASK_64)
+
+typedef struct ResetInfo {
+    uint32_t ipl_mask;
+    uint32_t ipl_addr;
+    uint32_t ipl_continue;
+} ResetInfo;
+
+static ResetInfo save;
+
+static void jump_to_IPL_2(void)
+{
+    ResetInfo *current = 0;
+
+    void (*ipl)(void) = (void *) (uint64_t) current->ipl_continue;
+    *current = save;
+    ipl(); /* should not return */
+}
+
+void jump_to_IPL_code(uint64_t address)
+{
+    /* store the subsystem information _after_ the bootmap was loaded */
+    write_subsystem_identification();
+
+    /* prevent unknown IPL types in the guest */
+    if (iplb.pbt == S390_IPL_TYPE_QEMU_SCSI) {
+        iplb.pbt = S390_IPL_TYPE_CCW;
+        set_iplb(&iplb);
+    }
+
+    /*
+     * The IPL PSW is at address 0. We also must not overwrite the
+     * content of non-BIOS memory after we loaded the guest, so we
+     * save the original content and restore it in jump_to_IPL_2.
+     */
+    ResetInfo *current = 0;
+
+    save = *current;
+    current->ipl_addr = (uint32_t) (uint64_t) &jump_to_IPL_2;
+    current->ipl_continue = address & 0x7fffffff;
+
+    debug_print_int("set IPL addr to", current->ipl_continue);
+
+    /* Ensure the guest output starts fresh */
+    sclp_print("\n");
+
+    /*
+     * HACK ALERT.
+     * We use the load normal reset to keep r15 unchanged. jump_to_IPL_2
+     * can then use r15 as its stack pointer.
+     */
+    asm volatile("lghi 1,1\n\t"
+                 "diag 1,1,0x308\n\t"
+                 : : : "1", "memory");
+    panic("\n! IPL returns !\n");
+}
+
+void jump_to_low_kernel(void)
+{
+    /* Trying to get PSW at zero address */
+    if (*((uint64_t *)0) & IPL_PSW_MASK) {
+        jump_to_IPL_code((*((uint64_t *)0)) & 0x7fffffff);
+    }
+
+    /* Try default linux start address */
+    jump_to_IPL_code(KERN_IMAGE_START);
+}
diff --git a/pc-bios/s390-ccw/netboot.mak b/pc-bios/s390-ccw/netboot.mak
index 8db9573..3434018 100644
--- a/pc-bios/s390-ccw/netboot.mak
+++ b/pc-bios/s390-ccw/netboot.mak
@@ -1,7 +1,8 @@
 
 SLOF_DIR := $(SRC_PATH)/roms/SLOF
 
-NETOBJS := start.o sclp.o virtio.o virtio-net.o netmain.o libnet.a libc.a
+NETOBJS := start.o sclp.o virtio.o virtio-net.o jump2ipl.o netmain.o \
+	   libnet.a libc.a
 
 LIBC_INC := -nostdinc -I$(SLOF_DIR)/lib/libc/include
 LIBNET_INC := -I$(SLOF_DIR)/lib/libnet
diff --git a/pc-bios/s390-ccw/netmain.c b/pc-bios/s390-ccw/netmain.c
index e5418a9..fdf115e 100644
--- a/pc-bios/s390-ccw/netmain.c
+++ b/pc-bios/s390-ccw/netmain.c
@@ -541,6 +541,15 @@ void panic(const char *string)
     }
 }
 
+void write_subsystem_identification(void)
+{
+    uint32_t *schid = (uint32_t *) 184;
+    uint32_t *zeroes = (uint32_t *) 188;
+
+    *schid = 0;         /* We must not set this for virtio-net */
+    *zeroes = 0;
+}
+
 static bool find_net_dev(Schib *schib, int dev_no)
 {
     int i, r;
@@ -629,7 +638,7 @@ void main(void)
 
     if (rc > 0) {
         sclp_print("Network loading done, starting kernel...\n");
-        asm volatile (" lpsw 0(%0) " : : "r"(0) : "memory");
+        jump_to_low_kernel();
     }
 
     panic("Failed to load OS from network\n");
diff --git a/pc-bios/s390-ccw/s390-ccw.h b/pc-bios/s390-ccw/s390-ccw.h
index fd18da2..d88e637 100644
--- a/pc-bios/s390-ccw/s390-ccw.h
+++ b/pc-bios/s390-ccw/s390-ccw.h
@@ -87,6 +87,10 @@ ulong get_second(void);
 /* bootmap.c */
 void zipl_load(void);
 
+/* jump2ipl.c */
+void jump_to_IPL_code(uint64_t address);
+void jump_to_low_kernel(void);
+
 /* menu.c */
 void menu_set_parms(uint8_t boot_menu_flag, uint32_t boot_menu_timeout);
 int menu_get_zipl_boot_index(const char *menu_data);
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [Qemu-devel] [PATCH v2 5/4] pc-bios/s390-ccw/net: Try to load pxelinux.cfg file accoring to the UUID
  2018-04-23  7:58 [Qemu-devel] [PATCH v2 0/4] pc-bios/s390-ccw: Network boot improvements Thomas Huth
                   ` (3 preceding siblings ...)
  2018-04-23  7:58 ` [Qemu-devel] [PATCH v2 4/4] pc-bios/s390-ccw/net: Use diag308 to reset machine before jumping to the OS Thomas Huth
@ 2018-04-23 14:55 ` Thomas Huth
  4 siblings, 0 replies; 11+ messages in thread
From: Thomas Huth @ 2018-04-23 14:55 UTC (permalink / raw)
  To: Christian Borntraeger, qemu-s390x, Viktor Mihajlovski
  Cc: Cornelia Huck, qemu-devel, Collin Walling, Farhan Ali

With the STSI instruction, we can get the UUID of the current VM instance,
so we can support loading pxelinux config files via UUID in the file name,
too.

Signed-off-by: Thomas Huth <thuth@redhat.com>
---
 Sorry, just found out how to get the VM UUID after sending out the v2
 series, so this is now patch 5 of 4 ;-)

 pc-bios/s390-ccw/netmain.c | 45 +++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 45 insertions(+)

diff --git a/pc-bios/s390-ccw/netmain.c b/pc-bios/s390-ccw/netmain.c
index fdf115e..f75bd7e 100644
--- a/pc-bios/s390-ccw/netmain.c
+++ b/pc-bios/s390-ccw/netmain.c
@@ -286,6 +286,37 @@ static void net_release(filename_ip_t *fn_ip)
     }
 }
 
+static int get_uuid(uint8_t *uuid)
+{
+    register int r0 asm("0");
+    register int r1 asm("1");
+    uint8_t *mem, *buf;
+    int i, chk = 0;
+
+    mem = malloc(2 * PAGE_SIZE);
+    if (!mem) {
+        puts("Out of memory ... can not get UUID.");
+        return -12;
+    }
+    buf = (uint8_t *)(((uint64_t)mem + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1));
+    memset(buf, 0, PAGE_SIZE);
+
+    /* Get SYSIB 3.2.2 */
+    r0 = (3 << 28) | 2;
+    r1 = 2;
+    asm volatile(" stsi 0(%2)\n" : : "d" (r0), "d" (r1), "a" (buf)
+                 : "cc", "memory");
+
+    for (i = 0; i < 16; i++) {
+        uuid[i] = buf[8 * 4 + 12 * 4 + i];
+        chk |= uuid[i];
+    }
+
+    free(mem);
+
+    return chk ? 0 : -1;
+}
+
 /* This structure holds the data from one pxelinux.cfg file entry */
 struct lkia {
     const char *label;
@@ -403,6 +434,7 @@ static int net_try_pxelinux_cfgs(filename_ip_t *fn_ip)
     int rc, idx;
     char basedir[256];
     int has_basedir;
+    uint8_t uuid[16];
 
     cfgbuf[sizeof(cfgbuf) - 1] = 0;   /* Make sure that it is NUL-terminated */
 
@@ -419,6 +451,19 @@ static int net_try_pxelinux_cfgs(filename_ip_t *fn_ip)
 
     printf("Trying pxelinux.cfg files...\n");
 
+    /* Try to load config file with name based on the VM UUID */
+    if (get_uuid(uuid) == 0) {
+        sprintf((char *)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 = tftp_load(fn_ip, cfgbuf, sizeof(cfgbuf) - 1);
+        if (rc > 0) {
+            return handle_pxelinux_cfg(fn_ip, cfgbuf, sizeof(cfgbuf));
+        }
+    }
+
     /* Look for config file with MAC address in its name */
     sprintf((char *)fn_ip->filename, "%s%02x-%02x-%02x-%02x-%02x-%02x",
             basedir, mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* Re: [Qemu-devel] [PATCH v2 2/4] pc-bios/s390-ccw/net: Add support for pxelinux-style config files
  2018-04-23  7:58 ` [Qemu-devel] [PATCH v2 2/4] pc-bios/s390-ccw/net: Add support for pxelinux-style config files Thomas Huth
@ 2018-04-24 11:07   ` Viktor VM Mihajlovski
  2018-04-24 11:23     ` Thomas Huth
  2018-04-24 13:41   ` Viktor VM Mihajlovski
  1 sibling, 1 reply; 11+ messages in thread
From: Viktor VM Mihajlovski @ 2018-04-24 11:07 UTC (permalink / raw)
  To: Thomas Huth, Christian Borntraeger, qemu-s390x
  Cc: Cornelia Huck, qemu-devel, Collin Walling, Farhan Ali

On 23.04.2018 09:58, Thomas Huth wrote:
> Since it is quite cumbersome to manually create a combined kernel with
> initrd image for network booting, we now support loading via pxelinux
> configuration files, too. In these files, the kernel, initrd and command
> line parameters can be specified seperately, and the firmware then takes
> care of glueing everything together in memory after the files have been
> downloaded.
> 
> The user can either specify a config file directly as bootfile via DHCP
> (but in this case, the file has to start either with "default" or a "#"
> comment so we can distinguish it from binary kernels), or a folder (i.e.
> the bootfile name must end with "/") where the firmware should look for
> the typical pxelinux.cfg file names based on MAC or IP address. If no
> direct file or folder has been specified, we still look for certain
> files in the default "pxelinux.cfg/" folder, but omit some of the file
> names to avoid to download x86 config files here by mistake.
I don't think this is necessary, since the DHCP server configuration
SHOULD take into consideration the processor architecture. In fact it is
even annoying and hard to understand that an attempt is made to load the
uuid, mac and "full ip" based config files but not the "abbreviated ip"
or default file. After all, even if the config file for x86 was loaded,
the effect will be that the network boot fails (as it does now).
> 
> Signed-off-by: Thomas Huth <thuth@redhat.com>
> ---
>  pc-bios/s390-ccw/netboot.mak |   5 +-
>  pc-bios/s390-ccw/netmain.c   | 225 +++++++++++++++++++++++++++++++++++++++++--
>  2 files changed, 222 insertions(+), 8 deletions(-)
> 
[...]
-- 
Regards,
  Viktor Mihajlovski

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [Qemu-devel] [PATCH v2 2/4] pc-bios/s390-ccw/net: Add support for pxelinux-style config files
  2018-04-24 11:07   ` Viktor VM Mihajlovski
@ 2018-04-24 11:23     ` Thomas Huth
  2018-04-24 12:19       ` Viktor VM Mihajlovski
  0 siblings, 1 reply; 11+ messages in thread
From: Thomas Huth @ 2018-04-24 11:23 UTC (permalink / raw)
  To: Viktor VM Mihajlovski, Christian Borntraeger, qemu-s390x
  Cc: Cornelia Huck, qemu-devel, Collin Walling, Farhan Ali

On 24.04.2018 13:07, Viktor VM Mihajlovski wrote:
> On 23.04.2018 09:58, Thomas Huth wrote:
>> Since it is quite cumbersome to manually create a combined kernel with
>> initrd image for network booting, we now support loading via pxelinux
>> configuration files, too. In these files, the kernel, initrd and command
>> line parameters can be specified seperately, and the firmware then takes
>> care of glueing everything together in memory after the files have been
>> downloaded.
>>
>> The user can either specify a config file directly as bootfile via DHCP
>> (but in this case, the file has to start either with "default" or a "#"
>> comment so we can distinguish it from binary kernels), or a folder (i.e.
>> the bootfile name must end with "/") where the firmware should look for
>> the typical pxelinux.cfg file names based on MAC or IP address. If no
>> direct file or folder has been specified, we still look for certain
>> files in the default "pxelinux.cfg/" folder, but omit some of the file
>> names to avoid to download x86 config files here by mistake.
> I don't think this is necessary, since the DHCP server configuration
> SHOULD take into consideration the processor architecture. In fact it is
> even annoying and hard to understand that an attempt is made to load the
> uuid, mac and "full ip" based config files but not the "abbreviated ip"
> or default file.

If the DHCP server has been been properly configured to take the
processor architecture into account, there should be a usable entry in
the bootfile (i.e. either a binary, a config file or a folder where
config files should be probed). So in this case the skipping does not
take place.

And if you want the full probing in the pxelinux.cfg/ directory, you can
also specify "pxelinux.xfg/" in the bootfile entry.

The skipping only happens if there is no valid entry in the bootfile,
i.e. the server configuration was likely wrong anyway, and we just do
some desperate final guesses with the default "pxelinux.cfg/" directory
before giving up.

> After all, even if the config file for x86 was loaded,
> the effect will be that the network boot fails (as it does now).

Ok, that's true, too.

Actually, I don't mind too much whether we probe the files based on the
partial IP address or the "default" name, or whether we skip them. I
thought it might be a good idea to avoid a potential clash with x86
files, but if you think that this is rather confusing, I also see your
point. So I'd say let's wait for some more opinions from others before
we decide about the final behavior...

 Thomas

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [Qemu-devel] [PATCH v2 2/4] pc-bios/s390-ccw/net: Add support for pxelinux-style config files
  2018-04-24 11:23     ` Thomas Huth
@ 2018-04-24 12:19       ` Viktor VM Mihajlovski
  0 siblings, 0 replies; 11+ messages in thread
From: Viktor VM Mihajlovski @ 2018-04-24 12:19 UTC (permalink / raw)
  To: Thomas Huth, Christian Borntraeger, qemu-s390x
  Cc: Cornelia Huck, qemu-devel, Collin Walling, Farhan Ali

On 24.04.2018 13:23, Thomas Huth wrote:
> On 24.04.2018 13:07, Viktor VM Mihajlovski wrote:
>> On 23.04.2018 09:58, Thomas Huth wrote:
>>> Since it is quite cumbersome to manually create a combined kernel with
>>> initrd image for network booting, we now support loading via pxelinux
>>> configuration files, too. In these files, the kernel, initrd and command
>>> line parameters can be specified seperately, and the firmware then takes
>>> care of glueing everything together in memory after the files have been
>>> downloaded.
>>>
>>> The user can either specify a config file directly as bootfile via DHCP
>>> (but in this case, the file has to start either with "default" or a "#"
>>> comment so we can distinguish it from binary kernels), or a folder (i.e.
>>> the bootfile name must end with "/") where the firmware should look for
>>> the typical pxelinux.cfg file names based on MAC or IP address. If no
>>> direct file or folder has been specified, we still look for certain
>>> files in the default "pxelinux.cfg/" folder, but omit some of the file
>>> names to avoid to download x86 config files here by mistake.
>> I don't think this is necessary, since the DHCP server configuration
>> SHOULD take into consideration the processor architecture. In fact it is
>> even annoying and hard to understand that an attempt is made to load the
>> uuid, mac and "full ip" based config files but not the "abbreviated ip"
>> or default file.
> 
> If the DHCP server has been been properly configured to take the
> processor architecture into account, there should be a usable entry in
> the bootfile (i.e. either a binary, a config file or a folder where
> config files should be probed). So in this case the skipping does not
> take place.
> 
> And if you want the full probing in the pxelinux.cfg/ directory, you can
> also specify "pxelinux.xfg/" in the bootfile entry.
> 
> The skipping only happens if there is no valid entry in the bootfile,
> i.e. the server configuration was likely wrong anyway, and we just do
> some desperate final guesses with the default "pxelinux.cfg/" directory
> before giving up.
> 
My major concern is consistency. The emergency probing is different from
the normal one and this can be hell to debug (it took me a while to
understand what went wrong[1]).
I like the idea to improve the usability by doing a wild guess, but only
if it is consistent with the regular behavior.
>> After all, even if the config file for x86 was loaded,
>> the effect will be that the network boot fails (as it does now).
> 
> Ok, that's true, too.
> 
> Actually, I don't mind too much whether we probe the files based on the
> partial IP address or the "default" name, or whether we skip them. I
> thought it might be a good idea to avoid a potential clash with x86
> files, but if you think that this is rather confusing, I also see your
> point. So I'd say let's wait for some more opinions from others before
> we decide about the final behavior...
> 
>  Thomas
> 

[1] What I did was to keep my previous pxelinux configuration but delete
the pxelinux.0 file on the server to force the built-in processing.

-- 
Regards,
  Viktor Mihajlovski

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [Qemu-devel] [PATCH v2 2/4] pc-bios/s390-ccw/net: Add support for pxelinux-style config files
  2018-04-23  7:58 ` [Qemu-devel] [PATCH v2 2/4] pc-bios/s390-ccw/net: Add support for pxelinux-style config files Thomas Huth
  2018-04-24 11:07   ` Viktor VM Mihajlovski
@ 2018-04-24 13:41   ` Viktor VM Mihajlovski
  2018-04-24 14:13     ` Thomas Huth
  1 sibling, 1 reply; 11+ messages in thread
From: Viktor VM Mihajlovski @ 2018-04-24 13:41 UTC (permalink / raw)
  To: Thomas Huth, Christian Borntraeger, qemu-s390x
  Cc: Cornelia Huck, qemu-devel, Collin Walling, Farhan Ali

On 23.04.2018 09:58, Thomas Huth wrote:
[...]
> +
> +static int net_try_pxelinux_cfgs(filename_ip_t *fn_ip)
> +{
> +    int rc, idx;
> +    char basedir[256];
> +    int has_basedir;
> +
> +    cfgbuf[sizeof(cfgbuf) - 1] = 0;   /* Make sure that it is NUL-terminated */
> +
> +    /* Did we get a usable base directory via DHCP? */
> +    idx = strlen((char *)fn_ip->filename);
> +    if (idx > 0 && idx < sizeof(basedir) - 40 &&
> +        fn_ip->filename[idx - 1] == '/') {
> +        has_basedir = true;
> +        strcpy(basedir, (char *)fn_ip->filename);
> +    } else {
> +        has_basedir = false;
> +        strcpy(basedir, "pxelinux.cfg/");
> +    }
> +
> +    printf("Trying pxelinux.cfg files...\n");
> +
> +    /* Look for config file with MAC address in its name */
> +    sprintf((char *)fn_ip->filename, "%s%02x-%02x-%02x-%02x-%02x-%02x",
> +            basedir, mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
Just noticed that the filename has to be <basedir>/pxelinux.cfg/01-<mac>
per [1].
> +    rc = tftp_load(fn_ip, cfgbuf, sizeof(cfgbuf) - 1);
> +    if (rc > 0) {
> +        return handle_pxelinux_cfg(fn_ip, cfgbuf, sizeof(cfgbuf));
> +    }
> +
> +    /* Look for config file with IP address in its name */
> +    if (ip_version == 4) {
> +        for (idx = 0; (has_basedir && idx <= 7) || idx < 1; idx++) {
> +            sprintf((char *)fn_ip->filename, "%s%02X%02X%02X%02X", basedir,
> +                    (fn_ip->own_ip >> 24) & 0xff, (fn_ip->own_ip >> 16) & 0xff,
> +                    (fn_ip->own_ip >> 8) & 0xff, fn_ip->own_ip & 0xff);
> +            fn_ip->filename[strlen((char *)fn_ip->filename) - idx] = 0;
> +            rc = tftp_load(fn_ip, cfgbuf, sizeof(cfgbuf) - 1);
> +            if (rc > 0) {
> +                return handle_pxelinux_cfg(fn_ip, cfgbuf, sizeof(cfgbuf));
> +            }
> +        }
> +    }
> +
> +    /* Try "default" config file */
> +    if (has_basedir) {
> +        sprintf((char *)fn_ip->filename, "%sdefault", basedir);
> +        rc = tftp_load(fn_ip, cfgbuf, sizeof(cfgbuf) - 1);
> +        if (rc > 0) {
> +            return handle_pxelinux_cfg(fn_ip, cfgbuf, sizeof(cfgbuf));
> +        }
> +    }
> +
> +    return -1;
> +}
> +
[...]

[1
]https://www.syslinux.org/wiki/index.php?title=PXELINUX#Configuration_filename

-- 
Regards,
  Viktor Mihajlovski

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [Qemu-devel] [PATCH v2 2/4] pc-bios/s390-ccw/net: Add support for pxelinux-style config files
  2018-04-24 13:41   ` Viktor VM Mihajlovski
@ 2018-04-24 14:13     ` Thomas Huth
  0 siblings, 0 replies; 11+ messages in thread
From: Thomas Huth @ 2018-04-24 14:13 UTC (permalink / raw)
  To: Viktor VM Mihajlovski, Christian Borntraeger, qemu-s390x
  Cc: Cornelia Huck, qemu-devel, Collin Walling, Farhan Ali

On 24.04.2018 15:41, Viktor VM Mihajlovski wrote:
> On 23.04.2018 09:58, Thomas Huth wrote:
> [...]
>> +
>> +static int net_try_pxelinux_cfgs(filename_ip_t *fn_ip)
>> +{
>> +    int rc, idx;
>> +    char basedir[256];
>> +    int has_basedir;
>> +
>> +    cfgbuf[sizeof(cfgbuf) - 1] = 0;   /* Make sure that it is NUL-terminated */
>> +
>> +    /* Did we get a usable base directory via DHCP? */
>> +    idx = strlen((char *)fn_ip->filename);
>> +    if (idx > 0 && idx < sizeof(basedir) - 40 &&
>> +        fn_ip->filename[idx - 1] == '/') {
>> +        has_basedir = true;
>> +        strcpy(basedir, (char *)fn_ip->filename);
>> +    } else {
>> +        has_basedir = false;
>> +        strcpy(basedir, "pxelinux.cfg/");
>> +    }
>> +
>> +    printf("Trying pxelinux.cfg files...\n");
>> +
>> +    /* Look for config file with MAC address in its name */
>> +    sprintf((char *)fn_ip->filename, "%s%02x-%02x-%02x-%02x-%02x-%02x",
>> +            basedir, mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
> Just noticed that the filename has to be <basedir>/pxelinux.cfg/01-<mac>
> per [1].

Ok. I just also had a closer look at the URL that you've mentioned on
IRC (http://jk.ozlabs.org/blog/post/158/netbooting-petitboot/), and
noticed that there is even an additional DHCP option (210) for
specifying the prefix path ... so I'll try to rework my patches accordingly.

 Thomas

^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2018-04-24 14:13 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-04-23  7:58 [Qemu-devel] [PATCH v2 0/4] pc-bios/s390-ccw: Network boot improvements Thomas Huth
2018-04-23  7:58 ` [Qemu-devel] [PATCH v2 1/4] pc-bios/s390-ccw/net: Split up net_load() into init, load and uninit parts Thomas Huth
2018-04-23  7:58 ` [Qemu-devel] [PATCH v2 2/4] pc-bios/s390-ccw/net: Add support for pxelinux-style config files Thomas Huth
2018-04-24 11:07   ` Viktor VM Mihajlovski
2018-04-24 11:23     ` Thomas Huth
2018-04-24 12:19       ` Viktor VM Mihajlovski
2018-04-24 13:41   ` Viktor VM Mihajlovski
2018-04-24 14:13     ` Thomas Huth
2018-04-23  7:58 ` [Qemu-devel] [PATCH v2 3/4] pc-bios/s390-ccw/net: Add support for .INS " Thomas Huth
2018-04-23  7:58 ` [Qemu-devel] [PATCH v2 4/4] pc-bios/s390-ccw/net: Use diag308 to reset machine before jumping to the OS Thomas Huth
2018-04-23 14:55 ` [Qemu-devel] [PATCH v2 5/4] pc-bios/s390-ccw/net: Try to load pxelinux.cfg file accoring to the UUID Thomas Huth

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.