def terminate_connection(self, volume, connector, **kwargs): self.do_setup_status.wait() ldev = self.common.get_ldev(volume) if ldev is None: msg = basic_lib.set_msg(302, volume_id=volume['id']) LOG.warning(msg) return if 'wwpns' not in connector: msg = basic_lib.output_err(650, resource='HBA') raise exception.HBSDError(message=msg) hostgroups = [] self._get_hostgroup_info(hostgroups, connector['wwpns'], login=False) if not hostgroups: msg = basic_lib.output_err(649) raise exception.HBSDError(message=msg) self.common.add_volinfo(ldev, volume['id']) with nested(self.common.volume_info[ldev]['lock'], self.common.volume_info[ldev]['in_use']): self._terminate_connection(ldev, connector, hostgroups) properties = self._get_properties(volume, hostgroups, terminate=True) LOG.debug('Terminate volume_info: %s' % self.common.volume_info) return {'driver_volume_type': 'fibre_channel', 'data': properties}
def create_volume_from_snapshot(self, volume, snapshot): pvol = self.get_ldev(snapshot) if pvol is None: msg = basic_lib.output_err(624, type='snapshot', id=snapshot['id']) raise exception.HBSDError(message=msg) self.add_volinfo(pvol, id=snapshot['id'], type='snapshot') with self.volume_info[pvol]['in_use']: is_vvol = self.get_snapshot_is_vvol(snapshot) if snapshot['status'] != 'available': msg = basic_lib.output_err(655, status=snapshot['status']) raise exception.HBSDError(message=msg) size = volume['size'] src_size = snapshot['volume_size'] if size != src_size: msg = basic_lib.output_err(617, type='snapshot', volume_id=volume['id']) raise exception.HBSDError(message=msg) metadata = self.get_volume_metadata(volume['id']) method = None if is_vvol else self.get_copy_method(volume) svol, type = self.copy_data(pvol, size, is_vvol, method) metadata['type'] = type metadata['snapshot'] = snapshot['id'] metadata['ldev'] = svol return {'provider_location': svol, 'metadata': metadata}
def create_cloned_volume(self, volume, src_vref): pvol = self.get_ldev(src_vref) if pvol is None: msg = basic_lib.output_err(624, type='volume', id=src_vref['id']) raise exception.HBSDError(message=msg) self.add_volinfo(pvol, src_vref['id']) with self.volume_info[pvol]['in_use']: is_vvol = self.get_volume_is_vvol(src_vref) self.check_volume_status(self.get_volume(src_vref['id']), is_vvol) size = volume['size'] src_size = src_vref['size'] if size != src_size: msg = basic_lib.output_err(617, type='volume', volume_id=volume['id']) raise exception.HBSDError(message=msg) metadata = self.get_volume_metadata(volume['id']) method = None if is_vvol else self.get_copy_method(volume) svol, type = self.copy_data(pvol, size, is_vvol, method) metadata['type'] = type metadata['volume'] = src_vref['id'] metadata['ldev'] = svol return {'provider_location': svol, 'metadata': metadata}
def _range2list(self, conf, param): str = getattr(conf, param) lists = str.split('-') if len(lists) != 2: msg = basic_lib.output_err(601, param=param) raise exception.HBSDError(message=msg) first_type = None for i in range(len(lists)): if lists[i].isdigit(): lists[i] = int(lists[i], 10) if first_type == 'hex': msg = basic_lib.output_err(601, param=param) raise exception.HBSDError(message=msg) first_type = 'dig' else: if (first_type == 'dig' or not re.match('\w\w:\w\w:\w\w', lists[i])): msg = basic_lib.output_err(601, param=param) raise exception.HBSDError(message=msg) try: lists[i] = int(lists[i].replace(':', ''), 16) first_type = 'hex' except Exception: msg = basic_lib.output_err(601, param=param) raise exception.HBSDError(message=msg) if lists[0] > lists[1]: msg = basic_lib.output_err(601, param=param) raise exception.HBSDError(message=msg) return lists
def get_gid_from_targetiqn(self, target_iqn, target_alias, port): unit = self.unit_name ret, stdout, stderr = self.exec_hsnm('autargetdef', '-unit %s -refer' % unit) if ret: msg = basic_lib.output_err(600, cmd='autargetdef', ret=ret, out=stdout, err=stderr) raise exception.HBSDCmdError(message=msg, ret=ret, err=stderr) gid = None tmp_port = None found_alias_full = False found_alias_part = False lines = stdout.splitlines() for line in lines: line = shlex.split(line) if not line: continue if line[0] == "Port": tmp_port = line[1] continue if port != tmp_port: continue if line[0][0:3].isdigit(): tmp_gid = int(line[0][0:3]) if re.match(basic_lib.NAME_PREFIX, line[0][4:]): found_alias_part = True if line[0][4:] == target_alias: found_alias_full = True continue if line[0] == "iSCSI": if line[3] == target_iqn: gid = tmp_gid break else: found_alias_part = False if found_alias_full and gid is None: msg = basic_lib.output_err(641) raise exception.HBSDError(message=msg) # When 'gid' is 0, it should be true. # So, it cannot remove 'is not None'. if not found_alias_part and gid is not None: msg = basic_lib.output_err(641) raise exception.HBSDError(message=msg) return gid
def get_copy_method(self, volume): method = self.get_value(volume, 'volume_metadata', 'copy_method') if method: if method not in COPY_METHOD: msg = basic_lib.output_err(602, meta='copy_method') raise exception.HBSDError(message=msg) elif (method == 'THIN' and self.configuration.hitachi_thin_pool_id is None): msg = basic_lib.output_err(601, param='hitachi_thin_pool_id') raise exception.HBSDError(message=msg) else: method = self.configuration.hitachi_default_copy_method return method
def comm_get_iscsi_ip(self, port): unit = self.unit_name ret, stdout, stderr = self.exec_hsnm('auiscsi', '-unit %s -refer' % unit) if ret: msg = basic_lib.output_err(600, cmd='auiscsi', ret=ret, out=stdout, err=stderr) raise exception.HBSDCmdError(message=msg, ret=ret, err=stderr) lines = stdout.splitlines() is_target_port = False for line in lines: line_array = shlex.split(line) if not line_array: continue if line_array[0] == 'Port' and line_array[1] != 'Number': if line_array[1] == port: is_target_port = True else: is_target_port = False continue if is_target_port and re.search('IPv4 Address', line): ip_addr = shlex.split(line)[3] break if is_target_port and re.search('Port Number', line): ip_port = shlex.split(line)[3] else: msg = basic_lib.output_err(651) raise exception.HBSDError(message=msg) return ip_addr, ip_port
def create_snapshot(self, snapshot): src_ref = self.get_volume(snapshot['volume_id']) pvol = self.get_ldev(src_ref) if pvol is None: msg = basic_lib.output_err(624, type='volume', id=src_ref['id']) raise exception.HBSDError(message=msg) self.add_volinfo(pvol, src_ref['id']) with self.volume_info[pvol]['in_use']: is_vvol = self.get_volume_is_vvol(src_ref) self.check_volume_status(src_ref, is_vvol) size = snapshot['volume_size'] snap_metadata = self.get_snapshot_metadata(snapshot['id']) method = None if is_vvol else self.get_copy_method(src_ref) svol, type = self.copy_data(pvol, size, is_vvol, method) if type == 'V-VOL': snap_metadata['type'] = type snap_metadata['ldev'] = svol snapshot_metadata = api._metadata_refs(snap_metadata, models.SnapshotMetadata) return {'provider_location': svol, 'snapshot_metadata': snapshot_metadata}
def get_unused_ldev(self, ldev_range): start = ldev_range[0] end = ldev_range[1] unit = self.unit_name ret, stdout, stderr = self.exec_hsnm('auluref', '-unit %s' % unit) if ret: msg = basic_lib.output_err( 600, cmd='auluref', ret=ret, out=stdout, err=stderr) raise exception.HBSDCmdError(message=msg, ret=ret, err=stderr) free_ldev = start lines = stdout.splitlines() found = False for line in lines[2:]: line = shlex.split(line) if not line: continue ldev_num = int(line[0]) if free_ldev > ldev_num: continue if free_ldev == ldev_num: free_ldev += 1 else: found = True break if free_ldev > end: break else: found = True if not found: msg = basic_lib.output_err(648, resource='LDEV') raise exception.HBSDError(message=msg) return free_ldev
def add_hostgroup_master(self, hgs, master_wwns, host_ip, security_ports): target_ports = self.configuration.hitachi_target_ports group_request = self.configuration.hitachi_group_request wwns = [] for wwn in master_wwns: wwns.append(wwn.lower()) if target_ports and group_request: host_grp_name = '%s%s' % (basic_lib.NAME_PREFIX, host_ip) for port in security_ports: wwns_copy = wwns[:] for hostgroup in hgs: if (hostgroup['port'] == port and hostgroup['initiator_wwn'].lower() in wwns_copy): wwns_copy.remove(hostgroup['initiator_wwn'].lower()) if wwns_copy: try: self._fill_group(hgs, port, host_grp_name, wwns_copy) except Exception as ex: LOG.warning( _('Failed to add host group: %s') % six.text_type(ex)) msg = basic_lib.set_msg(308, port=port, name=host_grp_name) LOG.warning(msg) if not hgs: msg = basic_lib.output_err(649) raise exception.HBSDError(message=msg)
def check_volume_status(self, volume, is_vvol): if not is_vvol: status = VALID_DP_VOLUME_STATUS else: status = VALID_V_VOLUME_STATUS if volume['status'] not in status: msg = basic_lib.output_err(654, status=volume['status']) raise exception.HBSDError(message=msg)
def extend_volume(self, volume, new_size): pvol = self.get_ldev(volume) self.add_volinfo(pvol, volume['id']) with self.volume_info[pvol]['in_use']: if self.get_volume_is_vvol(volume): msg = basic_lib.output_err(618, volume_id=volume['id']) raise exception.HBSDError(message=msg) self._extend_volume(pvol, volume['size'], new_size)
def create_empty_file(filename): if not os.path.exists(filename): try: utils.execute('touch', filename) except putils.ProcessExecutionError as ex: msg = output_err( 631, file=filename, ret=ex.exit_code, err=ex.stderr) raise exception.HBSDError(message=msg)
def _wait_for_pair_status(self, pvol, svol, is_vvol, status, timeout, start): if self._comm_pairevtwait(pvol, svol, is_vvol) in status: raise loopingcall.LoopingCallDone() if time.time() - start >= timeout: msg = basic_lib.output_err( 637, method='_wait_for_pair_status', timeout=timeout) raise exception.HBSDError(message=msg)
def _execute_with_exception(self, cmd, args, **kwargs): ret, stdout, stderr = self.exec_hsnm(cmd, args, **kwargs) if ret: cmds = '%(cmd)s %(args)s' % {'cmd': cmd, 'args': args} msg = basic_lib.output_err( 600, cmd=cmds, ret=ret, out=stdout, err=stderr) raise exception.HBSDError(data=msg) return ret, stdout, stderr
def check_param(self): try: self.common.check_param() self._check_param() except exception.HBSDError: raise except Exception as ex: raise exception.HBSDError( message=basic_lib.output_err(601, param=six.text_type(ex)))
def copy_volume_to_image(self, context, volume, image_service, image_meta): self.do_setup_status.wait() if volume['volume_attachment']: desc = 'volume %s' % volume['id'] raise exception.HBSDError( message=basic_lib.output_err(660, desc=desc)) super(HBSDISCSIDriver, self).copy_volume_to_image(context, volume, image_service, image_meta)
def copy_volume_to_image(self, context, volume, image_service, image_meta): self.do_setup_status.wait() if (volume['instance_uuid'] or volume['attached_host']): desc = 'volume %s' % volume['id'] msg = basic_lib.output_err(660, desc=desc) raise exception.HBSDError(message=msg) super(HBSDFCDriver, self).copy_volume_to_image(context, volume, image_service, image_meta)
def set_chap_authention(self, port, gid): ctl_no = port[0] port_no = port[1] unit = self.unit_name auth_username = self.conf.hitachi_auth_user auth_password = self.conf.hitachi_auth_password add_chap_user = self.conf.hitachi_add_chap_user assign_flag = True added_flag = False opt = '-unit %s -refer %s %s -user %s' % (unit, ctl_no, port_no, auth_username) ret, stdout, stderr = self.exec_hsnm('auchapuser', opt, noretry=True) if ret: if not add_chap_user: msg = basic_lib.output_err(643, user=auth_username) raise exception.HBSDError(message=msg) root_helper = utils.get_root_helper() cmd = ('%s env %s auchapuser -unit %s -add %s %s ' '-tno %d -user %s' % (root_helper, SNM2_ENV, unit, ctl_no, port_no, gid, auth_username)) LOG.debug('Add CHAP user') loop = loopingcall.FixedIntervalLoopingCall( self._wait_for_add_chap_user, cmd, auth_username, auth_password, time.time()) added_flag = loop.start(interval=EXEC_INTERVAL).wait() else: lines = stdout.splitlines()[4:] for line in lines: if int(shlex.split(line)[0][0:3]) == gid: assign_flag = False break if assign_flag: opt = '-unit %s -assign %s %s -tno %d -user %s' % ( unit, ctl_no, port_no, gid, auth_username) ret, stdout, stderr = self.exec_hsnm('auchapuser', opt) if ret: if added_flag: _ret, _stdout, _stderr = self.delete_chap_user(port) if _ret: msg = basic_lib.set_msg(303, user=auth_username) LOG.warning(msg) msg = basic_lib.output_err(600, cmd='auchapuser', ret=ret, out=stdout, err=stderr) raise exception.HBSDCmdError(message=msg, ret=ret, err=stderr) return added_flag
def _check_param(self): self.configuration.append_config_values(volume_opts) if (self.configuration.hitachi_auth_method and self.configuration.hitachi_auth_method not in CHAP_METHOD): raise exception.HBSDError( message=basic_lib.output_err(601, param='hitachi_auth_method')) if self.configuration.hitachi_auth_method == 'None': self.configuration.hitachi_auth_method = None for opt in volume_opts: getattr(self.configuration, opt.name)
def terminate_connection(self, volume, connector, **kwargs): self.do_setup_status.wait() ldev = self.common.get_ldev(volume) if ldev is None: LOG.warning(basic_lib.set_msg(302, volume_id=volume['id'])) return if 'initiator' not in connector: raise exception.HBSDError( message=basic_lib.output_err(650, resource='HBA')) hostgroups = [] self._get_hostgroup_info_iscsi(hostgroups, connector['initiator']) if not hostgroups: raise exception.HBSDError(message=basic_lib.output_err(649)) self.common.add_volinfo(ldev, volume['id']) with self.common.volume_info[ldev]['lock'],\ self.common.volume_info[ldev]['in_use']: self._terminate_connection(ldev, connector, hostgroups)
def add_hostgroup(self): properties = utils.brick_get_connector_properties() if 'initiator' not in properties: raise exception.HBSDError( message=basic_lib.output_err(650, resource='HBA')) LOG.debug("initiator: %s", properties['initiator']) hostgroups = [] security_ports = self._get_hostgroup_info_iscsi( hostgroups, properties['initiator']) self.add_hostgroup_master(hostgroups, properties['initiator'], properties['ip'], security_ports)
def add_hostgroup(self): properties = utils.brick_get_connector_properties() if 'wwpns' not in properties: msg = basic_lib.output_err(650, resource='HBA') raise exception.HBSDError(message=msg) LOG.debug("wwpns: %s" % properties['wwpns']) hostgroups = [] security_ports = self._get_hostgroup_info( hostgroups, properties['wwpns'], login=False) self.add_hostgroup_master(hostgroups, properties['wwpns'], properties['ip'], security_ports) self.add_hostgroup_pair(self.pair_hostgroups)
def get_unused_gid(self, group_range, port): start = group_range[0] end = group_range[1] unit = self.unit_name ret, stdout, stderr = self.exec_hsnm('auhgdef', '-unit %s -refer' % unit) if ret: msg = basic_lib.output_err(600, cmd='auhgdef', ret=ret, out=stdout, err=stderr) raise exception.HBSDCmdError(message=msg, ret=ret, err=stderr) lines = stdout.splitlines() is_target_port = False free_gid = start found = False for line in lines: line = shlex.split(line) if not line: continue if line[0] == 'Port' and line[1] == port: is_target_port = True continue if is_target_port: if line[0] == 'Port': found = True break if not line[0].isdigit(): continue gid = int(line[0]) if free_gid > gid: continue if free_gid == gid: free_gid += 1 else: found = True break if free_gid > end or free_gid > MAX_HOSTGROUPS: break else: found = True if not found: msg = basic_lib.output_err(648, resource='GID') raise exception.HBSDError(message=msg) return free_gid
def __enter__(self): if not os.access(self.fname, os.W_OK): msg = output_err(633, file=self.fname) raise exception.HBSDError(message=msg) self.lock_object.acquire() try: ret = super(FileLock, self).__enter__() except Exception: with excutils.save_and_reraise_exception(): self.lock_object.release() return ret
def _manage_existing_get_size(self, volume, existing_ref): """Return size of volume for manage_existing.""" ldev = self._string2int(existing_ref.get('ldev')) if ldev is None: msg = basic_lib.output_err(701) raise exception.HBSDError(data=msg) size = self.command.get_ldev_size_in_gigabyte(ldev, existing_ref) metadata = {'type': basic_lib.NORMAL_VOLUME_TYPE, 'ldev': ldev} self._update_volume_metadata(volume['id'], metadata) return size
def initialize_connection(self, volume, connector): self.do_setup_status.wait() ldev = self.common.get_ldev(volume) if ldev is None: msg = basic_lib.output_err(619, volume_id=volume['id']) raise exception.HBSDError(message=msg) self.common.add_volinfo(ldev, volume['id']) with nested(self.common.volume_info[ldev]['lock'], self.common.volume_info[ldev]['in_use']): hostgroups = self._initialize_connection(ldev, connector) properties = self._get_properties(volume, hostgroups) LOG.debug('Initialize volume_info: %s' % self.common.volume_info) LOG.debug('HFCDrv: properties=%s' % properties) return {'driver_volume_type': 'fibre_channel', 'data': properties}
def _fill_group(self, hgs, port, host_grp_name, wwns): added_hostgroup = False LOG.debug( 'Create host group (hgs: %(hgs)s port: %(port)s ' 'name: %(name)s wwns: %(wwns)s)', { 'hgs': hgs, 'port': port, 'name': host_grp_name, 'wwns': wwns }) gid = self._get_hgname_gid(port, host_grp_name) if gid is None: for retry_cnt in basic_lib.DEFAULT_TRY_RANGE: try: gid = self._get_unused_gid(port) self._add_hostgroup(port, gid, host_grp_name) added_hostgroup = True except exception.HBSDNotFound: gid = None LOG.warning(basic_lib.set_msg(312, resource='GID')) continue else: LOG.debug( 'Completed to add host target' '(port: %(port)s gid: %(gid)d)', { 'port': port, 'gid': gid }) break else: msg = basic_lib.output_err(641) raise exception.HBSDError(message=msg) try: if wwns: self._add_wwn(hgs, port, gid, wwns) else: hgs.append({ 'port': port, 'gid': gid, 'initiator_wwn': None, 'detected': True }) except Exception: with excutils.save_and_reraise_exception(): if added_hostgroup: self._delete_hostgroup(port, gid, host_grp_name)
def check_param(self): conf = self.configuration if conf.hitachi_unit_name and conf.hitachi_serial_number: msg = basic_lib.output_err(604) raise exception.HBSDError(message=msg) if not conf.hitachi_unit_name and not conf.hitachi_serial_number: msg = basic_lib.output_err(605) raise exception.HBSDError(message=msg) if conf.hitachi_pool_id is None: msg = basic_lib.output_err(601, param='hitachi_pool_id') raise exception.HBSDError(message=msg) for param in PARAM_RANGE.keys(): _value = getattr(conf, param) if (_value and (not PARAM_RANGE[param]['min'] <= _value <= PARAM_RANGE[param]['max'])): msg = basic_lib.output_err(601, param=param) raise exception.HBSDError(message=msg) if conf.hitachi_default_copy_method not in COPY_METHOD: msg = basic_lib.output_err(601, param='hitachi_default_copy_method') raise exception.HBSDError(message=msg) if (conf.hitachi_default_copy_method == 'THIN' and conf.hitachi_thin_pool_id is None): msg = basic_lib.output_err(601, param='hitachi_thin_pool_id') raise exception.HBSDError(message=msg) for param in ('hitachi_ldev_range', 'hitachi_group_range'): if not getattr(conf, param): continue else: _value = self._range2list(conf, param) setattr(conf, param, _value) if conf.hitachi_target_ports: conf.hitachi_target_ports = conf.hitachi_target_ports.split(',') for opt in volume_opts: getattr(conf, opt.name) if conf.hitachi_unit_name: self.command = snm2.HBSDSNM2(conf) else: conf.append_config_values(horcm.volume_opts) self.command = horcm.HBSDHORCM(conf) self.command.check_param() self.pair_flock = self.command.set_pair_flock() self.horcmgr_flock = self.command.set_horcmgr_flock()
def get_unused_gid_iscsi(self, group_range, port): start = group_range[0] end = min(group_range[1], MAX_HOSTGROUPS_ISCSI) unit = self.unit_name ret, stdout, stderr = self.exec_hsnm('autargetdef', '-unit %s -refer' % unit) if ret: msg = basic_lib.output_err(600, cmd='autargetdef', ret=ret, out=stdout, err=stderr) raise exception.HBSDCmdError(message=msg, ret=ret, err=stderr) used_list = [] tmp_port = None lines = stdout.splitlines() for line in lines: line = shlex.split(line) if not line: continue if line[0] == "Port": tmp_port = line[1] continue if port != tmp_port: continue if line[0][0:3].isdigit(): gid = int(line[0][0:3]) if start <= gid <= end: used_list.append(gid) if not used_list: return start for gid in range(start, end + 1): if gid not in used_list: break else: msg = basic_lib.output_err(648, resource='GID') raise exception.HBSDError(message=msg) return gid