def detach_disk(self, instance):
        """Detaches the storage adapters from the image disk.

        :param instance: Instance to disconnect the image for.
        :return: A list of all the backing storage elements that were
                 disconnected from the I/O Server and VM.
        """
        lpar_uuid = vm.get_pvm_uuid(instance)

        # Build the match function
        match_func = tsk_map.gen_match_func(pvm_stg.VDisk)

        vios_w = pvm_vios.VIOS.get(self._adapter,
                                   uuid=self._vios_uuid,
                                   xag=[pvm_const.XAG.VIO_SMAP])

        # Remove the mappings.
        mappings = tsk_map.remove_maps(vios_w,
                                       lpar_uuid,
                                       match_func=match_func)

        # Update the VIOS with the removed mappings.
        vios_w.update()

        return [x.backing_storage for x in mappings]
Example #2
0
    def dlt_vopt(self, instance, stg_ftsk):
        """Deletes the virtual optical and scsi mappings for a VM.

        :param instance: The nova instance whose VOpt(s) are to be removed.
        :param stg_ftsk: A FeedTask. The actions to modify the storage will be
                         added as batched functions onto the FeedTask.
        """
        lpar_uuid = vm.get_pvm_uuid(instance)

        # The matching function for find_maps, remove_maps
        match_func = tsk_map.gen_match_func(pvm_stg.VOptMedia)

        # Add a function to remove the mappings
        stg_ftsk.wrapper_tasks[self.vios_uuid].add_functor_subtask(
            tsk_map.remove_maps, lpar_uuid, match_func=match_func)

        # Find the VOpt device based from the mappings
        media_mappings = tsk_map.find_maps(stg_ftsk.get_wrapper(
            self.vios_uuid).scsi_mappings,
                                           client_lpar_id=lpar_uuid,
                                           match_func=match_func)
        media_elems = [x.backing_storage for x in media_mappings]

        def rm_vopt():
            LOG.info("Removing virtual optical storage.", instance=instance)
            vg_wrap = pvm_stg.VG.get(self.adapter,
                                     uuid=self.vg_uuid,
                                     parent_type=pvm_vios.VIOS,
                                     parent_uuid=self.vios_uuid)
            tsk_stg.rm_vg_storage(vg_wrap, vopts=media_elems)

        # Add task to remove the media if it exists
        if media_elems:
            stg_ftsk.add_post_execute(task.FunctorTask(rm_vopt))
Example #3
0
    def _check_host_mappings(self, vios_wrap, device_name):
        """Checks if the given hdisk has multiple mappings

        :param vio_wrap: The Virtual I/O Server wrapper to remove the disk
                         from.
        :param device_name: The hdisk name to remove.

        :return: True is there are multiple instances using the given hdisk
        """
        vios_scsi_mappings = next(v.scsi_mappings for v in self.stg_ftsk.feed
                                  if v.uuid == vios_wrap.uuid)
        mappings = tsk_map.find_maps(
            vios_scsi_mappings, None,
            tsk_map.gen_match_func(pvm_stor.PV, names=[device_name]))

        LOG.info("%(num)d storage mappings found for %(dev)s on VIOS %(vios)s",
                 {
                     'num': len(mappings),
                     'dev': device_name,
                     'vios': vios_wrap.name
                 },
                 instance=self.instance)
        # the mapping is still present as the task feed removes
        # the mapping later
        return len(mappings) > 1
Example #4
0
    def _disconnect_volume(self, slot_mgr):
        # Build the match function
        match_func = tsk_map.gen_match_func(pvm_stg.VDisk,
                                            names=[self._get_path()])

        # Make sure the remove function will run within the transaction manager
        def rm_func(vios_w):
            # If the vios doesn't match, just return
            if vios_w.uuid not in self.vios_uuids:
                return None

            LOG.info("Disconnecting storage disks.", instance=self.instance)
            removed_maps = tsk_map.remove_maps(vios_w,
                                               self.vm_uuid,
                                               match_func=match_func)
            for rm_map in removed_maps:
                slot_mgr.drop_vscsi_mapping(rm_map)
            return removed_maps

        self.stg_ftsk.add_functor_subtask(rm_func)
        # Find the disk directly.
        vios_w = self.stg_ftsk.wrapper_tasks[self.vios_uuids[0]].wrapper
        mappings = tsk_map.find_maps(vios_w.scsi_mappings,
                                     client_lpar_id=self.vm_uuid,
                                     match_func=match_func)

        return [x.backing_storage for x in mappings]
Example #5
0
    def dlt_vopt(self, instance, stg_ftsk):
        """Deletes the virtual optical and scsi mappings for a VM.

        :param instance: The nova instance whose VOpt(s) are to be removed.
        :param stg_ftsk: A FeedTask. The actions to modify the storage will be
                         added as batched functions onto the FeedTask.
        """
        lpar_uuid = vm.get_pvm_uuid(instance)

        # The matching function for find_maps, remove_maps
        match_func = tsk_map.gen_match_func(pvm_stg.VOptMedia)

        # Add a function to remove the mappings
        stg_ftsk.wrapper_tasks[self.vios_uuid].add_functor_subtask(
            tsk_map.remove_maps, lpar_uuid, match_func=match_func)

        # Find the VOpt device based from the mappings
        media_mappings = tsk_map.find_maps(
            stg_ftsk.get_wrapper(self.vios_uuid).scsi_mappings,
            client_lpar_id=lpar_uuid, match_func=match_func)
        media_elems = [x.backing_storage for x in media_mappings]

        def rm_vopt():
            LOG.info("Removing virtual optical storage.",
                     instance=instance)
            vg_wrap = pvm_stg.VG.get(self.adapter, uuid=self.vg_uuid,
                                     parent_type=pvm_vios.VIOS,
                                     parent_uuid=self.vios_uuid)
            tsk_stg.rm_vg_storage(vg_wrap, vopts=media_elems)

        # Add task to remove the media if it exists
        if media_elems:
            stg_ftsk.add_post_execute(task.FunctorTask(rm_vopt))
