Skip to content

Commit 15e8940

Browse files
authored
Improve D-Bus timeout error handling (#5664)
* Improve D-Bus timeout error handling Typically D-Bus timeouts are related to systemd activation timing out after 25s. The current dbus-fast timeout of 10s is well below that so we never get the actual D-Bus error. This increases the dbus-fast timeout to 30s, which will make sure we wait long enought to get the actual D-Bus error from the broker. Note that this should not slow down a typical system, since we tried three times each waiting for 10s. With the new error handling typically we'll end up waiting 25s and then receive the actual D-Bus error. There is no point in waiting for multiple D-Bus/systemd caused timeouts. * Create D-Bus TimedOut exception
1 parent 644ec45 commit 15e8940

File tree

4 files changed

+25
-11
lines changed

4 files changed

+25
-11
lines changed

supervisor/dbus/udisks2/__init__.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,8 +66,8 @@ async def connect(self, bus: MessageBus):
6666
try:
6767
await super().connect(bus)
6868
await self.udisks2_object_manager.connect(bus)
69-
except DBusError:
70-
_LOGGER.warning("Can't connect to udisks2")
69+
except DBusError as err:
70+
_LOGGER.critical("Can't connect to udisks2: %s", err)
7171
except (DBusServiceUnkownError, DBusInterfaceError):
7272
_LOGGER.warning(
7373
"No udisks2 support on the host. Host control has been disabled."

supervisor/exceptions.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -403,7 +403,11 @@ class DBusParseError(DBusError):
403403

404404

405405
class DBusTimeoutError(DBusError):
406-
"""D-Bus call timed out."""
406+
"""D-Bus call timeout."""
407+
408+
409+
class DBusTimedOutError(DBusError):
410+
"""D-Bus call timed out (typically when systemd D-Bus service activation fail)."""
407411

408412

409413
class DBusNoReplyError(DBusError):

supervisor/os/data_disk.py

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -189,12 +189,13 @@ async def load(self) -> None:
189189
await self.sys_dbus.agent.datadisk.reload_device()
190190

191191
# Register for signals on devices added/removed
192-
self.sys_dbus.udisks2.udisks2_object_manager.dbus.object_manager.on_interfaces_added(
193-
self._udisks2_interface_added
194-
)
195-
self.sys_dbus.udisks2.udisks2_object_manager.dbus.object_manager.on_interfaces_removed(
196-
self._udisks2_interface_removed
197-
)
192+
if self.sys_dbus.udisks2.is_connected:
193+
self.sys_dbus.udisks2.udisks2_object_manager.dbus.object_manager.on_interfaces_added(
194+
self._udisks2_interface_added
195+
)
196+
self.sys_dbus.udisks2.udisks2_object_manager.dbus.object_manager.on_interfaces_removed(
197+
self._udisks2_interface_removed
198+
)
198199

199200
@Job(
200201
name="data_disk_migrate",

supervisor/utils/dbus.py

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
DBusObjectError,
3232
DBusParseError,
3333
DBusServiceUnkownError,
34+
DBusTimedOutError,
3435
DBusTimeoutError,
3536
HassioNotSupportedError,
3637
)
@@ -87,6 +88,8 @@ def from_dbus_error(err: DBusFastDBusError) -> HassioNotSupportedError | DBusErr
8788
return DBusNotConnectedError(err.text)
8889
if err.type == ErrorType.TIMEOUT:
8990
return DBusTimeoutError(err.text)
91+
if err.type == ErrorType.TIMED_OUT:
92+
return DBusTimedOutError(err.text)
9093
if err.type == ErrorType.NO_REPLY:
9194
return DBusNoReplyError(err.text)
9295
return DBusFatalError(err.text, type_=err.type)
@@ -136,15 +139,21 @@ async def introspect(self) -> Node:
136139
for _ in range(3):
137140
try:
138141
return await self._bus.introspect(
139-
self.bus_name, self.object_path, timeout=10
142+
self.bus_name, self.object_path, timeout=30
140143
)
141144
except InvalidIntrospectionError as err:
142145
raise DBusParseError(
143146
f"Can't parse introspect data: {err}", _LOGGER.error
144147
) from err
145148
except DBusFastDBusError as err:
146149
raise DBus.from_dbus_error(err) from None
147-
except (EOFError, TimeoutError):
150+
except TimeoutError:
151+
# The systemd D-Bus activate service has a timeout of 25s, which will raise. We should
152+
# not end up here unless the D-Bus broker is majorly overwhelmed.
153+
_LOGGER.critical(
154+
"Timeout connecting to %s - %s", self.bus_name, self.object_path
155+
)
156+
except EOFError:
148157
_LOGGER.warning(
149158
"Busy system at %s - %s", self.bus_name, self.object_path
150159
)

0 commit comments

Comments
 (0)