def _get_next_available_lun(self, host_name):
        logger.debug(
            "getting host mapping list for host :{0}".format(host_name))
        try:
            host_mapping_list = self.client.cmd.mapping_list(
                host=host_name).as_list
        except xcli_errors.HostBadNameError as ex:
            logger.exception(ex)
            raise controller_errors.HostNotFoundError(host_name)

        luns_in_use = set(
            [int(host_mapping.lun) for host_mapping in host_mapping_list])
        logger.debug("luns in use : {0}".format(luns_in_use))

        # try to use random lun number just in case there are many calls at the same time to reduce re-tries
        all_available_luns = [
            i for i in range(self.MIN_LUN_NUMBER, self.MAX_LUN_NUMBER + 1)
            if i not in luns_in_use
        ]

        if len(all_available_luns) == 0:
            raise controller_errors.NoAvailableLunError(host_name)

        index = randint(0, len(all_available_luns) - 1)
        lun = all_available_luns[index]
        logger.debug("next random available lun is : {0}".format(lun))
        return lun
 def map_volume(self, volume_id, host_name, connectivity_type):
     logger.debug("Mapping volume {} to host {}".format(volume_id, host_name))
     try:
         mapping = self.client.map_volume_to_host(host_name, volume_id)
         lun = scsilun_to_int(mapping.lunid)
         logger.debug("Successfully mapped volume to host with lun {}".format(lun))
         return lun
     except exceptions.NotFound:
         raise array_errors.HostNotFoundError(host_name)
     except exceptions.ClientException as ex:
         if ERROR_CODE_MAP_VOLUME_NOT_ENOUGH_EXTENTS in str(ex.message).upper():
             raise array_errors.NoAvailableLunError(volume_id)
         if ERROR_CODE_VOLUME_NOT_FOUND_FOR_MAPPING in str(ex.message).upper():
             raise array_errors.ObjectNotFoundError(volume_id)
         raise array_errors.MappingError(volume_id, host_name, ex.details)
Esempio n. 3
0
 def get_first_free_lun(self, host_name):
     logger.debug("getting first free lun id for "
                  "host :{0}".format(host_name))
     lun = None
     luns_in_use = self._get_used_lun_ids_from_host(host_name)
     # Today we have SS_MAX_HLUN_MAPPINGS_PER_HOST as 2048 on high end
     # platforms (SVC / V7000 etc.) and 512 for the lower
     # end platforms (V3500 etc.). This limits the number of volumes that
     # can be mapped to a single host. (Note that some hosts such as linux
     # do not support more than 255 or 511 mappings today irrespective of
     # our constraint).
     for candidate in range(self.MIN_LUN_NUMBER, self.MAX_LUN_NUMBER + 1):
         if str(candidate) not in luns_in_use:
             logger.debug("First available LUN number for {0} is "
                          "{1}".format(host_name, str(candidate)))
             lun = str(candidate)
             break
     if not lun:
         raise array_errors.NoAvailableLunError(host_name)
     logger.debug("The first available lun is : {0}".format(lun))
     return lun