Commit Graph

84 Commits

Author SHA1 Message Date
openshift-merge-bot[bot] 6f4bc1fa7c
Merge pull request #2305 from kolyshkin/for-range
Use for range over integers
2025-04-01 21:57:19 +00:00
Kir Kolyshkin 73b194b8ed Use for range over integers
This form is available since Go 1.22 (see
https://tip.golang.org/ref/spec#For_range) and will probably be seen
more and more in the new code.

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
2025-03-31 15:39:12 -07:00
Kir Kolyshkin c3ff7f58df Use any instead of interface{}
It's available since Go 1.18 (see https://pkg.go.dev/builtin#any).

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
2025-03-31 15:37:25 -07:00
Jan Rodák 43d00099b2
Refactor of copying maps
Removes the duplicate copy*Map function using the general function newMapFrom.
Reduces the allocation of empty maps using the copyMapPrefferingNil function.
This change may affect the behavior so that instead of an empty allocated map, a nil will be returned.

Signed-off-by: Jan Rodák <hony.com@seznam.cz>
2024-10-25 10:24:48 +02:00
Jan Rodák 8a4741b74d
Refactor operations with slices
Removes duplicate copy*Slice functions using a generic copy function
or replaces them with the slices.Clone function.
Also simplifies the stringSliceWithoutValue function.
These changes should not change the behavior.

Signed-off-by: Jan Rodák <hony.com@seznam.cz>
2024-10-25 10:23:12 +02:00
Jan Rodák 5537f8ab2d
Revert the use of the slices.Clone function
because it does not return nil when the slice length is 0.
This behavior caused the slices.Clone function to allocate
a unnecessary amount of memory when the slice length is 0,
and the c/common tests failed.

Signed-off-by: Jan Rodák <hony.com@seznam.cz>
2024-10-08 14:26:51 +02:00
Miloslav Trmač 35b3e0f41b Avoid unnecessary manually-coded loops
Use the "slices", "maps" standard library packages, or other
readily-available features.

Should not change behavior.

Signed-off-by: Miloslav Trmač <mitr@redhat.com>
2024-09-05 19:45:45 +02:00
Miloslav Trmač 1fa3161756 Use slices.Delete* instead of manual append
Conservatively use Index* + Delete to delete the
first element where it's not obvious that the code would really
want to delete all instances.

Signed-off-by: Miloslav Trmač <mitr@redhat.com>
2024-09-05 19:44:49 +02:00
Miloslav Trmač 751c13d2a0 Use slices.Clone where appropriate
Signed-off-by: Miloslav Trmač <mitr@redhat.com>
2024-09-05 19:44:47 +02:00
Kir Kolyshkin a4d8f720a2 Format sources with gofumpt
gofumpt is a superset of gofmt, enabling some more code formatting
rules.

This commit is brought to you by

	gofumpt -w .

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
2023-05-26 16:17:31 -07:00
Giuseppe Scrivano ed76ab945c
store: ensure lockfile is updated before writes
The lockfile's write record is now updated prior to the actual write
operation.  This ensures that, in the event of an unexpected
termination, other processes are correctly notified of an initiated
write operation.

Signed-off-by: Giuseppe Scrivano <gscrivan@redhat.com>
2023-05-18 23:44:23 +02:00
Nalin Dahyabhai b0c1c886c3 "pull up" images when creating them, too
We previously started "pulling up" images when we changed their names,
and started denying the presence of images in read-only stores which
shared their ID with an image in the read-write store, so that it would
be possible to "remove" names from an image in read-only storage.  We
forgot about the Flags field, so start pulling that up, too.

Do all of the above when we're asked to create an image, since denying
the presence of images with the same ID in read-only stores would
prevent us from finding the image by any of the names that it "had" just
a moment before we created the new record.

Signed-off-by: Nalin Dahyabhai <nalin@redhat.com>
2023-04-06 18:21:11 -04:00
Nalin Dahyabhai f3808272d8 Drop nameLooksLikeID()
Replace the newer nameLooksLikeID() function with calls to
stringid.Validate(), which does the same thing.

Signed-off-by: Nalin Dahyabhai <nalin@redhat.com>
2023-04-03 10:21:35 -04:00
Nalin Dahyabhai 0f2bccfa56 Complete "pulling up" of images in updateNames()
When updateNames() copies an image's record from a read-only store into
the read-write store, copy the accompanying data as well.

Add fields for setting data items at creation-time to LayerOptions,
ImageOptions, and ContainerOptions to make this easier for us and our
consumers.

Replace the store-specific Create() (and the one CreateWithFlags() and
Put()) with private create() and put() methods, since they're not
intended for consumption outside of this package, and add Flags to the
options structures we pass into those methods.  In create() methods,
make copies of those passed-in options structures before modifying any
of their contents.

Signed-off-by: Nalin Dahyabhai <nalin@redhat.com>
2023-03-31 10:36:30 -04:00
Nalin Dahyabhai 6d91bc12f3 cmd: add a CLI wrapper for GarbageCollect
Add "gc" as an action for the CLI wrapper, for running the
GarbageCollect() method.

Signed-off-by: Nalin Dahyabhai <nalin@redhat.com>
2023-01-26 16:09:00 -05:00
Miloslav Trmač 24d3ecb9bb Optimize the "no changes" case of containerStore.startReading further
In that case, we can just get read locks, confirm that nothing has changed,
and continue; no need for any serialization on exclusively holding
loadMut / inProcessLock.

Signed-off-by: Miloslav Trmač <mitr@redhat.com>
2023-01-04 00:29:27 +01:00
Miloslav Trmač 76ea82571a Rework in-process concurrency control of containerStore
Instead of basing this on exclusivity loading via loadMut (which is AFAICS correct),
use a very traditional read-write lock to protect the fields of containerStore.
This is primarily so that all three stores use the same design.

Also explicitly document how concurrent access to fields of containerStore
is managed.

Signed-off-by: Miloslav Trmač <mitr@redhat.com>
2023-01-03 23:47:10 +01:00
Miloslav Trmač 4a043b5dc1 Annotate containerStore methods with the required lock access.
Should not change behavior.

Signed-off-by: Miloslav Trmač <mitr@redhat.com>
2023-01-03 23:47:07 +01:00
Miloslav Trmač 55d11a0389 Make change tracking error-resilient
Only update recorded LastWrite values _after_ we succesfully reload
container/image/layer stores; so, if the reload fails, the functions
will keep failing instead of using obsolete (and possibly partially loaded
and completely invalid) data.

Also, further improve mount change tracking, so that if layerStore.load()
loads it, we don't reload it afterwards.

This does not change the store.graphLock users; they will need to be cleaned up
more comprehensively, and separately, in the future.

Signed-off-by: Miloslav Trmač <mitr@redhat.com>
2022-11-29 18:12:43 +01:00
Miloslav Trmač b2d3379ed4 Deprecate *LockFile.Modified and *LockFile.Touch
They are a shared state across all users of the *LockFile in the process,
and therefore incorrect to use for any single consumer for change tracking.

Direct users to user the new GetLastWrite, ModifiedSince, and RecordWrite,
instead, and convert all c/storage users.

In addition to just being correct, the new API is also more efficient:
- We now initialize stores with GetLastWrite before loading state;
  so, we don't trigger an immediate reload on the _second_ use of a store,
  due to the problematic semantics of .Modified().
- Unlike Modified() and Touch(), the new APi can be safely used without
  locking *LockFile.stateMutex, for a tiny speedup.

The conversion is, for now, trivial, just immediately updating the lastWrite
value after the ModifiedSince call.  That will get better.

Signed-off-by: Miloslav Trmač <mitr@redhat.com>
2022-11-29 18:12:43 +01:00
Miloslav Trmač b74fdf4d23 Convert all c/storage users of Locker to *lockfile.LockFile
This will allow us to benefit from new features.

Should not change behavior.

Signed-off-by: Miloslav Trmač <mitr@redhat.com>
2022-11-29 18:12:43 +01:00
Alexander Larsson ddf18d41da Add Store.GarbageCollect() method
This looks in the container store for existing data dirs with ids not in
the container files and removes them. It also adds an (optional) driver
method to list available layers, then uses this and compares it to the
layers json file and removes layers that are not references.

Losing track of containers and layers can potentially happen in the
case of some kind of unclean shutdown, but mainly it happens at reboot
when using transient storage mode. Such users are recommended to run
a garbage collect at boot.

Signed-off-by: Alexander Larsson <alexl@redhat.com>
2022-11-14 16:36:30 +01:00
Alexander Larsson a17a35a8a2 containers store: handle volatile and transient containers
This splits up the containers.json file in the containers store into
two, adding the new file `volatile-containers.json`. This new file is
saved using the NoSync options, which is faster but isn't robust in
the case of an unclean shutdown.

In the standard case, only containers marked as "volatile" (i.e. those
started with `--rm`) are stored in the volatile json file. This means
such containers are faster, but may get lost in case of an unclean
shutdown. This is fine for these containers though, as they are not
meant to persist.

In the transient store case, all containers are stored in the volatile
json file, and it (plus the matching lock file) is stored on runroot
(i.e. tmpfs) instead of the regular directory. This mean all
containers are fast to write, and none are persisted across boot.

Signed-off-by: Alexander Larsson <alexl@redhat.com>
2022-11-14 16:36:30 +01:00
Miloslav Trmač 66f06a85ac Fix locking of containerStore.BigDataDigest
It requires a WRITE lock.

Signed-off-by: Miloslav Trmač <mitr@redhat.com>
2022-11-11 14:20:21 +01:00
Miloslav Trmač e2b414c6db Fix locking of containerStore.BigDataSize
It requires a WRITE lock.

Signed-off-by: Miloslav Trmač <mitr@redhat.com>
2022-11-11 14:20:21 +01:00
Miloslav Trmač 34ab9ed097 Remove unnecessary writes to BigDataDigests and BigDataSizes
This could, hypothetically, make the functions readers that are safe
to use concurrently with other readers.

Well, except for the SetBigData call...

So it's just a microoptimization.

Signed-off-by: Miloslav Trmač <mitr@redhat.com>
2022-11-11 14:20:21 +01:00
Miloslav Trmač 29dbc1df3a Clean up duplicate container names in readers instead of failing
Signed-off-by: Miloslav Trmač <mitr@redhat.com>
2022-11-10 16:13:53 +01:00
Miloslav Trmač 859d1791b8 In load methods, track the inconsistency we want to fix
... as an error value instead of just a boolean.  That
will allow extending the logic to more kinds of inconsistencies,
and consolidates the specifics of the inconsistency knowledge
into a single place.

Signed-off-by: Miloslav Trmač <mitr@redhat.com>
2022-11-10 16:13:53 +01:00
Miloslav Trmač 765414fbdb Use the simplest possible error handling flow in reloadIfChanged
... instead of combining control flow branches; we will change
behavior on some of them.

Should not change behavior.

Signed-off-by: Miloslav Trmač <mitr@redhat.com>
2022-11-10 16:13:53 +01:00
Miloslav Trmač f6776bf5dc Remove always-true err == nil checks
Signed-off-by: Miloslav Trmač <mitr@redhat.com>
2022-10-25 20:54:12 +02:00
Miloslav Trmač 7c5820ae1d Don't silently ignore failures to decode metadata JSON
Also tighten the scope of some error variables a bit.

Signed-off-by: Miloslav Trmač <mitr@redhat.com>
2022-10-25 20:50:23 +02:00
Miloslav Trmač 268b3e84df Modify containerStore not to rely on lockfile.Locked()
Instead, have the callers of ReloadIfChanged provide the
locking state.

Signed-off-by: Miloslav Trmač <mitr@redhat.com>
2022-10-21 21:10:33 +02:00
Miloslav Trmač adae72bf37 Move containerStore.ReloadIfChanged
... to be closer to the lock / load set of methods.

Only moves unchanged code, should not change behavior.

Signed-off-by: Miloslav Trmač <mitr@redhat.com>
2022-10-17 21:39:19 +02:00
Miloslav Trmač b44c193f3f Remove Lock/Unlock methods from rwContainerStore
They are now only used in the constructor, so use a variant
of startWriting instead.  This code path is not performance-critical,
so let's share as much code as possible to ensure consistency
in locking.

Should not change behavior.

Signed-off-by: Miloslav Trmač <mitr@redhat.com>
2022-10-17 21:39:15 +02:00
Miloslav Trmač 4c55fadd03 Remove Save() from rwContainerStore API
It is done implicitly by all writers already.

Also fix the documentation not to point at an explicit Touch(),
which is not actually necessary.

Should not change behavior.

Signed-off-by: Miloslav Trmač <mitr@redhat.com>
2022-10-17 21:35:15 +02:00
Miloslav Trmač 58f1120738 Remove Load() and ReloadIfChanged() from rwContainerStore API
Callers should just use startReading/startWriting.

Should not change behavior.

Signed-off-by: Miloslav Trmač <mitr@redhat.com>
2022-10-17 21:34:53 +02:00
Miloslav Trmač 409ee3ecbd Remove unused lockfile forwarders from rwContainerStore API
The only callers are internal, have them access r.lockfile directly.

Should not change behavior.

Signed-off-by: Miloslav Trmač <mitr@redhat.com>
2022-10-17 21:05:05 +02:00
Miloslav Trmač a64b85d256 Remove completely unused methods from rwContainerStore
Exposing the internals of the lock is not necessary, and exposes
too many implementation details.

Should not change behavior.

Signed-off-by: Miloslav Trmač <mitr@redhat.com>
2022-10-17 21:04:29 +02:00
Miloslav Trmač dcefc6da00 Replace containerStore.{Lock,Unlock} with {startWriting,stopWriting}
This integrates ReloadIfChanges, and makes it clearer that the responsibility
for maintaining locking details is with the containerStore; we can change it
in a single place.

Should not change behavior.

Signed-off-by: Miloslav Trmač <mitr@redhat.com>
2022-10-17 21:03:48 +02:00
Miloslav Trmač 243ec619f7 Replace containerStore.{RLock,Unlock} with {startReading,stopReading}
This integrates ReloadIfChanges, and makes it clearer that the responsibility
for maintaining locking details is with the containerStore; we can change it
in a single place.

Should not change behavior.

Signed-off-by: Miloslav Trmač <mitr@redhat.com>
2022-10-17 21:03:39 +02:00
Miloslav Trmač 749be716f3 Copy methods from included interfaces directly into rwContainerStore
... so that we can modify/replace them.

Should not change behavior.

Signed-off-by: Miloslav Trmač <mitr@redhat.com>
2022-10-17 21:03:27 +02:00
Daniel J Walsh d02a89afb6
Merge branch 'main' into warnings 2022-10-14 13:46:03 -04:00
Miloslav Trmač 703cbe965b Simplify the name update call stack
Instead of going
	3 store methods
	store.updateNames+enum
	3 sub-store methods
	subStore.updateNames+enum
	applyNameOperation+enum,
simplify to
	3 store methods
	store.updateNames+enum
	subStore.updateNames+enum
	applyNameOperation+enum,

Should not change behavior. Looking purely at updateNameOperation,
invalid values would now be detected after doing more work,
but there is no way for an external caller to trigger use of
an invalid value anyway.

Signed-off-by: Miloslav Trmač <mitr@redhat.com>
2022-10-14 17:23:08 +02:00
Miloslav Trmač 5e410ef763 Misc individual warning fixes
Signed-off-by: Miloslav Trmač <mitr@redhat.com>
2022-10-14 17:17:53 +02:00
Miloslav Trmač 821084ee68 Make all the various *Store interfaces, apart from storage.Store, private
There is no public way to obtain implementations of these interfaces; so
replace the public interfaces with private ones, to make it clear that we
_can_ modify them.

For formal API compatibility, preserve the old interface definitions
as copies.

Should not change behavior.

Signed-off-by: Miloslav Trmač <mitr@redhat.com>
2022-10-11 19:25:19 +02:00
Miloslav Trmač 082a8161ed Remove lockfile.Locker.RecursiveLock
It is not valid as currently implemented, and there is no known user.

Signed-off-by: Miloslav Trmač <mitr@redhat.com>
2022-10-07 19:45:14 +02:00
Miloslav Trmač a02dbdbfa1 Only touch lock files after successful JSON writes
AtomicWriteFile truly is atomic, it only changes the file
on success. So there's no point notifying other processes about
a changed file if we failed, they are going to see the same JSON data.

Signed-off-by: Miloslav Trmač <mitr@redhat.com>
2022-10-01 02:46:52 +02:00
Miloslav Trmač d1de06c839 Be explicit about how we ignore errors using trucindex.TruncIndex
This does not change behavior, it just makes it clearer
what is going on.

Signed-off-by: Miloslav Trmač <mitr@redhat.com>
2022-10-01 02:46:52 +02:00
Daniel J Walsh c9c7d28334
Fix accessing containers and image locks
Match containers and image lock to the new layer lock method.
in https://github.com/containers/storage/pull/1351

Signed-off-by: Daniel J Walsh <dwalsh@redhat.com>
2022-09-28 05:45:56 -04:00
Nalin Dahyabhai 449ffb0f8d Use defined constants for flag names
Use constants for the names of flags that we set in Flags maps that we
store in layer/image/container records, to make it easier to avoid
possible breakages due to typos in the future.

Signed-off-by: Nalin Dahyabhai <nalin@redhat.com>
2022-09-14 10:54:54 -04:00