예제 #1
0
    def get_device_path(self, blockdevice_id):
        """
        Return the device path that has been allocated to the block device on
        the host to which it is currently attached.

        :param unicode blockdevice_id: The unique identifier for the block
            device.
        :raises UnknownVolume: If the supplied ``blockdevice_id`` does not
            exist.
        :raises UnattachedVolume: If the supplied ``blockdevice_id`` is
            not attached to a host.
        :returns: A ``FilePath`` for the device.
        """
        # raises UnknownVolume
        volume = self._get(blockdevice_id)

        # raises UnattachedVolume
        if volume.attached_to is None:
            Message.new(Error="Could get Device Path "
                        + str(blockdevice_id)
                        + "is not attached").write(_logger)
            raise UnattachedVolume(blockdevice_id)

        # Check the "actual volume" for attachment
        sio_volume = self._client.get_volume_by_id(
            str(blockdevice_id))
        sdcs = self._client.get_sdc_for_volume(sio_volume)
        if len(sdcs) == 0:
            Message.new(Error="Could get Device Path "
                        + str(blockdevice_id)
                        + "is not attached").write(_logger)
            raise UnattachedVolume(blockdevice_id)

        # return the real path of the device
        return self._get_dev_from_blockdeviceid(volume.blockdevice_id)
예제 #2
0
    def detach_volume(self, blockdevice_id):
        """
        Detach ``blockdevice_id`` from whatever host it is attached to.

        :param unicode blockdevice_id: The unique identifier for the block
            device being detached.
        """

        LOG.debug("Call detach_volume blockdevice_id=%s" % blockdevice_id)

        if not self.rest.is_lun(self.Pool, blockdevice_id):
            raise UnknownVolume(blockdevice_id)

        target_name = '{}{}.{}'.format(self.jovian_target_prefix,
                                       blockdevice_id,
                                       self._compute_instance_id)

        jcom.iscsiadm_logout_target(target_name, self.host, self.target_port)

        if not self.rest.is_target(self.Pool, target_name):
            raise UnattachedVolume(blockdevice_id)
        elif not self.rest.is_target_lun(self.Pool, target_name,
                                         blockdevice_id):
            self.rest.delete_target(self.Pool, target_name)
            raise UnattachedVolume(blockdevice_id)

        self.rest.detach_target_vol(self.Pool, target_name,
                                    blockdevice_id)
        self.rest.delete_target(self.Pool, target_name)
        jcom.rm_local_dir('/flocker/{}/'.format(blockdevice_id))
예제 #3
0
    def detachOsnexusvolume(self, blockdevice_id):
        vol = self.validateVolume(blockdevice_id)
        if self.isVolumeAttached(blockdevice_id) is False:
            raise UnattachedVolume(blockdevice_id)
        try:
            self.doIscsiLogout(vol._name)
        except Exception as e:
            self._logger.error("failed to logout")
            raise UnattachedVolume(blockdevice_id)

        self._qsclient.volume_dettach(blockdevice_id, self._osnexusHostId)
    def detach_volume(self, blockdevice_id):
        """
        Detach ``blockdevice_id`` from whatever host it is attached to.
        :param unicode blockdevice_id: The unique identifier for the block
            device being detached.
        :raises UnknownVolume: If the supplied ``blockdevice_id`` does not
            exist.
        :raises UnattachedVolume: If the supplied ``blockdevice_id`` is
            not attached to anything.
        :returns: ``None``
        """

        _vmstate_lock.acquire()
        try:
            (target_disk, vm_name, lun) = \
                self._get_disk_vmname_lun(blockdevice_id)

            if target_disk is None:
                raise UnknownVolume(blockdevice_id)

            if lun is None:
                raise UnattachedVolume(blockdevice_id)

            self._manager.detach_disk(vm_name, target_disk)
        finally:
            _vmstate_lock.release()
