diff --git a/src/middlewared/middlewared/plugins/boot.py b/src/middlewared/middlewared/plugins/boot.py index 6b53f6ea11cdb..30e1577c92e5b 100644 --- a/src/middlewared/middlewared/plugins/boot.py +++ b/src/middlewared/middlewared/plugins/boot.py @@ -329,10 +329,6 @@ async def check_update_ashift_property(self): if properties: await self.middleware.call('zfs.pool.update', BOOT_POOL_NAME, {'properties': properties}) - @private - async def is_boot_pool_path(self, path): - return path.startswith(f'/dev/zvol/{await self.pool_name()}/') - async def on_config_upload(middleware, path): await middleware.call('boot.update_initramfs', {'database': path}) diff --git a/src/middlewared/middlewared/plugins/iscsi_/extents.py b/src/middlewared/middlewared/plugins/iscsi_/extents.py index ebb317f75a2a4..6087b0d51c390 100755 --- a/src/middlewared/middlewared/plugins/iscsi_/extents.py +++ b/src/middlewared/middlewared/plugins/iscsi_/extents.py @@ -335,8 +335,7 @@ def clean_type_and_path(self, data, schema_name, verrors): if not os.path.exists(device): verrors.add(f'{schema_name}.disk', f'Device {device!r} for volume {zvol_name!r} does not exist') - if self.middleware.call_sync('boot.is_boot_pool_path', device): - verrors.add(f'{schema_name}.disk', 'Disk residing in boot pool cannot be consumed and is not supported') + self.middleware.call_sync('iscsi.extent.validate_zvol_path', verrors, f'{schema_name}.disk', device) if '@' in zvol_name and not data['ro']: verrors.add(f'{schema_name}.ro', 'Must be set when disk is a ZFS Snapshot') diff --git a/src/middlewared/middlewared/plugins/vm/devices/storage_devices.py b/src/middlewared/middlewared/plugins/vm/devices/storage_devices.py index 703bdaf8cd1b0..8b3a938fe501a 100644 --- a/src/middlewared/middlewared/plugins/vm/devices/storage_devices.py +++ b/src/middlewared/middlewared/plugins/vm/devices/storage_devices.py @@ -2,6 +2,7 @@ import os from middlewared.plugins.zfs_.utils import zvol_name_to_path, zvol_path_to_name +from middlewared.plugins.zfs_.validation_utils import check_zvol_in_boot_pool_using_path from middlewared.schema import Bool, Dict, Int, Str from middlewared.validators import Match @@ -162,6 +163,8 @@ def _validate(self, device, verrors, old=None, vm_instance=None, update=True): verrors.add('attributes.path', 'Disk path is required.') elif not path.startswith('/dev/zvol/'): verrors.add('attributes.path', 'Disk path must start with "/dev/zvol/"') + elif check_zvol_in_boot_pool_using_path(path): + verrors.add('attributes.path', 'Disk residing in boot pool cannot be consumed and is not supported') else: zvol = self.middleware.call_sync( 'zfs.dataset.query', [['id', '=', zvol_path_to_name(path)]], {'extra': {'properties': []}} diff --git a/src/middlewared/middlewared/plugins/zfs_/validation_utils.py b/src/middlewared/middlewared/plugins/zfs_/validation_utils.py index bbafaeaf81ab4..5cccb73a59b97 100644 --- a/src/middlewared/middlewared/plugins/zfs_/validation_utils.py +++ b/src/middlewared/middlewared/plugins/zfs_/validation_utils.py @@ -1,5 +1,17 @@ import libzfs +from middlewared.plugins.boot import BOOT_POOL_NAME + +from .utils import zvol_name_to_path + + +def check_zvol_in_boot_pool_using_name(zvol_name: str) -> bool: + return check_zvol_in_boot_pool_using_path(zvol_name_to_path(zvol_name)) + + +def check_zvol_in_boot_pool_using_path(zvol_path: str) -> bool: + return zvol_path.startswith(f'/dev/zvol/{BOOT_POOL_NAME}/') + def validate_pool_name(name: str) -> bool: return libzfs.validate_pool_name(name) diff --git a/src/middlewared/middlewared/service/sharing_service.py b/src/middlewared/middlewared/service/sharing_service.py index bd64ed89a8a40..73d96d8c823d8 100644 --- a/src/middlewared/middlewared/service/sharing_service.py +++ b/src/middlewared/middlewared/service/sharing_service.py @@ -1,9 +1,6 @@ -import errno -import os - -from middlewared.service_exception import CallError -from middlewared.utils.path import FSLocation, path_location, strip_location_prefix from middlewared.async_validators import check_path_resides_within_volume +from middlewared.plugins.zfs_.validation_utils import check_zvol_in_boot_pool_using_path +from middlewared.utils.path import FSLocation, path_location, strip_location_prefix from .crud_service import CRUDService from .decorators import pass_app, private @@ -62,6 +59,11 @@ async def validate_external_path(self, verrors, name, path): # validation here because we can't predict what is required. raise NotImplementedError + @private + async def validate_zvol_path(self, verrors, name, path): + if check_zvol_in_boot_pool_using_path(path): + verrors.add(name, 'Disk residing in boot pool cannot be consumed and is not supported') + @private async def validate_local_path(self, verrors, name, path): await check_path_resides_within_volume(verrors, self.middleware, name, path) @@ -70,6 +72,7 @@ async def validate_local_path(self, verrors, name, path): async def validate_path_field(self, data, schema, verrors): name = f'{schema}.{self.path_field}' path = await self.get_path_field(data) + await self.validate_zvol_path(verrors, name, path) loc = path_location(path) if loc not in self.allowed_path_types: