Esempio n. 1
0
 def test_init_recreate_map_fails(self, mock_ftsk, mock_rebuild_slot):
     vios1, vios2 = mock.Mock(uuid='uuid1'), mock.Mock(uuid='uuid2')
     mock_ftsk.return_value.feed = [vios1, vios2]
     mock_rebuild_slot.side_effect = (
         pvm_exc.InvalidHostForRebuildNotEnoughVIOS(udid='udid56'))
     self.assertRaises(p_exc.InvalidRebuild,
                       self.slot_mgr.init_recreate_map, mock.Mock(),
                       self._vol_drv_iter())
Esempio n. 2
0
    def _vscsi_build_out(self, vol_to_vio):
        """Builds the '_build_map' for physical volumes and logical units."""
        slots_order = self._vscsi_build_slot_order()

        # We're going to use the vol_to_vio dictionary for consistency and
        # remove elements from it. We need to deepcopy so that the original
        # remains the same.
        vol_to_vio_cp = copy.deepcopy(vol_to_vio)

        for slot in slots_order:
            slot_topo = self._slot_store.topology[slot]
            if not any(
                    slot_topo.get(x)
                    for x in (IOCLASS.PV, IOCLASS.LU, IOCLASS.VDISK)):
                continue
            # Initialize the set of candidate VIOSes to all available VIOSes.
            # We'll filter out and remove any VIOSes that can't host any PV or
            # LU for this slot.
            candidate_vioses = set(vio.uuid for vio in self.vios_wraps)

            slot_info = [
                (udid, lua, IOCLASS.PV)
                for udid, lua in six.iteritems(slot_topo.get(IOCLASS.PV, {}))
            ]
            slot_info.extend([
                (udid, lua, IOCLASS.LU)
                for udid, lua in six.iteritems(slot_topo.get(IOCLASS.LU, {}))
            ])
            slot_info.extend([(udid, lua, IOCLASS.VDISK)
                              for udid, lua in six.iteritems(
                                  slot_topo.get(IOCLASS.VDISK, {}))])
            for udid, lua, stg_class in slot_info:

                # If the UDID isn't anywhere to be found on the destination
                # VIOSes then we have a problem.
                if udid not in vol_to_vio_cp:
                    raise pvm_ex.InvalidHostForRebuildNoVIOSForUDID(udid=udid)

                # Inner Join. The goal is to end up with a set that only has
                # VIOSes which can see every backing storage elem for this
                # slot.
                candidate_vioses &= set(vol_to_vio_cp[udid])

                # If the set of candidate VIOSes is empty then this host is
                # not a candidate for rebuild.
                if not candidate_vioses:
                    raise pvm_ex.InvalidHostForRebuildNotEnoughVIOS(udid=udid)

            # Just take one, doesn't matter which one.
            # TODO(IBM): Perhaps find a way to ensure better distribution.
            vios_uuid_for_slot = candidate_vioses.pop()

            for udid, lua, stg_class in slot_info:

                self._put_vios_val(stg_class, vios_uuid_for_slot, udid,
                                   (slot, lua))

                # There's somewhat of a problem with this. We want to remove
                # the VIOS UUID we're picking from this list so that other
                # VIOSes will pick up the other mappings for this storage, but
                # it may be the case that the original storage actually
                # belonged to more than one mapping on a single VIOS. It's not
                # clear if this is allowed, and if it is the backing storage
                # can potentially be corrupted.
                #
                # If there were multiple mappings for the same vSCSI storage
                # element on the same VIOS then the slot store could not
                # identify it. We may hit an invalid host for rebuild exception
                # if this happens or we may not. It depends on the differences
                # between source and destination VIOSes.
                vol_to_vio_cp[udid].remove(vios_uuid_for_slot)