예제 #5
0
    def detach_volume(self, blockdevice_id):
        """
        Detach ``blockdevice_id`` from whatever host it is attached to.
        :param unicode blockdevice_id: The unique identifier for the block
            device being detached.
        :raises UnknownVolume: If the supplied ``blockdevice_id`` does not
            exist.
        :raises UnattachedVolume: If the supplied ``blockdevice_id`` is
            not attached to anything.
        :returns: ``None``
        """

        (target_disk, role_name, lun) = \
            self._get_disk_vmname_lun(blockdevice_id)

        if target_disk is None:
            raise UnknownVolume(blockdevice_id)

        if lun is None:
            raise UnattachedVolume(blockdevice_id)

        # contrary to function name it doesn't delete by default, just detachs

        request = \
            self._azure_service_client.delete_data_disk(
                service_name=self._service_name,
                deployment_name=self._service_name,
                role_name=role_name, lun=lun)

        self._wait_for_async(request.request_id, 5000)

        self._wait_for_detach(blockdevice_id)
예제 #6
0
    def get_device_path(self, blockdevice_id):
        """
        Return the device path that has been allocated to the block device on
        the host to which it is currently attached.

        Returning the wrong value here can lead to data loss or corruption
        if a container is started with an unexpected volume. Make very
        sure you are returning the correct result.

        :param unicode blockdevice_id: The unique identifier for the block
            device.
        :raises UnknownVolume: If the supplied ``blockdevice_id`` does not
            exist.
        :raises UnattachedVolume: If the supplied ``blockdevice_id`` is
            not attached to a host.
        :returns: A ``FilePath`` for the device.
        """
        iscsi_name = self.eqlx_con.iscsi_name_from_dataset_id(blockdevice_id)
        output = check_output([b"/usr/bin/lsscsi", "-t"])
        if str(blockdevice_id) not in output:
            raise UnattachedVolume(blockdevice_id)
        for device_entry in output.split("\n"):
            if str(blockdevice_id) in device_entry:
                dev = device_entry.split().pop()
                return FilePath(dev)
예제 #7
0
    def get_device_path(self, blockdevice_id):
        """
        Get device path for the CIO volume corresponding to the given
        block device.

        :param unicode blockdevice_id: CIO UUID for the volume to look up.

        :returns: A ``FilePath`` for the device.
        :raises UnknownVolume: If the supplied ``blockdevice_id`` does not
            exist.
        :raises UnattachedVolume: If the supplied ``blockdevice_id`` is
            not attached to a host.
        """
        command = [b"/usr/bin/cio", b"vdinfo", b"-u", blockdevice_id, "-v"]
        output = check_output(command).split(b'\n')[0]
        cio_volume = output.split()[0]
        if cio_volume == "Fail:":
            raise UnknownVolume(blockdevice_id)
        command = [
            b"/usr/bin/cio", b"vdinfo", b"-v",
            bytes(cio_volume), b"--attachstatus"
        ]
        compute_output = check_output(command).split(b'\n')[0]
        attached_to = compute_output.split()[0]
        if attached_to == "None":
            raise UnattachedVolume(blockdevice_id)

        compute_instance_id = self.compute_instance_id()
        if attached_to != compute_instance_id:
            # This is untested.  See FLOC-2453.
            raise Exception("Volume is attached to {}, not to {}".format(
                attached_to, compute_instance_id))
        return FilePath("/dev/vdisk/vd" + str(cio_volume))
    def detach_volume(self, blockdevice_id):
        """
        Detach ``blockdevice_id`` from whatever host it is attached to.
        :param unicode blockdevice_id: The unique identifier for the block
            device being detached.
        :raises UnknownVolume: If the supplied ``blockdevice_id`` does not
            exist.
        :raises UnattachedVolume: If the supplied ``blockdevice_id`` is
            not attached to anything.
        :raises VolumeDetachFailure: If volume detach fails due to some error
        :returns: ``None``
        """
        vsphere_volume = self._get_vsphere_blockdevice_volume(blockdevice_id)
        if vsphere_volume.blockDeviceVolume.attached_to is None:
            logging.debug("Volume " + blockdevice_id + " not attached")
            raise UnattachedVolume(blockdevice_id)

        try:
            detached_volume = self._detach_vmdk(vsphere_volume)
        except Exception as e:
            logging.error("Detach volume {} failed with error: {}".format(
                detached_volume, e))
            raise VolumeDetachFailure(e)

        self._rescan_scsi()
        logging.debug(
            "Volume {} successfully detached.".format(blockdevice_id))
    def get_device_path(self, blockdevice_id):
        """
        Return the device path that has been allocated to the block device on
        the host to which it is currently attached.

        :param unicode blockdevice_id: The unique identifier for the block
            device.
        :raises UnknownVolume: If the supplied ``blockdevice_id`` does not
            exist.
        :raises UnattachedVolume: If the supplied ``blockdevice_id`` is
            not attached to a host.
        :returns: A ``FilePath`` for the device.
        """
        # raises UnknownVolume
        vol_info = self._get_volume_object(blockdevice_id)
        volume = self._get_blockdevicevolume_by_vol(vol_info)

        if volume.attached_to is None:
            LOG.error(messages.BLOCKDEVICE_NOT_ATTACHED_STOP_SEARCHING.
                      format(str(blockdevice_id)))
            raise UnattachedVolume(blockdevice_id)

        if self._is_multipathing:
            # Assume OS rescan was already triggered
            # TODO consider to rescan if device was not found
            return self._get_device_multipath(vol_info.name, blockdevice_id)
        else:
            raise Exception(messages.SUPPORT_ONLY_MULTIPATHING)
