Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 29 additions & 11 deletions qubes/storage/lvm.py
Original file line number Diff line number Diff line change
Expand Up @@ -221,14 +221,17 @@ def _parse_lvm_cache(lvm_output):
size, usage_percent = row['lv_size'], row['data_percent']
except KeyError:
continue
if '' in [pool_name, name, size, usage_percent]:
if '' in [pool_name, name, size]:
continue
pool_lv, attr, origin = row['pool_lv'], row['lv_attr'], row['origin']
metadata_size = row['lv_metadata_size']
metadata_percent = row['metadata_percent']
name = pool_name + "/" + name
size = int(size[:-1]) # Remove 'B' suffix
usage = int(size / 100 * float(usage_percent))
if usage_percent:
usage = int(size / 100 * float(usage_percent))
else:
usage = 0
if metadata_size:
metadata_size = int(metadata_size[:-1])
metadata_usage = int(metadata_size / 100 * float(metadata_percent))
Expand Down Expand Up @@ -384,6 +387,18 @@ async def _remove_revisions(self, revisions=None):
except qubes.storage.StoragePoolException:
pass

async def _activate(self):
"""
Ensure the volume is active.

:return: None
"""
vol_info = size_cache[self._vid_current]
if vol_info['attr'][4] == 'a':
return
cmd = ["activate", self._vid_current]
await qubes_lvm_coro(cmd, self.log)

async def _commit(self, vid_to_commit=None, keep=False):
'''
Commit temporary volume into current one. By default
Expand All @@ -407,7 +422,7 @@ async def _commit(self, vid_to_commit=None, keep=False):
vid_to_commit = self._vid_snap

assert self._lock.locked()
if not os.path.exists('/dev/' + vid_to_commit):
if vid_to_commit not in size_cache:
# nothing to commit
return False

Expand Down Expand Up @@ -453,7 +468,7 @@ async def create(self):
async def remove(self):
assert self.vid
try:
if os.path.exists('/dev/' + self._vid_snap):
if self._vid_snap in size_cache:
cmd = ['remove', self._vid_snap]
await qubes_lvm_coro(cmd, self.log)
except AttributeError:
Expand Down Expand Up @@ -499,12 +514,14 @@ async def import_volume(self, src_volume):
src_volume.pool.thin_pool == self.pool.thin_pool: # NOQA
# pylint: disable=protected-access
await self._commit(src_volume._vid_current, keep=True)
await reset_cache_coro()
else:
cmd = ['create',
self.pool._pool_id, # pylint: disable=protected-access
self._vid_import.split('/')[1],
str(src_volume.size)]
await qubes_lvm_coro(cmd, self.log)
await reset_cache_coro()
src_path = await qubes.utils.coro_maybe(src_volume.export())
try:
cmd = [_dd, 'if=' + src_path, 'of=/dev/' + self._vid_import,
Expand All @@ -525,6 +542,7 @@ async def import_volume(self, src_volume):
'Failed to import volume {!r}, dd exit code: {}'.format(
src_volume, p.returncode))
await self._commit(self._vid_import)
await reset_cache_coro()

return self

Expand Down Expand Up @@ -552,14 +570,15 @@ async def import_data_end(self, success):
'No import operation in progress on {}'.format(self.vid))
if success:
await self._commit(self._vid_import)
await reset_cache_coro()
else:
cmd = ['remove', self._vid_import]
await qubes_lvm_coro(cmd, self.log)
await reset_cache_coro()

def abort_if_import_in_progress(self):
try:
devpath = '/dev/' + self._vid_import
if os.path.exists(devpath):
if self._vid_import in size_cache:
raise qubes.storage.StoragePoolException(
'Import operation in progress on {}'.format(self.vid))
except AttributeError: # self._vid_import
Expand All @@ -568,7 +587,7 @@ def abort_if_import_in_progress(self):

def is_dirty(self):
if self.save_on_stop:
return os.path.exists('/dev/' + self._vid_snap)
return self._vid_snap in size_cache
return False

def is_outdated(self):
Expand Down Expand Up @@ -673,6 +692,8 @@ async def start(self):
if self.snap_on_start or self.save_on_stop:
if not self.save_on_stop or not self.is_dirty():
await self._snapshot()
else:
await self._activate()
else:
await self._reset()
finally:
Expand Down Expand Up @@ -706,10 +727,7 @@ async def verify(self):
else:
vid = self._vid_current
try:
vol_info = size_cache[vid]
if vol_info['attr'][4] != 'a':
raise qubes.storage.StoragePoolException(
'volume {} not active'.format(vid))
size_cache[vid]
except KeyError:
raise qubes.storage.StoragePoolException(
'volume {} missing'.format(vid))
Expand Down