7373 {"/var/log/journal" , "/run/host/var/log/journal" , "" },
7474 {"/var/mnt" , "/run/host/var/mnt" , "rslave" },
7575 }
76+
77+ initContainerIgnoredHostDevices = map [string ]struct {}{
78+ "console" : {},
79+ "core" : {},
80+ "fd" : {},
81+ "full" : {},
82+ "kmsg" : {},
83+ "mqueue" : {},
84+ "null" : {},
85+ "ptmx" : {},
86+ "pts" : {},
87+ "random" : {},
88+ "shm" : {},
89+ "stderr" : {},
90+ "stdin" : {},
91+ "stdout" : {},
92+ "tty" : {},
93+ "urandom" : {},
94+ "zero" : {},
95+ }
7696)
7797
7898var initContainerCmd = & cobra.Command {
@@ -263,6 +283,8 @@ func initContainer(cmd *cobra.Command, args []string) error {
263283 }
264284 }
265285
286+ projectHostDevices ()
287+
266288 if utils .PathExists ("/sys/fs/selinux" ) {
267289 if err := mountBind ("/sys/fs/selinux" , "/usr/share/empty" , "" ); err != nil {
268290 return err
@@ -1018,20 +1040,22 @@ func mountBind(containerPath, source, flags string) error {
10181040 if err := os .MkdirAll (containerPath , 0755 ); err != nil {
10191041 return fmt .Errorf ("failed to create directory %s: %w" , containerPath , err )
10201042 }
1021- } else if fileMode .IsRegular () || fileMode & os .ModeSocket != 0 {
1022- logrus .Debugf ("Creating regular file %s" , containerPath )
1023-
1043+ } else {
10241044 containerPathDir := filepath .Dir (containerPath )
10251045 if err := os .MkdirAll (containerPathDir , 0755 ); err != nil {
10261046 return fmt .Errorf ("failed to create directory %s: %w" , containerPathDir , err )
10271047 }
10281048
1029- containerPathFile , err := os .Create (containerPath )
1030- if err != nil && ! os .IsExist (err ) {
1031- return fmt .Errorf ("failed to create regular file %s: %w" , containerPath , err )
1032- }
1049+ if ! utils .PathExists (containerPath ) {
1050+ logrus .Debugf ("Creating file mount point %s" , containerPath )
1051+
1052+ containerPathFile , err := os .Create (containerPath )
1053+ if err != nil {
1054+ return fmt .Errorf ("failed to create file mount point %s: %w" , containerPath , err )
1055+ }
10331056
1034- defer containerPathFile .Close ()
1057+ defer containerPathFile .Close ()
1058+ }
10351059 }
10361060
10371061 logrus .Debugf ("Binding %s to %s" , containerPath , source )
@@ -1053,6 +1077,50 @@ func mountBind(containerPath, source, flags string) error {
10531077 return nil
10541078}
10551079
1080+ func projectHostDevices () {
1081+ const hostDevices = "/run/host/dev"
1082+ const logPrefix = "Projecting host devices into the container"
1083+
1084+ logrus .Debugf ("%s" , logPrefix )
1085+
1086+ entries , err := os .ReadDir (hostDevices )
1087+ if err != nil {
1088+ logrus .Debugf ("%s: failed to read %s: %s" , logPrefix , hostDevices , err )
1089+ logrus .Debugf ("%s: skipping" , logPrefix )
1090+ return
1091+ }
1092+
1093+ for _ , entry := range entries {
1094+ name := entry .Name ()
1095+ if _ , ignored := initContainerIgnoredHostDevices [name ]; ignored {
1096+ logrus .Debugf ("%s: skipping runtime-managed path /dev/%s" , logPrefix , name )
1097+ continue
1098+ }
1099+
1100+ source := filepath .Join (hostDevices , name )
1101+ fileInfo , err := os .Lstat (source )
1102+ if err != nil {
1103+ logrus .Debugf ("%s: failed to lstat %s: %s" , logPrefix , source , err )
1104+ continue
1105+ }
1106+
1107+ if fileInfo .Mode ()& os .ModeSymlink != 0 {
1108+ logrus .Debugf ("%s: skipping symbolic link %s" , logPrefix , source )
1109+ continue
1110+ }
1111+
1112+ flags := ""
1113+ if fileInfo .IsDir () {
1114+ flags = "rslave"
1115+ }
1116+
1117+ containerPath := filepath .Join ("/dev" , name )
1118+ if err := mountBind (containerPath , source , flags ); err != nil {
1119+ logrus .Debugf ("%s: failed to bind %s to %s: %s" , logPrefix , containerPath , source , err )
1120+ }
1121+ }
1122+ }
1123+
10561124// redirectPath serves for creating symbolic links for crucial system
10571125// configuration files to their counterparts on the host's file system.
10581126//
0 commit comments