[libvirt] [PATCH] qemu: Fix compilation error when enum variable size differs from 'int'
by Peter Krempa
Since commit bcd9a564b631aa virDomainNumatuneGetMode returns the value
via a pointer rather than in the return value. The change triggered
problems with platforms where the compiler decides to use a data type of
size different than integer at the point where we typecast it.
Work around the issue by using an intermediate variable of the correct
type that gets casted back by the default typecasting rules.
---
src/qemu/qemu_driver.c | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index aa0acde..2b9f125 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -10566,14 +10566,16 @@ qemuDomainGetNumaParameters(virDomainPtr dom,
virMemoryParameterPtr param = ¶ms[i];
switch (i) {
- case 0: /* fill numa mode here */
+ case 0: { /* fill numa mode here */
+ virDomainNumatuneMemMode tmp;
+ virDomainNumatuneGetMode(def->numa, -1, &tmp);
+
if (virTypedParameterAssign(param, VIR_DOMAIN_NUMA_MODE,
- VIR_TYPED_PARAM_INT, 0) < 0)
+ VIR_TYPED_PARAM_INT, tmp) < 0)
goto cleanup;
- virDomainNumatuneGetMode(def->numa, -1,
- (virDomainNumatuneMemMode *) ¶m->value.i);
break;
+ }
case 1: /* fill numa nodeset here */
nodeset = virDomainNumatuneFormatNodeset(def->numa, NULL, -1);
--
2.4.1
9 years, 7 months
[libvirt] [PATCH 0/5] Selective block device migration implementation
by Pavel Boldin
The patchset represented in the mail thread implements the selective block
device migration for the QEMU driver. This closes the referenced bug [1].
First the supplementary API implemented allowing for multiple key-values pair
in the virTypedParameter arrays. This is used to pass the list of block
devices to migrate in the following patches. Unit tests for this are added as
well. This is the subject of the first three patches.
Fourth patch is adding the necessary parameter `migrate_disks' and passes it
through the QEMU driver call stack. The introduced `qemuMigrateBlockDevice'
function is then checks that the disk is to be migrated because it is in the
list. If there is no list specified then the legacy check is used: the device
is not shared, not readonly and has a source.
Fifth and the last patch is adding the necessary code to the `virsh' utility
making it able for user to specify a comma-separated list of the block device
names that are to be migrated.
The implemented Python bindings patch is to be presented.
[1] https://bugzilla.redhat.com/show_bug.cgi?id=1203032
Pavel Boldin (5):
util: multi-value virTypedParameter
util: virTypedParamsPick* multikey API
util: add virTypedParamsPackStrings
qemu: migration: selective block device migration
virsh: selective block device migration
include/libvirt/libvirt-domain.h | 9 ++
include/libvirt/libvirt-host.h | 24 ++++
src/libvirt_public.syms | 3 +
src/qemu/qemu_driver.c | 63 ++++++---
src/qemu/qemu_migration.c | 197 ++++++++++++++++----------
src/qemu/qemu_migration.h | 23 ++--
src/util/virtypedparam.c | 290 +++++++++++++++++++++++++++++++--------
tests/Makefile.am | 6 +
tests/virtypedparamtest.c | 289 ++++++++++++++++++++++++++++++++++++++
tools/virsh-domain.c | 44 ++++++
10 files changed, 788 insertions(+), 160 deletions(-)
create mode 100644 tests/virtypedparamtest.c
--
1.9.1
9 years, 7 months
[libvirt] [PATCH v3 0/4] storage: fs: tweak dir perms handling on build
by Cole Robinson
Consider the following issue
- Using virt-manager with qemu:///session
- User adds a storage pool pointing at /tmp. No explicit permissions are
requested in the XML
- virt-manager calls PoolDefine, then PoolBuild
- libvirt tries to unconditionally chmod 755 /tmp. This fails because my
user doesn't own root. Pool build fails, virt-manager reports failure
Yes there's a couple ways we could avoid this specific case in
virt-manager, but I think it makes more sense to have pool.build on
a directory be a no-op in this case. The following patches address this.
I already pushed some bits of v2 of the series. Now the patches are:
- Patch 1 (new) update existing docs about storage <permissions>
- Patch 2 changes storage XML to not hardcode a <mode> value if the user
didn't specify one in.
- Patch 3 (new) don't output empty <permissions> block
- Patch 4 makes pool.build skip dir chmod unless the user explicitly
requested <mode> via the XML. However if a mode is required for mkdir,
continue to use the previous default.
Cole Robinson (4):
docs: formatstorage: Update <permissions> docs
storage: conf: Don't set any default <mode> in the XML
conf: storage: Don't emit empty <permissions> block
storage: fs: Only force directory permissions if required
docs/formatstorage.html.in | 40 ++++++++-----
docs/schemas/storagecommon.rng | 8 ++-
src/conf/storage_conf.c | 70 ++++++++++++----------
src/storage/storage_backend.c | 20 +++++--
src/storage/storage_backend.h | 3 +
src/storage/storage_backend_fs.c | 32 ++++++----
src/storage/storage_backend_logical.c | 4 +-
src/util/virfile.c | 4 +-
tests/storagepoolxml2xmlout/pool-netfs-gluster.xml | 3 -
tests/storagevolxml2xmlout/vol-gluster-dir.xml | 3 -
tests/storagevolxml2xmlout/vol-sheepdog.xml | 3 -
11 files changed, 113 insertions(+), 77 deletions(-)
--
2.4.1
9 years, 7 months
[libvirt] [PATCH 0/8] parallels: add vz driver
by Maxim Nestratov
This new driver 'vz' will be used as a substitution for parallels driver.
New domains will be created with 'vz' domain type. Old 'parallels' domains
remain supported. Connection to the driver can be made either way:
vz:///system or parallels:///system.
Maxim Nestratov (8):
parallels: introduce vz driver constant and string
parallels: use newly introduced VIR_DOMAIN_VIRT_VZ
parallels: add new guest capabilities assigned to vz driver
parallels: accept vz as a driver uri and name
parallels: add a new vz connection driver and hypervisor structures
parallels: increment the number of connection drivers
parallels: recommend to connect to vz:///system when connection fails
parallels: set VIR_DOMAIN_VIRT_VZ virtType for new domains
src/conf/domain_conf.c | 19 +++++++++-----
src/conf/domain_conf.h | 1 +
src/libvirt.c | 2 +-
src/parallels/parallels_driver.c | 52 ++++++++++++++++++++++++++++++++++-----
src/parallels/parallels_network.c | 3 ++-
src/parallels/parallels_sdk.c | 2 +-
src/parallels/parallels_storage.c | 3 ++-
7 files changed, 66 insertions(+), 16 deletions(-)
--
2.1.0
9 years, 7 months
[libvirt] [PATCH 0/2 v2] parallels: fix prlsdkLoadDomain
by Maxim Nestratov
Maxim Nestratov (2):
parallels: move up updating parameter in prlsdkLoadDomain
parallels: fix possible crash in case of errors in prlsdkLoadDomain
src/parallels/parallels_sdk.c | 35 +++++++++++++++++++++++------------
1 file changed, 23 insertions(+), 12 deletions(-)
--
2.1.0
9 years, 7 months
[libvirt] [PATCH] rpc: add testing of RPC JSON (de)serialization
by Daniel P. Berrange
The virNetServer class has the ability to serialize its state
to a JSON file, and then re-load that data after an in-place
execve() call to re-connect to active file handles. This data
format is critical ABI that must have compatibility across
releases, so it should be tested...
---
src/libvirt_remote.syms | 1 +
src/rpc/virnetserver.c | 4 +-
src/rpc/virnetserver.h | 3 +
src/rpc/virnetserverclient.c | 13 +-
src/rpc/virnetserverservice.c | 6 +-
tests/Makefile.am | 7 +
tests/virnetserverdata/README | 14 +
.../virnetserverdata/input-data-anon-clients.json | 63 +++++
tests/virnetserverdata/input-data-initial.json | 62 +++++
.../virnetserverdata/output-data-anon-clients.json | 63 +++++
tests/virnetserverdata/output-data-initial.json | 63 +++++
tests/virnetservertest.c | 290 +++++++++++++++++++++
12 files changed, 579 insertions(+), 10 deletions(-)
create mode 100644 tests/virnetserverdata/README
create mode 100644 tests/virnetserverdata/input-data-anon-clients.json
create mode 100644 tests/virnetserverdata/input-data-initial.json
create mode 100644 tests/virnetserverdata/output-data-anon-clients.json
create mode 100644 tests/virnetserverdata/output-data-initial.json
create mode 100644 tests/virnetservertest.c
diff --git a/src/libvirt_remote.syms b/src/libvirt_remote.syms
index 950e56e..bdd68f6 100644
--- a/src/libvirt_remote.syms
+++ b/src/libvirt_remote.syms
@@ -77,6 +77,7 @@ xdr_virNetMessageError;
# rpc/virnetserver.h
+virNetServerAddClient;
virNetServerAddProgram;
virNetServerAddService;
virNetServerAddShutdownInhibition;
diff --git a/src/rpc/virnetserver.c b/src/rpc/virnetserver.c
index 42427dc..091a1dc 100644
--- a/src/rpc/virnetserver.c
+++ b/src/rpc/virnetserver.c
@@ -259,8 +259,8 @@ static int virNetServerDispatchNewMessage(virNetServerClientPtr client,
}
-static int virNetServerAddClient(virNetServerPtr srv,
- virNetServerClientPtr client)
+int virNetServerAddClient(virNetServerPtr srv,
+ virNetServerClientPtr client)
{
virObjectLock(srv);
diff --git a/src/rpc/virnetserver.h b/src/rpc/virnetserver.h
index 8c5ae07..4b452be 100644
--- a/src/rpc/virnetserver.h
+++ b/src/rpc/virnetserver.h
@@ -79,6 +79,9 @@ int virNetServerAddService(virNetServerPtr srv,
virNetServerServicePtr svc,
const char *mdnsEntryName);
+int virNetServerAddClient(virNetServerPtr srv,
+ virNetServerClientPtr client);
+
int virNetServerAddProgram(virNetServerPtr srv,
virNetServerProgramPtr prog);
diff --git a/src/rpc/virnetserverclient.c b/src/rpc/virnetserverclient.c
index 34c1994..0e3a71f 100644
--- a/src/rpc/virnetserverclient.c
+++ b/src/rpc/virnetserverclient.c
@@ -536,13 +536,14 @@ virJSONValuePtr virNetServerClientPreExecRestart(virNetServerClientPtr client)
goto error;
}
- if (client->privateData && client->privateDataPreExecRestart &&
- !(child = client->privateDataPreExecRestart(client, client->privateData)))
- goto error;
+ if (client->privateData && client->privateDataPreExecRestart) {
+ if (!(child = client->privateDataPreExecRestart(client, client->privateData)))
+ goto error;
- if (virJSONValueObjectAppend(object, "privateData", child) < 0) {
- virJSONValueFree(child);
- goto error;
+ if (virJSONValueObjectAppend(object, "privateData", child) < 0) {
+ virJSONValueFree(child);
+ goto error;
+ }
}
virObjectUnlock(client);
diff --git a/src/rpc/virnetserverservice.c b/src/rpc/virnetserverservice.c
index d3cf31a..4df26cb 100644
--- a/src/rpc/virnetserverservice.c
+++ b/src/rpc/virnetserverservice.c
@@ -303,12 +303,15 @@ virNetServerServicePtr virNetServerServiceNewFD(int fd,
/* IO callback is initially disabled, until we're ready
* to deal with incoming clients */
+ virObjectRef(svc);
if (virNetSocketAddIOCallback(svc->socks[i],
0,
virNetServerServiceAccept,
svc,
- virObjectFreeCallback) < 0)
+ virObjectFreeCallback) < 0) {
+ virObjectUnref(svc);
goto error;
+ }
}
@@ -388,7 +391,6 @@ virNetServerServicePtr virNetServerServiceNewPostExecRestart(virJSONValuePtr obj
svc,
virObjectFreeCallback) < 0) {
virObjectUnref(svc);
- virObjectUnref(sock);
goto error;
}
}
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 8e2dbec..c9e2c8a 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -188,6 +188,7 @@ if WITH_REMOTE
test_programs += \
virnetmessagetest \
virnetsockettest \
+ virnetservertest \
virnetserverclienttest \
$(NULL)
if WITH_GNUTLS
@@ -921,6 +922,12 @@ virnetsockettest_SOURCES = \
virnetsockettest.c testutils.h testutils.c
virnetsockettest_LDADD = $(LDADDS)
+virnetservertest_SOURCES = \
+ virnetservertest.c \
+ testutils.h testutils.c
+virnetservertest_CFLAGS = $(XDR_CFLAGS) $(AM_CFLAGS)
+virnetservertest_LDADD = $(LDADDS)
+
virnetserverclienttest_SOURCES = \
virnetserverclienttest.c \
testutils.h testutils.c
diff --git a/tests/virnetserverdata/README b/tests/virnetserverdata/README
new file mode 100644
index 0000000..d6d79d2
--- /dev/null
+++ b/tests/virnetserverdata/README
@@ -0,0 +1,14 @@
+ virnetservertest data files
+ ===========================
+
+The various input-data-*.json files are a record of all the historical
+formats that libvirt has been able to produce data for. Everytime a
+new field is added to the JSON output, a *new* input data file should
+be created. We must not add new fields to existing input-data files,
+nor must we ever re-structure them if code changes, as we must check
+new code handles the legacy formats.
+
+The various output-data-*.json files are the record of what the *new*
+JSON output should look like for the correspondingly named input-data
+file. It is permissible to change the existing output-data-*.json
+files if the format we save in is updated.
diff --git a/tests/virnetserverdata/input-data-anon-clients.json b/tests/virnetserverdata/input-data-anon-clients.json
new file mode 100644
index 0000000..ed91b57
--- /dev/null
+++ b/tests/virnetserverdata/input-data-anon-clients.json
@@ -0,0 +1,63 @@
+{
+ "min_workers": 10,
+ "max_workers": 50,
+ "priority_workers": 5,
+ "max_clients": 100,
+ "max_anonymous_clients": 10,
+ "keepaliveInterval": 120,
+ "keepaliveCount": 5,
+ "keepaliveRequired": true,
+ "mdnsGroupName": "libvirtTest",
+ "services": [
+ {
+ "auth": 0,
+ "readonly": true,
+ "nrequests_client_max": 2,
+ "socks": [
+ {
+ "fd": 100,
+ "errfd": -1,
+ "pid": 0,
+ "isClient": false
+ }
+ ]
+ },
+ {
+ "auth": 2,
+ "readonly": false,
+ "nrequests_client_max": 5,
+ "socks": [
+ {
+ "fd": 101,
+ "errfd": -1,
+ "pid": 0,
+ "isClient": false
+ }
+ ]
+ }
+ ],
+ "clients": [
+ {
+ "auth": 1,
+ "readonly": true,
+ "nrequests_max": 15,
+ "sock": {
+ "fd": 102,
+ "errfd": -1,
+ "pid": -1,
+ "isClient": true
+ }
+ },
+ {
+ "auth": 2,
+ "readonly": true,
+ "nrequests_max": 66,
+ "sock": {
+ "fd": 103,
+ "errfd": -1,
+ "pid": -1,
+ "isClient": true
+ }
+ }
+ ]
+}
diff --git a/tests/virnetserverdata/input-data-initial.json b/tests/virnetserverdata/input-data-initial.json
new file mode 100644
index 0000000..7956225
--- /dev/null
+++ b/tests/virnetserverdata/input-data-initial.json
@@ -0,0 +1,62 @@
+{
+ "min_workers": 10,
+ "max_workers": 50,
+ "priority_workers": 5,
+ "max_clients": 100,
+ "keepaliveInterval": 120,
+ "keepaliveCount": 5,
+ "keepaliveRequired": true,
+ "mdnsGroupName": "libvirtTest",
+ "services": [
+ {
+ "auth": 0,
+ "readonly": true,
+ "nrequests_client_max": 2,
+ "socks": [
+ {
+ "fd": 100,
+ "errfd": -1,
+ "pid": 0,
+ "isClient": false
+ }
+ ]
+ },
+ {
+ "auth": 2,
+ "readonly": false,
+ "nrequests_client_max": 5,
+ "socks": [
+ {
+ "fd": 101,
+ "errfd": -1,
+ "pid": 0,
+ "isClient": false
+ }
+ ]
+ }
+ ],
+ "clients": [
+ {
+ "auth": 1,
+ "readonly": true,
+ "nrequests_max": 15,
+ "sock": {
+ "fd": 102,
+ "errfd": -1,
+ "pid": -1,
+ "isClient": true
+ }
+ },
+ {
+ "auth": 2,
+ "readonly": true,
+ "nrequests_max": 66,
+ "sock": {
+ "fd": 103,
+ "errfd": -1,
+ "pid": -1,
+ "isClient": true
+ }
+ }
+ ]
+}
diff --git a/tests/virnetserverdata/output-data-anon-clients.json b/tests/virnetserverdata/output-data-anon-clients.json
new file mode 100644
index 0000000..ed91b57
--- /dev/null
+++ b/tests/virnetserverdata/output-data-anon-clients.json
@@ -0,0 +1,63 @@
+{
+ "min_workers": 10,
+ "max_workers": 50,
+ "priority_workers": 5,
+ "max_clients": 100,
+ "max_anonymous_clients": 10,
+ "keepaliveInterval": 120,
+ "keepaliveCount": 5,
+ "keepaliveRequired": true,
+ "mdnsGroupName": "libvirtTest",
+ "services": [
+ {
+ "auth": 0,
+ "readonly": true,
+ "nrequests_client_max": 2,
+ "socks": [
+ {
+ "fd": 100,
+ "errfd": -1,
+ "pid": 0,
+ "isClient": false
+ }
+ ]
+ },
+ {
+ "auth": 2,
+ "readonly": false,
+ "nrequests_client_max": 5,
+ "socks": [
+ {
+ "fd": 101,
+ "errfd": -1,
+ "pid": 0,
+ "isClient": false
+ }
+ ]
+ }
+ ],
+ "clients": [
+ {
+ "auth": 1,
+ "readonly": true,
+ "nrequests_max": 15,
+ "sock": {
+ "fd": 102,
+ "errfd": -1,
+ "pid": -1,
+ "isClient": true
+ }
+ },
+ {
+ "auth": 2,
+ "readonly": true,
+ "nrequests_max": 66,
+ "sock": {
+ "fd": 103,
+ "errfd": -1,
+ "pid": -1,
+ "isClient": true
+ }
+ }
+ ]
+}
diff --git a/tests/virnetserverdata/output-data-initial.json b/tests/virnetserverdata/output-data-initial.json
new file mode 100644
index 0000000..da02aac
--- /dev/null
+++ b/tests/virnetserverdata/output-data-initial.json
@@ -0,0 +1,63 @@
+{
+ "min_workers": 10,
+ "max_workers": 50,
+ "priority_workers": 5,
+ "max_clients": 100,
+ "max_anonymous_clients": 100,
+ "keepaliveInterval": 120,
+ "keepaliveCount": 5,
+ "keepaliveRequired": true,
+ "mdnsGroupName": "libvirtTest",
+ "services": [
+ {
+ "auth": 0,
+ "readonly": true,
+ "nrequests_client_max": 2,
+ "socks": [
+ {
+ "fd": 100,
+ "errfd": -1,
+ "pid": 0,
+ "isClient": false
+ }
+ ]
+ },
+ {
+ "auth": 2,
+ "readonly": false,
+ "nrequests_client_max": 5,
+ "socks": [
+ {
+ "fd": 101,
+ "errfd": -1,
+ "pid": 0,
+ "isClient": false
+ }
+ ]
+ }
+ ],
+ "clients": [
+ {
+ "auth": 1,
+ "readonly": true,
+ "nrequests_max": 15,
+ "sock": {
+ "fd": 102,
+ "errfd": -1,
+ "pid": -1,
+ "isClient": true
+ }
+ },
+ {
+ "auth": 2,
+ "readonly": true,
+ "nrequests_max": 66,
+ "sock": {
+ "fd": 103,
+ "errfd": -1,
+ "pid": -1,
+ "isClient": true
+ }
+ }
+ ]
+}
diff --git a/tests/virnetservertest.c b/tests/virnetservertest.c
new file mode 100644
index 0000000..08431d7
--- /dev/null
+++ b/tests/virnetservertest.c
@@ -0,0 +1,290 @@
+/*
+ * Copyright (C) 2015 Red Hat, 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/>.
+ *
+ * Author: Daniel P. Berrange <berrange(a)redhat.com>
+ */
+
+#include <config.h>
+
+#include "testutils.h"
+#include "virerror.h"
+#include "rpc/virnetserver.h"
+
+#define VIR_FROM_THIS VIR_FROM_RPC
+
+#ifdef HAVE_SOCKETPAIR
+static virNetServerPtr
+testCreateServer(const char *host, int family)
+{
+ virNetServerPtr srv = NULL;
+ virNetServerServicePtr svc1 = NULL, svc2 = NULL;
+ virNetServerClientPtr cln1 = NULL, cln2 = NULL;
+ virNetSocketPtr sk1 = NULL, sk2 = NULL;
+ int fdclient[2];
+
+ if (socketpair(PF_UNIX, SOCK_STREAM, 0, fdclient) < 0) {
+ virReportSystemError(errno, "%s",
+ "Cannot create socket pair");
+ goto cleanup;
+ }
+
+ if (!(srv = virNetServerNew(10, 50, 5, 100, 10,
+ 120, 5, true,
+ "libvirtTest",
+ NULL,
+ NULL,
+ NULL,
+ NULL)))
+ goto error;
+
+ if (!(svc1 = virNetServerServiceNewTCP(host,
+ NULL,
+ family,
+ VIR_NET_SERVER_SERVICE_AUTH_NONE,
+# ifdef WITH_GNUTLS
+ NULL,
+# endif
+ true,
+ 5,
+ 2)))
+ goto error;
+
+ if (!(svc2 = virNetServerServiceNewTCP(host,
+ NULL,
+ VIR_NET_SERVER_SERVICE_AUTH_POLKIT,
+ family,
+# ifdef WITH_GNUTLS
+ NULL,
+# endif
+ false,
+ 25,
+ 5)))
+ goto error;
+
+ if (virNetServerAddService(srv, svc1, "libvirt-ro") < 0)
+ goto error;
+ if (virNetServerAddService(srv, svc2, "libvirt-ro") < 0)
+ goto error;
+
+ if (virNetSocketNewConnectSockFD(fdclient[0], &sk1) < 0)
+ goto error;
+ if (virNetSocketNewConnectSockFD(fdclient[1], &sk2) < 0)
+ goto error;
+
+ if (!(cln1 = virNetServerClientNew(sk1,
+ VIR_NET_SERVER_SERVICE_AUTH_SASL,
+ true,
+ 15,
+# ifdef WITH_GNUTLS
+ NULL,
+# endif
+ NULL, NULL, NULL, NULL)))
+ goto error;
+
+ if (!(cln2 = virNetServerClientNew(sk2,
+ VIR_NET_SERVER_SERVICE_AUTH_POLKIT,
+ true,
+ 66,
+# ifdef WITH_GNUTLS
+ NULL,
+# endif
+ NULL, NULL, NULL, NULL)))
+ goto error;
+
+ if (virNetServerAddClient(srv, cln1) < 0)
+ goto error;
+
+ if (virNetServerAddClient(srv, cln2) < 0)
+ goto error;
+
+ cleanup:
+ virObjectUnref(cln1);
+ virObjectUnref(cln2);
+ virObjectUnref(svc1);
+ virObjectUnref(svc2);
+ return srv;
+
+ error:
+ virObjectUnref(srv);
+ srv = NULL;
+ goto cleanup;
+}
+
+static char *testGenerateJSON(void)
+{
+ virNetServerPtr srv = NULL;
+ virJSONValuePtr json = NULL;
+ char *jsonstr = NULL;
+ bool has_ipv4, has_ipv6;
+
+ /* Our pre-saved JSON file is created so that each service
+ * only has one socket. If we let libvirt bind to IPv4 and
+ * IPv6 we might end up with two sockets, so force one or
+ * the other based on what's available on thehost
+ */
+ if (virNetSocketCheckProtocols(&has_ipv4,
+ &has_ipv6) < 0)
+ return NULL;
+
+ if (!has_ipv4 && !has_ipv6)
+ return NULL;
+
+ if (!(srv = testCreateServer(
+ has_ipv4 ? "127.0.0.1" : "::1",
+ has_ipv4 ? AF_INET : AF_INET6)))
+ goto cleanup;
+
+ if (!(json = virNetServerPreExecRestart(srv)))
+ goto cleanup;
+
+ if (!(jsonstr = virJSONValueToString(json, true)))
+ goto cleanup;
+ fprintf(stderr, "%s\n", jsonstr);
+ cleanup:
+ virNetServerClose(srv);
+ virObjectUnref(srv);
+ virJSONValueFree(json);
+ return jsonstr;
+}
+
+
+struct testExecRestartData {
+ const char *jsonfile;
+};
+
+static int testExecRestart(const void *opaque)
+{
+ int ret = -1;
+ virNetServerPtr srv = NULL;
+ const struct testExecRestartData *data = opaque;
+ char *infile = NULL, *outfile = NULL;
+ char *injsonstr = NULL, *outjsonstr = NULL;
+ virJSONValuePtr injson = NULL, outjson = NULL;
+ int fdclient[2] = { -1, -1 }, fdserver[2] = { -1, -1 };
+
+ if (socketpair(PF_UNIX, SOCK_STREAM, 0, fdclient) < 0) {
+ virReportSystemError(errno, "%s",
+ "Cannot create socket pair");
+ goto cleanup;
+ }
+
+ if (socketpair(PF_UNIX, SOCK_STREAM, 0, fdserver) < 0) {
+ virReportSystemError(errno, "%s",
+ "Cannot create socket pair");
+ goto cleanup;
+ }
+
+ /* We're blindly assuming the test case isn't using
+ * fds 100->103 for something else, which is probably
+ * fairly reasonable in general
+ */
+ dup2(fdserver[0], 100);
+ dup2(fdserver[1], 101);
+ dup2(fdclient[0], 102);
+ dup2(fdclient[1], 103);
+
+ if (virAsprintf(&infile, "%s/virnetserverdata/input-data-%s.json",
+ abs_srcdir, data->jsonfile) < 0)
+ goto cleanup;
+
+ if (virAsprintf(&outfile, "%s/virnetserverdata/output-data-%s.json",
+ abs_srcdir, data->jsonfile) < 0)
+ goto cleanup;
+
+ if (virFileReadAll(infile, 8192, &injsonstr) < 0)
+ goto cleanup;
+
+ if (!(injson = virJSONValueFromString(injsonstr)))
+ goto cleanup;
+
+ if (!(srv = virNetServerNewPostExecRestart(injson,
+ NULL, NULL, NULL,
+ NULL, NULL)))
+ goto cleanup;
+
+ if (!(outjson = virNetServerPreExecRestart(srv)))
+ goto cleanup;
+
+ if (!(outjsonstr = virJSONValueToString(outjson, true)))
+ goto cleanup;
+
+ if (virtTestCompareToFile(outjsonstr, outfile) < 0)
+ goto fail;
+
+ ret = 0;
+
+ cleanup:
+ if (ret < 0) {
+ virErrorPtr err = virGetLastError();
+ fprintf(stderr, "%s\n", err->message);
+ }
+ fail:
+ VIR_FREE(infile);
+ VIR_FREE(outfile);
+ VIR_FREE(injsonstr);
+ VIR_FREE(outjsonstr);
+ virJSONValueFree(injson);
+ virJSONValueFree(outjson);
+ virObjectUnref(srv);
+ VIR_FORCE_CLOSE(fdserver[0]);
+ VIR_FORCE_CLOSE(fdserver[1]);
+ VIR_FORCE_CLOSE(fdclient[0]);
+ VIR_FORCE_CLOSE(fdclient[1]);
+ return ret;
+}
+
+
+static int
+mymain(void)
+{
+ int ret = 0;
+
+ /* Hack to make it easier to generate new JSON files when
+ * the RPC classes change. Just set this env var, save
+ * the generated JSON, and replace the file descriptor
+ * numbers with 100, 101, 102, 103.
+ */
+ if (getenv("VIR_GENERATE_JSON")) {
+ char *json = testGenerateJSON();
+ fprintf(stdout, "%s\n", json);
+ VIR_FREE(json);
+ return EXIT_SUCCESS;
+ }
+
+# define EXEC_RESTART_TEST(file) \
+ do { \
+ struct testExecRestartData data = { \
+ file \
+ }; \
+ if (virtTestRun("ExecRestart " file, \
+ testExecRestart, &data) < 0) \
+ ret = -1; \
+ } while (0)
+
+ EXEC_RESTART_TEST("initial");
+ EXEC_RESTART_TEST("anon-clients");
+
+ return ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
+}
+#else
+static int
+mymain(void)
+{
+ return EXIT_AM_SKIP;
+}
+#endif
+VIRT_TEST_MAIN(mymain);
--
2.1.0
9 years, 7 months
[libvirt] [PATCH 0/3] Patches for a couple of Coverity errors
by John Ferlan
The first one is one I forgot the last time I sent Coverity patches a
few weeks ago. The next two are from changes made recently.
John Ferlan (3):
storage: Resolve Coverity FORWARD_NULL
conf: Resolve Coverity FORWARD_NULL
network: Resolve Coverity FORWARD_NULL
src/conf/domain_conf.c | 2 ++
src/network/bridge_driver.c | 2 +-
src/storage/storage_backend_disk.c | 2 +-
3 files changed, 4 insertions(+), 2 deletions(-)
--
2.1.0
9 years, 7 months
[libvirt] [PATCH] virsh: reject negative values for scaled integer
by Pavel Hrdina
Some virsh commands have a size parameter, which is handled as scaled
integer. We don't have any *feature* that would allow to use '-1' as
maximum size, so it's safe to reject any negative values for those
commands.
Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1159171
Signed-off-by: Pavel Hrdina <phrdina(a)redhat.com>
---
tools/virsh.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tools/virsh.c b/tools/virsh.c
index 4425774..1005ba8 100644
--- a/tools/virsh.c
+++ b/tools/virsh.c
@@ -1811,7 +1811,7 @@ vshCommandOptScaledInt(const vshCmd *cmd, const char *name,
ret = vshCommandOptString(cmd, name, &str);
if (ret <= 0)
return ret;
- if (virStrToLong_ull(str, &end, 10, value) < 0 ||
+ if (virStrToLong_ullp(str, &end, 10, value) < 0 ||
virScaleInteger(value, end, scale, max) < 0)
return -1;
return 1;
--
2.3.6
9 years, 7 months
[libvirt] [PATCH] libxl: load on FreeBSD
by Roman Bogorodskiy
The libxl tries to check if it's running in dom0 by parsing
/proc/xen/capabilities and if that fails it doesn't load.
There's no procfs interface in Xen on FreeBSD, so this check always
fails.
Instead of using procfs, check if /dev/xen/xenstored, that's enough to
check if we're running in dom0 in FreeBSD case.
--
The 'HYPERVISOR_CAPABILITIES' name could be misleading now, however, I'd
prefer to use a common variable to avoid duplicating of the file checking
code. Maybe it should be renamed to something like HYPERVISOR_CONTROL?
---
src/libxl/libxl_driver.c | 41 +++++++++++++++++++++++++----------------
1 file changed, 25 insertions(+), 16 deletions(-)
diff --git a/src/libxl/libxl_driver.c b/src/libxl/libxl_driver.c
index 12be816..c848210 100644
--- a/src/libxl/libxl_driver.c
+++ b/src/libxl/libxl_driver.c
@@ -73,7 +73,11 @@ VIR_LOG_INIT("libxl.libxl_driver");
#define LIBXL_CONFIG_FORMAT_XM "xen-xm"
#define LIBXL_CONFIG_FORMAT_SEXPR "xen-sxpr"
-#define HYPERVISOR_CAPABILITIES "/proc/xen/capabilities"
+#ifdef __FreeBSD__
+# define HYPERVISOR_CAPABILITIES "/dev/xen/xenstored"
+#else
+# define HYPERVISOR_CAPABILITIES "/proc/xen/capabilities"
+#endif
/* Number of Xen scheduler parameters */
#define XEN_SCHED_CREDIT_NPARAM 2
@@ -427,8 +431,6 @@ static bool
libxlDriverShouldLoad(bool privileged)
{
bool ret = false;
- int status;
- char *output = NULL;
/* Don't load if non-root */
if (!privileged) {
@@ -441,21 +443,28 @@ libxlDriverShouldLoad(bool privileged)
" does not exist");
return ret;
}
- /*
- * Don't load if not running on a Xen control domain (dom0). It is not
- * sufficient to check for the file to exist as any guest can mount
- * xenfs to /proc/xen.
- */
- status = virFileReadAll(HYPERVISOR_CAPABILITIES, 10, &output);
- if (status >= 0)
- status = strncmp(output, "control_d", 9);
- VIR_FREE(output);
- if (status) {
- VIR_INFO("No Xen capabilities detected, probably not running "
- "in a Xen Dom0. Disabling libxenlight driver");
+#if !defined(__FreeBSD__)
+ {
+ int status;
+ char *output = NULL;
- return ret;
+ /*
+ * Don't load if not running on a Xen control domain (dom0). It is not
+ * sufficient to check for the file to exist as any guest can mount
+ * xenfs to /proc/xen.
+ */
+ status = virFileReadAll(HYPERVISOR_CAPABILITIES, 10, &output);
+ if (status >= 0)
+ status = strncmp(output, "control_d", 9);
+ VIR_FREE(output);
+ if (status) {
+ VIR_INFO("No Xen capabilities detected, probably not running "
+ "in a Xen Dom0. Disabling libxenlight driver");
+
+ return ret;
+ }
}
+#endif
/* Don't load if legacy xen toolstack (xend) is in use */
if (virFileExists("/usr/sbin/xend")) {
--
2.3.7
9 years, 7 months