@@ -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,7 @@ 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+ self ._is_exporting = False
295297
296298 @property
297299 def path (self ):
@@ -470,13 +472,31 @@ async def remove(self):
470472 # pylint: disable=protected-access
471473 self .pool ._volume_objects_cache .pop (self .vid , None )
472474
473- async def export (self ):
475+ @property
476+ def _vid_export (self ) -> str :
477+ return self .vid + '+export'
478+
479+ @property
480+ def _path_export (self ) -> str :
481+ return '/dev/' + self ._vid_export
482+
483+ async def export (self ) -> str :
474484 ''' Returns an object that can be `open()`. '''
475485 # 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
486+ vid_export = self ._vid_export
487+ export_path = self ._path_export
488+ if not os .path .exists (export_path ):
489+ cmd = ['clone' , self ._vid_current , vid_export ]
490+ await qubes_lvm_coro (cmd , self .log )
491+ self ._is_exporting = True
492+ return export_path
493+
494+ async def export_end (self , path : str ) -> None :
495+ assert path == self ._path_export , \
496+ f'Refusing to remove incorrect path { path !r} ' \
497+ f'(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