Add ipmi_disable_timeout to avoid problematic IPMI command
The IPMI driver unconditionally instructed the BMC not automatically clear boot flag valid bit if Chassis Control command not received within 60-second timeout (countdown restarts when a Chassis Control command is received). Some BMCs do not support setting this. Sending the command aborts the node boot. A new driver option ``ipmi_disable_timeout`` is added to bypass sending this command. Change-Id: I1dda3cf3e4b7b888ed9d8931c8ede3a918dd01f4 Story: 2004266
This commit is contained in:
parent
ebd671c4b6
commit
eb29465bd5
api-ref/source/samples
ironic
releasenotes/notes
@ -7,6 +7,7 @@
|
||||
"image_no_proxy": "A comma-separated list of host names, IP addresses and domain names (with optional :port) that will be excluded from proxying. To denote a domain name, use a dot to prefix the domain name. This value will be ignored if ``image_http_proxy`` and ``image_https_proxy`` are not specified. Optional.",
|
||||
"ipmi_address": "IP address or hostname of the node. Required.",
|
||||
"ipmi_bridging": "bridging_type; default is \"no\". One of \"single\", \"dual\", \"no\". Optional.",
|
||||
"ipmi_disable_timeout": "By default ironic will send a raw IPMI command to disable the 60 second timeout for booting. Setting this option to False will NOT send that command; default value is True. Optional.",
|
||||
"ipmi_force_boot_device": "Whether Ironic should specify the boot device to the BMC each time the server is turned on, eg. because the BMC is not capable of remembering the selected boot device across power cycles; default value is False. Optional.",
|
||||
"ipmi_local_address": "local IPMB address for bridged requests. Used only if ipmi_bridging is set to \"single\" or \"dual\". Optional.",
|
||||
"ipmi_password": "password. Optional.",
|
||||
|
@ -97,7 +97,12 @@ OPTIONAL_PROPERTIES = {
|
||||
"is turned on, eg. because the BMC is not "
|
||||
"capable of remembering the selected boot "
|
||||
"device across power cycles; default value "
|
||||
"is False. Optional.")
|
||||
"is False. Optional."),
|
||||
'ipmi_disable_timeout': _('By default ironic will send a raw IPMI '
|
||||
'command to disable the 60 second timeout '
|
||||
'for booting. Setting this option to '
|
||||
'False will NOT send that command; default '
|
||||
'value is True. Optional.'),
|
||||
}
|
||||
COMMON_PROPERTIES = REQUIRED_PROPERTIES.copy()
|
||||
COMMON_PROPERTIES.update(OPTIONAL_PROPERTIES)
|
||||
@ -912,13 +917,24 @@ class IPMIManagement(base.ManagementInterface):
|
||||
raise exception.InvalidParameterValue(_(
|
||||
"Invalid boot device %s specified.") % device)
|
||||
|
||||
# note(JayF): IPMI spec indicates unless you send these raw bytes the
|
||||
# boot device setting times out after 60s. Since it's possible it
|
||||
# could be >60s before a node is rebooted, we should always send them.
|
||||
# This mimics pyghmi's current behavior, and the "option=timeout"
|
||||
# setting on newer ipmitool binaries.
|
||||
timeout_disable = "0x00 0x08 0x03 0x08"
|
||||
send_raw(task, timeout_disable)
|
||||
# NOTE(tonyb): Some BMCs do not implement Option 0x03, such as OpenBMC
|
||||
# and will error when we try to set this. Resulting in an abort. If
|
||||
# the BMC doesn't support this timeout there isn't a need to disable
|
||||
# it. Let's use a driver option to signify that
|
||||
idt = task.node.driver_info.get('ipmi_disable_timeout', True)
|
||||
if strutils.bool_from_string(idt):
|
||||
# note(JayF): IPMI spec indicates unless you send these raw bytes
|
||||
# the boot device setting times out after 60s. Since it's possible
|
||||
# it could be >60s before a node is rebooted, we should always send
|
||||
# them. This mimics pyghmi's current behavior, and the
|
||||
# "option=timeout" setting on newer ipmitool binaries.
|
||||
timeout_disable = "0x00 0x08 0x03 0x08"
|
||||
send_raw(task, timeout_disable)
|
||||
else:
|
||||
LOG.info('For node %(node_uuid)s, '
|
||||
'driver_info[\'ipmi_disable_timeout\'] is set to False, '
|
||||
'so not sending ipmi boot-timeout-disable',
|
||||
{'node_uuid', task.node.uuid})
|
||||
|
||||
if task.node.driver_info.get('ipmi_force_boot_device', False):
|
||||
driver_utils.force_persistent_boot(task,
|
||||
|
@ -6857,7 +6857,8 @@ class ManagerTestProperties(mgr_utils.ServiceSetUpMixin, db_base.DbTestCase):
|
||||
'deploy_kernel', 'deploy_ramdisk',
|
||||
'force_persistent_boot_device', 'ipmi_protocol_version',
|
||||
'ipmi_force_boot_device', 'deploy_forces_oob_reboot',
|
||||
'rescue_kernel', 'rescue_ramdisk']
|
||||
'rescue_kernel', 'rescue_ramdisk',
|
||||
'ipmi_disable_timeout']
|
||||
self._check_driver_properties("ipmi", expected)
|
||||
|
||||
def test_driver_properties_snmp(self):
|
||||
|
@ -1953,6 +1953,20 @@ class IPMIToolDriverTestCase(Base):
|
||||
self.management.set_boot_device,
|
||||
task, 'fake-device')
|
||||
|
||||
@mock.patch.object(ipmi, '_exec_ipmitool', autospec=True)
|
||||
def test_management_interface_set_boot_device_without_timeout(self,
|
||||
mock_exec):
|
||||
mock_exec.return_value = [None, None]
|
||||
|
||||
with task_manager.acquire(self.context, self.node.uuid) as task:
|
||||
driver_info = task.node.driver_info
|
||||
driver_info['ipmi_disable_timeout'] = 'False'
|
||||
task.node.driver_info = driver_info
|
||||
self.management.set_boot_device(task, boot_devices.PXE)
|
||||
|
||||
mock_calls = [mock.call(self.info, "chassis bootdev pxe")]
|
||||
mock_exec.assert_has_calls(mock_calls)
|
||||
|
||||
@mock.patch.object(ipmi, '_exec_ipmitool', autospec=True)
|
||||
def test_management_interface_set_boot_device_exec_failed(self, mock_exec):
|
||||
mock_exec.side_effect = processutils.ProcessExecutionError()
|
||||
|
13
releasenotes/notes/story-2004266-4725d327900850bf.yaml
Normal file
13
releasenotes/notes/story-2004266-4725d327900850bf.yaml
Normal file
@ -0,0 +1,13 @@
|
||||
---
|
||||
fixes:
|
||||
- |
|
||||
The IPMI hardware type unconditionally instructed the BMC to not
|
||||
automatically clear boot flag valid bit if Chassis Control command not
|
||||
received within 60-second timeout (countdown restarts when a Chassis
|
||||
Control command is received). Some BMCs do not support setting this; if
|
||||
sent it causes the boot to be aborted instead. For IPMI hardware type a
|
||||
new driver option ``node['driver_info']['ipmi_disable_timeout']`` can be
|
||||
specified. It is ``True`` by default; set it to ``False`` to bypass
|
||||
sending this command. See `story 2004266
|
||||
<https://storyboard.openstack.org/#!/story/2004266>`_ for additional
|
||||
information.
|
Loading…
x
Reference in New Issue
Block a user