Commit Graph

411 Commits

Author SHA1 Message Date
Marek Marczykowski-Górecki
d96480719f
storage: add Volume.export_end() function
This is a counterpart to Volume.export(). Up until now, no driver needed
any cleanup after exporting data, but it doesn't mean there won't be
any. This is especially relevant because Volume.export() is supposed to
return a path of a snapshot from before VM start - which may be a
different one than currently active one.

QubesOS/qubes-issues#5935
2020-07-08 06:05:02 +02:00
Marek Marczykowski-Górecki
d9d55b0586
storage: pass a copy of volume_config to pool.init_volume
Avoid local modification in a pool's init_volume influence
vm.volume_config. Currently every pool driver replaces
volume_config['pool'] with a pool object (instead of name) and it leads
to confusing cases where depending on start stage, it is sometimes an
object and sometimes a string.
Additionally, some pool drivers may modify volume_config in unexpected
way - for example test pool driver removes 'pool' entry entirely. Avoid
this fragile interface by giving pool driver a copy of volume_config,
instead of vm.volume_config directly.

Note one side effect is that 'vid' (and other pool-specific parameters)
is not set into vm.volume_config directly after creating a VM, but
possibly only after loading from XML. This should not be an issue in
theory (no core code should expect it), but if some place use
volume_config instead of Volume instance for getting pool-specific
options, it should be fixed.
2020-07-08 06:05:01 +02:00
Rusty Bird
1b09528740
storage/reflink: clarify comment 2020-07-07 16:25:48 +00:00
Rusty Bird
e188b93c95
storage: move @locked from lvm to Volume base class
And use it in reflink, instead of a synchronous lock.
2020-07-07 15:39:08 +00:00
Rusty Bird
a1b5262426
storeage/reflink: unlock size getter
Don't update _size in the getter, so it can be unlocked (which is
helpful for QubesOS/qubes-issues#5935).

!!! If cherry-picking for release4.0, also adjust import_data() to !!!
!!! use self.size (no underscore) instead of self._get_size()      !!!
2020-07-07 15:39:06 +00:00
Rusty Bird
b98c1814ee
storage/reflink: update _size during volatile volume stop 2020-07-07 15:39:05 +00:00
Rusty Bird
5ed762d152
storage: clean up __init__() of Pool() and subclasses
- Remove **kwargs
- Make all arguments keyword-only
- Use required arguments instead of asserts

QubesOS/qubes-issues#5895
2020-06-22 14:03:21 +00:00
Rusty Bird
652bf3b6d9
storage: modernize super() syntax 2020-06-22 14:03:20 +00:00
Rusty Bird
c2ce28936e
storage/reflink: prefer canonical values for setup_check 2020-06-22 14:03:19 +00:00
Rusty Bird
6f2d82fd20
storage/kernels: fix pool revisions_to_keep setter message 2020-06-22 14:03:18 +00:00
Rusty Bird
3ab789f5d8
storage/file: remove redundant _revisions_to_keep init
FilePool's revisions_to_keep setter - called in the next line via
Pool.__init__() - initializes the variable.
2020-06-22 14:03:17 +00:00
Frédéric Pierret (fepitre)
e4d7df4976
Prevent double hyphens in thin_pool parsing 2020-05-15 15:15:37 +02:00
Marek Marczykowski-Górecki
135eda0582
Merge remote-tracking branch 'origin/pr/320'
* origin/pr/320:
  storage/lvm: don't try to resize non-existing lvm volumes
  storage/lvm: update volume.size attribute on resize
2020-03-09 18:34:49 +01:00
Rusty Bird
8e581108b7
Remove pylint pragma working around very old false positive 2020-02-15 17:33:35 +00:00
Rusty Bird
1f71a06aed
Remove python2 compat __future__ imports 2020-02-15 17:33:34 +00:00
Marek Marczykowski-Górecki
86881afeef
storage/lvm: don't try to resize non-existing lvm volumes
Volume with save_on_stop=False and snap_on_start=False exists only when
VM is running and this is already handled under is_dirty() condition.
For non-running VMs, skip LVM resize step and only update internal size
attribute.

Fixes QubesOS/qubes-issues#5645
2020-02-12 21:57:34 +01:00
Marek Marczykowski-Górecki
6b474e39f6
storage/lvm: update volume.size attribute on resize
When volume is resized, underlying LVM is adjusted if exists. For
persistent volumes it is enough, as generally the driver prefers
underlying LVM size than internal attribute. But volatile volume is
removed at vm shutdown, so that value is lost.

