Centralize domain mac address handling in domain_conf.c/util.c

This commit is contained in:
Daniel P. Berrange 2008-10-24 11:20:08 +00:00
parent 327b2eea26
commit bdd50bc7f3
15 changed files with 116 additions and 65 deletions

View File

@ -1,3 +1,16 @@
Fri Oct 24 12:17:23 BST Daniel P. Berrange <berrange@redhat.com>
* src/capabilities.c, src/capabilities.h: Record MAC address
prefix info for hypervisor
* src/domain_conf.c, src/domain_conf.h: Use capabilities to
find MAC address prefix when generating MAC addrs
* src/lxc_conf.c, src/lxc_driver.c, src/openvz_conf.c,
src/qemu_conf.c, src/qemu_driver.c, src/xen_internal.c,
src/xend_internal.c, src/xm_internal.c: Provide vendor
MAC address prefix to capabilities
* src/util.c, src/util.h: Generic method for generating
mac addresses.
Fri Oct 24 10:54:23 CEST Jim Meyering <meyering@redhat.com> Fri Oct 24 10:54:23 CEST Jim Meyering <meyering@redhat.com>
fix mingw compilation warning fix mingw compilation warning

View File

@ -26,7 +26,7 @@
#include "capabilities.h" #include "capabilities.h"
#include "buf.h" #include "buf.h"
#include "memory.h" #include "memory.h"
#include "util.h"
/** /**
* virCapabilitiesNew: * virCapabilitiesNew:
@ -647,3 +647,17 @@ virCapabilitiesFormatXML(virCapsPtr caps)
return virBufferContentAndReset(&xml); return virBufferContentAndReset(&xml);
} }
extern void
virCapabilitiesSetMacPrefix(virCapsPtr caps,
unsigned char *prefix)
{
memcpy(caps->macPrefix, prefix, sizeof(caps->macPrefix));
}
extern void
virCapabilitiesGenerateMac(virCapsPtr caps,
unsigned char *mac)
{
virGenerateMacAddr(caps->macPrefix, mac);
}

View File

@ -24,6 +24,9 @@
#ifndef __VIR_CAPABILITIES_H #ifndef __VIR_CAPABILITIES_H
#define __VIR_CAPABILITIES_H #define __VIR_CAPABILITIES_H
#include "internal.h"
#include "util.h"
typedef struct _virCapsGuestFeature virCapsGuestFeature; typedef struct _virCapsGuestFeature virCapsGuestFeature;
typedef virCapsGuestFeature *virCapsGuestFeaturePtr; typedef virCapsGuestFeature *virCapsGuestFeaturePtr;
struct _virCapsGuestFeature { struct _virCapsGuestFeature {
@ -95,6 +98,7 @@ struct _virCaps {
virCapsHost host; virCapsHost host;
int nguests; int nguests;
virCapsGuestPtr *guests; virCapsGuestPtr *guests;
unsigned char macPrefix[VIR_MAC_PREFIX_BUFLEN];
}; };
@ -106,6 +110,13 @@ virCapabilitiesNew(const char *arch,
extern void extern void
virCapabilitiesFree(virCapsPtr caps); virCapabilitiesFree(virCapsPtr caps);
extern void
virCapabilitiesSetMacPrefix(virCapsPtr caps,
unsigned char *prefix);
extern void
virCapabilitiesGenerateMac(virCapsPtr caps,
unsigned char *mac);
extern int extern int
virCapabilitiesAddHostFeature(virCapsPtr caps, virCapabilitiesAddHostFeature(virCapsPtr caps,

View File

@ -762,23 +762,14 @@ cleanup:
} }
static void virDomainNetRandomMAC(virDomainNetDefPtr def) {
/* XXX there different vendor prefixes per hypervisor */
def->mac[0] = 0x52;
def->mac[1] = 0x54;
def->mac[2] = 0x00;
def->mac[3] = 1 + (int)(256*(rand()/(RAND_MAX+1.0)));
def->mac[4] = 1 + (int)(256*(rand()/(RAND_MAX+1.0)));
def->mac[5] = 1 + (int)(256*(rand()/(RAND_MAX+1.0)));
}
/* Parse the XML definition for a network interface /* Parse the XML definition for a network interface
* @param node XML nodeset to parse for net definition * @param node XML nodeset to parse for net definition
* @return 0 on success, -1 on failure * @return 0 on success, -1 on failure
*/ */
virDomainNetDefPtr static virDomainNetDefPtr
virDomainNetDefParseXML(virConnectPtr conn, virDomainNetDefParseXML(virConnectPtr conn,
virCapsPtr caps,
xmlNodePtr node) { xmlNodePtr node) {
virDomainNetDefPtr def; virDomainNetDefPtr def;
xmlNodePtr cur; xmlNodePtr cur;
@ -857,22 +848,9 @@ virDomainNetDefParseXML(virConnectPtr conn,
} }
if (macaddr) { if (macaddr) {
unsigned int mac[6]; virParseMacAddr((const char *)macaddr, def->mac);
sscanf((const char *)macaddr, "%02x:%02x:%02x:%02x:%02x:%02x",
(unsigned int*)&mac[0],
(unsigned int*)&mac[1],
(unsigned int*)&mac[2],
(unsigned int*)&mac[3],
(unsigned int*)&mac[4],
(unsigned int*)&mac[5]);
def->mac[0] = mac[0];
def->mac[1] = mac[1];
def->mac[2] = mac[2];
def->mac[3] = mac[3];
def->mac[4] = mac[4];
def->mac[5] = mac[5];
} else { } else {
virDomainNetRandomMAC(def); virCapabilitiesGenerateMac(caps, def->mac);
} }
switch (def->type) { switch (def->type) {
@ -1630,6 +1608,7 @@ static int virDomainLifecycleParseXML(virConnectPtr conn,
virDomainDeviceDefPtr virDomainDeviceDefParse(virConnectPtr conn, virDomainDeviceDefPtr virDomainDeviceDefParse(virConnectPtr conn,
virCapsPtr caps,
const virDomainDefPtr def, const virDomainDefPtr def,
const char *xmlStr) const char *xmlStr)
{ {
@ -1666,7 +1645,7 @@ virDomainDeviceDefPtr virDomainDeviceDefParse(virConnectPtr conn,
goto error; goto error;
} else if (xmlStrEqual(node->name, BAD_CAST "interface")) { } else if (xmlStrEqual(node->name, BAD_CAST "interface")) {
dev->type = VIR_DOMAIN_DEVICE_NET; dev->type = VIR_DOMAIN_DEVICE_NET;
if (!(dev->data.net = virDomainNetDefParseXML(conn, node))) if (!(dev->data.net = virDomainNetDefParseXML(conn, caps, node)))
goto error; goto error;
} else if (xmlStrEqual(node->name, BAD_CAST "input")) { } else if (xmlStrEqual(node->name, BAD_CAST "input")) {
dev->type = VIR_DOMAIN_DEVICE_INPUT; dev->type = VIR_DOMAIN_DEVICE_INPUT;
@ -1988,6 +1967,7 @@ static virDomainDefPtr virDomainDefParseXML(virConnectPtr conn,
goto no_memory; goto no_memory;
for (i = 0 ; i < n ; i++) { for (i = 0 ; i < n ; i++) {
virDomainNetDefPtr net = virDomainNetDefParseXML(conn, virDomainNetDefPtr net = virDomainNetDefParseXML(conn,
caps,
nodes[i]); nodes[i]);
if (!net) if (!net)
goto error; goto error;

View File

@ -127,14 +127,12 @@ enum virDomainNetType {
}; };
#define VIR_DOMAIN_NET_MAC_SIZE 6
/* Stores the virtual network interface configuration */ /* Stores the virtual network interface configuration */
typedef struct _virDomainNetDef virDomainNetDef; typedef struct _virDomainNetDef virDomainNetDef;
typedef virDomainNetDef *virDomainNetDefPtr; typedef virDomainNetDef *virDomainNetDefPtr;
struct _virDomainNetDef { struct _virDomainNetDef {
int type; int type;
unsigned char mac[VIR_DOMAIN_NET_MAC_SIZE]; unsigned char mac[VIR_MAC_BUFLEN];
char *model; char *model;
union { union {
struct { struct {
@ -513,6 +511,7 @@ void virDomainRemoveInactive(virDomainObjListPtr doms,
#ifndef PROXY #ifndef PROXY
virDomainDeviceDefPtr virDomainDeviceDefParse(virConnectPtr conn, virDomainDeviceDefPtr virDomainDeviceDefParse(virConnectPtr conn,
virCapsPtr caps,
const virDomainDefPtr def, const virDomainDefPtr def,
const char *xmlStr); const char *xmlStr);
virDomainDefPtr virDomainDefParseString(virConnectPtr conn, virDomainDefPtr virDomainDefParseString(virConnectPtr conn,
@ -573,9 +572,6 @@ int virDiskNameToBusDeviceIndex(virDomainDiskDefPtr disk,
int *busIdx, int *busIdx,
int *devIdx); int *devIdx);
virDomainNetDefPtr virDomainNetDefParseXML(virConnectPtr conn,
xmlNodePtr node);
const char *virDomainDefDefaultEmulator(virConnectPtr conn, const char *virDomainDefDefaultEmulator(virConnectPtr conn,
virDomainDefPtr def, virDomainDefPtr def,
virCapsPtr caps); virCapsPtr caps);

View File

@ -42,6 +42,9 @@ virCapsPtr lxcCapsInit(void)
0, 0)) == NULL) 0, 0)) == NULL)
goto no_memory; goto no_memory;
/* XXX shouldn't 'borrow' KVM's prefix */
virCapabilitiesSetMacPrefix(caps, (unsigned char []){ 0x52, 0x54, 0x00 });
if ((guest = virCapabilitiesAddGuest(caps, if ((guest = virCapabilitiesAddGuest(caps,
"exe", "exe",
utsname.machine, utsname.machine,

View File

@ -1187,6 +1187,7 @@ static int lxcGetSchedulerParameters(virDomainPtr _domain,
int rc = 0; int rc = 0;
virCgroupPtr group; virCgroupPtr group;
virDomainObjPtr domain; virDomainObjPtr domain;
unsigned long val;
if (virCgroupHaveSupport() != 0) if (virCgroupHaveSupport() != 0)
return 0; return 0;
@ -1208,7 +1209,8 @@ static int lxcGetSchedulerParameters(virDomainPtr _domain,
if (rc != 0) if (rc != 0)
return rc; return rc;
rc = virCgroupGetCpuShares(group, (unsigned long *)&params[0].value.ul); rc = virCgroupGetCpuShares(group, &val);
params[0].value.ul = val;
strncpy(params[0].field, "cpu_shares", sizeof(params[0].field)); strncpy(params[0].field, "cpu_shares", sizeof(params[0].field));
params[0].type = VIR_DOMAIN_SCHED_FIELD_ULLONG; params[0].type = VIR_DOMAIN_SCHED_FIELD_ULLONG;

View File

@ -108,7 +108,7 @@ no_memory:
int openvzCheckEmptyMac(const unsigned char *mac) int openvzCheckEmptyMac(const unsigned char *mac)
{ {
int i; int i;
for (i = 0; i < VIR_DOMAIN_NET_MAC_SIZE; i++) for (i = 0; i < VIR_MAC_BUFLEN; i++)
if (mac[i] != 0x00) if (mac[i] != 0x00)
return 1; return 1;

View File

@ -365,6 +365,9 @@ virCapsPtr qemudCapsInit(void) {
0, 0)) == NULL) 0, 0)) == NULL)
goto no_memory; goto no_memory;
/* Using KVM's mac prefix for QEMU too */
virCapabilitiesSetMacPrefix(caps, (unsigned char[]){ 0x52, 0x54, 0x00 });
if (qemudCapsInitNUMA(caps) < 0) if (qemudCapsInitNUMA(caps) < 0)
goto no_memory; goto no_memory;

View File

@ -2423,7 +2423,7 @@ static int qemudDomainChangeEjectableMedia(virDomainPtr dom,
{ {
struct qemud_driver *driver = (struct qemud_driver *)dom->conn->privateData; struct qemud_driver *driver = (struct qemud_driver *)dom->conn->privateData;
virDomainObjPtr vm = virDomainFindByUUID(&driver->domains, dom->uuid); virDomainObjPtr vm = virDomainFindByUUID(&driver->domains, dom->uuid);
virDomainDiskDefPtr origdisk, newdisk; virDomainDiskDefPtr origdisk = NULL, newdisk;
char *cmd, *reply, *safe_path; char *cmd, *reply, *safe_path;
char *devname = NULL; char *devname = NULL;
unsigned int qemuCmdFlags; unsigned int qemuCmdFlags;
@ -2752,7 +2752,9 @@ static int qemudDomainAttachDevice(virDomainPtr dom,
return -1; return -1;
} }
dev = virDomainDeviceDefParse(dom->conn, vm->def, xml); dev = virDomainDeviceDefParse(dom->conn,
driver->caps,
vm->def, xml);
if (dev == NULL) { if (dev == NULL) {
return -1; return -1;
} }

View File

@ -983,7 +983,7 @@ virParseMacAddr(const char* str, unsigned char *addr)
int i; int i;
errno = 0; errno = 0;
for (i = 0; i < 6; i++) { for (i = 0; i < VIR_MAC_BUFLEN; i++) {
char *end_ptr; char *end_ptr;
unsigned long result; unsigned long result;
@ -1013,6 +1013,28 @@ virParseMacAddr(const char* str, unsigned char *addr)
return -1; return -1;
} }
void virFormatMacAddr(const unsigned char *addr,
char *str)
{
snprintf(str, VIR_MAC_STRING_BUFLEN,
"%02X:%02X:%02X:%02X:%02X:%02X",
addr[0], addr[1], addr[2],
addr[3], addr[4], addr[5]);
str[VIR_MAC_STRING_BUFLEN-1] = '\0';
}
void virGenerateMacAddr(const unsigned char *prefix,
unsigned char *addr)
{
addr[0] = prefix[0];
addr[1] = prefix[1];
addr[2] = prefix[2];
addr[3] = (int)(256*(rand()/(RAND_MAX+1.0)));
addr[4] = (int)(256*(rand()/(RAND_MAX+1.0)));
addr[5] = (int)(256*(rand()/(RAND_MAX+1.0)));
}
int virEnumFromString(const char *const*types, int virEnumFromString(const char *const*types,
unsigned int ntypes, unsigned int ntypes,
const char *type) const char *type)

View File

@ -1,3 +1,4 @@
/* /*
* utils.h: common, generic utility functions * utils.h: common, generic utility functions
* *
@ -113,7 +114,16 @@ int __virMacAddrCompare (const char *mac1, const char *mac2);
void virSkipSpaces(const char **str); void virSkipSpaces(const char **str);
int virParseNumber(const char **str); int virParseNumber(const char **str);
int virParseMacAddr(const char* str, unsigned char *addr); #define VIR_MAC_BUFLEN 6
#define VIR_MAC_PREFIX_BUFLEN 3
#define VIR_MAC_STRING_BUFLEN VIR_MAC_BUFLEN * 3
int virParseMacAddr(const char* str,
unsigned char *addr);
void virFormatMacAddr(const unsigned char *addr,
char *str);
void virGenerateMacAddr(const unsigned char *prefix,
unsigned char *addr);
int virDiskNameToIndex(const char* str); int virDiskNameToIndex(const char* str);

View File

@ -2132,6 +2132,9 @@ xenHypervisorBuildCapabilities(virConnectPtr conn,
if ((caps = virCapabilitiesNew(hostmachine, 1, 1)) == NULL) if ((caps = virCapabilitiesNew(hostmachine, 1, 1)) == NULL)
goto no_memory; goto no_memory;
virCapabilitiesSetMacPrefix(caps, (unsigned char[]){ 0x00, 0x16, 0x3e });
if (hvm_type && STRNEQ(hvm_type, "") && if (hvm_type && STRNEQ(hvm_type, "") &&
virCapabilitiesAddHostFeature(caps, hvm_type) < 0) virCapabilitiesAddHostFeature(caps, hvm_type) < 0)
goto no_memory; goto no_memory;

View File

@ -3852,7 +3852,9 @@ xenDaemonAttachDevice(virDomainPtr domain, const char *xml)
NULL))) NULL)))
goto cleanup; goto cleanup;
if (!(dev = virDomainDeviceDefParse(domain->conn, def, xml))) if (!(dev = virDomainDeviceDefParse(domain->conn,
priv->caps,
def, xml)))
goto cleanup; goto cleanup;
@ -3940,7 +3942,9 @@ xenDaemonDetachDevice(virDomainPtr domain, const char *xml)
NULL))) NULL)))
goto cleanup; goto cleanup;
if (!(dev = virDomainDeviceDefParse(domain->conn, def, xml))) if (!(dev = virDomainDeviceDefParse(domain->conn,
priv->caps,
def, xml)))
goto cleanup; goto cleanup;
if (virDomainXMLDevID(domain, dev, class, ref, sizeof(ref))) if (virDomainXMLDevID(domain, dev, class, ref, sizeof(ref)))

View File

@ -2422,12 +2422,16 @@ xenXMDomainAttachDevice(virDomainPtr domain, const char *xml) {
int ret = -1; int ret = -1;
virDomainDeviceDefPtr dev = NULL; virDomainDeviceDefPtr dev = NULL;
virDomainDefPtr def; virDomainDefPtr def;
xenUnifiedPrivatePtr priv;
if ((!domain) || (!domain->conn) || (!domain->name) || (!xml)) { if ((!domain) || (!domain->conn) || (!domain->name) || (!xml)) {
xenXMError((domain ? domain->conn : NULL), VIR_ERR_INVALID_ARG, xenXMError((domain ? domain->conn : NULL), VIR_ERR_INVALID_ARG,
__FUNCTION__); __FUNCTION__);
return -1; return -1;
} }
priv = (xenUnifiedPrivatePtr) domain->conn->privateData;
if (domain->conn->flags & VIR_CONNECT_RO) if (domain->conn->flags & VIR_CONNECT_RO)
return -1; return -1;
if (domain->id != -1) if (domain->id != -1)
@ -2440,6 +2444,7 @@ xenXMDomainAttachDevice(virDomainPtr domain, const char *xml) {
def = entry->def; def = entry->def;
if (!(dev = virDomainDeviceDefParse(domain->conn, if (!(dev = virDomainDeviceDefParse(domain->conn,
priv->caps,
entry->def, entry->def,
xml))) xml)))
return -1; return -1;
@ -2490,28 +2495,6 @@ xenXMDomainAttachDevice(virDomainPtr domain, const char *xml) {
} }
/**
* xenXMAutoAssignMac:
* @mac: pointer to Mac String
*
* a mac is assigned automatically.
*
* Returns 0 in case of success, -1 in case of failure.
*/
char *
xenXMAutoAssignMac() {
char *buf;
if (VIR_ALLOC_N(buf, 18) < 0)
return 0;
srand((unsigned)time(NULL));
sprintf(buf, "00:16:3e:%02x:%02x:%02x"
,1 + (int)(256*(rand()/(RAND_MAX+1.0)))
,1 + (int)(256*(rand()/(RAND_MAX+1.0)))
,1 + (int)(256*(rand()/(RAND_MAX+1.0))));
return buf;
}
/** /**
* xenXMDomainDetachDevice: * xenXMDomainDetachDevice:
* @domain: pointer to domain object * @domain: pointer to domain object
@ -2529,12 +2512,16 @@ xenXMDomainDetachDevice(virDomainPtr domain, const char *xml) {
virDomainDefPtr def; virDomainDefPtr def;
int ret = -1; int ret = -1;
int i; int i;
xenUnifiedPrivatePtr priv;
if ((!domain) || (!domain->conn) || (!domain->name) || (!xml)) { if ((!domain) || (!domain->conn) || (!domain->name) || (!xml)) {
xenXMError((domain ? domain->conn : NULL), VIR_ERR_INVALID_ARG, xenXMError((domain ? domain->conn : NULL), VIR_ERR_INVALID_ARG,
__FUNCTION__); __FUNCTION__);
return -1; return -1;
} }
priv = (xenUnifiedPrivatePtr) domain->conn->privateData;
if (domain->conn->flags & VIR_CONNECT_RO) if (domain->conn->flags & VIR_CONNECT_RO)
return -1; return -1;
if (domain->id != -1) if (domain->id != -1)
@ -2546,6 +2533,7 @@ xenXMDomainDetachDevice(virDomainPtr domain, const char *xml) {
def = entry->def; def = entry->def;
if (!(dev = virDomainDeviceDefParse(domain->conn, if (!(dev = virDomainDeviceDefParse(domain->conn,
priv->caps,
entry->def, entry->def,
xml))) xml)))
return -1; return -1;
@ -2573,7 +2561,7 @@ xenXMDomainDetachDevice(virDomainPtr domain, const char *xml) {
for (i = 0 ; i < def->nnets ; i++) { for (i = 0 ; i < def->nnets ; i++) {
if (!memcmp(def->nets[i]->mac, if (!memcmp(def->nets[i]->mac,
dev->data.net->mac, dev->data.net->mac,
VIR_DOMAIN_NET_MAC_SIZE)) { sizeof(def->nets[i]->mac))) {
virDomainNetDefFree(def->nets[i]); virDomainNetDefFree(def->nets[i]);
if (i < (def->nnets - 1)) if (i < (def->nnets - 1))
memmove(def->nets + i, memmove(def->nets + i,