@@ -49,6 +49,7 @@ typedef enum MountPointFlags {
4949} MountPointFlags ;
5050
5151typedef struct Mount {
52+ bool for_initrd ;
5253 char * what ;
5354 char * where ;
5455 char * fstype ;
@@ -102,7 +103,13 @@ static void mount_array_free(Mount *mounts, size_t n) {
102103 free (mounts );
103104}
104105
105- static int mount_array_add_internal (char * in_what , char * in_where , const char * in_fstype , const char * in_options ) {
106+ static int mount_array_add_internal (
107+ bool for_initrd ,
108+ char * in_what ,
109+ char * in_where ,
110+ const char * in_fstype ,
111+ const char * in_options ) {
112+
106113 _cleanup_free_ char * what = NULL , * where = NULL , * fstype = NULL , * options = NULL ;
107114 int r ;
108115
@@ -135,6 +142,7 @@ static int mount_array_add_internal(char *in_what, char *in_where, const char *i
135142 return - ENOMEM ;
136143
137144 arg_mounts [arg_n_mounts ++ ] = (Mount ) {
145+ .for_initrd = for_initrd ,
138146 .what = TAKE_PTR (what ),
139147 .where = TAKE_PTR (where ),
140148 .fstype = TAKE_PTR (fstype ),
@@ -144,7 +152,7 @@ static int mount_array_add_internal(char *in_what, char *in_where, const char *i
144152 return 0 ;
145153}
146154
147- static int mount_array_add (const char * str ) {
155+ static int mount_array_add (bool for_initrd , const char * str ) {
148156 _cleanup_free_ char * what = NULL , * where = NULL , * fstype = NULL , * options = NULL ;
149157 int r ;
150158
@@ -159,10 +167,10 @@ static int mount_array_add(const char *str) {
159167 if (!isempty (str ))
160168 return - EINVAL ;
161169
162- return mount_array_add_internal (TAKE_PTR (what ), TAKE_PTR (where ), fstype , options );
170+ return mount_array_add_internal (for_initrd , TAKE_PTR (what ), TAKE_PTR (where ), fstype , options );
163171}
164172
165- static int mount_array_add_swap (const char * str ) {
173+ static int mount_array_add_swap (bool for_initrd , const char * str ) {
166174 _cleanup_free_ char * what = NULL , * options = NULL ;
167175 int r ;
168176
@@ -177,7 +185,7 @@ static int mount_array_add_swap(const char *str) {
177185 if (!isempty (str ))
178186 return - EINVAL ;
179187
180- return mount_array_add_internal (TAKE_PTR (what ), NULL , "swap" , options );
188+ return mount_array_add_internal (for_initrd , TAKE_PTR (what ), NULL , "swap" , options );
181189}
182190
183191static int write_options (FILE * f , const char * options ) {
@@ -306,9 +314,9 @@ static bool mount_is_network(const char *fstype, const char *options) {
306314 (fstype && fstype_is_network (fstype ));
307315}
308316
309- static bool mount_in_initrd (const char * where , const char * options ) {
317+ static bool mount_in_initrd (const char * where , const char * options , bool accept_root ) {
310318 return fstab_test_option (options , "x-initrd.mount\0" ) ||
311- (where && path_equal (where , "/usr" ));
319+ (where && PATH_IN_SET (where , "/usr" , accept_root ? "/" : NULL ));
312320}
313321
314322static int write_timeout (
@@ -801,7 +809,7 @@ static MountPointFlags fstab_options_to_flags(const char *options, bool is_swap)
801809 return flags ;
802810}
803811
804- static int canonicalize_mount_path (const char * path , const char * type , bool initrd , char * * ret ) {
812+ static int canonicalize_mount_path (const char * path , const char * type , bool prefix_sysroot , char * * ret ) {
805813 _cleanup_free_ char * p = NULL ;
806814 bool changed ;
807815 int r ;
@@ -813,11 +821,11 @@ static int canonicalize_mount_path(const char *path, const char *type, bool init
813821
814822 // FIXME: when chase() learns to chase non-existent paths, use this here and drop the prefixing with
815823 // /sysroot on error below.
816- r = chase (path , initrd ? "/sysroot" : NULL , CHASE_PREFIX_ROOT | CHASE_NONEXISTENT , & p , NULL );
824+ r = chase (path , prefix_sysroot ? "/sysroot" : NULL , CHASE_PREFIX_ROOT | CHASE_NONEXISTENT , & p , NULL );
817825 if (r < 0 ) {
818826 log_debug_errno (r , "Failed to chase '%s', using as-is: %m" , path );
819827
820- if (initrd )
828+ if (prefix_sysroot )
821829 p = path_join ("/sysroot" , path );
822830 else
823831 p = strdup (path );
@@ -842,7 +850,8 @@ static int parse_fstab_one(
842850 const char * fstype ,
843851 const char * options ,
844852 int passno ,
845- bool initrd ,
853+ bool prefix_sysroot ,
854+ bool accept_root , /* This takes an effect only when prefix_sysroot is true. */
846855 bool use_swap_enabled ) {
847856
848857 _cleanup_free_ char * what = NULL , * where = NULL ;
@@ -854,7 +863,7 @@ static int parse_fstab_one(
854863 assert (fstype );
855864 assert (options );
856865
857- if (initrd && !mount_in_initrd (where_original , options ))
866+ if (prefix_sysroot && !mount_in_initrd (where_original , options , accept_root ))
858867 return 0 ;
859868
860869 is_swap = streq_ptr (fstype , "swap" );
@@ -891,16 +900,16 @@ static int parse_fstab_one(
891900 * /etc/fstab. So we canonicalize here. Note that we use CHASE_NONEXISTENT to handle the case
892901 * where a symlink refers to another mount target; this works assuming the sub-mountpoint
893902 * target is the final directory. */
894- r = canonicalize_mount_path (where_original , "where" , initrd , & where );
903+ r = canonicalize_mount_path (where_original , "where" , prefix_sysroot , & where );
895904 if (r < 0 )
896905 return r ;
897906 where_changed = r > 0 ;
898907
899- if (initrd && fstab_is_bind (options , fstype )) {
908+ if (prefix_sysroot && fstab_is_bind (options , fstype )) {
900909 /* When in initrd, the source of bind mount needs to be prepended with /sysroot as well. */
901910 _cleanup_free_ char * p = NULL ;
902911
903- r = canonicalize_mount_path (what , "what" , initrd , & p );
912+ r = canonicalize_mount_path (what , "what" , prefix_sysroot , & p );
904913 if (r < 0 )
905914 return r ;
906915
@@ -919,9 +928,9 @@ static int parse_fstab_one(
919928 bool is_sysroot_usr = in_initrd () && path_equal (where , "/sysroot/usr" );
920929
921930 const char * target_unit =
922- initrd ? SPECIAL_INITRD_FS_TARGET :
923931 is_sysroot ? SPECIAL_INITRD_ROOT_FS_TARGET :
924932 is_sysroot_usr ? SPECIAL_INITRD_USR_FS_TARGET :
933+ prefix_sysroot ? SPECIAL_INITRD_FS_TARGET :
925934 mount_is_network (fstype , options ) ? SPECIAL_REMOTE_FS_TARGET :
926935 SPECIAL_LOCAL_FS_TARGET ;
927936
@@ -948,13 +957,13 @@ static int parse_fstab_one(
948957 return true;
949958}
950959
951- static int parse_fstab (bool initrd ) {
960+ static int parse_fstab (bool prefix_sysroot ) {
952961 _cleanup_endmntent_ FILE * f = NULL ;
953962 const char * fstab ;
954963 struct mntent * me ;
955964 int r , ret = 0 ;
956965
957- if (initrd )
966+ if (prefix_sysroot )
958967 fstab = sysroot_fstab_path ();
959968 else {
960969 fstab = fstab_path ();
@@ -974,7 +983,9 @@ static int parse_fstab(bool initrd) {
974983 while ((me = getmntent (f ))) {
975984 r = parse_fstab_one (fstab ,
976985 me -> mnt_fsname , me -> mnt_dir , me -> mnt_type , me -> mnt_opts , me -> mnt_passno ,
977- initrd , /* use_swap_enabled = */ true);
986+ prefix_sysroot ,
987+ /* accept_root = */ false,
988+ /* use_swap_enabled = */ true);
978989 if (r < 0 && ret >= 0 )
979990 ret = r ;
980991 if (arg_sysroot_check && r > 0 )
@@ -1282,14 +1293,18 @@ static int add_mounts_from_cmdline(void) {
12821293 /* Handle each entries found in cmdline as a fstab entry. */
12831294
12841295 FOREACH_ARRAY (m , arg_mounts , arg_n_mounts ) {
1296+ if (m -> for_initrd && !in_initrd ())
1297+ continue ;
1298+
12851299 r = parse_fstab_one (
12861300 "/proc/cmdline" ,
12871301 m -> what ,
12881302 m -> where ,
12891303 m -> fstype ,
12901304 m -> options ,
12911305 /* passno = */ 0 ,
1292- /* initrd = */ false,
1306+ /* prefix_sysroot = */ !m -> for_initrd && in_initrd (),
1307+ /* accept_root = */ true,
12931308 /* use_swap_enabled = */ false);
12941309 if (r < 0 && ret >= 0 )
12951310 ret = r ;
@@ -1298,14 +1313,16 @@ static int add_mounts_from_cmdline(void) {
12981313 return ret ;
12991314}
13001315
1301- static int add_mounts_from_creds (void ) {
1316+ static int add_mounts_from_creds (bool prefix_sysroot ) {
13021317 _cleanup_free_ void * b = NULL ;
13031318 struct mntent * me ;
13041319 int r , ret = 0 ;
13051320 size_t bs ;
13061321
1322+ assert (in_initrd () || !prefix_sysroot );
1323+
13071324 r = read_credential_with_decryption (
1308- in_initrd () ? "fstab.extra.initrd" : "fstab.extra" ,
1325+ in_initrd () && ! prefix_sysroot ? "fstab.extra.initrd" : "fstab.extra" ,
13091326 & b , & bs );
13101327 if (r <= 0 )
13111328 return r ;
@@ -1323,7 +1340,8 @@ static int add_mounts_from_creds(void) {
13231340 me -> mnt_type ,
13241341 me -> mnt_opts ,
13251342 me -> mnt_passno ,
1326- /* initrd = */ false,
1343+ /* prefix_sysroot = */ prefix_sysroot ,
1344+ /* accept_root = */ true,
13271345 /* use_swap_enabled = */ true);
13281346 if (r < 0 && ret >= 0 )
13291347 ret = r ;
@@ -1437,21 +1455,21 @@ static int parse_proc_cmdline_item(const char *key, const char *value, void *dat
14371455 else
14381456 arg_verity = r ;
14391457
1440- } else if (streq (key , "systemd.mount-extra" )) {
1458+ } else if (STR_IN_SET (key , "systemd.mount-extra" , "rd. systemd.mount-extra" )) {
14411459
14421460 if (proc_cmdline_value_missing (key , value ))
14431461 return 0 ;
14441462
1445- r = mount_array_add (value );
1463+ r = mount_array_add (startswith ( key , "rd." ), value );
14461464 if (r < 0 )
14471465 log_warning ("Failed to parse systemd.mount-extra= option, ignoring: %s" , value );
14481466
1449- } else if (streq (key , "systemd.swap-extra" )) {
1467+ } else if (STR_IN_SET (key , "systemd.swap-extra" , "rd. systemd.swap-extra" )) {
14501468
14511469 if (proc_cmdline_value_missing (key , value ))
14521470 return 0 ;
14531471
1454- r = mount_array_add_swap (value );
1472+ r = mount_array_add_swap (startswith ( key , "rd." ), value );
14551473 if (r < 0 )
14561474 log_warning ("Failed to parse systemd.swap-extra= option, ignoring: %s" , value );
14571475 }
@@ -1517,7 +1535,7 @@ static int run_generator(void) {
15171535 (void ) determine_usr ();
15181536
15191537 if (arg_sysroot_check ) {
1520- r = parse_fstab (/* initrd = */ true);
1538+ r = parse_fstab (/* prefix_sysroot = */ true);
15211539 if (r == 0 )
15221540 log_debug ("Nothing interesting found, not doing daemon-reload." );
15231541 if (r > 0 )
@@ -1547,13 +1565,13 @@ static int run_generator(void) {
15471565 /* Honour /etc/fstab only when that's enabled */
15481566 if (arg_fstab_enabled ) {
15491567 /* Parse the local /etc/fstab, possibly from the initrd */
1550- r = parse_fstab (/* initrd = */ false);
1568+ r = parse_fstab (/* prefix_sysroot = */ false);
15511569 if (r < 0 && ret >= 0 )
15521570 ret = r ;
15531571
15541572 /* If running in the initrd also parse the /etc/fstab from the host */
15551573 if (in_initrd ())
1556- r = parse_fstab (/* initrd = */ true);
1574+ r = parse_fstab (/* prefix_sysroot = */ true);
15571575 else
15581576 r = generator_enable_remount_fs_service (arg_dest );
15591577 if (r < 0 && ret >= 0 )
@@ -1564,10 +1582,16 @@ static int run_generator(void) {
15641582 if (r < 0 && ret >= 0 )
15651583 ret = r ;
15661584
1567- r = add_mounts_from_creds ();
1585+ r = add_mounts_from_creds (/* prefix_sysroot = */ false );
15681586 if (r < 0 && ret >= 0 )
15691587 ret = r ;
15701588
1589+ if (in_initrd ()) {
1590+ r = add_mounts_from_creds (/* prefix_sysroot = */ true);
1591+ if (r < 0 && ret >= 0 )
1592+ ret = r ;
1593+ }
1594+
15711595 return ret ;
15721596}
15731597
0 commit comments