When run in a shared environment ( as opposed as a machine created for
the purpose of running this test only ), it is important to cleanup
leftovers to avoid poluting the /tmp space. Create a common temporary
directory for all tmp files.
Signed-off-by: Loic Dachary <loic@dachary.org>
snap/clone promotion, flush, and other goodies
This is now passing the thrashing with both cache and snap ops:
sage-2014-01-13_15:45:26-rados:thrash-wip-cache-snap-testing-basic-plana
Reviewed-by: Samuel Just <sam.just@inktank.com>
find_object_context() has all the logic to choose a particular clone given
a logical snap. In the trim case, we want none of that: we just need to
pull the obc for a specific clone instance. Note that this changes
none of the failure cases (previous we asserted r == 0).
Signed-off-by: Sage Weil <sage@inktank.com>
We were fabricating an object_info_t correctly and writing it to disk, but
it was not reflected by the in-memory ObjectContext. If something came
along quickly (like backfill) and tried to use it, the info would be
invalid.
Fix this by fabricating it in the obc and copying it to the new_obs for
the update.
Fixes: #7122
Signed-off-by: Sage Weil <sage@inktank.com>
Previously, if a snap was deleted but the clone was there and we hadn't
trimmed it yet, we would still return the data. Instead, return ENOENT
unconditionally (even it's not removed yet). This makes the behavior from
the client perspective more predictable and conistent.
Signed-off-by: Sage Weil <sage@inktank.com>
This reliably returns ENODEV due to the test at the finish of flush. Not
because we are actually racing with trim, though: the trimmer doesn't run
at all. I believe it captures the important property, though. Namely:
we should not write a promoted object that is "behind" the snap trimmer's
progress. The fact that we are in front of it (the trimmer hasn't started
yet) should not matter since the object is logically deleted anyway.
We probably want to make the OSD return ENODEV on read in the normal case
when you try to access a clone that is pending trimming.
Signed-off-by: Sage Weil <sage@inktank.com>
If the object no longer exists (for example, because the snap trimmer just
killed it) clean up the flush state without trying to mark the object
clean.
Signed-off-by: Sage Weil <sage@inktank.com>
If we are promoting a clone and realize that the object is no longer
defined for any snaps, abort the copy and delete any temp object.
If the defined snaps have changed, make sure they are updated in memory
so that on promote completion the snapshot metadata is correct.
Signed-off-by: Sage Weil <sage@inktank.com>
Previously the caller was generating a temp object name and passing it
down in severaly different ways. Instead, generate one when we realize
that we need it, and store it in *one* place (CopyResults), where
the completions can get at the information.
Signed-off-by: Sage Weil <sage@inktank.com>
Make other find_object_context() callers handle the case where the object
in question needs to be promoted. We add a flag here that forces a promote
for these secondary objects so that the entire operation happens in the
same pool. Forwarding is not allowed in this case.
Signed-off-by: Sage Weil <sage@inktank.com>
If we have a clean object and clone it in make_writeable(), the clone
should also be clean (it does not need to be written back to the base
pool). If the object was dirty, the clone should be dirty.
Signed-off-by: Sage Weil <sage@inktank.com>
Consider:
- base and cache have same object foo; marked clean in cache pool
- modify + clone foo in cache pool. foo clone is clean.
- foo clone is evicted
- foo clone is read, and promoted
- we read foo@something from base pool, and get the head's content
copy-get does not provide us with a snaps list. Instead, we use the
snap_seq from the head to infer what the snaps vector was in the cache
pool and will be in the base pool when we flush the updates to the object.
Signed-off-by: Sage Weil <sage@inktank.com>
This is needed by the cache layer when reading a logical snap from a head
object on the backend in order to correctly recreate the clone in the
cache layer.
Signed-off-by: Sage Weil <sage@inktank.com>
Do not promote a clone for a snap that we know doesn't exist. If
find_object_context() didn't give us a missing_oid, there is nothing to
promote.
Signed-off-by: Sage Weil <sage@inktank.com>
This makes its results reliable. Otherwise, we can't mix the is_dirty
test with flush, which eliminates much of its value.
Signed-off-by: Sage Weil <sage@inktank.com>
If the next oldest clone is dirty, we cannot flush. That is, we must
always flush starting with the oldest dirty clone.
Note that we can never have a sequence like dirty -> clean -> dirty,
because clones are only dirty on creation, are created in order, and cannot
be flushed (cleaned) out of order. Thus checking the previous clone is
sufficient (and thankfully cheap).
Signed-off-by: Sage Weil <sage@inktank.com>
We do three things here:
- make cache-evict a CACHE instead of WR op, allowing us to submit it
on snaps (not just head)
- allow eviction of a snap
- verify that all snaps are missing before evicting a head
Signed-off-by: Sage Weil <sage@inktank.com>
It is useful to distinguish cache operations from read and modify
operations. Specifically, we will allow cache ops to be sent for
snaps and also allow those ops to result in a write.
Signed-off-by: Sage Weil <sage@inktank.com>
A clone that comes into existence via promotion takes an entirely
different path than a typical clone (which comes into existence via a
CLONE op in make_writeable()). Make sure snap_mapper is updated
accordingly.
Signed-off-by: Sage Weil <sage@inktank.com>
On promote we use finish_ctx to build the final log entries, and need to
encode the snaps vector in that case. (Normally this is done by
make_writeable or explicitly by the snap trimmer.)
Signed-off-by: Sage Weil <sage@inktank.com>
When we promote the head for an object, get the list of snaps from the
backend pool and construct an appropriate SnapSet. Note that this is
always placed on the head in the cache pool, since we will have a
whiteout object in this case.
Also note that the SnapSet's list of snapids will not include any snaps
for which there were no clones. This is fine, since it is only used for
creating clones, and we've already done that.
Signed-off-by: Sage Weil <sage@inktank.com>
This is an alternative to MODIFY that indicates the object was just
promoted from another tier. Thanksfully, is_modify() is used in very
few places!
Signed-off-by: Sage Weil <sage@inktank.com>
When promoting a snapped object, we need to also get the set of snaps over
which the clone is defined. This is not strictly available except via the
list-snaps rados call, but that is only used on the snapdir object much
earlier when the head (whiteout) is promoted, and is not conveniently
available now. Adding it to the internal copy-get is not exposed via
librados (copy-get is not exposed at all) so I don't think this is a
problem.
Signed-off-by: Sage Weil <sage@inktank.com>
find_object_context() now tells us which object it could use if it
doesn't find it on disk. Promote that one.
Signed-off-by: Sage Weil <sage@inktank.com>