예제 #1
0
 def check_param(self):
     """Check parameter values and consistency among them."""
     utils.check_opt_value(self.conf, _INHERITED_VOLUME_OPTS)
     utils.check_opts(self.conf, common_opts)
     utils.check_opts(self.conf, self.driver_info['volume_opts'])
     if (self.conf.vsp_default_copy_method == 'THIN'
             and not self.conf.vsp_thin_pool):
         msg = utils.output_log(MSG.INVALID_PARAMETER,
                                param='vsp_thin_pool')
         raise exception.VSPError(msg)
     if self.conf.vsp_ldev_range:
         self.storage_info['ldev_range'] = self._range2list(
             'vsp_ldev_range')
     if (not self.conf.vsp_target_ports
             and not self.conf.vsp_compute_target_ports):
         msg = utils.output_log(MSG.INVALID_PARAMETER,
                                param='vsp_target_ports or '
                                'vsp_compute_target_ports')
         raise exception.VSPError(msg)
     for opt in _REQUIRED_COMMON_OPTS:
         if not self.conf.safe_get(opt):
             msg = utils.output_log(MSG.INVALID_PARAMETER, param=opt)
             raise exception.VSPError(msg)
     if self.storage_info['protocol'] == 'iSCSI':
         self.check_param_iscsi()
예제 #2
0
 def create_cloned_volume(self, volume, src_vref):
     """Create a clone of the specified volume and return its properties."""
     ldev = utils.get_ldev(src_vref)
     # When 'ldev' is 0, it should be true.
     # Therefore, it cannot remove 'is not None'.
     if ldev is None:
         msg = utils.output_log(MSG.INVALID_LDEV_FOR_VOLUME_COPY,
                                type='volume',
                                id=src_vref['id'])
         raise exception.VSPError(msg)
     size = volume['size']
     metadata = utils.get_volume_metadata(volume)
     if size < src_vref['size']:
         msg = utils.output_log(MSG.INVALID_VOLUME_SIZE_FOR_COPY,
                                type='volume',
                                volume_id=volume['id'])
         raise exception.VSPError(msg)
     elif (size > src_vref['size'] and not self.check_vvol(ldev)
           and self.get_copy_method(metadata) == "THIN"):
         msg = utils.output_log(MSG.INVALID_VOLUME_SIZE_FOR_TI,
                                copy_method=utils.THIN,
                                type='volume',
                                volume_id=volume['id'])
         raise exception.VSPError(msg)
     sync = size > src_vref['size']
     new_ldev = self._copy_ldev(ldev, src_vref['size'], metadata, sync)
     if sync:
         self.delete_pair(new_ldev)
         self.extend_ldev(new_ldev, src_vref['size'], size)
     return {
         'provider_location': six.text_type(new_ldev),
     }
예제 #3
0
 def check_param_iscsi(self):
     """Check iSCSI-related parameter values and consistency among them."""
     if self.conf.vsp_use_chap_auth:
         if not self.conf.vsp_auth_user:
             msg = utils.output_log(MSG.INVALID_PARAMETER,
                                    param='vsp_auth_user')
             raise exception.VSPError(msg)
         if not self.conf.vsp_auth_password:
             msg = utils.output_log(MSG.INVALID_PARAMETER,
                                    param='vsp_auth_password')
             raise exception.VSPError(msg)
예제 #4
0
 def get_copy_method(self, metadata):
     """Return copy method(FULL or THIN)."""
     method = metadata.get('copy_method', self.conf.vsp_default_copy_method)
     if method not in _COPY_METHOD:
         msg = utils.output_log(MSG.INVALID_PARAMETER_VALUE,
                                meta='copy_method')
         raise exception.VSPError(msg)
     if method == 'THIN' and not self.conf.vsp_thin_pool:
         msg = utils.output_log(MSG.INVALID_PARAMETER,
                                param='vsp_thin_pool')
         raise exception.VSPError(msg)
     return method
예제 #5
0
 def extend_volume(self, volume, new_size):
     """Extend the specified volume to the specified size."""
     ldev = utils.get_ldev(volume)
     # When 'ldev' is 0, it should be true.
     # Therefore, it cannot remove 'is None'.
     if ldev is None:
         msg = utils.output_log(MSG.INVALID_LDEV_FOR_EXTENSION,
                                volume_id=volume['id'])
         raise exception.VSPError(msg)
     if self.check_vvol(ldev):
         msg = utils.output_log(MSG.INVALID_VOLUME_TYPE_FOR_EXTEND,
                                volume_id=volume['id'])
         raise exception.VSPError(msg)
     self.delete_pair(ldev)
     self.extend_ldev(ldev, volume['size'], new_size)