Fix it by updating Volume.size attribute too, to be updated in qubes.xml
later too.

Fixes QubesOS/qubes-issues#5645
2020-02-12 21:44:16 +01:00
Rusty Bird
ada27ee431
storage/reflink: trivial style tweaks
Avoid early return for short and not deeply nested functions.
2020-02-05 17:26:44 +00:00
Rusty Bird
21971d6d0a
storage/reflink: comment on _get_size() use in start() 2020-02-05 17:26:43 +00:00
Rusty Bird
749ce477df
storage/reflink: don't bother using _get_size() in create()
Only the nominal size is available at this point.
2020-01-28 13:40:15 +00:00
Rusty Bird
6659ed8d39
storage/reflink: delete all images at beginning of create()
Ensure that there are no leftover image files for the volume, e.g. from
an unsuccessful removal of a previous incarnation of this vid, or from
an messily restored pool filesystem backup. We don't want to preserve
any stale data (revisions) or metadata (size) in the new incarnation.
2020-01-28 13:40:14 +00:00
Rusty Bird
56f6a6ef65
storage/reflink: get VM dir from less arbitrary-looking path 2020-01-28 13:40:13 +00:00
Rusty Bird
12d882b355
storage/reflink: factor out _remove_all_images() 2020-01-28 13:40:11 +00:00
Rusty Bird
8f4c90c37a
storage/reflink: _remove_incomplete_{files -> images}() 2020-01-28 13:40:10 +00:00
Rusty Bird
9c9d71c069
storage/reflink: omit redundant comment
The is_dirty() one-liner is defined right above.
2020-01-28 13:40:09 +00:00
Marek Marczykowski-Górecki
869f963335
Merge remote-tracking branch 'origin/pr/311'
* origin/pr/311:
  Add a test for loading volume config from XML
  Fix ThinVolume.size initialization from string
2020-01-24 01:38:16 +01:00
Marek Marczykowski-Górecki
edf5977b23
Merge remote-tracking branch 'origin/pr/309'
* origin/pr/309:
  import: check exact size of copied data
  Implement new admin.vm.ImportWithSize API call

Fixes QubesOS/qubes-issues#5239
2020-01-24 01:35:00 +01:00
Pawel Marczewski
49f2c1b78d
Fix ThinVolume.size initialization from string
The size config parameter might be a string coming from XML.
The Volume base class handles the conversion to integer already.

Fixes QubesOS/qubes-issues#5219.
2020-01-23 10:39:47 +01:00
Pawel Marczewski
63ac952803
Implement new admin.vm.ImportWithSize API call
This should allow importing a volume and changing the size at the
same time, without performing the resize operation on original
volume first.

The internal API has been renamed to internal.vm.volume.ImportBegin
to avoid confusion, and for symmetry with ImportEnd.

See QubesOS/qubes-issues#5239.
2020-01-23 09:47:22 +01:00
Rusty Bird
d54e4b0c6e
storage/reflink: fix comment 2020-01-17 16:45:29 +00:00
Rusty Bird
ba662d2819
storage/reflink: bail out early on most FICLONE errnos
Don't fall back on 'cp' if the FICLONE ioctl gives an errno that's not
plausibly reflink specific, because in such a case any fallback could
theoretically mask real but intermittent system/storage errors.

Looking through ioctl_ficlone(2) and the kernel source, it should be
sufficient to do the fallback only on EBADF/EINVAL/EOPNOTSUPP/EXDEV.
(EISDIR/ETXTBSY don't apply to this storage driver, which will never
legitimately attempt to reflink a directory or an active - in the
storage domain - swap file.)
2020-01-17 15:56:51 +00:00
Rusty Bird
90f25890cf
storage/reflink: pool.setup_check -> pool._setup_check 2020-01-17 15:56:50 +00:00
Marek Marczykowski-Górecki
d181c0f354
storage/file: fix resize
Fixes QubesOS/qubes-issues#5518
2019-12-14 15:48:49 +01:00
Rusty Bird
87081d6ee3
storage/reflink: _cleanup() -> _remove_incomplete_files()
"cleanup" sounds related to the concept of a volume being "dirty" - but
it's unrelated. Rename it for clarity.
2019-12-03 18:21:55 +00:00
Rusty Bird
d7478d128b
storage/reflink: document hardcoded sizeof(int) for FICLONE
One alternative would look like

    import ctypes
    sizeof_int = ctypes.sizeof(ctypes.c_int)
    FICLONE = (1073741824 % 256**sizeof_int) | 37897 | (sizeof_int << 16)

