devcontroller.py

来自「xen虚拟机源代码安装包」· Python 代码 · 共 695 行 · 第 1/2 页

PY
695
字号
    def setupDevice(self, config):        """ Setup device from config.        """        return    def migrate(self, deviceConfig, network, dst, step, domName):        """ Migration of a device. The 'network' parameter indicates            whether the device is network-migrated (True). 'dst' then gives            the hostname of the machine to migrate to.        This function is called for 4 steps:        If step == 0: Check whether the device is ready to be migrated                      or can at all be migrated; return a '-1' if                      the device is NOT ready, a '0' otherwise. If it is                      not ready ( = not possible to migrate this device),                      migration will not take place.           step == 1: Called immediately after step 0; migration                      of the kernel has started;           step == 2: Called after the suspend has been issued                      to the domain and the domain is not scheduled anymore.                      Synchronize with what was started in step 1, if necessary.                      Now the device should initiate its transfer to the                      given target. Since there might be more than just                      one device initiating a migration, this step should                      put the process performing the transfer into the                      background and return immediately to achieve as much                      concurrency as possible.           step == 3: Synchronize with the migration of the device that                      was initiated in step 2.                      Make sure that the migration has finished and only                      then return from the call.        """        tool = xoptions.get_external_migration_tool()        if tool:            log.info("Calling external migration tool for step %d" % step)            fd = os.popen("%s -type %s -step %d -host %s -domname %s" %                          (tool, self.deviceClass, step, dst, domName))            for line in fd:                log.info(line.rstrip())            rc = fd.close()            if rc:                raise VmError('Migration tool returned %d' % (rc >> 8))        return 0    def recover_migrate(self, deviceConfig, network, dst, step, domName):        """ Recover from device migration. The given step was the            last one that was successfully executed.        """        tool = xoptions.get_external_migration_tool()        if tool:            log.info("Calling external migration tool")            fd = os.popen("%s -type %s -step %d -host %s -domname %s -recover" %                          (tool, self.deviceClass, step, dst, domName))            for line in fd:                log.info(line.rstrip())            rc = fd.close()            if rc:                raise VmError('Migration tool returned %d' % (rc >> 8))        return 0    def getDomid(self):        """Stub to {@link XendDomainInfo.getDomid}, for use by our        subclasses.        """        return self.vm.getDomid()    def allocateDeviceID(self):        """Allocate a device ID, allocating them consecutively on a        per-domain, per-device-class basis, and using the store to record the        next available ID.        This method is available to our subclasses, though it is not        compulsory to use it; subclasses may prefer to allocate IDs based upon        the device configuration instead.        """        path = self.frontendMiscPath()        return complete(path, self._allocateDeviceID)    def _allocateDeviceID(self, t):        result = t.read("nextDeviceID")        if result:            result = int(result)        else:            result = 0        t.write("nextDeviceID", str(result + 1))        return result    def removeBackend(self, devid, *args):        frontpath = self.frontendPath(devid)        backpath = xstransact.Read(frontpath, "backend")        if backpath:            return xstransact.Remove(backpath, *args)        else:            raise VmError("Device %s not connected" % devid)    def readBackend(self, devid, *args):        frontpath = self.frontendPath(devid)        backpath = xstransact.Read(frontpath, "backend")        if backpath:            return xstransact.Read(backpath, *args)        else:            raise VmError("Device %s not connected" % devid)    def readBackendTxn(self, transaction, devid, *args):        frontpath = self.frontendPath(devid)        backpath = transaction.read(frontpath + "/backend")        if backpath:            paths = map(lambda x: backpath + "/" + x, args)            return transaction.read(*paths)        else:            raise VmError("Device %s not connected" % devid)    def readFrontend(self, devid, *args):        return xstransact.Read(self.frontendPath(devid), *args)    def readFrontendTxn(self, transaction, devid, *args):        paths = map(lambda x: self.frontendPath(devid) + "/" + x, args)        return transaction.read(*paths)    def deviceIDs(self, transaction = None):        """@return The IDs of each of the devices currently configured for        this instance's deviceClass.        """        fe = self.backendRoot()        if transaction:            return map(lambda x: int(x.split('/')[-1]), transaction.list(fe))        else:            return map(int, xstransact.List(fe))    def writeBackend(self, devid, *args):        frontpath = self.frontendPath(devid)        backpath = xstransact.Read(frontpath, "backend")        if backpath:            xstransact.Write(backpath, *args)        else:            raise VmError("Device %s not connected" % devid)## private:    def addStoreEntries(self, config, devid, backDetails, frontDetails):        """Add to backDetails and frontDetails the entries to be written in        the store to trigger creation of a device.  The backend domain ID is        taken from the given config, paths for frontend and backend are        computed, and these are added to the backDetails and frontDetails        dictionaries for writing to the store, including references from        frontend to backend and vice versa.        @return A pair of (backpath, frontpath).  backDetails and frontDetails        will have been updated appropriately, also.        @param config The configuration of the device, as given to        {@link #createDevice}.        @param devid        As returned by {@link #getDeviceDetails}.        @param backDetails  As returned by {@link #getDeviceDetails}.        @param frontDetails As returned by {@link #getDeviceDetails}.        """        import xen.xend.XendDomain        xd = xen.xend.XendDomain.instance()        backdom_name = config.get('backend')        if backdom_name:            backdom = xd.domain_lookup_nr(backdom_name)        else:            backdom = xd.privilegedDomain()        if not backdom:            raise VmError("Cannot configure device for unknown backend %s" %                          backdom_name)        frontpath = self.frontendPath(devid)        backpath  = self.backendPath(backdom, devid)                frontDetails.update({            'backend' : backpath,            'backend-id' : "%i" % backdom.getDomid(),            'state' : str(xenbusState['Initialising'])            })        if self.vm.native_protocol:            frontDetails.update({'protocol' : self.vm.native_protocol})        backDetails.update({            'domain' : self.vm.getName(),            'frontend' : frontpath,            'frontend-id' : "%i" % self.vm.getDomid(),            'state' : str(xenbusState['Initialising']),            'online' : "1"            })        return (backpath, frontpath)    def waitForBackend(self, devid):        frontpath = self.frontendPath(devid)        # lookup a phantom         phantomPath = xstransact.Read(frontpath, 'phantom_vbd')        if phantomPath is not None:            log.debug("Waiting for %s's phantom %s.", devid, phantomPath)            statusPath = phantomPath + '/' + HOTPLUG_STATUS_NODE            ev = Event()            result = { 'status': Timeout }            xswatch(statusPath, hotplugStatusCallback, ev, result)            ev.wait(DEVICE_CREATE_TIMEOUT)            err = xstransact.Read(statusPath, HOTPLUG_ERROR_NODE)            if result['status'] != 'Connected':                return (result['status'], err)                    backpath = xstransact.Read(frontpath, "backend")        if backpath:            statusPath = backpath + '/' + HOTPLUG_STATUS_NODE            ev = Event()            result = { 'status': Timeout }            xswatch(statusPath, hotplugStatusCallback, ev, result)            ev.wait(DEVICE_CREATE_TIMEOUT)            err = xstransact.Read(backpath, HOTPLUG_ERROR_NODE)            return (result['status'], err)        else:            return (Missing, None)    def waitForBackend_destroy(self, backpath):        statusPath = backpath + '/' + HOTPLUG_STATUS_NODE        ev = Event()        result = { 'status': Timeout }        xswatch(statusPath, deviceDestroyCallback, ev, result)        ev.wait(DEVICE_DESTROY_TIMEOUT)        return result['status']    def waitForBackend_reconfigure(self, devid):        frontpath = self.frontendPath(devid)        backpath = xstransact.Read(frontpath, "backend")        if backpath:            statusPath = backpath + '/' + "state"            ev = Event()            result = { 'status': Timeout }            xswatch(statusPath, xenbusStatusCallback, ev, result)            ev.wait(DEVICE_CREATE_TIMEOUT)            return (result['status'], None)        else:            return (Missing, None)    def backendPath(self, backdom, devid):        """Construct backend path given the backend domain and device id.        @param backdom [XendDomainInfo] The backend domain info."""        return "%s/backend/%s/%s/%d" % (backdom.getDomainPath(),                                        self.deviceClass,                                        self.vm.getDomid(), devid)    def frontendPath(self, devid):        return "%s/%d" % (self.frontendRoot(), devid)    def frontendRoot(self):        return "%s/device/%s" % (self.vm.getDomainPath(), self.deviceClass)    def backendRoot(self):        """Construct backend root path assuming backend is domain 0."""        from xen.xend.XendDomain import DOM0_ID        from xen.xend.xenstore.xsutil import GetDomainPath        return "%s/backend/%s/%s" % (GetDomainPath(DOM0_ID),                                     self.deviceClass, self.vm.getDomid())    def frontendMiscPath(self):        return "%s/device-misc/%s" % (self.vm.getDomainPath(),                                      self.deviceClass)def hotplugStatusCallback(statusPath, ev, result):    log.debug("hotplugStatusCallback %s.", statusPath)    status = xstransact.Read(statusPath)    if status is not None:        if status == HOTPLUG_STATUS_ERROR:            result['status'] = Error        elif status == HOTPLUG_STATUS_BUSY:            result['status'] = Busy        else:            result['status'] = Connected    else:        return 1    log.debug("hotplugStatusCallback %d.", result['status'])    ev.set()    return 0def deviceDestroyCallback(statusPath, ev, result):    log.debug("deviceDestroyCallback %s.", statusPath)    status = xstransact.Read(statusPath)    if status is None:        result['status'] = Disconnected    else:        return 1    log.debug("deviceDestroyCallback %d.", result['status'])    ev.set()    return 0def xenbusStatusCallback(statusPath, ev, result):    log.debug("xenbusStatusCallback %s.", statusPath)    status = xstransact.Read(statusPath)    if status == str(xenbusState['Connected']):        result['status'] = Connected    else:        return 1    log.debug("xenbusStatusCallback %d.", result['status'])    ev.set()    return 0

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?