Module Name: src Committed By: martin Date: Fri Sep 27 09:32:22 UTC 2019
Modified Files: src/sys/arch/i386/stand/efiboot [netbsd-9]: boot.c conf.c dev_net.c devopen.c devopen.h Log Message: Pull up following revision(s) (requested by nonaka in ticket #253): sys/arch/i386/stand/efiboot/conf.c: revision 1.3 sys/arch/i386/stand/efiboot/devopen.h: revision 1.5 sys/arch/i386/stand/efiboot/devopen.c: revision 1.8 sys/arch/i386/stand/efiboot/boot.c: revision 1.17 sys/arch/i386/stand/efiboot/dev_net.c: revision 1.3 x86 efiboot: pass a filename to BOOTP and parse a DHCP server provided filename. To generate a diff of this commit: cvs rdiff -u -r1.13.2.2 -r1.13.2.3 src/sys/arch/i386/stand/efiboot/boot.c cvs rdiff -u -r1.2 -r1.2.6.1 src/sys/arch/i386/stand/efiboot/conf.c cvs rdiff -u -r1.2 -r1.2.2.1 src/sys/arch/i386/stand/efiboot/dev_net.c cvs rdiff -u -r1.5.6.1 -r1.5.6.2 src/sys/arch/i386/stand/efiboot/devopen.c cvs rdiff -u -r1.3.6.1 -r1.3.6.2 src/sys/arch/i386/stand/efiboot/devopen.h Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/arch/i386/stand/efiboot/boot.c diff -u src/sys/arch/i386/stand/efiboot/boot.c:1.13.2.2 src/sys/arch/i386/stand/efiboot/boot.c:1.13.2.3 --- src/sys/arch/i386/stand/efiboot/boot.c:1.13.2.2 Tue Sep 17 19:32:00 2019 +++ src/sys/arch/i386/stand/efiboot/boot.c Fri Sep 27 09:32:22 2019 @@ -1,4 +1,4 @@ -/* $NetBSD: boot.c,v 1.13.2.2 2019/09/17 19:32:00 martin Exp $ */ +/* $NetBSD: boot.c,v 1.13.2.3 2019/09/27 09:32:22 martin Exp $ */ /*- * Copyright (c) 2016 Kimihiro Nonaka <non...@netbsd.org> @@ -111,6 +111,7 @@ const struct bootblk_command commands[] { NULL, NULL }, }; +static char *default_fsname; static char *default_devname; static int default_unit, default_partition; static const char *default_filename; @@ -125,8 +126,11 @@ parsebootfile(const char *fname, char ** { const char *col; static char savedevname[MAXDEVNAME+1]; +#if defined(SUPPORT_NFS) || defined(SUPPORT_TFTP) + const struct netboot_fstab *nf; +#endif - *fsname = "ufs"; + *fsname = default_fsname; if (default_part_name == NULL) { *devname = default_devname; } else { @@ -152,6 +156,7 @@ parsebootfile(const char *fname, char ** if (strstr(fname, "NAME=") == fname) { strlcpy(savedevname, fname, devlen + 1); + *fsname = "ufs"; *devname = savedevname; *unit = -1; *partition = -1; @@ -188,6 +193,13 @@ parsebootfile(const char *fname, char ** if (i != devlen) return ENXIO; +#if defined(SUPPORT_NFS) || defined(SUPPORT_TFTP) + nf = netboot_fstab_find(savedevname); + if (nf != NULL) + *fsname = (char *)nf->name; + else +#endif + *fsname = "ufs"; *devname = savedevname; *unit = u; *partition = p; @@ -278,6 +290,9 @@ boot(void) { int currname; int c; +#if defined(SUPPORT_NFS) || defined(SUPPORT_TFTP) + const struct netboot_fstab *nf; +#endif boot_modules_enabled = !(boot_params.bp_flags & X86_BP_FLAGS_NOMODULES); @@ -288,6 +303,14 @@ boot(void) /* if the user types "boot" without filename */ default_filename = DEFFILENAME; +#if defined(SUPPORT_NFS) || defined(SUPPORT_TFTP) + nf = netboot_fstab_find(default_devname); + if (nf != NULL) + default_fsname = (char *)nf->name; + else +#endif + default_fsname = "ufs"; + if (!(boot_params.bp_flags & X86_BP_FLAGS_NOBOOTCONF)) { #ifdef EFIBOOTCFG_FILENAME int rv = EINVAL; @@ -456,7 +479,7 @@ command_dev(char *arg) { static char savedevname[MAXDEVNAME + 1]; char buf[80]; - char *fsname, *devname; + char *devname; const char *file; /* dummy */ if (*arg == '\0') { @@ -474,7 +497,7 @@ command_dev(char *arg) } if (strchr(arg, ':') == NULL || - parsebootfile(arg, &fsname, &devname, &default_unit, + parsebootfile(arg, &default_fsname, &devname, &default_unit, &default_partition, &file)) { command_help(NULL); return; Index: src/sys/arch/i386/stand/efiboot/conf.c diff -u src/sys/arch/i386/stand/efiboot/conf.c:1.2 src/sys/arch/i386/stand/efiboot/conf.c:1.2.6.1 --- src/sys/arch/i386/stand/efiboot/conf.c:1.2 Wed Apr 11 10:32:09 2018 +++ src/sys/arch/i386/stand/efiboot/conf.c Fri Sep 27 09:32:22 2019 @@ -1,4 +1,4 @@ -/* $NetBSD: conf.c,v 1.2 2018/04/11 10:32:09 nonaka Exp $ */ +/* $NetBSD: conf.c,v 1.2.6.1 2019/09/27 09:32:22 martin Exp $ */ /* * Copyright (c) 1997 @@ -54,20 +54,23 @@ #endif #endif #include <biosdisk.h> +#include "devopen.h" #include "efinet.h" struct devsw devsw[] = { { "disk", biosdisk_strategy, biosdisk_open, biosdisk_close, biosdisk_ioctl }, +#if defined(SUPPORT_NFS) || defined(SUPPORT_TFTP) { "net", net_strategy, net_open, net_close, net_ioctl }, +#endif }; int ndevs = __arraycount(devsw); -#if defined(SUPPORT_NFS) || defined(SUPPORT_TFTP) struct netif_driver *netif_drivers[] = { +#if defined(SUPPORT_NFS) || defined(SUPPORT_TFTP) &efinetif, +#endif }; int n_netif_drivers = __arraycount(netif_drivers); -#endif struct fs_ops file_system[] = { #ifdef SUPPORT_CD9660 @@ -113,3 +116,15 @@ struct fs_ops file_system_nfs = FS_OPS(n #ifdef SUPPORT_TFTP struct fs_ops file_system_tftp = FS_OPS(tftp); #endif + +#if defined(SUPPORT_NFS) || defined(SUPPORT_TFTP) +const struct netboot_fstab netboot_fstab[] = { +#ifdef SUPPORT_NFS + { "nfs", &file_system_nfs }, +#endif +#ifdef SUPPORT_TFTP + { "tftp", &file_system_tftp }, +#endif +}; +const int nnetboot_fstab = __arraycount(netboot_fstab); +#endif Index: src/sys/arch/i386/stand/efiboot/dev_net.c diff -u src/sys/arch/i386/stand/efiboot/dev_net.c:1.2 src/sys/arch/i386/stand/efiboot/dev_net.c:1.2.2.1 --- src/sys/arch/i386/stand/efiboot/dev_net.c:1.2 Fri Jul 26 11:30:31 2019 +++ src/sys/arch/i386/stand/efiboot/dev_net.c Fri Sep 27 09:32:22 2019 @@ -1,4 +1,4 @@ -/* $NetBSD: dev_net.c,v 1.2 2019/07/26 11:30:31 nonaka Exp $ */ +/* $NetBSD: dev_net.c,v 1.2.2.1 2019/09/27 09:32:22 martin Exp $ */ /*- * Copyright (c) 1997 The NetBSD Foundation, Inc. @@ -76,23 +76,23 @@ int net_open(struct open_file *f, ...) { va_list ap; - char *devname; /* Device part of file name (or NULL). */ + struct devdesc *dev; int error = 0; va_start(ap, f); - devname = va_arg(ap, char *); + dev = va_arg(ap, struct devdesc *); va_end(ap); #ifdef NETIF_DEBUG if (debug) - printf("%s\n", devname); + printf("%s\n", dev->devname); #endif /* On first open, do netif open, mount, etc. */ if (netdev_opens == 0) { /* Find network interface. */ if (netdev_sock < 0) { - netdev_sock = netif_open(devname); + netdev_sock = netif_open(dev); if (netdev_sock < 0) { printf("netif_open() failed\n"); return ENXIO; Index: src/sys/arch/i386/stand/efiboot/devopen.c diff -u src/sys/arch/i386/stand/efiboot/devopen.c:1.5.6.1 src/sys/arch/i386/stand/efiboot/devopen.c:1.5.6.2 --- src/sys/arch/i386/stand/efiboot/devopen.c:1.5.6.1 Fri Sep 13 07:00:13 2019 +++ src/sys/arch/i386/stand/efiboot/devopen.c Fri Sep 27 09:32:22 2019 @@ -1,4 +1,4 @@ -/* $NetBSD: devopen.c,v 1.5.6.1 2019/09/13 07:00:13 martin Exp $ */ +/* $NetBSD: devopen.c,v 1.5.6.2 2019/09/27 09:32:22 martin Exp $ */ /*- * Copyright (c) 2005 The NetBSD Foundation, Inc. @@ -57,6 +57,7 @@ #include "efiboot.h" #include <lib/libsa/dev_net.h> +#include <lib/libsa/net.h> #include <biosdisk.h> #include "devopen.h" @@ -106,6 +107,40 @@ bios2dev(int biosdev, daddr_t sector, ch } } +#if defined(SUPPORT_NFS) || defined(SUPPORT_TFTP) +const struct netboot_fstab * +netboot_fstab_find(const char *name) +{ + int i; + + if (strcmp(name, "net") == 0) + return &netboot_fstab[0]; + + for (i = 0; i < nnetboot_fstab; i++) { + if (strcmp(name, netboot_fstab[i].name) == 0) + return &netboot_fstab[i]; + } + + return NULL; +} + +static const struct netboot_fstab * +netboot_fstab_findn(const char *name, size_t len) +{ + int i; + + if (strncmp(name, "net", len) == 0) + return &netboot_fstab[0]; + + for (i = 0; i < nnetboot_fstab; i++) { + if (strncmp(name, netboot_fstab[i].name, len) == 0) + return &netboot_fstab[i]; + } + + return NULL; +} +#endif + struct btinfo_bootpath bibp; extern bool kernel_loaded; @@ -115,28 +150,27 @@ extern bool kernel_loaded; int devopen(struct open_file *f, const char *fname, char **file) { -#if defined(SUPPORT_NFS) || defined(SUPPORT_TFTP) - static const char *net_devnames[] = { -#if defined(SUPPORT_NFS) - "nfs", -#endif -#if defined(SUPPORT_TFTP) - "tftp", -#endif - }; -#endif - struct devdesc desc; - struct devsw *dev; char *fsname, *devname; int unit, partition; int biosdev; - int i, n, error; + int i, error; +#if defined(SUPPORT_NFS) || defined(SUPPORT_TFTP) + struct devdesc desc; + const struct netboot_fstab *nf; + char *filename; + size_t fsnamelen; + int n; +#endif error = parsebootfile(fname, &fsname, &devname, &unit, &partition, (const char **) file); if (error) return error; + memcpy(file_system, file_system_disk, + sizeof(struct fs_ops) * nfsys_disk); + nfsys = nfsys_disk; + /* Search by GPT label or raidframe name */ if ((strstr(devname, "NAME=") == devname) || (strstr(devname, "raid") == devname)) { @@ -151,64 +185,99 @@ devopen(struct open_file *f, const char return error; } - memcpy(file_system, file_system_disk, sizeof(*file_system) * nfsys); - nfsys = nfsys_disk; - + /* + * Network + */ #if defined(SUPPORT_NFS) || defined(SUPPORT_TFTP) - for (i = 0; i < __arraycount(net_devnames); i++) { - if (strcmp(devname, net_devnames[i]) == 0) { - fsname = devname; - devname = "net"; - break; + nf = netboot_fstab_find(devname); + if (nf != NULL) { + n = 0; + if (strcmp(devname, "net") == 0) { + for (i = 0; i < nnetboot_fstab; i++) { + memcpy(&file_system[n++], netboot_fstab[i].ops, + sizeof(struct fs_ops)); + } + } else { + memcpy(&file_system[n++], nf->ops, + sizeof(struct fs_ops)); } - } -#endif + nfsys = n; - for (i = 1; i < ndevs; i++) { - dev = &devsw[i]; - if (strcmp(devname, DEV_NAME(dev)) == 0) { - if (strcmp(devname, "net") == 0) { - n = 0; -#if defined(SUPPORT_NFS) - if (strcmp(fsname, "nfs") == 0) { - memcpy(&file_system[n++], &file_system_nfs, - sizeof(file_system_nfs)); - } else -#endif -#if defined(SUPPORT_TFTP) - if (strcmp(fsname, "tftp") == 0) { - memcpy(&file_system[n++], &file_system_tftp, - sizeof(file_system_tftp)); - } else -#endif - { -#if defined(SUPPORT_NFS) - memcpy(&file_system[n++], &file_system_nfs, - sizeof(file_system_nfs)); +#ifdef SUPPORT_BOOTP + try_bootp = 1; #endif -#if defined(SUPPORT_TFTP) - memcpy(&file_system[n++], &file_system_tftp, - sizeof(file_system_tftp)); -#endif - } - nfsys = n; - try_bootp = 1; - } + /* If we got passed a filename, pass it to the BOOTP server. */ + if (fname) { + filename = strchr(fname, ':'); + if (filename != NULL) + filename++; + else + filename = (char *)fname; + strlcpy(bootfile, filename, sizeof(bootfile)); + } - memset(&desc, 0, sizeof(desc)); - strlcpy(desc.d_name, devname, sizeof(desc.d_name)); - desc.d_unit = unit; - - f->f_dev = dev; - if (!kernel_loaded) { - strncpy(bibp.bootpath, *file, - sizeof(bibp.bootpath)); - BI_ADD(&bibp, BTINFO_BOOTPATH, sizeof(bibp)); + memset(&desc, 0, sizeof(desc)); + strlcpy(desc.d_name, "net", sizeof(desc.d_name)); + desc.d_unit = unit; + + f->f_dev = &devsw[1]; /* must be net */ + if (!kernel_loaded) { + strncpy(bibp.bootpath, *file, sizeof(bibp.bootpath)); + BI_ADD(&bibp, BTINFO_BOOTPATH, sizeof(bibp)); + } + error = DEV_OPEN(f->f_dev)(f, &desc); + if (error) + return error; + + /* + * If the DHCP server provided a file name: + * - If it contains a ":", assume it points to a NetBSD kernel. + * - If not, assume that the DHCP server was not able to pass + * a separate filename for the kernel. (The name probably was + * the same as used to load "efiboot".) Ignore it and use + * the default in this case. + * So we cater to simple DHCP servers while being able to use + * the power of conditional behaviour in modern ones. + */ + filename = strchr(bootfile, ':'); + if (filename != NULL) { + fname = bootfile; + + fsnamelen = filename - fname; + nf = netboot_fstab_findn(fname, fsnamelen); + if (nf == NULL || + strncmp(fname, "net", fsnamelen) == 0) { + printf("Invalid file system type specified in " + "%s\n", fname); + error = EINVAL; + goto neterr; } - return DEV_OPEN(f->f_dev)(f, &desc); + + memcpy(file_system, nf->ops, sizeof(struct fs_ops)); + nfsys = 1; } + + filename = fname ? strchr(fname, ':') : NULL; + if (filename != NULL) { + filename++; + if (*filename == '\0') { + printf("No file specified in %s\n", fname); + error = EINVAL; + goto neterr; + } + } else + filename = (char *)fname; + + *file = filename; + return 0; + +neterr: + DEV_CLOSE(f->f_dev)(f); + f->f_dev = NULL; + return error; } +#endif /* * biosdisk Index: src/sys/arch/i386/stand/efiboot/devopen.h diff -u src/sys/arch/i386/stand/efiboot/devopen.h:1.3.6.1 src/sys/arch/i386/stand/efiboot/devopen.h:1.3.6.2 --- src/sys/arch/i386/stand/efiboot/devopen.h:1.3.6.1 Fri Sep 13 07:00:13 2019 +++ src/sys/arch/i386/stand/efiboot/devopen.h Fri Sep 27 09:32:22 2019 @@ -1,4 +1,4 @@ -/* $NetBSD: devopen.h,v 1.3.6.1 2019/09/13 07:00:13 martin Exp $ */ +/* $NetBSD: devopen.h,v 1.3.6.2 2019/09/27 09:32:22 martin Exp $ */ /*- * Copyright (c) 2016 Kimihiro Nonaka <non...@netbsd.org> @@ -42,3 +42,13 @@ struct devdesc { char d_name[MAXDEVNAME]; char d_unit; }; + +struct netboot_fstab { + const char *name; + struct fs_ops *ops; +}; + +extern const struct netboot_fstab netboot_fstab[]; +extern const int nnetboot_fstab; + +const struct netboot_fstab *netboot_fstab_find(const char *);