diff --git a/xend/XendDomain.py b/xend/XendDomain.py index 55e8380..17e0d85 100644 --- a/xend/XendDomain.py +++ b/xend/XendDomain.py @@ -48,6 +48,7 @@ from xen.xend.XendConstants import DOM_STATE_CRASHED, HVM_PARAM_ACPI_S_STATE from xen.xend.XendConstants import TRIGGER_TYPE, TRIGGER_S3RESUME from xen.xend.XendDevices import XendDevices from xen.xend.XendAPIConstants import * +from xen.xend.server.netif import parseRate from xen.xend.xenstore.xstransact import xstransact from xen.xend.xenstore.xswatch import xswatch @@ -1541,7 +1542,6 @@ class XendDomain: else: log.debug("error: Domain is not running!") - def domain_usb_del(self, domid, dev_id): dominfo = self.domain_lookup_nr(domid) if not dominfo: @@ -1561,6 +1561,27 @@ class XendDomain: else: log.debug("error: Domain is not running!") + + def domain_set_xen_rate(self, domid, vif_name,xen_rate): + log.debug("resetting xen rate limit...") + dominfo = self.domain_lookup_nr(domid) + vifs= [x for x in dominfo.info['vif_refs'] + if dominfo.info['devices'][x][1]['vifname'] == vif_name] + if not vifs: + msg="vif %s doesn't exist"% vif_name + log.error(msg) + raise VmError(msg) + + devinfo = dominfo.info['devices'][vifs[0]] + try: + status=dominfo.getDeviceController(devinfo[0]).set_xen_rate(domid,devinfo[1],xen_rate) + if status ==0 : + log.info("succeed to reset xen rate") + else: + raise VmError("failed to reset xen rate" ) + except Exception, e: + raise VmError("failed to reset xen rate exception") + def domain_pincpu(self, domid, vcpu, cpumap): """Set which cpus vcpu can use diff --git a/xend/server/SrvDomain.py b/xend/server/SrvDomain.py index 77df314..1b0dfb2 100644 --- a/xend/server/SrvDomain.py +++ b/xend/server/SrvDomain.py @@ -225,6 +225,13 @@ class SrvDomain(SrvDir): self.acceptCommand(req) return self.xd.domain_reset(self.dom.getName()) + def op_set_xen_rate(self, op, req): + self.acceptCommand(req) + return req.threadRequest(self.do_set_xen_rate, op, req) + + def do_set_xen_rate(self, _, req): + return self.xd.domain_set_xen_rate(self.dom.getName(), req) + def op_usb_add(self, op, req): self.acceptCommand(req) return req.threadRequest(self.do_usb_add, op, req) diff --git a/xend/server/netif.py b/xend/server/netif.py index 8eb62b4..ca672a3 100644 --- a/xend/server/netif.py +++ b/xend/server/netif.py @@ -23,13 +23,17 @@ import os import random import re +import xen.xend.XendDomain +from xen.xend.xenstore.xswatch import xswatch +from threading import Event from xen.xend import XendOptions, sxp from xen.xend.server.DevController import DevController from xen.xend.XendError import VmError from xen.xend.XendXSPolicyAdmin import XSPolicyAdminInstance import xen.util.xsm.xsm as security from xen.util import xsconstants +from xen.xend.xenstore.xstransact import xstransact from xen.xend.XendLogging import log @@ -279,4 +283,38 @@ class NetifController(DevController): log.debug("delete tx rate (dev : %s, cmd : %s)", dev, cmd) os.system(cmd) self.removeBackend(dev, 'tx_rate') - + + def set_xen_rate(self,domid, config, limit): + xen_rate = parseRate(limit); + devid = self.convertToDeviceNumber(config['devid']) + + self.writeBackend(devid, 'rate_status','unchanged') + + ev=Event() + + result={'status':-1} + + backdom_name = xen.xend.XendDomain.instance().privilegedDomain() + statusPath=self.backendPath(backdom_name,devid)+'/rate_status' + + xswatch(statusPath, rateChangedCallback,devid,ev, result) + self.writeBackend(devid, 'rate', xen_rate) + ev.wait(50) + + self.removeBackend(devid,'rate_status') + return result['status'] + +def rateChangedCallback(statusPath,devid,ev,result): + status=xstransact.Read(statusPath) + if status is not None: + if status == 'changed': + result['status']=0 + else: + result['status']=-1 + return 1 + else: + result['status']=-1 + return 1 + + ev.set() + return 0 diff --git a/xm/main.py b/xm/main.py index 9cb7b0e..cb9550d 100644 --- a/xm/main.py +++ b/xm/main.py @@ -117,6 +117,8 @@ SUBCOMMAND_HELP = { 'Set the rx rate for a vif.'), 'tx-rate-set' : (' ', 'Set the tx rate for a vif.'), + 'xen-rate-set' : (' ', + 'Set the xen rate for a vif.'), 'migrate' : (' ', 'Migrate a domain to another machine.'), 'pause' : ('', 'Pause execution of a domain.'), @@ -360,6 +362,7 @@ common_commands = [ "mem-set", "rx-rate-set", "tx-rate-set", + "xen-rate-set", "migrate", "pause", "reboot", @@ -394,6 +397,7 @@ domain_commands = [ "mem-set", "rx-rate-set", "tx-rate-set", + "xen-rate-set", "migrate", "pause", "reboot", @@ -1545,6 +1549,19 @@ def xm_tx_rate_set(args): else: server.xend.domain.setTxRate(dom, vifname, tx_rate) +def xm_xen_rate_set(args): + arg_check(args, "xen-rate-set", 3) + + dom = args[0] + vifname = args[1] + xen_rate = args[2] + + if serverType == SERVER_XEN_API: + #TODO: add tx rate support + print "SERVER_XEN_API" + else: + server.xend.domain.set_xen_rate(dom, vifname, xen_rate) + def xm_usb_add(args): arg_check(args, "usb-add", 2) server.xend.domain.usb_add(args[0],args[1]) @@ -3509,6 +3526,7 @@ commands = { # rate "rx-rate-set": xm_rx_rate_set, "tx-rate-set": xm_tx_rate_set, + "xen-rate-set": xm_xen_rate_set, # cpu commands "vcpu-pin": xm_vcpu_pin, "vcpu-list": xm_vcpu_list,