Beispiel #1
0
def do_trim(session, args):
    """Attempt to trim the given LVHDSR"""
    util.SMlog("do_trim: %s" % args)
    sr_uuid = args["sr_uuid"]
    os.environ['LVM_SYSTEM_DIR'] = MASTER_LVM_CONF

    if TRIM_CAP not in util.sr_get_capability(sr_uuid):
        util.SMlog("Trim command ignored on unsupported SR %s" % sr_uuid)
        err_msg = {
            ERROR_CODE_KEY: 'UnsupportedSRForTrim',
            ERROR_MSG_KEY: 'Trim on [%s] not supported' % sr_uuid
        }
        return to_xml(err_msg)

    # Lock SR, get vg empty space details
    sr_lock = lock.Lock(vhdutil.LOCK_TYPE_SR, sr_uuid)
    got_lock = False
    for i in range(LOCK_RETRY_ATTEMPTS):
        got_lock = sr_lock.acquireNoblock()
        if got_lock:
            break
        time.sleep(LOCK_RETRY_INTERVAL)

    if got_lock:
        try:
            vg_name = _vg_by_sr_uuid(sr_uuid)
            lv_name = sr_uuid + TRIM_LV_TAG
            lv_path = _lvpath_by_vg_lv_name(vg_name, lv_name)

            # Clean trim LV in case the previous trim attemp failed
            if lvutil.exists(lv_path):
                lvutil.remove(lv_path)

            #Check if VG limits are enough for creating LV.
            stats = lvutil._getVGstats(vg_name)
            if (stats['freespace'] < lvutil.LVM_SIZE_INCREMENT):
                util.SMlog("No space to claim on a full SR %s" % sr_uuid)
                err_msg = {
                    ERROR_CODE_KEY: 'Trim failed on full SR',
                    ERROR_MSG_KEY: 'No space to claim on a full SR'
                }
                result = to_xml(err_msg)
            else:
                # Perform a lvcreate, blkdiscard and lvremove to
                # trigger trim on the array
                lvutil.create(lv_name, 0, vg_name, size_in_percentage="100%F")
                cmd = ["/usr/sbin/blkdiscard", "-v", lv_path]
                stdout = util.pread2(cmd)
                util.SMlog("Stdout is %s" % stdout)
                util.SMlog("Trim on SR: %s complete. " % sr_uuid)
                result = str(True)
        except util.CommandException, e:
            err_msg = {
                ERROR_CODE_KEY: 'TrimException',
                ERROR_MSG_KEY: e.reason
            }
            result = to_xml(err_msg)
        except:
Beispiel #2
0
 def _get_blocktracking_status(self, uuid=None):
     """ Get blocktracking status """
     if not uuid:
         uuid = self.uuid
     if self.vdi_type == vhdutil.VDI_TYPE_RAW:
         return False
     elif 'VDI_CONFIG_CBT' not in util.sr_get_capability(self.sr.uuid):
         return False
     logpath = self._get_cbt_logpath(uuid)
     return self._cbt_log_exists(logpath)
Beispiel #3
0
 def _get_blocktracking_status(self, uuid=None):
     """ Get blocktracking status """
     if not uuid:
         uuid = self.uuid
     if self.vdi_type == vhdutil.VDI_TYPE_RAW:
         return False
     elif 'VDI_CONFIG_CBT' not in util.sr_get_capability(self.sr.uuid):
         return False
     logpath = self._get_cbt_logpath(uuid)
     return self._cbt_log_exists(logpath)
