@@ -156,7 +156,8 @@ def list_volumes(self):
156156 continue
157157 if vol_info ['pool_lv' ] != self .thin_pool :
158158 continue
159- if vid .endswith ('-snap' ) or vid .endswith ('-import' ):
159+ if vid .endswith ('-snap' ) or vid .endswith ('-import' ) or \
160+ vid .endswith ('+export' ):
160161 # implementation detail volume
161162 continue
162163 if vid .endswith ('-back' ):
@@ -292,6 +293,9 @@ def __init__(self, volume_group, **kwargs):
292293 self ._vid_snap = self .vid + '-snap'
293294 if self .save_on_stop :
294295 self ._vid_import = self .vid + '-import'
296+ if os .path .exists (self ._path_export ):
297+ subprocess .check_call (_get_lvm_cmdline (['remove' , self ._vid_export ]))
298+ self ._is_exporting = False
295299
296300 @property
297301 def path (self ):
@@ -470,13 +474,29 @@ async def remove(self):
470474 # pylint: disable=protected-access
471475 self .pool ._volume_objects_cache .pop (self .vid , None )
472476
473- async def export (self ):
477+ @property
478+ def _vid_export (self ) -> str :
479+ return self .vid + '+export'
480+
481+ @property
482+ def _path_export (self ) -> str :
483+ return '/dev/' + self ._vid_export
484+
485+ async def export (self ) -> str :
474486 ''' Returns an object that can be `open()`. '''
475487 # make sure the device node is available
476- cmd = ['activate' , self .path ]
477- await qubes_lvm_coro (cmd , self .log )
478- devpath = self .path
479- return devpath
488+ vid_export = self ._vid_export
489+ export_path = self ._path_export
490+ if not os .path .exists (export_path ):
491+ cmd = ['clone' , self ._vid_current , vid_export ]
492+ await qubes_lvm_coro (cmd , self .log )
493+ self ._is_exporting = True
494+ return export_path
495+
496+ async def export_end (self , path : str ) -> None :
497+ assert path == self ._path_export , f'Refusing to remove incorrect path { path !r} (expected { self .path_export !r} )'
498+ await self ._remove_if_exists (self ._vid_export )
499+ self ._is_exporting = False
480500
481501 @qubes .storage .Volume .locked
482502 async def import_volume (self , src_volume ):
@@ -681,6 +701,8 @@ async def stop(self):
681701 changed = await self ._remove_if_exists (self ._vid_snap )
682702 else :
683703 changed = await self ._remove_if_exists (self .vid )
704+ if not self ._is_exporting :
705+ await self ._remove_if_exists (self ._vid_export )
684706 finally :
685707 if changed :
686708 await reset_cache_coro ()
0 commit comments