2012-12-11 10:59:45 +00:00
|
|
|
/*
|
2015-06-10 07:50:00 +00:00
|
|
|
* vz_network.c: core privconn functions for managing
|
2012-12-11 10:59:45 +00:00
|
|
|
* Parallels Cloud Server hosts
|
|
|
|
*
|
2014-04-20 20:07:46 +00:00
|
|
|
* Copyright (C) 2013-2014 Red Hat, Inc.
|
2012-12-11 10:59:45 +00:00
|
|
|
* Copyright (C) 2012 Parallels, Inc.
|
|
|
|
*
|
|
|
|
* This library is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
|
|
* License as published by the Free Software Foundation; either
|
|
|
|
* version 2.1 of the License, or (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This library is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
* Lesser General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
|
|
* License along with this library. If not, see
|
|
|
|
* <http://www.gnu.org/licenses/>.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <config.h>
|
|
|
|
|
|
|
|
#include "datatypes.h"
|
2013-04-25 20:24:42 +00:00
|
|
|
#include "dirname.h"
|
2012-12-12 18:06:53 +00:00
|
|
|
#include "viralloc.h"
|
2012-12-13 18:21:53 +00:00
|
|
|
#include "virerror.h"
|
2013-05-09 18:59:04 +00:00
|
|
|
#include "virfile.h"
|
2015-04-15 09:45:47 +00:00
|
|
|
#include "virnetdev.h"
|
2012-12-11 10:59:45 +00:00
|
|
|
#include "md5.h"
|
2015-06-10 07:50:00 +00:00
|
|
|
#include "vz_utils.h"
|
2013-04-03 10:36:23 +00:00
|
|
|
#include "virstring.h"
|
2012-12-11 10:59:45 +00:00
|
|
|
|
|
|
|
#define VIR_FROM_THIS VIR_FROM_PARALLELS
|
2012-12-11 10:59:48 +00:00
|
|
|
#define PARALLELS_ROUTED_NETWORK_UUID "eb593dd1-6846-45b0-84a0-de0729286982"
|
2012-12-11 10:59:45 +00:00
|
|
|
|
2015-06-10 07:50:00 +00:00
|
|
|
#define vzParseError() \
|
2012-12-11 10:59:45 +00:00
|
|
|
virReportErrorHelper(VIR_FROM_TEST, VIR_ERR_OPERATION_FAILED, __FILE__, \
|
|
|
|
__FUNCTION__, __LINE__, _("Can't parse prlctl output"))
|
|
|
|
|
2015-06-10 07:50:00 +00:00
|
|
|
static int vzGetBridgedNetInfo(virNetworkDefPtr def, virJSONValuePtr jobj)
|
2012-12-11 10:59:47 +00:00
|
|
|
{
|
|
|
|
const char *ifname;
|
|
|
|
char *bridgeLink = NULL;
|
|
|
|
char *bridgePath = NULL;
|
|
|
|
char *bridgeAddressPath = NULL;
|
|
|
|
char *bridgeAddress = NULL;
|
|
|
|
int len = 0;
|
|
|
|
int ret = -1;
|
|
|
|
|
|
|
|
if (!(ifname = virJSONValueObjectGetString(jobj, "Bound To"))) {
|
2015-06-10 07:50:00 +00:00
|
|
|
vzParseError();
|
2012-12-11 10:59:47 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
2015-04-15 09:45:47 +00:00
|
|
|
if (virAsprintf(&bridgeLink, SYSFS_NET_DIR "%s/brport/bridge", ifname) < 0)
|
2012-12-11 10:59:47 +00:00
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
if (virFileResolveLink(bridgeLink, &bridgePath) < 0) {
|
|
|
|
virReportSystemError(errno, _("cannot read link '%s'"), bridgeLink);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
2013-05-03 12:46:03 +00:00
|
|
|
if (VIR_STRDUP(def->bridge, last_component(bridgePath)) < 0)
|
2012-12-11 10:59:47 +00:00
|
|
|
goto cleanup;
|
|
|
|
|
2015-04-15 09:45:47 +00:00
|
|
|
if (virAsprintf(&bridgeAddressPath, SYSFS_NET_DIR "%s/brport/bridge/address",
|
|
|
|
ifname) < 0)
|
2012-12-11 10:59:47 +00:00
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
if ((len = virFileReadAll(bridgeAddressPath, 18, &bridgeAddress)) < 0) {
|
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("Error reading file '%s'"), bridgeAddressPath);
|
|
|
|
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (len < VIR_MAC_STRING_BUFLEN) {
|
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("Error reading MAC from '%s'"), bridgeAddressPath);
|
|
|
|
}
|
|
|
|
|
|
|
|
bridgeAddress[VIR_MAC_STRING_BUFLEN - 1] = '\0';
|
|
|
|
if (virMacAddrParse(bridgeAddress, &def->mac) < 0) {
|
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("Can't parse MAC '%s'"), bridgeAddress);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
def->mac_specified = 1;
|
|
|
|
|
|
|
|
ret = 0;
|
|
|
|
|
2014-03-25 06:57:01 +00:00
|
|
|
cleanup:
|
2012-12-11 10:59:47 +00:00
|
|
|
VIR_FREE(bridgeLink);
|
|
|
|
VIR_FREE(bridgePath);
|
|
|
|
VIR_FREE(bridgeAddress);
|
|
|
|
VIR_FREE(bridgeAddressPath);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2015-06-10 07:50:00 +00:00
|
|
|
static int vzGetHostOnlyNetInfo(virNetworkDefPtr def, const char *name)
|
2012-12-11 10:59:47 +00:00
|
|
|
{
|
|
|
|
const char *tmp;
|
|
|
|
virJSONValuePtr jobj = NULL, jobj2;
|
|
|
|
int ret = -1;
|
|
|
|
|
2013-07-04 10:13:24 +00:00
|
|
|
if (VIR_EXPAND_N(def->ips, def->nips, 1) < 0)
|
2012-12-11 10:59:47 +00:00
|
|
|
goto cleanup;
|
|
|
|
|
2015-06-10 07:50:00 +00:00
|
|
|
jobj = vzParseOutput("prlsrvctl", "net", "info", "-j", name, NULL);
|
2012-12-11 10:59:47 +00:00
|
|
|
|
|
|
|
if (!jobj) {
|
2015-06-10 07:50:00 +00:00
|
|
|
vzParseError();
|
2012-12-11 10:59:47 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!(jobj2 = virJSONValueObjectGet(jobj, "Parallels adapter"))) {
|
2015-06-10 07:50:00 +00:00
|
|
|
vzParseError();
|
2012-12-11 10:59:47 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
2013-05-03 12:46:03 +00:00
|
|
|
if (VIR_STRDUP(def->ips[0].family, "ipv4") < 0)
|
2012-12-11 10:59:47 +00:00
|
|
|
goto cleanup;
|
2013-05-03 12:46:03 +00:00
|
|
|
|
2012-12-11 10:59:47 +00:00
|
|
|
if (!(tmp = virJSONValueObjectGetString(jobj2, "IP address"))) {
|
2015-06-10 07:50:00 +00:00
|
|
|
vzParseError();
|
2012-12-11 10:59:47 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (virSocketAddrParseIPv4(&def->ips[0].address, tmp) < 0) {
|
2015-06-10 07:50:00 +00:00
|
|
|
vzParseError();
|
2012-12-11 10:59:47 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!(tmp = virJSONValueObjectGetString(jobj2, "Subnet mask"))) {
|
2015-06-10 07:50:00 +00:00
|
|
|
vzParseError();
|
2012-12-11 10:59:47 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (virSocketAddrParseIPv4(&def->ips[0].netmask, tmp) < 0) {
|
2015-06-10 07:50:00 +00:00
|
|
|
vzParseError();
|
2012-12-11 10:59:47 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!(jobj2 = virJSONValueObjectGet(jobj, "DHCPv4 server"))) {
|
2015-06-10 07:50:00 +00:00
|
|
|
vzParseError();
|
2012-12-11 10:59:47 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
2013-07-04 10:13:24 +00:00
|
|
|
if (VIR_EXPAND_N(def->ips[0].ranges, def->ips[0].nranges, 1) < 0)
|
2012-12-11 10:59:47 +00:00
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
if (!(tmp = virJSONValueObjectGetString(jobj2, "IP scope start address"))) {
|
2015-06-10 07:50:00 +00:00
|
|
|
vzParseError();
|
2012-12-11 10:59:47 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (virSocketAddrParseIPv4(&def->ips[0].ranges[0].start, tmp) < 0) {
|
2015-06-10 07:50:00 +00:00
|
|
|
vzParseError();
|
2012-12-11 10:59:47 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!(tmp = virJSONValueObjectGetString(jobj2, "IP scope end address"))) {
|
2015-06-10 07:50:00 +00:00
|
|
|
vzParseError();
|
2012-12-11 10:59:47 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (virSocketAddrParseIPv4(&def->ips[0].ranges[0].end, tmp) < 0) {
|
2015-06-10 07:50:00 +00:00
|
|
|
vzParseError();
|
2012-12-11 10:59:47 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
ret = 0;
|
2014-03-25 06:57:01 +00:00
|
|
|
cleanup:
|
2012-12-11 10:59:47 +00:00
|
|
|
virJSONValueFree(jobj);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2015-03-18 08:33:52 +00:00
|
|
|
static int
|
2015-06-10 07:50:00 +00:00
|
|
|
vzLoadNetwork(vzConnPtr privconn, virJSONValuePtr jobj)
|
2012-12-11 10:59:45 +00:00
|
|
|
{
|
2015-03-18 08:33:52 +00:00
|
|
|
int ret = -1;
|
|
|
|
virNetworkObjPtr net = NULL;
|
2012-12-11 10:59:45 +00:00
|
|
|
virNetworkDefPtr def;
|
|
|
|
const char *tmp;
|
|
|
|
/* MD5_DIGEST_SIZE = VIR_UUID_BUFLEN = 16 */
|
|
|
|
unsigned char md5[MD5_DIGEST_SIZE];
|
|
|
|
|
|
|
|
if (VIR_ALLOC(def) < 0)
|
2013-07-04 10:13:24 +00:00
|
|
|
goto cleanup;
|
2012-12-11 10:59:45 +00:00
|
|
|
|
|
|
|
if (!(tmp = virJSONValueObjectGetString(jobj, "Network ID"))) {
|
2015-06-10 07:50:00 +00:00
|
|
|
vzParseError();
|
2012-12-11 10:59:45 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
2013-05-03 12:46:03 +00:00
|
|
|
if (VIR_STRDUP(def->name, tmp) < 0)
|
|
|
|
goto cleanup;
|
2012-12-11 10:59:45 +00:00
|
|
|
|
|
|
|
/* Network names are unique in Parallels Cloud Server, so we can make
|
2014-04-20 20:07:46 +00:00
|
|
|
* a UUID from it */
|
2012-12-11 10:59:45 +00:00
|
|
|
md5_buffer(tmp, strlen(tmp), md5);
|
|
|
|
memcpy(def->uuid, md5, VIR_UUID_BUFLEN);
|
|
|
|
def->uuid_specified = 1;
|
|
|
|
|
2012-12-11 10:59:47 +00:00
|
|
|
if (!(tmp = virJSONValueObjectGetString(jobj, "Type"))) {
|
2015-06-10 07:50:00 +00:00
|
|
|
vzParseError();
|
2012-12-11 10:59:47 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
2015-03-18 08:33:51 +00:00
|
|
|
if (STREQ(tmp, PARALLELS_BRIDGED_NETWORK_TYPE)) {
|
2012-12-11 10:59:47 +00:00
|
|
|
def->forward.type = VIR_NETWORK_FORWARD_BRIDGE;
|
|
|
|
|
2015-06-10 07:50:00 +00:00
|
|
|
if (vzGetBridgedNetInfo(def, jobj) < 0) {
|
2015-03-18 08:33:52 +00:00
|
|
|
|
|
|
|
/* Only mandatory networks are required to be configured completely */
|
|
|
|
if (STRNEQ(def->name, PARALLELS_REQUIRED_BRIDGED_NETWORK))
|
|
|
|
ret = 0;
|
|
|
|
|
2012-12-11 10:59:47 +00:00
|
|
|
goto cleanup;
|
2015-03-18 08:33:52 +00:00
|
|
|
}
|
2015-03-18 08:33:51 +00:00
|
|
|
} else if (STREQ(tmp, PARALLELS_HOSTONLY_NETWORK_TYPE)) {
|
2012-12-11 10:59:47 +00:00
|
|
|
def->forward.type = VIR_NETWORK_FORWARD_NONE;
|
|
|
|
|
2015-06-10 07:50:00 +00:00
|
|
|
if (vzGetHostOnlyNetInfo(def, def->name) < 0) {
|
2015-03-18 08:33:52 +00:00
|
|
|
|
|
|
|
/* Only mandatory networks are required to be configured completely */
|
|
|
|
if (STRNEQ(def->name, PARALLELS_REQUIRED_HOSTONLY_NETWORK))
|
|
|
|
ret = 0;
|
|
|
|
|
2012-12-11 10:59:47 +00:00
|
|
|
goto cleanup;
|
2015-03-18 08:33:52 +00:00
|
|
|
}
|
2012-12-11 10:59:47 +00:00
|
|
|
} else {
|
2015-06-10 07:50:00 +00:00
|
|
|
vzParseError();
|
2012-12-11 10:59:47 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
network_conf: Drop virNetworkObjIsDuplicate
This function does not make any sense now, that network driver is
(almost) dropped. I mean, previously, when threads were
serialized, this function was there to check, if no other network
with the same name or UUID exists. However, nowadays that threads
can run more in parallel, this function is useless, in fact it
gives misleading return values. Consider the following scenario.
Two threads, both trying to define networks with same name but
different UUID (e.g. because it was generated during XML parsing
phase, whatever). Lets assume that both threads are about to call
networkValidate() which immediately calls
virNetworkObjIsDuplicate().
T1: calls virNetworkObjIsDuplicate() and since no network with
given name or UUID exist, success is returned.
T2: calls virNetworkObjIsDuplicate() and since no network with
given name or UUID exist, success is returned.
T1: calls virNetworkAssignDef() and successfully places its
network into the virNetworkObjList.
T2: calls virNetworkAssignDef() and since network with the same
name exists, the network definition is replaced.
Okay, this is mainly because virNetworkAssignDef() does not check
whether name and UUID matches. Well, lets make it so! And drop
useless function too.
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
2015-03-14 10:18:21 +00:00
|
|
|
if (!(net = virNetworkAssignDef(privconn->networks, def, 0)))
|
2012-12-11 10:59:45 +00:00
|
|
|
goto cleanup;
|
2015-03-18 08:33:52 +00:00
|
|
|
def = NULL;
|
2012-12-11 10:59:45 +00:00
|
|
|
net->active = 1;
|
|
|
|
net->autostart = 1;
|
2015-03-18 08:33:52 +00:00
|
|
|
ret = 0;
|
2012-12-11 10:59:45 +00:00
|
|
|
|
2014-03-25 06:57:01 +00:00
|
|
|
cleanup:
|
2015-03-18 08:33:52 +00:00
|
|
|
virNetworkObjEndAPI(&net);
|
2012-12-11 10:59:45 +00:00
|
|
|
virNetworkDefFree(def);
|
2015-03-18 08:33:52 +00:00
|
|
|
return ret;
|
2012-12-11 10:59:45 +00:00
|
|
|
}
|
|
|
|
|
2015-03-18 08:33:52 +00:00
|
|
|
static int
|
2015-06-10 07:50:00 +00:00
|
|
|
vzAddRoutedNetwork(vzConnPtr privconn)
|
2012-12-11 10:59:48 +00:00
|
|
|
{
|
2015-02-25 16:38:54 +00:00
|
|
|
virNetworkObjPtr net = NULL;
|
2012-12-11 10:59:48 +00:00
|
|
|
virNetworkDefPtr def;
|
|
|
|
|
|
|
|
if (VIR_ALLOC(def) < 0)
|
2013-07-04 10:13:24 +00:00
|
|
|
goto cleanup;
|
2012-12-11 10:59:48 +00:00
|
|
|
|
|
|
|
def->forward.type = VIR_NETWORK_FORWARD_ROUTE;
|
|
|
|
|
2015-03-18 08:33:51 +00:00
|
|
|
if (VIR_STRDUP(def->name, PARALLELS_DOMAIN_ROUTED_NETWORK_NAME) < 0)
|
2013-05-03 12:46:03 +00:00
|
|
|
goto cleanup;
|
2012-12-11 10:59:48 +00:00
|
|
|
|
|
|
|
if (virUUIDParse(PARALLELS_ROUTED_NETWORK_UUID, def->uuid) < 0) {
|
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
|
|
|
_("Can't parse UUID"));
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
def->uuid_specified = 1;
|
|
|
|
|
network_conf: Drop virNetworkObjIsDuplicate
This function does not make any sense now, that network driver is
(almost) dropped. I mean, previously, when threads were
serialized, this function was there to check, if no other network
with the same name or UUID exists. However, nowadays that threads
can run more in parallel, this function is useless, in fact it
gives misleading return values. Consider the following scenario.
Two threads, both trying to define networks with same name but
different UUID (e.g. because it was generated during XML parsing
phase, whatever). Lets assume that both threads are about to call
networkValidate() which immediately calls
virNetworkObjIsDuplicate().
T1: calls virNetworkObjIsDuplicate() and since no network with
given name or UUID exist, success is returned.
T2: calls virNetworkObjIsDuplicate() and since no network with
given name or UUID exist, success is returned.
T1: calls virNetworkAssignDef() and successfully places its
network into the virNetworkObjList.
T2: calls virNetworkAssignDef() and since network with the same
name exists, the network definition is replaced.
Okay, this is mainly because virNetworkAssignDef() does not check
whether name and UUID matches. Well, lets make it so! And drop
useless function too.
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
2015-03-14 10:18:21 +00:00
|
|
|
if (!(net = virNetworkAssignDef(privconn->networks, def, 0)))
|
2012-12-11 10:59:48 +00:00
|
|
|
goto cleanup;
|
2015-03-18 08:33:52 +00:00
|
|
|
|
2012-12-11 10:59:48 +00:00
|
|
|
net->active = 1;
|
|
|
|
net->autostart = 1;
|
2015-03-18 08:33:52 +00:00
|
|
|
virNetworkObjEndAPI(&net);
|
2012-12-11 10:59:48 +00:00
|
|
|
|
2015-03-18 08:33:52 +00:00
|
|
|
return 0;
|
2012-12-11 10:59:48 +00:00
|
|
|
|
2014-03-25 06:57:01 +00:00
|
|
|
cleanup:
|
2012-12-11 10:59:48 +00:00
|
|
|
virNetworkDefFree(def);
|
2015-03-18 08:33:52 +00:00
|
|
|
return -1;
|
2012-12-11 10:59:48 +00:00
|
|
|
}
|
|
|
|
|
2015-06-10 07:50:00 +00:00
|
|
|
static int vzLoadNetworks(vzConnPtr privconn)
|
2012-12-11 10:59:45 +00:00
|
|
|
{
|
|
|
|
virJSONValuePtr jobj, jobj2;
|
|
|
|
int ret = -1;
|
Convert 'int i' to 'size_t i' in src/parallels/ files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
int count;
|
|
|
|
size_t i;
|
2012-12-11 10:59:45 +00:00
|
|
|
|
2015-06-10 07:50:00 +00:00
|
|
|
jobj = vzParseOutput("prlsrvctl", "net", "list", "-j", NULL);
|
2012-12-11 10:59:45 +00:00
|
|
|
|
|
|
|
if (!jobj) {
|
2015-06-10 07:50:00 +00:00
|
|
|
vzParseError();
|
2012-12-11 10:59:45 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
count = virJSONValueArraySize(jobj);
|
|
|
|
if (count < 0) {
|
2015-06-10 07:50:00 +00:00
|
|
|
vzParseError();
|
2012-12-11 10:59:45 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (i = 0; i < count; i++) {
|
|
|
|
jobj2 = virJSONValueArrayGet(jobj, i);
|
|
|
|
if (!jobj2) {
|
2015-06-10 07:50:00 +00:00
|
|
|
vzParseError();
|
2012-12-11 10:59:45 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
2015-06-10 07:50:00 +00:00
|
|
|
if (vzLoadNetwork(privconn, jobj2) < 0)
|
2012-12-11 10:59:45 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
2015-06-10 07:50:00 +00:00
|
|
|
if (vzAddRoutedNetwork(privconn) < 0)
|
2012-12-11 10:59:48 +00:00
|
|
|
goto cleanup;
|
|
|
|
|
2012-12-11 10:59:45 +00:00
|
|
|
ret = 0;
|
|
|
|
|
2014-03-25 06:57:01 +00:00
|
|
|
cleanup:
|
2012-12-11 10:59:45 +00:00
|
|
|
virJSONValueFree(jobj);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2015-01-20 16:16:26 +00:00
|
|
|
virDrvOpenStatus
|
2015-06-10 07:50:00 +00:00
|
|
|
vzNetworkOpen(virConnectPtr conn,
|
2012-12-11 10:59:45 +00:00
|
|
|
unsigned int flags)
|
|
|
|
{
|
2015-06-10 07:50:00 +00:00
|
|
|
vzConnPtr privconn = conn->privateData;
|
2015-02-23 14:55:24 +00:00
|
|
|
|
2012-12-11 10:59:45 +00:00
|
|
|
virCheckFlags(VIR_CONNECT_RO, VIR_DRV_OPEN_ERROR);
|
|
|
|
|
2015-05-26 17:12:00 +00:00
|
|
|
if (STRNEQ(conn->driver->name, "vz") &&
|
|
|
|
STRNEQ(conn->driver->name, "Parallels"))
|
2012-12-11 10:59:45 +00:00
|
|
|
return VIR_DRV_OPEN_DECLINED;
|
|
|
|
|
2015-02-24 12:45:45 +00:00
|
|
|
if (!(privconn->networks = virNetworkObjListNew()))
|
2015-02-23 14:55:24 +00:00
|
|
|
goto error;
|
|
|
|
|
2015-06-10 07:50:00 +00:00
|
|
|
if (vzLoadNetworks(conn->privateData) < 0)
|
2015-02-23 14:55:24 +00:00
|
|
|
goto error;
|
2012-12-11 10:59:45 +00:00
|
|
|
|
|
|
|
return VIR_DRV_OPEN_SUCCESS;
|
2015-02-23 14:55:24 +00:00
|
|
|
error:
|
2015-02-24 12:45:45 +00:00
|
|
|
virObjectUnref(privconn->networks);
|
2015-03-19 14:43:21 +00:00
|
|
|
privconn->networks = NULL;
|
2015-04-20 06:24:00 +00:00
|
|
|
return VIR_DRV_OPEN_ERROR;
|
2012-12-11 10:59:45 +00:00
|
|
|
}
|
|
|
|
|
2015-06-10 07:50:00 +00:00
|
|
|
int vzNetworkClose(virConnectPtr conn)
|
2012-12-11 10:59:45 +00:00
|
|
|
{
|
2015-06-10 07:50:00 +00:00
|
|
|
vzConnPtr privconn = conn->privateData;
|
2015-02-26 16:13:53 +00:00
|
|
|
|
|
|
|
if (!privconn)
|
|
|
|
return 0;
|
|
|
|
|
2015-02-24 12:45:45 +00:00
|
|
|
virObjectUnref(privconn->networks);
|
2012-12-11 10:59:45 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2015-06-10 07:50:00 +00:00
|
|
|
static int vzConnectNumOfNetworks(virConnectPtr conn)
|
2012-12-11 10:59:45 +00:00
|
|
|
{
|
2015-02-24 10:32:52 +00:00
|
|
|
int nactive;
|
2015-06-10 07:50:00 +00:00
|
|
|
vzConnPtr privconn = conn->privateData;
|
2012-12-11 10:59:45 +00:00
|
|
|
|
2015-02-24 10:32:52 +00:00
|
|
|
nactive = virNetworkObjListNumOfNetworks(privconn->networks,
|
|
|
|
true, NULL, conn);
|
2012-12-11 10:59:45 +00:00
|
|
|
return nactive;
|
|
|
|
}
|
|
|
|
|
2015-06-10 07:50:00 +00:00
|
|
|
static int vzConnectListNetworks(virConnectPtr conn,
|
2013-04-23 12:50:18 +00:00
|
|
|
char **const names,
|
|
|
|
int nnames)
|
2012-12-11 10:59:45 +00:00
|
|
|
{
|
2015-06-10 07:50:00 +00:00
|
|
|
vzConnPtr privconn = conn->privateData;
|
2015-02-24 10:32:52 +00:00
|
|
|
int got;
|
2012-12-11 10:59:45 +00:00
|
|
|
|
2015-02-24 10:32:52 +00:00
|
|
|
got = virNetworkObjListGetNames(privconn->networks,
|
|
|
|
true, names, nnames, NULL, conn);
|
2012-12-11 10:59:45 +00:00
|
|
|
return got;
|
|
|
|
}
|
|
|
|
|
2015-06-10 07:50:00 +00:00
|
|
|
static int vzConnectNumOfDefinedNetworks(virConnectPtr conn)
|
2012-12-11 10:59:45 +00:00
|
|
|
{
|
2015-02-24 10:32:52 +00:00
|
|
|
int ninactive;
|
2015-06-10 07:50:00 +00:00
|
|
|
vzConnPtr privconn = conn->privateData;
|
2012-12-11 10:59:45 +00:00
|
|
|
|
2015-02-24 10:32:52 +00:00
|
|
|
ninactive = virNetworkObjListNumOfNetworks(privconn->networks,
|
|
|
|
false, NULL, conn);
|
2012-12-11 10:59:45 +00:00
|
|
|
return ninactive;
|
|
|
|
}
|
|
|
|
|
2015-06-10 07:50:00 +00:00
|
|
|
static int vzConnectListDefinedNetworks(virConnectPtr conn,
|
2013-04-23 12:50:18 +00:00
|
|
|
char **const names,
|
|
|
|
int nnames)
|
2012-12-11 10:59:45 +00:00
|
|
|
{
|
2015-06-10 07:50:00 +00:00
|
|
|
vzConnPtr privconn = conn->privateData;
|
2015-02-24 10:32:52 +00:00
|
|
|
int got;
|
2012-12-11 10:59:45 +00:00
|
|
|
|
2015-02-24 10:32:52 +00:00
|
|
|
got = virNetworkObjListGetNames(privconn->networks,
|
|
|
|
false, names, nnames, NULL, conn);
|
2012-12-11 10:59:45 +00:00
|
|
|
return got;
|
|
|
|
}
|
|
|
|
|
2015-06-10 07:50:00 +00:00
|
|
|
static int vzConnectListAllNetworks(virConnectPtr conn,
|
2013-04-23 12:50:18 +00:00
|
|
|
virNetworkPtr **nets,
|
|
|
|
unsigned int flags)
|
2012-12-11 10:59:45 +00:00
|
|
|
{
|
2015-06-10 07:50:00 +00:00
|
|
|
vzConnPtr privconn = conn->privateData;
|
2012-12-11 10:59:45 +00:00
|
|
|
|
|
|
|
virCheckFlags(VIR_CONNECT_LIST_NETWORKS_FILTERS_ALL, -1);
|
|
|
|
|
2015-02-26 13:36:47 +00:00
|
|
|
return virNetworkObjListExport(conn, privconn->networks, nets, NULL, flags);
|
2012-12-11 10:59:45 +00:00
|
|
|
}
|
|
|
|
|
2015-06-10 07:50:00 +00:00
|
|
|
static virNetworkPtr vzNetworkLookupByUUID(virConnectPtr conn,
|
2012-12-11 10:59:45 +00:00
|
|
|
const unsigned char *uuid)
|
|
|
|
{
|
2015-06-10 07:50:00 +00:00
|
|
|
vzConnPtr privconn = conn->privateData;
|
2012-12-11 10:59:45 +00:00
|
|
|
virNetworkObjPtr network;
|
|
|
|
virNetworkPtr ret = NULL;
|
|
|
|
|
2015-02-23 15:57:29 +00:00
|
|
|
network = virNetworkObjFindByUUID(privconn->networks, uuid);
|
2012-12-11 10:59:45 +00:00
|
|
|
if (!network) {
|
|
|
|
virReportError(VIR_ERR_NO_NETWORK,
|
|
|
|
"%s", _("no network with matching uuid"));
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
ret = virGetNetwork(conn, network->def->name, network->def->uuid);
|
|
|
|
|
2014-03-25 06:57:01 +00:00
|
|
|
cleanup:
|
2015-02-25 16:38:54 +00:00
|
|
|
virNetworkObjEndAPI(&network);
|
2012-12-11 10:59:45 +00:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2015-06-10 07:50:00 +00:00
|
|
|
static virNetworkPtr vzNetworkLookupByName(virConnectPtr conn,
|
2012-12-11 10:59:45 +00:00
|
|
|
const char *name)
|
|
|
|
{
|
2015-06-10 07:50:00 +00:00
|
|
|
vzConnPtr privconn = conn->privateData;
|
2012-12-11 10:59:45 +00:00
|
|
|
virNetworkObjPtr network;
|
|
|
|
virNetworkPtr ret = NULL;
|
|
|
|
|
2015-02-23 16:05:52 +00:00
|
|
|
network = virNetworkObjFindByName(privconn->networks, name);
|
2012-12-11 10:59:45 +00:00
|
|
|
if (!network) {
|
|
|
|
virReportError(VIR_ERR_NO_NETWORK,
|
|
|
|
_("no network with matching name '%s'"), name);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
ret = virGetNetwork(conn, network->def->name, network->def->uuid);
|
|
|
|
|
2014-03-25 06:57:01 +00:00
|
|
|
cleanup:
|
2015-02-25 16:38:54 +00:00
|
|
|
virNetworkObjEndAPI(&network);
|
2012-12-11 10:59:45 +00:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2015-06-10 07:50:00 +00:00
|
|
|
static char *vzNetworkGetXMLDesc(virNetworkPtr net,
|
2012-12-11 10:59:45 +00:00
|
|
|
unsigned int flags)
|
|
|
|
{
|
2015-06-10 07:50:00 +00:00
|
|
|
vzConnPtr privconn = net->conn->privateData;
|
2012-12-11 10:59:45 +00:00
|
|
|
virNetworkObjPtr network;
|
|
|
|
char *ret = NULL;
|
|
|
|
|
|
|
|
virCheckFlags(VIR_NETWORK_XML_INACTIVE, NULL);
|
|
|
|
|
2015-02-23 15:57:29 +00:00
|
|
|
network = virNetworkObjFindByUUID(privconn->networks, net->uuid);
|
2012-12-11 10:59:45 +00:00
|
|
|
if (!network) {
|
|
|
|
virReportError(VIR_ERR_NO_NETWORK,
|
|
|
|
"%s", _("no network with matching uuid"));
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
ret = virNetworkDefFormat(network->def, flags);
|
|
|
|
|
2014-03-25 06:57:01 +00:00
|
|
|
cleanup:
|
2015-02-25 16:38:54 +00:00
|
|
|
virNetworkObjEndAPI(&network);
|
2012-12-11 10:59:45 +00:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2015-06-10 07:50:00 +00:00
|
|
|
static int vzNetworkIsActive(virNetworkPtr net)
|
2012-12-11 10:59:45 +00:00
|
|
|
{
|
2015-06-10 07:50:00 +00:00
|
|
|
vzConnPtr privconn = net->conn->privateData;
|
2012-12-11 10:59:45 +00:00
|
|
|
virNetworkObjPtr obj;
|
|
|
|
int ret = -1;
|
|
|
|
|
2015-02-23 15:57:29 +00:00
|
|
|
obj = virNetworkObjFindByUUID(privconn->networks, net->uuid);
|
2012-12-11 10:59:45 +00:00
|
|
|
if (!obj) {
|
|
|
|
virReportError(VIR_ERR_NO_NETWORK, NULL);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
ret = virNetworkObjIsActive(obj);
|
|
|
|
|
2014-03-25 06:57:01 +00:00
|
|
|
cleanup:
|
2015-02-25 16:38:54 +00:00
|
|
|
virNetworkObjEndAPI(&obj);
|
2012-12-11 10:59:45 +00:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2015-06-10 07:50:00 +00:00
|
|
|
static int vzNetworkIsPersistent(virNetworkPtr net)
|
2012-12-11 10:59:45 +00:00
|
|
|
{
|
2015-06-10 07:50:00 +00:00
|
|
|
vzConnPtr privconn = net->conn->privateData;
|
2012-12-11 10:59:45 +00:00
|
|
|
virNetworkObjPtr obj;
|
|
|
|
int ret = -1;
|
|
|
|
|
2015-02-23 15:57:29 +00:00
|
|
|
obj = virNetworkObjFindByUUID(privconn->networks, net->uuid);
|
2012-12-11 10:59:45 +00:00
|
|
|
if (!obj) {
|
|
|
|
virReportError(VIR_ERR_NO_NETWORK, NULL);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
ret = obj->persistent;
|
|
|
|
|
2014-03-25 06:57:01 +00:00
|
|
|
cleanup:
|
2015-02-25 16:38:54 +00:00
|
|
|
virNetworkObjEndAPI(&obj);
|
2012-12-11 10:59:45 +00:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2015-06-10 07:50:00 +00:00
|
|
|
static int vzNetworkGetAutostart(virNetworkPtr net,
|
2012-12-11 10:59:45 +00:00
|
|
|
int *autostart)
|
|
|
|
{
|
2015-06-10 07:50:00 +00:00
|
|
|
vzConnPtr privconn = net->conn->privateData;
|
2012-12-11 10:59:45 +00:00
|
|
|
virNetworkObjPtr network;
|
|
|
|
int ret = -1;
|
|
|
|
|
2015-02-23 15:57:29 +00:00
|
|
|
network = virNetworkObjFindByUUID(privconn->networks, net->uuid);
|
2012-12-11 10:59:45 +00:00
|
|
|
if (!network) {
|
|
|
|
virReportError(VIR_ERR_NO_NETWORK,
|
|
|
|
"%s", _("no network with matching uuid"));
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
*autostart = network->autostart;
|
|
|
|
ret = 0;
|
|
|
|
|
2014-03-25 06:57:01 +00:00
|
|
|
cleanup:
|
2015-02-25 16:38:54 +00:00
|
|
|
virNetworkObjEndAPI(&network);
|
2012-12-11 10:59:45 +00:00
|
|
|
return ret;
|
|
|
|
}
|
2015-01-20 16:16:26 +00:00
|
|
|
|
2015-06-10 07:50:00 +00:00
|
|
|
virNetworkDriver vzNetworkDriver = {
|
2015-01-20 16:16:26 +00:00
|
|
|
.name = "Parallels",
|
2015-06-10 07:50:00 +00:00
|
|
|
.connectNumOfNetworks = vzConnectNumOfNetworks, /* 1.0.1 */
|
|
|
|
.connectListNetworks = vzConnectListNetworks, /* 1.0.1 */
|
|
|
|
.connectNumOfDefinedNetworks = vzConnectNumOfDefinedNetworks, /* 1.0.1 */
|
|
|
|
.connectListDefinedNetworks = vzConnectListDefinedNetworks, /* 1.0.1 */
|
|
|
|
.connectListAllNetworks = vzConnectListAllNetworks, /* 1.0.1 */
|
|
|
|
.networkLookupByUUID = vzNetworkLookupByUUID, /* 1.0.1 */
|
|
|
|
.networkLookupByName = vzNetworkLookupByName, /* 1.0.1 */
|
|
|
|
.networkGetXMLDesc = vzNetworkGetXMLDesc, /* 1.0.1 */
|
|
|
|
.networkGetAutostart = vzNetworkGetAutostart, /* 1.0.1 */
|
|
|
|
.networkIsActive = vzNetworkIsActive, /* 1.0.1 */
|
|
|
|
.networkIsPersistent = vzNetworkIsPersistent, /* 1.0.1 */
|
2012-12-11 10:59:45 +00:00
|
|
|
};
|