Example #6
0
    def _disconnect_volume(self, slot_mgr):
        # Get the hosting UUID
        nl_vios_wrap = partition.get_mgmt_partition(self.adapter)
        vios_uuid = nl_vios_wrap.uuid
        # Build the match function
        match_func = tsk_map.gen_match_func(pvm_stg.VDisk,
                                            names=[self._get_path()])

        # Make sure the remove function will run within the transaction manager
        def rm_func(vios_w):
            # If the vios doesn't match, just return
            if vios_w.uuid != vios_uuid:
                return None

            LOG.info(_LI("Disconnecting instance %(inst)s from storage "
                         "disks."), {'inst': self.instance.name},
                     instance=self.instance)
            return tsk_map.remove_maps(vios_w,
                                       self.vm_uuid,
                                       match_func=match_func)

        self.stg_ftsk.add_functor_subtask(rm_func)

        # Find the disk directly.
        vios_w = self.stg_ftsk.wrapper_tasks[vios_uuid].wrapper
        mappings = tsk_map.find_maps(vios_w.scsi_mappings,
                                     client_lpar_id=self.vm_uuid,
                                     match_func=match_func)

        return [x.backing_storage for x in mappings]
Example #7
0
    def disconnect_disk(self, instance, stg_ftsk=None, disk_type=None):
        """Disconnects the storage adapters from the image disk.

        :param instance: instance to disconnect the image for.
        :param stg_ftsk: (Optional) The pypowervm transaction FeedTask for
                         the I/O Operations.  If provided, the Virtual I/O
                         Server mapping updates will be added to the FeedTask.
                         This defers the updates to some later point in time.
                         If the FeedTask is not provided, the updates will be
                         run immediately when this method is executed.
        :param disk_type: The list of disk types to remove or None which means
                          to remove all disks from the VM.
        :return: A list of all the backing storage elements that were
                 disconnected from the I/O Server and VM.
        """
        if stg_ftsk is None:
            stg_ftsk = tsk_par.build_active_vio_feed_task(
                self.adapter, name='ssp', xag=[pvm_const.XAG.VIO_SMAP])

        lpar_uuid = vm.get_pvm_uuid(instance)
        match_func = tsk_map.gen_match_func(pvm_stg.LU, prefixes=disk_type)

        # Delay run function to remove the mapping between the VM and the LU
        def rm_func(vios_w):
            LOG.info("Removing SSP disk connection to VIOS %(vios)s.",
                     {'vios': vios_w.name},
                     instance=instance)
            return tsk_map.remove_maps(vios_w,
                                       lpar_uuid,
                                       match_func=match_func)

        # Add the mapping to *each* VIOS on the LPAR's host.
        # The LPAR's host has to be self.host_uuid, else the PowerVM API will
        # fail.
        #
        # Note - this may not be all the VIOSes on the system...just the ones
        # in the SSP cluster.
        #
        # The mappings will normally be the same on all VIOSes, unless a VIOS
        # was down when a disk was added.  So for the return value, we need to
        # collect the union of all relevant mappings from all VIOSes.
        lu_set = set()
        for vios_uuid in self.vios_uuids:
            # Add the remove for the VIO
            stg_ftsk.wrapper_tasks[vios_uuid].add_functor_subtask(rm_func)

            # Find the active LUs so that a delete op knows what to remove.
            vios_w = stg_ftsk.wrapper_tasks[vios_uuid].wrapper
            mappings = tsk_map.find_maps(vios_w.scsi_mappings,
                                         client_lpar_id=lpar_uuid,
                                         match_func=match_func)
            if mappings:
                lu_set.update([x.backing_storage for x in mappings])

        # Run the FeedTask if it was built locally
        if stg_ftsk.name == 'ssp':
            stg_ftsk.execute()

        return list(lu_set)
Example #8
0
    def add_dlt_vopt_tasks(self, lpar_uuid, stg_ftsk, remove_mappings=True):
        """Deletes the virtual optical and (optionally) scsi mappings for a VM.

        :param lpar_uuid: The pypowervm UUID of the LPAR whose vopt is to be
                          removed.
        :param stg_ftsk: A FeedTask handling storage I/O.  The task to remove
                         the mappings and media from the VM will be deferred on
                         to the FeedTask passed in. The execute can be done all
                         in one method (batched together).  No updates are
                         actually made here; they are simply added to the
                         FeedTask.
        :param remove_mappings: (Optional, Default: True) If set to true, will
                                remove the SCSI mappings as part of the
                                operation.  If false, will leave the mapping
                                but detach the storage from it.  If the VM is
                                running, it may be necessary to do the latter
                                as some operating systems will not allow the
                                removal.
        """
        # The function to find the VOpt
        match_func = tsk_map.gen_match_func(pvm_stg.VOptMedia)

        def rm_vopt_mapping(vios_w):
            return tsk_map.remove_maps(vios_w,
                                       lpar_uuid,
                                       match_func=match_func)

        def detach_vopt_from_map(vios_w):
            return tsk_map.detach_storage(vios_w,
                                          lpar_uuid,
                                          match_func=match_func)

        # Add a function to remove the map or detach the vopt
        stg_ftsk.wrapper_tasks[self.vios_uuid].add_functor_subtask(
            rm_vopt_mapping if remove_mappings else detach_vopt_from_map)

        # Find the vOpt device (before the remove is done) so that it can be
        # removed.
        partition_id = vm.get_vm_id(self.adapter, lpar_uuid)
        media_mappings = tsk_map.find_maps(stg_ftsk.get_wrapper(
            self.vios_uuid).scsi_mappings,
                                           client_lpar_id=partition_id,
                                           match_func=match_func)
        media_elems = [x.backing_storage for x in media_mappings]

        def rm_vopt():
            LOG.info(_LI("Removing virtual optical for VM with UUID %s."),
                     lpar_uuid)
            vg_wrap = pvm_stg.VG.get(self.adapter,
                                     uuid=self.vg_uuid,
                                     parent_type=pvm_vios.VIOS,
                                     parent_uuid=self.vios_uuid)
            tsk_stg.rm_vg_storage(vg_wrap, vopts=media_elems)

        # Don't add this task if there is no media to delete (eg. config drive)
        if media_elems:
            stg_ftsk.add_post_execute(task.FunctorTask(rm_vopt))
