diff --git a/supervisor/mounts/manager.py b/supervisor/mounts/manager.py index 1405690020f..332423f3daa 100644 --- a/supervisor/mounts/manager.py +++ b/supervisor/mounts/manager.py @@ -150,15 +150,10 @@ async def reload(self) -> None: *[mount.update() for mount in mounts], return_exceptions=True ) - # Try to reload any newly failed mounts and report issues if failure persists - new_failures = [ - mounts[i] - for i in range(len(mounts)) - if results[i] is not True - and mounts[i].failed_issue not in self.sys_resolution.issues - ] + # Try to reload failed mounts and report issues if failure persists + failures = [mounts[i] for i in range(len(mounts)) if results[i] is not True] await self._mount_errors_to_issues( - new_failures, [mount.reload() for mount in new_failures] + failures, [self.reload_mount(mount.name) for mount in failures] ) async def _mount_errors_to_issues( @@ -170,6 +165,8 @@ async def _mount_errors_to_issues( for i in range(len(errors)): # pylint: disable=consider-using-enumerate if not errors[i]: continue + if mounts[i].failed_issue in self.sys_resolution.issues: + continue if not isinstance(errors[i], MountError): capture_exception(errors[i]) diff --git a/supervisor/mounts/mount.py b/supervisor/mounts/mount.py index c6d1535e83c..5ee1f2fea09 100644 --- a/supervisor/mounts/mount.py +++ b/supervisor/mounts/mount.py @@ -342,20 +342,23 @@ async def reload(self) -> None: "Mount %s is not mounted, mounting instead of reloading", self.name ) await self.mount() - return except DBusError as err: raise MountError( f"Could not reload mount {self.name} due to: {err!s}", _LOGGER.error ) from err + else: + if await self._update_unit(): + await self._update_state_await(not_state=UnitActiveState.ACTIVATING) - if await self._update_unit(): - await self._update_state_await(not_state=UnitActiveState.ACTIVATING) + if not await self.is_mounted(): + raise MountActivationError( + f"Reloading {self.name} did not succeed. Check host logs for errors from mount or systemd unit {self.unit_name} for details.", + _LOGGER.error, + ) - if not await self.is_mounted(): - raise MountActivationError( - f"Reloading {self.name} did not succeed. Check host logs for errors from mount or systemd unit {self.unit_name} for details.", - _LOGGER.error, - ) + # If it is mounted now, dismiss corresponding issue if present + if self.failed_issue in self.sys_resolution.issues: + self.sys_resolution.dismiss_issue(self.failed_issue) class NetworkMount(Mount, ABC): diff --git a/tests/mounts/test_manager.py b/tests/mounts/test_manager.py index fe5b0e39e44..0b544384187 100644 --- a/tests/mounts/test_manager.py +++ b/tests/mounts/test_manager.py @@ -608,6 +608,49 @@ async def test_reload_mounts( assert not coresys.resolution.suggestions_for_issue(mount.failed_issue) +async def test_reload_mounts_attempts_initial_mount( + coresys: CoreSys, all_dbus_services: dict[str, DBusServiceMock], mount: Mount +): + """Test reloading mounts attempts initial mount.""" + systemd_service: SystemdService = all_dbus_services["systemd"] + systemd_service.StartTransientUnit.calls.clear() + systemd_service.response_get_unit = [ + ERROR_NO_UNIT, + "/org/freedesktop/systemd1/unit/tmp_2dyellow_2emount", + ERROR_NO_UNIT, + ERROR_NO_UNIT, + "/org/freedesktop/systemd1/unit/tmp_2dyellow_2emount", + ] + systemd_service.response_reload_or_restart_unit = ERROR_NO_UNIT + coresys.mounts.bound_mounts[0].emergency = True + + await coresys.mounts.reload() + + assert systemd_service.StartTransientUnit.calls == [ + ( + "mnt-data-supervisor-mounts-media_test.mount", + "fail", + [ + ["Options", Variant("s", "soft,timeo=200")], + ["Type", Variant("s", "nfs")], + ["Description", Variant("s", "Supervisor nfs mount: media_test")], + ["What", Variant("s", "media.local:/media")], + ], + [], + ), + ( + "mnt-data-supervisor-media-media_test.mount", + "fail", + [ + ["Options", Variant("s", "bind")], + ["Description", Variant("s", "Supervisor bind mount: bind_media_test")], + ["What", Variant("s", "/mnt/data/supervisor/mounts/media_test")], + ], + [], + ), + ] + + @pytest.mark.parametrize("os_available", ["9.5"], indirect=True) async def test_mounting_not_supported( coresys: CoreSys,