mirror of
https://github.com/containers/podman.git
synced 2025-09-15 12:48:58 +08:00
Use storage that better supports rootless overlayfs
overlayfs -- the kernel's version, not fuse-overlayfs -- recently learned (as of linux 5.16.0, I believe) how to support rootless users. Previously, rootless users had to use these storage.conf(5) settings: * storage.driver=vfs (aka STORAGE_DRIVER=vfs), or * storage.driver=overlay (aka STORAGE_DRIVER=overlay), storage.options.overlay.mount_program=/usr/bin/fuse-overlayfs (aka STORAGE_OPTS=/usr/bin/fuse-overlayfs) Now that a third backend is available, setting only: * storage.driver=overlay (aka STORAGE_DRIVER=overlay) https://github.com/containers/podman/issues/13123 reported EXDEV errors during the normal operation of their container. Tracing it out, the problem turned out to be that their container was being mounted without 'userxattr'; I don't fully understand why, but mount(8) mentions this is needed for rootless users: > userxattr > > Use the "user.overlay." xattr namespace instead of "trusted.overlay.". > This is useful for unprivileged mounting of overlayfs. https://github.com/containers/storage/pull/1156 found and fixed the issue in podman, and this just pulls in that via go get github.com/containers/storage@ebc90ab go mod vendor make vendor Closes https://github.com/containers/podman/issues/13123 Signed-off-by: Nick Guenther <nick.guenther@polymtl.ca>
This commit is contained in:
81
vendor/github.com/containers/storage/layers.go
generated
vendored
81
vendor/github.com/containers/storage/layers.go
generated
vendored
@ -399,14 +399,13 @@ func (r *layerStore) Load() error {
|
||||
if layer.Flags == nil {
|
||||
layer.Flags = make(map[string]interface{})
|
||||
}
|
||||
if cleanup, ok := layer.Flags[incompleteFlag]; ok {
|
||||
if b, ok := cleanup.(bool); ok && b {
|
||||
err = r.deleteInternal(layer.ID)
|
||||
if err != nil {
|
||||
break
|
||||
}
|
||||
shouldSave = true
|
||||
if layerHasIncompleteFlag(layer) {
|
||||
logrus.Warnf("Found incomplete layer %#v, deleting it", layer.ID)
|
||||
err = r.deleteInternal(layer.ID)
|
||||
if err != nil {
|
||||
break
|
||||
}
|
||||
shouldSave = true
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -742,26 +741,17 @@ func (r *layerStore) Put(id string, parentLayer *Layer, names []string, mountLab
|
||||
}
|
||||
if moreOptions.TemplateLayer != "" {
|
||||
if err = r.driver.CreateFromTemplate(id, moreOptions.TemplateLayer, templateIDMappings, parent, parentMappings, &opts, writeable); err != nil {
|
||||
if id != "" {
|
||||
return nil, -1, errors.Wrapf(err, "error creating copy of template layer %q with ID %q", moreOptions.TemplateLayer, id)
|
||||
}
|
||||
return nil, -1, errors.Wrapf(err, "error creating copy of template layer %q", moreOptions.TemplateLayer)
|
||||
return nil, -1, errors.Wrapf(err, "error creating copy of template layer %q with ID %q", moreOptions.TemplateLayer, id)
|
||||
}
|
||||
oldMappings = templateIDMappings
|
||||
} else {
|
||||
if writeable {
|
||||
if err = r.driver.CreateReadWrite(id, parent, &opts); err != nil {
|
||||
if id != "" {
|
||||
return nil, -1, errors.Wrapf(err, "error creating read-write layer with ID %q", id)
|
||||
}
|
||||
return nil, -1, errors.Wrapf(err, "error creating read-write layer")
|
||||
return nil, -1, errors.Wrapf(err, "error creating read-write layer with ID %q", id)
|
||||
}
|
||||
} else {
|
||||
if err = r.driver.Create(id, parent, &opts); err != nil {
|
||||
if id != "" {
|
||||
return nil, -1, errors.Wrapf(err, "error creating layer with ID %q", id)
|
||||
}
|
||||
return nil, -1, errors.Wrapf(err, "error creating layer")
|
||||
return nil, -1, errors.Wrapf(err, "error creating layer with ID %q", id)
|
||||
}
|
||||
}
|
||||
oldMappings = parentMappings
|
||||
@ -770,7 +760,9 @@ func (r *layerStore) Put(id string, parentLayer *Layer, names []string, mountLab
|
||||
if err = r.driver.UpdateLayerIDMap(id, oldMappings, idMappings, mountLabel); err != nil {
|
||||
// We don't have a record of this layer, but at least
|
||||
// try to clean it up underneath us.
|
||||
r.driver.Remove(id)
|
||||
if err2 := r.driver.Remove(id); err2 != nil {
|
||||
logrus.Errorf("While recovering from a failure creating in UpdateLayerIDMap, error deleting layer %#v: %v", id, err2)
|
||||
}
|
||||
return nil, -1, err
|
||||
}
|
||||
}
|
||||
@ -795,21 +787,26 @@ func (r *layerStore) Put(id string, parentLayer *Layer, names []string, mountLab
|
||||
for flag, value := range flags {
|
||||
layer.Flags[flag] = value
|
||||
}
|
||||
savedIncompleteLayer := false
|
||||
if diff != nil {
|
||||
layer.Flags[incompleteFlag] = true
|
||||
err = r.Save()
|
||||
if err != nil {
|
||||
// We don't have a record of this layer, but at least
|
||||
// try to clean it up underneath us.
|
||||
r.driver.Remove(id)
|
||||
if err2 := r.driver.Remove(id); err2 != nil {
|
||||
logrus.Errorf("While recovering from a failure saving incomplete layer metadata, error deleting layer %#v: %v", id, err2)
|
||||
}
|
||||
return nil, -1, err
|
||||
}
|
||||
savedIncompleteLayer = true
|
||||
size, err = r.applyDiffWithOptions(layer.ID, moreOptions, diff)
|
||||
if err != nil {
|
||||
if r.Delete(layer.ID) != nil {
|
||||
if err2 := r.Delete(layer.ID); err2 != nil {
|
||||
// Either a driver error or an error saving.
|
||||
// We now have a layer that's been marked for
|
||||
// deletion but which we failed to remove.
|
||||
logrus.Errorf("While recovering from a failure applying layer diff, error deleting layer %#v: %v", layer.ID, err2)
|
||||
}
|
||||
return nil, -1, err
|
||||
}
|
||||
@ -817,9 +814,20 @@ func (r *layerStore) Put(id string, parentLayer *Layer, names []string, mountLab
|
||||
}
|
||||
err = r.Save()
|
||||
if err != nil {
|
||||
// We don't have a record of this layer, but at least
|
||||
// try to clean it up underneath us.
|
||||
r.driver.Remove(id)
|
||||
if savedIncompleteLayer {
|
||||
if err2 := r.Delete(layer.ID); err2 != nil {
|
||||
// Either a driver error or an error saving.
|
||||
// We now have a layer that's been marked for
|
||||
// deletion but which we failed to remove.
|
||||
logrus.Errorf("While recovering from a failure saving finished layer metadata, error deleting layer %#v: %v", layer.ID, err2)
|
||||
}
|
||||
} else {
|
||||
// We don't have a record of this layer, but at least
|
||||
// try to clean it up underneath us.
|
||||
if err2 := r.driver.Remove(id); err2 != nil {
|
||||
logrus.Errorf("While recovering from a failure saving finished layer metadata, error deleting layer %#v in graph driver: %v", id, err2)
|
||||
}
|
||||
}
|
||||
return nil, -1, err
|
||||
}
|
||||
layer = copyLayer(layer)
|
||||
@ -1149,6 +1157,17 @@ func (r *layerStore) tspath(id string) string {
|
||||
return filepath.Join(r.layerdir, id+tarSplitSuffix)
|
||||
}
|
||||
|
||||
// layerHasIncompleteFlag returns true if layer.Flags contains an incompleteFlag set to true
|
||||
func layerHasIncompleteFlag(layer *Layer) bool {
|
||||
// layer.Flags[…] is defined to succeed and return ok == false if Flags == nil
|
||||
if flagValue, ok := layer.Flags[incompleteFlag]; ok {
|
||||
if b, ok := flagValue.(bool); ok && b {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (r *layerStore) deleteInternal(id string) error {
|
||||
if !r.IsReadWrite() {
|
||||
return errors.Wrapf(ErrStoreIsReadOnly, "not allowed to delete layers at %q", r.layerspath())
|
||||
@ -1157,6 +1176,18 @@ func (r *layerStore) deleteInternal(id string) error {
|
||||
if !ok {
|
||||
return ErrLayerUnknown
|
||||
}
|
||||
// Ensure that if we are interrupted, the layer will be cleaned up.
|
||||
if !layerHasIncompleteFlag(layer) {
|
||||
if layer.Flags == nil {
|
||||
layer.Flags = make(map[string]interface{})
|
||||
}
|
||||
layer.Flags[incompleteFlag] = true
|
||||
if err := r.Save(); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
// We never unset incompleteFlag; below, we remove the entire object from r.layers.
|
||||
|
||||
id = layer.ID
|
||||
err := r.driver.Remove(id)
|
||||
if err != nil {
|
||||
|
Reference in New Issue
Block a user