Example #9
0
 def rm_func(vios_w):
     LOG.info("Removing vSCSI mapping from physical volume %(dev)s "
              "on vios %(vios)s",
              {'dev': device_name, 'vios': vios_w.name},
              instance=self.instance)
     removed_maps = tsk_map.remove_maps(
         vios_w, vm_uuid,
         tsk_map.gen_match_func(pvm_stor.PV, names=[device_name]))
     return removed_maps
Example #10
0
 def rm_func(vios_w):
     LOG.info(_LI("Removing vSCSI mapping from Physical Volume %(dev)s "
                  "to VM %(vm)s") % {'dev': device_name, 'vm': vm_uuid})
     removed_maps = tsk_map.remove_maps(
         vios_w, vm_uuid,
         tsk_map.gen_match_func(pvm_stor.PV, names=[device_name]))
     for rm_map in removed_maps:
         slot_mgr.drop_vscsi_mapping(rm_map)
     return removed_maps
Example #11
0
 def rm_func(vios_w):
     LOG.info("Removing vSCSI mapping from physical volume %(dev)s "
              "on vios %(vios)s",
              {'dev': device_name, 'vios': vios_w.name},
              instance=self.instance)
     removed_maps = tsk_map.remove_maps(
         vios_w, vm_uuid,
         tsk_map.gen_match_func(pvm_stor.PV, names=[device_name]))
     return removed_maps
Example #12
0
    def disconnect_image_disk(self,
                              context,
                              instance,
                              stg_ftsk=None,
                              disk_type=None):
        """Disconnects the storage adapters from the image disk.

        :param context: nova context for operation
        :param instance: instance to disconnect the image for.
        :param stg_ftsk: (Optional) The pypowervm transaction FeedTask for the
                         I/O Operations.  If provided, the Virtual I/O Server
                         mapping updates will be added to the FeedTask.  This
                         defers the updates to some later point in time.  If
                         the FeedTask is not provided, the updates will be run
                         immediately when this method is executed.
        :param disk_type: The list of disk types to remove or None which means
                          to remove all disks from the VM.
        :return: A list of all the backing storage elements that were
                 disconnected from the I/O Server and VM.
        """
        lpar_uuid = vm.get_pvm_uuid(instance)

        # Ensure we have a transaction manager.
        if stg_ftsk is None:
            stg_ftsk = vios.build_tx_feed_task(
                self.adapter,
                self.host_uuid,
                name='localdisk',
                xag=[pvm_vios.VIOS.xags.SCSI_MAPPING])

        # Build the match function
        match_func = tsk_map.gen_match_func(pvm_stg.VDisk, prefixes=disk_type)

        # Make sure the remove function will run within the transaction manager
        def rm_func(vios_w):
            LOG.info(
                _LI("Disconnecting instance %(inst)s from storage disks.") %
                {'inst': instance.name})
            return tsk_map.remove_maps(vios_w,
                                       lpar_uuid,
                                       match_func=match_func)

        stg_ftsk.wrapper_tasks[self._vios_uuid].add_functor_subtask(rm_func)

        # Find the disk directly.
        vios_w = stg_ftsk.wrapper_tasks[self._vios_uuid].wrapper
        mappings = tsk_map.find_maps(vios_w.scsi_mappings,
                                     client_lpar_id=lpar_uuid,
                                     match_func=match_func)

        # Run the transaction manager if built locally.  Must be done after
        # the find to make sure the mappings were found previously.
        if stg_ftsk.name == 'localdisk':
            stg_ftsk.execute()

        return [x.backing_storage for x in mappings]
Example #13
0
 def rm_func(vios_w):
     LOG.info(
         _LI("Removing vSCSI mapping from Physical Volume %(dev)s "
             "to VM %(vm)s") % {
                 'dev': device_name,
                 'vm': vm_uuid
             })
     return tsk_map.remove_maps(
         vios_w, vm_uuid,
         tsk_map.gen_match_func(pvm_stor.PV, names=[device_name]))
Example #14
0
 def rm_func(vios_w):
     LOG.info("Removing vSCSI mapping from physical volume %(dev)s.",
              {'dev': device_name},
              instance=self.instance)
     removed_maps = tsk_map.remove_maps(
         vios_w, vm_uuid,
         tsk_map.gen_match_func(pvm_stor.PV, names=[device_name]))
     for rm_map in removed_maps:
         slot_mgr.drop_vscsi_mapping(rm_map)
     return removed_maps
Example #15
0
    def _disk_match_func(disk_type, instance):
        """Return a matching function to locate the disk for an instance.

        :param disk_type: One of the DiskType enum values.
        :param instance: The instance whose disk is to be found.
        :return: Callable suitable for the match_func parameter of the
                 pypowervm.tasks.scsi_mapper.find_maps method.
        """
        disk_name = SSPDiskAdapter._get_disk_name(disk_type, instance)
        return tsk_map.gen_match_func(pvm_stg.LU, names=[disk_name])
Example #16
0
    def _disk_match_func(disk_type, instance):
        """Return a matching function to locate the disk for an instance.

        :param disk_type: One of the DiskType enum values.
        :param instance: The instance whose disk is to be found.
        :return: Callable suitable for the match_func parameter of the
                 pypowervm.tasks.scsi_mapper.find_maps method.
        """
        disk_name = LocalStorage._get_disk_name(
            disk_type, instance, short=True)
        return tsk_map.gen_match_func(pvm_stg.VDisk, names=[disk_name])