예제 #10
0
    def detach_volume(self, blockdevice_id):
        """
        Detach ``blockdevice_id`` from whatever host it is attached to.

        :param unicode blockdevice_id: The unique identifier for the block
            device being detached.

        :raises UnknownVolume: If the supplied ``blockdevice_id`` does not
            exist.
        :raises UnattachedVolume: If the supplied ``blockdevice_id`` is
            not attached to anything.
        :returns: ``None``
        """
        # raises UnknownVolume
        volume = self._get_volume(blockdevice_id)

        # raises UnattachedVolume
        if volume.attached_to is None:
            LOG.error(messages.CANNOT_DETACH_VOLUME_NOT_ATTACHED.
                      format(str(blockdevice_id)))
            raise UnattachedVolume(blockdevice_id)

        self._clean_up_device_before_unmap(blockdevice_id)
        self._client.unmap_volume(wwn=blockdevice_id, host=volume.attached_to)
        LOG.info(messages.DRIVER_OPERATION_VOL_DETTACH.format(
            blockdevice_id=blockdevice_id, attach_to=volume.attached_to))

        # Rescan the OS to clean the detached volume
        LOG.info(messages.DRIVER_OPERATION_VOL_RESCAN_START_ATTACH.format(
            blockdevice_id=blockdevice_id))
        self._host_ops.rescan_scsi()
예제 #11
0
    def get_device_path(self, blockdevice_id):
        """
        Return the device path that has been allocated to the block device on
        the host to which it is currently attached.

        :param unicode blockdevice_id: The unique identifier for the block
            device.
        :returns: A ``FilePath`` for the device.
        """

        LOG.debug("Call get_device_path blockdevice_id=%s" % blockdevice_id)

        if not self.rest.is_lun(self.Pool, blockdevice_id):
            raise UnknownVolume(blockdevice_id)

        target_name = '{}{}.{}'.format(self.jovian_target_prefix,
                                        blockdevice_id,
                                        self._compute_instance_id)

        if not self.rest.is_target(self.Pool, target_name):
            raise UnattachedVolume(blockdevice_id)

        path = jcom.get_local_disk_path(target_name)
        if path:
            LOG.debug('device_path was found: {}'.format(path))
            return FilePath('/dev/' + str(path))

        return None
예제 #12
0
    def getOsNexusDevicePath(self, blockdevice_id):
        vol = self.validateVolume(blockdevice_id)
        if self.isVolumeAttached(blockdevice_id) is False:
            raise UnattachedVolume(blockdevice_id)

        targetIqn = self.iscsiDiscovery(vol._name)
        return self.getIscsiPath(targetIqn)
예제 #13
0
 def get_assignments_of_volume(self, blockdevice_id, volume_name):
     logger.debug('Getting the list of hosts assigned to volume {} .'.format(volume_name))
     assignmentlist = self._rdxapi.list_assignments(vol=volume_name)
     if (len(assignmentlist) == 0):
         logger.error("Volume {} is not attached to any node.".format(volume_name))
         raise UnattachedVolume(blockdevice_id)
     logger.debug('Fetched the list of hosts assigned to volume {} .'.format(volume_name))
     return assignmentlist