but, even if the above really(?) is a 100% correct Python port of

    $ echo FICLONE | cpp -include linux/fs.h | tail -n 1

it still seems more likely that the ctypes package is somehow buggy
somewhere than for Qubes storage to run on an exotic architecture with
non 32 bit ints (in the foreseeable future).

So just document the baked in assumption.
2019-12-03 18:21:54 +00:00
Rusty Bird
3f0286220c
storage/reflink: simplify _replace_file() comment 2019-12-03 18:21:52 +00:00
Rusty Bird
9d5deffb13
storage/reflink: open in binary mode for loopdev resize ioctl
The default (= text) mode for a loop device which contains a VM image
looked weird, even though it didn't make a difference here because the
dev_io object was never actually read from.
2019-12-03 18:21:51 +00:00
Rusty Bird
4cd9e42416
storage/reflink: use a conditional expression 2019-12-03 18:21:50 +00:00
Marta Marczykowska-Górecka
783832adde
Correct inconsistent behavior on unavailable usage data
fixes QubesOS/qubes-issues#5463
2019-11-15 20:01:43 +01:00
Marek Marczykowski-Górecki
77cf310c47
storage/kernels: fix listing volumes
Pool.volumes property is implemented in a base class, individual drivers
should provide list_volumes() method as a backend for that property.
Fix this in a LinuxKernel pool.
2019-11-10 01:14:34 +01:00
Marek Marczykowski-Górecki
dd037f4663
storage/file: get volume size from the actual image file size
Don't realy on a volume configuration only, it's easy to miss updating
it. Specifically, import_volume() function didn't updated the size based
on the source volume.
The size that the actual VM sees is based on the
file size, and so is the filesystem inside. Outdated size property can
lead to a data loss if the user perform an action based on a incorrect
assumption - like extending size, which actually will shrink the volume.

Fixes QubesOS/qubes-issues#4821
2019-10-31 21:53:35 +01:00
Marta Marczykowska-Górecka
2f6497e48d
Added admin.pool.UsageDetails API method
admin.pool.UsageDetails reports the usage data, unlike
admin.pool.Info, which should report the config/unchangeable data.
At the moment admin.Pool.Info still reports usage, to maintain
compatibility, but once all relevant tools are updated,
it should just return configuration data.
2019-10-23 03:04:30 +02:00
Marta Marczykowska-Górecka
04a215fb83
Add metadata info to LVM AdminAPI
Added usage_details method to Pool class
(returns a dictionary with detailed information
on pool usage) and LVM implementation that returns
metadata info.
Needed for QubesOS/qubes-issues#5053
2019-10-22 17:29:01 +02:00
Marek Marczykowski-Górecki
5fa75d73be
Make pylint happy 2019-09-27 16:29:20 +02:00
Brendan Hoar
a5378b5958
Update lvm.py 2019-07-31 19:40:33 -04:00
Rusty Bird
6e592a56d7
storage/reflink: update comment and whitespace 2019-06-28 10:29:31 +00:00
Rusty Bird
1fe2aff643
storage/reflink: _fsync_path(path_from) in _commit()
During regular VM shutdown, the VM should sync() anyway. (And
admin.vm.volume.Import does fdatasync(), which is also fine.) But let's
be extra careful.
2019-06-28 10:29:30 +00:00
Rusty Bird
df23720e4e
storage/reflink: _fsync_dir() -> _fsync_path()
Make it work when passed a file, too.
2019-06-28 10:29:29 +00:00
Rusty Bird
35b4b915e7
storage/reflink: coroutinize pool setup() 2019-06-28 10:29:27 +00:00
Rusty Bird
5b52d23478
factor out utils.void_coros_maybe() 2019-06-28 10:29:25 +00:00
Rusty Bird
fe97a15d11
factor out utils.coro_maybe() 2019-06-28 10:29:24 +00:00
Rusty Bird
2b4b45ead8
storage/reflink: preferably get volume size from image size
There were (at least) five ways for the volume's nominal size and the
volume image file's actual size to desynchronize:

- loading a stale qubes.xml if a crash happened right after resizing the
  image but before saving the updated qubes.xml (-> previously fixed)
