summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Garbutt <john.garbutt@rackspace.com>2013-11-15 15:44:26 +0000
committerJohn Garbutt <john.garbutt@rackspace.com>2014-01-03 13:27:50 +0000
commit3c25a3fe3ffeb899d6a8c93549988ea38750468b (patch)
treed33c28e5b4776c0ca0b666116b7943d461068c7e
parent01f85bdc057376708a1c1cca65bbcc85af494bfa (diff)
downloadnova-3c25a3fe3ffeb899d6a8c93549988ea38750468b.tar.gz
xenapi: add support for vcpu_pin_set
This moves vcpu_pin_set config from the libvirt driver into a place that can be shared between drivers, nova.virt.cpu At the same time, the utility function that converts the configuration value into a list of integers has also been moved into nova.virt.cpu This new code is then used in the XenAPI driver to apply a CPU mask that implements the currently configured value for vcpu_pin_set The main use case for this setting is to ensure all guest VMs are not using the physical CPUs that Dom0 are configured to use. DocImpact Completes blueprint xenapi-vcpu-pin-set Change-Id: I9d53d93db0c5f2a11ad685d3fc335f0cd6b1f79b
-rw-r--r--etc/nova/nova.conf.sample13
-rw-r--r--nova/tests/virt/libvirt/test_libvirt.py100
-rw-r--r--nova/tests/virt/test_cpu.py110
-rw-r--r--nova/tests/virt/xenapi/test_vm_utils.py94
-rw-r--r--nova/virt/cpu.py88
-rw-r--r--nova/virt/libvirt/driver.py62
-rw-r--r--nova/virt/xenapi/vm_utils.py6
7 files changed, 280 insertions, 193 deletions
diff --git a/etc/nova/nova.conf.sample b/etc/nova/nova.conf.sample
index 5856a03d36..efcec13a73 100644
--- a/etc/nova/nova.conf.sample
+++ b/etc/nova/nova.conf.sample
@@ -1884,6 +1884,15 @@
#
+# Options defined in nova.virt.cpu
+#
+
+# Which pcpus can be used by vcpus of instance e.g:
+# "4-12,^8,15" (string value)
+#vcpu_pin_set=<None>
+
+
+#
# Options defined in nova.virt.disk.api
#
@@ -2593,10 +2602,6 @@
# file=directsync,block=none (list value)
#disk_cachemodes=
-# Which pcpus can be used by vcpus of instance e.g:
-# "4-12,^8,15" (string value)
-#vcpu_pin_set=<None>
-
#
# Options defined in nova.virt.libvirt.imagebackend
diff --git a/nova/tests/virt/libvirt/test_libvirt.py b/nova/tests/virt/libvirt/test_libvirt.py
index 754a5d0a3d..e6370dec2e 100644
--- a/nova/tests/virt/libvirt/test_libvirt.py
+++ b/nova/tests/virt/libvirt/test_libvirt.py
@@ -7494,106 +7494,6 @@ class LibvirtDriverTestCase(test.TestCase):
self.libvirtconnection.get_instance_disk_info,
instance_name)
- def test_get_cpuset_ids(self):
- # correct syntax
- self.flags(vcpu_pin_set="1", group='libvirt')
- cpuset_ids = self.libvirtconnection._get_cpuset_ids()
- self.assertEqual([1], cpuset_ids)
-
- self.flags(vcpu_pin_set="1,2", group='libvirt')
- cpuset_ids = self.libvirtconnection._get_cpuset_ids()
- self.assertEqual([1, 2], cpuset_ids)
-
- self.flags(vcpu_pin_set=", , 1 , ,, 2, ,", group='libvirt')
- cpuset_ids = self.libvirtconnection._get_cpuset_ids()
- self.assertEqual([1, 2], cpuset_ids)
-
- self.flags(vcpu_pin_set="1-1", group='libvirt')
- cpuset_ids = self.libvirtconnection._get_cpuset_ids()
- self.assertEqual([1], cpuset_ids)
-
- self.flags(vcpu_pin_set=" 1 - 1, 1 - 2 , 1 -3", group='libvirt')
- cpuset_ids = self.libvirtconnection._get_cpuset_ids()
- self.assertEqual([1, 2, 3], cpuset_ids)
-
- self.flags(vcpu_pin_set="1,^2", group='libvirt')
- cpuset_ids = self.libvirtconnection._get_cpuset_ids()
- self.assertEqual([1], cpuset_ids)
-
- self.flags(vcpu_pin_set="1-2, ^1", group='libvirt')
- cpuset_ids = self.libvirtconnection._get_cpuset_ids()
- self.assertEqual([2], cpuset_ids)
-
- self.flags(vcpu_pin_set="1-3,5,^2", group='libvirt')
- cpuset_ids = self.libvirtconnection._get_cpuset_ids()
- self.assertEqual([1, 3, 5], cpuset_ids)
-
- self.flags(vcpu_pin_set=" 1 - 3 , ^2, 5",
- group='libvirt')
- cpuset_ids = self.libvirtconnection._get_cpuset_ids()
- self.assertEqual([1, 3, 5], cpuset_ids)
-
- # invalid syntax
- self.flags(vcpu_pin_set=" -1-3,5,^2", group='libvirt')
- self.assertRaises(exception.Invalid,
- self.libvirtconnection._get_cpuset_ids)
-
- self.flags(vcpu_pin_set="1-3-,5,^2", group='libvirt')
- self.assertRaises(exception.Invalid,
- self.libvirtconnection._get_cpuset_ids)
-
- self.flags(vcpu_pin_set="-3,5,^2", group='libvirt')
- self.assertRaises(exception.Invalid,
- self.libvirtconnection._get_cpuset_ids)
-
- self.flags(vcpu_pin_set="1-,5,^2", group='libvirt')
- self.assertRaises(exception.Invalid,
- self.libvirtconnection._get_cpuset_ids)
-
- self.flags(vcpu_pin_set="1-3,5,^2^", group='libvirt')
- self.assertRaises(exception.Invalid,
- self.libvirtconnection._get_cpuset_ids)
-
- self.flags(vcpu_pin_set="1-3,5,^2-", group='libvirt')
- self.assertRaises(exception.Invalid,
- self.libvirtconnection._get_cpuset_ids)
-
- self.flags(vcpu_pin_set="--13,^^5,^2", group='libvirt')
- self.assertRaises(exception.Invalid,
- self.libvirtconnection._get_cpuset_ids)
-
- self.flags(vcpu_pin_set="a-3,5,^2", group='libvirt')
- self.assertRaises(exception.Invalid,
- self.libvirtconnection._get_cpuset_ids)
-
- self.flags(vcpu_pin_set="1-a,5,^2", group='libvirt')
- self.assertRaises(exception.Invalid,
- self.libvirtconnection._get_cpuset_ids)
-
- self.flags(vcpu_pin_set="1-3,b,^2", group='libvirt')
- self.assertRaises(exception.Invalid,
- self.libvirtconnection._get_cpuset_ids)
-
- self.flags(vcpu_pin_set="1-3,5,^c", group='libvirt')
- self.assertRaises(exception.Invalid,
- self.libvirtconnection._get_cpuset_ids)
-
- self.flags(vcpu_pin_set="3 - 1, 5 , ^ 2 ", group='libvirt')
- self.assertRaises(exception.Invalid,
- self.libvirtconnection._get_cpuset_ids)
-
- self.flags(vcpu_pin_set=" 1,1, ^1", group='libvirt')
- self.assertRaises(exception.Invalid,
- self.libvirtconnection._get_cpuset_ids)
-
- self.flags(vcpu_pin_set=" 1,^1,^1,2, ^2", group='libvirt')
- self.assertRaises(exception.Invalid,
- self.libvirtconnection._get_cpuset_ids)
-
- self.flags(vcpu_pin_set="^2", group='libvirt')
- self.assertRaises(exception.Invalid,
- self.libvirtconnection._get_cpuset_ids)
-
class LibvirtVolumeUsageTestCase(test.TestCase):
"""Test for LibvirtDriver.get_all_volume_usage."""
diff --git a/nova/tests/virt/test_cpu.py b/nova/tests/virt/test_cpu.py
new file mode 100644
index 0000000000..fb97c408a9
--- /dev/null
+++ b/nova/tests/virt/test_cpu.py
@@ -0,0 +1,110 @@
+# vim: tabstop=4 shiftwidth=4 softtabstop=4
+
+# Copyright 2013 OpenStack Foundation
+# All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+from nova import exception
+from nova import test
+from nova.virt import cpu
+
+
+class CpuSetTestCase(test.NoDBTestCase):
+ def test_get_cpuset_ids_none_returns_none(self):
+ self.flags(vcpu_pin_set=None)
+ cpuset_ids = cpu.get_cpuset_ids()
+ self.assertEqual(None, cpuset_ids)
+
+ def test_get_cpuset_ids_valid_syntax_works(self):
+ self.flags(vcpu_pin_set="1")
+ cpuset_ids = cpu.get_cpuset_ids()
+ self.assertEqual([1], cpuset_ids)
+
+ self.flags(vcpu_pin_set="1,2")
+ cpuset_ids = cpu.get_cpuset_ids()
+ self.assertEqual([1, 2], cpuset_ids)
+
+ self.flags(vcpu_pin_set=", , 1 , ,, 2, ,")
+ cpuset_ids = cpu.get_cpuset_ids()
+ self.assertEqual([1, 2], cpuset_ids)
+
+ self.flags(vcpu_pin_set="1-1")
+ cpuset_ids = cpu.get_cpuset_ids()
+ self.assertEqual([1], cpuset_ids)
+
+ self.flags(vcpu_pin_set=" 1 - 1, 1 - 2 , 1 -3")
+ cpuset_ids = cpu.get_cpuset_ids()
+ self.assertEqual([1, 2, 3], cpuset_ids)
+
+ self.flags(vcpu_pin_set="1,^2")
+ cpuset_ids = cpu.get_cpuset_ids()
+ self.assertEqual([1], cpuset_ids)
+
+ self.flags(vcpu_pin_set="1-2, ^1")
+ cpuset_ids = cpu.get_cpuset_ids()
+ self.assertEqual([2], cpuset_ids)
+
+ self.flags(vcpu_pin_set="1-3,5,^2")
+ cpuset_ids = cpu.get_cpuset_ids()
+ self.assertEqual([1, 3, 5], cpuset_ids)
+
+ self.flags(vcpu_pin_set=" 1 - 3 , ^2, 5")
+ cpuset_ids = cpu.get_cpuset_ids()
+ self.assertEqual([1, 3, 5], cpuset_ids)
+
+ def test_get_cpuset_ids_invalid_syntax_raises(self):
+ self.flags(vcpu_pin_set=" -1-3,5,^2")
+ self.assertRaises(exception.Invalid, cpu.get_cpuset_ids)
+
+ self.flags(vcpu_pin_set="1-3-,5,^2")
+ self.assertRaises(exception.Invalid, cpu.get_cpuset_ids)
+
+ self.flags(vcpu_pin_set="-3,5,^2")
+ self.assertRaises(exception.Invalid, cpu.get_cpuset_ids)
+
+ self.flags(vcpu_pin_set="1-,5,^2")
+ self.assertRaises(exception.Invalid, cpu.get_cpuset_ids)
+
+ self.flags(vcpu_pin_set="1-3,5,^2^")
+ self.assertRaises(exception.Invalid, cpu.get_cpuset_ids)
+
+ self.flags(vcpu_pin_set="1-3,5,^2-")
+ self.assertRaises(exception.Invalid, cpu.get_cpuset_ids)
+
+ self.flags(vcpu_pin_set="--13,^^5,^2")
+ self.assertRaises(exception.Invalid, cpu.get_cpuset_ids)
+
+ self.flags(vcpu_pin_set="a-3,5,^2")
+ self.assertRaises(exception.Invalid, cpu.get_cpuset_ids)
+
+ self.flags(vcpu_pin_set="1-a,5,^2")
+ self.assertRaises(exception.Invalid, cpu.get_cpuset_ids)
+
+ self.flags(vcpu_pin_set="1-3,b,^2")
+ self.assertRaises(exception.Invalid, cpu.get_cpuset_ids)
+
+ self.flags(vcpu_pin_set="1-3,5,^c")
+ self.assertRaises(exception.Invalid, cpu.get_cpuset_ids)
+
+ self.flags(vcpu_pin_set="3 - 1, 5 , ^ 2 ")
+ self.assertRaises(exception.Invalid, cpu.get_cpuset_ids)
+
+ self.flags(vcpu_pin_set=" 1,1, ^1")
+ self.assertRaises(exception.Invalid, cpu.get_cpuset_ids)
+
+ self.flags(vcpu_pin_set=" 1,^1,^1,2, ^2")
+ self.assertRaises(exception.Invalid, cpu.get_cpuset_ids)
+
+ self.flags(vcpu_pin_set="^2")
+ self.assertRaises(exception.Invalid, cpu.get_cpuset_ids)
diff --git a/nova/tests/virt/xenapi/test_vm_utils.py b/nova/tests/virt/xenapi/test_vm_utils.py
index 2a5d7c361a..2e878f7039 100644
--- a/nova/tests/virt/xenapi/test_vm_utils.py
+++ b/nova/tests/virt/xenapi/test_vm_utils.py
@@ -1430,42 +1430,72 @@ class ScanSrTestCase(VMUtilsTestBase):
mock_sleep.assert_called_once_with(2)
-class AllowVSSProviderTest(VMUtilsTestBase):
- def setUp(self):
- super(AllowVSSProviderTest, self).setUp()
- self.flags(disable_process_locking=True,
- instance_name_template='%d',
- firewall_driver='nova.virt.xenapi.firewall.'
- 'Dom0IptablesFirewallDriver')
- self.flags(connection_url='test_url',
- connection_password='test_pass',
- group='xenserver')
- stubs.stubout_session(self.stubs, fake.SessionBase)
- driver = xenapi_conn.XenAPIDriver(False)
- self.session = driver._session
- self.session.is_local_connection = False
- self.instance = {
- 'uuid': 'fakeinstance',
- 'kernel_id': 'kernel',
+@mock.patch.object(flavors, 'extract_flavor',
+ return_value={
+ 'memory_mb': 1024,
+ 'vcpus': 1,
+ 'vcpu_weight': 1.0,
+ })
+class CreateVmTestCase(VMUtilsTestBase):
+ def test_vss_provider(self, mock_extract):
+ self.flags(vcpu_pin_set="2,3")
+ session = mock.Mock()
+ instance = {
+ "uuid": "uuid",
}
- def test_allow_vss_provider(self):
- def fake_extract_flavor(inst):
- return {
- 'memory_mb': 1024,
- 'vcpus': 1,
- 'vcpu_weight': 1.0,
- }
-
- def fake_call_xenapi(command, rec):
- xenstore_data = rec.get('xenstore_data')
- self.assertIn('vm-data/allowvssprovider', xenstore_data)
-
- self.stubs.Set(flavors, 'extract_flavor', fake_extract_flavor)
- self.stubs.Set(self.session, 'call_xenapi', fake_call_xenapi)
- vm_utils.create_vm(self.session, self.instance, "label",
+ vm_utils.create_vm(session, instance, "label",
"kernel", "ramdisk")
+ vm_rec = {
+ 'VCPUs_params': {'cap': '0', 'mask': '2,3', 'weight': '1.0'},
+ 'PV_args': '',
+ 'memory_static_min': '0',
+ 'ha_restart_priority': '',
+ 'HVM_boot_policy': 'BIOS order',
+ 'PV_bootloader': '', 'tags': [],
+ 'VCPUs_max': '1',
+ 'memory_static_max': '1073741824',
+ 'actions_after_shutdown': 'destroy',
+ 'memory_dynamic_max': '1073741824',
+ 'user_version': '0',
+ 'xenstore_data': {'vm-data/allowvssprovider': 'false'},
+ 'blocked_operations': {},
+ 'is_a_template': False,
+ 'name_description': '',
+ 'memory_dynamic_min': '1073741824',
+ 'actions_after_crash': 'destroy',
+ 'memory_target': '1073741824',
+ 'PV_ramdisk': '',
+ 'PV_bootloader_args': '',
+ 'PCI_bus': '',
+ 'other_config': {'nova_uuid': 'uuid'},
+ 'name_label': 'label',
+ 'actions_after_reboot': 'restart',
+ 'VCPUs_at_startup': '1',
+ 'HVM_boot_params': {'order': 'dc'},
+ 'platform': {'nx': 'true', 'pae': 'true', 'apic': 'true',
+ 'timeoffset': '0', 'viridian': 'true',
+ 'acpi': 'true'},
+ 'PV_legacy_args': '',
+ 'PV_kernel': '',
+ 'affinity': '',
+ 'recommendations': '',
+ 'ha_always_run': False
+ }
+ session.call_xenapi.assert_called_once_with("VM.create", vm_rec)
+
+ def test_invalid_cpu_mask_raises(self, mock_extract):
+ self.flags(vcpu_pin_set="asdf")
+ session = mock.Mock()
+ instance = {
+ "uuid": "uuid",
+ }
+ self.assertRaises(exception.Invalid,
+ vm_utils.create_vm,
+ session, instance, "label",
+ "kernel", "ramdisk")
+
class DetermineVmModeTestCase(VMUtilsTestBase):
def test_determine_vm_mode_returns_xen_mode(self):
diff --git a/nova/virt/cpu.py b/nova/virt/cpu.py
new file mode 100644
index 0000000000..6be25b7c75
--- /dev/null
+++ b/nova/virt/cpu.py
@@ -0,0 +1,88 @@
+# vim: tabstop=4 shiftwidth=4 softtabstop=4
+
+# Copyright 2013 OpenStack Foundation
+# All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+from oslo.config import cfg
+
+from nova import exception
+from nova.openstack.common.gettextutils import _
+from nova.openstack.common import log as logging
+
+LOG = logging.getLogger(__name__)
+
+virt_cpu_opts = [
+ cfg.StrOpt('vcpu_pin_set',
+ help='Which pcpus can be used by vcpus of instance '
+ 'e.g: "4-12,^8,15"',
+ deprecated_group='libvirt'),
+]
+
+CONF = cfg.CONF
+CONF.register_opts(virt_cpu_opts)
+
+
+def get_cpuset_ids():
+ """
+ Parsing vcpu_pin_set config.
+
+ Returns a list of pcpu ids can be used by instances.
+ """
+ if not CONF.vcpu_pin_set:
+ return None
+
+ cpuset_ids = set()
+ cpuset_reject_ids = set()
+ for rule in CONF.vcpu_pin_set.split(','):
+ rule = rule.strip()
+ # Handle multi ','
+ if len(rule) < 1:
+ continue
+ # Note the count limit in the .split() call
+ range_parts = rule.split('-', 1)
+ if len(range_parts) > 1:
+ # So, this was a range; start by converting the parts to ints
+ try:
+ start, end = [int(p.strip()) for p in range_parts]
+ except ValueError:
+ raise exception.Invalid(_("Invalid range expression %r")
+ % rule)
+ # Make sure it's a valid range
+ if start > end:
+ raise exception.Invalid(_("Invalid range expression %r")
+ % rule)
+ # Add available pcpu ids to set
+ cpuset_ids |= set(range(start, end + 1))
+ elif rule[0] == '^':
+ # Not a range, the rule is an exclusion rule; convert to int
+ try:
+ cpuset_reject_ids.add(int(rule[1:].strip()))
+ except ValueError:
+ raise exception.Invalid(_("Invalid exclusion "
+ "expression %r") % rule)
+ else:
+ # OK, a single PCPU to include; convert to int
+ try:
+ cpuset_ids.add(int(rule))
+ except ValueError:
+ raise exception.Invalid(_("Invalid inclusion "
+ "expression %r") % rule)
+ # Use sets to handle the exclusion rules for us
+ cpuset_ids -= cpuset_reject_ids
+ if not cpuset_ids:
+ raise exception.Invalid(_("No CPUs available after parsing %r") %
+ CONF.vcpu_pin_set)
+ # This will convert the set to a sorted list for us
+ return sorted(cpuset_ids)
diff --git a/nova/virt/libvirt/driver.py b/nova/virt/libvirt/driver.py
index 5c557febe6..eec7120475 100644
--- a/nova/virt/libvirt/driver.py
+++ b/nova/virt/libvirt/driver.py
@@ -91,6 +91,7 @@ from nova import unit
from nova import utils
from nova import version
from nova.virt import configdrive
+from nova.virt import cpu
from nova.virt.disk import api as disk
from nova.virt import driver
from nova.virt import event as virtevent
@@ -248,10 +249,6 @@ libvirt_opts = [
help='Specific cachemodes to use for different disk types '
'e.g: file=directsync,block=none',
deprecated_group='DEFAULT'),
- cfg.StrOpt('vcpu_pin_set',
- help='Which pcpus can be used by vcpus of instance '
- 'e.g: "4-12,^8,15"',
- deprecated_group='DEFAULT'),
]
CONF = cfg.CONF
@@ -263,6 +260,7 @@ CONF.import_opt('use_cow_images', 'nova.virt.driver')
CONF.import_opt('live_migration_retry_count', 'nova.compute.manager')
CONF.import_opt('vncserver_proxyclient_address', 'nova.vnc')
CONF.import_opt('server_proxyclient_address', 'nova.spice', group='spice')
+CONF.import_opt('vcpu_pin_set', 'nova.virt.cpu')
DEFAULT_FIREWALL_DRIVER = "%s.%s" % (
libvirt_firewall.__name__,
@@ -2991,7 +2989,7 @@ class LibvirtDriver(driver.ComputeDriver):
guest.uuid = instance['uuid']
guest.memory = inst_type['memory_mb'] * 1024
guest.vcpus = inst_type['vcpus']
- guest.cpuset = CONF.libvirt.vcpu_pin_set
+ guest.cpuset = CONF.vcpu_pin_set
quota_items = ['cpu_shares', 'cpu_period', 'cpu_quota']
for key, value in inst_type['extra_specs'].iteritems():
@@ -3498,56 +3496,6 @@ class LibvirtDriver(driver.ComputeDriver):
return interfaces
- def _get_cpuset_ids(self):
- """
- Parsing vcpu_pin_set config.
-
- Returns a list of pcpu ids can be used by instances.
- """
- cpuset_ids = set()
- cpuset_reject_ids = set()
- for rule in CONF.libvirt.vcpu_pin_set.split(','):
- rule = rule.strip()
- # Handle multi ','
- if len(rule) < 1:
- continue
- # Note the count limit in the .split() call
- range_parts = rule.split('-', 1)
- if len(range_parts) > 1:
- # So, this was a range; start by converting the parts to ints
- try:
- start, end = [int(p.strip()) for p in range_parts]
- except ValueError:
- raise exception.Invalid(_("Invalid range expression %r")
- % rule)
- # Make sure it's a valid range
- if start > end:
- raise exception.Invalid(_("Invalid range expression %r")
- % rule)
- # Add available pcpu ids to set
- cpuset_ids |= set(range(start, end + 1))
- elif rule[0] == '^':
- # Not a range, the rule is an exclusion rule; convert to int
- try:
- cpuset_reject_ids.add(int(rule[1:].strip()))
- except ValueError:
- raise exception.Invalid(_("Invalid exclusion "
- "expression %r") % rule)
- else:
- # OK, a single PCPU to include; convert to int
- try:
- cpuset_ids.add(int(rule))
- except ValueError:
- raise exception.Invalid(_("Invalid inclusion "
- "expression %r") % rule)
- # Use sets to handle the exclusion rules for us
- cpuset_ids -= cpuset_reject_ids
- if not cpuset_ids:
- raise exception.Invalid(_("No CPUs available after parsing %r") %
- CONF.libvirt.vcpu_pin_set)
- # This will convert the set to a sorted list for us
- return sorted(cpuset_ids)
-
def get_vcpu_total(self):
"""Get available vcpu number of physical computer.
@@ -3564,11 +3512,11 @@ class LibvirtDriver(driver.ComputeDriver):
"function is not implemented for this platform. "))
return 0
- if CONF.libvirt.vcpu_pin_set is None:
+ if CONF.vcpu_pin_set is None:
self._vcpu_total = total_pcpus
return self._vcpu_total
- available_ids = self._get_cpuset_ids()
+ available_ids = cpu.get_cpuset_ids()
if available_ids[-1] >= total_pcpus:
raise exception.Invalid(_("Invalid vcpu_pin_set config, "
"out of hypervisor cpu range."))
diff --git a/nova/virt/xenapi/vm_utils.py b/nova/virt/xenapi/vm_utils.py
index fea691aab3..580f9fcd59 100644
--- a/nova/virt/xenapi/vm_utils.py
+++ b/nova/virt/xenapi/vm_utils.py
@@ -52,6 +52,7 @@ from nova.openstack.common import xmlutils
from nova import unit
from nova import utils
from nova.virt import configdrive
+from nova.virt import cpu
from nova.virt.disk import api as disk
from nova.virt.disk.vfs import localfs as vfsimpl
from nova.virt.xenapi import agent
@@ -267,6 +268,11 @@ def create_vm(session, instance, name_label, kernel, ramdisk,
# we need to specify both weight and cap for either to apply
vcpu_params = {"weight": str(vcpu_weight), "cap": "0"}
+ cpu_mask_list = cpu.get_cpuset_ids()
+ if cpu_mask_list:
+ cpu_mask = ",".join(str(cpu_id) for cpu_id in cpu_mask_list)
+ vcpu_params["mask"] = cpu_mask
+
rec = {
'actions_after_crash': 'destroy',
'actions_after_reboot': 'restart',