code: plan9front

Download patch

ref: 27ad886c956acb71b4165219fcdd54c50b1c7811
parent: a96cf495fa9a315c86c723bd0a0bcd8bffaef42a
author: cinap_lenrek <>
date: Mon Feb 22 20:47:33 EST 2021

ip/tftpd: add -n namespace-file flag (thanks sam-d)

tftpd currently unconditionally sets its namespace via /lib/namespace
(newns("none", nil)), which stymied my attempts to pxe boot the
openbsd installer without creating a real /etc dir on 9front, which
would've been gross.

I tried working around this with -h (and -r for good measure), but
again hit issues because the namespace is rebuilt from scratch -- any
binds of /386, /amd64, /cfg/pxe, etc. into the tftp-specific directory
disappeared from tftpd's namespace and rendered my *9front* boxes
unable to boot. I could maintain copies of the needed files in the
tftp-specific directory, but that'd be kind of a drag.

The following patch adds a -n flag to allow the specification of a
namespace file in place of /lib/namespace; similar to ip/ftpd.

I thought about setting up a /lib/namespace.tftp to act as a default
rather than continuing to use /lib/namespace by default (which
security-wise is about the same as allowing 9p mounts by user none,
which I also have disabled), but I had trouble coming up with a sane
default. Maybe someone more experienced would like to try that out.

- sam-d

--- a/sys/man/8/dhcpd
+++ b/sys/man/8/dhcpd
@@ -42,6 +42,8 @@
 .IR homedir ]
 .RB [ -x
 .IR netmtpt ]
+.RB [ -n
+.IR namespace-file ]
 These programs support booting over the Internet.
 They should all be run on the same server to
@@ -318,6 +320,9 @@
 .B r
 Restricts access to only those files rooted in the
 .IR homedir .
+.B n
+Sets the namespace file (default /lib/namespace).
 .BR /lib/ndb/dhcp "    directory of dynamic address files
--- a/sys/src/cmd/ip/tftpd.c
+++ b/sys/src/cmd/ip/tftpd.c
@@ -93,6 +93,7 @@
 char	*dirsl;
 int	dirsllen;
 char	*homedir = "/";
+char	*nsfile = nil;
 char	flog[] = "ipboot";
 char	net[Maxpath];
@@ -138,6 +139,9 @@
 	case 'x':
 		setnetmtpt(net, sizeof net, EARGF(usage()));
+	case 'n':
+		nsfile = EARGF(usage());
+		break;
@@ -740,7 +744,7 @@
 	if(procsetuser("none") < 0)
 		sysfatal("can't become none: %r");
-	if(newns("none", nil) < 0)
+	if(newns("none", nsfile) < 0)
 		sysfatal("can't build namespace: %r");