[libvirt] [PATCH] test: fix build errors with gcc 4.7.0 and -O0
by Laine Stump
When building on Fedora 17 (which uses gcc 4.7.0) with -O0 in CFLAGS,
three of the tests failed to compile.
cputest.c and qemuxml2argvtest.c had non-static structs defined
inside the macro that was being repeatedly invoked. Due to some so-far
unidentified change in gcc, the stack space used by variables defined
inside { } is not recovered/re-used when the block ends, so all these
structs have become additive (this is the same problem worked around
in commit cf57d345b). Fortunately, these two files could be fixed with
a single line addition of "static" to the struct definition in the
macro.
virnettlscontexttest.c was a bit different, though. The structs were
all defined inline as static already, but for some reason now take up
space on the stack. The only reasonable solution here was to move all
of the struct definitions outside of the function.
In an ideal world, none of these changes should be necessary, but not
knowing how long it will be until the gcc regressions are fixed, and
since the code is just as correct after this patch as before, it makes
sense to fix libvirt's build for -O0 while also reporting the gcc
problem.
---
tests/cputest.c | 2 +-
tests/qemuxml2argvtest.c | 2 +-
tests/virnettlscontexttest.c | 168 ++++++++++++++++++++++--------------------
3 files changed, 91 insertions(+), 81 deletions(-)
diff --git a/tests/cputest.c b/tests/cputest.c
index 9928e5d..01db8f1 100644
--- a/tests/cputest.c
+++ b/tests/cputest.c
@@ -512,7 +512,7 @@ mymain(void)
#define DO_TEST(arch, api, name, host, cpu, \
models, nmodels, preferred, result) \
do { \
- struct data data = { \
+ static struct data data = { \
arch, api, host, cpu, models, \
models == NULL ? NULL : #models, \
nmodels, preferred, result \
diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c
index 637ca50..fdbe95a 100644
--- a/tests/qemuxml2argvtest.c
+++ b/tests/qemuxml2argvtest.c
@@ -314,7 +314,7 @@ mymain(void)
# define DO_TEST_FULL(name, migrateFrom, migrateFd, \
expectError, expectFailure, ...) \
do { \
- struct testInfo info = { \
+ static struct testInfo info = { \
name, NULL, migrateFrom, migrateFd, \
expectError, expectFailure \
}; \
diff --git a/tests/virnettlscontexttest.c b/tests/virnettlscontexttest.c
index 8e805d8..b4d1e0e 100644
--- a/tests/virnettlscontexttest.c
+++ b/tests/virnettlscontexttest.c
@@ -734,21 +734,6 @@ cleanup:
return ret;
}
-
-static int
-mymain(void)
-{
- int ret = 0;
- if (asn1_array2tree(pkix_asn1_tab, &pkix_asn1, NULL) != ASN1_SUCCESS)
- abort();
-
- gnutls_global_init();
-
- privkey = testTLSLoadKey();
-
- if (virFileWriteStr(keyfile, PRIVATE_KEY, 0600) < 0)
- return EXIT_FAILURE;
-
# define DO_CTX_TEST(isServer, caReq, certReq, expectFail) \
do { \
struct testTLSContextData data = { \
@@ -806,11 +791,6 @@ mymain(void)
0, 0,
};
-
- DO_CTX_TEST(true, cacertreq, servercertreq, false);
- DO_CTX_TEST(false, cacertreq, clientcertreq, false);
-
-
/* Some other CAs which are good */
/* Basic:CA:critical */
@@ -864,14 +844,6 @@ mymain(void)
0, 0,
};
- DO_CTX_TEST(true, cacert1req, servercertreq, false);
- DO_CTX_TEST(true, cacert2req, servercertreq, false);
-# if 0
- DO_CTX_TEST(true, cacert3req, servercertreq, false);
-# endif
- DO_CTX_TEST(true, cacert4req, servercertreq, false);
- DO_CTX_TEST(true, cacert5req, servercertreq, false);
-
/* Now some bad certs */
/* no-basic */
@@ -893,10 +865,6 @@ mymain(void)
0, 0,
};
- DO_CTX_TEST(true, cacert6req, servercertreq, true);
- DO_CTX_TEST(true, cacert7req, servercertreq, true);
-
-
/* Various good servers */
/* no usage or purpose */
static struct testTLSCertReq servercert1req = {
@@ -962,13 +930,6 @@ mymain(void)
0, 0,
};
- DO_CTX_TEST(true, cacertreq, servercert1req, false);
- DO_CTX_TEST(true, cacertreq, servercert2req, false);
- DO_CTX_TEST(true, cacertreq, servercert3req, false);
- DO_CTX_TEST(true, cacertreq, servercert4req, false);
- DO_CTX_TEST(true, cacertreq, servercert5req, false);
- DO_CTX_TEST(true, cacertreq, servercert6req, false);
- DO_CTX_TEST(true, cacertreq, servercert7req, false);
/* Bad servers */
/* usage:cert-sign:critical */
@@ -999,12 +960,6 @@ mymain(void)
0, 0,
};
- DO_CTX_TEST(true, cacertreq, servercert8req, true);
- DO_CTX_TEST(true, cacertreq, servercert9req, true);
- DO_CTX_TEST(true, cacertreq, servercert10req, true);
-
-
-
/* Various good clients */
/* no usage or purpose */
static struct testTLSCertReq clientcert1req = {
@@ -1070,13 +1025,6 @@ mymain(void)
0, 0,
};
- DO_CTX_TEST(false, cacertreq, clientcert1req, false);
- DO_CTX_TEST(false, cacertreq, clientcert2req, false);
- DO_CTX_TEST(false, cacertreq, clientcert3req, false);
- DO_CTX_TEST(false, cacertreq, clientcert4req, false);
- DO_CTX_TEST(false, cacertreq, clientcert5req, false);
- DO_CTX_TEST(false, cacertreq, clientcert6req, false);
- DO_CTX_TEST(false, cacertreq, clientcert7req, false);
/* Bad clients */
/* usage:cert-sign:critical */
@@ -1107,12 +1055,6 @@ mymain(void)
0, 0,
};
- DO_CTX_TEST(false, cacertreq, clientcert8req, true);
- DO_CTX_TEST(false, cacertreq, clientcert9req, true);
- DO_CTX_TEST(false, cacertreq, clientcert10req, true);
-
-
-
/* Expired stuff */
static struct testTLSCertReq cacertexpreq = {
@@ -1140,11 +1082,6 @@ mymain(void)
0, -1,
};
- DO_CTX_TEST(true, cacertexpreq, servercertreq, true);
- DO_CTX_TEST(true, cacertreq, servercertexpreq, true);
- DO_CTX_TEST(false, cacertreq, clientcertexpreq, true);
-
-
/* Not activated stuff */
static struct testTLSCertReq cacertnewreq = {
@@ -1172,14 +1109,6 @@ mymain(void)
1, 2,
};
- DO_CTX_TEST(true, cacertnewreq, servercertreq, true);
- DO_CTX_TEST(true, cacertreq, servercertnewreq, true);
- DO_CTX_TEST(false, cacertreq, clientcertnewreq, true);
-
-
- DO_SESS_TEST(cacertreq, servercertreq, clientcertreq, false, false, "libvirt.org", NULL);
- DO_SESS_TEST_EXT(cacertreq, cacert1req, servercertreq, clientcertreq, true, true, "libvirt.org", NULL);
-
/* When an altname is set, the CN is ignored, so it must be duplicated
* as an altname for it to match */
static struct testTLSCertReq servercertalt1req = {
@@ -1190,6 +1119,7 @@ mymain(void)
true, true, GNUTLS_KP_TLS_WWW_SERVER, NULL,
0, 0,
};
+
/* This intentionally doesn't replicate */
static struct testTLSCertReq servercertalt2req = {
NULL, NULL, "servercert.pem", "UK",
@@ -1200,14 +1130,6 @@ mymain(void)
0, 0,
};
- DO_SESS_TEST(cacertreq, servercertalt1req, clientcertreq, false, false, "libvirt.org", NULL);
- DO_SESS_TEST(cacertreq, servercertalt1req, clientcertreq, false, false, "www.libvirt.org", NULL);
- DO_SESS_TEST(cacertreq, servercertalt1req, clientcertreq, false, true, "wiki.libvirt.org", NULL);
-
- DO_SESS_TEST(cacertreq, servercertalt2req, clientcertreq, false, true, "libvirt.org", NULL);
- DO_SESS_TEST(cacertreq, servercertalt2req, clientcertreq, false, false, "www.libvirt.org", NULL);
- DO_SESS_TEST(cacertreq, servercertalt2req, clientcertreq, false, false, "wiki.libvirt.org", NULL);
-
const char *const wildcards1[] = {
"C=UK,CN=dogfood",
NULL,
@@ -1234,6 +1156,94 @@ mymain(void)
NULL,
};
+static int
+mymain(void)
+{
+ int ret = 0;
+ if (asn1_array2tree(pkix_asn1_tab, &pkix_asn1, NULL) != ASN1_SUCCESS)
+ abort();
+
+ gnutls_global_init();
+
+ privkey = testTLSLoadKey();
+
+ if (virFileWriteStr(keyfile, PRIVATE_KEY, 0600) < 0)
+ return EXIT_FAILURE;
+
+ /* A perfect CA, perfect client & perfect server */
+ DO_CTX_TEST(true, cacertreq, servercertreq, false);
+ DO_CTX_TEST(false, cacertreq, clientcertreq, false);
+
+
+ /* Some other CAs which are good */
+ DO_CTX_TEST(true, cacert1req, servercertreq, false);
+ DO_CTX_TEST(true, cacert2req, servercertreq, false);
+# if 0
+ DO_CTX_TEST(true, cacert3req, servercertreq, false);
+# endif
+ DO_CTX_TEST(true, cacert4req, servercertreq, false);
+ DO_CTX_TEST(true, cacert5req, servercertreq, false);
+
+ /* Now some bad certs */
+ DO_CTX_TEST(true, cacert6req, servercertreq, true);
+ DO_CTX_TEST(true, cacert7req, servercertreq, true);
+
+
+ /* Various good servers */
+ DO_CTX_TEST(true, cacertreq, servercert1req, false);
+ DO_CTX_TEST(true, cacertreq, servercert2req, false);
+ DO_CTX_TEST(true, cacertreq, servercert3req, false);
+ DO_CTX_TEST(true, cacertreq, servercert4req, false);
+ DO_CTX_TEST(true, cacertreq, servercert5req, false);
+ DO_CTX_TEST(true, cacertreq, servercert6req, false);
+ DO_CTX_TEST(true, cacertreq, servercert7req, false);
+
+ /* Bad servers */
+ DO_CTX_TEST(true, cacertreq, servercert8req, true);
+ DO_CTX_TEST(true, cacertreq, servercert9req, true);
+ DO_CTX_TEST(true, cacertreq, servercert10req, true);
+
+ /* Various good clients */
+ DO_CTX_TEST(false, cacertreq, clientcert1req, false);
+ DO_CTX_TEST(false, cacertreq, clientcert2req, false);
+ DO_CTX_TEST(false, cacertreq, clientcert3req, false);
+ DO_CTX_TEST(false, cacertreq, clientcert4req, false);
+ DO_CTX_TEST(false, cacertreq, clientcert5req, false);
+ DO_CTX_TEST(false, cacertreq, clientcert6req, false);
+ DO_CTX_TEST(false, cacertreq, clientcert7req, false);
+
+ /* Bad clients */
+ DO_CTX_TEST(false, cacertreq, clientcert8req, true);
+ DO_CTX_TEST(false, cacertreq, clientcert9req, true);
+ DO_CTX_TEST(false, cacertreq, clientcert10req, true);
+
+
+ /* Expired stuff */
+ DO_CTX_TEST(true, cacertexpreq, servercertreq, true);
+ DO_CTX_TEST(true, cacertreq, servercertexpreq, true);
+ DO_CTX_TEST(false, cacertreq, clientcertexpreq, true);
+
+
+ /* Not activated stuff */
+ DO_CTX_TEST(true, cacertnewreq, servercertreq, true);
+ DO_CTX_TEST(true, cacertreq, servercertnewreq, true);
+ DO_CTX_TEST(false, cacertreq, clientcertnewreq, true);
+
+
+ DO_SESS_TEST(cacertreq, servercertreq, clientcertreq, false, false, "libvirt.org", NULL);
+ DO_SESS_TEST_EXT(cacertreq, cacert1req, servercertreq, clientcertreq, true, true, "libvirt.org", NULL);
+
+ /* When an altname is set, the CN is ignored, so it must be duplicated
+ * as an altname for it to match */
+ DO_SESS_TEST(cacertreq, servercertalt1req, clientcertreq, false, false, "libvirt.org", NULL);
+ DO_SESS_TEST(cacertreq, servercertalt1req, clientcertreq, false, false, "www.libvirt.org", NULL);
+ DO_SESS_TEST(cacertreq, servercertalt1req, clientcertreq, false, true, "wiki.libvirt.org", NULL);
+
+ /* This intentionally doesn't replicate */
+ DO_SESS_TEST(cacertreq, servercertalt2req, clientcertreq, false, true, "libvirt.org", NULL);
+ DO_SESS_TEST(cacertreq, servercertalt2req, clientcertreq, false, false, "www.libvirt.org", NULL);
+ DO_SESS_TEST(cacertreq, servercertalt2req, clientcertreq, false, false, "wiki.libvirt.org", NULL);
+
DO_SESS_TEST(cacertreq, servercertreq, clientcertreq, true, false, "libvirt.org", wildcards1);
DO_SESS_TEST(cacertreq, servercertreq, clientcertreq, false, false, "libvirt.org", wildcards2);
DO_SESS_TEST(cacertreq, servercertreq, clientcertreq, false, false, "libvirt.org", wildcards3);
--
1.7.9.3
12 years, 7 months
[libvirt] [PATCH] virURIParse: don't forget to copy the user part
by Guido Günther
This got dropped with 300e60e15b22387dda41ed5985a9ebadfd86dd25
Cheers,
-- Guido
---
src/util/viruri.c | 5 ++++-
tests/viruritest.c | 24 +++++++++++++-----------
2 files changed, 17 insertions(+), 12 deletions(-)
diff --git a/src/util/viruri.c b/src/util/viruri.c
index 2c6de51..a41f345 100644
--- a/src/util/viruri.c
+++ b/src/util/viruri.c
@@ -185,7 +185,9 @@ virURIParse(const char *uri)
if (xmluri->fragment &&
!(ret->fragment = strdup(xmluri->fragment)))
goto no_memory;
-
+ if (xmluri->user &&
+ !(ret->user = strdup(xmluri->user)))
+ goto no_memory;
/* First check: does it even make sense to jump inside */
if (ret->server != NULL &&
@@ -249,6 +251,7 @@ virURIFormat(virURIPtr uri)
xmluri.query = uri->query;
#endif
xmluri.fragment = uri->fragment;
+ xmluri.user = uri->user;
/* First check: does it make sense to do anything */
if (xmluri.server != NULL &&
diff --git a/tests/viruritest.c b/tests/viruritest.c
index 3570217..4bb6a03 100644
--- a/tests/viruritest.c
+++ b/tests/viruritest.c
@@ -42,6 +42,7 @@ struct URIParseData {
const char *path;
const char *query;
const char *fragment;
+ const char *user;
virURIParamPtr params;
};
@@ -143,33 +144,34 @@ mymain(void)
signal(SIGPIPE, SIG_IGN);
#define TEST_FULL(uri, uri_out, scheme, server, port, path, query, \
- fragment, params) \
+ fragment, user, params) \
do { \
const struct URIParseData data = { \
uri, (uri_out) ? (uri_out) : (uri), scheme, server, port, \
- path, query, fragment, params \
+ path, query, fragment, user, params \
}; \
if (virtTestRun("Test URI " # uri, 1, testURIParse, &data) < 0) \
ret = -1; \
} while (0)
-#define TEST_PARSE(uri, scheme, server, port, path, query, fragment, params) \
- TEST_FULL(uri, NULL, scheme, server, port, path, query, fragment, params)
+#define TEST_PARSE(uri, scheme, server, port, path, query, fragment, user, params) \
+ TEST_FULL(uri, NULL, scheme, server, port, path, query, fragment, user, params)
#define TEST_PARAMS(query_in, query_out, params) \
TEST_FULL("test://example.com/?" query_in, \
*query_out ? "test://example.com/?" query_out : NULL, \
- "test", "example.com", 0, "/", query_in, NULL, params)
+ "test", "example.com", 0, "/", query_in, NULL, NULL, params)
virURIParam params[] = {
{ (char*)"name", (char*)"value" },
{ NULL, NULL },
};
- TEST_PARSE("test://example.com", "test", "example.com", 0, NULL, NULL, NULL, NULL);
- TEST_PARSE("test://example.com:123", "test", "example.com", 123, NULL, NULL, NULL, NULL);
- TEST_PARSE("test://example.com:123/system?name=value#foo", "test", "example.com", 123, "/system", "name=value", "foo", params);
- TEST_PARSE("test://127.0.0.1:123/system", "test", "127.0.0.1", 123, "/system", NULL, NULL, NULL);
- TEST_PARSE("test://[::1]:123/system", "test", "::1", 123, "/system", NULL, NULL, NULL);
- TEST_PARSE("test://[2001:41c8:1:4fd4::2]:123/system", "test", "2001:41c8:1:4fd4::2", 123, "/system", NULL, NULL, NULL);
+ TEST_PARSE("test://example.com", "test", "example.com", 0, NULL, NULL, NULL, NULL, NULL);
+ TEST_PARSE("test://foo@example.com", "test", "example.com", 0, NULL, NULL, NULL, "foo", NULL);
+ TEST_PARSE("test://example.com:123", "test", "example.com", 123, NULL, NULL, NULL, NULL, NULL);
+ TEST_PARSE("test://example.com:123/system?name=value#foo", "test", "example.com", 123, "/system", "name=value", "foo", NULL, params);
+ TEST_PARSE("test://127.0.0.1:123/system", "test", "127.0.0.1", 123, "/system", NULL, NULL, NULL, NULL);
+ TEST_PARSE("test://[::1]:123/system", "test", "::1", 123, "/system", NULL, NULL, NULL, NULL);
+ TEST_PARSE("test://[2001:41c8:1:4fd4::2]:123/system", "test", "2001:41c8:1:4fd4::2", 123, "/system", NULL, NULL, NULL, NULL);
virURIParam params1[] = {
{ (char*)"foo", (char*)"one" },
--
1.7.9.1
12 years, 7 months
[libvirt] [PATCH] conf: Plug memory leaks on virDomainDiskDefParseXML
by Alex Jia
Detected by valgrind. Leaks are introduced in commit b22eaa7.
* src/conf/domain_conf.c (virDomainDiskDefParseXML): fix memory leaks.
How to reproduce?
% make && make -C tests check TESTS=qemuxml2argvtest
% cd tests && valgrind -v --leak-check=full ./qemuxml2argvtest
actual result:
==2143== 12 bytes in 2 blocks are definitely lost in loss record 74 of 179
==2143== at 0x4A05FDE: malloc (vg_replace_malloc.c:236)
==2143== by 0x39D90A67DD: xmlStrndup (xmlstring.c:45)
==2143== by 0x4F5EC0: virDomainDiskDefParseXML (domain_conf.c:3438)
==2143== by 0x502F00: virDomainDefParseXML (domain_conf.c:8304)
==2143== by 0x505FE3: virDomainDefParseNode (domain_conf.c:9080)
==2143== by 0x5069AE: virDomainDefParse (domain_conf.c:9030)
==2143== by 0x41CBF4: testCompareXMLToArgvHelper (qemuxml2argvtest.c:105)
==2143== by 0x41E5DD: virtTestRun (testutils.c:145)
==2143== by 0x416FA3: mymain (qemuxml2argvtest.c:399)
==2143== by 0x41DCB7: virtTestMain (testutils.c:700)
==2143== by 0x39CF01ECDC: (below main) (libc-start.c:226)
Signed-off-by: Alex Jia <ajia(a)redhat.com>
---
src/conf/domain_conf.c | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index cca757d..c6b97e1 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -3893,6 +3893,7 @@ cleanup:
VIR_FREE(rawio);
VIR_FREE(target);
VIR_FREE(source);
+ VIR_FREE(tray);
while (nhosts > 0) {
virDomainDiskHostDefFree(&hosts[nhosts - 1]);
nhosts--;
--
1.7.1
12 years, 7 months
[libvirt] Experience with Libvirt JAVA API
by Yaniv Hadad
Hi All,
I look for someone who have experience with the Java API.
My aim is to investigate hyper visors and their guest details like : os,
network , ran,vCPU and more...
Can some one have experience with that ??
Yaniv.
(Embedded image moved to file:
pic59134.jpg)
Yaniv Hadad ,
(Embedded image moved to file: pic50897.jpg)+972 4
8296594 (Embedded image moved to file:
pic56120.jpg)+972 50-40-78-908
12 years, 7 months
[libvirt] [PATCH] test: fix segfault in networkxml2argvtest
by Laine Stump
This bug resolves https://bugzilla.redhat.com/show_bug.cgi?id=810100
rpm builds for i686 were failing with a segfault in
networkxml2argvtest. Running under valgrind showed that a region of
memory was being referenced after it had been freed (as the result of
realloc - see the valgrind report in the BZ).
The problem (in replaceTokens() - added in commit 22ec60, meaning this
bug was in 0.9.10 and 0.9.11) was that the pointers token_start and
token_end were being computed based on the value of *buf, then *buf
was being realloc'ed (potentially moving it), then token_start and
token_end were used without recomputing them to account for movement
of *buf.
The solution is to change the code so that token_start and token_end
are offsets into *buf rather than pointers. This way there is only a
single pointer to the buffer, and nothing needs readjusting after a
realloc. (You may note that some uses of token_start/token_end didn't
need to be changed to add in "*buf +" - that's because there ended up
being a +*buf and -*buf which canceled each other out).
DV gets the credit for finding this bug and pointing out the valgrind
report.
---
tests/networkxml2argvtest.c | 13 +++++++------
1 files changed, 7 insertions(+), 6 deletions(-)
diff --git a/tests/networkxml2argvtest.c b/tests/networkxml2argvtest.c
index cf00181..87519e4 100644
--- a/tests/networkxml2argvtest.c
+++ b/tests/networkxml2argvtest.c
@@ -18,18 +18,19 @@
/* Replace all occurrences of @token in @buf by @replacement and adjust size of
* @buf accordingly. Returns 0 on success and -1 on out-of-memory errors. */
static int replaceTokens(char **buf, const char *token, const char *replacement) {
- char *token_start, *token_end;
+ size_t token_start, token_end;
size_t buf_len, rest_len;
const size_t token_len = strlen(token);
const size_t replacement_len = strlen(replacement);
const int diff = replacement_len - token_len;
buf_len = rest_len = strlen(*buf) + 1;
- token_end = *buf;
+ token_end = 0;
for (;;) {
- token_start = strstr(token_end, token);
- if (token_start == NULL)
+ char *match = strstr(*buf + token_end, token);
+ if (match == NULL)
break;
+ token_start = match - *buf;
rest_len -= token_start + token_len - token_end;
token_end = token_start + token_len;
buf_len += diff;
@@ -37,8 +38,8 @@ static int replaceTokens(char **buf, const char *token, const char *replacement)
if (VIR_REALLOC_N(*buf, buf_len) < 0)
return -1;
if (diff != 0)
- memmove(token_end + diff, token_end, rest_len);
- memcpy(token_start, replacement, replacement_len);
+ memmove(*buf + token_end + diff, *buf + token_end, rest_len);
+ memcpy(*buf + token_start, replacement, replacement_len);
token_end += diff;
}
/* if diff < 0, we could shrink the buffer here... */
--
1.7.7.6
12 years, 7 months
[libvirt] [test-API] RFC: Stabilization of libvirt-test-API
by Martin Kletzander
Hi everyone,
following our minutes, I'd like to start a discussion on what should be
done with libvirt-test-API so we can say it's stable and usable.
I would like to stress out that everything mentioned here is just an
opinion and I don't mean to talk down to someone as it may have seemed
earlier.
I think we should get some ideas from everyone, mostly QE as they will
be (are) the ones using this the most (if I understood correctly), and
then I'll be happy to help getting the code to the agreed status. I was
thinking about this from the wrong way probably and changing the angle
from what I look at it (and knowing there is some deadline) makes me
think of few levels of changes, which when introduced, could speed up
the test development and code understandability.
So here are the things I would like to do definitely (the optional
things follow later on):
- fix hard-coded options into real options (e.g. commit 65449e)
- fix some env_* and util* code (functions duplicated with different
behavior)
- fix or remove harmful and pointless code (at this point, when
creating domain on remote machine, be prepared for the test to fail with
any other user then root and with root, have backup of both local and
remote '/root/.ssh' directories as the contents will be erased!)
- fix method names for the {connect,domain,etc.}API (get_host_name vs.
lookupByUUID etc.)
The optional things:
- get rid of classes in lib and make just few utility functions
covering *only* the methods that do something else than call the same
method in underlying class from the libvirt module.
- get rid of the new exception (I don't see any other difference than
in the name, which can make a difference in "except:" clause, but it's
converted everywhere)
- be able to share variables between tests (connection object and
anything else)
- introduce new config file for tests (.ini format, can be parsed by
ConfigParser, same as env.cfg, define variables used throughout the test
specifications
- update the documentation
- use some python code style (PEP-8?), make use of True/False, None
- eliminate duplicated (and x-plicated) code (append_path in all the
files, etc.)
I have all of these figured out, so I'm willing to discuss all of them,
but in most cases changing it in the current code seems very
time-consumable to me.
Please, feel free to comment on any of these, add yours, discuss, shout
at me, etc. =)
Regards,
Martin
P.S.: I don't see any point in sending my patches until some of these
points are resolved as that could mean rewriting more code.
12 years, 7 months
[libvirt] [PATCH 1/3] Move linux specific symbol to src/libvirt_linux.syms
by Daniel P. Berrange
From: "Daniel P. Berrange" <berrange(a)redhat.com>
linuxNodeInfoCPUPopulate is not built on Mingw32 so
should be in libvirt_linux.syms, not libvirt_private.syms
Signed-off-by: Daniel P. Berrange <berrange(a)redhat.com>
---
src/libvirt_linux.syms | 3 +++
1 files changed, 3 insertions(+), 0 deletions(-)
diff --git a/src/libvirt_linux.syms b/src/libvirt_linux.syms
index 018c892..2258739 100644
--- a/src/libvirt_linux.syms
+++ b/src/libvirt_linux.syms
@@ -6,3 +6,6 @@
# stats_linux.h
linuxDomainInterfaceStats;
xenLinuxDomainBlockStats;
+
+# nodeinfo.h
+linuxNodeInfoCPUPopulate;
--
1.7.7.6
12 years, 7 months
[libvirt] [PATCH V2] nwfilter: Add support for ipset
by Stefan Berger
This patch adds support for the recent ipset iptables extension
to libvirt's nwfilter subsystem. Ipset allows to maintain 'sets'
of IP addresses, ports and other packet parameters and allows for
faster lookup (in the order of O(1) vs. O(n)) and rule evaluation
to achieve higher throughput than what can be achieved with
individual iptables rules.
On the command line iptables supports ipset using
iptables ... -m set --match-set <ipset name> <flags> -j ...
where 'ipset name' is the name of a previously created ipset and
flags is a comma-separated list of up to 6 flags. Flags use 'src' and 'dst'
for selecting IP addresses, ports etc. from the source or
destination part of a packet. So a concrete example may look like this:
iptables -A INPUT -m set --match-set test src,src -j ACCEPT
Since ipset management is quite complex, the idea was to leave ipset
management outside of libvirt but still allow users to reference an ipset.
The user would have to make sure the ipset is available once the VM is
started so that the iptables rule(s) referencing the ipset can be created.
Using XML to describe an ipset in an nwfilter rule would then look as
follows:
<rule action='accept' direction='in'>
<all ipset='test' ipsetflags='src,src'/>
</rule>
The two parameters on the command line are also the two distinct XML
attributes
'ipset' and 'ipsetflags'.
FYI: Here is the man page for ipset:
https://ipset.netfilter.org/ipset.man.html
Regards,
Stefan
---
v2:
- split ipset description into ipset and ipsetflags attribute
- improved on documentation
---
docs/formatnwfilter.html.in | 64 ++++++++++++++
docs/schemas/nwfilter.rng | 23 +++++
src/conf/nwfilter_conf.c | 135
+++++++++++++++++++++++++++++-
src/conf/nwfilter_conf.h | 12 ++
src/nwfilter/nwfilter_ebiptables_driver.c | 71 +++++++++++++++
tests/nwfilterxml2xmlin/ipset-test.xml | 15 +++
tests/nwfilterxml2xmlout/ipset-test.xml | 15 +++
tests/nwfilterxml2xmltest.c | 2
8 files changed, 332 insertions(+), 5 deletions(-)
Index: libvirt/src/conf/nwfilter_conf.c
===================================================================
--- libvirt.orig/src/conf/nwfilter_conf.c
+++ libvirt/src/conf/nwfilter_conf.c
@@ -183,6 +183,8 @@ static const char dstportstart_str[] = "
static const char dstportend_str[] = "dstportend";
static const char dscp_str[] = "dscp";
static const char state_str[] = "state";
+static const char ipset_str[] = "ipset";
+static const char ipsetflags_str[] = "ipsetflags";
#define SRCMACADDR srcmacaddr_str
#define SRCMACMASK srcmacmask_str
@@ -206,6 +208,8 @@ static const char state_str[] = "
#define DSTPORTEND dstportend_str
#define DSCP dscp_str
#define STATE state_str
+#define IPSET ipset_str
+#define IPSETFLAGS ipsetflags_str
/**
@@ -980,6 +984,97 @@ tcpFlagsFormatter(virBufferPtr buf,
return true;
}
+static bool
+ipsetValidator(enum attrDatatype datatype ATTRIBUTE_UNUSED, union data
*val,
+ virNWFilterRuleDefPtr nwf ATTRIBUTE_UNUSED,
+ nwItemDesc *item)
+{
+ const char *errmsg = NULL;
+
+ if (virStrcpy(item->u.ipset.setname, val->c,
+ sizeof(item->u.ipset.setname)) == NULL) {
+ errmsg = _("ipset name is too long");
+ goto arg_err_exit;
+ }
+
+ if (item->u.ipset.setname[strspn(item->u.ipset.setname,
+ VALID_IPSETNAME)] != 0) {
+ errmsg = _("ipset name contains invalid characters");
+ goto arg_err_exit;
+ }
+
+ return true;
+
+arg_err_exit:
+ virNWFilterReportError(VIR_ERR_INVALID_ARG,
+ "%s", errmsg);
+ return false;
+}
+
+static bool
+ipsetFormatter(virBufferPtr buf,
+ virNWFilterRuleDefPtr nwf ATTRIBUTE_UNUSED,
+ nwItemDesc *item)
+{
+ virBufferAdd(buf, item->u.ipset.setname, -1);
+
+ return true;
+}
+
+static bool
+ipsetFlagsValidator(enum attrDatatype datatype ATTRIBUTE_UNUSED, union
data *val,
+ virNWFilterRuleDefPtr nwf ATTRIBUTE_UNUSED,
nwItemDesc *item)
+{
+ const char *errmsg = NULL;
+ size_t idx = 0;
+
+ item->u.ipset.numFlags = 0;
+ item->u.ipset.flags = 0;
+
+ errmsg = _("malformed ipset flags");
+
+ while (item->u.ipset.numFlags < 6) {
+ if (STRCASEEQLEN(&val->c[idx], "src", 3)) {
+ item->u.ipset.flags |= (1 << item->u.ipset.numFlags);
+ } else if (!STRCASEEQLEN(&val->c[idx], "dst", 3)) {
+ goto arg_err_exit;
+ }
+ item->u.ipset.numFlags++;
+ idx += 3;
+ if (val->c[idx] != ',')
+ break;
+ idx++;
+ }
+
+ if (val->c[idx] != '\0')
+ goto arg_err_exit;
+
+ return true;
+
+arg_err_exit:
+ virNWFilterReportError(VIR_ERR_INVALID_ARG,
+ "%s", errmsg);
+ return false;
+}
+
+static bool
+ipsetFlagsFormatter(virBufferPtr buf,
+ virNWFilterRuleDefPtr nwf ATTRIBUTE_UNUSED,
+ nwItemDesc *item)
+{
+ uint8_t ctr;
+
+ for (ctr = 0; ctr < item->u.ipset.numFlags; ctr++) {
+ if (ctr != 0)
+ virBufferAddLit(buf, ",");
+ if ((item->u.ipset.flags & (1 << ctr)))
+ virBufferAddLit(buf, "src");
+ else
+ virBufferAddLit(buf, "dst");
+ }
+
+ return true;
+}
#define COMMON_MAC_PROPS(STRUCT) \
{\
@@ -1411,6 +1506,20 @@ static const virXMLAttr2Struct ipv6Attri
.dataIdx = offsetof(virNWFilterRuleDef,
p.STRUCT.ipHdr.dataState),\
.validator = stateValidator,\
.formatter = stateFormatter,\
+ },\
+ {\
+ .name = IPSET,\
+ .datatype = DATATYPE_STRING,\
+ .dataIdx = offsetof(virNWFilterRuleDef, p.STRUCT.ipHdr.dataIPSet),\
+ .validator = ipsetValidator,\
+ .formatter = ipsetFormatter,\
+ },\
+ {\
+ .name = IPSETFLAGS,\
+ .datatype = DATATYPE_IPSETFLAGS,\
+ .dataIdx = offsetof(virNWFilterRuleDef,
p.STRUCT.ipHdr.dataIPSetFlags),\
+ .validator = ipsetFlagsValidator,\
+ .formatter = ipsetFlagsFormatter,\
}
#define COMMON_PORT_PROPS(STRUCT) \
@@ -1853,6 +1962,7 @@ virNWFilterRuleDetailsParse(xmlNodePtr n
break;
case DATATYPE_STRING:
+ case DATATYPE_IPSETFLAGS:
if (!validator) {
/* not supported */
rc = -1;
@@ -1964,6 +2074,19 @@ err_exit:
goto cleanup;
}
+static void
+virNWFilterRuleDefFixupIPSet(ipHdrDataDefPtr ipHdr)
+{
+ if (HAS_ENTRY_ITEM(&ipHdr->dataIPSet) &&
+ !HAS_ENTRY_ITEM(&ipHdr->dataIPSetFlags)) {
+ ipHdr->dataIPSetFlags.flags = NWFILTER_ENTRY_ITEM_FLAG_EXISTS;
+ ipHdr->dataIPSetFlags.u.ipset.numFlags = 1;
+ ipHdr->dataIPSetFlags.u.ipset.flags = 1;
+ } else {
+ ipHdr->dataIPSet.flags = 0;
+ ipHdr->dataIPSetFlags.flags = 0;
+ }
+}
static void
virNWFilterRuleDefFixup(virNWFilterRuleDefPtr rule)
@@ -2017,6 +2140,7 @@ virNWFilterRuleDefFixup(virNWFilterRuleD
rule->p.ipHdrFilter.ipHdr.dataSrcIPAddr);
COPY_NEG_SIGN(rule->p.ipHdrFilter.ipHdr.dataDstIPMask,
rule->p.ipHdrFilter.ipHdr.dataDstIPAddr);
+ virNWFilterRuleDefFixupIPSet(&rule->p.ipHdrFilter.ipHdr);
break;
case VIR_NWFILTER_RULE_PROTOCOL_IPV6:
@@ -2024,6 +2148,7 @@ virNWFilterRuleDefFixup(virNWFilterRuleD
rule->p.ipv6HdrFilter.ipHdr.dataSrcIPAddr);
COPY_NEG_SIGN(rule->p.ipv6HdrFilter.ipHdr.dataDstIPMask,
rule->p.ipv6HdrFilter.ipHdr.dataDstIPAddr);
+ virNWFilterRuleDefFixupIPSet(&rule->p.ipv6HdrFilter.ipHdr);
break;
case VIR_NWFILTER_RULE_PROTOCOL_ARP:
@@ -2047,6 +2172,7 @@ virNWFilterRuleDefFixup(virNWFilterRuleD
rule->p.tcpHdrFilter.portData.dataSrcPortStart);
COPY_NEG_SIGN(rule->p.tcpHdrFilter.portData.dataDstPortEnd,
rule->p.tcpHdrFilter.portData.dataSrcPortStart);
+ virNWFilterRuleDefFixupIPSet(&rule->p.tcpHdrFilter.ipHdr);
break;
case VIR_NWFILTER_RULE_PROTOCOL_UDP:
@@ -2065,6 +2191,7 @@ virNWFilterRuleDefFixup(virNWFilterRuleD
rule->p.udpHdrFilter.portData.dataSrcPortStart);
COPY_NEG_SIGN(rule->p.udpHdrFilter.portData.dataDstPortEnd,
rule->p.udpHdrFilter.portData.dataSrcPortStart);
+ virNWFilterRuleDefFixupIPSet(&rule->p.udpHdrFilter.ipHdr);
break;
case VIR_NWFILTER_RULE_PROTOCOL_UDPLITE:
@@ -2077,6 +2204,7 @@ virNWFilterRuleDefFixup(virNWFilterRuleD
rule->p.udpliteHdrFilter.ipHdr.dataSrcIPFrom);
COPY_NEG_SIGN(rule->p.udpliteHdrFilter.ipHdr.dataDstIPTo,
rule->p.udpliteHdrFilter.ipHdr.dataDstIPFrom);
+ virNWFilterRuleDefFixupIPSet(&rule->p.udpliteHdrFilter.ipHdr);
break;
case VIR_NWFILTER_RULE_PROTOCOL_ESP:
@@ -2089,6 +2217,7 @@ virNWFilterRuleDefFixup(virNWFilterRuleD
rule->p.espHdrFilter.ipHdr.dataSrcIPFrom);
COPY_NEG_SIGN(rule->p.espHdrFilter.ipHdr.dataDstIPTo,
rule->p.espHdrFilter.ipHdr.dataDstIPFrom);
+ virNWFilterRuleDefFixupIPSet(&rule->p.espHdrFilter.ipHdr);
break;
case VIR_NWFILTER_RULE_PROTOCOL_AH:
@@ -2101,6 +2230,7 @@ virNWFilterRuleDefFixup(virNWFilterRuleD
rule->p.ahHdrFilter.ipHdr.dataSrcIPFrom);
COPY_NEG_SIGN(rule->p.ahHdrFilter.ipHdr.dataDstIPTo,
rule->p.ahHdrFilter.ipHdr.dataDstIPFrom);
+ virNWFilterRuleDefFixupIPSet(&rule->p.ahHdrFilter.ipHdr);
break;
case VIR_NWFILTER_RULE_PROTOCOL_SCTP:
@@ -2119,6 +2249,7 @@ virNWFilterRuleDefFixup(virNWFilterRuleD
rule->p.sctpHdrFilter.portData.dataSrcPortStart);
COPY_NEG_SIGN(rule->p.sctpHdrFilter.portData.dataDstPortEnd,
rule->p.sctpHdrFilter.portData.dataSrcPortStart);
+ virNWFilterRuleDefFixupIPSet(&rule->p.sctpHdrFilter.ipHdr);
break;
case VIR_NWFILTER_RULE_PROTOCOL_ICMP:
@@ -2133,6 +2264,7 @@ virNWFilterRuleDefFixup(virNWFilterRuleD
rule->p.icmpHdrFilter.ipHdr.dataDstIPFrom);
COPY_NEG_SIGN(rule->p.icmpHdrFilter.dataICMPCode,
rule->p.icmpHdrFilter.dataICMPType);
+ virNWFilterRuleDefFixupIPSet(&rule->p.icmpHdrFilter.ipHdr);
break;
case VIR_NWFILTER_RULE_PROTOCOL_ALL:
@@ -2156,6 +2288,7 @@ virNWFilterRuleDefFixup(virNWFilterRuleD
rule->p.igmpHdrFilter.ipHdr.dataSrcIPFrom);
COPY_NEG_SIGN(rule->p.igmpHdrFilter.ipHdr.dataDstIPTo,
rule->p.igmpHdrFilter.ipHdr.dataDstIPFrom);
+ virNWFilterRuleDefFixupIPSet(&rule->p.igmpHdrFilter.ipHdr);
break;
case VIR_NWFILTER_RULE_PROTOCOL_LAST:
@@ -3120,7 +3253,7 @@ virNWFilterRuleDefDetailsFormat(virBuffe
virBufferAsprintf(buf, " %s='",
att[i].name);
- if (att[i].formatter) {
+ if (att[i].formatter && !(flags &
NWFILTER_ENTRY_ITEM_FLAG_HAS_VAR)) {
if (!att[i].formatter(buf, def, item)) {
virNWFilterReportError(VIR_ERR_INTERNAL_ERROR,
_("formatter for %s %s
reported error"),
Index: libvirt/src/conf/nwfilter_conf.h
===================================================================
--- libvirt.orig/src/conf/nwfilter_conf.h
+++ libvirt/src/conf/nwfilter_conf.h
@@ -103,8 +103,9 @@ enum attrDatatype {
DATATYPE_BOOLEAN = (1 << 12),
DATATYPE_UINT32 = (1 << 13),
DATATYPE_UINT32_HEX = (1 << 14),
+ DATATYPE_IPSETFLAGS = (1 << 15),
- DATATYPE_LAST = (1 << 15),
+ DATATYPE_LAST = (1 << 16),
};
# define NWFILTER_MAC_BGA "01:80:c2:00:00:00"
@@ -136,9 +137,16 @@ struct _nwItemDesc {
uint8_t mask;
uint8_t flags;
} tcpFlags;
+ struct {
+ char setname[32];
+ uint8_t numFlags;
+ uint8_t flags;
+ } ipset;
} u;
};
+# define VALID_IPSETNAME \
+ "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_.:-+ "
typedef struct _ethHdrDataDef ethHdrDataDef;
typedef ethHdrDataDef *ethHdrDataDefPtr;
@@ -232,6 +240,8 @@ struct _ipHdrDataDef {
nwItemDesc dataState;
nwItemDesc dataConnlimitAbove;
nwItemDesc dataComment;
+ nwItemDesc dataIPSet;
+ nwItemDesc dataIPSetFlags;
};
Index: libvirt/src/nwfilter/nwfilter_ebiptables_driver.c
===================================================================
--- libvirt.orig/src/nwfilter/nwfilter_ebiptables_driver.c
+++ libvirt/src/nwfilter/nwfilter_ebiptables_driver.c
@@ -256,10 +256,13 @@ static int
_printDataType(virNWFilterVarCombIterPtr vars,
char *buf, int bufsize,
nwItemDescPtr item,
- bool asHex)
+ bool asHex, bool directionIn)
{
int done;
char *data;
+ uint8_t ctr;
+ virBuffer vb = VIR_BUFFER_INITIALIZER;
+ char *flags;
if (printVar(vars, buf, bufsize, item, &done) < 0)
return -1;
@@ -346,6 +349,40 @@ _printDataType(virNWFilterVarCombIterPtr
}
break;
+ case DATATYPE_IPSETFLAGS:
+ for (ctr = 0; ctr < item->u.ipset.numFlags; ctr++) {
+ if (ctr != 0)
+ virBufferAddLit(&vb, ",");
+ if ((item->u.ipset.flags & (1 << ctr))) {
+ if (directionIn)
+ virBufferAddLit(&vb, "dst");
+ else
+ virBufferAddLit(&vb, "src");
+ } else {
+ if (directionIn)
+ virBufferAddLit(&vb, "src");
+ else
+ virBufferAddLit(&vb, "dst");
+ }
+ }
+
+ if (virBufferError(&vb)) {
+ virReportOOMError();
+ virBufferFreeAndReset(&vb);
+ return -1;
+ }
+
+ flags = virBufferContentAndReset(&vb);
+
+ if (snprintf(buf, bufsize, "%s", flags) >= bufsize) {
+ virNWFilterReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("Buffer too small for IPSETFLAGS
type"));
+ VIR_FREE(flags);
+ return -1;
+ }
+ VIR_FREE(flags);
+ break;
+
default:
virNWFilterReportError(VIR_ERR_INTERNAL_ERROR,
_("Unhandled datatype %x"),
item->datatype);
@@ -362,16 +399,23 @@ printDataType(virNWFilterVarCombIterPtr
char *buf, int bufsize,
nwItemDescPtr item)
{
- return _printDataType(vars, buf, bufsize, item, 0);
+ return _printDataType(vars, buf, bufsize, item, 0, 0);
}
+static int
+printDataTypeDirection(virNWFilterVarCombIterPtr vars,
+ char *buf, int bufsize,
+ nwItemDescPtr item, bool directionIn)
+{
+ return _printDataType(vars, buf, bufsize, item, 0, directionIn);
+}
static int
printDataTypeAsHex(virNWFilterVarCombIterPtr vars,
char *buf, int bufsize,
nwItemDescPtr item)
{
- return _printDataType(vars, buf, bufsize, item, 1);
+ return _printDataType(vars, buf, bufsize, item, 1, 0);
}
@@ -927,6 +971,7 @@ iptablesHandleIpHdr(virBufferPtr buf,
char ipaddr[INET6_ADDRSTRLEN],
number[MAX(INT_BUFSIZE_BOUND(uint32_t),
INT_BUFSIZE_BOUND(int))];
+ char str[200];
const char *src = "--source";
const char *dst = "--destination";
const char *srcrange = "--src-range";
@@ -938,6 +983,26 @@ iptablesHandleIpHdr(virBufferPtr buf,
dstrange = "--src-range";
}
+ if (HAS_ENTRY_ITEM(&ipHdr->dataIPSet) &&
+ HAS_ENTRY_ITEM(&ipHdr->dataIPSetFlags)) {
+
+ if (printDataType(vars,
+ str, sizeof(str),
+ &ipHdr->dataIPSet) < 0)
+ goto err_exit;
+
+ virBufferAsprintf(afterStateMatch,
+ " -m set --match-set \"%s\" ",
+ str);
+
+ if (printDataTypeDirection(vars,
+ str, sizeof(str),
+ &ipHdr->dataIPSetFlags, directionIn) < 0)
+ goto err_exit;
+
+ virBufferAdd(afterStateMatch, str, -1);
+ }
+
if (HAS_ENTRY_ITEM(&ipHdr->dataSrcIPAddr)) {
if (printDataType(vars,
Index: libvirt/docs/schemas/nwfilter.rng
===================================================================
--- libvirt.orig/docs/schemas/nwfilter.rng
+++ libvirt/docs/schemas/nwfilter.rng
@@ -485,6 +485,14 @@
<ref name="stateflags-type"/>
</attribute>
</optional>
+ <optional>
+ <attribute name="ipset">
+ <ref name="ipset-type"/>
+ </attribute>
+ <attribute name="ipsetflags">
+ <ref name="ipsetflags-type"/>
+ </attribute>
+ </optional>
</interleave>
</define>
@@ -1060,4 +1068,19 @@
<param
name="pattern">((SYN|ACK|URG|PSH|FIN|RST)(,(SYN|ACK|URG|PSH|FIN|RST))*|ALL|NONE)/((SYN|ACK|URG|PSH|FIN|RST)(,(SYN|ACK|URG|PSH|FIN|RST))*|ALL|NONE)</param>
</data>
</define>
+
+ <define name='ipset-type'>
+ <choice>
+ <ref name="variable-name-type"/>
+ <data type="string">
+ <param name="pattern">[a-zA-Z0-9_\.:\-\+]{1,31}</param>
+ </data>
+ </choice>
+ </define>
+
+ <define name='ipsetflags-type'>
+ <data type="string">
+ <param name="pattern">(src|dst)(,(src|dst)){0,5}</param>
+ </data>
+ </define>
</grammar>
Index: libvirt/tests/nwfilterxml2xmlin/ipset-test.xml
===================================================================
--- /dev/null
+++ libvirt/tests/nwfilterxml2xmlin/ipset-test.xml
@@ -0,0 +1,15 @@
+<filter name='testcase' chain='root'>
+ <uuid>5c6d49af-b071-6127-b4ec-6f8ed4b55335</uuid>
+ <rule action='accept' direction='out'>
+ <all ipset='test' ipsetflags='src,dst' />
+ </rule>
+ <rule action='accept' direction='in'>
+ <all ipset='test' ipsetflags='SRC,DST,SRC' />
+ </rule>
+ <rule action='accept' direction='in'>
+ <all ipset='test:_.-+' ipsetflags='SRC,dSt,SRC' />
+ </rule>
+ <rule action='accept' direction='in'>
+ <all ipset='$IPSETNAME' ipsetflags='src,dst' />
+ </rule>
+</filter>
Index: libvirt/tests/nwfilterxml2xmlout/ipset-test.xml
===================================================================
--- /dev/null
+++ libvirt/tests/nwfilterxml2xmlout/ipset-test.xml
@@ -0,0 +1,15 @@
+<filter name='testcase' chain='root'>
+ <uuid>5c6d49af-b071-6127-b4ec-6f8ed4b55335</uuid>
+ <rule action='accept' direction='out' priority='500'>
+ <all ipset='test' ipsetflags='src,dst'/>
+ </rule>
+ <rule action='accept' direction='in' priority='500'>
+ <all ipset='test' ipsetflags='src,dst,src'/>
+ </rule>
+ <rule action='accept' direction='in' priority='500'>
+ <all ipset='test:_.-+' ipsetflags='src,dst,src'/>
+ </rule>
+ <rule action='accept' direction='in' priority='500'>
+ <all ipset='$IPSETNAME' ipsetflags='src,dst'/>
+ </rule>
+</filter>
Index: libvirt/tests/nwfilterxml2xmltest.c
===================================================================
--- libvirt.orig/tests/nwfilterxml2xmltest.c
+++ libvirt/tests/nwfilterxml2xmltest.c
@@ -157,6 +157,8 @@ mymain(void)
DO_TEST("iter-test2", false);
DO_TEST("iter-test3", false);
+ DO_TEST("ipset-test", false);
+
return ret==0 ? EXIT_SUCCESS : EXIT_FAILURE;
}
Index: libvirt/docs/formatnwfilter.html.in
===================================================================
--- libvirt.orig/docs/formatnwfilter.html.in
+++ libvirt/docs/formatnwfilter.html.in
@@ -528,6 +528,10 @@
<li>IPV6_MASK: IPv6 mask in numbers format (FFFF:FFFF:FC00::) or CIDR
mask (0-128)</li>
<li>STRING: A string</li>
<li>BOOLEAN: 'true', 'yes', '1' or 'false', 'no', '0'</li>
+ <li>IPSETFLAGS: The source and destination flags of the ipset described
+ by up to 6 'src' or 'dst' elements selecting features from either
+ the source or destination part of the packet header; example:
+ src,src,dst</li>
</ul>
<p>
<br/><br/>
@@ -1169,6 +1173,16 @@
<td>STRING</td>
<td>TCP-only: format of mask/flags with mask and flags each being a
comma separated list of SYN,ACK,URG,PSH,FIN,RST or NONE or ALL</td>
</tr>
+ <tr>
+ <td>ipset <span class="since">(Since 0.9.11)</span></td>
+ <td>STRING</td>
+ <td>The name of an IPSet managed outside of libvirt</td>
+ </tr>
+ <tr>
+ <td>ipsetflags <span class="since">(Since 0.9.11)</span></td>
+ <td>IPSETFLAGS</td>
+ <td>flags for the IPSet; requires ipset attributed</td>
+ </tr>
</table>
<p>
<br/><br/>
@@ -1269,6 +1283,16 @@
<td>STRING</td>
<td>comma separated list of NEW,ESTABLISHED,RELATED,INVALID or NONE</td>
</tr>
+ <tr>
+ <td>ipset <span class="since">(Since 0.9.11)</span></td>
+ <td>STRING</td>
+ <td>The name of an IPSet managed outside of libvirt</td>
+ </tr>
+ <tr>
+ <td>ipsetflags <span class="since">(Since 0.9.11)</span></td>
+ <td>IPSETFLAGS</td>
+ <td>flags for the IPSet; requires ipset attributed</td>
+ </tr>
</table>
<p>
<br/><br/>
@@ -1358,6 +1382,16 @@
<td>STRING</td>
<td>comma separated list of NEW,ESTABLISHED,RELATED,INVALID or NONE</td>
</tr>
+ <tr>
+ <td>ipset <span class="since">(Since 0.9.11)</span></td>
+ <td>STRING</td>
+ <td>The name of an IPSet managed outside of libvirt</td>
+ </tr>
+ <tr>
+ <td>ipsetflags <span class="since">(Since 0.9.11)</span></td>
+ <td>IPSETFLAGS</td>
+ <td>flags for the IPSet; requires ipset attributed</td>
+ </tr>
</table>
<p>
<br/><br/>
@@ -1459,6 +1493,16 @@
<td>STRING</td>
<td>TCP-only: format of mask/flags with mask and flags each being a
comma separated list of SYN,ACK,URG,PSH,FIN,RST or NONE or ALL</td>
</tr>
+ <tr>
+ <td>ipset <span class="since">(Since 0.9.11)</span></td>
+ <td>STRING</td>
+ <td>The name of an IPSet managed outside of libvirt</td>
+ </tr>
+ <tr>
+ <td>ipsetflags <span class="since">(Since 0.9.11)</span></td>
+ <td>IPSETFLAGS</td>
+ <td>flags for the IPSet; requires ipset attributed</td>
+ </tr>
</table>
<p>
<br/><br/>
@@ -1545,6 +1589,16 @@
<td>STRING</td>
<td>comma separated list of NEW,ESTABLISHED,RELATED,INVALID or NONE</td>
</tr>
+ <tr>
+ <td>ipset <span class="since">(Since 0.9.11)</span></td>
+ <td>STRING</td>
+ <td>The name of an IPSet managed outside of libvirt</td>
+ </tr>
+ <tr>
+ <td>ipsetflags <span class="since">(Since 0.9.11)</span></td>
+ <td>IPSETFLAGS</td>
+ <td>flags for the IPSet; requires ipset attributed</td>
+ </tr>
</table>
<p>
<br/><br/>
@@ -1619,6 +1673,16 @@
<td>STRING</td>
<td>comma separated list of NEW,ESTABLISHED,RELATED,INVALID or NONE</td>
</tr>
+ <tr>
+ <td>ipset <span class="since">(Since 0.9.11)</span></td>
+ <td>STRING</td>
+ <td>The name of an IPSet managed outside of libvirt</td>
+ </tr>
+ <tr>
+ <td>ipsetflags <span class="since">(Since 0.9.11)</span></td>
+ <td>IPSETFLAGS</td>
+ <td>flags for the IPSet; requires ipset attributed</td>
+ </tr>
</table>
<p>
<br/><br/>
12 years, 7 months
[libvirt] problems starting several qemu VMS simultaneously
by Serge Hallyn
Hi,
I grabbed today's git head of libvirt. Created a VM (clean install of
ubuntu oneiric, installed through virt-manager), and cloned it 3 times.
Then I did
serge@ubuntu:~$ for i in `seq 1 4`; do virsh start o$i > /tmp/o$i 2>&1 & done
[1] 12184
[2] 12185
[3] 12186
[4] 12187
serge@ubuntu:~$ virsh list
error: Failed to list active domains
error: End of file while reading data: Input/output error
serge@ubuntu:~$ virsh list
Id Name State
----------------------------------------------------
5 o2 shut off
7 o3 shut off
8 o4 shut off
[1] Exit 1 virsh start o$i > /tmp/o$i 2>&1
[2] Done virsh start o$i > /tmp/o$i 2>&1
serge@ubuntu:~$ virsh list
Id Name State
----------------------------------------------------
5 o2 running
7 o3 running
8 o4 running
[3]- Done virsh start o$i > /tmp/o$i 2>&1
[4]+ Done virsh start o$i > /tmp/o$i 2>&1
serge@ubuntu:~$ cat /tmp/o1
error: Failed to start domain o1
error: Unable to wait for child process: Bad file descriptor
It's quite reproducible. An ubuntu bug report was filed at
https://bugs.launchpad.net/ubuntu/+source/libvirt/+bug/961217
It's also very reminiscent of some lxc startup handshake issues
which have been fixed.
You can find the last chunk of the log file at
http://people.canonical.com/~serge/libvirtd-parallel-startup.log
-serge
12 years, 7 months