summaryrefslogtreecommitdiff
path: root/nova/virt/powervm/mgmt.py
diff options
context:
space:
mode:
Diffstat (limited to 'nova/virt/powervm/mgmt.py')
-rw-r--r--nova/virt/powervm/mgmt.py175
1 files changed, 0 insertions, 175 deletions
diff --git a/nova/virt/powervm/mgmt.py b/nova/virt/powervm/mgmt.py
deleted file mode 100644
index a62fa29bde..0000000000
--- a/nova/virt/powervm/mgmt.py
+++ /dev/null
@@ -1,175 +0,0 @@
-# Copyright 2015, 2018 IBM Corp.
-#
-# All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-"""Utilities related to the PowerVM management partition.
-
-The management partition is a special LPAR that runs the PowerVM REST API
-service. It itself appears through the REST API as a LogicalPartition of type
-aixlinux, but with the is_mgmt_partition property set to True.
-The PowerVM Nova Compute service runs on the management partition.
-"""
-import glob
-import os
-from os import path
-
-from oslo_concurrency import lockutils
-from oslo_log import log as logging
-from pypowervm.tasks import partition as pvm_par
-import retrying
-
-from nova import exception
-import nova.privsep.path
-
-
-LOG = logging.getLogger(__name__)
-
-_MP_UUID = None
-
-
-@lockutils.synchronized("mgmt_lpar_uuid")
-def mgmt_uuid(adapter):
- """Returns the management partitions UUID."""
- global _MP_UUID
- if not _MP_UUID:
- _MP_UUID = pvm_par.get_this_partition(adapter).uuid
- return _MP_UUID
-
-
-def discover_vscsi_disk(mapping, scan_timeout=300):
- """Bring a mapped device into the management partition and find its name.
-
- Based on a VSCSIMapping, scan the appropriate virtual SCSI host bus,
- causing the operating system to discover the mapped device. Find and
- return the path of the newly-discovered device based on its UDID in the
- mapping.
-
- Note: scanning the bus will cause the operating system to discover *all*
- devices on that bus. However, this method will only return the path for
- the specific device from the input mapping, based on its UDID.
-
- :param mapping: The pypowervm.wrappers.virtual_io_server.VSCSIMapping
- representing the mapping of the desired disk to the
- management partition.
- :param scan_timeout: The maximum number of seconds after scanning to wait
- for the specified device to appear.
- :return: The udev-generated ("/dev/sdX") name of the discovered disk.
- :raise NoDiskDiscoveryException: If the disk did not appear after the
- specified timeout.
- :raise UniqueDiskDiscoveryException: If more than one disk appears with the
- expected UDID.
- """
- # Calculate the Linux slot number from the client adapter slot number.
- lslot = 0x30000000 | mapping.client_adapter.lpar_slot_num
- # We'll match the device ID based on the UDID, which is actually the last
- # 32 chars of the field we get from PowerVM.
- udid = mapping.backing_storage.udid[-32:]
-
- LOG.debug("Trying to discover VSCSI disk with UDID %(udid)s on slot "
- "%(slot)x.", {'udid': udid, 'slot': lslot})
-
- # Find the special file to scan the bus, and scan it.
- # This glob should yield exactly one result, but use the loop just in case.
- for scanpath in glob.glob(
- '/sys/bus/vio/devices/%x/host*/scsi_host/host*/scan' % lslot):
- # Writing '- - -' to this sysfs file triggers bus rescan
- nova.privsep.path.writefile(scanpath, 'a', '- - -')
-
- # Now see if our device showed up. If so, we can reliably match it based
- # on its Linux ID, which ends with the disk's UDID.
- dpathpat = '/dev/disk/by-id/*%s' % udid
-
- # The bus scan is asynchronous. Need to poll, waiting for the device to
- # spring into existence. Stop when glob finds at least one device, or
- # after the specified timeout. Sleep 1/4 second between polls.
- @retrying.retry(retry_on_result=lambda result: not result, wait_fixed=250,
- stop_max_delay=scan_timeout * 1000)
- def _poll_for_dev(globpat):
- return glob.glob(globpat)
- try:
- disks = _poll_for_dev(dpathpat)
- except retrying.RetryError as re:
- raise exception.NoDiskDiscoveryException(
- bus=lslot, udid=udid, polls=re.last_attempt.attempt_number,
- timeout=scan_timeout)
- # If we get here, _poll_for_dev returned a nonempty list. If not exactly
- # one entry, this is an error.
- if len(disks) != 1:
- raise exception.UniqueDiskDiscoveryException(path_pattern=dpathpat,
- count=len(disks))
-
- # The by-id path is a symlink. Resolve to the /dev/sdX path
- dpath = path.realpath(disks[0])
- LOG.debug("Discovered VSCSI disk with UDID %(udid)s on slot %(slot)x at "
- "path %(devname)s.",
- {'udid': udid, 'slot': lslot, 'devname': dpath})
- return dpath
-
-
-def remove_block_dev(devpath, scan_timeout=10):
- """Remove a block device from the management partition.
-
- This method causes the operating system of the management partition to
- delete the device special files associated with the specified block device.
-
- :param devpath: Any path to the block special file associated with the
- device to be removed.
- :param scan_timeout: The maximum number of seconds after scanning to wait
- for the specified device to disappear.
- :raise InvalidDevicePath: If the specified device or its 'delete' special
- file cannot be found.
- :raise DeviceDeletionException: If the deletion was attempted, but the
- device special file is still present
- afterward.
- """
- # Resolve symlinks, if any, to get to the /dev/sdX path
- devpath = path.realpath(devpath)
- try:
- os.stat(devpath)
- except OSError:
- raise exception.InvalidDevicePath(path=devpath)
- devname = devpath.rsplit('/', 1)[-1]
- delpath = '/sys/block/%s/device/delete' % devname
- try:
- os.stat(delpath)
- except OSError:
- raise exception.InvalidDevicePath(path=delpath)
- LOG.debug("Deleting block device %(devpath)s from the management "
- "partition via special file %(delpath)s.",
- {'devpath': devpath, 'delpath': delpath})
- # Writing '1' to this sysfs file deletes the block device and rescans.
- nova.privsep.path.writefile(delpath, 'a', '1')
-
- # The bus scan is asynchronous. Need to poll, waiting for the device to
- # disappear. Stop when stat raises OSError (dev file not found) - which is
- # success - or after the specified timeout (which is failure). Sleep 1/4
- # second between polls.
- @retrying.retry(retry_on_result=lambda result: result, wait_fixed=250,
- stop_max_delay=scan_timeout * 1000)
- def _poll_for_del(statpath):
- try:
- os.stat(statpath)
- return True
- except OSError:
- # Device special file is absent, as expected
- return False
- try:
- _poll_for_del(devpath)
- except retrying.RetryError as re:
- # stat just kept returning (dev file continued to exist).
- raise exception.DeviceDeletionException(
- devpath=devpath, polls=re.last_attempt.attempt_number,
- timeout=scan_timeout)
- # Else stat raised - the device disappeared - all done.