--- a/components/openstack/cinder/files/solaris/zfs.py Tue Mar 21 13:15:18 2017 -0700
+++ b/components/openstack/cinder/files/solaris/zfs.py Wed May 25 14:31:44 2016 -0700
@@ -2,7 +2,7 @@
# Copyright (c) 2012 OpenStack LLC.
# All Rights Reserved.
#
-# Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2014, 2017, Oracle and/or its affiliates. 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
@@ -965,14 +965,18 @@
return status
- def check_for_setup_error(self):
- """Check the setup error."""
- wwns = self._get_wwns()
- if not wwns:
+ def do_setup(self, context):
+ """Check wwns and setup the target group."""
+ self.wwns = self._get_wwns()
+ if not self.wwns:
msg = (_("Could not determine fibre channel world wide "
"node names."))
raise exception.VolumeBackendAPIException(data=msg)
+ self.tg = 'tg-wwn-%s' % self.wwns[0]
+ if not self._check_tg(self.tg):
+ self._setup_tg(self.tg)
+
def _get_wwns(self):
"""Get the FC port WWNs of the host."""
(out, _err) = self._execute('/usr/sbin/fcinfo', 'hba-port', '-t')
@@ -986,19 +990,45 @@
return wwns
- def _check_wwn_tg(self, wwn):
- """Check if the target group 'tg-wwn-xxx' exists."""
- (out, _err) = self._execute('/usr/sbin/stmfadm', 'list-tg')
+ def _get_target_wwns(self, tg):
+ """Get the target members in the tg."""
+ (out, _err) = self._execute('/usr/sbin/stmfadm', 'list-tg',
+ '-v', tg)
+ wwns = []
for line in [l.strip() for l in out.splitlines()]:
- if line.startswith("Target Group:") and wwn in line:
- tg = line.split()[-1]
- break
- else:
- LOG.debug(_("The target group 'tg-wwn-%s' doesn't exist.") % wwn)
- tg = None
+ if line.startswith("Member:"):
+ wwn = line.split()[-1]
+ target_wwn = wwn.split('.')[-1]
+ wwns.append(target_wwn)
+ return wwns
+
+ def _setup_tg(self, tg):
+ """Setup the target group."""
+ self._stmf_execute('/usr/sbin/stmfadm', 'create-tg', tg)
- return tg
+ # Add free target wwns into the target group
+ for wwn in self.wwns:
+ if not self._target_in_tg(wwn, None):
+ target_wwn = 'wwn.%s' % wwn
+ try:
+ self._stmf_execute('/usr/sbin/stmfadm', 'offline-target',
+ target_wwn)
+ self._stmf_execute('/usr/sbin/stmfadm', 'add-tg-member',
+ '-g', tg, target_wwn)
+ self._stmf_execute('/usr/sbin/stmfadm', 'online-target',
+ target_wwn)
+ assert self._check_target(wwn, 'Channel') == 'Online'
+
+ except:
+ LOG.error(_LE("Failed to add and online the target '%s'.")
+ % (target_wwn))
+
+ target_wwns = self._get_target_wwns(tg)
+ if not target_wwns:
+ msg = (_("No target members exist in the target group '%s'.")
+ % tg)
+ raise exception.VolumeBackendAPIException(data=msg)
def _only_lu(self, lu):
"""Check if the LU is the only one."""
@@ -1025,13 +1055,19 @@
'-v', tg)
else:
(out, _err) = self._execute('/usr/sbin/stmfadm', 'list-tg', '-v')
-
for line in [l.strip() for l in out.splitlines()]:
if line.startswith("Member:") and target in line:
return True
- LOG.debug(_("The target '%s' is not in any target group.") % target)
+ LOG.debug(_("The target '%s' is not in %s target group.") %
+ (target, tg if tg else 'any'))
return False
+ def _force_lip_wwn(self):
+ """Force the link to reinitialize."""
+ target_wwns = self._get_target_wwns(self.tg)
+ for target_wwn in target_wwns:
+ self._stmf_execute('/usr/sbin/fcadm', 'force-lip', target_wwn)
+
def create_export(self, context, volume):
"""Export the volume."""
# If the volume is already exported there is nothing to do, as we
@@ -1047,7 +1083,6 @@
raise exception.VolumeBackendAPIException(data=msg)
zvol = self._get_zvol_path(volume)
-
# Create a Logical Unit (LU)
self._stmf_execute('/usr/sbin/stmfadm', 'create-lu', zvol)
luid = self._get_luid(volume)
@@ -1056,55 +1091,28 @@
% volume['name'])
raise exception.VolumeBackendAPIException(data=msg)
- wwns = self._get_wwns()
- wwn = wwns[0]
- target_group = self._check_wwn_tg(wwn)
- if target_group is None:
- target_group = 'tg-wwn-%s' % wwn
- if self._target_in_tg(wwn, None):
- msg = (_("Target WWN '%s' has been found in another"
- "target group, so it will not be added "
- "into the expected target group '%s'.") %
- (wwn, target_group))
- raise exception.VolumeBackendAPIException(data=msg)
-
- # Create a target group for the wwn
- self._stmf_execute('/usr/sbin/stmfadm', 'create-tg', target_group)
-
- # Enable the target and add it to the 'tg-wwn-xxx' group
- self._stmf_execute('/usr/sbin/stmfadm', 'offline-target',
- 'wwn.%s' % wwn)
- self._stmf_execute('/usr/sbin/stmfadm', 'add-tg-member', '-g',
- target_group, 'wwn.%s' % wwn)
-
+ # setup the target group if it doesn't exist.
+ if not self._check_tg(self.tg):
+ self._setup_tg(self.tg)
# Add a logical unit view entry
- # TODO(Strony): replace the auto assigned LUN with '-n' option
- if luid is not None:
- self._stmf_execute('/usr/sbin/stmfadm', 'add-view', '-t',
- target_group, luid)
- self._stmf_execute('/usr/sbin/stmfadm', 'online-target',
- 'wwn.%s' % wwn)
- assert self._target_in_tg(wwn, target_group)
+ self._stmf_execute('/usr/sbin/stmfadm', 'add-view', '-t',
+ self.tg, luid)
+ self._force_lip_wwn()
def remove_export(self, context, volume):
"""Remove an export for a volume."""
luid = self._get_luid(volume)
if luid is not None:
- wwns = self._get_wwns()
- wwn = wwns[0]
- target_wwn = 'wwn.%s' % wwn
- target_group = 'tg-wwn-%s' % wwn
+ target_group = self.tg
view_lun = self._get_view_and_lun(luid)
if view_lun['view']:
self._stmf_execute('/usr/sbin/stmfadm', 'remove-view', '-l',
luid, view_lun['view'])
- # Remove the target group when only one LU exists.
+ # Remove the target group when the LU to be deleted is last one
+ # exposed by the target group.
if self._only_lu(luid):
- if self._check_target(target_wwn, 'Channel') == 'Online':
- self._stmf_execute('/usr/sbin/stmfadm', 'offline-target',
- target_wwn)
if self._check_tg(target_group):
self._stmf_execute('/usr/sbin/stmfadm', 'delete-tg',
target_group)
@@ -1120,12 +1128,6 @@
:target_lun: the lun assigned to the LU for the view entry
"""
- wwns = self._get_wwns()
- if not wwns:
- msg = (_("Could not determine fibre channel world wide "
- "node names."))
- raise exception.VolumeBackendAPIException(data=msg)
-
luid = self._get_luid(volume)
if not luid:
msg = (_("Failed to get logic unit for volume '%s'")
@@ -1135,7 +1137,7 @@
properties = {}
properties['target_discovered'] = True
- properties['target_wwn'] = wwns
+ properties['target_wwn'] = self._get_target_wwns(self.tg)
view_lun = self._get_view_and_lun(luid)
if view_lun['lun'] is not None:
properties['target_lun'] = view_lun['lun']