Add support for SR-IOV NICs to VMs
This commit is contained in:
@ -27,6 +27,7 @@ import lxml.etree
|
||||
import daemon_lib.common as common
|
||||
|
||||
import daemon_lib.ceph as ceph
|
||||
from daemon_lib.network import set_sriov_vf_vm, unset_sriov_vf_vm
|
||||
|
||||
|
||||
#
|
||||
@ -191,6 +192,21 @@ def define_vm(zkhandler, config_data, target_node, node_limit, node_selector, no
|
||||
if not valid_node:
|
||||
return False, 'ERROR: Specified node "{}" is invalid.'.format(target_node)
|
||||
|
||||
# If a SR-IOV network device is being added, set its used state
|
||||
dnetworks = common.getDomainNetworks(parsed_xml, {})
|
||||
for network in dnetworks:
|
||||
if network['type'] in ['direct', 'hostdev']:
|
||||
dom_node = zkhandler.read(('domain.node', dom_uuid))
|
||||
|
||||
# Check if the network is already in use
|
||||
is_used = zkhandler.read(('node.sriov.vf', dom_node, 'sriov_vf.used', network['source']))
|
||||
if is_used == 'True':
|
||||
used_by_name = searchClusterByUUID(zkhandler, zkhandler.read(('node.sriov.vf', dom_node, 'sriov_vf.used_by', network['source'])))
|
||||
return False, 'ERROR: Attempted to use SR-IOV network "{}" which is already used by VM "{}" on node "{}".'.format(network['source'], used_by_name, dom_node)
|
||||
|
||||
# We must update the "used" section
|
||||
set_sriov_vf_vm(zkhandler, dom_uuid, dom_node, network['source'], network['mac'], network['type'])
|
||||
|
||||
# Obtain the RBD disk list using the common functions
|
||||
ddisks = common.getDomainDisks(parsed_xml, {})
|
||||
rbd_list = []
|
||||
@ -211,7 +227,7 @@ def define_vm(zkhandler, config_data, target_node, node_limit, node_selector, no
|
||||
formatted_rbd_list = ''
|
||||
|
||||
# Add the new domain to Zookeeper
|
||||
result = zkhandler.write([
|
||||
zkhandler.write([
|
||||
(('domain', dom_uuid), dom_name),
|
||||
(('domain.xml', dom_uuid), config_data),
|
||||
(('domain.state', dom_uuid), initial_state),
|
||||
@ -230,10 +246,7 @@ def define_vm(zkhandler, config_data, target_node, node_limit, node_selector, no
|
||||
(('domain.migrate.sync_lock', dom_uuid), ''),
|
||||
])
|
||||
|
||||
if result:
|
||||
return True, 'Added new VM with Name "{}" and UUID "{}" to database.'.format(dom_name, dom_uuid)
|
||||
else:
|
||||
return False, 'ERROR: Failed to add new VM.'
|
||||
return True, 'Added new VM with Name "{}" and UUID "{}" to database.'.format(dom_name, dom_uuid)
|
||||
|
||||
|
||||
def modify_vm_metadata(zkhandler, domain, node_limit, node_selector, node_autostart, provisioner_profile, migration_method):
|
||||
@ -276,7 +289,36 @@ def modify_vm(zkhandler, domain, restart, new_vm_config):
|
||||
try:
|
||||
parsed_xml = lxml.objectify.fromstring(new_vm_config)
|
||||
except Exception:
|
||||
return False, 'ERROR: Failed to parse XML data.'
|
||||
return False, 'ERROR: Failed to parse new XML data.'
|
||||
|
||||
# If a SR-IOV network device is being added, set its used state
|
||||
dnetworks = common.getDomainNetworks(parsed_xml, {})
|
||||
for network in dnetworks:
|
||||
if network['type'] in ['direct', 'hostdev']:
|
||||
dom_node = zkhandler.read(('domain.node', dom_uuid))
|
||||
|
||||
# Check if the network is already in use
|
||||
is_used = zkhandler.read(('node.sriov.vf', dom_node, 'sriov_vf.used', network['source']))
|
||||
if is_used == 'True':
|
||||
used_by_name = searchClusterByUUID(zkhandler, zkhandler.read(('node.sriov.vf', dom_node, 'sriov_vf.used_by', network['source'])))
|
||||
return False, 'ERROR: Attempted to use SR-IOV network "{}" which is already used by VM "{}" on node "{}".'.format(network['source'], used_by_name, dom_node)
|
||||
|
||||
# We must update the "used" section
|
||||
set_sriov_vf_vm(zkhandler, dom_uuid, dom_node, network['source'], network['mac'], network['type'])
|
||||
|
||||
# If a SR-IOV network device is being removed, unset its used state
|
||||
old_vm_config = zkhandler.read(('domain.xml', dom_uuid))
|
||||
try:
|
||||
old_parsed_xml = lxml.objectify.fromstring(old_vm_config)
|
||||
except Exception:
|
||||
return False, 'ERROR: Failed to parse old XML data.'
|
||||
old_dnetworks = common.getDomainNetworks(old_parsed_xml, {})
|
||||
for network in old_dnetworks:
|
||||
if network['type'] in ['direct', 'hostdev']:
|
||||
if network['mac'] not in [n['mac'] for n in dnetworks]:
|
||||
dom_node = zkhandler.read(('domain.node', dom_uuid))
|
||||
# We must update the "used" section
|
||||
unset_sriov_vf_vm(zkhandler, dom_node, network['source'])
|
||||
|
||||
# Obtain the RBD disk list using the common functions
|
||||
ddisks = common.getDomainDisks(parsed_xml, {})
|
||||
|
Reference in New Issue
Block a user