Example #17
0
    def add_dlt_vopt_tasks(self, lpar_uuid, stg_ftsk, remove_mappings=True):
        """Deletes the virtual optical and (optionally) scsi mappings for a VM.

        :param lpar_uuid: The pypowervm UUID of the LPAR whose vopt is to be
                          removed.
        :param stg_ftsk: A FeedTask handling storage I/O.  The task to remove
                         the mappings and media from the VM will be deferred on
                         to the FeedTask passed in. The execute can be done all
                         in one method (batched together).  No updates are
                         actually made here; they are simply added to the
                         FeedTask.
        :param remove_mappings: (Optional, Default: True) If set to true, will
                                remove the SCSI mappings as part of the
                                operation.  If false, will leave the mapping
                                but detach the storage from it.  If the VM is
                                running, it may be necessary to do the latter
                                as some operating systems will not allow the
                                removal.
        """
        # The function to find the VOpt
        match_func = tsk_map.gen_match_func(pvm_stg.VOptMedia)

        def rm_vopt_mapping(vios_w):
            return tsk_map.remove_maps(vios_w, lpar_uuid,
                                       match_func=match_func)

        def detach_vopt_from_map(vios_w):
            return tsk_map.detach_storage(vios_w, lpar_uuid,
                                          match_func=match_func)

        # Add a function to remove the map or detach the vopt
        stg_ftsk.wrapper_tasks[self.vios_uuid].add_functor_subtask(
            rm_vopt_mapping if remove_mappings else detach_vopt_from_map)

        # Find the vOpt device (before the remove is done) so that it can be
        # removed.
        partition_id = vm.get_vm_id(self.adapter, lpar_uuid)
        media_mappings = tsk_map.find_maps(
            stg_ftsk.get_wrapper(self.vios_uuid).scsi_mappings,
            client_lpar_id=partition_id, match_func=match_func)
        media_elems = [x.backing_storage for x in media_mappings]

        def rm_vopt():
            LOG.info(_LI("Removing virtual optical for VM with UUID %s."),
                     lpar_uuid)
            vg_rsp = self.adapter.read(pvm_vios.VIOS.schema_type,
                                       root_id=self.vios_uuid,
                                       child_type=pvm_stg.VG.schema_type,
                                       child_id=self.vg_uuid)
            tsk_stg.rm_vg_storage(pvm_stg.VG.wrap(vg_rsp), vopts=media_elems)

        # Don't add this task if there is no media to delete (eg. config drive)
        if media_elems:
            stg_ftsk.add_post_execute(task.FunctorTask(rm_vopt))
Example #18
0
 def rm_func(vios_w):
     LOG.info(
         _LI("Removing vSCSI mapping from Physical Volume %(dev)s "
             "to VM %(vm)s"), {
                 'dev': device_name,
                 'vm': vm_uuid
             })
     removed_maps = tsk_map.remove_maps(
         vios_w, vm_uuid,
         tsk_map.gen_match_func(pvm_stor.PV, names=[device_name]))
     for rm_map in removed_maps:
         slot_mgr.drop_vscsi_mapping(rm_map)
     return removed_maps
Example #19
0
    def disconnect_image_disk(self, context, instance, stg_ftsk=None,
                              disk_type=None):
        """Disconnects the storage adapters from the image disk.

        :param context: nova context for operation
        :param instance: instance to disconnect the image for.
        :param stg_ftsk: (Optional) The pypowervm transaction FeedTask for the
                         I/O Operations.  If provided, the Virtual I/O Server
                         mapping updates will be added to the FeedTask.  This
                         defers the updates to some later point in time.  If
                         the FeedTask is not provided, the updates will be run
                         immediately when this method is executed.
        :param disk_type: The list of disk types to remove or None which means
                          to remove all disks from the VM.
        :return: A list of all the backing storage elements that were
                 disconnected from the I/O Server and VM.
        """
        lpar_uuid = vm.get_pvm_uuid(instance)

        # Ensure we have a transaction manager.
        if stg_ftsk is None:
            stg_ftsk = vios.build_tx_feed_task(
                self.adapter, self.host_uuid, name='localdisk',
                xag=[pvm_vios.VIOS.xags.SCSI_MAPPING])

        # Build the match function
        match_func = tsk_map.gen_match_func(pvm_stg.VDisk, prefixes=disk_type)

        # Make sure the remove function will run within the transaction manager
        def rm_func(vios_w):
            LOG.info(_LI("Disconnecting instance %(inst)s from storage disks.")
                     % {'inst': instance.name})
            return tsk_map.remove_maps(vios_w, lpar_uuid,
                                       match_func=match_func)

        stg_ftsk.wrapper_tasks[self._vios_uuid].add_functor_subtask(rm_func)

        # Find the disk directly.
        vios_w = stg_ftsk.wrapper_tasks[self._vios_uuid].wrapper
        mappings = tsk_map.find_maps(vios_w.scsi_mappings,
                                     client_lpar_id=lpar_uuid,
                                     match_func=match_func)

        # Run the transaction manager if built locally.  Must be done after
        # the find to make sure the mappings were found previously.
        if stg_ftsk.name == 'localdisk':
            stg_ftsk.execute()

        return [x.backing_storage for x in mappings]
Example #20
0
    def disk_match_func(self, disk_type, instance):
        """Return a matching function to locate the disk for an instance.

        :param disk_type: One of the DiskType enum values.
        :param instance: The instance whose disk is to be found.
        :return: Callable suitable for the match_func parameter of the
                 pypowervm.tasks.scsi_mapper.find_maps method, with the
                 following specification:
            def match_func(storage_elem)
                param storage_elem: A backing storage element wrapper (VOpt,
                                    VDisk, PV, or LU) to be analyzed.
                return: True if the storage_elem's mapping should be included;
                        False otherwise.
        """
        disk_name = self._get_disk_name(disk_type, instance, short=True)
        return tsk_map.gen_match_func(pvm_stg.VDisk, names=[disk_name])
