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>
Remove compatibility hacks for older versions which didn't track size or
digest information for big data items, hopefully without any impact.
Signed-off-by: Nalin Dahyabhai <nalin@redhat.com>
These aren't exhaustive, but they're something.
Also change Modified() to not return an ENOSPC error when the length of
the last-writer ID doesn't match the one we'd use, since it's enough
that it's different from the one we'd use, whatever its length.
Signed-off-by: Nalin Dahyabhai <nalin@redhat.com>
Panic in Touch() if we're not holding a write lock in one of our
threads. Hopefully that's the one we're being called from, but we
don't guarantee that.
Panic in Modified() if we're not holding some kind of lock.
As with Locked(), this doesn't keep us from getting a false positive
when it's a different thread that holds the lock, but it's better than
nothing.
Signed-off-by: Nalin Dahyabhai <nalin@redhat.com>
Separate loading and saving the mountpoints.json table out of the main
layer load/save paths so that they can be called independently, so that
we can mount and unmount layers (which requires that we update that
information) when the layer list itself may only be held with a read
lock.
The new loadMounts() and saveMounts() methods need to be called only for
read-write layer stores. Callers that just refer to the mount
information can take a read lock on the mounts information, but callers
that modify the mount information need to acquire a write lock.
Break the unwritten "stores don't manage their own locks" rule and have
the layer store handle managing the lock for the mountpoints list, with
the understanding that the layer store's lock will always have been
acquired before we try to take the mounts lock.
Signed-off-by: Nalin Dahyabhai <nalin@redhat.com>
Don't attempt to remove conflicting names or finish layer cleanups if we
only have a read-only lock on layer or image stores, since doing either
means we'd have to modify the list of layers or images, and our lock
that we've obtained doesn't allow us to do that.
Signed-off-by: Nalin Dahyabhai <nalin@redhat.com>
Clarify that Locker.Locked() checks if we have a write lock, since
that's what we care about whenever we check it.
Signed-off-by: Nalin Dahyabhai <nalin@redhat.com>
Print backtrace information when displaying an error returned by our
API, to make troubleshooting tests a bit easier.
Signed-off-by: Nalin Dahyabhai <nalin@redhat.com>
Enable executing parallel `GetBlob()` executions in containers/image by
using reader-lock acquisitions in `ImageBigData()` and `Diff()`.
Signed-off-by: Valentin Rothberg <rothberg@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>
Deferring method calls on loop variables must be avoided by all means as
the calls will be invoked on the last item of the loop.
The intermediate fix used in this commit is to allocate a new variable
on the heap for each loop iteration. An example transformation is:
FROM:
for _, x := range x_slice {
x.Lock()
defer x.Unlock()
}
TO:
for _, x_itr := range x_slice {
x := x_itr
x.Lock()
defer x.Unlock()
}
Signed-off-by: Valentin Rothberg <rothberg@redhat.com>
When we removed all traces of override_kernel_check, we created a
situation where older configuration files would suddenly start causing
us to emit an error at startup. Soften that to a warning, for now at
least.
Signed-off-by: Nalin Dahyabhai <nalin@redhat.com>
Change how we compute digests for BigData items with names that start
with "manifest" so that we use the image library's manifest.Digest()
function, which knows how to preprocess schema1 manifests to get the
right value, instead of just trying to finesse it.
Track the digests of multiple manifest-named items for images.
Signed-off-by: Nalin Dahyabhai <nalin@redhat.com>
Display the output from commands before we check their exit status, so
that we can see what they output if a check fails.
Signed-off-by: Nalin Dahyabhai <nalin@redhat.com>
Need to access the storage structs in the machine-config
operator code for container runtime configuration but
with it being in store.go, it is pullng in way too many
dependencies. Moving it out to a separate package cuts down
the dependencies by a huge amount.
Signed-off-by: Urvashi Mohnani <umohnani@redhat.com>