예제 #14
0
 def doIscsiLogout(self, volName):
     try:
         targetIqn = self.iscsiDiscovery(volName)
     except Exception as e:
         self._logger.error("Volume [" + volName +
                            "] not found during discovery")
         raise UnattachedVolume(volName)
     self.iscsiLogout(targetIqn)
예제 #15
0
    def detach_volume(self, blockdevice_id):
        """
        Detach ``blockdevice_id`` from whatever host it is attached to.

        :param unicode blockdevice_id: The unique identifier for the block
            device being detached.

        :raises UnknownVolume: If the supplied ``blockdevice_id`` does not
            exist.
        :raises UnattachedVolume: If the supplied ``blockdevice_id`` is
            not attached to anything.
        :returns: ``None``
        """
        volName = str(blockdevice_id)
        vdiskInfo = findVDisk(volName)
        if (vdiskInfo == None):
            raise UnknownVolume(blockdevice_id)

        computeHost = self.compute_instance_id()
        try:
            tgtHost = hedvigLookupTgt('wood', self.logger_)
            lunnum = hedvigGetLun(tgtHost, volName, self.logger_)
        except:
            raise UnattachedVolume(blockdevice_id)
        if lunnum == -1:
            raise UnattachedVolume(blockdevice_id)
        if (self._is_attached(tgtHost, lunnum) == None):
            raise UnattachedVolume(blockdevice_id)
        devicepath = self.get_device_path(blockdevice_id)
        try:
            self.logout(blockdevice_id)
            hedvigRemoveAccess(
                tgtHost, lunnum,
                socket.gethostbyname(socket.getfqdn(computeHost)),
                devicepath.path, self.logger_)
            hedvigRemoveAccess(tgtHost, lunnum,
                               socket.gethostbyname(socket.getfqdn()),
                               devicepath.path, self.logger_)
        except Exception as e:
            print e
            raise Exception(
                "Not able to detach volume with blockdevice_id: %s" %
                blockdevice_id)
    def get_device_path(self, blockdevice_id):
        """
        Return the device path that has been allocated to the block device on
        the host to which it is currently attached.
        :param unicode blockdevice_id: The unique identifier for the block
            device.
        :raises UnknownVolume: If the supplied ``blockdevice_id`` does not
            exist.
        :raises UnattachedVolume: If the supplied ``blockdevice_id`` is
            not attached to a host.
        :raises GetDevicePathFailure: If get_device_path fails due to some error
        :returns: A ``FilePath`` for the device.
        """
        vsphere_volume = self._get_vsphere_blockdevice_volume(blockdevice_id)
        if vsphere_volume.blockDeviceVolume.attached_to is None:
            logging.error("Volume is not attached to a vm.")
            raise UnattachedVolume(blockdevice_id)

        try:
            devices = self._find_all_disk_devices()
            for device in devices:
                try:
                    logging.debug("Executing scsiinfo -s {} ".format(device))
                    platform_dist = self.get_platform()
                    if 'centos' in platform_dist.lower():
                        output = check_output(["sginfo", "-s", device])
                        logging.debug("SERIAL ID on CENTOS VM")
                    else:
                        output = check_output(["scsiinfo", "-s", device])
                    logging.debug(output)
                except Exception, ex:
                    logging.error(
                        "Error occured for scsiinfo -s {}: {}".format(
                            device, ex))
                    continue
                serial_id_line_index = output.find("'")
                if serial_id_line_index < 0:
                    logging.debug(
                        "No serial id found for device: {}".format(device))
                    continue
                serial_id = output[serial_id_line_index:]
                logging.debug(serial_id)
                uid = self._normalize_uuid(serial_id)
                logging.debug(uid)
                logging.debug(blockdevice_id)
                if str(uid) == str(blockdevice_id):
                    logging.debug("Found device path {}".format(device))
                    return FilePath(device)
        except Exception, ex:
            logging.error("Get device path failed with error: {}".format(ex))
            raise GetDevicePathFailure(ex)
 def detach_volume(self, blockdevice_id):
     """
     :param: volume id = blockdevice_id
     :raises: unknownvolume exception if not found
     """
     vol = self._get_vol_details(blockdevice_id)
     if vol.attached_to is not None:
         self.data.destroy_lun_map(blockdevice_id,
                                   self._compute_instance_id)
         self.data.rescan_scsi()
     else:
         Message.new(Info="Volume" + blockdevice_id +
                     "not attached").write(_logger)
         raise UnattachedVolume(blockdevice_id)