예제 #6
0
    def get_properties_iscsi(self, targets, multipath):
        """Check if specified iSCSI targets exist and store their IQNs."""
        if not multipath:
            target_list = targets['list'][:1]
        else:
            target_list = targets['list'][:]

        for target in target_list:
            if target not in targets['iqns']:
                port, gid = target
                result = self.run_raidcom('get', 'host_grp', '-port', port)
                match = re.search(
                    r"^CL\w-\w+ +%s +\S+ +(?P<iqn>\S+) +\w+ +\w +\d+ " % gid,
                    result[1], re.M)
                if not match:
                    msg = utils.output_log(MSG.RESOURCE_NOT_FOUND,
                                           resource='Target IQN')
                    raise exception.VSPError(msg)
                targets['iqns'][target] = match.group('iqn')
                LOG.debug(
                    'Found iqn of the iSCSI target. (port: %(port)s, '
                    'gid: %(gid)s, target iqn: %(iqn)s)', {
                        'port': port,
                        'gid': gid,
                        'iqn': match.group('iqn')
                    })
        return super(VSPHORCMISCSI,
                     self).get_properties_iscsi(targets, multipath)
예제 #7
0
    def initialize_connection(self, volume, connector):
        """Initialize connection between the server and the volume."""
        targets = {
            'info': {},
            'list': [],
            'lun': {},
            'iqns': {},
        }
        ldev = utils.get_ldev(volume)
        # When 'ldev' is 0, it should be true.
        # Therefore, it cannot remove 'is None'.
        if ldev is None:
            msg = utils.output_log(MSG.INVALID_LDEV_FOR_CONNECTION,
                                   volume_id=volume['id'])
            raise exception.VSPError(msg)

        if (self.find_targets_from_storage(targets, connector,
                                           self.storage_info['ports'])
                and self.conf.vsp_group_request):
            self.create_mapping_targets(targets, connector)

        utils.require_target_existed(targets)

        targets['list'].sort()
        for port in self.storage_info['ports']:
            targets['lun'][port] = False
        target_lun = int(self.map_ldev(targets, ldev))

        return {
            'driver_volume_type': self.driver_info['volume_type'],
            'data': self.get_properties(targets, connector, target_lun),
        }
예제 #8
0
 def get_hba_ids_from_connector(self, connector):
     """Return the HBA ID stored in the connector."""
     if self.driver_info['hba_id'] in connector:
         return connector[self.driver_info['hba_id']]
     msg = utils.output_log(MSG.RESOURCE_NOT_FOUND,
                            resource=self.driver_info['hba_id_type'])
     raise exception.VSPError(msg)
예제 #9
0
    def connect_storage(self):
        """Prepare for using the storage."""
        target_ports = self.conf.vsp_target_ports
        compute_target_ports = self.conf.vsp_compute_target_ports
        pair_target_ports = self.conf.vsp_horcm_pair_target_ports

        super(VSPHORCMISCSI, self).connect_storage()
        result = self.run_raidcom('get', 'port')
        for port in _ISCSI_PORT_PATTERN.findall(result[1]):
            if (target_ports and port in target_ports
                    and self._set_target_portal(port)):
                self.storage_info['controller_ports'].append(port)
            if (compute_target_ports and port in compute_target_ports
                    and (port in self.storage_info['portals']
                         or self._set_target_portal(port))):
                self.storage_info['compute_ports'].append(port)
            if pair_target_ports and port in pair_target_ports:
                self.storage_info['pair_ports'].append(port)

        self.check_ports_info()
        if pair_target_ports and not self.storage_info['pair_ports']:
            msg = utils.output_log(MSG.RESOURCE_NOT_FOUND,
                                   resource="Pair target ports")
            raise exception.VSPError(msg)
        utils.output_log(MSG.SET_CONFIG_VALUE,
                         object='pair target port list',
                         value=self.storage_info['pair_ports'])
        utils.output_log(MSG.SET_CONFIG_VALUE,
                         object='port-<IP address:port> list',
                         value=self.storage_info['portals'])