- restarting a snap_on_start volume after resizing the volume or its
  source volume (-> previously fixed)
- reverting to a differently sized revision
- importing a volume
- user tinkering with image files

Rather than trying to fix these one by one and hoping that there aren't
any others, override the volume size getter itself to always update from
the image file size. (If the getter is called though the storage API, it
takes the volume lock to avoid clobbering the nominal size when resize()
is running concurrently.)
2019-06-23 12:48:00 +00:00
Rusty Bird
de159a1e1e
storage/reflink: don't run verify() under volume lock 2019-06-23 12:47:59 +00:00
Rusty Bird
4c9c0a88d5
storage/reflink: split @_unblock into @_coroutinized @_locked
And change the volume lock from an asyncio.Lock to a threading.Lock -
locking is now handled before coroutinization.

This will allow the coroutinized resize() and a new *not* coroutinized
size() getter from one of the next commits ("storage/reflink: preferably
get volume size from image size") to both run under the volume lock.
2019-06-23 12:47:58 +00:00
Rusty Bird
ab929baa38
Revert "storage/reflink: update volume size in __init__()"
Fixed more generally in one of the next commits ("storage/reflink:
preferably get volume size from image size").

This reverts commit 9f5d05bfde.
2019-06-23 12:47:57 +00:00
Rusty Bird
58a7e0f158
Revert "storage/reflink: update snap_on_start volume size in start()"
Fixed more generally in one of the next commits ("storage/reflink:
preferably get volume size from image size").

This reverts commit c43df968d5.
2019-06-23 12:47:56 +00:00
Marek Marczykowski-Górecki
d5bdb5d5e0
Merge remote-tracking branch 'origin/pr/267'
* origin/pr/267:
  lvm: run blkdiscard before remove
2019-06-23 03:26:30 +02:00
Christopher Laprise
62e3d57120
lvm: run blkdiscard before remove
issue #5077
2019-06-21 18:40:03 -04:00
Rusty Bird
ef128156a3
storage/reflink: volume.resize(): succeed without image
Successfully resize volumes without any currently existing image file,
e.g. cleanly stopped volatile volumes: Just update the nominal size in
this case.
2019-06-15 16:03:46 +00:00
Rusty Bird
25e92bd19b
storage/reflink: volume.resize(): remove safety check
It is handled by 'qvm-volume resize', which has a '--force' option that
can't work if the check is duplicated in the storage driver.
2019-06-15 16:03:45 +00:00
Rusty Bird
30b92f8845
storage/reflink: simplify volume.usage() 2019-06-15 16:03:43 +00:00
Rusty Bird
9f5d05bfde
storage/reflink: update volume size in __init__() 2019-06-15 16:03:42 +00:00
Rusty Bird
c43df968d5
storage/reflink: update snap_on_start volume size in start() 2019-06-15 16:03:41 +00:00
Marek Marczykowski-Górecki
aa7c0b71a7
storage/lvm: refresh size cache if it's older than 30sec
Disk usage may change dynamically not only at VM start/stop. Refresh the
size cache before checking usage property, but no more than once every
30sec (refresh interval of disk space widget)

Fixes QubesOS/qubes-issues#4888
2019-03-17 20:45:46 +01:00
Marek Marczykowski-Górecki
092fb9659d
Make pylint happy
Fix multiple instances of 'no-else-raise' warning.
2019-02-27 18:40:18 +01:00
Marek Marczykowski-Górecki
e110cbecb3
storage: fallback kernels_dir path if there is no 'kernel' volume
Return meaningful value for kernels_dir if VM has no 'kernel' volume.
Right now it's mostly useful for tests, but could be also used for new
VM classes which doesn't have modules.img, but still use dom0-provided
kernel.
2019-02-27 06:03:57 +01:00
Marek Marczykowski-Górecki
318ed439ff
storage/file: gracefully handle not mounted pool
Fixes QubesOS/qubes-issues#4668
2019-02-27 06:03:57 +01:00
Marek Marczykowski-Górecki
d8b6d3efde
Make add_pool/remove_pool coroutines, allow Pool.{setup,destroy} as coroutines
Pool setup/destroy may be a time consuming operation, allow them to be
asynchronous. Fortunately add_pool and remove_pool are used only through
Admin API, so the change does not require modification of other
components.
2019-02-27 06:03:57 +01:00
Marek Marczykowski-Górecki
4e5a14774a
storage/lvm: fix listing volume revisions when VM name include volume name
some-vm-root is a valid VM name, and in that case it's volume can be
named some-vm-root-private. Do not let it confuse revision listing,
check for unexpected '-' in volume revision number.

The proper solution would be to use different separator, that is not
allowed in VM names. But that would require migration code that is
undesired in the middle of stable release life cycle.

Fixes QubesOS/qubes-issues#4680
2019-01-19 03:25:19 +01:00
Marek Marczykowski-Górecki
91c9e49612
Drop unnecessary 'pass' to make pylint happy 2018-12-04 16:06:33 +01:00
Rusty Bird
7e4812a525
storage: fix NotImplementedError message for import_data() 2018-10-29 20:21:42 +00:00
Rusty Bird
73db2751b8
storage/reflink: make resize()/import_volume() more readable 2018-10-29 20:21:41 +00:00
Rusty Bird
425d993769
storage/reflink: unblock import_data() and import_data_end() 2018-10-29 20:21:39 +00:00
Marek Marczykowski-Górecki
26a553737f
storage/lvm: minor fix for lvs command building
Do not prepend 'sudo' each time - do a copy of array if that's
necessary.
2018-10-29 05:16:23 +01:00
Marek Marczykowski-Górecki
b65fdf9700
storage: convert lvm driver to async version
LVM operations can take significant amount of time. This is especially
visible when stopping a VM (`vm.storage.stop()`) - in that time the
whole qubesd freeze for about 2 seconds.

Fix this by making all the ThinVolume methods a coroutines (where
supported). Each public coroutine is also wrapped with locking on
volume._lock to avoid concurrency-related problems.
This all also require changing internal helper functions to
coroutines. There are two functions that still needs to be called from
non-coroutine call sites:
 - init_cache/reset_cache (initial cache fill, ThinPool.setup())
 - qubes_lvm (ThinVolume.export()

So, those two functions need to live in two variants. Extract its common
code to separate functions to reduce code duplications.

Fixes QubesOS/qubes-issues#4283
2018-10-23 16:53:35 +02:00
Marek Marczykowski-Górecki
6170edb291
storage: allow import_data and import_data_end be coroutines
On some storage pools this operation can also be time consuming - for
example require creating temporary volume, and volume.create() already
can be a coroutine.
This is also requirement for making common code used by start()/create()
etc be a coroutine, otherwise neither of them can be and will block
other operations.

Related to QubesOS/qubes-issues#4283
2018-10-23 16:53:35 +02:00
Rusty Bird
5756e870bd
storage/reflink: use context managers in is_supported()
Don't rely on garbage collection to close and remove the tempfiles.
2018-09-13 19:46:48 +00:00
Rusty Bird
d181bf1aa4
storage: factor out _wait_and_reraise(); fix clone/create
_wait_and_reraise() is similar to asyncio.gather(), but it preserves the
current behavior of waiting for all futures and only _then_ reraising
the first exception (if there is any) in line.

Also switch Storage.create() and Storage.clone() to _wait_and_reraise().
Previously, they called asyncio.wait() and implicitly swallowed all
exceptions.
2018-09-11 23:50:22 +00:00
Rusty Bird
d33bd3f2b6
storage: fix search_pool_containing_dir()
Canonicalize both directories, resolving symlink components. Compare
with commonpath() instead of startswith(), because /foo doesn't contain
/foobar.
2018-09-11 23:50:21 +00:00
Rusty Bird
f0ee73e63f
storage: remove broken default parameter from isodate()
With that syntax, the default timestamp would have been from the time of
the function's definition (not invocation). But all callers are passing
an explicit timestamp anyway.
2018-09-11 23:50:20 +00:00
Rusty Bird
44ca78523f
storage: insert missing NotImplementedError in Volume.stop() 2018-09-11 23:50:19 +00:00
Rusty Bird
266d90c2f9
storage: fix docstrings 2018-09-11 23:50:18 +00:00
Rusty Bird
c75fe09814
storage/reflink: is_reflink_supported() -> is_supported() 2018-09-11 23:50:16 +00:00
Rusty Bird
1889c9b75f
storage/reflink: run synchronous volume methods in executor
Convert create(), verify(), remove(), start(), stop(), revert(),
resize(), and import_volume() into coroutine methods, via a decorator
that runs them in the event loop's thread-based default executor.

This reduces UI hangs by unblocking the event loop, and can e.g. speed
up VM starts by starting multiple volumes in parallel.
2018-09-11 23:50:15 +00:00
Rusty Bird
3d986be02a
storage/reflink: native FICLONE in _copy_file() happy path
Avoid a subprocess launch, and distinguish reflink vs. fallback copy in
the log.
2018-09-11 23:50:14 +00:00
Rusty Bird
edda3a1734
storage/reflink: factor out _ficlone() 2018-09-11 23:50:13 +00:00
Rusty Bird
69af0a48ec
storage/reflink: inline and simplify _cmd() 2018-09-11 23:50:12 +00:00
Rusty Bird
fb06a8089a
storage/reflink: _update_loopdev_sizes() without losetup
Factor out a function, and use the LOOP_SET_CAPACITY ioctl instead of
going through losetup.
2018-09-11 23:50:10 +00:00
Rusty Bird
385ba91772
storage/reflink: resize(): don't look for loopdevs if clean 2018-09-09 20:01:22 +00:00
Rusty Bird
e7b7c253ac
storage/reflink: inline _require_self_on_stop() 2018-09-09 20:01:20 +00:00
Rusty Bird
6e8d7d4201
storage/reflink: no-op import_volume() if not save_on_stop
Instead of raising a NotImplementedError, just return self like 'file'
and lvm_thin. This is needed when Storage.clone() is modified in another
commit* to no longer swallow exceptions.

* "storage: factor out _wait_and_reraise(); fix clone/create"
2018-09-09 20:01:19 +00:00
Rusty Bird
60bf68a748
storage/reflink: add _path_import (don't reuse _path_dirty)
Import volume data to a new _path_import (instead of _path_dirty) before
committing to _path_clean. In case the computer crashes while an import
operation is running, the partially written file should not be attached
to Xen on the next volume startup.

Use <name>-import.img as the filename like 'file' does, to be compatible
with qubes.tests.api_admin/TC_00_VMs/test_510_vm_volume_import.
2018-09-09 20:01:18 +00:00
Rusty Bird
d301aa2e50
storage/reflink: delete stale tempfiles on start and remove
When the AT_REPLACE flag for linkat() finally lands in the Linux kernel,
_replace_file() can be modified to use unnamed (O_TMPFILE) tempfiles.
Until then, make sure stale tempfiles from previous crashes can't hang
around for too long.
2018-09-09 20:01:17 +00:00
Rusty Bird
75a4a1340e
storage/reflink: don't recompute static properties per call 2018-09-09 20:01:15 +00:00
Rusty Bird
ef2698adb4
storage/reflink: make revisions() more readable, use iglob 2018-09-09 20:01:14 +00:00
Rusty Bird
18f9356c2c
storage/reflink: refuse to revert() dirty volume 2018-09-09 20:01:13 +00:00
Rusty Bird
677183d8a6
storage/reflink: add revision even if empty
It's sort of useful to be able to revert a volume that has only ever
been started once to its empty state. And the lvm_thin driver allows it
too, so why not.
2018-09-09 20:01:12 +00:00
Rusty Bird
850778b52a
storage/reflink: remove redundant format specifiers 2018-09-09 20:01:11 +00:00
Marek Marczykowski-Górecki
7f1e2741ec
Merge remote-tracking branch 'qubesos/pr/228'
* qubesos/pr/228:
  storage/lvm: filter out warning about intended over-provisioning
  tests: fix getting kernel package version inside VM
  tests/extra: add start_guid option to VMWrapper
  vm/qubesvm: fire 'domain-start-failed' event even if fail was early
  vm/qubesvm: check if all required devices are available before start
  storage/lvm: fix reporting lvm command error
  storage/lvm: save pool's revision_to_keep property
2018-09-07 01:06:59 +02:00
Marek Marczykowski-Górecki
ce87451c73
Merge branch 'lvm-snapshots'
* lvm-snapshots:
  tests: fix handling app.pools iteration
  storage/lvm: add repr(ThinPool) for more meaningful test reports
  tests: adjust for variable volume path
  api/admin: expose volume path in admin.vm.volume.Info
  tests: LVM: import, list_volumes, volatile volume, snapshot volume
  tests: collect all SIGCHLD before cleaning event loop
  storage/lvm: use temporary volume for data import
  tests: ThinVolume.revert()
  tests: LVM volume naming migration, and new naming in general
  storage/lvm: improve handling interrupted commit
2018-07-16 16:40:35 +02:00