1010#include "fileio.h"
1111#include "fstab-util.h"
1212#include "generator.h"
13+ #include "in-addr-util.h"
1314#include "log.h"
1415#include "main-func.h"
1516#include "mkdir.h"
@@ -691,6 +692,57 @@ static int parse_fstab(bool initrd) {
691692 return r ;
692693}
693694
695+ static int sysroot_is_nfsroot (void ) {
696+ union in_addr_union u ;
697+ const char * sep , * a ;
698+ int r ;
699+
700+ assert (arg_root_what );
701+
702+ /* From dracut.cmdline(7).
703+ *
704+ * root=[<server-ip>:]<root-dir>[:<nfs-options>]
705+ * root=nfs:[<server-ip>:]<root-dir>[:<nfs-options>],
706+ * root=nfs4:[<server-ip>:]<root-dir>[:<nfs-options>],
707+ * root={dhcp|dhcp6}
708+ *
709+ * mount nfs share from <server-ip>:/<root-dir>, if no server-ip is given, use dhcp next_server.
710+ * If server-ip is an IPv6 address it has to be put in brackets, e.g. [2001:DB8::1]. NFS options
711+ * can be appended with the prefix ":" or "," and are separated by ",". */
712+
713+ if (path_equal (arg_root_what , "/dev/nfs" ) ||
714+ STR_IN_SET (arg_root_what , "dhcp" , "dhcp6" ) ||
715+ STARTSWITH_SET (arg_root_what , "nfs:" , "nfs4:" ))
716+ return true;
717+
718+ /* IPv6 address */
719+ if (arg_root_what [0 ] == '[' ) {
720+ sep = strchr (arg_root_what + 1 , ']' );
721+ if (!sep )
722+ return - EINVAL ;
723+
724+ a = strndupa (arg_root_what + 1 , sep - arg_root_what - 1 );
725+
726+ r = in_addr_from_string (AF_INET6 , a , & u );
727+ if (r < 0 )
728+ return r ;
729+
730+ return true;
731+ }
732+
733+ /* IPv4 address */
734+ sep = strchr (arg_root_what , ':' );
735+ if (sep ) {
736+ a = strndupa (arg_root_what , sep - arg_root_what );
737+
738+ if (in_addr_from_string (AF_INET , a , & u ) >= 0 )
739+ return true;
740+ }
741+
742+ /* root directory without address */
743+ return path_is_absolute (arg_root_what ) && !path_startswith (arg_root_what , "/dev" );
744+ }
745+
694746static int add_sysroot_mount (void ) {
695747 _cleanup_free_ char * what = NULL ;
696748 const char * opts , * fstype ;
@@ -708,9 +760,12 @@ static int add_sysroot_mount(void) {
708760 return 0 ;
709761 }
710762
711- if (path_equal (arg_root_what , "/dev/nfs" )) {
763+ r = sysroot_is_nfsroot ();
764+ if (r < 0 )
765+ log_debug_errno (r , "Failed to determine if the root directory is on NFS, assuming not: %m" );
766+ else if (r > 0 ) {
712767 /* This is handled by the kernel or the initrd */
713- log_debug ("Skipping root directory handling, as /dev/nfs was requested." );
768+ log_debug ("Skipping root directory handling, as root on NFS was requested." );
714769 return 0 ;
715770 }
716771
0 commit comments