Drew Thorstensen 9b1319c1c5 Support parallel IO next steps
This change set supports the second step of I/O parallelization that is
required for PowerVM.  It makes use of a new pypowervm function
surrounding 'Transactions'.  These transactions encapsulate retry
functions, locking, etc...

The main benefit for this is around the Virtual I/O Server changes.  The
most expensive part of the deploy path is adding/removing vSCSI and NPIV
mappings from the I/O Server to the VM.

This change allows us to batch together the I/O Server changes into a
single transaction for vDisk and NPIV operations.  A second change set
will be provided to include the config drive functions as well.

These transaction allow for us to batch together many changes to I/O
servers within a single update.  Also if multiple I/O servers are being
updated, they will each be able to run in parallel.  The multiple I/O
server changes are handled via pypowervm's transaction FeedTask.

This should allow for linear scaling regardless of the number of storage
operations that are required and independent of the number of VIOSes.

Future change sets will further enhance the amount of work delegated to
the transaction feed task.

Change-Id: I4de93f5cbdb56c337b65868c5412c69fd702e82d
2015-08-12 15:05:33 -04:00

103 lines
4.0 KiB
Python

# Copyright 2015 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.
from oslo_config import cfg
from oslo_log import log as logging
from pypowervm.utils import transaction as pvm_tx
from pypowervm.wrappers import base_partition as pvm_bp
from pypowervm.wrappers import managed_system as pvm_ms
from pypowervm.wrappers import virtual_io_server as pvm_vios
LOG = logging.getLogger(__name__)
CONF = cfg.CONF
# RMC must be either active or busy. Busy is allowed because that simply
# means that something is running against the VIOS at the moment...but
# it should recover shortly.
VALID_RMC_STATES = [pvm_bp.RMCState.ACTIVE, pvm_bp.RMCState.BUSY]
# Only a running state is OK for now.
VALID_VM_STATES = [pvm_bp.LPARState.RUNNING]
def get_active_vioses(adapter, host_uuid, xag=None):
"""Returns a list of active Virtual I/O Server Wrappers for a host.
Active is defined by powered on and RMC state being 'active'.
:param adapter: The pypowervm adapter for the query.
:param host_uuid: The host servers UUID.
:param xag: Optional list of extended attributes to use. If not passed
in defaults to None.
:return: List of VIOS wrappers.
"""
vio_feed_resp = adapter.read(pvm_ms.System.schema_type, root_id=host_uuid,
child_type=pvm_vios.VIOS.schema_type,
xag=xag)
wrappers = pvm_vios.VIOS.wrap(vio_feed_resp)
return [vio for vio in wrappers if is_vios_active(vio)]
def is_vios_active(vios):
"""Returns a boolean to indicate if the VIOS is active.
Active is defined by running, and the RMC being 'active'.
:param vios: The Virtual I/O Server wrapper to validate.
:return: Boolean
"""
return (vios.rmc_state in VALID_RMC_STATES and
vios.state in VALID_VM_STATES)
def get_physical_wwpns(adapter, ms_uuid):
"""Returns the active WWPNs of the FC ports across all VIOSes on system."""
resp = adapter.read(pvm_ms.System.schema_type, root_id=ms_uuid,
child_type=pvm_vios.VIOS.schema_type,
xag=[pvm_vios.VIOS.xags.STORAGE])
vios_feed = pvm_vios.VIOS.wrap(resp)
wwpn_list = []
for vios in vios_feed:
wwpn_list.extend(vios.get_active_pfc_wwpns())
return wwpn_list
def build_tx_feed_task(adapter, host_uuid, name='vio_feed_mgr',
xag=[pvm_vios.VIOS.xags.STORAGE,
pvm_vios.VIOS.xags.SCSI_MAPPING,
pvm_vios.VIOS.xags.FC_MAPPING]):
"""Builds the pypowervm transaction FeedTask.
The transaction FeedTask enables users to collect a set of
'WrapperTasks' against a feed of entities (in this case a set of VIOSes).
The WrapperTask (within the FeedTask) handles lock and retry.
This is useful to batch together a set of updates across a feed of elements
(and multiple updates within a given wrapper). This allows for significant
performance improvements.
:param adapter: The pypowervm adapter for the query.
:param host_uuid: The host server's UUID.
:param name: (Optional) The name of the feed manager. Defaults to
vio_feed_mgr.
:param xag: (Optional) List of extended attributes to use. If not passed
in defaults to all storage options (as this is most common
case for using a transaction manager).
"""
return pvm_tx.FeedTask(name,
get_active_vioses(adapter, host_uuid, xag=xag))