Exemplo n.º 1
0
    def _weigh_object(self, host_state, weight_properties):
        """Higher weighers win.  We want spreading to be the default."""
        reserved = float(host_state.reserved_percentage) / 100
        free_space = host_state.free_capacity_gb
        total_space = host_state.total_capacity_gb
        if 'unknown' in (total_space, free_space):
            # NOTE(u_glide): "unknown" capacity always sorts to the bottom
            if CONF.capacity_weight_multiplier > 0:
                free = float('-inf')
            else:
                free = float('inf')
        else:
            total = float(total_space)

            share_type = weight_properties.get('share_type', {})
            use_thin_logic = utils.use_thin_logic(share_type)
            thin_provisioning = utils.thin_provisioning(
                host_state.thin_provisioning)

            if use_thin_logic and thin_provisioning:
                # NOTE(xyang): Calculate virtual free capacity for thin
                # provisioning.
                free = math.floor(total *
                                  host_state.max_over_subscription_ratio -
                                  host_state.provisioned_capacity_gb -
                                  total * reserved)
            else:
                # NOTE(xyang): Calculate how much free space is left after
                # taking into account the reserved space.
                free = math.floor(free_space - total * reserved)
        return free
Exemplo n.º 2
0
    def _weigh_object(self, host_state, weight_properties):
        """Higher weighers win.  We want spreading to be the default."""
        reserved = float(host_state.reserved_percentage) / 100
        free_space = host_state.free_capacity_gb
        total_space = host_state.total_capacity_gb
        if 'unknown' in (total_space, free_space):
            # NOTE(u_glide): "unknown" capacity always sorts to the bottom
            if CONF.capacity_weight_multiplier > 0:
                free = float('-inf')
            else:
                free = float('inf')
        else:
            total = float(total_space)

            share_type = weight_properties.get('share_type', {})
            use_thin_logic = utils.use_thin_logic(share_type)
            thin_provisioning = utils.thin_provisioning(
                host_state.thin_provisioning)

            if use_thin_logic and thin_provisioning:
                # NOTE(xyang): Calculate virtual free capacity for thin
                # provisioning.
                free = math.floor(
                    total * host_state.max_over_subscription_ratio -
                    host_state.provisioned_capacity_gb -
                    total * reserved)
            else:
                # NOTE(xyang): Calculate how much free space is left after
                # taking into account the reserved space.
                free = math.floor(free_space - total * reserved)
        return free
Exemplo n.º 3
0
 def test_use_thin_logic(self, properties, use_thin):
     use_thin_logic = utils.use_thin_logic(properties)
     self.assertEqual(use_thin, use_thin_logic)
Exemplo n.º 4
0
 def test_use_thin_logic(self, properties, use_thin):
     use_thin_logic = utils.use_thin_logic(properties)
     self.assertEqual(use_thin, use_thin_logic)
Exemplo n.º 5
0
    def host_passes(self, host_state, filter_properties):
        """Return True if host has sufficient capacity."""
        share_size = filter_properties.get('size', 0)

        if host_state.free_capacity_gb is None:
            # Fail Safe
            LOG.error("Free capacity not set: "
                      "share node info collection broken.")
            return False

        free_space = host_state.free_capacity_gb
        total_space = host_state.total_capacity_gb
        reserved = float(host_state.reserved_percentage) / 100
        if free_space == 'unknown':
            # NOTE(zhiteng) for those back-ends cannot report actual
            # available capacity, we assume it is able to serve the
            # request.  Even if it was not, the retry mechanism is
            # able to handle the failure by rescheduling
            return True
        elif total_space == 'unknown':
            # NOTE(xyang): If total_space is 'unknown' and
            # reserved is 0, we assume the back-ends can serve the request.
            # If total_space is 'unknown' and reserved
            # is not 0, we cannot calculate the reserved space.
            # float(total_space) will throw an exception. total*reserved
            # also won't work. So the back-ends cannot serve the request.
            return reserved == 0 and share_size <= free_space
        total = float(total_space)
        if total <= 0:
            LOG.warning("Insufficient free space for share creation. "
                        "Total capacity is %(total).2f on host %(host)s.",
                        {"total": total,
                         "host": host_state.host})
            return False
        # NOTE(xyang): Calculate how much free space is left after taking
        # into account the reserved space.
        free = math.floor(free_space - total * reserved)

        msg_args = {"host": host_state.host,
                    "requested": share_size,
                    "available": free}

        LOG.debug("Space information for share creation "
                  "on host %(host)s (requested / avail): "
                  "%(requested)s/%(available)s", msg_args)

        share_type = filter_properties.get('share_type', {})
        use_thin_logic = utils.use_thin_logic(share_type)
        thin_provisioning = utils.thin_provisioning(
            host_state.thin_provisioning)

        # NOTE(xyang): Only evaluate using max_over_subscription_ratio
        # if use_thin_logic and thin_provisioning are True. Check if the
        # ratio of provisioned capacity over total capacity would exceed
        # subscription ratio.
        # If max_over_subscription_ratio = 1, the provisioned_ratio
        # should still be limited by the max_over_subscription_ratio;
        # otherwise, it could result in infinite provisioning.
        if (use_thin_logic and thin_provisioning and
                host_state.max_over_subscription_ratio >= 1):
            provisioned_ratio = ((host_state.provisioned_capacity_gb +
                                  share_size) / total)
            if provisioned_ratio > host_state.max_over_subscription_ratio:
                LOG.warning(
                    "Insufficient free space for thin provisioning. "
                    "The ratio of provisioned capacity over total capacity "
                    "%(provisioned_ratio).2f would exceed the maximum over "
                    "subscription ratio %(oversub_ratio).2f on host "
                    "%(host)s.",
                    {"provisioned_ratio": provisioned_ratio,
                     "oversub_ratio": host_state.max_over_subscription_ratio,
                     "host": host_state.host})
                return False
            else:
                # NOTE(xyang): Adjust free_virtual calculation based on
                # free and max_over_subscription_ratio.
                adjusted_free_virtual = (
                    free * host_state.max_over_subscription_ratio)
                return adjusted_free_virtual >= share_size
        elif (use_thin_logic and thin_provisioning and
              host_state.max_over_subscription_ratio < 1):
            LOG.error("Invalid max_over_subscription_ratio: %(ratio)s. "
                      "Valid value should be >= 1.",
                      {"ratio": host_state.max_over_subscription_ratio})
            return False

        if free < share_size:
            LOG.warning("Insufficient free space for share creation "
                        "on host %(host)s (requested / avail): "
                        "%(requested)s/%(available)s", msg_args)
            return False

        return True