107 """Force the link reinitialization to make the LUN present.""" |
107 """Force the link reinitialization to make the LUN present.""" |
108 wwpns = self.get_fc_wwpns() |
108 wwpns = self.get_fc_wwpns() |
109 for wwpn in wwpns: |
109 for wwpn in wwpns: |
110 self.execute('/usr/sbin/fcadm', 'force-lip', wwpn) |
110 self.execute('/usr/sbin/fcadm', 'force-lip', wwpn) |
111 |
111 |
112 def _get_device_path(self, wwn): |
112 def _get_device_path(self, wwn, target_lun): |
113 """Get the Device Name of the WWN""" |
113 """Get the Device path for the specified LUN. |
|
114 |
|
115 The output of CMD below is like this: |
|
116 |
|
117 OS Device Name: /dev/rdsk/c0t600C0FF0000000000036223AE73EB705d0s2 |
|
118 HBA Port WWN: 210100e08b27a8a1 |
|
119 Remote Port WWN: 256000c0ffc03622 |
|
120 LUN: 0 |
|
121 Remote Port WWN: 216000c0ff803622 |
|
122 LUN: 0 |
|
123 HBA Port WWN: 210000e08b07a8a1 |
|
124 Remote Port WWN: 256000c0ffc03622 |
|
125 LUN: 0 |
|
126 Remote Port WWN: 216000c0ff803622 |
|
127 LUN: 0 |
|
128 Vendor: SUN |
|
129 Product: StorEdge 3510 |
|
130 Device Type: Disk device |
|
131 ...... |
|
132 """ |
114 try: |
133 try: |
115 out, err = self.execute('/usr/sbin/fcinfo', 'logical-unit', '-v') |
134 out, err = self.execute('/usr/sbin/fcinfo', 'logical-unit', '-v') |
116 except putils.ProcessExecutionError as err: |
135 except putils.ProcessExecutionError as err: |
117 return None |
136 return None |
118 |
137 |
119 host_dev = None |
138 host_device = None |
120 remote_port = None |
139 remote_port = None |
121 if out is not None: |
140 if out is not None: |
122 for line in [l.strip() for l in out.splitlines()]: |
141 for line in [l.strip() for l in out.splitlines()]: |
123 if line.startswith("OS Device Name:"): |
142 if line.startswith("OS Device Name:"): |
124 host_dev = line.split()[-1] |
143 host_device = line.split()[-1] |
125 if line.startswith("Remote Port WWN:"): |
144 if line.startswith("Remote Port WWN:"): |
126 remote_port = line.split()[-1] |
145 remote_port = line.split()[-1] |
127 if remote_port == wwn: |
146 if line.startswith("LUN:"): |
128 return host_dev |
147 lun = line.split()[-1] |
|
148 if remote_port.upper() == wwn and \ |
|
149 int(lun) == int(target_lun): |
|
150 return host_device |
129 |
151 |
130 return None |
152 return None |
131 |
153 |
132 def connect_volume(self, connection_properties, scan_tries): |
154 def connect_volume(self, connection_properties, scan_tries): |
133 """Attach the volume to instance_name. |
155 """Attach the volume to instance_name. |
134 |
156 |
135 connection_properties for Fibre Channel must include: |
157 connection_properties for Fibre Channel must include: |
136 target_portal - ip and optional port |
158 target_wwn - Specified port WWNs |
137 target_iqn - iSCSI Qualified Name |
|
138 target_lun - LUN id of the volume |
159 target_lun - LUN id of the volume |
139 """ |
160 """ |
140 device_info = {'type': 'block'} |
161 device_info = {'type': 'block'} |
141 target_wwn = connection_properties['target_wwn'] |
162 target_wwn = connection_properties['target_wwn'] |
142 # Check for multiple target_wwn values in a list |
163 target_lun = connection_properties['target_lun'] |
|
164 wwns = [] |
143 if isinstance(target_wwn, list): |
165 if isinstance(target_wwn, list): |
144 wwn = target_wwn[0] |
166 wwns = target_wwn |
|
167 else: |
|
168 wwns.append(target_wwn) |
145 |
169 |
146 # The scsi_vhci disk node is not always present immediately. |
170 # The scsi_vhci disk node is not always present immediately. |
147 # Sometimes we need to reinitialize the connection to trigger |
171 # Sometimes we need to reinitialize the connection to trigger |
148 # a refresh. |
172 # a refresh. |
149 for i in range(1, scan_tries): |
173 for i in range(1, scan_tries): |
150 LOG.debug("Looking for Fibre Channel device") |
174 # initiator needs time to refresh the LU list |
151 host_dev = self._get_device_path(wwn) |
175 time.sleep(i * 2) |
|
176 host_device = self._get_device_path(wwns[0], target_lun) |
152 |
177 |
153 if host_dev is not None and os.path.exists(host_dev): |
178 if host_device is not None and os.path.exists(host_device): |
154 break |
179 break |
155 else: |
180 else: |
156 self._refresh_connection() |
181 self._refresh_connection() |
157 time.sleep(i ** 2) |
|
158 else: |
182 else: |
159 msg = _("Fibre Channel volume device not found.") |
183 msg = _("Fibre Channel volume device not found.") |
160 LOG.error(msg) |
184 LOG.error(msg) |
161 raise exception.NoFibreChannelVolumeDeviceFound() |
185 raise exception.NoFibreChannelVolumeDeviceFound() |
162 |
186 |