[PATCH] gnu: Handle nfs-root device strings.

  • Done
  • quality assurance status badge
Details
3 participants
  • Danny Milosavljevic
  • Ludovic Courtès
  • Stefan
Owner
unassigned
Submitted by
Stefan
Severity
normal
S
S
Stefan wrote on 5 Sep 2020 13:26
(address . guix-patches@gnu.org)
4D0B1280-3FB5-48E5-B985-24773F966618@vodafonemail.de
* gnu/bootloader/grub.scm (grub-root-search): Suppor nfs-root device strings to
set the root to tftp.
* gnu/build/file-systems.scm (canonicalize-device-spec): Support nfs-root device
strings.
* gnu/build/linux-boot.scm (device-string->file-system-device): Support nfs-root
device strings.
* gnu/machine/ssh.scm (machine-check-file-system-availability): Avoid checking
of nfs file systems as in guix/scripts/system.scm.
* gnu/system.scm (read-boot-parameters, device-sexp->device): Support nfs-root
device strings.

---
gnu/bootloader/grub.scm | 3 +++
gnu/build/file-systems.scm | 3 ++-
gnu/build/linux-boot.scm | 5 +++--
gnu/machine/ssh.scm | 2 ++
gnu/system.scm | 12 +++++++-----
5 files changed, 17 insertions(+), 8 deletions(-)