Example #21
0
    def disk_match_func(self, disk_type, instance):
        """Return a matching function to locate the disk for an instance.

        :param disk_type: One of the DiskType enum values.
        :param instance: The instance whose disk is to be found.
        :return: Callable suitable for the match_func parameter of the
                 pypowervm.tasks.scsi_mapper.find_maps method, with the
                 following specification:
            def match_func(storage_elem)
                param storage_elem: A backing storage element wrapper (VOpt,
                                    VDisk, PV, or LU) to be analyzed.
                return: True if the storage_elem's mapping should be included;
                        False otherwise.
        """
        disk_name = self._get_disk_name(disk_type, instance, short=True)
        return tsk_map.gen_match_func(pvm_stg.VDisk, names=[disk_name])
Example #22
0
    def _check_host_mappings(self, vios_wrap, device_name):
        """Checks if the given hdisk has multiple mappings

        :param vio_wrap: The Virtual I/O Server wrapper to remove the disk
                         from.
        :param device_name: The hdisk name to remove.

        :return: True is there are multiple instances using the given hdisk
        """
        vios_scsi_mappings = next(v.scsi_mappings for v in self.stg_ftsk.feed if v.uuid == vios_wrap.uuid)
        mappings = tsk_map.find_maps(vios_scsi_mappings, None, tsk_map.gen_match_func(pvm_stor.PV, names=[device_name]))

        LOG.info(_LI("%(num)d Storage Mappings found for %(dev)s"), {"num": len(mappings), "dev": device_name})
        # the mapping is still present as the task feed removes
        # the mapping later
        return len(mappings) > 1
Example #23
0
    def detach_disk(self, instance):
        """Detaches the storage adapters from the disk.

        :param instance: instance from which to detach the image.
        :return: A list of all the backing storage elements that were detached
                 from the I/O Server and VM.
        """
        stg_ftsk = tsk_par.build_active_vio_feed_task(
            self._adapter, name='ssp', xag=[pvm_const.XAG.VIO_SMAP])

        lpar_uuid = vm.get_pvm_uuid(instance)
        match_func = tsk_map.gen_match_func(pvm_stg.LU)

        def rm_func(vwrap):
            LOG.info("Removing SSP disk connection to VIOS %s.",
                     vwrap.name,
                     instance=instance)
            return tsk_map.remove_maps(vwrap, lpar_uuid, match_func=match_func)

        # Remove the mapping from *each* VIOS on the LPAR's host.
        # The LPAR's host has to be self._host_uuid, else the PowerVM API will
        # fail.
        #
        # Note - this may not be all the VIOSes on the system...just the ones
        # in the SSP cluster.
        #
        # The mappings will normally be the same on all VIOSes, unless a VIOS
        # was down when a disk was added.  So for the return value, we need to
        # collect the union of all relevant mappings from all VIOSes.
        lu_set = set()
        for vios_uuid in self._vios_uuids:
            # Add the remove for the VIO
            stg_ftsk.wrapper_tasks[vios_uuid].add_functor_subtask(rm_func)

            # Find the active LUs so that a delete op knows what to remove.
            vios_w = stg_ftsk.wrapper_tasks[vios_uuid].wrapper
            mappings = tsk_map.find_maps(vios_w.scsi_mappings,
                                         client_lpar_id=lpar_uuid,
                                         match_func=match_func)
            if mappings:
                lu_set.update([x.backing_storage for x in mappings])

        stg_ftsk.execute()

        return list(lu_set)
Example #24
0
File: ssp.py Project: Juniper/nova
    def detach_disk(self, instance):
        """Detaches the storage adapters from the disk.

        :param instance: instance from which to detach the image.
        :return: A list of all the backing storage elements that were detached
                 from the I/O Server and VM.
        """
        stg_ftsk = tsk_par.build_active_vio_feed_task(
            self._adapter, name='ssp', xag=[pvm_const.XAG.VIO_SMAP])

        lpar_uuid = vm.get_pvm_uuid(instance)
        match_func = tsk_map.gen_match_func(pvm_stg.LU)

        def rm_func(vwrap):
            LOG.info("Removing SSP disk connection to VIOS %s.",
                     vwrap.name, instance=instance)
            return tsk_map.remove_maps(vwrap, lpar_uuid,
                                       match_func=match_func)

        # Remove the mapping from *each* VIOS on the LPAR's host.
        # The LPAR's host has to be self.host_uuid, else the PowerVM API will
        # fail.
        #
        # Note - this may not be all the VIOSes on the system...just the ones
        # in the SSP cluster.
        #
        # The mappings will normally be the same on all VIOSes, unless a VIOS
        # was down when a disk was added.  So for the return value, we need to
        # collect the union of all relevant mappings from all VIOSes.
        lu_set = set()
        for vios_uuid in self._vios_uuids:
            # Add the remove for the VIO
            stg_ftsk.wrapper_tasks[vios_uuid].add_functor_subtask(rm_func)

            # Find the active LUs so that a delete op knows what to remove.
            vios_w = stg_ftsk.wrapper_tasks[vios_uuid].wrapper
            mappings = tsk_map.find_maps(vios_w.scsi_mappings,
                                         client_lpar_id=lpar_uuid,
                                         match_func=match_func)
            if mappings:
                lu_set.update([x.backing_storage for x in mappings])

        stg_ftsk.execute()

        return list(lu_set)
