Browse code

cdi: skip scanning non-readable dirs

This simplifies `dockerd-rootless.sh` by removing the workaround for
`CDI: Error associated with spec file /etc/cdi: failed to monitor for changes: permission denied`.

Signed-off-by: Akihiro Suda <akihiro.suda.cz@hco.ntt.co.jp>

Akihiro Suda authored on 2025/12/01 17:51:00
Showing 2 changed files
... ...
@@ -190,24 +190,6 @@ if [ -z "$_DOCKERD_ROOTLESS_CHILD" ]; then
190 190
 else
191 191
 	[ "$_DOCKERD_ROOTLESS_CHILD" = 1 ]
192 192
 
193
-	# The Container Device Interface (CDI) specs can be found by default
194
-	# under {/etc,/var/run}/cdi. More information at:
195
-	# https://github.com/cncf-tags/container-device-interface
196
-	#
197
-	# In order to use the Container Device Interface (CDI) integration,
198
-	# the CDI paths need to exist before the Docker daemon is started in
199
-	# order for it to read the CDI specification files. Otherwise, a
200
-	# Docker daemon restart will be required for the daemon to discover
201
-	# them.
202
-	#
203
-	# If another set of CDI paths (other than the default /etc/cdi and
204
-	# /var/run/cdi) are configured through the Docker configuration file
205
-	# (using "cdi-spec-dirs"), they need to be bind mounted in rootless
206
-	# mode; otherwise the Docker daemon won't have access to the CDI
207
-	# specification files.
208
-	mount_directory /etc/cdi
209
-	mount_directory /var/run/cdi
210
-
211 193
 	# remove the symlinks for the existing files in the parent namespace if any,
212 194
 	# so that we can create our own files in our mount namespace.
213 195
 	rm -f /run/docker /run/containerd /run/xtables.lock
... ...
@@ -57,6 +57,7 @@ import (
57 57
 	"github.com/moby/moby/v2/pkg/homedir"
58 58
 	"github.com/moby/moby/v2/pkg/pidfile"
59 59
 	"github.com/moby/moby/v2/pkg/plugingetter"
60
+	"github.com/moby/sys/userns"
60 61
 	"github.com/pkg/errors"
61 62
 	"github.com/sirupsen/logrus"
62 63
 	"github.com/spf13/pflag"
... ...
@@ -668,7 +669,23 @@ func loadDaemonCliConfig(opts *daemonOptions) (*config.Config, error) {
668 668
 			}
669 669
 			conf.CDISpecDirs = append(conf.CDISpecDirs, filepath.Join(xch, "cdi"), filepath.Join(xrd, "cdi"))
670 670
 		}
671
-	} else if len(conf.CDISpecDirs) == 1 && conf.CDISpecDirs[0] == "" {
671
+	}
672
+	// Filter out CDI spec directories that are not readable, and log appropriately
673
+	var cdiSpecDirs []string
674
+	for _, dir := range conf.CDISpecDirs {
675
+		// Non-existing directories are not filtered out here, as CDI spec directories are allowed to not exist.
676
+		if _, err := os.ReadDir(dir); err == nil || errors.Is(err, os.ErrNotExist) {
677
+			cdiSpecDirs = append(cdiSpecDirs, dir)
678
+		} else {
679
+			logLevel := log.ErrorLevel
680
+			if userns.RunningInUserNS() && errors.Is(err, os.ErrPermission) {
681
+				logLevel = log.DebugLevel
682
+			}
683
+			log.L.WithField("dir", dir).WithError(err).Log(logLevel, "CDI spec directory cannot be accessed, skipping")
684
+		}
685
+	}
686
+	conf.CDISpecDirs = cdiSpecDirs
687
+	if len(conf.CDISpecDirs) == 1 && conf.CDISpecDirs[0] == "" {
672 688
 		// If CDISpecDirs is set to an empty string, we clear it to ensure that CDI is disabled.
673 689
 		conf.CDISpecDirs = nil
674 690
 	}