From f88af9dc16cf891f88bb925885bdf5e328cf44df Mon Sep 17 00:00:00 2001 From: "Daniel P. Berrange" Date: Wed, 18 May 2011 11:33:17 -0400 Subject: [PATCH] Perform feature flag compat checking in QEMU migration cookies To allow new mandatory migration cookie data to be introduced, add support for checking supported feature flags when parsing migration cookie. * src/qemu/qemu_migration.c: Feature flag checking in migration cookie parsing --- .gnulib | 2 +- src/qemu/qemu_migration.c | 56 ++++++++++++++++++++++++++++++++++++++- 2 files changed, 56 insertions(+), 2 deletions(-) diff --git a/.gnulib b/.gnulib index 2c25c9ebe8..64a5e38bce 160000 --- a/.gnulib +++ b/.gnulib @@ -1 +1 @@ -Subproject commit 2c25c9ebe8db1415bfde25f0a451767332c8cf59 +Subproject commit 64a5e38bced6c8f5117efbed95cdfd8ca133ed54 diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c index 4d7bc38c4c..cc9f6fb4a4 100644 --- a/src/qemu/qemu_migration.c +++ b/src/qemu/qemu_migration.c @@ -48,7 +48,18 @@ #define timeval_to_ms(tv) (((tv).tv_sec * 1000ull) + ((tv).tv_usec / 1000)) enum qemuMigrationCookieFlags { - QEMU_MIGRATION_COOKIE_GRAPHICS = (1 << 0), + QEMU_MIGRATION_COOKIE_FLAG_GRAPHICS, + + QEMU_MIGRATION_COOKIE_FLAG_LAST +}; + +VIR_ENUM_DECL(qemuMigrationCookieFlag); +VIR_ENUM_IMPL(qemuMigrationCookieFlag, + QEMU_MIGRATION_COOKIE_FLAG_LAST, + "graphics"); + +enum qemuMigrationCookieFeatures { + QEMU_MIGRATION_COOKIE_GRAPHICS = (1 << QEMU_MIGRATION_COOKIE_FLAG_GRAPHICS), }; typedef struct _qemuMigrationCookieGraphics qemuMigrationCookieGraphics; @@ -65,6 +76,7 @@ typedef struct _qemuMigrationCookie qemuMigrationCookie; typedef qemuMigrationCookie *qemuMigrationCookiePtr; struct _qemuMigrationCookie { int flags; + int flagsMandatory; /* Host properties */ unsigned char hostuuid[VIR_UUID_BUFLEN]; @@ -286,6 +298,7 @@ static void qemuMigrationCookieXMLFormat(virBufferPtr buf, { char uuidstr[VIR_UUID_STRING_BUFLEN]; char hostuuidstr[VIR_UUID_STRING_BUFLEN]; + int i; virUUIDFormat(mig->uuid, uuidstr); virUUIDFormat(mig->hostuuid, hostuuidstr); @@ -296,6 +309,12 @@ static void qemuMigrationCookieXMLFormat(virBufferPtr buf, virBufferEscapeString(buf, " %s\n", mig->hostname); virBufferAsprintf(buf, " %s\n", hostuuidstr); + for (i = 0 ; i < QEMU_MIGRATION_COOKIE_FLAG_LAST ; i++) { + if (mig->flagsMandatory & (1 << i)) + virBufferAsprintf(buf, " \n", + qemuMigrationCookieFlagTypeToString(i)); + } + if ((mig->flags & QEMU_MIGRATION_COOKIE_GRAPHICS) && mig->graphics) qemuMigrationCookieGraphicsXMLFormat(buf, mig->graphics); @@ -377,6 +396,8 @@ qemuMigrationCookieXMLParse(qemuMigrationCookiePtr mig, { char uuidstr[VIR_UUID_STRING_BUFLEN]; char *tmp; + xmlNodePtr *nodes = NULL; + int i, n; /* We don't store the uuid, name, hostname, or hostuuid * values. We just compare them to local data to do some @@ -440,6 +461,38 @@ qemuMigrationCookieXMLParse(qemuMigrationCookiePtr mig, } VIR_FREE(tmp); + /* Check to ensure all mandatory features from XML are also + * present in 'flags' */ + if ((n = virXPathNodeSet("./features", ctxt, &nodes)) < 0) + goto error; + + for (i = 0 ; i < n ; i++) { + int val; + char *str = virXMLPropString(nodes[i], "name"); + if (!str) { + qemuReportError(VIR_ERR_INTERNAL_ERROR, + "%s", _("missing feature name")); + goto error; + } + + if ((val = qemuMigrationCookieFlagTypeFromString(str)) < 0) { + qemuReportError(VIR_ERR_INTERNAL_ERROR, + _("Unknown migration cookie feature %s"), + str); + VIR_FREE(str); + goto error; + } + + if ((flags & (1 << val)) == 0) { + qemuReportError(VIR_ERR_INTERNAL_ERROR, + _("Unsupported migration cookie feature %s"), + str); + VIR_FREE(str); + } + VIR_FREE(str); + } + VIR_FREE(nodes); + if ((flags & QEMU_MIGRATION_COOKIE_GRAPHICS) && virXPathBoolean("count(./graphics) > 0", ctxt) && (!(mig->graphics = qemuMigrationCookieGraphicsXMLParse(ctxt)))) @@ -449,6 +502,7 @@ qemuMigrationCookieXMLParse(qemuMigrationCookiePtr mig, error: VIR_FREE(tmp); + VIR_FREE(nodes); return -1; }