autotest:add file based lock/unlock logical to servo host.
BUG=chromium:971915
TEST=repair task on santiam lab hosts.
Change-Id: I7fc6c593de089a34d2c216c9bb01e3d500a90d77
Reviewed-on: https://chromium-review.googlesource.com/1655676
Tested-by: Garry Wang <xianuowang@chromium.org>
Commit-Ready: Garry Wang <xianuowang@chromium.org>
Legacy-Commit-Queue: Commit Bot <commit-bot@chromium.org>
Reviewed-by: Garry Wang <xianuowang@chromium.org>
diff --git a/server/hosts/base_servohost.py b/server/hosts/base_servohost.py
index 7b2f839..f835667 100644
--- a/server/hosts/base_servohost.py
+++ b/server/hosts/base_servohost.py
@@ -38,10 +38,13 @@
"""
REBOOT_CMD = 'sleep 1; reboot & sleep 10; reboot -f'
- SERVOHOST_TEMP_FILE_DIR = '/var/lib/servod/'
+ TEMP_FILE_DIR = '/var/lib/servod/'
+
+ LOCK_FILE_POSTFIX = '_in_use'
+ REBOOT_FILE_POSTFIX = '_reboot'
# Time to wait a rebooting servohost. In seconds
- SERVOHOST_REBOOT_TIMEOUT = 120
+ REBOOT_TIMEOUT = 120
def _initialize(self, hostname, is_in_lab=None, *args, **dargs):
@@ -299,7 +302,7 @@
raise error.AutoservHostError(
'servo host %s failed to shut down.' %
self.hostname)
- if self.wait_up(timeout=self.SERVOHOST_REBOOT_TIMEOUT):
+ if self.wait_up(timeout=self.REBOOT_TIMEOUT):
logging.info('servo host %s back from reboot, with build %s',
self.hostname, self._get_release_version())
else:
diff --git a/server/hosts/servo_host.py b/server/hosts/servo_host.py
index 811ef4d..5d34ea2 100644
--- a/server/hosts/servo_host.py
+++ b/server/hosts/servo_host.py
@@ -14,6 +14,7 @@
import os
from autotest_lib.client.bin import utils
+from autotest_lib.client.common_lib import error
from autotest_lib.client.common_lib import global_config
from autotest_lib.client.common_lib import hosts
from autotest_lib.client.common_lib.cros import retry
@@ -87,6 +88,20 @@
self.servo_model = servo_model
self.servo_serial = servo_serial
self._servo = None
+ # Path of the servo host lock file.
+ self._lock_file = (self.TEMP_FILE_DIR + str(self.servo_port)
+ + self.LOCK_FILE_POSTFIX)
+ # File path to declare a reboot request.
+ self._reboot_file = (self.TEMP_FILE_DIR + str(self.servo_port)
+ + self.REBOOT_FILE_POSTFIX)
+
+ # Lock the servo host if it's an in-lab labstation to prevent other
+ # task to reboot it until current task completes. We also wait and
+ # make sure the labstation is up here, in the case of the labstation is
+ # in the middle of reboot.
+ if (self.is_in_lab() and self.is_labstation()
+ and self.wait_up(self.REBOOT_TIMEOUT)):
+ self._lock()
self._repair_strategy = (
servo_repair.create_servo_repair_strategy())
@@ -183,6 +198,30 @@
return self._servo
+ def request_reboot(self):
+ """Request servohost to be rebooted when it's safe to by touch a file.
+ """
+ logging.debug('Request to reboot servohost %s has been created by '
+ 'servo with port %s', self.hostname, self.servo_port)
+ self.run('touch %s' % self._reboot_file, ignore_status=True)
+
+
+ def _lock(self):
+ """lock servohost by touching a file.
+ """
+ logging.debug('Locking servohost %s by touching %s file',
+ self.hostname, self._lock_file)
+ self.run('touch %s' % self._lock_file, ignore_status=True)
+
+
+ def _unlock(self):
+ """Unlock servohost by removing the lock file.
+ """
+ logging.debug('Unlocking servohost by removing %s file',
+ self._lock_file)
+ self.run('rm %s' % self._lock_file, ignore_status=True)
+
+
def close(self):
"""Close the associated servo and the host object."""
if self._servo:
@@ -191,6 +230,15 @@
self._servo.uart_logs_dir = self.job.resultdir
self._servo.close()
+ if self.is_in_lab() and self.is_labstation():
+ # Remove the lock if the host is an in-lab labstation.
+ try:
+ self._unlock()
+ except error.AutoservSSHTimeout:
+ logging.error('Unlock servohost failed due to ssh timeout.'
+ ' It may caused by servohost went down during'
+ ' the task.')
+
super(ServoHost, self).close()
diff --git a/server/hosts/servo_repair.py b/server/hosts/servo_repair.py
index 953934d..d73d004 100644
--- a/server/hosts/servo_repair.py
+++ b/server/hosts/servo_repair.py
@@ -309,10 +309,9 @@
'Target servo is not a test lab servo',
'servo_not_applicable_to_host_outside_lab')
if host.is_labstation():
- raise hosts.AutoservRepairError(
- 'Repairing that reboot labstation is not supported.'
- ' See crbug.com/843358',
- 'can_not_repair_labstation_with_multiple_hosts')
+ host.request_reboot()
+ logging.warning('Reboot labstation requested, it will be '
+ 'handled by labstation administrative task.')
else:
host.update_image(wait_for_update=True)
super(_ServoRebootRepair, self).repair(host)