diff -r 5c30a9dec02d tools/python/xen/xend/XendAPI.py --- a/tools/python/xen/xend/XendAPI.py Wed Jan 30 18:39:04 2008 +0000 +++ b/tools/python/xen/xend/XendAPI.py Thu Jan 31 13:00:50 2008 +0800 @@ -1985,7 +1985,8 @@ class XendAPI(object): VIF_attr_inst = VIF_attr_rw - VIF_methods = [('destroy', None)] + VIF_methods = [('destroy', None), + ('vmq_ctrl', None)] VIF_funcs = [('create', 'VIF')] @@ -2032,6 +2033,14 @@ class XendAPI(object): return xen_api_error(['HANDLE_INVALID', 'VIF', vif_ref]) vm.destroy_vif(vif_ref) + return xen_api_success_void() + + def VIF_vmq_ctrl(self, session, vif_ref, nic): + xendom = XendDomain.instance() + vm = xendom.get_vm_with_dev_uuid('vif', vif_ref) + if not vm: + return xen_api_error(['HANDLE_INVALID', 'VIF', vif_ref]) + vm.xenapi_vmq_ctrl(vif_ref, nic) return xen_api_success_void() def _VIF_get(self, ref, prop): diff -r 5c30a9dec02d tools/python/xen/xend/XendDomainInfo.py --- a/tools/python/xen/xend/XendDomainInfo.py Wed Jan 30 18:39:04 2008 +0000 +++ b/tools/python/xen/xend/XendDomainInfo.py Thu Jan 31 13:00:54 2008 +0800 @@ -667,6 +667,10 @@ class XendDomainInfo: if dev_info: return dev_info[0] + def vmq_ctrl(self, devid, nic): + if self.domid is not None: + self.getDeviceController('vif').netif_vmq(devid, nic) + def _getDeviceInfo_vif(self, mac): for dev_type, dev_info in self.info.all_devices_sxpr(): if dev_type != 'vif': @@ -2893,6 +2897,19 @@ class XendDomainInfo: def has_device(self, dev_class, dev_uuid): return (dev_uuid in self.info['%s_refs' % dev_class.lower()]) + def xenapi_vmq_ctrl(self, dev_uuid, nic): + if dev_uuid not in self.info['devices']: + raise XendError('Device does not exist') + + if self._stateGet() in (XEN_API_VM_POWER_STATE_RUNNING, + XEN_API_VM_POWER_STATE_PAUSED): + _, config = self.info['devices'][dev_uuid] + devid = config.get('devid') + if devid != None: + self.getDeviceController('vif').netif_vmq(devid, nic) + else: + raise XendError('Unable to get devid for device: vif:%s' % dev_uuid) + def __str__(self): return '' % \ (str(self.domid), self.info['name_label'], diff -r 5c30a9dec02d tools/python/xen/xend/server/XMLRPCServer.py --- a/tools/python/xen/xend/server/XMLRPCServer.py Wed Jan 30 18:39:04 2008 +0000 +++ b/tools/python/xen/xend/server/XMLRPCServer.py Thu Jan 31 12:37:22 2008 +0800 @@ -87,7 +87,7 @@ methods = ['device_create', 'device_conf 'destroyDevice','getDeviceSxprs', 'setMemoryTarget', 'setName', 'setVCpuCount', 'shutdown', 'send_sysrq', 'getVCPUInfo', 'waitForDevices', - 'getRestartCount', 'getBlockDeviceClass'] + 'getRestartCount', 'getBlockDeviceClass', 'vmq_ctrl'] exclude = ['domain_create', 'domain_restore'] diff -r 5c30a9dec02d tools/python/xen/xend/server/netif.py --- a/tools/python/xen/xend/server/netif.py Wed Jan 30 18:39:04 2008 +0000 +++ b/tools/python/xen/xend/server/netif.py Thu Jan 31 15:34:32 2008 +0800 @@ -25,7 +25,7 @@ import re import re from xen.xend import XendOptions -from xen.xend.server.DevController import DevController +from xen.xend.server.DevController import DevController, Connected, Error from xen.xend.XendError import VmError from xen.xend.XendXSPolicyAdmin import XSPolicyAdminInstance import xen.util.xsm.xsm as security @@ -91,6 +91,12 @@ def parseRate(ratestr): interval_usecs = 0L return "%lu,%lu" % (bytes_per_interval, interval_usecs) + +def do_vmq_ctrl(cmd, vmq, mac = None, vif = None): + log.debug("vmq: %s, %s, %s, %s" % (cmd, vmq, mac, vif)) + # XXX need an interface here + # return os.system("vmq_ctrl " + cmd + " " + vmq + " " + mac) + return 0 class NetifController(DevController): @@ -114,6 +120,7 @@ class NetifController(DevController): model = config.get('model') accel = config.get('accel') sec_lab = config.get('security_label') + vmq = config.get('vmq') if not mac: raise VmError("MAC address not specified or generated.") @@ -140,6 +147,8 @@ class NetifController(DevController): back['accel'] = accel if sec_lab: back['security_label'] = sec_lab + if vmq: + back['vmq'] = vmq config_path = "device/%s/%d/" % (self.deviceClass, devid) for x in back: @@ -192,14 +201,14 @@ class NetifController(DevController): devinfo = () for x in ( 'script', 'ip', 'bridge', 'mac', 'type', 'vifname', 'rate', 'uuid', 'model', 'accel', - 'security_label'): + 'security_label', 'vmq'): if transaction is None: y = self.vm._readVm(config_path + x) else: y = self.vm._readVmTxn(transaction, config_path + x) devinfo += (y,) (script, ip, bridge, mac, typ, vifname, rate, uuid, - model, accel, security_label) = devinfo + model, accel, security_label, vmq) = devinfo if script: result['script'] = script @@ -223,5 +232,59 @@ class NetifController(DevController): result['accel'] = accel if security_label: result['security_label'] = security_label + if vmq: + result['vmq'] = vmq return result + + def destroyDevice(self, devid, force): + + dev = self.convertToDeviceNumber(devid) + vmq = self.readBackend(dev, 'vmq') + if vmq: + mac = self.readBackend(dev, 'mac') + do_vmq_ctrl("del", vmq, mac) + self.writeBackend(dev, 'vmq', "") + + return DevController.destroyDevice(self, devid, force) + + def waitForBackend(self, devid): + + (status, err) = DevController.waitForBackend(self, devid) + if status == Connected: + dev = self.convertToDeviceNumber(devid) + vmq = self.readBackend(dev, 'vmq') + if vmq: + mac = self.readBackend(dev, 'mac') + vif = self.readBackend(dev, 'vifname') + if not vif: + vif = "vif%s.%s" % (self.vm.getDomid(), devid) + if do_vmq_ctrl("add", vmq, mac, vif): + self.writeBackend(dev, 'vmq', "") + return (Error, "Canno create VM queue on %s." % vmq) + + return (status, err) + + def netif_vmq(self, devid, vmq): + + dev = self.convertToDeviceNumber(devid) + mac = self.readBackend(dev, 'mac') + + if vmq is not None: + if self.readBackend(dev, 'vmq'): + raise VmError("VM queue has already configured on vif:%s" % devid) + vif = self.readBackend(dev, 'vifname') + if not vif: + vif = "vif%s.%s" % (self.vm.getDomid(), devid) + if do_vmq_ctrl("add", vmq, mac, vif): + self.writeBackend(dev, 'vmq', "") + raise VmError("Cannot create VM queue on %s." % vmq) + + self.writeBackend(dev, 'vmq', vmq) + else: + vmq = self.readBackend(dev, 'vmq') + if vmq: + do_vmq_ctrl("del", vmq, mac) + self.writeBackend(dev, 'vmq', "") + else: + raise VmError("VM queue has not configured on vif:%s" % devid) diff -r 5c30a9dec02d tools/python/xen/xm/create.py --- a/tools/python/xen/xm/create.py Wed Jan 30 18:39:04 2008 +0000 +++ b/tools/python/xen/xm/create.py Thu Jan 31 12:36:22 2008 +0800 @@ -323,7 +323,7 @@ gopts.var('vfb', val="type={vnc,sdl},vnc ones.""") gopts.var('vif', val="type=TYPE,mac=MAC,bridge=BRIDGE,ip=IPADDR,script=SCRIPT," + \ - "backend=DOM,vifname=NAME,rate=RATE,model=MODEL,accel=ACCEL", + "backend=DOM,vifname=NAME,rate=RATE,model=MODEL,accel=ACCEL,vmq=NIC", fn=append_value, default=[], use="""Add a network interface with the given MAC address and bridge. The vif is configured by calling the given configuration script. @@ -338,6 +338,7 @@ gopts.var('vif', val="type=TYPE,mac=MAC, If rate is not specified the default rate is used. If model is not specified the default model is used. If accel is not specified an accelerator plugin module is not used. + If vmq is not specified NIC VM queue function is not used. This option may be repeated to add more than one vif. Specifying vifs will increase the number of interfaces as needed.""") @@ -715,7 +716,7 @@ def configure_vifs(config_devs, vals): def f(k): if k not in ['backend', 'bridge', 'ip', 'mac', 'script', 'type', - 'vifname', 'rate', 'model', 'accel', + 'vifname', 'rate', 'model', 'accel', 'vmq', 'policy', 'label']: err('Invalid vif option: ' + k) diff -r 5c30a9dec02d tools/python/xen/xm/main.py --- a/tools/python/xen/xm/main.py Wed Jan 30 18:39:04 2008 +0000 +++ b/tools/python/xen/xm/main.py Thu Jan 31 14:26:56 2008 +0800 @@ -164,13 +164,15 @@ SUBCOMMAND_HELP = { 'List virtual block devices for a domain.'), 'network-attach': (' [type=] [mac=] [bridge=] ' '[ip=] [script=