예제 #18
0
    def detach_volume(self, blockdevice_id):
        """
        Detach ``blockdevice_id`` from whatever host it is attached to.

        :param unicode blockdevice_id: The unique identifier for the block
            device being detached.

        :raises UnknownVolume: If the supplied ``blockdevice_id`` does not
            exist.
        :raises UnattachedVolume: If the supplied ``blockdevice_id`` is
            not attached to anything.
        :returns: ``None``
        """
        # raises UnknownVolume
        volume = self._get(blockdevice_id)
        # raises UnattachedVolume
        if volume.attached_to is None:
            Message.new(Error="Could Not Attach Volume "
                        + str(blockdevice_id)
                        + "is unattached").write(_logger)
            raise UnattachedVolume(blockdevice_id)

        # This list should consist of only one SDC, however
        # future versions of this may use mappingToAllSdcsEnabled
        # or ``allowMultipleMappings`` in the above function
        # which we would need to remove potentially all SDC mappings
        # if we initially map a volume to all SDCs
        sio_volume = self._client.get_volume_by_id(str(blockdevice_id))
        sdcs = self._client.get_sdc_for_volume(sio_volume)
        if len(sdcs) > 0:
            for sdc in sdcs:
                sdc = self._client.get_sdc_by_id(sdc['sdcId'])
                self._client.unmap_volume_from_sdc(sio_volume, sdcObj=sdc)
        else:
            # raises UnattachedVolume (is this needed?)
            raise UnattachedVolume(blockdevice_id)
        volume.set(attached_to=None)
예제 #19
0
    def get_device_path(self, blockdevice_id):
        """
        :param blockdevice_id:
        :return:the device path
        """
        if not self._known(blockdevice_id):
            raise UnknownVolume(blockdevice_id)

        # Datera mulitpath resolution
        # Get the IQN
        # Translate to host sdXX
        # Translate to dm-X
        # Translate to mpathXX
        ai_name = self._vols[blockdevice_id]['ai_name']
        try:
            si = get_datera_storageinst(self._api, ai_name)
            iqn = si['access']['iqn']
        except ApiError as ex:
            raise DeviceExceptionAPIError
        sd = iqn_to_sd(iqn)
        if not sd:
            Message.new(
                Info='FAIL iqn_to_sd for : ' + str(iqn)).write(_logger)
            raise UnattachedVolume(blockdevice_id)
        dm = sd_to_dm(sd)
        if not dm:
            Message.new(
                Info='FAIL sd_to_dm for : ' + str(sd)).write(_logger)
            raise UnattachedVolume(blockdevice_id)
        mpath = dm_to_mapper(dm)
        if mpath:
            return FilePath("/dev/mapper/" + mpath)
        else:
            Message.new(
                Info='FAIL dm_to_mapper for : ' + str(dm)).write(_logger)
        raise UnattachedVolume(blockdevice_id)
예제 #20
0
 def logout(self, blockdevice_id):
     """
     """
     volName = str(blockdevice_id)
     if (findVDisk(volName) == None):
         raise UnknownVolume(blockdevice_id)
     tgtHost = hedvigLookupTgt('wood', self.logger_)
     lunnum = hedvigGetLun(tgtHost, volName, self.logger_)
     try:
         targetName, portal = hedvigDoIscsiDiscovery(
             tgtHost, lunnum, self.logger_)
     except Exception as e:
         targetName = None
     if (targetName == None):
         raise UnattachedVolume(blockdevice_id)
     hedvigDoIscsiLogout(targetName, portal, self.logger_)
