We now use the golang error wrapping format specifier `%w` instead of the
deprecated github.com/pkg/errors package.
Signed-off-by: Sascha Grunert <sgrunert@redhat.com>
Adds AddNames and RemoveNames so operations which are invoked in parallel
manner can use it without destroying names from storage.
For instance
We are deleting names which were already written in store.
This creates faulty behavior when builds are invoked in parallel manner, as
this removes names for other builds.
To fix this behavior we must append to already written names and
override if needed. But this should be optional and not break public API
Following patch will be used by parallel operations at podman or buildah end, directly or indirectly.
Signed-off-by: Aditya R <arajan@redhat.com>
when the container specifies some mappings to be applied, verify that
they are not overlapping and give a clearer error message.
Closes: https://github.com/containers/storage/issues/1127
Signed-off-by: Giuseppe Scrivano <gscrivan@redhat.com>
add a new class of containers that are not guaranteed to survive a
crash. The advantage of such containers is that storage can be
optimized to skip some synchronizations with the underlying storage.
Signed-off-by: Giuseppe Scrivano <gscrivan@redhat.com>
Use RLock() to lock stores that we know are read-only, and panic in
Lock() if we know that we're not a read-write lock.
Signed-off-by: Nalin Dahyabhai <nalin@redhat.com>
Add a RecursiveLock() API to allow for recursive acquisitions of a
writer lock within the same process space. This is yet another
requirement for the copy-detection mechanism in containers/image where
multiple goroutines can be pulling the same blob. Having a recursive
lock avoids a complex synchronization mechanism as the commit order is
determinted by the corresponding index in the image.
Signed-off-by: Valentin Rothberg <rothberg@redhat.com>
Drop our dependency on the image library's manifest package by requiring
that callers pass its Digest() function to us as a callback. This makes
our CLI test/diagnostic tool calculate digests of s1 manifests
incorrectly, but that's not something that we were testing.
Signed-off-by: Nalin Dahyabhai <nalin@redhat.com>
Implement reader-writer locks to allow allow multiple readers to hold
the lock in parallel.
* The locks are still based on fcntl(2).
* Changing the lock from a reader to a writer and vice versa will block
on the syscall.
* A writer lock can be held only by one process. To protect against
concurrent accesses by gourtines within the same process space, use a
writer mutex.
* Extend the Locker interface with the `RLock()` method to acquire a
reader lock. If the lock is set to be read-only, all calls to
`Lock()` will be redirected to `RLock()`. A reader lock is only
released via fcntl(2) when all gourtines within the same process space
have unlocked it. This is done via an internal counter which is
protected (among other things) by an internal state mutex.
* Panic on violations of the lock protocol, namely when calling
`Unlock()` on an unlocked lock. This helps detecting violations in
the code but also protects the storage from corruption. Doing this
has revealed some bugs fixed in ealier commits.
Signed-off-by: Valentin Rothberg <rothberg@redhat.com>
We want to allow tools like podman/buildah to override default storage
container mount options on a container by container basis.
For example if the default mount options for containers/storage include
nodev or nosuid, we want to allow podman to turn these off if the user
specifies --privileged.
We also might want to turn off certain user namespace flags that will cause
buildah and podman build to work slower when creating container images.
Signed-off-by: Daniel J Walsh <dwalsh@redhat.com>
I have experienced "layer not known" corruption triggered by concurrent
buildah/skopeo processes, and hopefully lock sanity checks will help to
prevent this kind of problem.
Signed-off-by: Zac Medico <zmedico@gmail.com>
Signed-off-by: Marco Vedovati <mvedovati@suse.com>
Make the error message more informative by specifying the duplicate name
and the existing container ID.
When creating new Layers, Images, or Containers, only try to copy the
newly-created results if we actually created them.
Signed-off-by: Nalin Dahyabhai <nalin@redhat.com>
Add support to the Store objects for per-container UID/GID mapping.
* UID and GID maps can be specified when creating layers and containers.
* If mapping options are specified when creating a container, those
options are used for creating the layer which we create for the
container and recorded with the container for convenience.
* A layer defaults to using the ID mapping configured for its parent, or
to the default which was used to initialize the Store object if it has
no parent.
Signed-off-by: Nalin Dahyabhai <nalin@redhat.com>
Always copy slices and maps in Layer, Image, and Container structures
before handing them back to callers so that, even if they modify them
directly, they won't accidentally mess with our in-memory copies of
those fields in the copies of the structures that we're using.
Signed-off-by: Nalin Dahyabhai <nalin@redhat.com>
Teach image and container store types to also track the digests of "big
data" items that we have them store.
Signed-off-by: Nalin Dahyabhai <nalin@redhat.com>
When we read itms from disk, if maps in the structures are empty, they
won't be allocated as part of the decoding process. When we
subsequently go to read or write something from such a map, make sure
it's been initialized.
Add some validation of names that we convert to file names, and of
digest values, so that we can be more precise about the error code we
return when there's a problem with the values.
Signed-off-by: Nalin Dahyabhai <nalin@redhat.com>
Take a guess at the final size of some slices that we build up item by
item, and try to allocate enough capacity for them before starting to
build them. It's probably not a big speedup, though.
Signed-off-by: Nalin Dahyabhai <nalin@redhat.com>
We already deduplicated names in Store.SetNames(), but we weren't also
doing that when creating layers, images, and containers, or in the
individual store SetNames() methods.
Signed-off-by: Nalin Dahyabhai <nalin@redhat.com>
Use the standard library's "errors" package to create errors so that
backtraces in wrapped errors terminate at the point where the error was
first wrapped, and not at the line where we created the error, which
isn't as useful for troubleshooting.
Signed-off-by: Nalin Dahyabhai <nalin@redhat.com>
When Delete:ing a layer or a container the code was always allocating a
new slice just to remove an element from the original slice.
Profiling cri-o with c/storage showed that doing it at every delete is
pretty expensive:
```
. . 309: newContainers := []Container{}
. . 310: for _, candidate := range r.containers
{
. . 311: if candidate.ID != id {
528.17kB 528.17kB 312: newContainers =
append(newContainers, candidate)
. . 313: }
. . 314: }
. . 552: newLayers := []Layer{}
. . 553: for _, candidate := range
r.layers {
. . 554: if candidate.ID != id {
1.03MB 1.03MB 555: newLayers =
append(newLayers, candidate)
. . 556: }
. . 557: }
. . 558: r.layers = newLayers
```
This patch just filters out the element to remove from the original
slice w/o allocating a new slice. After this patch, no memory overhead
anymore is shown in the profiler.
Signed-off-by: Antonio Murdaca <runcom@redhat.com>
Add a Created field to Layer, Image, and Container structures that we
intialize when creating one of them.
Signed-off-by: Nalin Dahyabhai <nalin@redhat.com>
We need to be able to acquire locks on storage areas which aren't
mounted read-write, which return errors when we attempt to open a file
in the mode where we can take write locks on them. This patch adds a
read-only lock type for use in those cases.
A given file can be opened for read-locking or write-locking, but not
both. Our Locker interface gains an IsReadWrite() method to let callers
tell the difference.
Based on patches by Dan Walsh <dwalsh@redhat.com>
Signed-off-by: Nalin Dahyabhai <nalin@redhat.com>
Fix consistency errors we'd hit after creating or deleting a layer,
image, or container, by replacing the slice of items in their respective
stores with a slice of pointers to items, so that pointers in name- and
ID-based indexes don't become invalid when the slice is resized.
Signed-off-by: Nalin Dahyabhai <nalin@redhat.com>