Toggle diff (83 lines)
diff --git a/gnu/bootloader/grub.scm b/gnu/bootloader/grub.scm
index b905ae360c..b3efcfa1db 100644
--- a/gnu/bootloader/grub.scm
+++ b/gnu/bootloader/grub.scm
@@ -295,6 +295,9 @@ code."
((? file-system-label? label)
(format #f "search --label --set ~a"
(file-system-label->string label)))
+ ((? (lambda (device)
+ (and (string? device) (string-contains device ":/"))) nfs-uri)
+ "set root=(tftp)")
((or #f (? string?))
#~(format #f "search --file --set ~a" #$file)))))

diff --git a/gnu/build/file-systems.scm b/gnu/build/file-systems.scm
index 4ba1503b9f..734d648575 100644
--- a/gnu/build/file-systems.scm
+++ b/gnu/build/file-systems.scm
@@ -675,7 +675,8 @@ were found."
^L
(define (canonicalize-device-spec spec)
"Return the device name corresponding to SPEC, which can be a <uuid>, a
-<file-system-label>, or a string (typically a /dev file name)."
+<file-system-label>, or a string (typically a /dev file name or an nfs-root
+containing ':/')."
(define max-trials
;; Number of times we retry partition label resolution, 1 second per
;; trial. Note: somebody reported a delay of 16 seconds (!) before their
diff --git a/gnu/build/linux-boot.scm b/gnu/build/linux-boot.scm
index 80fe0cfb9d..32e3536039 100644
--- a/gnu/build/linux-boot.scm
+++ b/gnu/build/linux-boot.scm
@@ -469,9 +469,10 @@ upon error."

(define (device-string->file-system-device device-string)
;; The "--root=SPEC" kernel command-line option always provides a
- ;; string, but the string can represent a device, a UUID, or a
- ;; label. So check for all three.
+ ;; string, but the string can represent a device, an nfs-root, a UUID, or a
+ ;; label. So check for all four.
(cond ((string-prefix? "/" device-string) device-string)
+ ((string-contains device-string ":/") device-string) ; nfs-root
((uuid device-string) => identity)
(else (file-system-label device-string))))

diff --git a/gnu/machine/ssh.scm b/gnu/machine/ssh.scm
index 4e31baa4b9..35b42add48 100644
--- a/gnu/machine/ssh.scm
+++ b/gnu/machine/ssh.scm
@@ -172,6 +172,8 @@ exist on the machine."
(and (file-system-mount? fs)
(not (member (file-system-type fs)
%pseudo-file-system-types))
+ ;; Don't try to validate network file systems.
+ (not (string-prefix? "nfs" (file-system-type fs)))
(not (memq 'bind-mount (file-system-flags fs)))))
(operating-system-file-systems (machine-operating-system machine))))

diff --git a/gnu/system.scm b/gnu/system.scm
index f092df56ce..bdb696fe2e 100644
--- a/gnu/system.scm
+++ b/gnu/system.scm
@@ -316,11 +316,13 @@ file system labels."
((? bytevector? bv) ;old format
(bytevector->uuid bv 'dce))
((? string? device)
- ;; It used to be that we would not distinguish between labels and
- ;; device names. Try to infer the right thing here.
- (if (string-prefix? "/dev/" device)
- device
- (file-system-label device)))))
+ (if (string-contains device ":/")
+ device ; nfs-root
+ ;; It used to be that we would not distinguish between labels and
+ ;; device names. Try to infer the right thing here.
+ (if (string-prefix? "/" device)
+ device
+ (file-system-label device))))))

(match (read port)
(('boot-parameters ('version 0)
--
2.26.0
S
S
Stefan wrote on 6 Sep 2020 13:52
(address . 43219@debbugs.gnu.org)
AF7EB79E-4418-4FBF-8DBD-3EC937ADBC8B@vodafonemail.de
Hi!

I’d like to propose these minimal changes to support an NFS as a root file system.

Currently there are three ways to define the root file system:

• (file-system (device (label …)) …),
• (file-system (device (union …)) …),
• (file-system (device "<string>") …).

The manual does not mention that an NFS is currently not supported as a root file system. However, NFS mounts are possible already with (file-system (type "nfs") (device "<string>") …).

This patch enables users to use an NFS also as a root file system without introducing a new syntax.

I was asked before to introduce an <nfs-share> record to achieve the same. And I did so, see https://debbugs.gnu.org/cgi/bugreport.cgi?bug=41820#20. But due to some other PXE efforts – for which I don’t see progress – that patch got on hold.

However, that <nfs-share> record would brake with the compatibility of how an NFS mount is defined today, and it makes the code much more complex without having a real gain.

I think this minimal patch will not conflict with that other PXE effort. Its only purpose is to enable the use of an NFS as a root file system already today.


Bye

Stefan
D
D
Danny Milosavljevic wrote on 6 Sep 2020 14:21
(name . Stefan)(address . stefan-guix@vodafonemail.de)
20200906142118.092b702e@scratchpost.org
Hello Stefan,

On Sun, 6 Sep 2020 13:52:28 +0200
Stefan <stefan-guix@vodafonemail.de> wrote:

Toggle quote (2 lines)
> I’d like to propose these minimal changes to support an NFS as a root file system.

Thanks!

Toggle quote (8 lines)
> Currently there are three ways to define the root file system:
>
> • (file-system (device (label …)) …),
> • (file-system (device (union …)) …),
> • (file-system (device "<string>") …).
>
> The manual does not mention that an NFS is currently not supported as a root file system. However, NFS mounts are possible already with (file-system (type "nfs") (device "<string>") …).

Yeah.

Toggle quote (2 lines)
> This patch enables users to use an NFS also as a root file system without introducing a new syntax.

That sounds like a good idea.

For the time being, let's just use the string thing for your
functionality--nevermind the <nfs-share> thing for now.

Toggle quote (5 lines)
> I was asked before to introduce an <nfs-share> record to achieve the same
>And I did so, see <https://debbugs.gnu.org/cgi/bugreport.cgi?bug=41820#20>.
>But due to some other PXE efforts – for which I don’t see progress – that
>patch got on hold.

First, I like to apologize for the huge delay in handling this stuff. My
original intent was to let Brice Waegeneire <brice@waegenei.re>, my GSoC intern
for network booting, handle your request--both because he needs it anyway and
because he presumably has more knowledge on network booting. He's missing in
action (no communication at all) and I gave up having Brice do it.
In any case, his GSoC is over.

I will now look at your request on my own. I obtained some Raspberry Pis, a
NAS with TFTP server support out of the box and I made sure I could manipulate
the DHCP server I use on my network, so the next step is to try to actually
use your patchset myself--which I didn't do before (sorry).

I want to note that patches with system tests are processed *much* faster--I
don't think many reviewers would go to those lengths I did (obtaining special
hardware) in order to test contributions--so usually, it would have been
basically stuck forever without system tests.

Thanks for persevering on this feature.

Toggle quote (4 lines)
> However, that <nfs-share> record would brake with the compatibility of how an
>NFS mount is defined today, and it makes the code much more complex without
>having a real gain.

The real gain would be this:

There are a lot of options that one could need (see

Toggle quote (12 lines)
>* <server-ip> (IP address of the NFS server)
>* <root-dir> (name of the directory on the NFS server to mount as /, with %s as format string in order to substitute client IP address)
>* <nfs-options>: port (!), rsize, wsize, timeo, retrans, acregmin, acregmax, acregmin, acregmax, flags (hard, nointr, noposix, cto, ac).

>ip=<client-ip>:<server-ip>:<gw-ip>:<netmask>:<hostname>:<device>:<autoconf>:
> <dns0-ip>:<dns1-ip>:<ntp0-ip>
>
> This parameter tells the kernel how to configure IP addresses of devices
> and also how to set up the IP routing table. It was originally called
> `nfsaddrs', but now the boot-time IP configuration works independently of
> NFS, so it was renamed to `ip' and the old name remained as an alias for
> compatibility reasons.
).

I'm just saying that it will become a record over time anyway. But maybe
it will be something more general for PXE--hard to tell which is better at
this point in time. So nevermind for now.

Toggle quote (3 lines)
> I think this minimal patch will not conflict with that other PXE effort.
>Its only purpose is to enable the use of an NFS as a root file system already today.

Yeah, I agree.

However, I cannot see a patch as attachment to your E-Mail.
-----BEGIN PGP SIGNATURE-----

iQEzBAEBCgAdFiEEds7GsXJ0tGXALbPZ5xo1VCwwuqUFAl9U1D4ACgkQ5xo1VCww
uqV0IAf/UuCPClO5bYmVdQvDGz2Si0tfkHiYHEdiHiPOsqpLE+xeTMGCqPj8pQ2Z
g5Z46qg5OLWODf7fmzSMSEd4EbdrWedbFNmeALGgTi2giEynMXy+Xcs0aKTD4izq
eBIN/oej8XpuaZMBC7RMAuhTb8PgAb6WybqcpemJNCUmwA7a35dpyMvp7t7R5Ft0
Ae7XFCp/t+eH8WRbQeUIg6a8TkzbrtLGiP4PNqHmsF9PkVGP/cxr78rvM6/giyuy
fdYQUVrw4YXdwQ8RiZ3YFygA64XvgfCqUbdpnW6vD/SpuNCE0IAz4fGUbjRemP4F
NAqiwphPD2gr2oGPJxQ6YI18n5q0CQ==
=65XK
-----END PGP SIGNATURE-----


D
D
Danny Milosavljevic wrote on 7 Sep 2020 11:05
Re: [bug#43219] [PATCH] gnu: Handle nfs-root device strings.
(name . Stefan)(address . stefan-guix@vodafonemail.de)(address . 43219@debbugs.gnu.org)
20200907110552.0bdef27e@scratchpost.org
Hi Stefan,

On Sat, 5 Sep 2020 13:26:25 +0200
Stefan <stefan-guix@vodafonemail.de> wrote:

Toggle quote (3 lines)
> * gnu/bootloader/grub.scm (grub-root-search): Suppor nfs-root device strings to
> set the root to tftp.

Why does having a NFS root "device" imply using TFTP?

I can see that it would be nice--but I've been using NFS for many years without
using TFTP.

Toggle quote (4 lines)
> + ((? (lambda (device)
> + (and (string? device) (string-contains device ":/"))) nfs-uri)
> + "set root=(tftp)")

What is that required for in practice?

Pushed all the other hunks except for the one above--for now.

Guix master commit 1c3b709edb8e6248a9a84dde57b27f3fdc997f21.
-----BEGIN PGP SIGNATURE-----

iQEzBAEBCgAdFiEEds7GsXJ0tGXALbPZ5xo1VCwwuqUFAl9V9/AACgkQ5xo1VCww
uqWdMQf+KppdbwedX35/ZxH7VZgLb5kUyKRYlj7lNiOur1vEQAO0bJUH7mp9DkV0
byO5TPo15TyEMJMjTqLTkIIYcpzaKxhJ4L5CaPnmipv5mAlfXNPIkhaLW3oGzCIa
XlE35SF3mt4otkMjpo2NmmBRsKNLtHHbEX9+aUVtpesZyKUEqjjeoSGNtwG2ybvB
ChPph688mBGyHGy9wuRxbL3yjlYpTjDbsHEg5B13wqal0u52Y8qiXoMPMm5hGlO4
QvFmqOf15olUQOgQ2jOzsUUs5lwoAPtEw8zDw5Mw60UvaN2jDD2ta0Yvevf5g+qZ
J+uH3FSAPKog2VVoFu5epqaszEU5AQ==
=5k/g
-----END PGP SIGNATURE-----


S
S
Stefan wrote on 7 Sep 2020 11:32
Fwd: [PATCH] gnu: Handle nfs-root device strings.
(address . 43219@debbugs.gnu.org)
0919615E-841A-429D-A61F-720DD7FED43D@vodafonemail.de
Hi Danny!

Toggle quote (2 lines)
> That sounds like a good idea.

I'm glad to hear this. :-)

Toggle quote (2 lines)
> First, I like to apologize for the huge delay in handling this stuff.

Nevermind.

Toggle quote (7 lines)
> My
> original intent was to let Brice Waegeneire <brice@waegenei.re>, my GSoC intern
> for network booting, handle your request--both because he needs it anyway and
> because he presumably has more knowledge on network booting. He's missing in
> action (no communication at all) and I gave up having Brice do it.
> In any case, his GSoC is over.

That’s a pity.

Toggle quote (10 lines)
> I will now look at your request on my own. I obtained some Raspberry Pis, a
> NAS with TFTP server support out of the box and I made sure I could manipulate
> the DHCP server I use on my network, so the next step is to try to actually
> use your patchset myself--which I didn't do before (sorry).
>
> I want to note that patches with system tests are processed *much* faster--I
> don't think many reviewers would go to those lengths I did (obtaining special
> hardware) in order to test contributions--so usually, it would have been
> basically stuck forever without system tests.

Oh, I would never have expected that. I tried to do a system test, but for aarch64 substitutes where missing (I think basically qemu) and building locally on my small system took days and failed in the end, so I gave up. But please take a look here, it may help: https://debbugs.gnu.org/cgi/bugreport.cgi?bug=41820#17

Toggle quote (2 lines)
> Thanks for persevering on this feature.

Sure, its in my own interest. :-)

Toggle quote (13 lines)
>> However, that <nfs-share> record would brake with the compatibility of how an
>> NFS mount is defined today, and it makes the code much more complex without
>> having a real gain.
>
> The real gain would be this:
>
> There are a lot of options that one could need (see
> https://www.kernel.org/doc/Documentation/filesystems/nfs/nfsroot.txt .

> I'm just saying that it will become a record over time anyway. But maybe
> it will be something more general for PXE--hard to tell which is better at
> this point in time. So nevermind for now.

I know about them and used them before. I agree, a bigger record makes sense. But please consider that these options actually disable the use of an initrd, which brings more complications, as guix currently relies on having an initrd.

Toggle quote (2 lines)
> However, I cannot see a patch as attachment to your E-Mail.

Oh, that was just my initial e-mail generating this ticket yesterday: https://debbugs.gnu.org/cgi/bugreport.cgi?bug=43219#5


Bye

Stefan
S
S
Stefan wrote on 7 Sep 2020 14:50
Re: [bug#43219] [PATCH] gnu: Handle nfs-root device strings.
(name . Danny Milosavljevic)(address . dannym@scratchpost.org)(address . 43219@debbugs.gnu.org)
6354A850-CD6B-43EC-8DFA-3B1F172C935B@vodafonemail.de
Hi Danny!

Toggle quote (8 lines)
>> * gnu/bootloader/grub.scm (grub-root-search): Suppor nfs-root device strings to
>> set the root to tftp.
>
> Why does having a NFS root "device" imply using TFTP?
>
> I can see that it would be nice--but I've been using NFS for many years without
> using TFTP.

True.

If you use an NFS share as the root file system, it’s just very likely that you use a diskless setup.

It is uncommon, that you have some storage device, from which you load the kernel and the initrd, but which is not also your root file system device. Usually the kernel and the initrd are located in the root file system.

But take a closer look at (grub-root-search device file): This function gets a device record or device string, which is expected to contain the file to look for.

If that device string is an NFS share, then GRUB has only two possibilities to access that file: either via TFTP or HTTP. Actually there is no way yet to divide between these two possibilities.

GRUB does not support NFS, and the chance that the searched file on the NFS share is accessible on a local storage as well is very low.

I chose TFTP over HTTP because of this reasons:

• PXE specifies TFTP but seems not to specify HTTP.
• The ‘file’ field inside the DHCP header implies TFTP.
• For BOOTP/DHCPv4 the RFC 2132 defines a TFTP server for option 66.
• U-Boot supports TFTP but not HTTP (important for chain-loading).
• The Raspberry Pi only supports TFTP.

Only with DHCPv6 there is RFC 5970, which specifies option 59 to contain a boot-file-url, which may start with ‘http://’ but also allows ‘tftp://’.

Toggle quote (6 lines)
>> + ((? (lambda (device)
>> + (and (string? device) (string-contains device ":/"))) nfs-uri)
>> + "set root=(tftp)")
>
> What is that required for in practice?

As stated above, (grub-root-search device file) is used to find the device from which to load the file. It normally generates a GRUB search command to specify inside the root variable where to find that file. That the root variable gets set is not obvious from the generated search command. But take a look here, it is the default: https://www.gnu.org/software/grub/manual/grub/grub.html#search.

However, searching for files is not possible via TFTP, so with “set root=(tftp)” we specify not to search for the file, but to assume that it is accessible via TFTP. Beside a “set root=(http)” this is the only way to specify the root, if the device is an NFS share.

However, the grub.cfg is loaded via TFTP as well, so root must be preset to ‘(tftp)’ or even ‘(http)’ due to DHCP options. So omitting the search command could be enough and even allow the use of HTTP.

It could also be possible to keep the ‘search —file’ command, if it does not produce an error.

I’ll check that.

Toggle quote (4 lines)
> Pushed all the other hunks except for the one above--for now.
>
> Guix master commit 1c3b709edb8e6248a9a84dde57b27f3fdc997f21.

Thanks.


Bye

Stefan
D
D
Danny Milosavljevic wrote on 7 Sep 2020 15:33
20200907153302.296bdb5a@scratchpost.org
Pushed "nfs-root-fs" system test--with minimal changes--to guix master as
commit a1a39ed5a46044161a71cbe6931c7e3006a82ecb.
-----BEGIN PGP SIGNATURE-----

iQEzBAEBCgAdFiEEds7GsXJ0tGXALbPZ5xo1VCwwuqUFAl9WNo4ACgkQ5xo1VCww
uqVI2QgAlXwubeH8YibbZyJOjNLhlsgF9soKyX3Bq66W8sE+sah4bjqIs5mBOXaz
mDahEKJq2vMMoQGdEEQIYEfjvScT88nT4WDENDDvXZhAK+z4HQo8y6Ii/qPCwspG
Zp7r9ZuhKZa0qZOGezQdaY8hoSH0gplCMgGsb9yy1nOc3cZhTWi0x4lUO7kmZ7zV
MSVuyj/Pf1tAOCovDDIlG3JbvhM9ElDu/fytEEFwj+YFMSrQi6cJ6raw9ZWK3akg
1+wOvd8D2ISEUO98vjfVoAzqDza4odI08Rv7WvWjJWLVnDdLXsHG+Ud6bLPpzpJO
XFgvKYA4SwaDy+uiy87QRb1n+BhGKw==
=6iYi
-----END PGP SIGNATURE-----


S
S
Stefan wrote on 7 Sep 2020 20:44
(name . Danny Milosavljevic)(address . dannym@scratchpost.org)(address . 43219@debbugs.gnu.org)
6028D7D4-E880-4E45-8D5B-6FDE196809CD@vodafonemail.de
Hi Danny!

Toggle quote (6 lines)
> However, the grub.cfg is loaded via TFTP as well, so root must be preset to ‘(tftp)’ or even ‘(http)’ due to DHCP options. So omitting the search command could be enough and even allow the use of HTTP.
>
> It could also be possible to keep the ‘search —file’ command, if it does not produce an error.
>
> I’ll check that.

I think we should use that change.

+ ((? (lambda (device)
+ (and (string? device) (string-contains device ":/"))) nfs-uri)
+ "set root=(tftp)")

The point is the following: It is possible that GRUB got loaded from a local storage and that the current system is also on a local storage. Then the root variable is set to some ‘(hd0,1)’ or similar.

If you then select to boot an older system generation or a custom menu entry, which is using TFTP and NFS, then the root variable has to be changed to ‘(tftp)’.


Bye

Stefan
S
S
Stefan wrote on 13 Sep 2020 20:30
(name . Danny Milosavljevic)(address . dannym@scratchpost.org)(address . 43219@debbugs.gnu.org)
9ED0EFDA-8A93-4243-9644-BD4DEBE93353@vodafonemail.de
Hi Danny!

Toggle quote (11 lines)
> Why does having a NFS root "device" imply using TFTP?
>
> I can see that it would be nice--but I've been using NFS for many years without
> using TFTP.
>
>> + ((? (lambda (device)
>> + (and (string? device) (string-contains device ":/"))) nfs-uri)
>> + "set root=(tftp)")
>
> What is that required for in practice?

One more remark to this.

If you used an NFS root file system without using TFTP during boot, then certainly your bootloader, the initrd and the kernel where stored locally and have been loaded from disk, not over the network.

In Guix the initrd and the kernel are loaded from the store. If the store is located on a local device, then (grub-root-search) will still load them from that local device, even if the root file system is on an NFS share.

But in Guix its likely that the store is on the same device as the root file system. And if the root file system containing the store is mounted via NFS, then GRUB needs to access the initrd and kernel via network.


Bye

Stefan
L
L
Ludovic Courtès wrote on 5 Oct 2020 10:40
(name . Stefan)(address . stefan-guix@vodafonemail.de)
877ds53w1s.fsf@gnu.org
Hi!

Danny, Stefan: what’s the status of this patch?


Thanks,
Ludo’.

Stefan <stefan-guix@vodafonemail.de> skribis:

Toggle quote (25 lines)
> Hi Danny!
>
>> Why does having a NFS root "device" imply using TFTP?
>>
>> I can see that it would be nice--but I've been using NFS for many years without
>> using TFTP.
>>
>>> + ((? (lambda (device)
>>> + (and (string? device) (string-contains device ":/"))) nfs-uri)
>>> + "set root=(tftp)")
>>
>> What is that required for in practice?
>
> One more remark to this.
>
> If you used an NFS root file system without using TFTP during boot, then certainly your bootloader, the initrd and the kernel where stored locally and have been loaded from disk, not over the network.
>
> In Guix the initrd and the kernel are loaded from the store. If the store is located on a local device, then (grub-root-search) will still load them from that local device, even if the root file system is on an NFS share.
>
> But in Guix its likely that the store is on the same device as the root file system. And if the root file system containing the store is mounted via NFS, then GRUB needs to access the initrd and kernel via network.
>
>
> Bye
>
> Stefan
S
S
Stefan wrote on 5 Oct 2020 18:31
(name . Ludovic Courtès)(address . ludo@gnu.org)
831B1B07-F59A-4636-A57A-F8EBB1C6D5B6@vodafonemail.de
Hi Ludo!

Toggle quote (4 lines)
> Danny, Stefan: what’s the status of this patch?
>
> https://issues.guix.gnu.org/43219

It got committed in two chunks:

1c3b709edb8e6248a9a84dde57b27f3fdc997f21
8c4f1aa85f3844fc8c989e74cef9d269dd30889c

Closing. Thanks for the reminder.


Bye

Stefan
Closed
?
Your comment

This issue is archived.

To comment on this conversation send an email to 43219@debbugs.gnu.org

To respond to this issue using the mumi CLI, first switch to it
mumi current 43219
Then, you may apply the latest patchset in this issue (with sign off)
mumi am -- -s
Or, compose a reply to this issue
mumi compose
Or, send patches to this issue
mumi send-email *.patch