예제 #21
0
    def get_device_path(self, blockdevice_id):
        """
        Return the device path that has been allocated to the block device on
        the host to which it is currently attached.

        :param unicode blockdevice_id: The unique identifier for the block
            device.
        :raises UnknownVolume: If the supplied ``blockdevice_id`` does not
            exist.
        :raises UnattachedVolume: If the supplied ``blockdevice_id`` is
            not attached to a host.
        :returns: A ``FilePath`` for the device.
        """
        self._check_exists(blockdevice_id)
        maps = self._list_maps()
        try:
            return maps[blockdevice_id]
        except KeyError:
            raise UnattachedVolume(blockdevice_id)
 def get_lun_map(self, blockdevice_id):
     """
     :param blockdevice_id: Volume id
     :return:return lun mapping if for the volume
     :exception: Volume unattached, if no mapping was found
     """
     try:
         vol = self.mgmt.request('volumes',
                                 name=str(blockdevice_id))['content']
         if int(vol['num-of-lun-mappings']) == 0:
             raise UnattachedVolume(blockdevice_id)
         else:
             # EMC XtremIO gives unique lun number for each
             # volume when it is attached. The unique lun number is
             # generated in sequence
             lun_mapping_list = vol['lun-mapping-list']
             return lun_mapping_list[0][2]
     except DeviceExceptionObjNotFound:
         Message.new(Error="get_lun_map: could not be found for" +
                     str(blockdevice_id)).write(_logger)
    def detach_volume(self, blockdevice_id):
        """ Detach ``blockdevice_id`` from whatever host it is attached to.

        :param unicode blockdevice_id: The unique identifier for the block
            device being detached.

        :raises UnknownVolume: If the supplied ``blockdevice_id`` does not
            exist.
        :raises UnattachedVolume: If the supplied ``blockdevice_id`` is
            not attached to anything.
        :returns: ``None``
        """
        vol = self._get_solidfire_volume(blockdevice_id)
        if not vol:
            raise UnknownVolume(blockdevice_id)

        tgt_iqn = vol['iqn']
        if not utils.path_exists('/dev/disk/by-path/ip-%s-iscsi-%s-lun-0' %
                                 (self.svip, tgt_iqn), 1):
            raise UnattachedVolume(blockdevice_id)
        utils.iscsi_logout(self.svip, tgt_iqn)
    def detach_volume(self, blockdevice_id):
        with start_action(action_type=six.text_type(
                "flocker:node:agents:do:detach_volume"),
                          blockdevice_id=blockdevice_id) as a:
            try:
                vol = self._get_volume(blockdevice_id)
                if not vol.droplet_ids:
                    raise UnattachedVolume(blockdevice_id)
                detach_from = vol.droplet_ids[0]
                region = vol.region["slug"]
                r = vol.detach(detach_from, region)

                if self._await_action_id(r['action']['id']):
                    vol.droplet_ids = None
                a.add_success_fields(detached_from={
                    'droplet_id': detach_from,
                    'region': region
                })
                return self._to_block_device_volume(vol)
            except NotFoundError as _:
                raise UnknownVolume(blockdevice_id)
예제 #25
0
    def _get_device_multipath(self, vol_name, blockdevice_id):
        """
        :param vol_name: Volume name for logging
        :param blockdevice_id: which is the WWN of the volume
        :return: A ``FilePath`` for the multipath device.
        """
        try:
            device_path = self._host_ops.get_multipath_device(
                vol_wwn=blockdevice_id)
        except (host_actions.MultipathDeviceNotFound,
                host_actions.MultipathDeviceFilePathNotFound,
                host_actions.CalledProcessError) as e:
            LOG.error(messages.CANNOT_FIND_DEVICE_PATH.format(
                str(blockdevice_id), vol_name, e))

            raise UnattachedVolume(blockdevice_id)
        device_path_obj = FilePath(device_path)
        LOG.info(messages.DRIVER_OPERATION_GET_MULTIPATH_DEVICE.format(
            volname=vol_name, device_path=device_path_obj.path,
            cmd=self._host_ops.multipath_cmd_ll))

        return device_path_obj
    def detach_volume(self, blockdevice_id):
        """
        See ``BlockDeviceAPI.detach_volume``.
        :returns:
        """
        volume, profile = self._get_volume(blockdevice_id)
        self._gather_info(profile)

        if volume['attach_to'] is None:
            LOG.error("detach_volume: UnattachedVolume, " + blockdevice_id)
            raise UnattachedVolume(blockdevice_id)

        connector = self._find_vmax_host(volume['attach_to'])
        if connector is None:
            LOG.error("detach_volume: VolumeException, " + blockdevice_id)
            raise VolumeException(blockdevice_id)

        LOG.info(u"detach_volume " + unicode(volume) + u" from " +
                 unicode(connector))

        self.vmax_common[profile].terminate_connection(volume, connector)
        self._rescan_scsi_bus()
