Skip to content

Commit

Permalink
Recursively mount root dataset during boot if it is not encrypted (#1…
Browse files Browse the repository at this point in the history
…3553)

Import the pools during boot without mounting any of the datasets.
Check on 'feature@encryption' for imported pool. If feature is not
active, recursively mount the root datasets, which effectively
mounts all datasets present on the pool.

If the encryption feature is active, continue and unlock the
datasets.

Signed-off-by: Umer Saleem <usaleem@ixsystems.com>
  • Loading branch information
usaleem-ix committed May 13, 2024
1 parent c1ef176 commit bf7cb49
Showing 1 changed file with 58 additions and 0 deletions.
58 changes: 58 additions & 0 deletions src/middlewared/middlewared/plugins/pool_/import_pool.py
Original file line number Diff line number Diff line change
Expand Up @@ -212,13 +212,67 @@ async def import_pool(self, job, data):

return True

@private
def recursive_mount(self, name):
cmd = [
'zfs', 'mount',
'-R', # recursive flag
name, # name of the zpool / root dataset
]
try:
self.logger.debug('Going to mount root dataset recusively: %r', name)
cp = subprocess.run(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
if cp.returncode != 0:
self.logger.error(
'Failed to mount datasets for pool: %r with error: %r',
name, cp.stdout.decode()
)
return False
return True
except Exception:
self.logger.error(
'Unhandled exception while mounting datasets for pool: %r',
name, exc_info=True
)
return False

@private
def encryption_is_active(self, name):
cmd = [
'zpool', 'get',
'-H', # use in script
'-o', 'value', # retrieve the value
'feature@encryption', # property to retrieve
name, # name of the zpool
]
try:
self.logger.debug('Checking if feature@encryption is active on pool: %r', name)
cp = subprocess.run(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
if cp.returncode != 0:
self.logger.error(
'Failed to get feature@encryption for pool: %r with error: %r',
name, cp.stdout.decode()
)
return False
if cp.stdout.decode().strip() == 'active':
return True
else:
return False
except Exception:
self.logger.error(
'Unhandled exception while checking on feature@encryption for pool: %r',
name, exc_info=True
)
return False

@private
def import_on_boot_impl(self, vol_name, vol_guid, set_cachefile=False):
cmd = [
'zpool', 'import',
vol_guid, # the GUID of the zpool
'-R', '/mnt', # altroot
'-m', # import pool with missing log device(s)
'-N', # do not mount the datasets
'-f', # force import since hostid can change (upgrade from CORE to SCALE changes it, for example)
'-o', f'cachefile={ZPOOL_CACHE_FILE}' if set_cachefile else 'cachefile=none',
]
Expand Down Expand Up @@ -421,6 +475,10 @@ def import_on_boot(self, job):
if not self.import_on_boot_impl(name, guid, set_cachefile_property):
continue

if not self.encryption_is_active(name):
self.recursive_mount(name)
continue

self.unlock_on_boot_impl(name)

# no reason to wait on this to complete
Expand Down

0 comments on commit bf7cb49

Please sign in to comment.