Devel
Threads by month
- ----- 2026 -----
- March
- February
- January
- ----- 2025 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2007 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2006 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2005 -----
- December
- 9 participants
- 40089 discussions
[libvirt] [PATCH] openvz: read vmguarpages/privvmpages to set memory tunables [v2]
by Guido Günther 15 May '12
by Guido Günther 15 May '12
15 May '12
---
This is a reworked version of the patch already sent, now adding
handling for "unlimited" (represented by LONG_MAX in openvz) as well as
a schema testcase. I also switched all value to unsigned long long to
avoid overflows.
Note that privvmpages is the amount of memory available to the
application. The total memory usage of the container might be higher due
to used kernel memory. This does probably warrant an extra tunable
later. O.k. to apply?
Cheers,
-- Guido
src/openvz/openvz_conf.c | 113 ++++++++++++
src/openvz/openvz_driver.c | 208 +++++++++++++++++++++++
tests/domainschemadata/domain-openvz-simple.xml | 27 +++
3 files changed, 348 insertions(+)
create mode 100644 tests/domainschemadata/domain-openvz-simple.xml
diff --git a/src/openvz/openvz_conf.c b/src/openvz/openvz_conf.c
index 5848ec4..a169ae6 100644
--- a/src/openvz/openvz_conf.c
+++ b/src/openvz/openvz_conf.c
@@ -129,6 +129,46 @@ int openvzExtractVersion(struct openvz_driver *driver)
}
+/* Parse config values of the form barrier:limit into barrier and limit */
+static int
+openvzParseBarrierLimit(const char* value,
+ unsigned long long *barrier,
+ unsigned long long *limit)
+{
+ char *token;
+ char *saveptr = NULL;
+ char *str = strdup(value);
+
+ if (str == NULL) {
+ virReportOOMError();
+ goto error;
+ }
+
+ token = strtok_r(str, ":", &saveptr);
+ if (token == NULL) {
+ goto error;
+ } else {
+ if (barrier != NULL) {
+ if (virStrToLong_ull(token, NULL, 10, barrier))
+ goto error;
+ }
+ }
+ token = strtok_r(NULL, ":", &saveptr);
+ if (token == NULL) {
+ goto error;
+ } else {
+ if (limit != NULL) {
+ if (virStrToLong_ull(token, NULL, 10, limit))
+ goto error;
+ }
+ }
+ return 0;
+error:
+ VIR_FREE(str);
+ return -1;
+}
+
+
static int openvzDefaultConsoleType(const char *ostype ATTRIBUTE_UNUSED)
{
return VIR_DOMAIN_CHR_CONSOLE_TARGET_TYPE_OPENVZ;
@@ -423,6 +463,78 @@ error:
}
+static int
+openvzReadMemConf(virDomainDefPtr def, int veid)
+{
+ int ret;
+ char *temp = NULL;
+ unsigned long long barrier, limit;
+ const char *param;
+ unsigned long kb_per_pages;
+
+ kb_per_pages = sysconf(_SC_PAGESIZE) / 1024;
+ if (kb_per_pages == -1) {
+ openvzError(VIR_ERR_INTERNAL_ERROR,
+ _("Can't determine page size"));
+ goto error;
+ }
+
+ /* Memory allocation guarantee */
+ param = "VMGUARPAGES";
+ ret = openvzReadVPSConfigParam(veid, param, &temp);
+ if (ret < 0) {
+ openvzError(VIR_ERR_INTERNAL_ERROR,
+ _("Could not read '%s' from config for container %d"),
+ param, veid);
+ goto error;
+ } else if (ret > 0) {
+ ret = openvzParseBarrierLimit(temp, &barrier, NULL);
+ if (ret < 0) {
+ openvzError(VIR_ERR_INTERNAL_ERROR,
+ _("Could not parse barrier of '%s' "
+ "from config for container %d"), param, veid);
+ goto error;
+ }
+ if (barrier == LONG_MAX)
+ def->mem.min_guarantee = 0ull;
+ else
+ def->mem.min_guarantee = barrier * kb_per_pages;
+ }
+
+ /* Memory hard and soft limits */
+ param = "PRIVVMPAGES";
+ ret = openvzReadVPSConfigParam(veid, param, &temp);
+ if (ret < 0) {
+ openvzError(VIR_ERR_INTERNAL_ERROR,
+ _("Could not read '%s' from config for container %d"),
+ param, veid);
+ goto error;
+ } else if (ret > 0) {
+ ret = openvzParseBarrierLimit(temp, &barrier, &limit);
+ if (ret < 0) {
+ openvzError(VIR_ERR_INTERNAL_ERROR,
+ _("Could not parse barrier and limit of '%s' "
+ "from config for container %d"), param, veid);
+ goto error;
+ }
+ if (barrier == LONG_MAX)
+ def->mem.soft_limit = 0ull;
+ else
+ def->mem.soft_limit = barrier * kb_per_pages;
+
+ if (limit == LONG_MAX)
+ def->mem.hard_limit = 0ull;
+ else
+ def->mem.hard_limit = limit * kb_per_pages;
+ }
+
+ ret = 0;
+error:
+ VIR_FREE(temp);
+ return ret;
+}
+
+
/* Free all memory associated with a openvz_driver structure */
void
openvzFreeDriver(struct openvz_driver *driver)
@@ -535,6 +647,7 @@ int openvzLoadDomains(struct openvz_driver *driver) {
openvzReadNetworkConf(dom->def, veid);
openvzReadFSConf(dom->def, veid);
+ openvzReadMemConf(dom->def, veid);
virUUIDFormat(dom->def->uuid, uuidstr);
if (virHashAddEntry(driver->domains.objs, uuidstr, dom) < 0)
diff --git a/src/openvz/openvz_driver.c b/src/openvz/openvz_driver.c
index e8b6915..555161e 100644
--- a/src/openvz/openvz_driver.c
+++ b/src/openvz/openvz_driver.c
@@ -54,6 +54,7 @@
#include "nodeinfo.h"
#include "memory.h"
#include "virfile.h"
+#include "virtypedparam.h"
#include "logging.h"
#include "command.h"
#include "viruri.h"
@@ -65,6 +66,8 @@
#define CMDBUF_LEN 1488
#define CMDOP_LEN 288
+#define OPENVZ_NB_MEM_PARAM 3
+
static int openvzGetProcessInfo(unsigned long long *cpuTime, int vpsid);
static int openvzGetMaxVCPUs(virConnectPtr conn, const char *type);
static int openvzDomainGetMaxVcpus(virDomainPtr dom);
@@ -1631,6 +1634,209 @@ cleanup:
return -1;
}
+
+static int
+openvzDomainGetBarrierLimit(virDomainPtr domain,
+ const char *param,
+ unsigned long long *barrier,
+ unsigned long long *limit)
+{
+ int status, ret = -1;
+ char *output = NULL;
+ virCommandPtr cmd = virCommandNewArgList(VZLIST, "--no-header", NULL);
+
+ virCommandSetOutputBuffer(cmd, &output);
+ virCommandAddArgFormat(cmd, "-o%s.b,%s.l", param, param);
+ virCommandAddArg(cmd, domain->name);
+ if (virCommandRun(cmd, &status)) {
+ openvzError(VIR_ERR_OPERATION_FAILED,
+ _("Failed to get %s for %s: %d"), param, domain->name,
+ status);
+ goto cleanup;
+ }
+
+ if (sscanf(output, "%llu %llu", barrier, limit) != 2) {
+ openvzError(VIR_ERR_INTERNAL_ERROR,
+ _("Can't parse "VZLIST" output, got %s"), output);
+ goto cleanup;
+ }
+
+ ret = 0;
+cleanup:
+ VIR_FREE(output);
+ virCommandFree(cmd);
+ return ret;
+}
+
+
+static int
+openvzDomainSetBarrierLimit(virDomainPtr domain,
+ const char *param,
+ unsigned long long barrier,
+ unsigned long long limit)
+{
+ int status, ret = -1;
+ virCommandPtr cmd = virCommandNewArgList(VZCTL, "--quiet", "set", NULL);
+
+ /* LONG_MAX indicates unlimited so reject larger values */
+ if (barrier > LONG_MAX || limit > LONG_MAX) {
+ openvzError(VIR_ERR_OPERATION_FAILED,
+ _("Failed to set %s for %s: value too large"), param,
+ domain->name);
+ goto cleanup;
+ }
+
+ virCommandAddArg(cmd, domain->name);
+ virCommandAddArgFormat(cmd, "--%s", param);
+ virCommandAddArgFormat(cmd, "%llu:%llu", barrier, limit);
+ virCommandAddArg(cmd, "--save");
+ if (virCommandRun(cmd, &status)) {
+ openvzError(VIR_ERR_OPERATION_FAILED,
+ _("Failed to set %s for %s: %d"), param, domain->name,
+ status);
+ goto cleanup;
+ }
+
+ ret = 0;
+cleanup:
+ virCommandFree(cmd);
+ return ret;
+}
+
+
+static int
+openvzDomainGetMemoryParameters(virDomainPtr domain,
+ virTypedParameterPtr params,
+ int *nparams,
+ unsigned int flags)
+{
+ int i, result = -1;
+ const char *name;
+ long kb_per_pages;
+ unsigned long long barrier, limit, val;
+
+ virCheckFlags(0, -1);
+
+ kb_per_pages = sysconf(_SC_PAGESIZE) / 1024;
+ if (kb_per_pages == -1) {
+ openvzError(VIR_ERR_INTERNAL_ERROR,
+ _("Can't determine page size"));
+ goto cleanup;
+ }
+
+ if (*nparams == 0) {
+ *nparams = OPENVZ_NB_MEM_PARAM;
+ return 0;
+ }
+
+ for (i = 0; i <= *nparams; i++) {
+ virMemoryParameterPtr param = ¶ms[i];
+
+ switch (i) {
+ case 0:
+ name = "privvmpages";
+ if (openvzDomainGetBarrierLimit(domain, name, &barrier, &limit) < 0)
+ goto cleanup;
+
+ val = (limit == LONG_MAX) ? 0ull : limit * kb_per_pages;
+ if (virTypedParameterAssign(param, VIR_DOMAIN_MEMORY_HARD_LIMIT,
+ VIR_TYPED_PARAM_ULLONG, val) < 0)
+ goto cleanup;
+ break;
+
+ case 1:
+ name = "privvmpages";
+ if (openvzDomainGetBarrierLimit(domain, name, &barrier, &limit) < 0)
+ goto cleanup;
+
+ val = (barrier == LONG_MAX) ? 0ull : barrier * kb_per_pages;
+ if (virTypedParameterAssign(param, VIR_DOMAIN_MEMORY_SOFT_LIMIT,
+ VIR_TYPED_PARAM_ULLONG, val) < 0)
+ goto cleanup;
+ break;
+
+ case 2:
+ name = "vmguarpages";
+ if (openvzDomainGetBarrierLimit(domain, name, &barrier, &limit) < 0)
+ goto cleanup;
+
+ val = (barrier == LONG_MAX) ? 0ull : barrier * kb_per_pages;
+ if (virTypedParameterAssign(param, VIR_DOMAIN_MEMORY_MIN_GUARANTEE,
+ VIR_TYPED_PARAM_ULLONG, val) < 0)
+ goto cleanup;
+ break;
+ }
+ }
+
+ if (*nparams > OPENVZ_NB_MEM_PARAM)
+ *nparams = OPENVZ_NB_MEM_PARAM;
+ result = 0;
+
+cleanup:
+ return result;
+}
+
+
+static int
+openvzDomainSetMemoryParameters(virDomainPtr domain,
+ virTypedParameterPtr params,
+ int nparams,
+ unsigned int flags)
+{
+ int i, result = -1;
+ long kb_per_pages;
+
+ kb_per_pages = sysconf(_SC_PAGESIZE) / 1024;
+ if (kb_per_pages == -1) {
+ openvzError(VIR_ERR_INTERNAL_ERROR,
+ _("Can't determine page size"));
+ goto cleanup;
+ }
+
+ virCheckFlags(0, -1);
+ if (virTypedParameterArrayValidate(params, nparams,
+ VIR_DOMAIN_MEMORY_HARD_LIMIT,
+ VIR_TYPED_PARAM_ULLONG,
+ VIR_DOMAIN_MEMORY_SOFT_LIMIT,
+ VIR_TYPED_PARAM_ULLONG,
+ VIR_DOMAIN_MEMORY_MIN_GUARANTEE,
+ VIR_TYPED_PARAM_ULLONG,
+ NULL) < 0)
+ return -1;
+
+ for (i = 0; i < nparams; i++) {
+ virTypedParameterPtr param = ¶ms[i];
+ unsigned long long barrier, limit;
+
+ if (STREQ(param->field, VIR_DOMAIN_MEMORY_HARD_LIMIT)) {
+ if (openvzDomainGetBarrierLimit(domain, "privvmpages",
+ &barrier, &limit) < 0)
+ goto cleanup;
+ limit = params[i].value.ul / kb_per_pages;
+ if (openvzDomainSetBarrierLimit(domain, "privvmpages",
+ barrier, limit) < 0)
+ goto cleanup;
+ } else if (STREQ(param->field, VIR_DOMAIN_MEMORY_SOFT_LIMIT)) {
+ if (openvzDomainGetBarrierLimit(domain, "privvmpages",
+ &barrier, &limit) < 0)
+ goto cleanup;
+ barrier = params[i].value.ul / kb_per_pages;
+ if (openvzDomainSetBarrierLimit(domain, "privvmpages",
+ barrier, limit) < 0)
+ goto cleanup;
+ } else if (STREQ(param->field, VIR_DOMAIN_MEMORY_MIN_GUARANTEE)) {
+ barrier = params[i].value.ul / kb_per_pages;
+ if (openvzDomainSetBarrierLimit(domain, "vmguarpages",
+ barrier, LONG_MAX) < 0)
+ goto cleanup;
+ }
+ }
+ result = 0;
+cleanup:
+ return result;
+}
+
+
static int
openvzGetVEStatus(virDomainObjPtr vm, int *status, int *reason)
{
@@ -1752,6 +1958,8 @@ static virDriver openvzDriver = {
.domainDestroy = openvzDomainShutdown, /* 0.3.1 */
.domainDestroyFlags = openvzDomainShutdownFlags, /* 0.9.4 */
.domainGetOSType = openvzGetOSType, /* 0.3.1 */
+ .domainGetMemoryParameters = openvzDomainGetMemoryParameters, /* 0.9.12 */
+ .domainSetMemoryParameters = openvzDomainSetMemoryParameters, /* 0.9.12 */
.domainGetInfo = openvzDomainGetInfo, /* 0.3.1 */
.domainGetState = openvzDomainGetState, /* 0.9.2 */
.domainSetVcpus = openvzDomainSetVcpus, /* 0.4.6 */
diff --git a/tests/domainschemadata/domain-openvz-simple.xml b/tests/domainschemadata/domain-openvz-simple.xml
new file mode 100644
index 0000000..aba64a4
--- /dev/null
+++ b/tests/domainschemadata/domain-openvz-simple.xml
@@ -0,0 +1,27 @@
+<domain type='openvz'>
+ <name>100</name>
+ <uuid>7109d234-f5a8-30a6-5dd2-39ca85ce3958</uuid>
+ <memory unit='KiB'>0</memory>
+ <currentMemory unit='KiB'>0</currentMemory>
+ <memtune>
+ <hard_limit unit='KiB'>278528</hard_limit>
+ <soft_limit unit='KiB'>262144</soft_limit>
+ <min_guarantee unit='KiB'>135168</min_guarantee>
+ </memtune>
+ <vcpu>1</vcpu>
+ <os>
+ <type>exe</type>
+ <init>/sbin/init</init>
+ </os>
+ <clock offset='utc'/>
+ <on_poweroff>destroy</on_poweroff>
+ <on_reboot>destroy</on_reboot>
+ <on_crash>destroy</on_crash>
+ <devices>
+ <filesystem type='template' accessmode='passthrough'>
+ <source name='debian'/>
+ <target dir='/'/>
+ </filesystem>
+ </devices>
+</domain>
+
--
1.7.10
2
7
[libvirt] [PATCH] Allow stack traces to be included with log messages
by Daniel P. Berrange 15 May '12
by Daniel P. Berrange 15 May '12
15 May '12
From: "Daniel P. Berrange" <berrange(a)redhat.com>
Sometimes it is useful to see the callpath for log messages.
This change enhances the log filter syntax so that stck traces
can be show by setting '1:+NAME' instead of '1:NAME'.
This results in output like:
2012-05-09 14:18:45.136+0000: 13314: debug : virInitialize:414 : register drivers
/home/berrange/src/virt/libvirt/src/.libs/libvirt.so.0(virInitialize+0xd6)[0x7f89188ebe86]
/home/berrange/src/virt/libvirt/tools/.libs/lt-virsh[0x431921]
/lib64/libc.so.6(__libc_start_main+0xf5)[0x3a21e21735]
/home/berrange/src/virt/libvirt/tools/.libs/lt-virsh[0x40a279]
2012-05-09 14:18:45.136+0000: 13314: debug : virRegisterDriver:775 : driver=0x7f8918d02760 name=Test
/home/berrange/src/virt/libvirt/src/.libs/libvirt.so.0(virRegisterDriver+0x6b)[0x7f89188ec717]
/home/berrange/src/virt/libvirt/src/.libs/libvirt.so.0(+0x11b3ad)[0x7f891891e3ad]
/home/berrange/src/virt/libvirt/src/.libs/libvirt.so.0(virInitialize+0xf3)[0x7f89188ebea3]
/home/berrange/src/virt/libvirt/tools/.libs/lt-virsh[0x431921]
/lib64/libc.so.6(__libc_start_main+0xf5)[0x3a21e21735]
/home/berrange/src/virt/libvirt/tools/.libs/lt-virsh[0x40a279]
* docs/logging.html.in: Document new syntax
* configure.ac: Check for execinfo.h
* src/util/logging.c, src/util/logging.h: Add support for
stack traces
* tests/testutils.c: Adapt to API change
Signed-off-by: Daniel P. Berrange <berrange(a)redhat.com>
---
configure.ac | 2 +-
docs/logging.html.in | 6 +++--
src/util/logging.c | 67 +++++++++++++++++++++++++++++++++++++++++---------
src/util/logging.h | 9 ++++++-
tests/testutils.c | 1 +
5 files changed, 70 insertions(+), 15 deletions(-)
diff --git a/configure.ac b/configure.ac
index 30eff91..c1bf57b 100644
--- a/configure.ac
+++ b/configure.ac
@@ -158,7 +158,7 @@ dnl Availability of various common headers (non-fatal if missing).
AC_CHECK_HEADERS([pwd.h paths.h regex.h sys/un.h \
sys/poll.h syslog.h mntent.h net/ethernet.h linux/magic.h \
sys/un.h sys/syscall.h netinet/tcp.h ifaddrs.h libtasn1.h \
- net/if.h])
+ net/if.h execinfo.h])
AC_MSG_CHECKING([for struct ifreq in net/if.h])
AC_COMPILE_IFELSE([AC_LANG_PROGRAM(
diff --git a/docs/logging.html.in b/docs/logging.html.in
index 22b5422..87e2292 100644
--- a/docs/logging.html.in
+++ b/docs/logging.html.in
@@ -114,8 +114,10 @@
</h3>
<p>The syntax for filters and outputs is the same for both types of
variables.</p>
- <p>The format for a filter is:</p>
- <pre>x:name</pre>
+ <p>The format for a filter is one of:</p>
+ <pre>
+ x:name (log message only)
+ x:+name (log message + stack trace)</pre>
<p>where <code>name</code> is a match string e.g. <code>remote</code> or
<code>qemu</code> and the x is the minimal level where matching messages
should be logged:</p>
diff --git a/src/util/logging.c b/src/util/logging.c
index 48a056d..062917d 100644
--- a/src/util/logging.c
+++ b/src/util/logging.c
@@ -34,6 +34,9 @@
#if HAVE_SYSLOG_H
# include <syslog.h>
#endif
+#ifdef HAVE_EXECINFO_H
+# include <execinfo.h>
+#endif
#include "ignore-value.h"
#include "virterror_internal.h"
@@ -64,6 +67,7 @@ static int virLogEnd = 0;
struct _virLogFilter {
const char *match;
int priority;
+ unsigned int flags;
};
typedef struct _virLogFilter virLogFilter;
typedef virLogFilter *virLogFilterPtr;
@@ -99,7 +103,9 @@ static int virLogResetFilters(void);
static int virLogResetOutputs(void);
static int virLogOutputToFd(const char *category, int priority,
const char *funcname, long long linenr,
- const char *timestamp, const char *str,
+ const char *timestamp,
+ unsigned int flags,
+ const char *str,
void *data);
/*
@@ -472,7 +478,7 @@ static int virLogResetFilters(void) {
* virLogDefineFilter:
* @match: the pattern to match
* @priority: the priority to give to messages matching the pattern
- * @flags: extra flag, currently unused
+ * @flags: extra flags, see virLogFilterFlags enum
*
* Defines a pattern used for log filtering, it allow to select or
* reject messages independently of the default priority.
@@ -487,7 +493,7 @@ int virLogDefineFilter(const char *match, int priority,
int i;
char *mdup = NULL;
- virCheckFlags(0, -1);
+ virCheckFlags(VIR_LOG_STACK_TRACE, -1);
if ((match == NULL) || (priority < VIR_LOG_DEBUG) ||
(priority > VIR_LOG_ERROR))
@@ -514,6 +520,7 @@ int virLogDefineFilter(const char *match, int priority,
}
virLogFilters[i].match = mdup;
virLogFilters[i].priority = priority;
+ virLogFilters[i].flags = flags;
virLogNbFilters++;
cleanup:
virLogUnlock();
@@ -530,7 +537,8 @@ cleanup:
*
* Returns 0 if not matched or the new priority if found.
*/
-static int virLogFiltersCheck(const char *input) {
+static int virLogFiltersCheck(const char *input,
+ unsigned int *flags) {
int ret = 0;
int i;
@@ -538,6 +546,7 @@ static int virLogFiltersCheck(const char *input) {
for (i = 0;i < virLogNbFilters;i++) {
if (strstr(input, virLogFilters[i].match)) {
ret = virLogFilters[i].priority;
+ *flags = virLogFilters[i].flags;
break;
}
}
@@ -691,6 +700,7 @@ void virLogMessage(const char *category, int priority, const char *funcname,
int saved_errno = errno;
int emit = 1;
va_list ap;
+ unsigned int filterflags = 0;
if (!virLogInitialized)
virLogStartup();
@@ -701,7 +711,7 @@ void virLogMessage(const char *category, int priority, const char *funcname,
/*
* check against list of specific logging patterns
*/
- fprio = virLogFiltersCheck(category);
+ fprio = virLogFiltersCheck(category, &filterflags);
if (fprio == 0) {
if (priority < virLogDefaultPriority)
emit = 0;
@@ -753,13 +763,14 @@ void virLogMessage(const char *category, int priority, const char *funcname,
if (virLogVersionString(&ver) >= 0)
virLogOutputs[i].f(category, VIR_LOG_INFO,
__func__, __LINE__,
- timestamp, ver,
+ timestamp, 0, ver,
virLogOutputs[i].data);
VIR_FREE(ver);
virLogOutputs[i].logVersion = false;
}
virLogOutputs[i].f(category, priority, funcname, linenr,
- timestamp, msg, virLogOutputs[i].data);
+ timestamp, filterflags,
+ msg, virLogOutputs[i].data);
}
}
if ((virLogNbOutputs == 0) && (flags != 1)) {
@@ -768,13 +779,14 @@ void virLogMessage(const char *category, int priority, const char *funcname,
if (virLogVersionString(&ver) >= 0)
virLogOutputToFd(category, VIR_LOG_INFO,
__func__, __LINE__,
- timestamp, ver,
+ timestamp, 0, ver,
(void *) STDERR_FILENO);
VIR_FREE(ver);
logVersionStderr = false;
}
virLogOutputToFd(category, priority, funcname, linenr,
- timestamp, msg, (void *) STDERR_FILENO);
+ timestamp, filterflags,
+ msg, (void *) STDERR_FILENO);
}
virLogUnlock();
@@ -783,11 +795,30 @@ cleanup:
errno = saved_errno;
}
+
+static void virLogStackTraceToFd(int fd)
+{
+#ifdef HAVE_EXECINFO_H
+ void *array[100];
+ int size;
+
+#define STRIP_DEPTH 3
+
+ size = backtrace(array, sizeof(array)/sizeof(array[0]));
+ backtrace_symbols_fd(array + STRIP_DEPTH, size - STRIP_DEPTH, fd);
+ ignore_value(safewrite(fd, "\n", 1));
+#else
+ const char *msg = "stack trace not available on this platform";
+ ignore_value(safewrite(fd, msg, strlen(msg)));
+#endif
+}
+
static int virLogOutputToFd(const char *category ATTRIBUTE_UNUSED,
int priority ATTRIBUTE_UNUSED,
const char *funcname ATTRIBUTE_UNUSED,
long long linenr ATTRIBUTE_UNUSED,
const char *timestamp,
+ unsigned int flags,
const char *str,
void *data)
{
@@ -804,6 +835,9 @@ static int virLogOutputToFd(const char *category ATTRIBUTE_UNUSED,
ret = safewrite(fd, msg, strlen(msg));
VIR_FREE(msg);
+ if (flags & VIR_LOG_STACK_TRACE)
+ virLogStackTraceToFd(fd);
+
return ret;
}
@@ -841,6 +875,7 @@ static int virLogOutputToSyslog(const char *category ATTRIBUTE_UNUSED,
const char *funcname ATTRIBUTE_UNUSED,
long long linenr ATTRIBUTE_UNUSED,
const char *timestamp ATTRIBUTE_UNUSED,
+ unsigned int flags ATTRIBUTE_UNUSED,
const char *str,
void *data ATTRIBUTE_UNUSED)
{
@@ -1024,12 +1059,17 @@ int virLogParseFilters(const char *filters) {
virSkipSpaces(&cur);
while (*cur != 0) {
+ unsigned int flags = 0;
prio= virParseNumber(&cur);
if ((prio < VIR_LOG_DEBUG) || (prio > VIR_LOG_ERROR))
goto cleanup;
if (*cur != ':')
goto cleanup;
cur++;
+ if (*cur == '+') {
+ flags |= VIR_LOG_STACK_TRACE;
+ cur++;
+ }
str = cur;
while ((*cur != 0) && (!IS_SPACE(cur)))
cur++;
@@ -1038,7 +1078,7 @@ int virLogParseFilters(const char *filters) {
name = strndup(str, cur - str);
if (name == NULL)
goto cleanup;
- if (virLogDefineFilter(name, prio, 0) >= 0)
+ if (virLogDefineFilter(name, prio, flags) >= 0)
count++;
VIR_FREE(name);
virSkipSpaces(&cur);
@@ -1072,7 +1112,12 @@ char *virLogGetFilters(void) {
virLogLock();
for (i = 0; i < virLogNbFilters; i++) {
- virBufferAsprintf(&filterbuf, "%d:%s ", virLogFilters[i].priority,
+ const char *sep = ":";
+ if (virLogFilters[i].flags & VIR_LOG_STACK_TRACE)
+ sep = ":+";
+ virBufferAsprintf(&filterbuf, "%d%s%s ",
+ virLogFilters[i].priority,
+ sep,
virLogFilters[i].match);
}
virLogUnlock();
diff --git a/src/util/logging.h b/src/util/logging.h
index 2343de0..a6fa63e 100644
--- a/src/util/logging.h
+++ b/src/util/logging.h
@@ -79,6 +79,7 @@ typedef enum {
* @funcname: the function emitting the message
* @linenr: line where the message was emitted
* @timestamp: zero terminated string with timestamp of the message
+ * @flags: flags associated with the message
* @str: the message to log, preformatted and zero terminated
* @data: extra output logging data
*
@@ -88,7 +89,9 @@ typedef enum {
*/
typedef int (*virLogOutputFunc) (const char *category, int priority,
const char *funcname, long long linenr,
- const char *timestamp, const char *str,
+ const char *timestamp,
+ unsigned int flags,
+ const char *str,
void *data);
/**
@@ -99,6 +102,10 @@ typedef int (*virLogOutputFunc) (const char *category, int priority,
*/
typedef void (*virLogCloseFunc) (void *data);
+typedef enum {
+ VIR_LOG_STACK_TRACE = (1 << 0),
+} virLogFlags;
+
extern int virLogGetNbFilters(void);
extern int virLogGetNbOutputs(void);
extern char *virLogGetFilters(void);
diff --git a/tests/testutils.c b/tests/testutils.c
index 4e8484f..57cf84c 100644
--- a/tests/testutils.c
+++ b/tests/testutils.c
@@ -469,6 +469,7 @@ virtTestLogOutput(const char *category ATTRIBUTE_UNUSED,
const char *funcname ATTRIBUTE_UNUSED,
long long lineno ATTRIBUTE_UNUSED,
const char *timestamp,
+ unsigned int flags ATTRIBUTE_UNUSED,
const char *str,
void *data)
{
--
1.7.10.1
2
2
14 May '12
> >> Thanks, your patch looks good but needs two further small additions
> >> to the libvirt_sanlock.aug and test_libvirt_sanlock.aug files to
> >> take account of the new config parameter.
> >
> > Oops, Updated patch attached (tested with augparse)
> >
> > David
> >
> >
> > ----------------------------------------
> >
> > commit 33678a8b2d294bebf327106d586d41c9b157174f
> > Author: David Weber <wb(a)munzinger.de>
> > Date: Mon May 14 09:43:27 2012 +0200
> >
> > Add ignore param for readonly and shared disk in sanlock
>
> ACK and pushed, after fixing up whitespace nits ('make syntax-check'
> would have caught the trailing whitespace, but not the other one), and
> adding you to AUTHORS (let me know if you prefer an alternate spelling).
Thanks for the push. Sorry for all the problems. I'll do it better next
time ;)
>
> Is it sanlock, or libvirt, or a combination of both that don't yet
> support shared resource locks? I modified this as follows (and hope
> that it was good enough, since I pushed):
>
> # Enable this flag to have sanlock ignore readonly and shared disks.
> # If disabled, then this rejects attempts to share resources until
> # sanlock gains support for shared locks.
> #
> #ignore_readonly_and_shared_disks = 1
Right, it's sanlock who doesn't support it. So your text is right.
David
To: eblake(a)redhat.com
Cc: berrange(a)redhat.com
libvir-list(a)redhat.com
sanlock-devel(a)lists.fedorahosted.org
1
0
[libvirt] no check of freeMem before restoring a VM in libxl-driver, is it a bug?
by Oscar Ben 14 May '12
by Oscar Ben 14 May '12
14 May '12
in func 'libxlDomainRestoreFlags',it doesn't use 'libxlFreeMem' to check
whether there are enough memory before restoring the vm!It just restore the
vm anyway,until xenlight found no enough space in the middle of the process
Is this a bug?or It's designed this way by purpose?Thanks in advance.
2
1
[libvirt] [PATCH] libvirt-guests: Remove LISTFILE if it's empty when stopping service
by Osier Yang 14 May '12
by Osier Yang 14 May '12
14 May '12
$LISTFILE is created even no domain is running, and the empty
$LISTFILE could cause improper service status.
stoped ,with saved guests
Which is not right, as there is no domain was saved.
---
tools/libvirt-guests.init.sh | 42 +++++++++++++++++++++++-------------------
1 files changed, 23 insertions(+), 19 deletions(-)
diff --git a/tools/libvirt-guests.init.sh b/tools/libvirt-guests.init.sh
index aafb4d4..c0d8a7e 100644
--- a/tools/libvirt-guests.init.sh
+++ b/tools/libvirt-guests.init.sh
@@ -461,26 +461,30 @@ stop() {
done
set +f
- while read uri list; do
- if "$suspending"; then
- eval_gettext "Suspending guests on \$uri URI..."; echo
- else
- eval_gettext "Shutting down guests on \$uri URI..."; echo
- fi
+ if [ -s $LISTFILE ]; then
+ while read uri list; do
+ if "$suspending"; then
+ eval_gettext "Suspending guests on \$uri URI..."; echo
+ else
+ eval_gettext "Shutting down guests on \$uri URI..."; echo
+ fi
- if [ "$PARALLEL_SHUTDOWN" -gt 1 ] &&
- ! "$suspending"; then
- shutdown_guests_parallel "$uri" "$list"
- else
- for guest in $list; do
- if "$suspending"; then
- suspend_guest "$uri" "$guest"
- else
- shutdown_guest "$uri" "$guest"
- fi
- done
- fi
- done <"$LISTFILE"
+ if [ "$PARALLEL_SHUTDOWN" -gt 1 ] &&
+ ! "$suspending"; then
+ shutdown_guests_parallel "$uri" "$list"
+ else
+ for guest in $list; do
+ if "$suspending"; then
+ suspend_guest "$uri" "$guest"
+ else
+ shutdown_guest "$uri" "$guest"
+ fi
+ done
+ fi
+ done <"$LISTFILE"
+ else
+ rm -f $LISTFILE
+ fi
rm -f "$VAR_SUBSYS_LIBVIRT_GUESTS"
}
--
1.7.7.3
2
2
This builds on Osier's patch v1 here:
https://www.redhat.com/archives/libvir-list/2012-May/msg00663.html
to add some tests as recommended by Dan Berrange.
Patches 1-3 are new, and patch 4 is Osier's patch plus a change
to the testsuite to show what really changed. According to sysfs
of the AMD machine that he and I were playing with, there were 8
NUMA nodes of 6 CPUs each in a staggered grouping; for example,
/sys/devices/system/node/node0/cpulist shows 0,4,8,12,16,20.
I'd have to think a lot more about whether we are representing
things correctly with the hack of going by cpuinfo's claim of
12 cores (2 cores per socket, with 6 sockets). For example,
is node/has_cpu any better than node/possible, or any better
than a readdir() over node/ looking for all node[0-9]*
subdirectories? At any rate, having tests will help us feel
better about any v3 tweaks to this series.
Please feel free to contribute more tests for machines with
different NUMA configurations that you have access to.
Eric Blake (3):
nodeinfo: drop static variable
nodeinfo: avoid probing host filesystem during test
nodeinfo: add some more tests
Osier Yang (1):
nodeinfo: Get the correct CPU number on AMD Magny Cours platform
src/nodeinfo.c | 181 ++-
.../linux-nodeinfo-sysfs-test-2-cpu-x86-output.txt | 1 +
.../linux-nodeinfo-sysfs-test-2-x86.cpuinfo | 52 +
.../cpu/cpu0/topology/core_id | 1 +
.../cpu/cpu0/topology/core_siblings | 1 +
.../cpu/cpu0/topology/core_siblings_list | 1 +
.../cpu/cpu0/topology/physical_package_id | 1 +
.../cpu/cpu0/topology/thread_siblings | 1 +
.../cpu/cpu0/topology/thread_siblings_list | 1 +
.../linux-nodeinfo-sysfs-test-2/cpu/cpu1/online | 1 +
.../cpu/cpu1/topology/core_id | 1 +
.../cpu/cpu1/topology/core_siblings | 1 +
.../cpu/cpu1/topology/core_siblings_list | 1 +
.../cpu/cpu1/topology/physical_package_id | 1 +
.../cpu/cpu1/topology/thread_siblings | 1 +
.../cpu/cpu1/topology/thread_siblings_list | 1 +
.../linux-nodeinfo-sysfs-test-2/node/node0/meminfo | 29 +
.../linux-nodeinfo-sysfs-test-2/node/possible | 1 +
.../linux-nodeinfo-sysfs-test-3-cpu-x86-output.txt | 1 +
.../linux-nodeinfo-sysfs-test-3-x86.cpuinfo | 1248 ++++++++++++++++++++
.../cpu/cpu0/topology/core_id | 1 +
.../cpu/cpu0/topology/physical_package_id | 1 +
.../cpu/cpu0/topology/thread_siblings | 1 +
.../linux-nodeinfo-sysfs-test-3/cpu/cpu1/online | 1 +
.../cpu/cpu1/topology/core_id | 1 +
.../cpu/cpu1/topology/physical_package_id | 1 +
.../cpu/cpu1/topology/thread_siblings | 1 +
.../linux-nodeinfo-sysfs-test-3/cpu/cpu10/online | 1 +
.../cpu/cpu10/topology/core_id | 1 +
.../cpu/cpu10/topology/physical_package_id | 1 +
.../cpu/cpu10/topology/thread_siblings | 1 +
.../linux-nodeinfo-sysfs-test-3/cpu/cpu11/online | 1 +
.../cpu/cpu11/topology/core_id | 1 +
.../cpu/cpu11/topology/physical_package_id | 1 +
.../cpu/cpu11/topology/thread_siblings | 1 +
.../linux-nodeinfo-sysfs-test-3/cpu/cpu12/online | 1 +
.../cpu/cpu12/topology/core_id | 1 +
.../cpu/cpu12/topology/physical_package_id | 1 +
.../cpu/cpu12/topology/thread_siblings | 1 +
.../linux-nodeinfo-sysfs-test-3/cpu/cpu13/online | 1 +
.../cpu/cpu13/topology/core_id | 1 +
.../cpu/cpu13/topology/physical_package_id | 1 +
.../cpu/cpu13/topology/thread_siblings | 1 +
.../linux-nodeinfo-sysfs-test-3/cpu/cpu14/online | 1 +
.../cpu/cpu14/topology/core_id | 1 +
.../cpu/cpu14/topology/physical_package_id | 1 +
.../cpu/cpu14/topology/thread_siblings | 1 +
.../linux-nodeinfo-sysfs-test-3/cpu/cpu15/online | 1 +
.../cpu/cpu15/topology/core_id | 1 +
.../cpu/cpu15/topology/physical_package_id | 1 +
.../cpu/cpu15/topology/thread_siblings | 1 +
.../linux-nodeinfo-sysfs-test-3/cpu/cpu16/online | 1 +
.../cpu/cpu16/topology/core_id | 1 +
.../cpu/cpu16/topology/physical_package_id | 1 +
.../cpu/cpu16/topology/thread_siblings | 1 +
.../linux-nodeinfo-sysfs-test-3/cpu/cpu17/online | 1 +
.../cpu/cpu17/topology/core_id | 1 +
.../cpu/cpu17/topology/physical_package_id | 1 +
.../cpu/cpu17/topology/thread_siblings | 1 +
.../linux-nodeinfo-sysfs-test-3/cpu/cpu18/online | 1 +
.../cpu/cpu18/topology/core_id | 1 +
.../cpu/cpu18/topology/physical_package_id | 1 +
.../cpu/cpu18/topology/thread_siblings | 1 +
.../linux-nodeinfo-sysfs-test-3/cpu/cpu19/online | 1 +
.../cpu/cpu19/topology/core_id | 1 +
.../cpu/cpu19/topology/physical_package_id | 1 +
.../cpu/cpu19/topology/thread_siblings | 1 +
.../linux-nodeinfo-sysfs-test-3/cpu/cpu2/online | 1 +
.../cpu/cpu2/topology/core_id | 1 +
.../cpu/cpu2/topology/physical_package_id | 1 +
.../cpu/cpu2/topology/thread_siblings | 1 +
.../linux-nodeinfo-sysfs-test-3/cpu/cpu20/online | 1 +
.../cpu/cpu20/topology/core_id | 1 +
.../cpu/cpu20/topology/physical_package_id | 1 +
.../cpu/cpu20/topology/thread_siblings | 1 +
.../linux-nodeinfo-sysfs-test-3/cpu/cpu21/online | 1 +
.../cpu/cpu21/topology/core_id | 1 +
.../cpu/cpu21/topology/physical_package_id | 1 +
.../cpu/cpu21/topology/thread_siblings | 1 +
.../linux-nodeinfo-sysfs-test-3/cpu/cpu22/online | 1 +
.../cpu/cpu22/topology/core_id | 1 +
.../cpu/cpu22/topology/physical_package_id | 1 +
.../cpu/cpu22/topology/thread_siblings | 1 +
.../linux-nodeinfo-sysfs-test-3/cpu/cpu23/online | 1 +
.../cpu/cpu23/topology/core_id | 1 +
.../cpu/cpu23/topology/physical_package_id | 1 +
.../cpu/cpu23/topology/thread_siblings | 1 +
.../linux-nodeinfo-sysfs-test-3/cpu/cpu24/online | 1 +
.../cpu/cpu24/topology/core_id | 1 +
.../cpu/cpu24/topology/physical_package_id | 1 +
.../cpu/cpu24/topology/thread_siblings | 1 +
.../linux-nodeinfo-sysfs-test-3/cpu/cpu25/online | 1 +
.../cpu/cpu25/topology/core_id | 1 +
.../cpu/cpu25/topology/physical_package_id | 1 +
.../cpu/cpu25/topology/thread_siblings | 1 +
.../linux-nodeinfo-sysfs-test-3/cpu/cpu26/online | 1 +
.../cpu/cpu26/topology/core_id | 1 +
.../cpu/cpu26/topology/physical_package_id | 1 +
.../cpu/cpu26/topology/thread_siblings | 1 +
.../linux-nodeinfo-sysfs-test-3/cpu/cpu27/online | 1 +
.../cpu/cpu27/topology/core_id | 1 +
.../cpu/cpu27/topology/physical_package_id | 1 +
.../cpu/cpu27/topology/thread_siblings | 1 +
.../linux-nodeinfo-sysfs-test-3/cpu/cpu28/online | 1 +
.../cpu/cpu28/topology/core_id | 1 +
.../cpu/cpu28/topology/physical_package_id | 1 +
.../cpu/cpu28/topology/thread_siblings | 1 +
.../linux-nodeinfo-sysfs-test-3/cpu/cpu29/online | 1 +
.../cpu/cpu29/topology/core_id | 1 +
.../cpu/cpu29/topology/physical_package_id | 1 +
.../cpu/cpu29/topology/thread_siblings | 1 +
.../linux-nodeinfo-sysfs-test-3/cpu/cpu3/online | 1 +
.../cpu/cpu3/topology/core_id | 1 +
.../cpu/cpu3/topology/physical_package_id | 1 +
.../cpu/cpu3/topology/thread_siblings | 1 +
.../linux-nodeinfo-sysfs-test-3/cpu/cpu30/online | 1 +
.../cpu/cpu30/topology/core_id | 1 +
.../cpu/cpu30/topology/physical_package_id | 1 +
.../cpu/cpu30/topology/thread_siblings | 1 +
.../linux-nodeinfo-sysfs-test-3/cpu/cpu31/online | 1 +
.../cpu/cpu31/topology/core_id | 1 +
.../cpu/cpu31/topology/physical_package_id | 1 +
.../cpu/cpu31/topology/thread_siblings | 1 +
.../linux-nodeinfo-sysfs-test-3/cpu/cpu32/online | 1 +
.../cpu/cpu32/topology/core_id | 1 +
.../cpu/cpu32/topology/physical_package_id | 1 +
.../cpu/cpu32/topology/thread_siblings | 1 +
.../linux-nodeinfo-sysfs-test-3/cpu/cpu33/online | 1 +
.../cpu/cpu33/topology/core_id | 1 +
.../cpu/cpu33/topology/physical_package_id | 1 +
.../cpu/cpu33/topology/thread_siblings | 1 +
.../linux-nodeinfo-sysfs-test-3/cpu/cpu34/online | 1 +
.../cpu/cpu34/topology/core_id | 1 +
.../cpu/cpu34/topology/physical_package_id | 1 +
.../cpu/cpu34/topology/thread_siblings | 1 +
.../linux-nodeinfo-sysfs-test-3/cpu/cpu35/online | 1 +
.../cpu/cpu35/topology/core_id | 1 +
.../cpu/cpu35/topology/physical_package_id | 1 +
.../cpu/cpu35/topology/thread_siblings | 1 +
.../linux-nodeinfo-sysfs-test-3/cpu/cpu36/online | 1 +
.../cpu/cpu36/topology/core_id | 1 +
.../cpu/cpu36/topology/physical_package_id | 1 +
.../cpu/cpu36/topology/thread_siblings | 1 +
.../linux-nodeinfo-sysfs-test-3/cpu/cpu37/online | 1 +
.../cpu/cpu37/topology/core_id | 1 +
.../cpu/cpu37/topology/physical_package_id | 1 +
.../cpu/cpu37/topology/thread_siblings | 1 +
.../linux-nodeinfo-sysfs-test-3/cpu/cpu38/online | 1 +
.../cpu/cpu38/topology/core_id | 1 +
.../cpu/cpu38/topology/physical_package_id | 1 +
.../cpu/cpu38/topology/thread_siblings | 1 +
.../linux-nodeinfo-sysfs-test-3/cpu/cpu39/online | 1 +
.../cpu/cpu39/topology/core_id | 1 +
.../cpu/cpu39/topology/physical_package_id | 1 +
.../cpu/cpu39/topology/thread_siblings | 1 +
.../linux-nodeinfo-sysfs-test-3/cpu/cpu4/online | 1 +
.../cpu/cpu4/topology/core_id | 1 +
.../cpu/cpu4/topology/physical_package_id | 1 +
.../cpu/cpu4/topology/thread_siblings | 1 +
.../linux-nodeinfo-sysfs-test-3/cpu/cpu40/online | 1 +
.../cpu/cpu40/topology/core_id | 1 +
.../cpu/cpu40/topology/physical_package_id | 1 +
.../cpu/cpu40/topology/thread_siblings | 1 +
.../linux-nodeinfo-sysfs-test-3/cpu/cpu41/online | 1 +
.../cpu/cpu41/topology/core_id | 1 +
.../cpu/cpu41/topology/physical_package_id | 1 +
.../cpu/cpu41/topology/thread_siblings | 1 +
.../linux-nodeinfo-sysfs-test-3/cpu/cpu42/online | 1 +
.../cpu/cpu42/topology/core_id | 1 +
.../cpu/cpu42/topology/physical_package_id | 1 +
.../cpu/cpu42/topology/thread_siblings | 1 +
.../linux-nodeinfo-sysfs-test-3/cpu/cpu43/online | 1 +
.../cpu/cpu43/topology/core_id | 1 +
.../cpu/cpu43/topology/physical_package_id | 1 +
.../cpu/cpu43/topology/thread_siblings | 1 +
.../linux-nodeinfo-sysfs-test-3/cpu/cpu44/online | 1 +
.../cpu/cpu44/topology/core_id | 1 +
.../cpu/cpu44/topology/physical_package_id | 1 +
.../cpu/cpu44/topology/thread_siblings | 1 +
.../linux-nodeinfo-sysfs-test-3/cpu/cpu45/online | 1 +
.../cpu/cpu45/topology/core_id | 1 +
.../cpu/cpu45/topology/physical_package_id | 1 +
.../cpu/cpu45/topology/thread_siblings | 1 +
.../linux-nodeinfo-sysfs-test-3/cpu/cpu46/online | 1 +
.../cpu/cpu46/topology/core_id | 1 +
.../cpu/cpu46/topology/physical_package_id | 1 +
.../cpu/cpu46/topology/thread_siblings | 1 +
.../linux-nodeinfo-sysfs-test-3/cpu/cpu47/online | 1 +
.../cpu/cpu47/topology/core_id | 1 +
.../cpu/cpu47/topology/physical_package_id | 1 +
.../cpu/cpu47/topology/thread_siblings | 1 +
.../linux-nodeinfo-sysfs-test-3/cpu/cpu5/online | 1 +
.../cpu/cpu5/topology/core_id | 1 +
.../cpu/cpu5/topology/physical_package_id | 1 +
.../cpu/cpu5/topology/thread_siblings | 1 +
.../linux-nodeinfo-sysfs-test-3/cpu/cpu6/online | 1 +
.../cpu/cpu6/topology/core_id | 1 +
.../cpu/cpu6/topology/physical_package_id | 1 +
.../cpu/cpu6/topology/thread_siblings | 1 +
.../linux-nodeinfo-sysfs-test-3/cpu/cpu7/online | 1 +
.../cpu/cpu7/topology/core_id | 1 +
.../cpu/cpu7/topology/physical_package_id | 1 +
.../cpu/cpu7/topology/thread_siblings | 1 +
.../linux-nodeinfo-sysfs-test-3/cpu/cpu8/online | 1 +
.../cpu/cpu8/topology/core_id | 1 +
.../cpu/cpu8/topology/physical_package_id | 1 +
.../cpu/cpu8/topology/thread_siblings | 1 +
.../linux-nodeinfo-sysfs-test-3/cpu/cpu9/online | 1 +
.../cpu/cpu9/topology/core_id | 1 +
.../cpu/cpu9/topology/physical_package_id | 1 +
.../cpu/cpu9/topology/thread_siblings | 1 +
.../linux-nodeinfo-sysfs-test-3/node/node0/meminfo | 29 +
.../linux-nodeinfo-sysfs-test-3/node/node1/meminfo | 29 +
.../linux-nodeinfo-sysfs-test-3/node/node2/meminfo | 29 +
.../linux-nodeinfo-sysfs-test-3/node/node3/meminfo | 29 +
.../linux-nodeinfo-sysfs-test-3/node/node4/meminfo | 29 +
.../linux-nodeinfo-sysfs-test-3/node/node5/meminfo | 29 +
.../linux-nodeinfo-sysfs-test-3/node/node6/meminfo | 29 +
.../linux-nodeinfo-sysfs-test-3/node/node7/meminfo | 29 +
.../linux-nodeinfo-sysfs-test-3/node/possible | 1 +
tests/nodeinfotest.c | 50 +-
221 files changed, 1906 insertions(+), 94 deletions(-)
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-2-cpu-x86-output.txt
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-2-x86.cpuinfo
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-2/cpu/cpu0/topology/core_id
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-2/cpu/cpu0/topology/core_siblings
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-2/cpu/cpu0/topology/core_siblings_list
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-2/cpu/cpu0/topology/physical_package_id
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-2/cpu/cpu0/topology/thread_siblings
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-2/cpu/cpu0/topology/thread_siblings_list
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-2/cpu/cpu1/online
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-2/cpu/cpu1/topology/core_id
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-2/cpu/cpu1/topology/core_siblings
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-2/cpu/cpu1/topology/core_siblings_list
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-2/cpu/cpu1/topology/physical_package_id
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-2/cpu/cpu1/topology/thread_siblings
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-2/cpu/cpu1/topology/thread_siblings_list
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-2/node/node0/meminfo
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-2/node/possible
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3-cpu-x86-output.txt
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3-x86.cpuinfo
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/cpu/cpu0/topology/core_id
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/cpu/cpu0/topology/physical_package_id
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/cpu/cpu0/topology/thread_siblings
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/cpu/cpu1/online
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/cpu/cpu1/topology/core_id
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/cpu/cpu1/topology/physical_package_id
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/cpu/cpu1/topology/thread_siblings
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/cpu/cpu10/online
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/cpu/cpu10/topology/core_id
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/cpu/cpu10/topology/physical_package_id
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/cpu/cpu10/topology/thread_siblings
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/cpu/cpu11/online
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/cpu/cpu11/topology/core_id
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/cpu/cpu11/topology/physical_package_id
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/cpu/cpu11/topology/thread_siblings
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/cpu/cpu12/online
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/cpu/cpu12/topology/core_id
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/cpu/cpu12/topology/physical_package_id
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/cpu/cpu12/topology/thread_siblings
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/cpu/cpu13/online
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/cpu/cpu13/topology/core_id
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/cpu/cpu13/topology/physical_package_id
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/cpu/cpu13/topology/thread_siblings
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/cpu/cpu14/online
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/cpu/cpu14/topology/core_id
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/cpu/cpu14/topology/physical_package_id
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/cpu/cpu14/topology/thread_siblings
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/cpu/cpu15/online
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/cpu/cpu15/topology/core_id
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/cpu/cpu15/topology/physical_package_id
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/cpu/cpu15/topology/thread_siblings
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/cpu/cpu16/online
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/cpu/cpu16/topology/core_id
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/cpu/cpu16/topology/physical_package_id
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/cpu/cpu16/topology/thread_siblings
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/cpu/cpu17/online
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/cpu/cpu17/topology/core_id
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/cpu/cpu17/topology/physical_package_id
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/cpu/cpu17/topology/thread_siblings
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/cpu/cpu18/online
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/cpu/cpu18/topology/core_id
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/cpu/cpu18/topology/physical_package_id
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/cpu/cpu18/topology/thread_siblings
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/cpu/cpu19/online
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/cpu/cpu19/topology/core_id
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/cpu/cpu19/topology/physical_package_id
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/cpu/cpu19/topology/thread_siblings
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/cpu/cpu2/online
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/cpu/cpu2/topology/core_id
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/cpu/cpu2/topology/physical_package_id
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/cpu/cpu2/topology/thread_siblings
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/cpu/cpu20/online
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/cpu/cpu20/topology/core_id
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/cpu/cpu20/topology/physical_package_id
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/cpu/cpu20/topology/thread_siblings
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/cpu/cpu21/online
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/cpu/cpu21/topology/core_id
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/cpu/cpu21/topology/physical_package_id
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/cpu/cpu21/topology/thread_siblings
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/cpu/cpu22/online
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/cpu/cpu22/topology/core_id
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/cpu/cpu22/topology/physical_package_id
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/cpu/cpu22/topology/thread_siblings
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/cpu/cpu23/online
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/cpu/cpu23/topology/core_id
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/cpu/cpu23/topology/physical_package_id
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/cpu/cpu23/topology/thread_siblings
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/cpu/cpu24/online
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/cpu/cpu24/topology/core_id
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/cpu/cpu24/topology/physical_package_id
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/cpu/cpu24/topology/thread_siblings
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/cpu/cpu25/online
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/cpu/cpu25/topology/core_id
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/cpu/cpu25/topology/physical_package_id
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/cpu/cpu25/topology/thread_siblings
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/cpu/cpu26/online
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/cpu/cpu26/topology/core_id
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/cpu/cpu26/topology/physical_package_id
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/cpu/cpu26/topology/thread_siblings
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/cpu/cpu27/online
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/cpu/cpu27/topology/core_id
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/cpu/cpu27/topology/physical_package_id
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/cpu/cpu27/topology/thread_siblings
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/cpu/cpu28/online
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/cpu/cpu28/topology/core_id
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/cpu/cpu28/topology/physical_package_id
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/cpu/cpu28/topology/thread_siblings
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/cpu/cpu29/online
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/cpu/cpu29/topology/core_id
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/cpu/cpu29/topology/physical_package_id
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/cpu/cpu29/topology/thread_siblings
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/cpu/cpu3/online
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/cpu/cpu3/topology/core_id
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/cpu/cpu3/topology/physical_package_id
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/cpu/cpu3/topology/thread_siblings
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/cpu/cpu30/online
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/cpu/cpu30/topology/core_id
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/cpu/cpu30/topology/physical_package_id
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/cpu/cpu30/topology/thread_siblings
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/cpu/cpu31/online
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/cpu/cpu31/topology/core_id
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/cpu/cpu31/topology/physical_package_id
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/cpu/cpu31/topology/thread_siblings
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/cpu/cpu32/online
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/cpu/cpu32/topology/core_id
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/cpu/cpu32/topology/physical_package_id
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/cpu/cpu32/topology/thread_siblings
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/cpu/cpu33/online
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/cpu/cpu33/topology/core_id
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/cpu/cpu33/topology/physical_package_id
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/cpu/cpu33/topology/thread_siblings
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/cpu/cpu34/online
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/cpu/cpu34/topology/core_id
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/cpu/cpu34/topology/physical_package_id
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/cpu/cpu34/topology/thread_siblings
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/cpu/cpu35/online
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/cpu/cpu35/topology/core_id
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/cpu/cpu35/topology/physical_package_id
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/cpu/cpu35/topology/thread_siblings
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/cpu/cpu36/online
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/cpu/cpu36/topology/core_id
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/cpu/cpu36/topology/physical_package_id
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/cpu/cpu36/topology/thread_siblings
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/cpu/cpu37/online
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/cpu/cpu37/topology/core_id
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/cpu/cpu37/topology/physical_package_id
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/cpu/cpu37/topology/thread_siblings
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/cpu/cpu38/online
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/cpu/cpu38/topology/core_id
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/cpu/cpu38/topology/physical_package_id
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/cpu/cpu38/topology/thread_siblings
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/cpu/cpu39/online
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/cpu/cpu39/topology/core_id
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/cpu/cpu39/topology/physical_package_id
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/cpu/cpu39/topology/thread_siblings
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/cpu/cpu4/online
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/cpu/cpu4/topology/core_id
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/cpu/cpu4/topology/physical_package_id
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/cpu/cpu4/topology/thread_siblings
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/cpu/cpu40/online
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/cpu/cpu40/topology/core_id
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/cpu/cpu40/topology/physical_package_id
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/cpu/cpu40/topology/thread_siblings
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/cpu/cpu41/online
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/cpu/cpu41/topology/core_id
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/cpu/cpu41/topology/physical_package_id
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/cpu/cpu41/topology/thread_siblings
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/cpu/cpu42/online
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/cpu/cpu42/topology/core_id
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/cpu/cpu42/topology/physical_package_id
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/cpu/cpu42/topology/thread_siblings
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/cpu/cpu43/online
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/cpu/cpu43/topology/core_id
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/cpu/cpu43/topology/physical_package_id
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/cpu/cpu43/topology/thread_siblings
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/cpu/cpu44/online
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/cpu/cpu44/topology/core_id
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/cpu/cpu44/topology/physical_package_id
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/cpu/cpu44/topology/thread_siblings
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/cpu/cpu45/online
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/cpu/cpu45/topology/core_id
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/cpu/cpu45/topology/physical_package_id
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/cpu/cpu45/topology/thread_siblings
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/cpu/cpu46/online
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/cpu/cpu46/topology/core_id
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/cpu/cpu46/topology/physical_package_id
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/cpu/cpu46/topology/thread_siblings
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/cpu/cpu47/online
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/cpu/cpu47/topology/core_id
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/cpu/cpu47/topology/physical_package_id
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/cpu/cpu47/topology/thread_siblings
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/cpu/cpu5/online
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/cpu/cpu5/topology/core_id
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/cpu/cpu5/topology/physical_package_id
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/cpu/cpu5/topology/thread_siblings
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/cpu/cpu6/online
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/cpu/cpu6/topology/core_id
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/cpu/cpu6/topology/physical_package_id
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/cpu/cpu6/topology/thread_siblings
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/cpu/cpu7/online
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/cpu/cpu7/topology/core_id
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/cpu/cpu7/topology/physical_package_id
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/cpu/cpu7/topology/thread_siblings
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/cpu/cpu8/online
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/cpu/cpu8/topology/core_id
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/cpu/cpu8/topology/physical_package_id
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/cpu/cpu8/topology/thread_siblings
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/cpu/cpu9/online
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/cpu/cpu9/topology/core_id
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/cpu/cpu9/topology/physical_package_id
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/cpu/cpu9/topology/thread_siblings
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/node/node0/meminfo
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/node/node1/meminfo
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/node/node2/meminfo
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/node/node3/meminfo
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/node/node4/meminfo
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/node/node5/meminfo
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/node/node6/meminfo
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/node/node7/meminfo
create mode 100644 tests/nodeinfodata/linux-nodeinfo-sysfs-test-3/node/possible
--
1.7.7.6
3
15
[libvirt] [PATCH 1/2] qemu: Set memory policy using cgroup if placement is auto
by Osier Yang 14 May '12
by Osier Yang 14 May '12
14 May '12
Like for 'static' placement, when the memory policy mode is
'strict', set the memory policy by writing the advisory nodeset
returned from numad to cgroup file cpuset.mems,
---
src/qemu/qemu_cgroup.c | 15 +++++++++--
src/qemu/qemu_cgroup.h | 3 +-
src/qemu/qemu_process.c | 62 +++++++++++++++++++++++++----------------------
3 files changed, 47 insertions(+), 33 deletions(-)
diff --git a/src/qemu/qemu_cgroup.c b/src/qemu/qemu_cgroup.c
index a07b6cd..f8f375f 100644
--- a/src/qemu/qemu_cgroup.c
+++ b/src/qemu/qemu_cgroup.c
@@ -194,7 +194,8 @@ int qemuSetupHostUsbDeviceCgroup(usbDevice *dev ATTRIBUTE_UNUSED,
}
int qemuSetupCgroup(struct qemud_driver *driver,
- virDomainObjPtr vm)
+ virDomainObjPtr vm,
+ char *nodemask)
{
virCgroupPtr cgroup = NULL;
int rc;
@@ -391,10 +392,18 @@ int qemuSetupCgroup(struct qemud_driver *driver,
}
}
- if (vm->def->numatune.memory.nodemask &&
+ if ((vm->def->numatune.memory.nodemask ||
+ (vm->def->numatune.memory.placement_mode ==
+ VIR_DOMAIN_NUMATUNE_MEM_PLACEMENT_MODE_AUTO)) &&
vm->def->numatune.memory.mode == VIR_DOMAIN_NUMATUNE_MEM_STRICT &&
qemuCgroupControllerActive(driver, VIR_CGROUP_CONTROLLER_CPUSET)) {
- char *mask = virDomainCpuSetFormat(vm->def->numatune.memory.nodemask, VIR_DOMAIN_CPUMASK_LEN);
+ char *mask = NULL;
+ if (vm->def->numatune.memory.placement_mode ==
+ VIR_DOMAIN_NUMATUNE_MEM_PLACEMENT_MODE_AUTO)
+ mask = virDomainCpuSetFormat(nodemask, VIR_DOMAIN_CPUMASK_LEN);
+ else
+ mask = virDomainCpuSetFormat(vm->def->numatune.memory.nodemask,
+ VIR_DOMAIN_CPUMASK_LEN);
if (!mask) {
qemuReportError(VIR_ERR_INTERNAL_ERROR,
_("failed to convert memory nodemask"));
diff --git a/src/qemu/qemu_cgroup.h b/src/qemu/qemu_cgroup.h
index 17164d9..c1023b3 100644
--- a/src/qemu/qemu_cgroup.h
+++ b/src/qemu/qemu_cgroup.h
@@ -48,7 +48,8 @@ int qemuSetupHostUsbDeviceCgroup(usbDevice *dev,
const char *path,
void *opaque);
int qemuSetupCgroup(struct qemud_driver *driver,
- virDomainObjPtr vm);
+ virDomainObjPtr vm,
+ char *nodemask);
int qemuSetupCgroupVcpuBW(virCgroupPtr cgroup,
unsigned long long period,
long long quota);
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index d226067..19bb22a 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -2544,6 +2544,7 @@ struct qemuProcessHookData {
virConnectPtr conn;
virDomainObjPtr vm;
struct qemud_driver *driver;
+ char *nodemask;
};
static int qemuProcessHook(void *data)
@@ -2551,8 +2552,6 @@ static int qemuProcessHook(void *data)
struct qemuProcessHookData *h = data;
int ret = -1;
int fd;
- char *nodeset = NULL;
- char *nodemask = NULL;
/* Some later calls want pid present */
h->vm->pid = getpid();
@@ -2582,37 +2581,16 @@ static int qemuProcessHook(void *data)
/* This must take place before exec(), so that all QEMU
* memory allocation is on the correct NUMA node
*/
- VIR_DEBUG("Moving procss to cgroup");
+ VIR_DEBUG("Moving process to cgroup");
if (qemuAddToCgroup(h->driver, h->vm->def) < 0)
goto cleanup;
- if ((h->vm->def->placement_mode ==
- VIR_DOMAIN_CPU_PLACEMENT_MODE_AUTO) ||
- (h->vm->def->numatune.memory.placement_mode ==
- VIR_DOMAIN_NUMATUNE_MEM_PLACEMENT_MODE_AUTO)) {
- nodeset = qemuGetNumadAdvice(h->vm->def);
- if (!nodeset)
- goto cleanup;
-
- VIR_DEBUG("Nodeset returned from numad: %s", nodeset);
-
- if (VIR_ALLOC_N(nodemask, VIR_DOMAIN_CPUMASK_LEN) < 0) {
- virReportOOMError();
- goto cleanup;
- }
-
- if (virDomainCpuSetParse(nodeset, 0, nodemask,
- VIR_DOMAIN_CPUMASK_LEN) < 0)
- goto cleanup;
- }
-
/* This must be done after cgroup placement to avoid resetting CPU
* affinity */
- VIR_DEBUG("Setup CPU affinity");
- if (qemuProcessInitCpuAffinity(h->driver, h->vm, nodemask) < 0)
+ if (qemuProcessInitCpuAffinity(h->driver, h->vm, h->nodemask) < 0)
goto cleanup;
- if (qemuProcessInitNumaMemoryPolicy(h->vm, nodemask) < 0)
+ if (qemuProcessInitNumaMemoryPolicy(h->vm, h->nodemask) < 0)
goto cleanup;
VIR_DEBUG("Setting up security labelling");
@@ -2623,8 +2601,6 @@ static int qemuProcessHook(void *data)
cleanup:
VIR_DEBUG("Hook complete ret=%d", ret);
- VIR_FREE(nodeset);
- VIR_FREE(nodemask);
return ret;
}
@@ -3300,6 +3276,8 @@ int qemuProcessStart(virConnectPtr conn,
struct qemuProcessHookData hookData;
unsigned long cur_balloon;
int i;
+ char *nodeset = NULL;
+ char *nodemask = NULL;
/* Okay, these are just internal flags,
* but doesn't hurt to check */
@@ -3455,8 +3433,32 @@ int qemuProcessStart(virConnectPtr conn,
flags & VIR_QEMU_PROCESS_START_COLD) < 0)
goto cleanup;
+ /* Get the advisory nodeset from numad if 'placement' of
+ * either <vcpu> or <numatune> is 'auto'.
+ */
+ if ((vm->def->placement_mode ==
+ VIR_DOMAIN_CPU_PLACEMENT_MODE_AUTO) ||
+ (vm->def->numatune.memory.placement_mode ==
+ VIR_DOMAIN_NUMATUNE_MEM_PLACEMENT_MODE_AUTO)) {
+ nodeset = qemuGetNumadAdvice(vm->def);
+ if (!nodeset)
+ goto cleanup;
+
+ VIR_DEBUG("Nodeset returned from numad: %s", nodeset);
+
+ if (VIR_ALLOC_N(nodemask, VIR_DOMAIN_CPUMASK_LEN) < 0) {
+ virReportOOMError();
+ goto cleanup;
+ }
+
+ if (virDomainCpuSetParse(nodeset, 0, nodemask,
+ VIR_DOMAIN_CPUMASK_LEN) < 0)
+ goto cleanup;
+ }
+ hookData.nodemask = nodemask;
+
VIR_DEBUG("Setting up domain cgroup (if required)");
- if (qemuSetupCgroup(driver, vm) < 0)
+ if (qemuSetupCgroup(driver, vm, nodemask) < 0)
goto cleanup;
if (VIR_ALLOC(priv->monConfig) < 0) {
@@ -3761,6 +3763,8 @@ cleanup:
/* We jump here if we failed to start the VM for any reason, or
* if we failed to initialize the now running VM. kill it off and
* pretend we never started it */
+ VIR_FREE(nodeset);
+ VIR_FREE(nodemask);
virCommandFree(cmd);
VIR_FORCE_CLOSE(logfile);
qemuProcessStop(driver, vm, 0, VIR_DOMAIN_SHUTOFF_FAILED);
--
1.7.7.3
2
2
[libvirt] [PATCH] qemu: Use the CPU index in capabilities to map NUMA node to cpu list.
by Osier Yang 14 May '12
by Osier Yang 14 May '12
14 May '12
On some of the NUMA platforms, the CPU index in each NUMA node
grows sequentially. While on other platforms, it can be inconsecutive,
E.g.
% numactl --hardware
available: 4 nodes (0-3)
node 0 cpus: 0 4 8 12 16 20 24 28
node 0 size: 131058 MB
node 0 free: 86531 MB
node 1 cpus: 1 5 9 13 17 21 25 29
node 1 size: 131072 MB
node 1 free: 127070 MB
node 2 cpus: 2 6 10 14 18 22 26 30
node 2 size: 131072 MB
node 2 free: 127758 MB
node 3 cpus: 3 7 11 15 19 23 27 31
node 3 size: 131072 MB
node 3 free: 127226 MB
node distances:
node 0 1 2 3
0: 10 20 20 20
1: 20 10 20 20
2: 20 20 10 20
3: 20 20 20 10
This patch is to fix the problem by using the CPU index in
caps->host.numaCell[i]->cpus[i] to set the bitmask instead of
assuming the CPU index of the NUMA nodes are always sequential.
---
src/qemu/qemu_process.c | 11 ++---------
1 files changed, 2 insertions(+), 9 deletions(-)
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 19bb22a..58ba5bf 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -1825,20 +1825,13 @@ qemuProcessInitCpuAffinity(struct qemud_driver *driver,
if (vm->def->placement_mode == VIR_DOMAIN_CPU_PLACEMENT_MODE_AUTO) {
VIR_DEBUG("Set CPU affinity with advisory nodeset from numad");
/* numad returns the NUMA node list, convert it to cpumap */
- int prev_total_ncpus = 0;
for (i = 0; i < driver->caps->host.nnumaCell; i++) {
int j;
int cur_ncpus = driver->caps->host.numaCell[i]->ncpus;
if (nodemask[i]) {
- for (j = prev_total_ncpus;
- j < cur_ncpus + prev_total_ncpus &&
- j < maxcpu &&
- j < VIR_DOMAIN_CPUMASK_LEN;
- j++) {
- VIR_USE_CPU(cpumap, j);
- }
+ for (j = 0; j < cur_ncpus; j++)
+ VIR_USE_CPU(cpumap, driver->caps->host.numaCell[i]->cpus[j]);
}
- prev_total_ncpus += cur_ncpus;
}
} else {
VIR_DEBUG("Set CPU affinity with specified cpuset");
--
1.7.7.3
2
2
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
---
v3:
- use DATATYPE_IPSETNAME for the name of the ipset
- adapted documentation for 0.9.12
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 | 136 +++++++++++++++++++++++++++++-
src/conf/nwfilter_conf.h | 13 ++
src/nwfilter/nwfilter_ebiptables_driver.c | 75 +++++++++++++++-
tests/nwfilterxml2xmlin/ipset-test.xml | 24 +++++
tests/nwfilterxml2xmlout/ipset-test.xml | 24 +++++
tests/nwfilterxml2xmltest.c | 2
8 files changed, 356 insertions(+), 5 deletions(-)
Index: libvirt-acl/src/conf/nwfilter_conf.c
===================================================================
--- libvirt-acl.orig/src/conf/nwfilter_conf.c
+++ libvirt-acl/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_IPSETNAME,\
+ .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,8 @@ virNWFilterRuleDetailsParse(xmlNodePtr n
break;
case DATATYPE_STRING:
+ case DATATYPE_IPSETFLAGS:
+ case DATATYPE_IPSETNAME:
if (!validator) {
/* not supported */
rc = -1;
@@ -1964,6 +2075,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 +2141,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 +2149,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 +2173,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 +2192,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 +2205,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 +2218,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 +2231,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 +2250,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 +2265,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 +2289,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 +3254,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-acl/src/conf/nwfilter_conf.h
===================================================================
--- libvirt-acl.orig/src/conf/nwfilter_conf.h
+++ libvirt-acl/src/conf/nwfilter_conf.h
@@ -103,8 +103,10 @@ enum attrDatatype {
DATATYPE_BOOLEAN = (1 << 12),
DATATYPE_UINT32 = (1 << 13),
DATATYPE_UINT32_HEX = (1 << 14),
+ DATATYPE_IPSETNAME = (1 << 15),
+ DATATYPE_IPSETFLAGS = (1 << 16),
- DATATYPE_LAST = (1 << 15),
+ DATATYPE_LAST = (1 << 17),
};
# define NWFILTER_MAC_BGA "01:80:c2:00:00:00"
@@ -136,9 +138,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 +241,8 @@ struct _ipHdrDataDef {
nwItemDesc dataState;
nwItemDesc dataConnlimitAbove;
nwItemDesc dataComment;
+ nwItemDesc dataIPSet;
+ nwItemDesc dataIPSetFlags;
};
Index: libvirt-acl/src/nwfilter/nwfilter_ebiptables_driver.c
===================================================================
--- libvirt-acl.orig/src/nwfilter/nwfilter_ebiptables_driver.c
+++ libvirt-acl/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,44 @@ _printDataType(virNWFilterVarCombIterPtr
}
break;
+ case DATATYPE_IPSETNAME:
+ snprintf(buf, bufsize, "%s", item->u.ipset.setname);
+ 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 +403,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 +975,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 +987,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-acl/docs/schemas/nwfilter.rng
===================================================================
--- libvirt-acl.orig/docs/schemas/nwfilter.rng
+++ libvirt-acl/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-acl/tests/nwfilterxml2xmlin/ipset-test.xml
===================================================================
--- /dev/null
+++ libvirt-acl/tests/nwfilterxml2xmlin/ipset-test.xml
@@ -0,0 +1,24 @@
+<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 state='NONE' ipset='test' ipsetflags='src,dst' comment='in+NONE'/>
+ </rule>
+ <rule action='accept' direction='out'>
+ <all state='NONE' ipset='test' ipsetflags='src,dst' comment='out+NONE'/>
+ </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>
+ <rule action='accept' direction='inout'>
+ <all ipset='$IPSETNAME' ipsetflags='src,dst' comment='inout'/>
+ </rule>
+</filter>
Index: libvirt-acl/tests/nwfilterxml2xmlout/ipset-test.xml
===================================================================
--- /dev/null
+++ libvirt-acl/tests/nwfilterxml2xmlout/ipset-test.xml
@@ -0,0 +1,24 @@
+<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 state='NONE' ipset='test' ipsetflags='src,dst' comment='in+NONE'/>
+ </rule>
+ <rule action='accept' direction='out' priority='500'>
+ <all state='NONE' ipset='test' ipsetflags='src,dst' comment='out+NONE'/>
+ </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>
+ <rule action='accept' direction='inout' priority='500'>
+ <all ipset='$IPSETNAME' ipsetflags='src,dst' comment='inout'/>
+ </rule>
+</filter>
Index: libvirt-acl/tests/nwfilterxml2xmltest.c
===================================================================
--- libvirt-acl.orig/tests/nwfilterxml2xmltest.c
+++ libvirt-acl/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-acl/docs/formatnwfilter.html.in
===================================================================
--- libvirt-acl.orig/docs/formatnwfilter.html.in
+++ libvirt-acl/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.12)</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.12)</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.12)</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.12)</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.12)</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.12)</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.12)</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.12)</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.12)</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.12)</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.12)</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.12)</span></td>
+ <td>IPSETFLAGS</td>
+ <td>flags for the IPSet; requires ipset attributed</td>
+ </tr>
</table>
<p>
<br/><br/>
2
3
14 May '12
For pseries guest, the default controller model is
ibmvscsi controller, this controller only can work
on spapr-vio address.
This patch is to assign spapr-vio address type to
ibmvscsi controller and correct vscsi test case.
Signed-off-by: Li Zhang <zhlcindy(a)linux.vnet.ibm.com>
---
src/qemu/qemu_command.c | 17 +++++++++++++----
.../qemuxml2argv-disk-scsi-vscsi.args | 4 ++--
2 files changed, 15 insertions(+), 6 deletions(-)
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 117542f..0a85d19 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -779,6 +779,7 @@ qemuAssignSpaprVIOAddress(virDomainDefPtr def, virDomainDeviceInfoPtr info,
int qemuDomainAssignSpaprVIOAddresses(virDomainDefPtr def)
{
int i, rc;
+ int model;
/* Default values match QEMU. See spapr_(llan|vscsi|vty).c */
@@ -790,10 +791,18 @@ int qemuDomainAssignSpaprVIOAddresses(virDomainDefPtr def)
}
for (i = 0 ; i < def->ncontrollers; i++) {
- rc = qemuAssignSpaprVIOAddress(def, &def->controllers[i]->info,
- 0x2000ul);
- if (rc)
- return rc;
+ model = def->controllers[i]->model;
+ if (model == -1 &&
+ def->controllers[i]->type == VIR_DOMAIN_CONTROLLER_TYPE_SCSI)
+ model = qemuDefaultScsiControllerModel(def);
+ if (model == VIR_DOMAIN_CONTROLLER_MODEL_SCSI_IBMVSCSI &&
+ def->controllers[i]->type == VIR_DOMAIN_CONTROLLER_TYPE_SCSI) {
+ def->controllers[i]->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_SPAPRVIO;
+ rc = qemuAssignSpaprVIOAddress(def, &def->controllers[i]->info,
+ 0x2000ul);
+ if (rc)
+ return rc;
+ }
}
for (i = 0 ; i < def->nserials; i++) {
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-scsi-vscsi.args b/tests/qemuxml2argvdata/qemuxml2argv-disk-scsi-vscsi.args
index 4261a84..d57159f 100644
--- a/tests/qemuxml2argvdata/qemuxml2argv-disk-scsi-vscsi.args
+++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-scsi-vscsi.args
@@ -1,8 +1,8 @@
LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M \
pc -m 214 -smp 1 -nographic -nodefconfig -nodefaults -monitor \
unix:/tmp/test-monitor,server,nowait -no-acpi -boot c -device spapr-vscsi,id=scsi0,\
-bus=pci.0,addr=0x3 -drive file=/dev/HostVG/QEMUGuest1,if=none,\
+reg=0x2000 -drive file=/dev/HostVG/QEMUGuest1,if=none,\
id=drive-ide0-0-0 -device ide-drive,bus=ide.0,unit=0,drive=drive-ide0-0-0,id=ide0-0-0 \
-drive file=/tmp/scsidisk.img,if=none,id=drive-scsi0-0-3-0 \
-device scsi-disk,bus=scsi0.0,channel=0,scsi-id=3,lun=0,drive=drive-scsi0-0-3-0,id=scsi0-0-3-0 \
--usb -device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x4
+-usb -device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3
--
1.7.9.5
2
1