Beispiel #4
0
def do_trim(session, args):
    """Attempt to trim the given LVHDSR"""
    util.SMlog("do_trim: %s" % args)
    sr_uuid = args["sr_uuid"]
    os.environ['LVM_SYSTEM_DIR'] = MASTER_LVM_CONF

    if TRIM_CAP not in util.sr_get_capability(sr_uuid):
        util.SMlog("Trim command ignored on unsupported SR %s" % sr_uuid)
        err_msg = {ERROR_CODE_KEY: 'UnsupportedSRForTrim',
                   ERROR_MSG_KEY: 'Trim on [%s] not supported' % sr_uuid}
        return to_xml(err_msg)

    # Lock SR, get vg empty space details
    sr_lock = lock.Lock(vhdutil.LOCK_TYPE_SR, sr_uuid)
    got_lock = False
    for i in range(LOCK_RETRY_ATTEMPTS):
        got_lock = sr_lock.acquireNoblock()
        if got_lock:
            break
        time.sleep(LOCK_RETRY_INTERVAL)

    if got_lock:
        try:
            vg_name = _vg_by_sr_uuid(sr_uuid)
            lv_name = sr_uuid + TRIM_LV_TAG
            lv_path = _lvpath_by_vg_lv_name(vg_name, lv_name)

            # Clean trim LV in case the previous trim attemp failed
            if lvutil.exists(lv_path):
               lvutil.remove(lv_path)

            #Check if VG limits are enough for creating LV.
            stats = lvutil._getVGstats(vg_name)
            if (stats['freespace'] < lvutil.LVM_SIZE_INCREMENT):
                util.SMlog("No space to claim on a full SR %s" % sr_uuid)
                err_msg = {ERROR_CODE_KEY: 'Trim failed on full SR',
                           ERROR_MSG_KEY: 'No space to claim on a full SR'}
                result = to_xml(err_msg)
            else:
                # Perform a lvcreate, blkdiscard and lvremove to
                # trigger trim on the array
                lvutil.create(lv_name, 0, vg_name, size_in_percentage="100%F")
                cmd = ["/usr/sbin/blkdiscard", "-v", lv_path]
                stdout = util.pread2(cmd)
                util.SMlog("Stdout is %s" % stdout)
                util.SMlog("Trim on SR: %s complete. " % sr_uuid)
                result = str(True)
        except util.CommandException, e:
            err_msg = {
                ERROR_CODE_KEY: 'TrimException',
                ERROR_MSG_KEY: e.reason
            }
            result = to_xml(err_msg)
        except:
Beispiel #5
0
def do_trim(session, args):
    """Attempt to trim the given LVHDSR"""
    util.SMlog("do_trim: %s" % args)
    sr_uuid = args["sr_uuid"]

    if TRIM_CAP not in util.sr_get_capability(sr_uuid):
        util.SMlog("Trim command ignored on unsupported SR %s" % sr_uuid)
        err_msg = {ERROR_CODE_KEY: 'UnsupportedSRForTrim',
                   ERROR_MSG_KEY: 'Trim on [%s] not supported' % sr_uuid}
        return to_xml(err_msg)

    # Lock SR, get vg empty space details
    sr_lock = lock.Lock(vhdutil.LOCK_TYPE_SR, sr_uuid)
    got_lock = False
    for i in range(LOCK_RETRY_ATTEMPTS):
        got_lock = sr_lock.acquireNoblock()
        if got_lock:
            break
        time.sleep(LOCK_RETRY_INTERVAL)

    if got_lock:
        try:
            vg_name = _vg_by_sr_uuid(sr_uuid)
            lv_name = sr_uuid + TRIM_LV_TAG
            lv_path = _lvpath_by_vg_lv_name(vg_name, lv_name)

            # Clean trim LV in case the previous trim attemp failed
            if lvutil.exists(lv_path):
                lvutil.remove(lv_path)

            # Perform a lvcreate and lvremove to trigger trim on the array
            lvutil.create(lv_name, 0, vg_name, size_in_percentage="100%F")
            lvutil.remove(lv_path,  config_param="issue_discards=1")
            util.SMlog("Trim on SR: %s complete. " % sr_uuid)
            result = str(True)
        except:
            err_msg = {
                ERROR_CODE_KEY: 'UnknownTrimException',
                ERROR_MSG_KEY: 'Unknown Exception: trim failed on SR [%s]'
                % sr_uuid
            }
            result = to_xml(err_msg)

        _log_last_triggered(session, sr_uuid)

        sr_lock.release()
        return result
    else:
        util.SMlog("Could not complete Trim on %s, Lock unavailable !" \
                   % sr_uuid)
        err_msg = {ERROR_CODE_KEY: 'SRUnavailable',
                   ERROR_MSG_KEY: 'Unable to get SR lock [%s]' % sr_uuid}
        return to_xml(err_msg)