예제 #10
0
 def check_ports_info(self):
     """Check if available storage ports exist."""
     if (self.conf.vsp_target_ports and
             not self.storage_info['controller_ports']):
         msg = utils.output_log(MSG.RESOURCE_NOT_FOUND,
                                resource="Target ports")
         raise exception.VSPError(msg)
     if (self.conf.vsp_compute_target_ports and
             not self.storage_info['compute_ports']):
         msg = utils.output_log(MSG.RESOURCE_NOT_FOUND,
                                resource="Compute target ports")
         raise exception.VSPError(msg)
     utils.output_log(MSG.SET_CONFIG_VALUE, object='target port list',
                      value=self.storage_info['controller_ports'])
     utils.output_log(MSG.SET_CONFIG_VALUE,
                      object='compute target port list',
                      value=self.storage_info['compute_ports'])
예제 #11
0
 def _range2list(self, param):
     """Analyze a 'xxx-xxx' string and return a list of two integers."""
     values = [
         _str2int(value) for value in self.conf.safe_get(param).split('-')
     ]
     if (len(values) != 2 or values[0] is None or values[1] is None
             or values[0] > values[1]):
         msg = utils.output_log(MSG.INVALID_PARAMETER, param=param)
         raise exception.VSPError(msg)
     return values
예제 #12
0
 def connect_storage(self):
     """Prepare for using the storage."""
     self.storage_info['pool_id'] = self.get_pool_id()
     # When 'pool_id' is 0, it should be true.
     # Therefore, it cannot remove 'is None'.
     if self.storage_info['pool_id'] is None:
         msg = utils.output_log(MSG.POOL_NOT_FOUND, pool=self.conf.vsp_pool)
         raise exception.VSPError(msg)
     utils.output_log(MSG.SET_CONFIG_VALUE, object='DP Pool ID',
                      value=self.storage_info['pool_id'])
예제 #13
0
 def run_and_verify_storage_cli(self, *cmd, **kwargs):
     """Run storage CLI and return the result or raise an exception."""
     do_raise = kwargs.pop('do_raise', True)
     ignore_error = kwargs.get('ignore_error')
     success_code = kwargs.get('success_code', set([0]))
     (ret, stdout, stderr) = self.run_storage_cli(*cmd, **kwargs)
     if (ret not in success_code and
             not utils.check_ignore_error(ignore_error, stderr)):
         msg = utils.output_log(
             MSG.STORAGE_COMMAND_FAILED, cmd=utils.mask_password(cmd),
             ret=ret, out=' '.join(stdout.splitlines()),
             err=' '.join(stderr.splitlines()))
         if do_raise:
             raise exception.VSPError(msg)
     return ret, stdout, stderr
예제 #14
0
 def create_snapshot(self, snapshot):
     """Create a snapshot from a volume and return its properties."""
     src_vref = snapshot.volume
     ldev = utils.get_ldev(src_vref)
     # When 'ldev' is 0, it should be true.
     # Therefore, it cannot remove 'is None'.
     if ldev is None:
         msg = utils.output_log(MSG.INVALID_LDEV_FOR_VOLUME_COPY,
                                type='volume', id=src_vref['id'])
         raise exception.VSPError(msg)
     size = snapshot['volume_size']
     metadata = utils.get_volume_metadata(src_vref)
     new_ldev = self._copy_ldev(ldev, size, metadata)
     return {
         'provider_location': six.text_type(new_ldev),
     }
예제 #15
0
 def set_hba_ids(self, port, gid, hba_ids):
     """Connect all specified HBAs with the specified port."""
     registered_wwns = []
     for wwn in hba_ids:
         try:
             self.run_raidcom('add', 'hba_wwn', '-port',
                              '-'.join([port, gid]), '-hba_wwn', wwn)
             registered_wwns.append(wwn)
         except exception.VSPError:
             utils.output_log(MSG.ADD_HBA_WWN_FAILED,
                              port=port,
                              gid=gid,
                              wwn=wwn)
     if not registered_wwns:
         msg = utils.output_log(MSG.NO_HBA_WWN_ADDED_TO_HOST_GRP,
                                port=port,
                                gid=gid)
         raise exception.VSPError(msg)
예제 #16
0
def require_target_existed(targets):
    """Check if the target list includes one or more members."""
    if not targets['list']:
        msg = output_log(MSG.NO_CONNECTED_TARGET)
        raise exception.VSPError(msg)