예제 #27
0
    def attachOsnexusVolume(self, blockdevice_id, attach_to):
        vol = self.validateVolume(blockdevice_id)
        volUuid = self.getDataSetId(vol._name)
        if volUuid is None:
            raise UnknownVolume(blockdevice_id)

        if self.isVolumeAttached(blockdevice_id) is True:
            raise AlreadyAttachedVolume(blockdevice_id)

        self.createHost()
        self._qsclient.volume_attach(blockdevice_id, self._osnexusHostId)

        try:
            self.doIscsiLogin(vol._name)
        except Exception as e:
            self._logger.error("failed to login")
            raise UnattachedVolume(blockdevice_id)

        return BlockDeviceVolume(blockdevice_id=blockdevice_id,
                                 size=int(vol._size),
                                 attached_to=attach_to,
                                 dataset_id=volUuid)
    def get_device_path(self, blockdevice_id):
        """
        Return the device path that has been allocated to the block device on
        the host to which it is currently attached.
        :param unicode blockdevice_id: The unique identifier for the block
            device.
        :raises UnknownVolume: If the supplied ``blockdevice_id`` does not
            exist.
        :raises UnattachedVolume: If the supplied ``blockdevice_id`` is
            not attached to a host.
        :returns: A ``FilePath`` for the device.
        """

        (target_disk, vm_name, lun) = \
            self._get_disk_vmname_lun(blockdevice_id)

        if target_disk is None:
            raise UnknownVolume(blockdevice_id)

        if lun is None:
            raise UnattachedVolume(blockdevice_id)

        return Lun.get_device_path_for_lun(lun)
    def get_device_path(self, blockdevice_id):
        """
        See ``BlockDeviceAPI.get_device_path``.
        :returns: A ``Deferred`` that fires with a ``FilePath`` for the device.
        """
        volume, profile = self._get_volume(blockdevice_id)
        symm_id = self._get_symmetrix_id(profile=profile)

        output = self._execute_inq()
        for line in output.splitlines():
            fields = unicode(line).split()
            if len(fields) == 4 and fields[0].startswith('/dev/') \
                    and fields[1] == symm_id and fields[2] == volume['name']:
                device_path = FilePath(fields[0])
                break
        else:
            LOG.error(u"get_device_path: UnattachedVolume, " +
                      unicode(blockdevice_id))
            raise UnattachedVolume(blockdevice_id)

        LOG.debug(u"get_device_path: bid = %s, path = %s" %
                  (unicode(blockdevice_id), unicode(device_path)))
        return device_path
예제 #30
0
    def detach_volume(self, blockdevice_id):
        """
        See ``BlockDeviceAPI.detach_volume``.
        :returns:
        """
        volume = self._get_volume(blockdevice_id)
        if volume['attach_to'] is None:
            LOG.error("detach_volume: UnattachedVolume, " +
                      unicode(blockdevice_id))
            raise UnattachedVolume(blockdevice_id)

        connector = self._find_vmax_host(volume['attach_to'])
        if connector is None:
            LOG.error("detach_volume: VolumeException, " +
                      unicode(blockdevice_id))
            raise VolumeException(blockdevice_id)

        LOG.info("detach_volume " + unicode(volume) + " to " +
                 unicode(connector))

        volume['attach_to'] = None
        self.dbconn.update_volume_by_id(blockdevice_id, volume)
        self.vmax_common.terminate_connection(volume, connector)