@@ -563,15 +563,16 @@ int mount_all(const char *dest,
563563 MOUNT_FATAL |MOUNT_MKDIR },
564564 { "tmpfs" , "/run" , "tmpfs" , "mode=755" TMPFS_LIMITS_RUN , MS_NOSUID |MS_NODEV |MS_STRICTATIME ,
565565 MOUNT_FATAL |MOUNT_MKDIR },
566- { "/usr/lib/os-release" , "/run/host/usr/lib/os-release" , NULL , NULL , MS_BIND ,
567- MOUNT_FATAL |MOUNT_MKDIR |MOUNT_TOUCH }, /* As per kernel interface requirements, bind mount first (creating mount points) and make read-only later */
568- { NULL , "/run/host/usr/lib/os-release" , NULL , NULL , MS_BIND |MS_RDONLY |MS_NOSUID |MS_NOEXEC |MS_NODEV |MS_REMOUNT ,
569- 0 },
570- { "/etc/os-release" , "/run/host/etc/os-release" , NULL , NULL , MS_BIND ,
571- MOUNT_MKDIR |MOUNT_TOUCH },
572- { NULL , "/run/host/etc/os-release" , NULL , NULL , MS_BIND |MS_RDONLY |MS_NOSUID |MS_NOEXEC |MS_NODEV |MS_REMOUNT ,
573- 0 },
574-
566+ { "/run/host" , "/run/host" , NULL , NULL , MS_BIND ,
567+ MOUNT_FATAL |MOUNT_MKDIR |MOUNT_PREFIX_ROOT }, /* Prepare this so that we can make it read-only when we are done */
568+ { "/etc/os-release" , "/run/host/os-release" , NULL , NULL , MS_BIND ,
569+ MOUNT_TOUCH }, /* As per kernel interface requirements, bind mount first (creating mount points) and make read-only later */
570+ { "/usr/lib/os-release" , "/run/host/os-release" , NULL , NULL , MS_BIND ,
571+ MOUNT_FATAL }, /* If /etc/os-release doesn't exist use the version in /usr/lib as fallback */
572+ { NULL , "/run/host/os-release" , NULL , NULL , MS_BIND |MS_RDONLY |MS_NOSUID |MS_NOEXEC |MS_NODEV |MS_REMOUNT ,
573+ MOUNT_FATAL },
574+ { NULL , "/run/host" , NULL , NULL , MS_BIND |MS_RDONLY |MS_NOSUID |MS_NOEXEC |MS_NODEV |MS_REMOUNT ,
575+ MOUNT_FATAL |MOUNT_IN_USERNS },
575576#if HAVE_SELINUX
576577 { "/sys/fs/selinux" , "/sys/fs/selinux" , NULL , NULL , MS_BIND ,
577578 MOUNT_MKDIR }, /* Bind mount first (mkdir/chown the mount point in case /sys/ is mounted as minimal skeleton tmpfs) */
@@ -589,9 +590,9 @@ int mount_all(const char *dest,
589590 int r ;
590591
591592 for (k = 0 ; k < ELEMENTSOF (mount_table ); k ++ ) {
592- _cleanup_free_ char * where = NULL , * options = NULL ;
593- const char * o ;
593+ _cleanup_free_ char * where = NULL , * options = NULL , * prefixed = NULL ;
594594 bool fatal = FLAGS_SET (mount_table [k ].mount_settings , MOUNT_FATAL );
595+ const char * o ;
595596
596597 if (in_userns != FLAGS_SET (mount_table [k ].mount_settings , MOUNT_IN_USERNS ))
597598 continue ;
@@ -616,20 +617,9 @@ int mount_all(const char *dest,
616617 return log_error_errno (r , "Failed to detect whether %s is a mount point: %m" , where );
617618 if (r > 0 )
618619 continue ;
619-
620- /* Shortcut for optional bind mounts: if the source can't be found skip ahead to avoid creating
621- * empty and unused directories. */
622- if (!fatal && FLAGS_SET (mount_table [k ].mount_settings , MOUNT_MKDIR ) && FLAGS_SET (mount_table [k ].flags , MS_BIND )) {
623- r = access (mount_table [k ].what , F_OK );
624- if (r < 0 ) {
625- if (errno == ENOENT )
626- continue ;
627- return log_error_errno (errno , "Failed to stat %s: %m" , mount_table [k ].what );
628- }
629- }
630620 }
631621
632- if (FLAGS_SET (mount_table [k ].mount_settings , MOUNT_MKDIR ) ) {
622+ if ((mount_table [k ].mount_settings & ( MOUNT_MKDIR | MOUNT_TOUCH )) != 0 ) {
633623 uid_t u = (use_userns && !in_userns ) ? uid_shift : UID_INVALID ;
634624
635625 if (FLAGS_SET (mount_table [k ].mount_settings , MOUNT_TOUCH ))
@@ -647,13 +637,17 @@ int mount_all(const char *dest,
647637 if (r != - EROFS )
648638 continue ;
649639 }
650- if (FLAGS_SET (mount_table [k ].mount_settings , MOUNT_TOUCH )) {
651- r = touch (where );
652- if (r < 0 && r != - EEXIST ) {
653- if (fatal )
654- return log_error_errno (r , "Failed to create mount point %s: %m" , where );
655- log_debug_errno (r , "Failed to create mount point %s: %m" , where );
656- }
640+ }
641+
642+ if (FLAGS_SET (mount_table [k ].mount_settings , MOUNT_TOUCH )) {
643+ r = touch (where );
644+ if (r < 0 && r != - EEXIST ) {
645+ if (fatal && r != - EROFS )
646+ return log_error_errno (r , "Failed to create file %s: %m" , where );
647+
648+ log_debug_errno (r , "Failed to create file %s: %m" , where );
649+ if (r != - EROFS )
650+ continue ;
657651 }
658652 }
659653
@@ -666,8 +660,18 @@ int mount_all(const char *dest,
666660 o = options ;
667661 }
668662
663+ if (FLAGS_SET (mount_table [k ].mount_settings , MOUNT_PREFIX_ROOT )) {
664+ /* Optionally prefix the mount source with the root dir. This is useful in bind
665+ * mounts to be created within the container image before we transition into it. Note
666+ * that MOUNT_IN_USERNS is run after we transitioned hence prefixing is not ncessary
667+ * for those. */
668+ r = chase_symlinks (mount_table [k ].what , dest , CHASE_PREFIX_ROOT , & prefixed , NULL );
669+ if (r < 0 )
670+ return log_error_errno (r , "Failed to resolve %s/%s: %m" , dest , mount_table [k ].what );
671+ }
672+
669673 r = mount_verbose (fatal ? LOG_ERR : LOG_DEBUG ,
670- mount_table [k ].what ,
674+ prefixed ?: mount_table [k ].what ,
671675 where ,
672676 mount_table [k ].type ,
673677 mount_table [k ].flags ,
0 commit comments