diff --git a/ChangeLog b/ChangeLog index 4e9a905de9..1d3a2a8540 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,16 @@ +Fri Oct 24 12:17:23 BST Daniel P. Berrange + + * 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 fix mingw compilation warning diff --git a/src/capabilities.c b/src/capabilities.c index 2b7576e807..158873ced9 100644 --- a/src/capabilities.c +++ b/src/capabilities.c @@ -26,7 +26,7 @@ #include "capabilities.h" #include "buf.h" #include "memory.h" - +#include "util.h" /** * virCapabilitiesNew: @@ -647,3 +647,17 @@ virCapabilitiesFormatXML(virCapsPtr caps) 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); +} diff --git a/src/capabilities.h b/src/capabilities.h index 770779cba4..c991ea192d 100644 --- a/src/capabilities.h +++ b/src/capabilities.h @@ -24,6 +24,9 @@ #ifndef __VIR_CAPABILITIES_H #define __VIR_CAPABILITIES_H +#include "internal.h" +#include "util.h" + typedef struct _virCapsGuestFeature virCapsGuestFeature; typedef virCapsGuestFeature *virCapsGuestFeaturePtr; struct _virCapsGuestFeature { @@ -95,6 +98,7 @@ struct _virCaps { virCapsHost host; int nguests; virCapsGuestPtr *guests; + unsigned char macPrefix[VIR_MAC_PREFIX_BUFLEN]; }; @@ -106,6 +110,13 @@ virCapabilitiesNew(const char *arch, extern void virCapabilitiesFree(virCapsPtr caps); +extern void +virCapabilitiesSetMacPrefix(virCapsPtr caps, + unsigned char *prefix); + +extern void +virCapabilitiesGenerateMac(virCapsPtr caps, + unsigned char *mac); extern int virCapabilitiesAddHostFeature(virCapsPtr caps, diff --git a/src/domain_conf.c b/src/domain_conf.c index 2bade8dbe9..13baa29196 100644 --- a/src/domain_conf.c +++ b/src/domain_conf.c @@ -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 * @param node XML nodeset to parse for net definition * @return 0 on success, -1 on failure */ -virDomainNetDefPtr +static virDomainNetDefPtr virDomainNetDefParseXML(virConnectPtr conn, + virCapsPtr caps, xmlNodePtr node) { virDomainNetDefPtr def; xmlNodePtr cur; @@ -857,22 +848,9 @@ virDomainNetDefParseXML(virConnectPtr conn, } if (macaddr) { - unsigned int mac[6]; - 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]; + virParseMacAddr((const char *)macaddr, def->mac); } else { - virDomainNetRandomMAC(def); + virCapabilitiesGenerateMac(caps, def->mac); } switch (def->type) { @@ -1630,6 +1608,7 @@ static int virDomainLifecycleParseXML(virConnectPtr conn, virDomainDeviceDefPtr virDomainDeviceDefParse(virConnectPtr conn, + virCapsPtr caps, const virDomainDefPtr def, const char *xmlStr) { @@ -1666,7 +1645,7 @@ virDomainDeviceDefPtr virDomainDeviceDefParse(virConnectPtr conn, goto error; } else if (xmlStrEqual(node->name, BAD_CAST "interface")) { dev->type = VIR_DOMAIN_DEVICE_NET; - if (!(dev->data.net = virDomainNetDefParseXML(conn, node))) + if (!(dev->data.net = virDomainNetDefParseXML(conn, caps, node))) goto error; } else if (xmlStrEqual(node->name, BAD_CAST "input")) { dev->type = VIR_DOMAIN_DEVICE_INPUT; @@ -1988,6 +1967,7 @@ static virDomainDefPtr virDomainDefParseXML(virConnectPtr conn, goto no_memory; for (i = 0 ; i < n ; i++) { virDomainNetDefPtr net = virDomainNetDefParseXML(conn, + caps, nodes[i]); if (!net) goto error; diff --git a/src/domain_conf.h b/src/domain_conf.h index 4d193f4e7a..62731e6c55 100644 --- a/src/domain_conf.h +++ b/src/domain_conf.h @@ -127,14 +127,12 @@ enum virDomainNetType { }; -#define VIR_DOMAIN_NET_MAC_SIZE 6 - /* Stores the virtual network interface configuration */ typedef struct _virDomainNetDef virDomainNetDef; typedef virDomainNetDef *virDomainNetDefPtr; struct _virDomainNetDef { int type; - unsigned char mac[VIR_DOMAIN_NET_MAC_SIZE]; + unsigned char mac[VIR_MAC_BUFLEN]; char *model; union { struct { @@ -513,6 +511,7 @@ void virDomainRemoveInactive(virDomainObjListPtr doms, #ifndef PROXY virDomainDeviceDefPtr virDomainDeviceDefParse(virConnectPtr conn, + virCapsPtr caps, const virDomainDefPtr def, const char *xmlStr); virDomainDefPtr virDomainDefParseString(virConnectPtr conn, @@ -573,9 +572,6 @@ int virDiskNameToBusDeviceIndex(virDomainDiskDefPtr disk, int *busIdx, int *devIdx); -virDomainNetDefPtr virDomainNetDefParseXML(virConnectPtr conn, - xmlNodePtr node); - const char *virDomainDefDefaultEmulator(virConnectPtr conn, virDomainDefPtr def, virCapsPtr caps); diff --git a/src/lxc_conf.c b/src/lxc_conf.c index d522c4e80c..b8d6c74929 100644 --- a/src/lxc_conf.c +++ b/src/lxc_conf.c @@ -42,6 +42,9 @@ virCapsPtr lxcCapsInit(void) 0, 0)) == NULL) goto no_memory; + /* XXX shouldn't 'borrow' KVM's prefix */ + virCapabilitiesSetMacPrefix(caps, (unsigned char []){ 0x52, 0x54, 0x00 }); + if ((guest = virCapabilitiesAddGuest(caps, "exe", utsname.machine, diff --git a/src/lxc_driver.c b/src/lxc_driver.c index 6b34620d02..8b30cdd3b0 100644 --- a/src/lxc_driver.c +++ b/src/lxc_driver.c @@ -1187,6 +1187,7 @@ static int lxcGetSchedulerParameters(virDomainPtr _domain, int rc = 0; virCgroupPtr group; virDomainObjPtr domain; + unsigned long val; if (virCgroupHaveSupport() != 0) return 0; @@ -1208,7 +1209,8 @@ static int lxcGetSchedulerParameters(virDomainPtr _domain, if (rc != 0) return rc; - rc = virCgroupGetCpuShares(group, (unsigned long *)¶ms[0].value.ul); + rc = virCgroupGetCpuShares(group, &val); + params[0].value.ul = val; strncpy(params[0].field, "cpu_shares", sizeof(params[0].field)); params[0].type = VIR_DOMAIN_SCHED_FIELD_ULLONG; diff --git a/src/openvz_conf.c b/src/openvz_conf.c index afd18a69fb..5c70f630ee 100644 --- a/src/openvz_conf.c +++ b/src/openvz_conf.c @@ -108,7 +108,7 @@ no_memory: int openvzCheckEmptyMac(const unsigned char *mac) { int i; - for (i = 0; i < VIR_DOMAIN_NET_MAC_SIZE; i++) + for (i = 0; i < VIR_MAC_BUFLEN; i++) if (mac[i] != 0x00) return 1; diff --git a/src/qemu_conf.c b/src/qemu_conf.c index c7168a3be7..7702090c50 100644 --- a/src/qemu_conf.c +++ b/src/qemu_conf.c @@ -365,6 +365,9 @@ virCapsPtr qemudCapsInit(void) { 0, 0)) == NULL) goto no_memory; + /* Using KVM's mac prefix for QEMU too */ + virCapabilitiesSetMacPrefix(caps, (unsigned char[]){ 0x52, 0x54, 0x00 }); + if (qemudCapsInitNUMA(caps) < 0) goto no_memory; diff --git a/src/qemu_driver.c b/src/qemu_driver.c index e2b34e35b3..e21f3fdb6c 100644 --- a/src/qemu_driver.c +++ b/src/qemu_driver.c @@ -2423,7 +2423,7 @@ static int qemudDomainChangeEjectableMedia(virDomainPtr dom, { struct qemud_driver *driver = (struct qemud_driver *)dom->conn->privateData; virDomainObjPtr vm = virDomainFindByUUID(&driver->domains, dom->uuid); - virDomainDiskDefPtr origdisk, newdisk; + virDomainDiskDefPtr origdisk = NULL, newdisk; char *cmd, *reply, *safe_path; char *devname = NULL; unsigned int qemuCmdFlags; @@ -2752,7 +2752,9 @@ static int qemudDomainAttachDevice(virDomainPtr dom, return -1; } - dev = virDomainDeviceDefParse(dom->conn, vm->def, xml); + dev = virDomainDeviceDefParse(dom->conn, + driver->caps, + vm->def, xml); if (dev == NULL) { return -1; } diff --git a/src/util.c b/src/util.c index aa216532d6..5bcd87ae59 100644 --- a/src/util.c +++ b/src/util.c @@ -983,7 +983,7 @@ virParseMacAddr(const char* str, unsigned char *addr) int i; errno = 0; - for (i = 0; i < 6; i++) { + for (i = 0; i < VIR_MAC_BUFLEN; i++) { char *end_ptr; unsigned long result; @@ -1013,6 +1013,28 @@ virParseMacAddr(const char* str, unsigned char *addr) 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, unsigned int ntypes, const char *type) diff --git a/src/util.h b/src/util.h index 093ef46674..689da60207 100644 --- a/src/util.h +++ b/src/util.h @@ -1,3 +1,4 @@ + /* * utils.h: common, generic utility functions * @@ -113,7 +114,16 @@ int __virMacAddrCompare (const char *mac1, const char *mac2); void virSkipSpaces(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); diff --git a/src/xen_internal.c b/src/xen_internal.c index 023222fb32..5e34c257b8 100644 --- a/src/xen_internal.c +++ b/src/xen_internal.c @@ -2132,6 +2132,9 @@ xenHypervisorBuildCapabilities(virConnectPtr conn, if ((caps = virCapabilitiesNew(hostmachine, 1, 1)) == NULL) goto no_memory; + + virCapabilitiesSetMacPrefix(caps, (unsigned char[]){ 0x00, 0x16, 0x3e }); + if (hvm_type && STRNEQ(hvm_type, "") && virCapabilitiesAddHostFeature(caps, hvm_type) < 0) goto no_memory; diff --git a/src/xend_internal.c b/src/xend_internal.c index eb67235215..21f1f1ab4d 100644 --- a/src/xend_internal.c +++ b/src/xend_internal.c @@ -3852,7 +3852,9 @@ xenDaemonAttachDevice(virDomainPtr domain, const char *xml) NULL))) goto cleanup; - if (!(dev = virDomainDeviceDefParse(domain->conn, def, xml))) + if (!(dev = virDomainDeviceDefParse(domain->conn, + priv->caps, + def, xml))) goto cleanup; @@ -3940,7 +3942,9 @@ xenDaemonDetachDevice(virDomainPtr domain, const char *xml) NULL))) goto cleanup; - if (!(dev = virDomainDeviceDefParse(domain->conn, def, xml))) + if (!(dev = virDomainDeviceDefParse(domain->conn, + priv->caps, + def, xml))) goto cleanup; if (virDomainXMLDevID(domain, dev, class, ref, sizeof(ref))) diff --git a/src/xm_internal.c b/src/xm_internal.c index 6c84b9107d..12b78526c2 100644 --- a/src/xm_internal.c +++ b/src/xm_internal.c @@ -2422,12 +2422,16 @@ xenXMDomainAttachDevice(virDomainPtr domain, const char *xml) { int ret = -1; virDomainDeviceDefPtr dev = NULL; virDomainDefPtr def; + xenUnifiedPrivatePtr priv; if ((!domain) || (!domain->conn) || (!domain->name) || (!xml)) { xenXMError((domain ? domain->conn : NULL), VIR_ERR_INVALID_ARG, __FUNCTION__); return -1; } + + priv = (xenUnifiedPrivatePtr) domain->conn->privateData; + if (domain->conn->flags & VIR_CONNECT_RO) return -1; if (domain->id != -1) @@ -2440,6 +2444,7 @@ xenXMDomainAttachDevice(virDomainPtr domain, const char *xml) { def = entry->def; if (!(dev = virDomainDeviceDefParse(domain->conn, + priv->caps, entry->def, xml))) 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: * @domain: pointer to domain object @@ -2529,12 +2512,16 @@ xenXMDomainDetachDevice(virDomainPtr domain, const char *xml) { virDomainDefPtr def; int ret = -1; int i; + xenUnifiedPrivatePtr priv; if ((!domain) || (!domain->conn) || (!domain->name) || (!xml)) { xenXMError((domain ? domain->conn : NULL), VIR_ERR_INVALID_ARG, __FUNCTION__); return -1; } + + priv = (xenUnifiedPrivatePtr) domain->conn->privateData; + if (domain->conn->flags & VIR_CONNECT_RO) return -1; if (domain->id != -1) @@ -2546,6 +2533,7 @@ xenXMDomainDetachDevice(virDomainPtr domain, const char *xml) { def = entry->def; if (!(dev = virDomainDeviceDefParse(domain->conn, + priv->caps, entry->def, xml))) return -1; @@ -2573,7 +2561,7 @@ xenXMDomainDetachDevice(virDomainPtr domain, const char *xml) { for (i = 0 ; i < def->nnets ; i++) { if (!memcmp(def->nets[i]->mac, dev->data.net->mac, - VIR_DOMAIN_NET_MAC_SIZE)) { + sizeof(def->nets[i]->mac))) { virDomainNetDefFree(def->nets[i]); if (i < (def->nnets - 1)) memmove(def->nets + i,