Commit Graph

11 Commits

Author SHA1 Message Date
Miloslav Trmač ca05f7b600 Don't set (struct flock).l_pid
This field is only used for passing values back from the kernel.

Signed-off-by: Miloslav Trmač <mitr@redhat.com>
2019-04-02 23:02:31 +02:00
Miloslav Trmač f71dab2d08 Rename getLockFile to createLockerForPath, and document it
It's terribly confusing to have different functions named getLockFile and getLockfile;
rename the platform-specific one-shot one to createLockerForPath.

Also document all its surprising platform differences.

Signed-off-by: Miloslav Trmač <mitr@redhat.com>
2019-04-02 23:02:31 +02:00
Valentin Rothberg 8017d7a735 add digest locks
Add a method to generate a lock file for a specific digest.  Such a
digest-specific lock file is needed to synchronize threads and processes
when copying blobs from a registry to the containers-storage.

Whenever a layer is about to get copied, the lock must be acquired which
indicates to other processes and threads that the layer/blob is already
being copied.

To avoid leaking file descriptors for long-living users of
containers/storage, such as CRI-O, open and close the file on demand
during Lock() and Unlock().  The internal reference counters allows to
determine if we are the first or last user.

Note: as deleting the lock files is subject to race conditions, we place
the lock files in a graph-specific directory in the runroot.  Since the
runroot is a tmpfs, the files will be cleanup during reboot.

Signed-off-by: Valentin Rothberg <rothberg@redhat.com>
2019-03-28 09:53:02 +01:00
Nalin Dahyabhai aa5c9b7871 lockfile: add some unit tests
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>
2019-02-28 13:03:18 -05:00
Nalin Dahyabhai cf287aff45 lockfile_unix: add a couple of additional safety checks
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>
2019-02-26 15:51:48 -05:00
Nalin Dahyabhai 45b0aa27aa Locker.Locked(): clarify that we're checking for write locks
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>
2019-02-26 14:19:50 -05:00
Valentin Rothberg 5ecc5f23b3 lockfile: use a sync.RWMutex
Use a `sync.RWMutex` to synchronize the lockfile within the same process
space.

Signed-off-by: Valentin Rothberg <rothberg@redhat.com>
2019-02-26 14:19:15 -05:00
Valentin Rothberg 68d65106a0 enable parallel blob reads
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>
2019-02-15 15:00:37 +01:00
Valentin Rothberg f58686dcce lockfile: implement reader-writer locks
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>
2019-02-15 09:49:44 +01:00
Zac Medico c7ba5749d4
Add lock sanity checks to Save() methods
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>
2018-08-24 20:31:47 -07:00
Vincent Batts 6217167281
lockfile: reshape for multiplatform
this stubs out for having platform-independent file locking

This still functions the same on `GOOS=linux`, and now succeeds for
`GOOS=windows`. But still fails on `freebsd`, `darwin`, `solaris`, etc

Signed-off-by: Vincent Batts <vbatts@hashbangbash.com>
2018-01-30 05:00:58 -05:00