Kefu Chai [Thu, 8 Dec 2022 16:49:37 +0000 (00:49 +0800)]
pybind/mgr: do not test with py37
as we always test with ubuntu jammy, which does not provide python3.7:
py37: skipped because could not find python interpreter with spec(s): py37
so there is no point testing with python3.7.
also, in tox v4, it is not able to handle "key = value" anymore, where
value has newlines in it. so we need to find a better way passing
command line options to the test command.
Kefu Chai [Thu, 8 Dec 2022 06:42:42 +0000 (14:42 +0800)]
qa: set locale to C.UTF-8 in tox.ini
as ansible is using UTF-8 encoded characters in the file names, so,
to avoid failures like:
File "/home/jenkins-build/build/workspace/ceph-pull-requests/qa/.tox/py3/lib/python3.10/site-packages/pip/_internal/utils/unpacking.py", line 217, in untar_file
with open(path, "wb") as destfp:
UnicodeEncodeError: 'latin-1' codec can't encode characters in position 137-140: ordinal not in range(256)
we have to set a locale which is able to handle UTF-8.
see also https://github.com/ceph/teuthology/pull/1671
Kefu Chai [Thu, 8 Dec 2022 10:25:20 +0000 (18:25 +0800)]
pybind/mgr: drop cython from requires
cython is not required for running tox commands.
this should address the test failure like:
ROOT: will run in automatically provisioned tox, host /home/jenkins-build/build/workspace/ceph-pull-requests/build/mgr-virtualenv/bin/python3.10 is missing [requires (has)]: cython
Kefu Chai [Thu, 8 Dec 2022 06:53:33 +0000 (14:53 +0800)]
*: s/whitelist_externals/allowlist_externals/
as allowlist_externals was introduced in
tox v4.0. see
https://github.com/tox-dev/tox/commit/5e33fda1a40ffb4973de3d607a572891eb3cb2d2 , but
this option was backported to 3.18 as an alias of whitelist_externals, so we don't need
to specify the minversion to 4.0 in this change.
as we started using tox 4.0 and up (v4.0.2 in specific). tox complains
and fails like:
alerts-lint: failed with promtool is not allowed, use allowlist_externals to allow it
alerts-lint: FAIL code 1 (9.25 seconds)
see https://tox.wiki/en/latest/faq.html#tox-4-removed-tox-ini-keys
and https://tox.wiki/en/latest/config.html#allowlist_externals
it'd be nice to use a more inclusive language also. so, in this change,
s/whitelist_externals/allowlist_externals/ in all tox.ini in this
project.
Laura Flores [Mon, 5 Dec 2022 21:07:42 +0000 (15:07 -0600)]
.github: add core label to files under src/test/librados
In response to https://tracker.ceph.com/issues/58173, it would have helped to have the PR label librados test files with core, so the PR would have been tagged for rados qa.
Ilya Dryomov [Sat, 3 Dec 2022 14:37:14 +0000 (15:37 +0100)]
qa/workunits/rbd: add encryption-aware resize test
Note that we are hitting https://tracker.ceph.com/issues/58160 here
because by the time we get to "rbd resize" RAW_DEV mapping owns the
lock (due to a write to /dev/mapper/cryptsetupdev being last).
While at it, resurrect the ability to easily run this script on
vstart clusters -- see commit f737c2855a19 ("qa/workunits/rbd: make
luks-encryption test work on vstart cluster").
Ilya Dryomov [Sat, 19 Nov 2022 12:30:55 +0000 (13:30 +0100)]
rbd, rbd-nbd: accept "luks", "luks1" and "luks2" formats
Since RBD_ENCRYPTION_FORMAT_LUKS1, RBD_ENCRYPTION_FORMAT_LUKS2
and RBD_ENCRYPTION_FORMAT_LUKS aren't treated the same when loading
encryption anymore, "luks1" and "luks2" formats need to be accepted
in addition to "luks" format.
Ilya Dryomov [Fri, 18 Nov 2022 13:53:24 +0000 (14:53 +0100)]
librbd: don't decay LUKS{1,2}EncryptionFormat into LUKSEncryptionFormat
Commit 9892ead7fcd9 ("librbd/crypto: allow loading luks format
without specifying version") introduced RBD_ENCRYPTION_FORMAT_LUKS
format identifier, matching cryptsetup's CRYPT_LUKS ("load any LUKS
version happens to be there"). However, in an effort to enable an
obscure "layered encryption with the same passphrase + old QEMU" use
case, it also introduced decaying of RBD_ENCRYPTION_FORMAT_LUKS1 and
RBD_ENCRYPTION_FORMAT_LUKS2 format identifiers, making it impossible
to assert on the format that is being loaded. This new behavior was
then extended to standalone images.
Treating RBD_ENCRYPTION_FORMAT_LUKS1, RBD_ENCRYPTION_FORMAT_LUKS2
and RBD_ENCRYPTION_FORMAT_LUKS the same when loading encryption can
be construed as an opening for a format downgrade attack. Let's
resurrect the previous standalone images behavior and extend it to
layered encryption instead.
Ilya Dryomov [Mon, 14 Nov 2022 13:14:10 +0000 (14:14 +0100)]
rbd: fix passphrase zeroing in "rbd encryption format" handler
"rbd encryption format" handler sets up a scope guard to zero out
the passphrase string on return but also makes a copy of same which
isn't zeroed out.
Ilya Dryomov [Mon, 14 Nov 2022 12:24:00 +0000 (13:24 +0100)]
rbd, rbd-nbd: don't strip trailing newline in passphrase files
One of the stated goals is compatibility with standard LUKS tools,
in particular being able to load encryption on images formatted with
cryptsetup. cryptsetup doesn't do this and this really interferes
with randomly generated (binary) passphrases.
While at it, open passphrase files as binary -- it communicates the
intent if nothing else on POSIX.
Ilya Dryomov [Mon, 17 Oct 2022 13:51:04 +0000 (15:51 +0200)]
librbd: non-pruning parent overlap handling fixes
Apply similar "reduce overlap and respect area" logic to places
that don't use prune_parent_extents(). Changes to FlattenRequest
and TrimRequest here should complete the long tail of encrypted
I/O path and flatten fixes.
Ilya Dryomov [Sat, 15 Oct 2022 16:31:45 +0000 (18:31 +0200)]
librbd: reduce overlap and respect area when pruning parent extents
DATA area in the parent may be smaller than the part of DATA area in
the clone that is still within the overlap. This would occur e.g. in
LUKS2-formatted parent + LUKS1-formatted clone case, due to LUKS2
header usually being bigger than LUKS1 header:
parent: raw size = 64M
LUKS2 header area = 16M
data area = 48M
clone: raw size = 64M (raw overlap 64M)
LUKS1 header area = 4M
data area = 60M
Currently, because parent extents are pruned only according to raw
overlap (64M), the clone ends up attempting to reach the parent for all
of its data area (60M < 64M) even though the parent only has 48M worth
of data. All kinds of bugs ensue for 48M..60M offsets and this range
basically becomes inaccessible to the user.
A related issue is that prune_parent_extents() ignores area.
librbd: clip extents to their area instead of DATA area
This fixes cases where CRYPTO HEADER area is larger than DATA area.
In particular, it was effectively impossible to flatten unformatted
clones of such images.
Ilya Dryomov [Fri, 14 Oct 2022 14:20:24 +0000 (16:20 +0200)]
librbd: introduce reduce_parent_overlap() and switch overlap API
When encryption is loaded, rbd_get_overlap() and Image::overlap() now
return "effective" overlap, similar to rbd_get_size() and Image::size().
Previously, returned overlap could have been bigger than "effective"
size.
Note that get_effective_image_size() successor doesn't take snap_id
because passing anything but ictx->snap_id was broken. Since the size
of the crypto header is stored in the crypto header itself, image areas
are defined only for the "opened at" snap_id. Getting "effective" size
for an arbitrary snapshot requires actually opening it and loading
encryption on it.
Ilya Dryomov [Fri, 14 Oct 2022 14:01:45 +0000 (16:01 +0200)]
librbd: tweak get_parent_overlap() signature
Make it clear that get_parent_overlap() returns the raw parent overlap
value (i.e. physical offset into the parent image). Also drop redundant
ceph_mutex_is_locked assert -- get_parent_info() already has one.
Ilya Dryomov [Thu, 20 Oct 2022 15:25:46 +0000 (17:25 +0200)]
librbd: remap resize target size if encryption is loaded
When encryption is loaded, rbd_get_size() and Image::size() return
"effective" size, but rbd_resize() and Image::resize() continue to take
raw size. The user has to constantly keep these domains in mind.
Saying that resize must be done without encryption loaded is not an
answer because shrinking a clone that has snapshots involves copying up
objects in the affected range (identical to flattening). In addition,
even if a clone doesn't have snapshots, shrinking it to a size that
isn't an object boundary is going to involve a copyup for the victim
object as well.
To avoid subtle data corruption on shrink, treat resize operation the
same as flatten operation (including on the CLI).
librbd: check stripe pattern when loading encryption
Currently it's done in FormatRequest but not in LoadRequest. However
an image can be deep copied or exported and imported with a different
stripe pattern such that an area boundary would fall in the middle of
an object.
Currently it's done in FormatRequest but not in LoadRequest. However
an image can be shrunk to a size such that encryption can loaded (i.e.
enough of the header is still present) but nothing else can, breaking
implicit assumptions all around.
Ilya Dryomov [Fri, 7 Oct 2022 09:56:27 +0000 (11:56 +0200)]
librbd: relax image size check in luks::FormatRequest
Proceed with formatting an image even if all space would be consumed by
the crypto header. There is no reason to be strict here since we allow
creating zero-sized images as well as shrinking any image to 0.
librbd: don't temporarily shut down crypto when flattening
(Temporarily) shutting down crypto can lead to data corruption in the
face of concurrent I/O, especially when flatten operation is proxied to
the remote lock owner. This was added to be able to read, optionally
modify and write crypto header without it being subjected to remapping
and encryption itself. read_header() and write_header() now achieve
that by specifying CRYPTO_HEADER area explicitly.
librbd: move get_file_offset() into CryptoObjectDispatch
This method doesn't propagate area. Since its only user is
CryptoObjectDispatch which is now applied only to DATA area,
move get_file_offset() there to avoid misuse in the future.
librbd: apply CryptoObjectDispatch layer only to DATA area
Objects in CRYPTO_HEADER area should not be subjected to encryption.
Unit tests needed adjustment because MockCryptoInterface is configured
with DATA_OFFSET = 4 * 1024 * 1024, thus disqualifying object 0.
- readahead and PWL cache are limited to DATA area as explained in
the previous commit
- DATA area is assumed for the journal as encryption can't be used
with journaling anyway
To postpone the churn associated with passing area through
ImageDispatchInterface (where only WriteLogImageDispatch and
ImageDispatch care), add a new image dispatch flag.
librbd: pass area to ImageDispatchSpec::create_*()
- DATA area is assumed at the API layer as there is no way to pass
an area
- DATA area is assumed by ImageWriteback because PWL cache persists
image extents as provided by the user without any kind of designator
and therefore can be active only in either area
- luks::FlattenRequest operates on CRYPTO_HEADER area
The passed area is acted upon in ImageDispatchSpec constructor in the
next commit.
Note that, as suggested by extents_to_file() signature, all returned
image extents would pertain to the same area. This means that an area
boundary must coincide with an object boundary.
luks::FormatRequest is actually more strict: crypto header area size is
set to a multiple of stripe period (i.e. one or more whole objects).