I'm trying to run ndb/dns in a separate namespace so that I can use it to forward requests (in the namespace) to another DNS server. Recently, ndb/dns was updated to use /srv instead of '#s', which is necessary to keep it separate from the primary devsrv. srv(3) states I can clone /srv and access that in two ways, via /srv/id or directly using srvspec: bind -c #s$srvspec /srv /srv/clone /srv/id/... /srv/service1 /srv/service2 The functionality is explained near the end of the man page: Opening the clone file allocates a new service directory. Reading clone returns the id of the new directory. This new service directory can then be accessed at /srv/id. Directo- ries are recursive; each new service directory contains its own clone file and sub-directories. Directories can be walked from the root such as #s/id1/id2/id3 which makes them globally addressable. As a convention, /lib/namespace accepts the path to the service directory from the environ- ment variable $srvspec, making it possible to start a new namespace using a specific service directory as a starting point. If I do: cpu% cat /srv/clone 15cpu% I get a new id. I expected to be able to go to the clone using /srv/15, but that is not available: cpu% lc /srv/15 ls: /srv/15: '/srv/15' file does not exist I can, however, specify the srvspec to (supposedly) bind to a new service directtory: cpu% srvspec=`{cat /srv/clone} bind -c '#s'^$srvspec /srv cpu% Yet I would have expected this cloned service directory to be disassociated from its parents so that manipulating it would not affect the parent. Right now, that is not the case. If I rm /srv/dns', after cloning the service directory, it is reflected across all namespaces. Is this a feature that hasn't been implemented? Am I misunderstanding how it's meant to work?
On 3/29/23 11:45, unobe@cpan.org wrote:
> I'm trying to run ndb/dns in a separate namespace so that I can use it
> to forward requests (in the namespace) to another DNS server.
> Recently, ndb/dns was updated to use /srv instead of '#s', which is
> necessary to keep it separate from the primary devsrv. srv(3) states
> I can clone /srv and access that in two ways, via /srv/id or directly
> using srvspec:
>
> bind -c #s$srvspec /srv
>
> /srv/clone
> /srv/id/...
> /srv/service1
> /srv/service2
>
> The functionality is explained near the end of the man page:
> Opening the clone file allocates a new service directory.
> Reading clone returns the id of the new directory. This new
> service directory can then be accessed at /srv/id. Directo-
> ries are recursive; each new service directory contains its
> own clone file and sub-directories. Directories can be
> walked from the root such as #s/id1/id2/id3 which makes them
> globally addressable. As a convention, /lib/namespace
> accepts the path to the service directory from the environ-
> ment variable $srvspec, making it possible to start a new
> namespace using a specific service directory as a starting
> point.
>
> If I do:
> cpu% cat /srv/clone
> 15cpu%
>
> I get a new id. I expected to be able to go to the clone using
> /srv/15, but that is not available:
> cpu% lc /srv/15
> ls: /srv/15: '/srv/15' file does not exist
>
> I can, however, specify the srvspec to (supposedly) bind to a new
> service directtory:
> cpu% srvspec=`{cat /srv/clone} bind -c '#s'^$srvspec /srv
> cpu%
>
> Yet I would have expected this cloned service directory to be
> disassociated from its parents so that manipulating it would not
> affect the parent. Right now, that is not the case. If I rm
> /srv/dns', after cloning the service directory, it is reflected across
> all namespaces. Is this a feature that hasn't been implemented? Am I
> misunderstanding how it's meant to work?
>
Yes, clone works like how it does in /net, the board is only open for as long
as you have the fd open. So you cat'd it which opened it, read the new id, then closed
it deallocating the child srv. You need to keep the fd open for the length of time you
use the child srv, Or if you wish to 'pin' the child srv you can stash the clone fd itself
as a file in the child srv. This will keep the child srv around until you remove the pinned
clone fd.
Quoth Jacob Moody <moody@mail.posixcafe.org>:
> On 3/29/23 11:45, unobe@cpan.org wrote:
> > I'm trying to run ndb/dns in a separate namespace so that I can use it
> > to forward requests (in the namespace) to another DNS server.
> > Recently, ndb/dns was updated to use /srv instead of '#s', which is
> > necessary to keep it separate from the primary devsrv. srv(3) states
> > I can clone /srv and access that in two ways, via /srv/id or directly
> > using srvspec:
> >
> > bind -c #s$srvspec /srv
> >
> > /srv/clone
> > /srv/id/...
> > /srv/service1
> > /srv/service2
> >
> > The functionality is explained near the end of the man page:
> > Opening the clone file allocates a new service directory.
> > Reading clone returns the id of the new directory. This new
> > service directory can then be accessed at /srv/id. Directo-
> > ries are recursive; each new service directory contains its
> > own clone file and sub-directories. Directories can be
> > walked from the root such as #s/id1/id2/id3 which makes them
> > globally addressable. As a convention, /lib/namespace
> > accepts the path to the service directory from the environ-
> > ment variable $srvspec, making it possible to start a new
> > namespace using a specific service directory as a starting
> > point.
> >
> > If I do:
> > cpu% cat /srv/clone
> > 15cpu%
> >
> > I get a new id. I expected to be able to go to the clone using
> > /srv/15, but that is not available:
> > cpu% lc /srv/15
> > ls: /srv/15: '/srv/15' file does not exist
> >
> > I can, however, specify the srvspec to (supposedly) bind to a new
> > service directtory:
> > cpu% srvspec=`{cat /srv/clone} bind -c '#s'^$srvspec /srv
> > cpu%
> >
> > Yet I would have expected this cloned service directory to be
> > disassociated from its parents so that manipulating it would not
> > affect the parent. Right now, that is not the case. If I rm
> > /srv/dns', after cloning the service directory, it is reflected across
> > all namespaces. Is this a feature that hasn't been implemented? Am I
> > misunderstanding how it's meant to work?
> >
>
> Yes, clone works like how it does in /net, the board is only open for as long
> as you have the fd open. So you cat'd it which opened it, read the new id, then closed
> it deallocating the child srv. You need to keep the fd open for the length of time you
> use the child srv, Or if you wish to 'pin' the child srv you can stash the clone fd itself
> as a file in the child srv. This will keep the child srv around until you remove the pinned
> clone fd.
>
for an example of how it's used on shithub:
<[3]/srv/clone{
d=`{<[0=3]read}
bind /srv/$d /srv
# ugly, but we don't want to leak the clone fd into
# procs that may stick around, so write over fd3 again
<[3=0]{
rfork n
bind /usr/web /mnt/static
execfs -m /usr/web /sys/lib/tcp80/gitrules
bind /mnt/static /usr/web/static
rfork n
cd /
exec /bin/tcp80
}
}
Quoth ori@eigenstate.org: > Quoth Jacob Moody <moody@mail.posixcafe.org>: > > Yes, clone works like how it does in /net, the board is only open for as long > > as you have the fd open. So you cat'd it which opened it, read the new id, then closed > > it deallocating the child srv. You need to keep the fd open for the length of time you > > use the child srv, Or if you wish to 'pin' the child srv you can stash the clone fd itself > > as a file in the child srv. This will keep the child srv around until you remove the pinned > > clone fd. Thank you Moody. I'm still misunderstanding something because I would have that: bind -c '#s20' /srv when /srv/20 isn't available would have failed somehow, since the man page states: As a convention, /lib/namespace accepts the path to the service directory from the environ- ment variable $srvspec, making it possible to start a new namespace using a specific service directory as a starting point. But for comparison, this has no failure either: bind '#l20' /net so I still need to wrap my head around something. > for an example of how it's used on shithub: > > <[3]/srv/clone{ > d=`{<[0=3]read} > bind /srv/$d /srv > # ugly, but we don't want to leak the clone fd into > # procs that may stick around, so write over fd3 again > <[3=0]{ > rfork n > bind /usr/web /mnt/static > execfs -m /usr/web /sys/lib/tcp80/gitrules > bind /mnt/static /usr/web/static > rfork n > cd / > exec /bin/tcp80 > } > } > Thank you Ori, that was very helpful. I was surprised to see that the file is left open when there's an rc error: cpu% lc /srv acme.glenn.3372 cons hjfs.cmd rio.glenn.504 acme.glenn.908 cs mntexport rio.glenn.836 boot dns pin-glenn slashmnt clone factotum plumb.glenn.495 slashn cpu% </srv/clone { d=`{<f} } /fd/0:2: < can't open: f: 'f' not found cpu% lc /srv 36/ cons mntexport slashmnt acme.glenn.3372 cs pin-glenn slashn acme.glenn.908 dns plumb.glenn.495 boot factotum rio.glenn.504 clone hjfs.cmd rio.glenn.836 cpu% bind -c '#s36' /srv cpu% lc /srv 36/ cons mntexport slashmnt acme.glenn.3372 cs pin-glenn slashn acme.glenn.908 dns plumb.glenn.495 boot factotum rio.glenn.504 clone hjfs.cmd rio.glenn.836 cpu% bind -c '#s'/36 /srv cpu% lc /srv clone When the window is closed, then 36/ finally is cleaned up.
On 3/29/23 14:15, unobe@cpan.org wrote: > Quoth ori@eigenstate.org: >> Quoth Jacob Moody <moody@mail.posixcafe.org>: >>> Yes, clone works like how it does in /net, the board is only open for as long >>> as you have the fd open. So you cat'd it which opened it, read the new id, then closed >>> it deallocating the child srv. You need to keep the fd open for the length of time you >>> use the child srv, Or if you wish to 'pin' the child srv you can stash the clone fd itself >>> as a file in the child srv. This will keep the child srv around until you remove the pinned >>> clone fd. > > Thank you Moody. I'm still misunderstanding something because I would have that: > bind -c '#s20' /srv > when /srv/20 isn't available would have failed somehow, since the man page states: > As a convention, /lib/namespace > accepts the path to the service directory from the environ- > ment variable $srvspec, making it possible to start a new > namespace using a specific service directory as a starting > point. > > But for comparison, this has no failure either: > bind '#l20' /net > so I still need to wrap my head around something. #s20 and $s/20 are different things. The first is an attach argument, the second is access the sub directory 20. > >> for an example of how it's used on shithub: >> >> <[3]/srv/clone{ >> d=`{<[0=3]read} >> bind /srv/$d /srv >> # ugly, but we don't want to leak the clone fd into >> # procs that may stick around, so write over fd3 again >> <[3=0]{ >> rfork n >> bind /usr/web /mnt/static >> execfs -m /usr/web /sys/lib/tcp80/gitrules >> bind /mnt/static /usr/web/static >> rfork n >> cd / >> exec /bin/tcp80 >> } >> } >> > > Thank you Ori, that was very helpful. I was surprised to see that the > file is left open when there's an rc error: > cpu% lc /srv > acme.glenn.3372 cons hjfs.cmd rio.glenn.504 > acme.glenn.908 cs mntexport rio.glenn.836 > boot dns pin-glenn slashmnt > clone factotum plumb.glenn.495 slashn > cpu% </srv/clone { d=`{<f} } > /fd/0:2: < can't open: f: 'f' not found > cpu% lc /srv > 36/ cons mntexport slashmnt > acme.glenn.3372 cs pin-glenn slashn > acme.glenn.908 dns plumb.glenn.495 > boot factotum rio.glenn.504 > clone hjfs.cmd rio.glenn.836 > cpu% bind -c '#s36' /srv > cpu% lc /srv > 36/ cons mntexport slashmnt > acme.glenn.3372 cs pin-glenn slashn > acme.glenn.908 dns plumb.glenn.495 > boot factotum rio.glenn.504 > clone hjfs.cmd rio.glenn.836 > cpu% bind -c '#s'/36 /srv > cpu% lc /srv > clone > > When the window is closed, then 36/ finally is cleaned up. > > This seems like an rc bug that is leaking the file descriptor.