Beispiel #6
0
    def _run(self, sr, target):
        dconf_type = sr.dconf.get("type")
        if not dconf_type or not NO_LOGGING.get(dconf_type) or \
                not self.cmd in NO_LOGGING[dconf_type]:
            if 'device_config' in self.params:
                util.SMlog(
                    "%s %s" %
                    (self.cmd,
                     util.hidePasswdInParams(self.params, 'device_config')))
            else:
                util.SMlog("%s %s" % (self.cmd, repr(self.params)))

        caching_params = dict((k, self.params.get(k)) for k in \
                [blktap2.VDI.CONF_KEY_ALLOW_CACHING,
                 blktap2.VDI.CONF_KEY_MODE_ON_BOOT,
                 blktap2.VDI.CONF_KEY_CACHE_SR,
                 blktap2.VDI.CONF_KEY_O_DIRECT])

        if self.cmd == 'vdi_create':
            # These are the fields owned by the backend, passed on the
            # commandline:

            # LVM SRs store their metadata in XML format. XML does not support
            # all unicode characters, so we must check if the label or the
            # description contain such characters. We must enforce this
            # restriction to other SRs as well (even if they do allow these
            # characters) in order to be consistent.
            target.label = self.params['args'][1]
            target.description = self.params['args'][2]

            if not util.isLegalXMLString(target.label) \
                    or not util.isLegalXMLString(target.description):
                raise xs_errors.XenError('IllegalXMLChar', \
                        opterr = 'The name and/or description you supplied contains one or more unsupported characters. The name and/or description must contain valid XML characters. See http://www.w3.org/TR/2004/REC-xml-20040204/#charsets for more information.')

            target.ty = self.params['vdi_type']
            target.metadata_of_pool = self.params['args'][3]
            target.is_a_snapshot = self.params['args'][4] == "true"
            target.snapshot_time = self.params['args'][5]
            target.snapshot_of = self.params['args'][6]
            target.read_only = self.params['args'][7] == "true"

            return target.create(self.params['sr_uuid'], self.vdi_uuid,
                                 long(self.params['args'][0]))

        elif self.cmd == 'vdi_update':
            # Check for invalid XML characters, similar to VDI.create right
            # above.

            vdi_ref = sr.session.xenapi.VDI.get_by_uuid(self.vdi_uuid)
            name_label = sr.session.xenapi.VDI.get_name_label(vdi_ref)
            description = sr.session.xenapi.VDI.get_name_description(vdi_ref)

            if not util.isLegalXMLString(name_label) \
                    or not util.isLegalXMLString(description):
                raise xs_errors.XenError('IllegalXMLChar', \
                        opterr = 'The name and/or description you supplied contains one or more unsupported characters. The name and/or description must contain valid XML characters. See http://www.w3.org/TR/2004/REC-xml-20040204/#charsets for more information.')

            return target.update(self.params['sr_uuid'], self.vdi_uuid)

        elif self.cmd == 'vdi_introduce':
            target = sr.vdi(self.params['new_uuid'])
            return target.introduce(self.params['sr_uuid'],
                                    self.params['new_uuid'])

        elif self.cmd == 'vdi_delete':
            if 'VDI_CONFIG_CBT' in util.sr_get_capability(
                    self.params['sr_uuid']):
                return target.delete(self.params['sr_uuid'],
                                     self.vdi_uuid,
                                     data_only=False)
            else:
                return target.delete(self.params['sr_uuid'], self.vdi_uuid)

        elif self.cmd == 'vdi_attach':
            target = blktap2.VDI(self.vdi_uuid, target, self.driver_info)
            writable = self.params['args'][0] == 'true'
            return target.attach(self.params['sr_uuid'],
                                 self.vdi_uuid,
                                 writable,
                                 caching_params=caching_params)

        elif self.cmd == 'vdi_detach':
            target = blktap2.VDI(self.vdi_uuid, target, self.driver_info)
            return target.detach(self.params['sr_uuid'], self.vdi_uuid)

        elif self.cmd == 'vdi_snapshot':
            return target.snapshot(self.params['sr_uuid'], self.vdi_uuid)

        elif self.cmd == 'vdi_clone':
            return target.clone(self.params['sr_uuid'], self.vdi_uuid)

        elif self.cmd == 'vdi_resize':
            return target.resize(self.params['sr_uuid'], self.vdi_uuid,
                                 long(self.params['args'][0]))

        elif self.cmd == 'vdi_resize_online':
            return target.resize_online(self.params['sr_uuid'], self.vdi_uuid,
                                        long(self.params['args'][0]))

        elif self.cmd == 'vdi_activate':
            target = blktap2.VDI(self.vdi_uuid, target, self.driver_info)
            writable = self.params['args'][0] == 'true'
            return target.activate(self.params['sr_uuid'], self.vdi_uuid,
                                   writable, caching_params)

        elif self.cmd == 'vdi_deactivate':
            target = blktap2.VDI(self.vdi_uuid, target, self.driver_info)
            return target.deactivate(self.params['sr_uuid'], self.vdi_uuid,
                                     caching_params)

        elif self.cmd == 'vdi_epoch_begin':
            if caching_params.get(
                    blktap2.VDI.CONF_KEY_MODE_ON_BOOT) != "reset":
                return
            if not "VDI_RESET_ON_BOOT/2" in self.driver_info['capabilities']:
                raise xs_errors.XenError('Unimplemented')
            return target.reset_leaf(self.params['sr_uuid'], self.vdi_uuid)

        elif self.cmd == 'vdi_epoch_end':
            return

        elif self.cmd == 'vdi_generate_config':
            return target.generate_config(self.params['sr_uuid'],
                                          self.vdi_uuid)

        elif self.cmd == 'vdi_compose':
            vdi1_uuid = sr.session.xenapi.VDI.get_uuid(self.params['args'][0])
            return target.compose(self.params['sr_uuid'], vdi1_uuid,
                                  self.vdi_uuid)

        elif self.cmd == 'vdi_attach_from_config':
            ret = target.attach_from_config(self.params['sr_uuid'],
                                            self.vdi_uuid)
            if not target.sr.driver_config.get(
                    "ATTACH_FROM_CONFIG_WITH_TAPDISK"):
                return ret
            target = blktap2.VDI(self.vdi_uuid, target, self.driver_info)
            return target.attach(self.params['sr_uuid'], self.vdi_uuid, True,
                                 True)

        elif self.cmd == 'vdi_detach_from_config':
            extras = {}
            if target.sr.driver_config.get("ATTACH_FROM_CONFIG_WITH_TAPDISK"):
                target = blktap2.VDI(self.vdi_uuid, target, self.driver_info)
                extras['deactivate'] = True
                extras['caching_params'] = caching_params
            target.detach(self.params['sr_uuid'], self.vdi_uuid, **extras)

        elif self.cmd == 'vdi_enable_cbt':
            return target.configure_blocktracking(self.params['sr_uuid'],
                                                  self.vdi_uuid, True)

        elif self.cmd == 'vdi_disable_cbt':
            return target.configure_blocktracking(self.params['sr_uuid'],
                                                  self.vdi_uuid, False)

        elif self.cmd == 'vdi_data_destroy':
            return target.data_destroy(self.params['sr_uuid'], self.vdi_uuid)

        elif self.cmd == 'vdi_list_changed_blocks':
            return target.list_changed_blocks()

        elif self.cmd == 'sr_create':
            return sr.create(self.params['sr_uuid'],
                             long(self.params['args'][0]))

        elif self.cmd == 'sr_delete':
            return sr.delete(self.params['sr_uuid'])

        elif self.cmd == 'sr_update':
            return sr.update(self.params['sr_uuid'])

        elif self.cmd == 'sr_probe':
            txt = sr.probe()
            util.SMlog("sr_probe result: %s" %
                       util.splitXmlText(txt, showContd=True))
            # return the XML document as a string
            return xmlrpclib.dumps((txt, ), "", True)

        elif self.cmd == 'sr_attach':
            is_master = False
            if sr.dconf.get("SRmaster") == "true":
                is_master = True

            resetvdis.reset_sr(sr.session, util.get_this_host(),
                               self.params['sr_uuid'], is_master)

            if is_master:
                # Schedule a scan only when attaching on the SRmaster
                util.set_dirty(sr.session, self.params["sr_ref"])

            return sr.attach(self.params['sr_uuid'])

        elif self.cmd == 'sr_detach':
            return sr.detach(self.params['sr_uuid'])

        elif self.cmd == 'sr_content_type':
            return sr.content_type(self.params['sr_uuid'])

        elif self.cmd == 'sr_scan':
            return sr.scan(self.params['sr_uuid'])

        else:
            util.SMlog("Unknown command: %s" % self.cmd)
            raise xs_errors.XenError('BadRequest')
