1
0
mirror of https://github.com/ARM-software/devlib.git synced 2025-01-31 02:00:45 +00:00

utils/android: Fix AdbConnection.adb_root()

adb_root() restarts the server, leading to aborting commands ran by
other connections and also apparently leading to command hanging in some
situations.

Therefore, only allow adb_root() when there is only one connection
active. That should not be a big issue as this is typically called by
the first connection ever made when the Target is created.
This commit is contained in:
Douglas Raillard 2022-08-12 18:14:12 +01:00 committed by Marc Bonnici
parent b7ef2dc2e0
commit b988e245d9
2 changed files with 22 additions and 4 deletions

View File

@ -180,3 +180,11 @@ def get_traceback(exc=None):
traceback.print_tb(tb, file=sio)
del tb # needs to be done explicitly see: http://docs.python.org/2/library/sys.html#sys.exc_info
return sio.getvalue()
class AdbRootError(TargetStableError):
"""
Exception raised when it is not safe to use ``adb root`` or ``adb unroot``
because other connections are known to be active, and changing rootness
requires restarting the server.
"""

View File

@ -40,7 +40,7 @@ try:
except ImportError:
from pipes import quote
from devlib.exception import TargetTransientError, TargetStableError, HostError, TargetTransientCalledProcessError, TargetStableCalledProcessError
from devlib.exception import TargetTransientError, TargetStableError, HostError, TargetTransientCalledProcessError, TargetStableCalledProcessError, AdbRootError
from devlib.utils.misc import check_output, which, ABI_MAP, redirect_streams, get_subprocess
from devlib.connection import ConnectionBase, AdbBackgroundCommand, PopenBackgroundCommand, PopenTransferManager
@ -301,10 +301,17 @@ class AdbConnection(ConnectionBase):
'poll_period': transfer_poll_period,
}
self.transfer_mgr = PopenTransferManager(self, **transfer_opts) if poll_transfers else None
if self.adb_as_root:
self.adb_root(enable=True)
adb_connect(self.device, adb_server=self.adb_server, attempts=connection_attempts)
AdbConnection.active_connections[self.device] += 1
if self.adb_as_root:
try:
self.adb_root(enable=True)
# Exception will be raised if we are not the only connection
# active. adb_root() requires restarting the server, which is not
# acceptable if other connections are active and can apparently
# lead to commands hanging forever in some situations.
except AdbRootError:
pass
adb_connect(self.device, adb_server=self.adb_server, attempts=connection_attempts)
self._setup_ls()
self._setup_su()
@ -384,6 +391,9 @@ class AdbConnection(ConnectionBase):
pass
def adb_root(self, enable=True):
if AdbConnection.active_connections[self.device] > 1:
raise AdbRootError('Can only restart adb server if no other connection is active')
cmd = 'root' if enable else 'unroot'
try:
output = adb_command(self.device, cmd, timeout=30, adb_server=self.adb_server)