Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make the priority for picking the storage driver configurable #1460

Merged
merged 2 commits into from
Jan 6, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
5 changes: 5 additions & 0 deletions docs/containers-storage.conf.5.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,11 @@ A common use case for this field is to provide a local storage directory when us
container storage run dir (default: "/run/containers/storage")
Default directory to store all temporary writable content created by container storage programs. The rootless runroot path supports environment variable substitutions (ie. `$HOME/containers/storage`)

**driver_priority**=[]
Priority list for the storage drivers that will be tested one after the other to pick the storage driver if it is not defined. The first storage driver in this list that can be used, will be picked as the new one and all subsequent ones will not be tried. If all drivers in this list are not viable, then **all** known drivers will be tried and the first working one will be picked.
By default, the storage driver is set via the `driver` option. If it is not defined, then the best driver will be picked according to the current platform. This option allows you to override this internal priority list with a custom one to prefer certain drivers.
Setting this option only has an effect if the local storage has not been initialized yet and the driver name is not set.

### STORAGE OPTIONS TABLE

The `storage.options` table supports the following options:
Expand Down
18 changes: 14 additions & 4 deletions drivers/driver.go
Original file line number Diff line number Diff line change
Expand Up @@ -322,6 +322,7 @@ func getBuiltinDriver(name, home string, options Options) (Driver, error) {
type Options struct {
Root string
RunRoot string
DriverPriority []string
DriverOptions []string
UIDMaps []idtools.IDMap
GIDMaps []idtools.IDMap
Expand All @@ -337,9 +338,18 @@ func New(name string, config Options) (Driver, error) {

// Guess for prior driver
driversMap := scanPriorDrivers(config.Root)
for _, name := range priority {
if name == "vfs" {
// don't use vfs even if there is state present.

// use the supplied priority list unless it is empty
prioList := config.DriverPriority
if len(prioList) == 0 {
prioList = priority
}

for _, name := range prioList {
if name == "vfs" && len(config.DriverPriority) == 0 {
// don't use vfs even if there is state present and vfs
// has not been explicitly added to the override driver
// priority list
continue
}
if _, prior := driversMap[name]; prior {
Expand Down Expand Up @@ -372,7 +382,7 @@ func New(name string, config Options) (Driver, error) {
}

// Check for priority drivers first
for _, name := range priority {
for _, name := range prioList {
driver, err := getBuiltinDriver(name, config.Root, config)
if err != nil {
if isDriverNotSupported(err) {
Expand Down
45 changes: 24 additions & 21 deletions store.go
Original file line number Diff line number Diff line change
Expand Up @@ -599,8 +599,9 @@ type store struct {

// The following fields are only set when constructing store, and must never be modified afterwards.
// They are safe to access without any other locking.
runRoot string
graphDriverName string // Initially set to the user-requested value, possibly ""; updated during store construction, and does not change afterwards.
runRoot string
graphDriverName string // Initially set to the user-requested value, possibly ""; updated during store construction, and does not change afterwards.
graphDriverPriority []string
// graphLock:
// - Ensures that we always reload graphDriver, and the primary layer store, after any process does store.Shutdown. This is necessary
// because (??) the Shutdown may forcibly unmount and clean up, affecting graph driver state in a way only a graph driver
Expand Down Expand Up @@ -731,20 +732,21 @@ func GetStore(options types.StoreOptions) (Store, error) {
autoNsMaxSize = AutoUserNsMaxSize
}
s := &store{
runRoot: options.RunRoot,
graphDriverName: options.GraphDriverName,
graphLock: graphLock,
usernsLock: usernsLock,
graphRoot: options.GraphRoot,
graphOptions: options.GraphDriverOptions,
pullOptions: options.PullOptions,
uidMap: copyIDMap(options.UIDMap),
gidMap: copyIDMap(options.GIDMap),
autoUsernsUser: options.RootAutoNsUser,
autoNsMinSize: autoNsMinSize,
autoNsMaxSize: autoNsMaxSize,
disableVolatile: options.DisableVolatile,
transientStore: options.TransientStore,
runRoot: options.RunRoot,
graphDriverName: options.GraphDriverName,
graphDriverPriority: options.GraphDriverPriority,
graphLock: graphLock,
usernsLock: usernsLock,
graphRoot: options.GraphRoot,
graphOptions: options.GraphDriverOptions,
pullOptions: options.PullOptions,
uidMap: copyIDMap(options.UIDMap),
gidMap: copyIDMap(options.GIDMap),
autoUsernsUser: options.RootAutoNsUser,
autoNsMinSize: autoNsMinSize,
autoNsMaxSize: autoNsMaxSize,
disableVolatile: options.DisableVolatile,
transientStore: options.TransientStore,

additionalUIDs: nil,
additionalGIDs: nil,
Expand Down Expand Up @@ -942,11 +944,12 @@ func (s *store) stopUsingGraphDriver() {
// The caller must hold s.graphLock.
func (s *store) createGraphDriverLocked() (drivers.Driver, error) {
config := drivers.Options{
Root: s.graphRoot,
RunRoot: s.runRoot,
DriverOptions: s.graphOptions,
UIDMaps: s.uidMap,
GIDMaps: s.gidMap,
Root: s.graphRoot,
RunRoot: s.runRoot,
DriverPriority: s.graphDriverPriority,
DriverOptions: s.graphOptions,
UIDMaps: s.uidMap,
GIDMaps: s.gidMap,
}
return drivers.New(s.graphDriverName, config)
}
Expand Down
18 changes: 13 additions & 5 deletions types/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import (
type TomlConfig struct {
Storage struct {
Driver string `toml:"driver,omitempty"`
DriverPriority []string `toml:"driver_priority,omitempty"`
RunRoot string `toml:"runroot,omitempty"`
GraphRoot string `toml:"graphroot,omitempty"`
RootlessStoragePath string `toml:"rootless_storage_path,omitempty"`
Expand Down Expand Up @@ -213,10 +214,16 @@ type StoreOptions struct {
// RootlessStoragePath is the storage path for rootless users
// default $HOME/.local/share/containers/storage
RootlessStoragePath string `toml:"rootless_storage_path"`
// GraphDriverName is the underlying storage driver that we'll be
// using. It only needs to be specified the first time a Store is
// initialized for a given RunRoot and GraphRoot.
// If the driver is not specified, the best suited driver will be picked
// either from GraphDriverPriority, if specified, or from the platform
// dependent priority list (in that order).
GraphDriverName string `json:"driver,omitempty"`
// GraphDriverPriority is a list of storage drivers that will be tried
// to initialize the Store for a given RunRoot and GraphRoot unless a
// GraphDriverName is set.
// This list can be used to define a custom order in which the drivers
// will be tried.
GraphDriverPriority []string `json:"driver-priority,omitempty"`
// GraphDriverOptions are driver-specific options.
GraphDriverOptions []string `json:"driver-options,omitempty"`
// UIDMap and GIDMap are used for setting up a container's root filesystem
Expand Down Expand Up @@ -380,8 +387,9 @@ func ReloadConfigurationFile(configFile string, storeOptions *StoreOptions) erro
logrus.Warnf("Switching default driver from overlay2 to the equivalent overlay driver")
storeOptions.GraphDriverName = overlayDriver
}
if storeOptions.GraphDriverName == "" {
logrus.Errorf("The storage 'driver' option must be set in %s to guarantee proper operation", configFile)
storeOptions.GraphDriverPriority = config.Storage.DriverPriority
if storeOptions.GraphDriverName == "" && len(storeOptions.GraphDriverPriority) == 0 {
logrus.Warnf("The storage 'driver' option should be set in %s. A driver was picked automatically.", configFile)
}
if config.Storage.RunRoot != "" {
storeOptions.RunRoot = config.Storage.RunRoot
Expand Down