Example #25
0
    def _check_host_mappings(self, vios_wrap, device_name):
        """Checks if the given hdisk has multiple mappings

        :param vio_wrap: The Virtual I/O Server wrapper to remove the disk
                         from.
        :param device_name: The hdisk name to remove.
        :return: True if there are multiple instances using the given hdisk
        """
        vios_scsi_mappings = next(v.scsi_mappings for v in self.stg_ftsk.feed
                                  if v.uuid == vios_wrap.uuid)
        mappings = tsk_map.find_maps(
            vios_scsi_mappings, None,
            tsk_map.gen_match_func(pvm_stor.PV, names=[device_name]))

        LOG.debug("%(num)d storage mapping(s) found for %(dev)s on VIOS "
                  "%(vios)s", {'num': len(mappings), 'dev': device_name,
                               'vios': vios_wrap.name}, instance=self.instance)
        # The mapping is still present as the task feed removes it later.
        return len(mappings) > 1
Example #26
0
    def add_dlt_vopt_tasks(self, lpar_uuid, stg_ftsk):
        """Deletes the virtual optical and scsi mappings for a VM.

        :param lpar_uuid: The pypowervm UUID of the LPAR to remove.
        :param stg_ftsk: A FeedTask handling storage I/O.  The task to remove
                         the mappings and media from the VM will be deferred on
                         to the FeedTask passed in. The execute can be done all
                         in one method (batched together).  No updates are
                         actually made here; they are simply added to the
                         FeedTask.
        """
        # The function to find the VOpt
        match_func = tsk_map.gen_match_func(pvm_stg.VOptMedia)

        def rm_vopt_mapping(vios_w):
            return tsk_map.remove_maps(vios_w,
                                       lpar_uuid,
                                       match_func=match_func)

        # Add a function to remove the map
        stg_ftsk.wrapper_tasks[self.vios_uuid].add_functor_subtask(
            rm_vopt_mapping)

        # Find the vOpt device (before the remove is done) so that it can be
        # removed.
        partition_id = vm.get_vm_id(self.adapter, lpar_uuid)
        media_mappings = tsk_map.find_maps(stg_ftsk.get_wrapper(
            self.vios_uuid).scsi_mappings,
                                           client_lpar_id=partition_id,
                                           match_func=match_func)
        media_elems = [x.backing_storage for x in media_mappings]

        def rm_vopt():
            LOG.info(_LI("Removing virtual optical for VM with UUID %s."),
                     lpar_uuid)
            vg_rsp = self.adapter.read(pvm_vios.VIOS.schema_type,
                                       root_id=self.vios_uuid,
                                       child_type=pvm_stg.VG.schema_type,
                                       child_id=self.vg_uuid)
            tsk_stg.rm_vg_storage(pvm_stg.VG.wrap(vg_rsp), vopts=media_elems)

        stg_ftsk.add_post_execute(task.FunctorTask(rm_vopt))
Example #27
0
    def add_dlt_vopt_tasks(self, lpar_uuid, stg_ftsk):
        """Deletes the virtual optical and scsi mappings for a VM.

        :param lpar_uuid: The pypowervm UUID of the LPAR to remove.
        :param stg_ftsk: A FeedTask handling storage I/O.  The task to remove
                         the mappings and media from the VM will be deferred on
                         to the FeedTask passed in. The execute can be done all
                         in one method (batched together).  No updates are
                         actually made here; they are simply added to the
                         FeedTask.
        """
        # The function to find the VOpt
        match_func = tsk_map.gen_match_func(pvm_stg.VOptMedia)

        def rm_vopt_mapping(vios_w):
            return tsk_map.remove_maps(vios_w, lpar_uuid,
                                       match_func=match_func)

        # Add a function to remove the map
        stg_ftsk.wrapper_tasks[self.vios_uuid].add_functor_subtask(
            rm_vopt_mapping)

        # Find the vOpt device (before the remove is done) so that it can be
        # removed.
        partition_id = vm.get_vm_id(self.adapter, lpar_uuid)
        media_mappings = tsk_map.find_maps(
            stg_ftsk.get_wrapper(self.vios_uuid).scsi_mappings,
            client_lpar_id=partition_id, match_func=match_func)
        media_elems = [x.backing_storage for x in media_mappings]

        def rm_vopt():
            LOG.info(_LI("Removing virtual optical for VM with UUID %s."),
                     lpar_uuid)
            vg_rsp = self.adapter.read(pvm_vios.VIOS.schema_type,
                                       root_id=self.vios_uuid,
                                       child_type=pvm_stg.VG.schema_type,
                                       child_id=self.vg_uuid)
            tsk_stg.rm_vg_storage(pvm_stg.VG.wrap(vg_rsp), vopts=media_elems)

        stg_ftsk.add_post_execute(task.FunctorTask(rm_vopt))
Example #28
0
    def detach_disk(self, instance):
        """Detaches the storage adapters from the image disk.

        :param instance: Instance to disconnect the image for.
        :return: A list of all the backing storage elements that were
                 disconnected from the I/O Server and VM.
        """
        lpar_uuid = vm.get_pvm_uuid(instance)

        # Build the match function
        match_func = tsk_map.gen_match_func(pvm_stg.VDisk)

        vios_w = pvm_vios.VIOS.get(
            self._adapter, uuid=self._vios_uuid, xag=[pvm_const.XAG.VIO_SMAP])

        # Remove the mappings.
        mappings = tsk_map.remove_maps(
            vios_w, lpar_uuid, match_func=match_func)

        # Update the VIOS with the removed mappings.
        vios_w.update()

        return [x.backing_storage for x in mappings]
