The branch main has been updated by sjg: URL: https://cgit.FreeBSD.org/src/commit/?id=b44cc1b479fefc8570611309c3f5a6966fb26e3b
commit b44cc1b479fefc8570611309c3f5a6966fb26e3b Author: Simon J. Gerraty <s...@freebsd.org> AuthorDate: 2025-08-20 22:45:54 +0000 Commit: Simon J. Gerraty <s...@freebsd.org> CommitDate: 2025-08-20 22:45:54 +0000 loader: do not try to open directories with TFTP Attempting to mount or even open / with some tftp servers causes a several minute delay in boot. Since opening a directory via TFTP does not make sense, we avoid it. We don't know if using TFTP until after net_open() has been called. Add an is_tftp() accessor to avoid everyone having to include all the net* headers. Sponsored by: Juniper Networks, Inc. Differential Revision: https://reviews.freebsd.org/D51447 --- stand/common/dev_net.c | 9 ++++++++- stand/libsa/mount.c | 5 ++++- stand/libsa/open.c | 8 ++++++++ stand/libsa/stand.h | 3 +++ 4 files changed, 23 insertions(+), 2 deletions(-) diff --git a/stand/common/dev_net.c b/stand/common/dev_net.c index 964fa514cac5..10389db27b99 100644 --- a/stand/common/dev_net.c +++ b/stand/common/dev_net.c @@ -182,6 +182,7 @@ net_open(struct open_file *f, ...) setenv("boot.netif.mtu", mtu, 1); } + DEBUG_PRINTF(1,("%s: netproto=%d\n", __func__, netproto)); } netdev_opens++; dev->d_opendata = &netdev_sock; @@ -193,7 +194,7 @@ net_close(struct open_file *f) { struct devdesc *dev; - DEBUG_PRINTF(1,("%s: opens=%d\n", __func__, netdev_opens)); + DEBUG_PRINTF(2,("%s: opens=%d\n", __func__, netdev_opens)); dev = f->f_devdata; dev->d_opendata = NULL; @@ -344,6 +345,12 @@ net_print(int verbose) return (ret); } +bool +is_tftp(void) +{ + return (netproto == NET_TFTP); +} + /* * Parses the rootpath if present * diff --git a/stand/libsa/mount.c b/stand/libsa/mount.c index 73bf6ab8118c..c866dc9c7055 100644 --- a/stand/libsa/mount.c +++ b/stand/libsa/mount.c @@ -107,7 +107,10 @@ mount(const char *dev, const char *path, int flags __unused, void *data) fs = file_system[i]; if (fs->fo_mount == NULL) continue; - + DEBUG_PRINTF(1,("%s: fs=%s path=%s\n", + __func__, fs->fs_name, path)); + if (is_tftp()) + break; if (fs->fo_mount(dev, path, &data) != 0) continue; diff --git a/stand/libsa/open.c b/stand/libsa/open.c index c97aa5977f9e..91848aca7dbe 100644 --- a/stand/libsa/open.c +++ b/stand/libsa/open.c @@ -138,6 +138,8 @@ open(const char *fname, int mode) struct fs_ops *fs; struct open_file *f; int fd, i, error, besterror; + bool is_dir; + size_t n; const char *file; TSENTER(); @@ -182,8 +184,14 @@ open(const char *fname, int mode) /* pass file name to the different filesystem open routines */ besterror = ENOENT; + n = strlen(file); + is_dir = (n > 0 && file[n - 1] == '/'); for (i = 0; file_system[i] != NULL; i++) { fs = file_system[i]; + if (is_dir && is_tftp()) { + error = EOPNOTSUPP; + goto err; + } error = (fs->fo_open)(file, f); if (error == 0) goto ok; diff --git a/stand/libsa/stand.h b/stand/libsa/stand.h index c6a08be2f7e3..233d11ab3ecb 100644 --- a/stand/libsa/stand.h +++ b/stand/libsa/stand.h @@ -507,6 +507,9 @@ extern void *reallocf(void *, size_t); */ caddr_t ptov(uintptr_t); +/* dev_net.c */ +bool is_tftp(void); + /* features.c */ typedef void (feature_iter_fn)(void *, const char *, const char *, bool);