Beispiel #7
0
    def _run(self, sr, target):
        dconf_type = sr.dconf.get("type")
        if not dconf_type or not NO_LOGGING.get(dconf_type) or \
                not self.cmd in NO_LOGGING[dconf_type]:
            if 'device_config' in self.params:
                util.SMlog("%s %s" % (self.cmd, util.hidePasswdInParams(self.params,'device_config')))
            else:
                util.SMlog("%s %s" % (self.cmd, repr(self.params)))

        caching_params = dict((k, self.params.get(k)) for k in \
                [blktap2.VDI.CONF_KEY_ALLOW_CACHING,
                 blktap2.VDI.CONF_KEY_MODE_ON_BOOT,
                 blktap2.VDI.CONF_KEY_CACHE_SR,
                 blktap2.VDI.CONF_KEY_O_DIRECT])

        if self.cmd == 'vdi_create':
            # These are the fields owned by the backend, passed on the
            # commandline:

            # LVM SRs store their metadata in XML format. XML does not support
            # all unicode characters, so we must check if the label or the
            # description contain such characters. We must enforce this
            # restriction to other SRs as well (even if they do allow these
            # characters) in order to be consistent.
            target.label = self.params['args'][1]
            target.description = self.params['args'][2]

            if not util.isLegalXMLString(target.label) \
                    or not util.isLegalXMLString(target.description):
                raise xs_errors.XenError('IllegalXMLChar', \
                        opterr = 'The name and/or description you supplied contains one or more unsupported characters. The name and/or description must contain valid XML characters. See http://www.w3.org/TR/2004/REC-xml-20040204/#charsets for more information.')

            target.ty = self.params['vdi_type']
            target.metadata_of_pool = self.params['args'][3]
            target.is_a_snapshot = self.params['args'][4] == "true"
            target.snapshot_time = self.params['args'][5]
            target.snapshot_of = self.params['args'][6]
            target.read_only = self.params['args'][7] == "true"

            return target.create(self.params['sr_uuid'], self.vdi_uuid, long(self.params['args'][0]))

        elif self.cmd == 'vdi_update':
            # Check for invalid XML characters, similar to VDI.create right
            # above.

            vdi_ref = sr.session.xenapi.VDI.get_by_uuid(self.vdi_uuid)
            name_label = sr.session.xenapi.VDI.get_name_label(vdi_ref)
            description = sr.session.xenapi.VDI.get_name_description(vdi_ref)

            if not util.isLegalXMLString(name_label) \
                    or not util.isLegalXMLString(description):
                raise xs_errors.XenError('IllegalXMLChar', \
                        opterr = 'The name and/or description you supplied contains one or more unsupported characters. The name and/or description must contain valid XML characters. See http://www.w3.org/TR/2004/REC-xml-20040204/#charsets for more information.')

            return target.update(self.params['sr_uuid'], self.vdi_uuid)

        elif self.cmd == 'vdi_introduce':
            target = sr.vdi(self.params['new_uuid'])
            return target.introduce(self.params['sr_uuid'], self.params['new_uuid'])

        elif self.cmd == 'vdi_delete':
            if 'VDI_CONFIG_CBT' in util.sr_get_capability(
                                        self.params['sr_uuid']): 
                return target.delete(self.params['sr_uuid'],
                                     self.vdi_uuid, data_only = False)
            else:
                return target.delete(self.params['sr_uuid'], self.vdi_uuid)

        elif self.cmd == 'vdi_attach':
            target = blktap2.VDI(self.vdi_uuid, target, self.driver_info)
            writable = self.params['args'][0] == 'true'
            return target.attach(self.params['sr_uuid'], self.vdi_uuid, writable, caching_params = caching_params)

        elif self.cmd == 'vdi_detach':
            target = blktap2.VDI(self.vdi_uuid, target, self.driver_info)
            return target.detach(self.params['sr_uuid'], self.vdi_uuid)

        elif self.cmd == 'vdi_snapshot':
            return target.snapshot(self.params['sr_uuid'], self.vdi_uuid)

        elif self.cmd == 'vdi_clone':
            return target.clone(self.params['sr_uuid'], self.vdi_uuid)            

        elif self.cmd == 'vdi_resize':
            return target.resize(self.params['sr_uuid'], self.vdi_uuid, long(self.params['args'][0]))

        elif self.cmd == 'vdi_resize_online':
            return target.resize_online(self.params['sr_uuid'], self.vdi_uuid, long(self.params['args'][0]))
        
        elif self.cmd == 'vdi_activate':
            target = blktap2.VDI(self.vdi_uuid, target, self.driver_info)
            writable = self.params['args'][0] == 'true'
            return target.activate(self.params['sr_uuid'], self.vdi_uuid,
                                   writable, caching_params)

        elif self.cmd == 'vdi_deactivate':
            target = blktap2.VDI(self.vdi_uuid, target, self.driver_info)
            return target.deactivate(self.params['sr_uuid'], self.vdi_uuid,
                    caching_params)

        elif self.cmd == 'vdi_epoch_begin':
            if caching_params.get(blktap2.VDI.CONF_KEY_MODE_ON_BOOT) != "reset":
                return
            if not "VDI_RESET_ON_BOOT/2" in self.driver_info['capabilities']:
                raise xs_errors.XenError('Unimplemented')
            return target.reset_leaf(self.params['sr_uuid'], self.vdi_uuid)

        elif self.cmd == 'vdi_epoch_end':
            return

        elif self.cmd == 'vdi_generate_config':
            return target.generate_config(self.params['sr_uuid'], self.vdi_uuid)

        elif self.cmd == 'vdi_compose':
            vdi1_uuid = sr.session.xenapi.VDI.get_uuid(self.params['args'][0])
            return target.compose(self.params['sr_uuid'], vdi1_uuid, self.vdi_uuid)

        elif self.cmd == 'vdi_attach_from_config':
            ret = target.attach_from_config(self.params['sr_uuid'], self.vdi_uuid)
            if not target.sr.driver_config.get("ATTACH_FROM_CONFIG_WITH_TAPDISK"):
                return ret
            target = blktap2.VDI(self.vdi_uuid, target, self.driver_info)
            return target.attach(self.params['sr_uuid'], self.vdi_uuid, True, True)

        elif self.cmd == 'vdi_detach_from_config':
            extras= {}
            if target.sr.driver_config.get("ATTACH_FROM_CONFIG_WITH_TAPDISK"):
                target = blktap2.VDI(self.vdi_uuid, target, self.driver_info)
                extras['deactivate'] = True
                extras['caching_params'] = caching_params
            target.detach(self.params['sr_uuid'], self.vdi_uuid, **extras)

        elif self.cmd == 'vdi_enable_cbt':
            return target.configure_blocktracking(self.params['sr_uuid'],
                                                  self.vdi_uuid, True)

        elif self.cmd == 'vdi_disable_cbt':
            return target.configure_blocktracking(self.params['sr_uuid'],
                                                  self.vdi_uuid, False)

        elif self.cmd == 'vdi_data_destroy':
            return target.data_destroy(self.params['sr_uuid'], self.vdi_uuid)

        elif self.cmd == 'vdi_list_changed_blocks':
            return target.list_changed_blocks()

        elif self.cmd == 'sr_create':
            return sr.create(self.params['sr_uuid'], long(self.params['args'][0]))

        elif self.cmd == 'sr_delete':
            return sr.delete(self.params['sr_uuid'])

        elif self.cmd == 'sr_update':
            return sr.update(self.params['sr_uuid'])

        elif self.cmd == 'sr_probe':
            txt = sr.probe()
            util.SMlog( "sr_probe result: %s" % util.splitXmlText( txt, showContd=True ) )
            # return the XML document as a string
            return xmlrpclib.dumps((txt,), "", True)

        elif self.cmd == 'sr_attach':
            is_master = False
            if sr.dconf.get("SRmaster") == "true":
                is_master = True

            resetvdis.reset_sr(sr.session, util.get_this_host(),
                    self.params['sr_uuid'], is_master)

            if is_master:
                # Schedule a scan only when attaching on the SRmaster
                util.set_dirty(sr.session, self.params["sr_ref"])

            return sr.attach(self.params['sr_uuid'])

        elif self.cmd == 'sr_detach':
            return sr.detach(self.params['sr_uuid'])

        elif self.cmd == 'sr_content_type':
            return sr.content_type(self.params['sr_uuid'])        

        elif self.cmd == 'sr_scan':
            return sr.scan(self.params['sr_uuid'])

        else:
            util.SMlog("Unknown command: %s" % self.cmd)
            raise xs_errors.XenError('BadRequest')