Repository: moby/moby
File: daemon/cdi.go (Go)

Code before:
	// We construct a spec updates that injects CDI devices into the OCI spec using the initialized registry.
	c := &cdiHandler{
		registry: cache,
	}

	return &deviceDriver{
		updateSpec:  c.injectCDIDevices,
		ListDevices: c.listDevices,
	}
}

// createCDICache creates a CDI cache for the specified CDI specification directories.
// If the list of CDI specification directories is empty or the creation of the CDI cache fails, an error is returned.
func createCDICache(cdiSpecDirs ...string) (*cdi.Cache, error) {
	if len(cdiSpecDirs) == 0 {
		return nil, fmt.Errorf("no CDI specification directories specified")
	}

	err := cdi.Configure(cdi.WithSpecDirs(cdiSpecDirs...))
	if err != nil {
		return nil, fmt.Errorf("CDI registry initialization failure: %w", err)
	}

	cache := cdi.GetDefaultCache()

	for dir, errs := range cache.GetErrors() {
		for _, err := range errs {
			if errors.Is(err, os.ErrNotExist) {
				log.L.WithField("dir", dir).Infof("CDI directory does not exist, skipping: %v", err)
				continue
			}
			log.L.WithField("dir", dir).Warnf("CDI setup error: %+v", err)
		}
	}

	return cache, nil
}

// injectCDIDevices injects a set of CDI devices into the specified OCI specification.
func (c *cdiHandler) injectCDIDevices(s *specs.Spec, dev *deviceInstance) error {
	if dev.req.Count != 0 {
		return errdefs.InvalidParameter(errors.New("unexpected count in CDI device request"))
	}
	if len(dev.req.Options) > 0 {
		return errdefs.InvalidParameter(errors.New("unexpected options in CDI device request"))
	}

	cdiDeviceNames := dev.req.DeviceIDs
	if len(cdiDeviceNames) == 0 {
		return nil
	}

Review comment (performance):
So moby and buildkit are now using the same default cache instance instead of creating a new one which seems to be the same for containerd: https://github.com/containerd/containerd/blob/f6724ac31904c4d41d6794b4df130565829b5621/cmd/ctr/commands/run/run_unix.go#L482 so we should be good.

When containerd runs as a service it also uses the default cache: https://github.com/containerd/containerd/blob/f6724ac31904c4d41d6794b4df130565829b5621/internal/cri/server/service_linux.go#L105. But no issue here as it's pretty much a standalone product. I just wonder why they disable auto refresh.

Code after:

	// We construct a spec updates that injects CDI devices into the OCI spec using the initialized registry.
	c := &cdiHandler{
		registry: cache,
	}

	return &deviceDriver{
		updateSpec:  c.injectCDIDevices,
		ListDevices: c.listDevices,
	}, cache
}

// createCDICache creates a CDI cache for the specified CDI specification directories.
// If the list of CDI specification directories is empty or the creation of the CDI cache fails, an error is returned.
func createCDICache(cdiSpecDirs ...string) (*cdi.Cache, error) {
	if len(cdiSpecDirs) == 0 {
		return nil, fmt.Errorf("no CDI specification directories specified")
	}

	cache, err := cdi.NewCache(cdi.WithSpecDirs(cdiSpecDirs...))
	if err != nil {
		return nil, fmt.Errorf("CDI registry initialization failure: %w", err)
	}

	for dir, errs := range cache.GetErrors() {
		for _, err := range errs {
			if errors.Is(err, os.ErrNotExist) {
				log.L.WithField("dir", dir).Infof("CDI directory does not exist, skipping: %v", err)
				continue
			}
			log.L.WithField("dir", dir).Warnf("CDI setup error: %+v", err)
		}
	}

	return cache, nil
}

// injectCDIDevices injects a set of CDI devices into the specified OCI specification.
func (c *cdiHandler) injectCDIDevices(s *specs.Spec, dev *deviceInstance) error {
	if dev.req.Count != 0 {
		return errdefs.InvalidParameter(errors.New("unexpected count in CDI device request"))
	}
	if len(dev.req.Options) > 0 {
		return errdefs.InvalidParameter(errors.New("unexpected options in CDI device request"))
	}

	cdiDeviceNames := dev.req.DeviceIDs
	if len(cdiDeviceNames) == 0 {
		return nil
	}