@@ -17,7 +17,7 @@ import (
1717
1818// systemdProperties takes the configured device rules and generates a
1919// corresponding set of systemd properties to configure the devices correctly.
20- func systemdProperties (r * configs.Resources ) ([]systemdDbus.Property , error ) {
20+ func systemdProperties (r * configs.Resources , sdVer int ) ([]systemdDbus.Property , error ) {
2121 if r .SkipDevices {
2222 return nil , nil
2323 }
@@ -78,9 +78,10 @@ func systemdProperties(r *configs.Resources) ([]systemdDbus.Property, error) {
7878 // trickery to convert things:
7979 //
8080 // * Concrete rules with non-wildcard major/minor numbers have to use
81- // /dev/{block,char} paths. This is slightly odd because it means
82- // that we cannot add whitelist rules for devices that don't exist,
83- // but there's not too much we can do about that.
81+ // /dev/{block,char}/MAJOR:minor paths. Before v240, systemd uses
82+ // stat(2) on such paths to look up device properties, meaning we
83+ // cannot add whitelist rules for devices that don't exist. Since v240,
84+ // device properties are parsed from the path string.
8485 //
8586 // However, path globbing is not support for path-based rules so we
8687 // need to handle wildcards in some other manner.
@@ -128,21 +129,14 @@ func systemdProperties(r *configs.Resources) ([]systemdDbus.Property, error) {
128129 case devices .CharDevice :
129130 entry .Path = fmt .Sprintf ("/dev/char/%d:%d" , rule .Major , rule .Minor )
130131 }
131- // systemd will issue a warning if the path we give here doesn't exist.
132- // Since all of this logic is best-effort anyway (we manually set these
133- // rules separately to systemd) we can safely skip entries that don't
134- // have a corresponding path.
135- if _ , err := os .Stat (entry .Path ); err != nil {
136- // Also check /sys/dev so that we don't depend on /dev/{block,char}
137- // being populated. (/dev/{block,char} is populated by udev, which
138- // isn't strictly required for systemd). Ironically, this happens most
139- // easily when starting containerd within a runc created container
140- // itself.
141-
142- // We don't bother with securejoin here because we create entry.Path
143- // right above here, so we know it's safe.
144- if _ , err := os .Stat ("/sys" + entry .Path ); err != nil {
145- logrus .Warnf ("skipping device %s for systemd: %s" , entry .Path , err )
132+ if sdVer < 240 {
133+ // Old systemd versions use stat(2) on path to find out device major:minor
134+ // numbers and type. If the path doesn't exist, it will not add the rule,
135+ // emitting a warning instead.
136+ // Since all of this logic is best-effort anyway (we manually set these
137+ // rules separately to systemd) we can safely skip entries that don't
138+ // have a corresponding path.
139+ if _ , err := os .Stat (entry .Path ); err != nil {
146140 continue
147141 }
148142 }
0 commit comments