[libvirt] [PATCH] daemon: plug a memory leak
by Eric Blake
* daemon/libvirtd.c (qemudStartWorker, qemudStartEventLoop): Avoid
leaking pthread_attr resources.
---
daemon/libvirtd.c | 36 ++++++++++++++++++++++++++----------
1 files changed, 26 insertions(+), 10 deletions(-)
diff --git a/daemon/libvirtd.c b/daemon/libvirtd.c
index 2914f2f..14777dd 100644
--- a/daemon/libvirtd.c
+++ b/daemon/libvirtd.c
@@ -1600,15 +1600,20 @@ static void *qemudWorker(void *data)
}
}
-static int qemudStartWorker(struct qemud_server *server,
- struct qemud_worker *worker) {
+static int
+qemudStartWorker(struct qemud_server *server,
+ struct qemud_worker *worker)
+{
pthread_attr_t attr;
- pthread_attr_init(&attr);
+ int ret = -1;
+
+ if (pthread_attr_init(&attr) != 0)
+ return -1;
/* We want to join workers, so don't detach them */
/*pthread_attr_setdetachstate(&attr, 1);*/
if (worker->hasThread)
- return -1;
+ goto cleanup;
worker->server = server;
worker->hasThread = 1;
@@ -1621,10 +1626,13 @@ static int qemudStartWorker(struct qemud_server *server,
worker) != 0) {
worker->hasThread = 0;
worker->server = NULL;
- return -1;
+ goto cleanup;
}
- return 0;
+ ret = 0;
+cleanup:
+ pthread_attr_destroy(&attr);
+ return ret;
}
@@ -2414,9 +2422,14 @@ cleanup:
}
-static int qemudStartEventLoop(struct qemud_server *server) {
+static int
+qemudStartEventLoop(struct qemud_server *server)
+{
pthread_attr_t attr;
- pthread_attr_init(&attr);
+ int ret = -1;
+
+ if (pthread_attr_init(&attr) != 0)
+ return -1;
/* We want to join the eventloop, so don't detach it */
/*pthread_attr_setdetachstate(&attr, 1);*/
@@ -2424,11 +2437,14 @@ static int qemudStartEventLoop(struct qemud_server *server) {
&attr,
qemudRunLoop,
server) != 0)
- return -1;
+ goto cleanup;
server->hasEventThread = 1;
- return 0;
+ ret = 0;
+cleanup:
+ pthread_attr_destroy(&attr);
+ return ret;
}
--
1.7.3.3
14 years
[libvirt] [PATCH] util: Fix logical error in virReportSystemErrorFull
by Jiri Denemark
---
src/util/virterror.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/src/util/virterror.c b/src/util/virterror.c
index 6e49fa2..b912737 100644
--- a/src/util/virterror.c
+++ b/src/util/virterror.c
@@ -1301,7 +1301,7 @@ void virReportSystemErrorFull(int domcode,
n = vsnprintf(msgDetailBuf, sizeof(msgDetailBuf), fmt, args);
va_end(args);
- size_t len = strlen (msgDetailBuf);
+ size_t len = strlen(errnoDetail);
if (0 <= n && n + 2 + len < sizeof (msgDetailBuf)) {
char *p = msgDetailBuf + n;
stpcpy (stpcpy (p, ": "), errnoDetail);
--
1.7.3.3
14 years
[libvirt] [PATCH] util: Fix error message in __virExec
by Jiri Denemark
Remove superfluous ": %s" suffix from the error message.
---
src/util/util.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/src/util/util.c b/src/util/util.c
index 1b5bc68..e24facb 100644
--- a/src/util/util.c
+++ b/src/util/util.c
@@ -617,7 +617,7 @@ __virExec(const char *const*argv,
if (chdir("/") < 0) {
virReportSystemError(errno,
- "%s", _("cannot change to root directory: %s"));
+ "%s", _("cannot change to root directory"));
goto fork_error;
}
--
1.7.3.3
14 years
[libvirt] [PATCH] daemon: Change CWD to / before daemonizing
by Jiri Denemark
We were doing so for child processes but not for libvirtd itself.
---
daemon/libvirtd.c | 7 +++++++
1 files changed, 7 insertions(+), 0 deletions(-)
diff --git a/daemon/libvirtd.c b/daemon/libvirtd.c
index 791b3dc..58fc492 100644
--- a/daemon/libvirtd.c
+++ b/daemon/libvirtd.c
@@ -3158,6 +3158,13 @@ int main(int argc, char **argv) {
if (godaemon) {
char ebuf[1024];
+
+ if (chdir("/") < 0) {
+ VIR_ERROR(_("cannot change to root directory: %s"),
+ virStrerror(errno, ebuf, sizeof(ebuf)));
+ goto error;
+ }
+
if ((statuswrite = daemonForkIntoBackground()) < 0) {
VIR_ERROR(_("Failed to fork as daemon: %s"),
virStrerror(errno, ebuf, sizeof ebuf));
--
1.7.3.3
14 years
[libvirt] [PATCH] cpu: Unify CPUID data structures
by Jiri Denemark
So far, CPUID data were stored in two different data structures. First
of them was a structure allowing direct access for CPUID data according
to function number and the second was a plain array of struct
cpuX86cpuid. This was a silly design which resulted in converting data
from one type to the other and back again or implementing similar
functionality for both data structures.
The patch leaves only the direct access structure. This makes the code
both smaller and more maintainable since operations on different objects
can use common low-level operations.
All 57 tests for cpu subsystem still pass after this rewrite.
---
src/cpu/cpu_x86.c | 576 +++++++++++++++++++++--------------------------
src/cpu/cpu_x86_data.h | 4 +-
2 files changed, 259 insertions(+), 321 deletions(-)
diff --git a/src/cpu/cpu_x86.c b/src/cpu/cpu_x86.c
index 425a8eb..df1e431 100644
--- a/src/cpu/cpu_x86.c
+++ b/src/cpu/cpu_x86.c
@@ -37,6 +37,7 @@
#define VENDOR_STRING_LENGTH 12
+static const struct cpuX86cpuid cpuidNull = { 0, 0, 0, 0, 0 };
static const char *archs[] = { "i686", "x86_64" };
@@ -49,8 +50,7 @@ struct x86_vendor {
struct x86_feature {
char *name;
- unsigned int ncpuid;
- struct cpuX86cpuid *cpuid;
+ union cpuData *data;
struct x86_feature *next;
};
@@ -58,8 +58,7 @@ struct x86_feature {
struct x86_model {
char *name;
const struct x86_vendor *vendor;
- unsigned int ncpuid;
- struct cpuX86cpuid *cpuid;
+ union cpuData *data;
struct x86_model *next;
};
@@ -79,23 +78,28 @@ enum compare_result {
};
-static struct cpuX86cpuid *
-x86cpuidFind(struct cpuX86cpuid *cpuids,
- unsigned int ncpuids,
- uint32_t function)
-{
- unsigned int i;
+struct data_iterator {
+ union cpuData *data;
+ int pos;
+ bool extended;
+};
- for (i = 0; i < ncpuids; i++) {
- if (cpuids[i].function == function)
- return cpuids + i;
- }
- return NULL;
+#define DATA_ITERATOR_INIT(data) \
+ { data, -1, false }
+
+
+static void
+x86DataIteratorInit(struct data_iterator *iter,
+ union cpuData *data)
+{
+ struct data_iterator init = DATA_ITERATOR_INIT(data);
+
+ *iter = init;
}
-static inline int
+static int
x86cpuidMatch(const struct cpuX86cpuid *cpuid1,
const struct cpuX86cpuid *cpuid2)
{
@@ -106,7 +110,7 @@ x86cpuidMatch(const struct cpuX86cpuid *cpuid1,
}
-static inline int
+static int
x86cpuidMatchMasked(const struct cpuX86cpuid *cpuid,
const struct cpuX86cpuid *mask)
{
@@ -117,7 +121,7 @@ x86cpuidMatchMasked(const struct cpuX86cpuid *cpuid,
}
-static inline int
+static int
x86cpuidMatchAny(const struct cpuX86cpuid *cpuid,
const struct cpuX86cpuid *mask)
{
@@ -128,7 +132,7 @@ x86cpuidMatchAny(const struct cpuX86cpuid *cpuid,
}
-static inline void
+static void
x86cpuidSetBits(struct cpuX86cpuid *cpuid,
const struct cpuX86cpuid *mask)
{
@@ -139,7 +143,7 @@ x86cpuidSetBits(struct cpuX86cpuid *cpuid,
}
-static inline void
+static void
x86cpuidClearBits(struct cpuX86cpuid *cpuid,
const struct cpuX86cpuid *mask)
{
@@ -150,7 +154,7 @@ x86cpuidClearBits(struct cpuX86cpuid *cpuid,
}
-static inline void
+static void
x86cpuidAndBits(struct cpuX86cpuid *cpuid,
const struct cpuX86cpuid *mask)
{
@@ -161,6 +165,40 @@ x86cpuidAndBits(struct cpuX86cpuid *cpuid,
}
+/* skips all zero CPUID leafs */
+static struct cpuX86cpuid *
+x86DataCpuidNext(struct data_iterator *iterator)
+{
+ struct cpuX86cpuid *ret;
+ struct cpuX86Data *data;
+
+ if (!iterator->data)
+ return NULL;
+
+ data = &iterator->data->x86;
+
+ do {
+ ret = NULL;
+ iterator->pos++;
+
+ if (!iterator->extended) {
+ if (iterator->pos < data->basic_len)
+ ret = data->basic + iterator->pos;
+ else {
+ iterator->extended = true;
+ iterator->pos = 0;
+ }
+ }
+
+ if (iterator->extended && iterator->pos < data->extended_len) {
+ ret = data->extended + iterator->pos;
+ }
+ } while (ret && x86cpuidMatch(ret, &cpuidNull));
+
+ return ret;
+}
+
+
static struct cpuX86cpuid *
x86DataCpuid(const union cpuData *data,
uint32_t function)
@@ -180,7 +218,7 @@ x86DataCpuid(const union cpuData *data,
i = function - CPUX86_EXTENDED;
}
- if (i < len)
+ if (i < len && !x86cpuidMatch(cpuids + i, &cpuidNull))
return cpuids + i;
else
return NULL;
@@ -225,38 +263,86 @@ x86DataCopy(const union cpuData *data)
static int
+x86DataExpand(union cpuData *data,
+ int basic_by,
+ int extended_by)
+{
+ size_t i;
+
+ if (basic_by > 0) {
+ size_t len = data->x86.basic_len;
+ if (VIR_EXPAND_N(data->x86.basic, data->x86.basic_len, basic_by) < 0)
+ goto no_memory;
+
+ for (i = 0; i < basic_by; i++)
+ data->x86.basic[len + i].function = len + i;
+ }
+
+ if (extended_by > 0) {
+ size_t len = data->x86.extended_len;
+ if (VIR_EXPAND_N(data->x86.extended, data->x86.extended_len, extended_by) < 0)
+ goto no_memory;
+
+ for (i = 0; i < extended_by; i++)
+ data->x86.extended[len + i].function = len + i + CPUX86_EXTENDED;
+ }
+
+ return 0;
+
+no_memory:
+ virReportOOMError();
+ return -1;
+}
+
+
+static int
x86DataAddCpuid(union cpuData *data,
const struct cpuX86cpuid *cpuid)
{
+ unsigned int basic_by = 0;
+ unsigned int extended_by = 0;
struct cpuX86cpuid **cpuids;
- int *len;
unsigned int pos;
- unsigned int ext;
if (cpuid->function < CPUX86_EXTENDED) {
pos = cpuid->function;
- ext = 0;
- len = &data->x86.basic_len;
+ basic_by = pos + 1 - data->x86.basic_len;
cpuids = &data->x86.basic;
} else {
pos = cpuid->function - CPUX86_EXTENDED;
- ext = CPUX86_EXTENDED;
- len = &data->x86.extended_len;
+ extended_by = pos + 1 - data->x86.extended_len;
cpuids = &data->x86.extended;
}
- if (pos >= *len) {
- unsigned int i;
+ if (x86DataExpand(data, basic_by, extended_by) < 0)
+ return -1;
+
+ x86cpuidSetBits((*cpuids) + pos, cpuid);
- if (VIR_ALLOC_N(*cpuids, pos + 1) < 0)
- return -1;
+ return 0;
+}
+
+
+static int
+x86DataAdd(union cpuData *data1,
+ const union cpuData *data2)
+{
+ unsigned int i;
+
+ if (x86DataExpand(data1,
+ data2->x86.basic_len - data1->x86.basic_len,
+ data2->x86.extended_len - data1->x86.extended_len) < 0)
+ return -1;
- for (i = *len; i <= pos; i++)
- (*cpuids)[i].function = i + ext;
- *len = pos + 1;
+ for (i = 0; i < data2->x86.basic_len; i++) {
+ x86cpuidSetBits(data1->x86.basic + i,
+ data2->x86.basic + i);
}
- x86cpuidSetBits((*cpuids) + pos, cpuid);
+ for (i = 0; i < data2->x86.extended_len; i++) {
+ x86cpuidSetBits(data1->x86.extended + i,
+ data2->x86.extended + i);
+ }
return 0;
}
@@ -283,61 +369,49 @@ x86DataSubtract(union cpuData *data1,
}
-static bool
-x86DataIsEmpty(union cpuData *data)
+static void
+x86DataIntersect(union cpuData *data1,
+ const union cpuData *data2)
{
- struct cpuX86cpuid zero = { 0, 0, 0, 0, 0 };
- unsigned int i;
-
- for (i = 0; i < data->x86.basic_len; i++) {
- if (!x86cpuidMatch(data->x86.basic + i, &zero))
- return false;
- }
+ struct data_iterator iter = DATA_ITERATOR_INIT(data1);
+ struct cpuX86cpuid *cpuid1;
+ struct cpuX86cpuid *cpuid2;
- for (i = 0; i < data->x86.extended_len; i++) {
- if (!x86cpuidMatch(data->x86.extended + i, &zero))
- return false;
+ while ((cpuid1 = x86DataCpuidNext(&iter))) {
+ cpuid2 = x86DataCpuid(data2, cpuid1->function);
+ if (cpuid2)
+ x86cpuidAndBits(cpuid1, cpuid2);
+ else
+ x86cpuidClearBits(cpuid1, cpuid1);
}
-
- return true;
}
-static union cpuData *
-x86DataFromModel(const struct x86_model *model)
+static bool
+x86DataIsEmpty(union cpuData *data)
{
- union cpuData *data = NULL;
- uint32_t basic_len = 0;
- uint32_t extended_len = 0;
- struct cpuX86cpuid *cpuid;
- int i;
+ struct data_iterator iter = DATA_ITERATOR_INIT(data);
- for (i = 0; i < model->ncpuid; i++) {
- cpuid = model->cpuid + i;
- if (cpuid->function < CPUX86_EXTENDED) {
- if (cpuid->function >= basic_len)
- basic_len = cpuid->function + 1;
- }
- else if (cpuid->function - CPUX86_EXTENDED >= extended_len)
- extended_len = cpuid->function - CPUX86_EXTENDED + 1;
- }
+ return (x86DataCpuidNext(&iter) == NULL);
+}
- if (VIR_ALLOC(data) < 0
- || VIR_ALLOC_N(data->x86.basic, basic_len) < 0
- || VIR_ALLOC_N(data->x86.extended, extended_len) < 0) {
- x86DataFree(data);
- return NULL;
- }
- data->x86.basic_len = basic_len;
- data->x86.extended_len = extended_len;
+static bool
+x86DataIsSubset(const union cpuData *data,
+ const union cpuData *subset)
+{
+
+ struct data_iterator iter = DATA_ITERATOR_INIT((union cpuData *) subset);
+ const struct cpuX86cpuid *cpuid;
+ const struct cpuX86cpuid *cpuidSubset;
- for (i = 0; i < model->ncpuid; i++) {
- cpuid = x86DataCpuid(data, model->cpuid[i].function);
- *cpuid = model->cpuid[i];
+ while ((cpuidSubset = x86DataCpuidNext(&iter))) {
+ if (!(cpuid = x86DataCpuid(data, cpuidSubset->function)) ||
+ !x86cpuidMatchMasked(cpuid, cpuidSubset))
+ return false;
}
- return data;
+ return true;
}
@@ -349,17 +423,12 @@ x86DataToCPUFeatures(virCPUDefPtr cpu,
const struct x86_map *map)
{
const struct x86_feature *feature = map->features;
- struct cpuX86cpuid *cpuid;
- unsigned int i;
while (feature != NULL) {
- for (i = 0; i < feature->ncpuid; i++) {
- if ((cpuid = x86DataCpuid(data, feature->cpuid[i].function))
- && x86cpuidMatchMasked(cpuid, feature->cpuid + i)) {
- x86cpuidClearBits(cpuid, feature->cpuid + i);
- if (virCPUDefAddFeature(cpu, feature->name, policy) < 0)
- return -1;
- }
+ if (x86DataIsSubset(data, feature->data)) {
+ x86DataSubtract(data, feature->data);
+ if (virCPUDefAddFeature(cpu, feature->name, policy) < 0)
+ return -1;
}
feature = feature->next;
}
@@ -402,7 +471,7 @@ x86DataToCPU(const union cpuData *data,
if (VIR_ALLOC(cpu) < 0 ||
!(cpu->model = strdup(model->name)) ||
!(copy = x86DataCopy(data)) ||
- !(modelData = x86DataFromModel(model)))
+ !(modelData = x86DataCopy(model->data)))
goto no_memory;
if ((vendor = x86DataToVendor(copy, map)) &&
@@ -441,7 +510,7 @@ x86VendorFree(struct x86_vendor *vendor)
VIR_FREE(vendor->name);
VIR_FREE(vendor);
-};
+}
static struct x86_vendor *
@@ -533,6 +602,23 @@ ignore:
}
+static struct x86_feature *
+x86FeatureNew(void)
+{
+ struct x86_feature *feature;
+
+ if (VIR_ALLOC(feature) < 0)
+ return NULL;
+
+ if (VIR_ALLOC(feature->data) < 0) {
+ VIR_FREE(feature);
+ return NULL;
+ }
+
+ return feature;
+}
+
+
static void
x86FeatureFree(struct x86_feature *feature)
{
@@ -540,7 +626,7 @@ x86FeatureFree(struct x86_feature *feature)
return;
VIR_FREE(feature->name);
- VIR_FREE(feature->cpuid);
+ x86DataFree(feature->data);
VIR_FREE(feature);
}
@@ -569,12 +655,12 @@ x86FeatureLoad(xmlXPathContextPtr ctxt,
{
xmlNodePtr *nodes = NULL;
xmlNodePtr ctxt_node = ctxt->node;
- struct x86_feature *feature = NULL;
+ struct x86_feature *feature;
int ret = 0;
int i;
int n;
- if (VIR_ALLOC(feature) < 0)
+ if (!(feature = x86FeatureNew()))
goto no_memory;
feature->name = virXPathString("string(@name)", ctxt);
@@ -594,14 +680,8 @@ x86FeatureLoad(xmlXPathContextPtr ctxt,
if (n < 0)
goto ignore;
- if (n > 0) {
- if (VIR_ALLOC_N(feature->cpuid, n) < 0)
- goto no_memory;
- feature->ncpuid = n;
- }
-
for (i = 0; i < n; i++) {
- struct cpuX86cpuid *cpuid = feature->cpuid + i;
+ struct cpuX86cpuid cpuid;
unsigned long fun, eax, ebx, ecx, edx;
int ret_fun, ret_eax, ret_ebx, ret_ecx, ret_edx;
@@ -620,11 +700,14 @@ x86FeatureLoad(xmlXPathContextPtr ctxt,
goto ignore;
}
- cpuid->function = fun;
- cpuid->eax = eax;
- cpuid->ebx = ebx;
- cpuid->ecx = ecx;
- cpuid->edx = edx;
+ cpuid.function = fun;
+ cpuid.eax = eax;
+ cpuid.ebx = ebx;
+ cpuid.ecx = ecx;
+ cpuid.edx = edx;
+
+ if (x86DataAddCpuid(feature->data, &cpuid))
+ goto no_memory;
}
if (map->features == NULL)
@@ -650,6 +733,23 @@ ignore:
}
+static struct x86_model *
+x86ModelNew(void)
+{
+ struct x86_model *model;
+
+ if (VIR_ALLOC(model) < 0)
+ return NULL;
+
+ if (VIR_ALLOC(model->data) < 0) {
+ VIR_FREE(model);
+ return NULL;
+ }
+
+ return model;
+}
+
+
static void
x86ModelFree(struct x86_model *model)
{
@@ -657,7 +757,7 @@ x86ModelFree(struct x86_model *model)
return;
VIR_FREE(model->name);
- VIR_FREE(model->cpuid);
+ x86DataFree(model->data);
VIR_FREE(model);
}
@@ -666,99 +766,20 @@ static struct x86_model *
x86ModelCopy(const struct x86_model *model)
{
struct x86_model *copy;
- int i;
if (VIR_ALLOC(copy) < 0
- || (copy->name = strdup(model->name)) == NULL
- || VIR_ALLOC_N(copy->cpuid, model->ncpuid) < 0) {
+ || !(copy->name = strdup(model->name))
+ || !(copy->data = x86DataCopy(model->data))) {
x86ModelFree(copy);
return NULL;
}
copy->vendor = model->vendor;
- copy->ncpuid = model->ncpuid;
- for (i = 0; i < model->ncpuid; i++)
- copy->cpuid[i] = model->cpuid[i];
return copy;
}
-static int
-x86ModelAddCpuid(struct x86_model *model,
- const struct cpuX86cpuid *cpuid)
-{
- struct cpuX86cpuid *model_cpuid;
-
- model_cpuid = x86cpuidFind(model->cpuid, model->ncpuid, cpuid->function);
-
- if (model_cpuid != NULL)
- x86cpuidSetBits(model_cpuid, cpuid);
- else {
- if (VIR_REALLOC_N(model->cpuid, model->ncpuid + 1) < 0)
- return -1;
-
- model->cpuid[model->ncpuid] = *cpuid;
- model->ncpuid++;
- }
-
- return 0;
-}
-
-
-static void
-x86ModelSubtract(struct x86_model *model1,
- const struct x86_model *model2)
-{
- int i;
- struct cpuX86cpuid *cpuid;
-
- for (i = 0; i < model2->ncpuid; i++) {
- cpuid = x86cpuidFind(model1->cpuid,
- model1->ncpuid,
- model2->cpuid[i].function);
- if (cpuid != NULL)
- x86cpuidClearBits(cpuid, model2->cpuid + i);
- }
-}
-
-
-static void
-x86ModelIntersect(struct x86_model *model1,
- const struct x86_model *model2)
-{
- int i;
- struct cpuX86cpuid *cpuid;
-
- for (i = 0; i < model1->ncpuid; i++) {
- struct cpuX86cpuid *intersection = model1->cpuid + i;
-
- cpuid = x86cpuidFind(model2->cpuid,
- model2->ncpuid,
- intersection->function);
- if (cpuid != NULL)
- x86cpuidAndBits(intersection, cpuid);
- else
- x86cpuidClearBits(intersection, intersection);
- }
-}
-
-
-static int
-x86ModelAdd(struct x86_model *model1,
- const struct x86_model *model2)
-{
- int i;
-
- for (i = 0; i < model2->ncpuid; i++) {
- if (x86ModelAddCpuid(model1, model2->cpuid + i))
- return -1;
- }
-
- return 0;
-}
-
-
static struct x86_model *
x86ModelFind(const struct x86_map *map,
const char *name)
@@ -777,47 +798,6 @@ x86ModelFind(const struct x86_map *map,
}
-static int
-x86ModelMergeFeature(struct x86_model *model,
- const struct x86_feature *feature)
-{
- int i;
-
- if (feature == NULL)
- return 0;
-
- for (i = 0; i < feature->ncpuid; i++) {
- if (x86ModelAddCpuid(model, feature->cpuid + i))
- return -1;
- }
-
- return 0;
-}
-
-
-static bool
-x86ModelHasFeature(struct x86_model *model,
- const struct x86_feature *feature)
-{
- unsigned int i;
- struct cpuX86cpuid *cpuid;
- struct cpuX86cpuid *model_cpuid;
-
- if (feature == NULL)
- return false;
-
- for (i = 0; i < feature->ncpuid; i++) {
- cpuid = feature->cpuid + i;
- model_cpuid = x86cpuidFind(model->cpuid, model->ncpuid,
- cpuid->function);
- if (!model_cpuid || !x86cpuidMatchMasked(model_cpuid, cpuid))
- return false;
- }
-
- return true;
-}
-
-
static struct x86_model *
x86ModelFromCPU(const virCPUDefPtr cpu,
const struct x86_map *map,
@@ -835,11 +815,11 @@ x86ModelFromCPU(const virCPUDefPtr cpu,
if ((model = x86ModelCopy(model)) == NULL)
goto no_memory;
- }
- else if (VIR_ALLOC(model) < 0)
+ } else if (!(model = x86ModelNew())) {
goto no_memory;
- else if (cpu->type == VIR_CPU_TYPE_HOST)
+ } else if (cpu->type == VIR_CPU_TYPE_HOST) {
return model;
+ }
for (i = 0; i < cpu->nfeatures; i++) {
const struct x86_feature *feature;
@@ -854,7 +834,7 @@ x86ModelFromCPU(const virCPUDefPtr cpu,
goto error;
}
- if (x86ModelMergeFeature(model, feature))
+ if (x86DataAdd(model->data, feature->data))
goto no_memory;
}
@@ -884,11 +864,10 @@ x86ModelSubtractCPU(struct x86_model *model,
return -1;
}
- x86ModelSubtract(model, cpu_model);
+ x86DataSubtract(model->data, cpu_model->data);
for (i = 0; i < cpu->nfeatures; i++) {
const struct x86_feature *feature;
- unsigned int j;
if (!(feature = x86FeatureFind(map, cpu->features[i].name))) {
virCPUReportError(VIR_ERR_INTERNAL_ERROR,
@@ -897,13 +876,7 @@ x86ModelSubtractCPU(struct x86_model *model,
return -1;
}
- for (j = 0; j < feature->ncpuid; j++) {
- struct cpuX86cpuid *cpuid;
- cpuid = x86cpuidFind(model->cpuid, model->ncpuid,
- feature->cpuid[j].function);
- if (cpuid)
- x86cpuidClearBits(cpuid, feature->cpuid + j);
- }
+ x86DataSubtract(model->data, feature->data);
}
return 0;
@@ -915,18 +888,15 @@ x86ModelCompare(const struct x86_model *model1,
const struct x86_model *model2)
{
enum compare_result result = EQUAL;
+ struct data_iterator iter1 = DATA_ITERATOR_INIT(model1->data);
+ struct data_iterator iter2 = DATA_ITERATOR_INIT(model2->data);
struct cpuX86cpuid *cpuid1;
struct cpuX86cpuid *cpuid2;
- int i;
- for (i = 0; i < model1->ncpuid; i++) {
+ while ((cpuid1 = x86DataCpuidNext(&iter1))) {
enum compare_result match = SUPERSET;
- cpuid1 = model1->cpuid + i;
- cpuid2 = x86cpuidFind(model2->cpuid,
- model2->ncpuid,
- cpuid1->function);
- if (cpuid2 != NULL) {
+ if ((cpuid2 = x86DataCpuid(model2->data, cpuid1->function))) {
if (x86cpuidMatch(cpuid1, cpuid2))
continue;
else if (!x86cpuidMatchMasked(cpuid1, cpuid2))
@@ -939,14 +909,10 @@ x86ModelCompare(const struct x86_model *model1,
return UNRELATED;
}
- for (i = 0; i < model2->ncpuid; i++) {
+ while ((cpuid2 = x86DataCpuidNext(&iter2))) {
enum compare_result match = SUBSET;
- cpuid2 = model2->cpuid + i;
- cpuid1 = x86cpuidFind(model1->cpuid,
- model1->ncpuid,
- cpuid2->function);
- if (cpuid1 != NULL) {
+ if ((cpuid1 = x86DataCpuid(model1->data, cpuid2->function))) {
if (x86cpuidMatch(cpuid2, cpuid1))
continue;
else if (!x86cpuidMatchMasked(cpuid2, cpuid1))
@@ -968,13 +934,13 @@ x86ModelLoad(xmlXPathContextPtr ctxt,
struct x86_map *map)
{
xmlNodePtr *nodes = NULL;
- struct x86_model *model = NULL;
+ struct x86_model *model;
char *vendor = NULL;
int ret = 0;
int i;
int n;
- if (VIR_ALLOC(model) < 0)
+ if (!(model = x86ModelNew()))
goto no_memory;
model->name = virXPathString("string(@name)", ctxt);
@@ -1006,13 +972,9 @@ x86ModelLoad(xmlXPathContextPtr ctxt,
VIR_FREE(name);
- if (VIR_ALLOC_N(model->cpuid, ancestor->ncpuid) < 0)
- goto no_memory;
-
model->vendor = ancestor->vendor;
- model->ncpuid = ancestor->ncpuid;
- memcpy(model->cpuid, ancestor->cpuid,
- sizeof(*model->cpuid) * model->ncpuid);
+ if (!(model->data = x86DataCopy(ancestor->data)))
+ goto no_memory;
}
if (virXPathBoolean("boolean(./vendor)", ctxt)) {
@@ -1055,7 +1017,7 @@ x86ModelLoad(xmlXPathContextPtr ctxt,
}
VIR_FREE(name);
- if (x86ModelMergeFeature(model, feature))
+ if (x86DataAdd(model->data, feature->data))
goto no_memory;
}
@@ -1157,7 +1119,6 @@ x86Compute(virCPUDefPtr host,
virCPUDefPtr cpu,
union cpuData **guest)
{
- struct cpuX86cpuid cpuid_zero = { 0, 0, 0, 0, 0 };
struct x86_map *map = NULL;
struct x86_model *host_model = NULL;
struct x86_model *cpu_force = NULL;
@@ -1167,6 +1128,8 @@ x86Compute(virCPUDefPtr host,
struct x86_model *cpu_forbid = NULL;
struct x86_model *diff = NULL;
struct x86_model *guest_model = NULL;
+ struct data_iterator iter;
+ const struct cpuX86cpuid *cpuid;
virCPUCompareResult ret;
enum compare_result result;
unsigned int i;
@@ -1203,24 +1166,20 @@ x86Compute(virCPUDefPtr host,
!(cpu_forbid = x86ModelFromCPU(cpu, map, VIR_CPU_FEATURE_FORBID)))
goto error;
- for (i = 0; i < cpu_forbid->ncpuid; i++) {
- const struct cpuX86cpuid *cpuid1;
+ x86DataIteratorInit(&iter, cpu_forbid->data);
+ while ((cpuid = x86DataCpuidNext(&iter))) {
const struct cpuX86cpuid *cpuid2;
- cpuid1 = cpu_forbid->cpuid + i;
- cpuid2 = x86cpuidFind(host_model->cpuid,
- host_model->ncpuid,
- cpuid1->function);
-
- if (cpuid2 != NULL && x86cpuidMatchAny(cpuid2, cpuid1)) {
+ cpuid2 = x86DataCpuid(host_model->data, cpuid->function);
+ if (cpuid2 != NULL && x86cpuidMatchAny(cpuid2, cpuid)) {
VIR_DEBUG("Host CPU provides forbidden features in CPUID function 0x%x",
- cpuid1->function);
+ cpuid->function);
ret = VIR_CPU_COMPARE_INCOMPATIBLE;
goto out;
}
}
- x86ModelSubtract(cpu_require, cpu_disable);
+ x86DataSubtract(cpu_require->data, cpu_disable->data);
result = x86ModelCompare(host_model, cpu_require);
if (result == SUBSET || result == UNRELATED) {
VIR_DEBUG0("Host CPU does not provide all required features");
@@ -1233,17 +1192,13 @@ x86Compute(virCPUDefPtr host,
if ((diff = x86ModelCopy(host_model)) == NULL)
goto no_memory;
- x86ModelSubtract(diff, cpu_optional);
- x86ModelSubtract(diff, cpu_require);
- x86ModelSubtract(diff, cpu_disable);
- x86ModelSubtract(diff, cpu_force);
+ x86DataSubtract(diff->data, cpu_optional->data);
+ x86DataSubtract(diff->data, cpu_require->data);
+ x86DataSubtract(diff->data, cpu_disable->data);
+ x86DataSubtract(diff->data, cpu_force->data);
- for (i = 0; i < diff->ncpuid; i++) {
- if (!x86cpuidMatch(diff->cpuid + i, &cpuid_zero)) {
- ret = VIR_CPU_COMPARE_SUPERSET;
- break;
- }
- }
+ if (!x86DataIsEmpty(diff->data))
+ ret = VIR_CPU_COMPARE_SUPERSET;
if (ret == VIR_CPU_COMPARE_SUPERSET
&& cpu->type == VIR_CPU_TYPE_GUEST
@@ -1259,14 +1214,14 @@ x86Compute(virCPUDefPtr host,
if (cpu->type == VIR_CPU_TYPE_GUEST
&& cpu->match == VIR_CPU_MATCH_EXACT)
- x86ModelSubtract(guest_model, diff);
+ x86DataSubtract(guest_model->data, diff->data);
- if (x86ModelAdd(guest_model, cpu_force))
+ if (x86DataAdd(guest_model->data, cpu_force->data))
goto no_memory;
- x86ModelSubtract(guest_model, cpu_disable);
+ x86DataSubtract(guest_model->data, cpu_disable->data);
- if ((*guest = x86DataFromModel(guest_model)) == NULL)
+ if ((*guest = x86DataCopy(guest_model->data)) == NULL)
goto no_memory;
}
@@ -1418,9 +1373,8 @@ x86EncodePolicy(const virCPUDefPtr cpu,
if (!(model = x86ModelFromCPU(cpu, map, policy)))
return NULL;
- if (!(data = x86DataFromModel(model)))
- virReportOOMError();
-
+ data = model->data;
+ model->data = NULL;
x86ModelFree(model);
return data;
@@ -1584,19 +1538,20 @@ static union cpuData *
x86NodeData(void)
{
union cpuData *data;
+ int ret;
if (VIR_ALLOC(data) < 0) {
virReportOOMError();
return NULL;
}
- data->x86.basic_len = cpuidSet(CPUX86_BASIC, &data->x86.basic);
- if (data->x86.basic_len < 0)
+ if ((ret = cpuidSet(CPUX86_BASIC, &data->x86.basic)) < 0)
goto error;
+ data->x86.basic_len = ret;
- data->x86.extended_len = cpuidSet(CPUX86_EXTENDED, &data->x86.extended);
- if (data->x86.extended_len < 0)
+ if ((ret = cpuidSet(CPUX86_EXTENDED, &data->x86.extended)) < 0)
goto error;
+ data->x86.extended_len = ret;
return data;
@@ -1616,7 +1571,6 @@ x86Baseline(virCPUDefPtr *cpus,
{
struct x86_map *map = NULL;
struct x86_model *base_model = NULL;
- union cpuData *data = NULL;
virCPUDefPtr cpu = NULL;
unsigned int i;
const struct x86_vendor *vendor = NULL;
@@ -1679,24 +1633,21 @@ x86Baseline(virCPUDefPtr *cpus,
}
}
- x86ModelIntersect(base_model, model);
+ x86DataIntersect(base_model->data, model->data);
x86ModelFree(model);
model = NULL;
}
- if (!(data = x86DataFromModel(base_model)))
- goto no_memory;
-
- if (x86DataIsEmpty(data)) {
+ if (x86DataIsEmpty(base_model->data)) {
virCPUReportError(VIR_ERR_OPERATION_FAILED,
"%s", _("CPUs are incompatible"));
goto error;
}
- if (vendor && x86DataAddCpuid(data, &vendor->cpuid) < 0)
+ if (vendor && x86DataAddCpuid(base_model->data, &vendor->cpuid) < 0)
goto no_memory;
- if (x86Decode(cpu, data, models, nmodels, NULL) < 0)
+ if (x86Decode(cpu, base_model->data, models, nmodels, NULL) < 0)
goto error;
if (!outputVendor)
@@ -1705,7 +1656,6 @@ x86Baseline(virCPUDefPtr *cpus,
VIR_FREE(cpu->arch);
cleanup:
- x86DataFree(data);
x86ModelFree(base_model);
x86MapFree(map);
@@ -1729,7 +1679,6 @@ x86Update(virCPUDefPtr guest,
unsigned int i;
struct x86_map *map;
struct x86_model *host_model = NULL;
- union cpuData *data = NULL;
if (!(map = x86LoadMap()) ||
!(host_model = x86ModelFromCPU(host, map, VIR_CPU_FEATURE_REQUIRE)))
@@ -1745,7 +1694,7 @@ x86Update(virCPUDefPtr guest,
goto cleanup;
}
- if (x86ModelHasFeature(host_model, feature))
+ if (x86DataIsSubset(host_model->data, feature->data))
guest->features[i].policy = VIR_CPU_FEATURE_REQUIRE;
else
guest->features[i].policy = VIR_CPU_FEATURE_DISABLE;
@@ -1755,8 +1704,8 @@ x86Update(virCPUDefPtr guest,
if (guest->match == VIR_CPU_MATCH_MINIMUM) {
guest->match = VIR_CPU_MATCH_EXACT;
if (x86ModelSubtractCPU(host_model, guest, map)
- || !(data = x86DataFromModel(host_model))
- || x86DataToCPUFeatures(guest, VIR_CPU_FEATURE_REQUIRE, data, map))
+ || x86DataToCPUFeatures(guest, VIR_CPU_FEATURE_REQUIRE,
+ host_model->data, map))
goto cleanup;
}
@@ -1765,7 +1714,6 @@ x86Update(virCPUDefPtr guest,
cleanup:
x86MapFree(map);
x86ModelFree(host_model);
- x86DataFree(data);
return ret;
}
@@ -1775,7 +1723,6 @@ static int x86HasFeature(const union cpuData *data,
struct x86_map *map;
struct x86_feature *feature;
int ret = -1;
- int i;
if (!(map = x86LoadMap()))
return -1;
@@ -1783,16 +1730,7 @@ static int x86HasFeature(const union cpuData *data,
if (!(feature = x86FeatureFind(map, name)))
goto cleanup;
- for (i = 0 ; i < feature->ncpuid ; i++) {
- struct cpuX86cpuid *cpuid;
-
- cpuid = x86DataCpuid(data, feature->cpuid[i].function);
- if (cpuid && x86cpuidMatchMasked(cpuid, feature->cpuid + i)) {
- ret = 1;
- goto cleanup;
- }
- }
- ret = 0;
+ ret = x86DataIsSubset(data, feature->data) ? 1 : 0;
cleanup:
x86MapFree(map);
diff --git a/src/cpu/cpu_x86_data.h b/src/cpu/cpu_x86_data.h
index 46d2517..34a5b06 100644
--- a/src/cpu/cpu_x86_data.h
+++ b/src/cpu/cpu_x86_data.h
@@ -38,9 +38,9 @@ struct cpuX86cpuid {
# define CPUX86_EXTENDED 0x80000000
struct cpuX86Data {
- int basic_len;
+ size_t basic_len;
struct cpuX86cpuid *basic;
- int extended_len;
+ size_t extended_len;
struct cpuX86cpuid *extended;
};
--
1.7.3.3
14 years
[libvirt] [PATCH] esx: Add support for storage volume cloning
by Matthias Bolte
---
src/esx/esx_storage_driver.c | 198 +++++++++++++++++++++++++++++++++++++++-
src/esx/esx_vi_generator.input | 11 ++
2 files changed, 208 insertions(+), 1 deletions(-)
diff --git a/src/esx/esx_storage_driver.c b/src/esx/esx_storage_driver.c
index 9165f7a..e6803c2 100644
--- a/src/esx/esx_storage_driver.c
+++ b/src/esx/esx_storage_driver.c
@@ -1180,6 +1180,202 @@ esxStorageVolumeCreateXML(virStoragePoolPtr pool, const char *xmldesc,
+static virStorageVolPtr
+esxStorageVolumeCreateXMLFrom(virStoragePoolPtr pool, const char *xmldesc,
+ virStorageVolPtr sourceVolume, unsigned int flags)
+{
+ virStorageVolPtr volume = NULL;
+ esxPrivate *priv = pool->conn->storagePrivateData;
+ virStoragePoolDef poolDef;
+ char *sourceDatastorePath = NULL;
+ virStorageVolDefPtr def = NULL;
+ char *tmp;
+ char *unescapedDatastorePath = NULL;
+ char *unescapedDirectoryName = NULL;
+ char *unescapedDirectoryAndFileName = NULL;
+ char *directoryName = NULL;
+ char *fileName = NULL;
+ char *datastorePathWithoutFileName = NULL;
+ char *datastorePath = NULL;
+ esxVI_FileInfo *fileInfo = NULL;
+ esxVI_ManagedObjectReference *task = NULL;
+ esxVI_TaskInfoState taskInfoState;
+ char *taskInfoErrorMessage = NULL;
+ char *uuid_string = NULL;
+ char *key = NULL;
+
+ virCheckFlags(0, NULL);
+
+ memset(&poolDef, 0, sizeof (poolDef));
+
+ if (esxVI_EnsureSession(priv->primary) < 0) {
+ return NULL;
+ }
+
+ if (esxStoragePoolLookupType(priv->primary, pool->name, &poolDef.type) < 0) {
+ return NULL;
+ }
+
+ if (virAsprintf(&sourceDatastorePath, "[%s] %s", sourceVolume->pool,
+ sourceVolume->name) < 0) {
+ virReportOOMError();
+ goto cleanup;
+ }
+
+ /* Parse config */
+ def = virStorageVolDefParseString(&poolDef, xmldesc);
+
+ if (def == NULL) {
+ goto cleanup;
+ }
+
+ if (def->type != VIR_STORAGE_VOL_FILE) {
+ ESX_ERROR(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("Creating non-file volumes is not supported"));
+ goto cleanup;
+ }
+
+ /* Validate config */
+ tmp = strrchr(def->name, '/');
+
+ if (tmp == NULL || *def->name == '/' || tmp[1] == '\0') {
+ ESX_ERROR(VIR_ERR_INTERNAL_ERROR,
+ _("Volume name '%s' doesn't have expected format "
+ "'<directory>/<file>'"), def->name);
+ goto cleanup;
+ }
+
+ if (! virFileHasSuffix(def->name, ".vmdk")) {
+ ESX_ERROR(VIR_ERR_INTERNAL_ERROR,
+ _("Volume name '%s' has unsupported suffix, expecting '.vmdk'"),
+ def->name);
+ goto cleanup;
+ }
+
+ if (virAsprintf(&unescapedDatastorePath, "[%s] %s", pool->name,
+ def->name) < 0) {
+ virReportOOMError();
+ goto cleanup;
+ }
+
+ if (def->target.format == VIR_STORAGE_FILE_VMDK) {
+ /* Parse and escape datastore path */
+ if (esxUtil_ParseDatastorePath(unescapedDatastorePath, NULL,
+ &unescapedDirectoryName,
+ &unescapedDirectoryAndFileName) < 0) {
+ goto cleanup;
+ }
+
+ directoryName = esxUtil_EscapeDatastoreItem(unescapedDirectoryName);
+
+ if (directoryName == NULL) {
+ goto cleanup;
+ }
+
+ fileName = esxUtil_EscapeDatastoreItem(unescapedDirectoryAndFileName +
+ strlen(unescapedDirectoryName) + 1);
+
+ if (fileName == NULL) {
+ goto cleanup;
+ }
+
+ if (virAsprintf(&datastorePathWithoutFileName, "[%s] %s", pool->name,
+ directoryName) < 0) {
+ virReportOOMError();
+ goto cleanup;
+ }
+
+ if (virAsprintf(&datastorePath, "[%s] %s/%s", pool->name, directoryName,
+ fileName) < 0) {
+ virReportOOMError();
+ goto cleanup;
+ }
+
+ /* Create directory, if it doesn't exist yet */
+ if (esxVI_LookupFileInfoByDatastorePath
+ (priv->primary, datastorePathWithoutFileName, true, &fileInfo,
+ esxVI_Occurrence_OptionalItem) < 0) {
+ goto cleanup;
+ }
+
+ if (fileInfo == NULL) {
+ if (esxVI_MakeDirectory(priv->primary, datastorePathWithoutFileName,
+ priv->primary->datacenter->_reference,
+ esxVI_Boolean_True) < 0) {
+ goto cleanup;
+ }
+ }
+
+ /* Copy VirtualDisk */
+ if (esxVI_CopyVirtualDisk_Task(priv->primary, sourceDatastorePath,
+ priv->primary->datacenter->_reference,
+ datastorePath,
+ priv->primary->datacenter->_reference,
+ NULL, esxVI_Boolean_False, &task) < 0 ||
+ esxVI_WaitForTaskCompletion(priv->primary, task, NULL,
+ esxVI_Occurrence_None,
+ priv->autoAnswer, &taskInfoState,
+ &taskInfoErrorMessage) < 0) {
+ goto cleanup;
+ }
+
+ if (taskInfoState != esxVI_TaskInfoState_Success) {
+ ESX_ERROR(VIR_ERR_INTERNAL_ERROR, _("Could not copy volume: %s"),
+ taskInfoErrorMessage);
+ goto cleanup;
+ }
+
+ if (priv->primary->hasQueryVirtualDiskUuid) {
+ if (VIR_ALLOC_N(key, VIR_UUID_STRING_BUFLEN) < 0) {
+ virReportOOMError();
+ goto cleanup;
+ }
+
+ if (esxVI_QueryVirtualDiskUuid(priv->primary, datastorePath,
+ priv->primary->datacenter->_reference,
+ &uuid_string) < 0) {
+ goto cleanup;
+ }
+
+ if (esxUtil_ReformatUuid(uuid_string, key) < 0) {
+ goto cleanup;
+ }
+ } else {
+ /* Fall back to the path as key */
+ if (esxVI_String_DeepCopyValue(&key, datastorePath) < 0) {
+ goto cleanup;
+ }
+ }
+ } else {
+ ESX_ERROR(VIR_ERR_INTERNAL_ERROR,
+ _("Creation of %s volumes is not supported"),
+ virStorageFileFormatTypeToString(def->target.format));
+ goto cleanup;
+ }
+
+ volume = virGetStorageVol(pool->conn, pool->name, def->name, key);
+
+ cleanup:
+ VIR_FREE(sourceDatastorePath);
+ virStorageVolDefFree(def);
+ VIR_FREE(unescapedDatastorePath);
+ VIR_FREE(unescapedDirectoryName);
+ VIR_FREE(unescapedDirectoryAndFileName);
+ VIR_FREE(directoryName);
+ VIR_FREE(fileName);
+ VIR_FREE(datastorePathWithoutFileName);
+ VIR_FREE(datastorePath);
+ esxVI_FileInfo_Free(&fileInfo);
+ esxVI_ManagedObjectReference_Free(&task);
+ VIR_FREE(taskInfoErrorMessage);
+ VIR_FREE(uuid_string);
+ VIR_FREE(key);
+
+ return volume;
+}
+
+
+
static int
esxStorageVolumeGetInfo(virStorageVolPtr volume, virStorageVolInfoPtr info)
{
@@ -1377,7 +1573,7 @@ static virStorageDriver esxStorageDriver = {
esxStorageVolumeLookupByKey, /* volLookupByKey */
esxStorageVolumeLookupByPath, /* volLookupByPath */
esxStorageVolumeCreateXML, /* volCreateXML */
- NULL, /* volCreateXMLFrom */
+ esxStorageVolumeCreateXMLFrom, /* volCreateXMLFrom */
NULL, /* volDelete */
NULL, /* volWipe */
esxStorageVolumeGetInfo, /* volGetInfo */
diff --git a/src/esx/esx_vi_generator.input b/src/esx/esx_vi_generator.input
index 991ce8a..4018c6e 100644
--- a/src/esx/esx_vi_generator.input
+++ b/src/esx/esx_vi_generator.input
@@ -700,6 +700,17 @@ method CancelTask
end
+method CopyVirtualDisk_Task returns ManagedObjectReference r
+ ManagedObjectReference _this:VirtualDiskManager r
+ String sourceName r
+ ManagedObjectReference sourceDatacenter o
+ String destName r
+ ManagedObjectReference destDatacenter o
+ VirtualDiskSpec destSpec o
+ Boolean force o
+end
+
+
method CreateFilter returns ManagedObjectReference r
ManagedObjectReference _this:PropertyCollector r
PropertyFilterSpec spec r
--
1.7.0.4
14 years
[libvirt] [PATCH] qemu: Use -vga none only if it is supported
by Jiri Denemark
Commit febc591683cf51e4551f8bcf3ce279a776056e1c introduced -vga none in
case no video card is included in domain XML. However, old qemu
versions do not support this and such domain cannot be successfully
started.
---
src/qemu/qemu_conf.c | 10 ++++++-
src/qemu/qemu_conf.h | 1 +
tests/qemuhelptest.c | 18 +++++++++----
.../qemuxml2argvdata/qemuxml2argv-nographics.args | 1 +
tests/qemuxml2argvdata/qemuxml2argv-nographics.xml | 25 ++++++++++++++++++++
tests/qemuxml2argvtest.c | 4 ++-
6 files changed, 50 insertions(+), 9 deletions(-)
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-nographics.args
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-nographics.xml
diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c
index e5d0206..d5e72cd 100644
--- a/src/qemu/qemu_conf.c
+++ b/src/qemu/qemu_conf.c
@@ -1220,6 +1220,7 @@ static unsigned long long qemudComputeCmdFlags(const char *help,
unsigned int kvm_version)
{
unsigned long long flags = 0;
+ const char *p;
if (strstr(help, "-no-kqemu"))
flags |= QEMUD_CMD_FLAG_KQEMU;
@@ -1252,11 +1253,15 @@ static unsigned long long qemudComputeCmdFlags(const char *help,
if (strstr(help, "readonly="))
flags |= QEMUD_CMD_FLAG_DRIVE_READONLY;
}
- if (strstr(help, "-vga") && !strstr(help, "-std-vga")) {
+ if ((p = strstr(help, "-vga")) && !strstr(help, "-std-vga")) {
+ const char *nl = strstr(p, "\n");
+
flags |= QEMUD_CMD_FLAG_VGA;
if (strstr(help, "|qxl"))
flags |= QEMUD_CMD_FLAG_VGA_QXL;
+ if ((p = strstr(p, "|none")) && p < nl)
+ flags |= QEMUD_CMD_FLAG_VGA_NONE;
}
if (strstr(help, "-spice"))
flags |= QEMUD_CMD_FLAG_SPICE;
@@ -5192,7 +5197,8 @@ qemudBuildCommandLine(virConnectPtr conn,
} else {
/* If we have -device, then we set -nodefault already */
if (!(qemuCmdFlags & QEMUD_CMD_FLAG_DEVICE) &&
- (qemuCmdFlags & QEMUD_CMD_FLAG_VGA))
+ (qemuCmdFlags & QEMUD_CMD_FLAG_VGA) &&
+ (qemuCmdFlags & QEMUD_CMD_FLAG_VGA_NONE))
virCommandAddArgList(cmd, "-vga", "none", NULL);
}
diff --git a/src/qemu/qemu_conf.h b/src/qemu/qemu_conf.h
index 71318bf..2d0314c 100644
--- a/src/qemu/qemu_conf.h
+++ b/src/qemu/qemu_conf.h
@@ -101,6 +101,7 @@ enum qemud_cmd_flags {
QEMUD_CMD_FLAG_SMBIOS_TYPE = (1LL << 44), /* Is -smbios type= available */
QEMUD_CMD_FLAG_VGA_QXL = (1LL << 45), /* The 'qxl' arg for '-vga' */
QEMUD_CMD_FLAG_SPICE = (1LL << 46), /* Is -spice avail */
+ QEMUD_CMD_FLAG_VGA_NONE = (1LL << 47), /* The 'none' arg for '-vga' */
};
/* Main driver state */
diff --git a/tests/qemuhelptest.c b/tests/qemuhelptest.c
index 5339ec8..f3b6537 100644
--- a/tests/qemuhelptest.c
+++ b/tests/qemuhelptest.c
@@ -173,7 +173,8 @@ mymain(int argc, char **argv)
QEMUD_CMD_FLAG_ENABLE_KVM |
QEMUD_CMD_FLAG_SDL |
QEMUD_CMD_FLAG_RTC_TD_HACK |
- QEMUD_CMD_FLAG_NO_HPET,
+ QEMUD_CMD_FLAG_NO_HPET |
+ QEMUD_CMD_FLAG_VGA_NONE,
10005, 0, 0);
DO_TEST("qemu-kvm-0.10.5",
QEMUD_CMD_FLAG_VNC_COLON |
@@ -198,7 +199,8 @@ mymain(int argc, char **argv)
QEMUD_CMD_FLAG_NO_HPET |
QEMUD_CMD_FLAG_NO_KVM_PIT |
QEMUD_CMD_FLAG_TDF |
- QEMUD_CMD_FLAG_NESTING,
+ QEMUD_CMD_FLAG_NESTING |
+ QEMUD_CMD_FLAG_VGA_NONE,
10005, 1, 0);
DO_TEST("kvm-86",
QEMUD_CMD_FLAG_VNC_COLON |
@@ -223,7 +225,8 @@ mymain(int argc, char **argv)
QEMUD_CMD_FLAG_NO_KVM_PIT |
QEMUD_CMD_FLAG_TDF |
QEMUD_CMD_FLAG_NESTING |
- QEMUD_CMD_FLAG_SMBIOS_TYPE,
+ QEMUD_CMD_FLAG_SMBIOS_TYPE |
+ QEMUD_CMD_FLAG_VGA_NONE,
10050, 1, 0);
DO_TEST("qemu-kvm-0.11.0-rc2",
QEMUD_CMD_FLAG_VNC_COLON |
@@ -253,7 +256,8 @@ mymain(int argc, char **argv)
QEMUD_CMD_FLAG_BOOT_MENU |
QEMUD_CMD_FLAG_NESTING |
QEMUD_CMD_FLAG_NAME_PROCESS |
- QEMUD_CMD_FLAG_SMBIOS_TYPE,
+ QEMUD_CMD_FLAG_SMBIOS_TYPE |
+ QEMUD_CMD_FLAG_VGA_NONE,
10092, 1, 0);
DO_TEST("qemu-0.12.1",
QEMUD_CMD_FLAG_VNC_COLON |
@@ -281,7 +285,8 @@ mymain(int argc, char **argv)
QEMUD_CMD_FLAG_NO_HPET |
QEMUD_CMD_FLAG_BOOT_MENU |
QEMUD_CMD_FLAG_NAME_PROCESS |
- QEMUD_CMD_FLAG_SMBIOS_TYPE,
+ QEMUD_CMD_FLAG_SMBIOS_TYPE |
+ QEMUD_CMD_FLAG_VGA_NONE,
12001, 0, 0);
DO_TEST("qemu-kvm-0.12.3",
QEMUD_CMD_FLAG_VNC_COLON |
@@ -316,7 +321,8 @@ mymain(int argc, char **argv)
QEMUD_CMD_FLAG_BOOT_MENU |
QEMUD_CMD_FLAG_NESTING |
QEMUD_CMD_FLAG_NAME_PROCESS |
- QEMUD_CMD_FLAG_SMBIOS_TYPE,
+ QEMUD_CMD_FLAG_SMBIOS_TYPE |
+ QEMUD_CMD_FLAG_VGA_NONE,
12003, 1, 0);
return ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-nographics.args b/tests/qemuxml2argvdata/qemuxml2argv-nographics.args
new file mode 100644
index 0000000..0d3ef6f
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-nographics.args
@@ -0,0 +1 @@
+LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -monitor unix:/tmp/test-monitor,server,nowait -no-acpi -boot c -hda /dev/HostVG/QEMUGuest1 -net none -serial none -parallel none -usb
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-nographics.xml b/tests/qemuxml2argvdata/qemuxml2argv-nographics.xml
new file mode 100644
index 0000000..ed91e37
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-nographics.xml
@@ -0,0 +1,25 @@
+<domain type='qemu'>
+ <name>QEMUGuest1</name>
+ <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
+ <memory>219200</memory>
+ <currentMemory>219200</currentMemory>
+ <vcpu>1</vcpu>
+ <os>
+ <type arch='i686' machine='pc'>hvm</type>
+ <boot dev='hd'/>
+ </os>
+ <clock offset='utc'/>
+ <on_poweroff>destroy</on_poweroff>
+ <on_reboot>restart</on_reboot>
+ <on_crash>destroy</on_crash>
+ <devices>
+ <emulator>/usr/bin/qemu</emulator>
+ <disk type='block' device='disk'>
+ <source dev='/dev/HostVG/QEMUGuest1'/>
+ <target dev='hda' bus='ide'/>
+ <address type='drive' controller='0' bus='0' unit='0'/>
+ </disk>
+ <controller type='ide' index='0'/>
+ <memballoon model='virtio'/>
+ </devices>
+</domain>
diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c
index 5fe91f1..662f7bb 100644
--- a/tests/qemuxml2argvtest.c
+++ b/tests/qemuxml2argvtest.c
@@ -325,7 +325,9 @@ mymain(int argc, char **argv)
DO_TEST("graphics-sdl", 0, false);
DO_TEST("graphics-sdl-fullscreen", 0, false);
- DO_TEST("nographics-vga", QEMUD_CMD_FLAG_VGA, false);
+ DO_TEST("nographics", QEMUD_CMD_FLAG_VGA, false);
+ DO_TEST("nographics-vga", QEMUD_CMD_FLAG_VGA |
+ QEMUD_CMD_FLAG_VGA_NONE, false);
DO_TEST("graphics-spice",
QEMUD_CMD_FLAG_VGA | QEMUD_CMD_FLAG_VGA_QXL |
QEMUD_CMD_FLAG_DEVICE | QEMUD_CMD_FLAG_SPICE, false);
--
1.7.3.3
14 years
[libvirt] [PATCHv2 0/5] smbios cleanups
by Eric Blake
No change to the first three patches (but reposting so they'll all be
in the same thread). The last two patches are new.
Eric Blake (5):
qemu: avoid adding "" in smbios arguments
smbios: support system family
smbios: allow () in smbios strings
uuid: require smbios uuid and domain uuid to match
sysinfo: convert to virCommand
docs/schemas/domain.rng | 3 +-
src/conf/domain_conf.c | 31 ++++++++++++-
src/qemu/qemu_conf.c | 40 ++++++++++------
src/util/sysinfo.c | 57 +++++++----------------
src/util/sysinfo.h | 1 +
tests/qemuxml2argvdata/qemuxml2argv-smbios.args | 2 +-
tests/qemuxml2argvdata/qemuxml2argv-smbios.xml | 20 ++++----
7 files changed, 85 insertions(+), 69 deletions(-)
--
1.7.3.2
14 years
[libvirt] [PATCH] build: update gnulib for pipe on mingw
by Eric Blake
* .gnulib: Update to latest.
* bootstrap.conf (gnulib_modules): Import pipe-posix for mingw.
* src/remote/remote_driver.c (pipe): Drop dead macro.
---
Matthias complianed on IRC that mingw builds are broken since
they unconditionally build virCommand, which unconditionally
uses pipe() and waitpid() even though those are missing on mingw.
I've fixed pipe() in gnulib. waitpid() will need a bit more
invasive fix; I'm thinking of creating:
struct virPid {
#ifdef WIN32
HANDLE pid;
#else
pid_t pid;
#endif
};
/* Wait for a child process to complete. */
int virPidWait(virPid pid, int *status)
{
#ifdef WIN32
whatever windows provides
#else
return waitpid(pid.pid, status, 0);
#endif
}
or something like that.
* .gnulib 6491120...e2f1471 (3):
> pipe-posix: new module
> * build-aux/gendocs.sh: restore x bit
> autoupdate
.gnulib | 2 +-
bootstrap.conf | 1 +
src/remote/remote_driver.c | 5 -----
3 files changed, 2 insertions(+), 6 deletions(-)
diff --git a/.gnulib b/.gnulib
index 6491120..e2f1471 160000
--- a/.gnulib
+++ b/.gnulib
@@ -1 +1 @@
-Subproject commit 64911207854610668b480939469282fdaeb96f74
+Subproject commit e2f1471b021a285916339a73bc12c6b44dbf9a76
diff --git a/bootstrap.conf b/bootstrap.conf
index 2ad1957..dbed752 100644
--- a/bootstrap.conf
+++ b/bootstrap.conf
@@ -48,6 +48,7 @@ mktempd
netdb
perror
physmem
+pipe-posix
poll
posix-shell
pthread
diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c
index e6eb9b5..fae191c 100644
--- a/src/remote/remote_driver.c
+++ b/src/remote/remote_driver.c
@@ -86,11 +86,6 @@
#define VIR_FROM_THIS VIR_FROM_REMOTE
-#ifdef WIN32
-# define pipe(fds) _pipe(fds,4096, _O_BINARY)
-#endif
-
-
static int inside_daemon = 0;
struct remote_thread_call;
--
1.7.3.2
14 years
[libvirt] [PATCH] test: fix commantest under autobuild.sh
by Eric Blake
* tests/commandtest.c (mymain): Kill off any leaked-in fds.
* autobuild.sh: Don't leak fds.
Signed-off-by: Eric Blake <eblake(a)redhat.com>
---
Autobuild failed because it triggered a commandtest failure where
commandtest was too sensitive to the environment. Fix the problem
at both ends - autobuild shouldn't leak, and commandtest should
work even when somebody else leaked.
autobuild.sh | 2 +-
tests/commandtest.c | 6 ++++++
2 files changed, 7 insertions(+), 1 deletions(-)
diff --git a/autobuild.sh b/autobuild.sh
index 8248a59..91e2ab2 100755
--- a/autobuild.sh
+++ b/autobuild.sh
@@ -38,7 +38,7 @@ make install
exec 3>&1
st=$(
exec 4>&1 >&3
- { make check syntax-check 2>&1; echo $? >&4; } | tee "$RESULTS"
+ { make check syntax-check 2>&1 3>&- 4>&-; echo $? >&4; } | tee "$RESULTS"
)
exec 3>&-
test "$st" = 0
diff --git a/tests/commandtest.c b/tests/commandtest.c
index a1bcf68..333dd4d 100644
--- a/tests/commandtest.c
+++ b/tests/commandtest.c
@@ -688,6 +688,12 @@ mymain(int argc, char **argv)
if (chdir("/tmp") < 0)
return(EXIT_FAILURE);
+ /* Kill off any inherited fds that might interfere with our
+ * testing. */
+ close(3);
+ close(4);
+ close(5);
+
virInitialize();
const char *const newenv[] = {
--
1.7.3.2
14 years