def remove_iscsi_target(self, tid, lun, vol_id, **kwargs): LOG.info(_('Removing iscsi_target for: %s') % vol_id) vol_uuid_file = FLAGS.volume_name_template % vol_id volume_path = os.path.join(FLAGS.volumes_dir, vol_uuid_file) if os.path.isfile(volume_path): iqn = '%s%s' % (FLAGS.iscsi_target_prefix, vol_uuid_file) else: raise exception.ISCSITargetRemoveFailed(volume_id=vol_id) try: # NOTE(vish): --force is a workaround for bug: # https://bugs.launchpad.net/cinder/+bug/1159948 self._execute('tgt-admin', '--force', '--delete', iqn, run_as_root=True) except exception.ProcessExecutionError as e: LOG.error( _("Failed to remove iscsi target for volume " "id:%(vol_id)s: %(e)s") % { 'vol_id': vol_id, 'e': str(e) }) raise exception.ISCSITargetRemoveFailed(volume_id=vol_id) os.unlink(volume_path)
def remove_iscsi_target(self, tid, lun, vol_id, vol_name, **kwargs): LOG.info(_('Removing iscsi_target for: %s') % vol_id) vol_uuid_file = vol_name volume_path = os.path.join(self.volumes_dir, vol_uuid_file) if not os.path.exists(volume_path): LOG.warning(_('Volume path %s does not exist, ' 'nothing to remove.') % volume_path) return if os.path.isfile(volume_path): iqn = '%s%s' % (self.iscsi_target_prefix, vol_uuid_file) else: raise exception.ISCSITargetRemoveFailed(volume_id=vol_id) try: # NOTE(vish): --force is a workaround for bug: # https://bugs.launchpad.net/cinder/+bug/1159948 self._execute('tgt-admin', '--force', '--delete', iqn, run_as_root=True) except putils.ProcessExecutionError as e: LOG.error(_("Failed to remove iscsi target for volume " "id:%(vol_id)s: %(e)s") % {'vol_id': vol_id, 'e': e}) raise exception.ISCSITargetRemoveFailed(volume_id=vol_id) # NOTE(jdg): There's a bug in some versions of tgt that # will sometimes fail silently when using the force flag # https://bugs.launchpad.net/ubuntu/+source/tgt/+bug/1305343 # For now work-around by checking if the target was deleted, # if it wasn't, try again without the force. # This will NOT do any good for the case of mutliple sessions # which the force was aded for but it will however address # the cases pointed out in bug: # https://bugs.launchpad.net/cinder/+bug/1304122 if self._get_target(iqn): try: LOG.warning(_('Silent failure of target removal ' 'detected, retry....')) self._execute('tgt-admin', '--delete', iqn, run_as_root=True) except putils.ProcessExecutionError as e: LOG.error(_("Failed to remove iscsi target for volume " "id:%(vol_id)s: %(e)s") % {'vol_id': vol_id, 'e': e}) raise exception.ISCSITargetRemoveFailed(volume_id=vol_id) # NOTE(jdg): This *should* be there still but incase # it's not we don't care, so just ignore it if was # somehow deleted between entry of this method # and here if os.path.exists(volume_path): os.unlink(volume_path) else: LOG.debug('Volume path %s not found at end, ' 'of remove_iscsi_target.' % volume_path)
def remove_iscsi_target(self, tid, lun, vol_id, vol_name, **kwargs): LOG.info(_LI("Removing iscsi_target for volume: %s"), vol_id) try: self._delete_logicalunit(tid, lun) session_info = self._find_sid_cid_for_target(tid, vol_name, vol_id) if session_info: sid, cid = session_info self._force_delete_target(tid, sid, cid) self._delete_target(tid) except putils.ProcessExecutionError: LOG.exception( _LE("Failed to remove iscsi target for volume " "id:%s"), vol_id) raise exception.ISCSITargetRemoveFailed(volume_id=vol_id) vol_uuid_file = vol_name conf_file = self.iet_conf if os.path.exists(conf_file): try: with utils.temporary_chown(conf_file): with open(conf_file, 'r+') as iet_conf_text: full_txt = iet_conf_text.readlines() new_iet_conf_txt = [] count = 0 for line in full_txt: if count > 0: count -= 1 continue elif vol_uuid_file in line: count = 2 continue else: new_iet_conf_txt.append(line) iet_conf_text.seek(0) iet_conf_text.truncate(0) iet_conf_text.writelines(new_iet_conf_txt) except Exception: LOG.exception( _LE("Failed to update %(conf)s for volume id " "%(vol_id)s after removing iscsi target"), { 'conf': conf_file, 'vol_id': vol_id }) raise exception.ISCSITargetRemoveFailed(volume_id=vol_id) else: LOG.warning( _LW("Failed to update %(conf)s for volume id " "%(vol_id)s after removing iscsi target. " "%(conf)s does not exist."), { 'conf': conf_file, 'vol_id': vol_id })
def remove_iscsi_target(self, tid, lun, vol_id, **kwargs): LOG.info(_('Removing volume: %s') % vol_id) vol_uuid_file = 'volume-%s' % vol_id volume_path = os.path.join(FLAGS.volumes_dir, vol_uuid_file) if os.path.isfile(volume_path): iqn = '%s%s' % (FLAGS.iscsi_target_prefix, vol_uuid_file) else: raise exception.ISCSITargetRemoveFailed(volume_id=vol_id) try: self._execute('tgt-admin', '--delete', iqn, run_as_root=True) except exception.ProcessExecutionError, e: LOG.error( _("Failed to create iscsi target for volume " "id:%(volume_id)s.") % locals()) raise exception.ISCSITargetRemoveFailed(volume_id=vol_id)
def remove_iscsi_target(self, tid, lun, vol_id, **kwargs): LOG.info(_('Removing iscsi_target: %s') % vol_id) vol_uuid_name = 'volume-%s' % vol_id iqn = '%s%s' % (FLAGS.iscsi_target_prefix, vol_uuid_name) try: self._execute('rtstool', 'delete', iqn, run_as_root=True) except exception.ProcessExecutionError as e: LOG.error( _("Failed to remove iscsi target for volume " "id:%(vol_id)s.") % locals()) LOG.error("%s" % str(e)) raise exception.ISCSITargetRemoveFailed(volume_id=vol_id)
def remove_iscsi_target(self, tid, lun, vol_id, vol_name, **kwargs): LOG.info(_('Removing iscsi_target: %s') % vol_id) vol_uuid_name = vol_name iqn = '%s%s' % (self.iscsi_target_prefix, vol_uuid_name) try: self._execute('cinder-rtstool', 'delete', iqn, run_as_root=True) except putils.ProcessExecutionError as e: LOG.error( _("Failed to remove iscsi target for volume " "id:%s.") % vol_id) LOG.error(_("%s") % e) raise exception.ISCSITargetRemoveFailed(volume_id=vol_id)
def remove_iscsi_target(self, tid, lun, vol_id, vol_name, **kwargs): LOG.info('Removing iscsi_target: %s', vol_id) vol_uuid_name = vol_name iqn = '%s%s' % (self.iscsi_target_prefix, vol_uuid_name) try: self._execute('cinder-rtstool', 'delete', iqn, run_as_root=True) except putils.ProcessExecutionError: LOG.exception("Failed to remove iscsi target for volume id:%s.", vol_id) raise exception.ISCSITargetRemoveFailed(volume_id=vol_id) # We make changes persistent self._persist_configuration(vol_id)
def remove_iscsi_target(self, tid, lun, vol_id, vol_name, **kwargs): LOG.info(_LI('Removing iscsi_target for: %s'), vol_id) vol_uuid_file = vol_name volume_path = os.path.join(self._get_volumes_dir(), vol_uuid_file) if not os.path.exists(volume_path): LOG.warning( _LW('Volume path %s does not exist, ' 'nothing to remove.'), volume_path) return if os.path.isfile(volume_path): iqn = '%s%s' % (self.iscsi_target_prefix, vol_uuid_file) else: raise exception.ISCSITargetRemoveFailed(volume_id=vol_id) target_exists = False try: (out, err) = utils.execute('iscsictl', '-c', 'target=%s' % iqn, run_as_root=True) LOG.debug("StdOut from iscsictl -c: %s", out) LOG.debug("StdErr from iscsictl -c: %s", err) except putils.ProcessExecutionError as e: if "NOT found" in e.stdout: LOG.info( _LI("No iscsi target present for volume " "id:%(vol_id)s: %(e)s"), { 'vol_id': vol_id, 'e': e }) return else: raise exception.ISCSITargetRemoveFailed(volume_id=vol_id) else: target_exists = True try: utils.execute('iscsictl', '-s', 'target=%s' % iqn, run_as_root=True) except putils.ProcessExecutionError as e: # There exists a race condition where multiple calls to # remove_iscsi_target come in simultaneously. If we can poll # for a target successfully but it is gone before we can remove # it, fail silently if "is not found" in e.stderr and target_exists: LOG.info( _LI("No iscsi target present for volume " "id:%(vol_id)s: %(e)s"), { 'vol_id': vol_id, 'e': e }) return else: LOG.error( _LE("Failed to remove iscsi target for volume " "id:%(vol_id)s: %(e)s"), { 'vol_id': vol_id, 'e': e }) raise exception.ISCSITargetRemoveFailed(volume_id=vol_id) # Carried over from tgt # NOTE(jdg): This *should* be there still but incase # it's not we don't care, so just ignore it if was # somehow deleted between entry of this method # and here if os.path.exists(volume_path): os.unlink(volume_path) else: LOG.debug( 'Volume path %s not found at end, ' 'of remove_iscsi_target.', volume_path)
def remove_iscsi_target(self, tid, lun, vol_id, vol_name, **kwargs): disk_id = "%s%s" % (lun, vol_id.split('-')[-1]) vol_uuid_file = vol_name if self.target_name is None: iqn = '%s%s' % (self.iscsi_target_prefix, vol_uuid_file) else: iqn = self.target_name if self.target_name is None: try: self.scst_execute('-noprompt', '-rem_target', iqn, '-driver', 'iscsi') except putils.ProcessExecutionError as e: LOG.error( "Failed to remove iscsi target for volume " "id:%(vol_id)s: %(e)s", { 'vol_id': vol_id, 'e': e }) raise exception.ISCSITargetRemoveFailed(volume_id=vol_id) try: self.scst_execute('-noprompt', '-close_dev', "disk%s" % tid, '-handler', 'vdisk_fileio') except putils.ProcessExecutionError as e: LOG.error("Failed to close disk device %s", e) raise exception.ISCSITargetHelperCommandFailed( error_message="Failed to close disk device for " "SCST handler.") if self._get_target(iqn): try: self.scst_execute('-noprompt', '-rem_target', iqn, '-driver', self.target_driver) except putils.ProcessExecutionError as e: LOG.error( "Failed to remove iscsi target for " "volume id:%(vol_id)s: %(e)s", { 'vol_id': vol_id, 'e': e }) raise exception.ISCSITargetRemoveFailed(volume_id=vol_id) else: if not int(lun) in self._get_luns_info(): raise exception.ISCSITargetRemoveFailed(volume_id=vol_id) try: scst_group = "%s%s" % (self.remove_initiator_iqn, self.target_name) self.scst_execute('-noprompt', '-rem_lun', lun, '-driver', self.target_driver, '-target', iqn, '-group', scst_group) except putils.ProcessExecutionError as e: LOG.error("Failed to remove LUN %s", e) raise exception.ISCSITargetHelperCommandFailed( error_message="Failed to remove LUN for SCST Target.") try: self.scst_execute('-noprompt', '-close_dev', disk_id, '-handler', 'vdisk_fileio') except putils.ProcessExecutionError as e: LOG.error("Failed to close disk device %s", e) raise exception.ISCSITargetHelperCommandFailed( error_message="Failed to close disk device for " "SCST handler.") self.scst_execute('-write_config', '/etc/scst.conf')
def remove_iscsi_target(self, tid, lun, vol_id, vol_name, **kwargs): LOG.info('Removing iscsi_target for Volume ID: %s', vol_id) vol_uuid_file = vol_name volume_path = os.path.join(self.volumes_dir, vol_uuid_file) if not os.path.exists(volume_path): LOG.warning('Volume path %s does not exist, ' 'nothing to remove.', volume_path) return if os.path.isfile(volume_path): iqn = '%s%s' % (self.iscsi_target_prefix, vol_uuid_file) else: raise exception.ISCSITargetRemoveFailed(volume_id=vol_id) try: # NOTE(vish): --force is a workaround for bug: # https://bugs.launchpad.net/cinder/+bug/1159948 cinder.privsep.targets.tgt.tgtadmin_delete(iqn, force=True) except putils.ProcessExecutionError as e: non_fatal_errors = ("can't find the target", "access control rule does not exist") if any(error in e.stderr for error in non_fatal_errors): LOG.warning( "Failed target removal because target or " "ACL's couldn't be found for iqn: %s.", iqn) else: LOG.error( "Failed to remove iscsi target for Volume " "ID: %(vol_id)s: %(e)s", { 'vol_id': vol_id, 'e': e }) raise exception.ISCSITargetRemoveFailed(volume_id=vol_id) # NOTE(jdg): There's a bug in some versions of tgt that # will sometimes fail silently when using the force flag # https://bugs.launchpad.net/ubuntu/+source/tgt/+bug/1305343 # For now work-around by checking if the target was deleted, # if it wasn't, try again without the force. # This will NOT do any good for the case of mutliple sessions # which the force was aded for but it will however address # the cases pointed out in bug: # https://bugs.launchpad.net/cinder/+bug/1304122 if self._get_target(iqn): try: LOG.warning('Silent failure of target removal ' 'detected, retry....') cinder.privsep.targets.tgt.tgtadmin_delete(iqn) except putils.ProcessExecutionError as e: LOG.error( "Failed to remove iscsi target for Volume " "ID: %(vol_id)s: %(e)s", { 'vol_id': vol_id, 'e': e }) raise exception.ISCSITargetRemoveFailed(volume_id=vol_id) # NOTE(jdg): This *should* be there still but incase # it's not we don't care, so just ignore it if was # somehow deleted between entry of this method # and here if os.path.exists(volume_path): os.unlink(volume_path) else: LOG.debug( 'Volume path %s not found at end, ' 'of remove_iscsi_target.', volume_path)