Example #29
0
    def test_gen_match_func(self):
        """Tests for gen_match_func."""

        # Class must match
        mfunc = scsi_mapper.gen_match_func(str)
        self.assertFalse(mfunc(1))
        self.assertTrue(mfunc('foo'))

        # Match names
        elem = mock.Mock()
        elem.name = 'foo'
        # 'False' names/prefixes ignored
        mfunc = scsi_mapper.gen_match_func(mock.Mock, names=[])
        self.assertTrue(mfunc(elem))
        mfunc = scsi_mapper.gen_match_func(mock.Mock, prefixes=[])
        self.assertTrue(mfunc(elem))
        mfunc = scsi_mapper.gen_match_func(mock.Mock, names=[], prefixes=[])
        self.assertTrue(mfunc(elem))
        mfunc = scsi_mapper.gen_match_func(mock.Mock, names=['bar', 'baz'])
        self.assertFalse(mfunc(elem))
        mfunc = scsi_mapper.gen_match_func(mock.Mock,
                                           names=['bar', 'foobar', 'baz'])
        self.assertFalse(mfunc(elem))
        mfunc = scsi_mapper.gen_match_func(mock.Mock,
                                           names=['bar', 'foo', 'baz'])
        self.assertTrue(mfunc(elem))

        # Prefixes are ignored if names specified
        mfunc = scsi_mapper.gen_match_func(mock.Mock,
                                           prefixes='x',
                                           names=['bar', 'foo', 'baz'])
        self.assertTrue(mfunc(elem))
        mfunc = scsi_mapper.gen_match_func(mock.Mock,
                                           names=['bar', 'baz'],
                                           prefixes=['f'])
        self.assertFalse(mfunc(elem))

        # Prefixes
        mfunc = scsi_mapper.gen_match_func(mock.Mock, prefixes=['f'])
        self.assertTrue(mfunc(elem))
        mfunc = scsi_mapper.gen_match_func(mock.Mock, prefixes=['foo'])
        self.assertTrue(mfunc(elem))
        mfunc = scsi_mapper.gen_match_func(mock.Mock, prefixes=['foo', 'x'])
        self.assertTrue(mfunc(elem))
        mfunc = scsi_mapper.gen_match_func(mock.Mock, prefixes=['x'])
        self.assertFalse(mfunc(elem))
        mfunc = scsi_mapper.gen_match_func(mock.Mock,
                                           prefixes=['xfoo', 'foox', 'xfoox'])
        self.assertFalse(mfunc(elem))

        # Alternate key for the name property
        elem = mock.Mock(alt_name='foo')
        mfunc = scsi_mapper.gen_match_func(mock.Mock,
                                           name_prop='alt_name',
                                           names=[])
        self.assertTrue(mfunc(elem))
        mfunc = scsi_mapper.gen_match_func(mock.Mock, names=['bar', 'baz'])
        self.assertFalse(mfunc(elem))
        mfunc = scsi_mapper.gen_match_func(mock.Mock,
                                           name_prop='alt_name',
                                           names=['bar', 'baz'])
        self.assertFalse(mfunc(elem))
        mfunc = scsi_mapper.gen_match_func(mock.Mock,
                                           names=['bar', 'foo', 'baz'])
        self.assertFalse(mfunc(elem))
        mfunc = scsi_mapper.gen_match_func(mock.Mock,
                                           name_prop='alt_name',
                                           names=['bar', 'foo', 'baz'])
        self.assertTrue(mfunc(elem))
Example #30
0
    def test_detach_storage(self):
        """Detach storage from some mappings."""
        # In v1wrap, all five maps are associated with LPAR 2
        num_matches = 5
        self.assertEqual(num_matches, len(self.v1wrap.scsi_mappings))
        # Beforehand, four of them have storage and one does not.
        self.assertEqual(
            4,
            len([
                sm.backing_storage for sm in self.v1wrap.scsi_mappings
                if sm.backing_storage is not None
            ]))
        removals = scsi_mapper.detach_storage(self.v1wrap, 2)
        # The number of mappings is the same afterwards.
        self.assertEqual(num_matches, len(self.v1wrap.scsi_mappings))
        # But now the mappings have no storage
        for smap in self.v1wrap.scsi_mappings:
            self.assertIsNone(smap.backing_storage)
        # The return list contains all the mappings
        self.assertEqual(num_matches, len(removals))
        # The return list members contain the storage (the four that had it
        # beforehand).
        self.assertEqual(
            4,
            len([
                sm.backing_storage for sm in removals
                if sm.backing_storage is not None
            ]))

        # In v2wrap, there are four VOptMedia mappings
        num_matches = 4
        match_class = pvm_stor.VOptMedia
        # Number of mappings should be the same before and after.
        len_before = len(self.v2wrap.scsi_mappings)
        self.assertEqual(
            num_matches,
            len([
                1 for sm in self.v2wrap.scsi_mappings
                if isinstance(sm.backing_storage, match_class)
            ]))
        removals = scsi_mapper.detach_storage(
            self.v2wrap,
            None,
            match_func=scsi_mapper.gen_match_func(match_class))
        self.assertEqual(num_matches, len(removals))
        # The number of mappings is the same as beforehand.
        self.assertEqual(len_before, len(self.v2wrap.scsi_mappings))
        # Now there should be no mappings with VOptMedia
        self.assertEqual(
            0,
            len([
                1 for sm in self.v2wrap.scsi_mappings
                if isinstance(sm.backing_storage, match_class)
            ]))
        # The removals contain the storage
        self.assertEqual(
            num_matches,
            len([
                1 for sm in removals
                if isinstance(sm.backing_storage, match_class)
            ]))
Example #31
0
    def test_gen_match_func(self):
        """Tests for gen_match_func."""

        # Class must match
        mfunc = scsi_mapper.gen_match_func(str)
        self.assertFalse(mfunc(1))
        self.assertTrue(mfunc('foo'))

        # Match names
        elem = mock.Mock()
        elem.name = 'foo'
        # 'False' names/prefixes ignored
        mfunc = scsi_mapper.gen_match_func(mock.Mock, names=[])
        self.assertTrue(mfunc(elem))
        mfunc = scsi_mapper.gen_match_func(mock.Mock, prefixes=[])
        self.assertTrue(mfunc(elem))
        mfunc = scsi_mapper.gen_match_func(mock.Mock, names=[], prefixes=[])
        self.assertTrue(mfunc(elem))
        mfunc = scsi_mapper.gen_match_func(mock.Mock, names=['bar', 'baz'])
        self.assertFalse(mfunc(elem))
        mfunc = scsi_mapper.gen_match_func(mock.Mock, names=['bar', 'foobar',
                                                             'baz'])
        self.assertFalse(mfunc(elem))
        mfunc = scsi_mapper.gen_match_func(mock.Mock,
                                           names=['bar', 'foo', 'baz'])
        self.assertTrue(mfunc(elem))

        # Prefixes are ignored if names specified
        mfunc = scsi_mapper.gen_match_func(mock.Mock, prefixes='x',
                                           names=['bar', 'foo', 'baz'])
        self.assertTrue(mfunc(elem))
        mfunc = scsi_mapper.gen_match_func(mock.Mock, names=['bar', 'baz'],
                                           prefixes=['f'])
        self.assertFalse(mfunc(elem))

        # Prefixes
        mfunc = scsi_mapper.gen_match_func(mock.Mock, prefixes=['f'])
        self.assertTrue(mfunc(elem))
        mfunc = scsi_mapper.gen_match_func(mock.Mock, prefixes=['foo'])
        self.assertTrue(mfunc(elem))
        mfunc = scsi_mapper.gen_match_func(mock.Mock, prefixes=['foo', 'x'])
        self.assertTrue(mfunc(elem))
        mfunc = scsi_mapper.gen_match_func(mock.Mock, prefixes=['x'])
        self.assertFalse(mfunc(elem))
        mfunc = scsi_mapper.gen_match_func(mock.Mock, prefixes=['xfoo', 'foox',
                                                                'xfoox'])
        self.assertFalse(mfunc(elem))

        # Alternate key for the name property
        elem = mock.Mock(alt_name='foo')
        mfunc = scsi_mapper.gen_match_func(mock.Mock, name_prop='alt_name',
                                           names=[])
        self.assertTrue(mfunc(elem))
        mfunc = scsi_mapper.gen_match_func(mock.Mock, names=['bar', 'baz'])
        self.assertFalse(mfunc(elem))
        mfunc = scsi_mapper.gen_match_func(mock.Mock, name_prop='alt_name',
                                           names=['bar', 'baz'])
        self.assertFalse(mfunc(elem))
        mfunc = scsi_mapper.gen_match_func(mock.Mock,
                                           names=['bar', 'foo', 'baz'])
        self.assertFalse(mfunc(elem))
        mfunc = scsi_mapper.gen_match_func(mock.Mock, name_prop='alt_name',
                                           names=['bar', 'foo', 'baz'])
        self.assertTrue(mfunc(elem))
Example #32
0
    def disconnect_image_disk(self, context, instance, stg_ftsk=None,
                              disk_type=None):
        """Disconnects the storage adapters from the image disk.

        :param context: nova context for operation
        :param instance: instance to disconnect the image for.
        :param stg_ftsk: (Optional) The pypowervm transaction FeedTask for
                         the I/O Operations.  If provided, the Virtual I/O
                         Server mapping updates will be added to the FeedTask.
                         This defers the updates to some later point in time.
                         If the FeedTask is not provided, the updates will be
                         run immediately when this method is executed.
        :param disk_type: The list of disk types to remove or None which means
                          to remove all disks from the VM.
        :return: A list of all the backing storage elements that were
                 disconnected from the I/O Server and VM.
        """
        if stg_ftsk is None:
            stg_ftsk = vios.build_tx_feed_task(
                self.adapter, self.host_uuid, name='ssp',
                xag=[pvm_vios.VIOS.xags.SCSI_MAPPING])

        lpar_uuid = vm.get_pvm_uuid(instance)
        match_func = tsk_map.gen_match_func(pvm_stg.LU, prefixes=disk_type)

        # Delay run function to remove the mapping between the VM and the LU
        def rm_func(vios_w):
            LOG.info(_LI("Removing SSP disk connection between VM %(vm)s and "
                         "VIOS %(vios)s."),
                     {'vm': instance.name, 'vios': vios_w.name})
            return tsk_map.remove_maps(vios_w, lpar_uuid,
                                       match_func=match_func)

        # Add the mapping to *each* VIOS on the LPAR's host.
        # The LPAR's host has to be self.host_uuid, else the PowerVM API will
        # fail.
        #
        # Note - this may not be all the VIOSes on the system...just the ones
        # in the SSP cluster.
        #
        # The mappings will normally be the same on all VIOSes, unless a VIOS
        # was down when a disk was added.  So for the return value, we need to
        # collect the union of all relevant mappings from all VIOSes.
        lu_set = set()
        for vios_uuid in self.vios_uuids:
            # Add the remove for the VIO
            stg_ftsk.wrapper_tasks[vios_uuid].add_functor_subtask(rm_func)

            # Find the active LUs so that a delete op knows what to remove.
            vios_w = stg_ftsk.wrapper_tasks[vios_uuid].wrapper
            mappings = tsk_map.find_maps(vios_w.scsi_mappings,
                                         client_lpar_id=lpar_uuid,
                                         match_func=match_func)
            if mappings:
                lu_set.update([x.backing_storage for x in mappings])

        # Run the FeedTask if it was built locally
        if stg_ftsk.name == 'ssp':
            stg_ftsk.execute()

        return list(lu_set)
Example #33
0
 def rm_func(vios_w):
     LOG.info(
         _LI("Removing vSCSI mapping from Physical Volume %(dev)s " "to VM %(vm)s")
         % {"dev": device_name, "vm": vm_uuid}
     )
     return tsk_map.remove_maps(vios_w, vm_uuid, tsk_map.gen_match_func(pvm_stor.PV, names=[device_name]))