On 04/02/2010 09:25 AM, Matthias Bolte wrote: > 2010/4/2 Chris Lalancette <clalance@xxxxxxxxxx>: >> Signed-off-by: Chris Lalancette <clalance@xxxxxxxxxx> >> --- >> src/conf/domain_conf.c | 402 ++++++++++++++++++++++++++++++++++++++++++++-- >> src/conf/domain_conf.h | 53 ++++++ >> src/libvirt_private.syms | 10 ++ >> 3 files changed, 455 insertions(+), 10 deletions(-) >> >> diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c >> index e260dce..1971b9a 100644 >> --- a/src/conf/domain_conf.c >> +++ b/src/conf/domain_conf.c > > >> @@ -6096,22 +6101,25 @@ static virDomainObjPtr virDomainLoadConfig(virCapsPtr caps, >> >> if ((configFile = virDomainConfigFile(configDir, name)) == NULL) >> goto error; >> - if ((autostartLink = virDomainConfigFile(autostartDir, name)) == NULL) >> - goto error; >> - >> - if ((autostart = virFileLinkPointsTo(autostartLink, configFile)) < 0) >> - goto error; >> - >> if (!(def = virDomainDefParseFile(caps, configFile, >> VIR_DOMAIN_XML_INACTIVE))) >> goto error; >> >> - if ((dom = virDomainFindByName(doms, def->name))) { >> - virDomainObjUnlock(dom); >> - dom = NULL; >> - newVM = 0; >> + /* if the domain is already in our hashtable, we don't need to do >> + * anything further >> + */ >> + if ((dom = virDomainFindByUUID(doms, def->uuid))) { >> + VIR_FREE(configFile); >> + virDomainDefFree(def); >> + return dom; >> } >> >> + if ((autostartLink = virDomainConfigFile(autostartDir, name)) == NULL) >> + goto error; >> + >> + if ((autostart = virFileLinkPointsTo(autostartLink, configFile)) < 0) >> + goto error; >> + >> if (!(dom = virDomainAssignDef(caps, doms, def, false))) >> goto error; > > What's the reason for this reordering? It seems to be independent from > snapshots. Maybe it should go into a separate patch? Oops, yeah, I forgot to split that out. It's either a feature of def/newDef that I don't understand, or it's a bugfix. That being said, I'm not sure I even need this bugfix anymore, so I'll retest and split it into a separate patch if I still need it. > >> +virDomainSnapshotDefPtr virDomainSnapshotDefParseString(const char *xmlStr, >> + int newSnapshot) >> +{ >> + xmlXPathContextPtr ctxt = NULL; >> + xmlDocPtr xml = NULL; >> + xmlNodePtr root; >> + virDomainSnapshotDefPtr def = NULL; >> + virDomainSnapshotDefPtr ret = NULL; >> + char *creation = NULL, *state = NULL; >> + struct timeval tv; >> + struct tm time_info; >> + char timestr[100]; >> + >> + xml = virXMLParse(NULL, xmlStr, "domainsnapshot.xml"); >> + if (!xml) { >> + virDomainReportError(VIR_ERR_XML_ERROR, >> + "%s",_("failed to parse snapshot xml document")); >> + return NULL; >> + } >> + >> + if ((root = xmlDocGetRootElement(xml)) == NULL) { >> + virDomainReportError(VIR_ERR_INTERNAL_ERROR, >> + "%s", _("missing root element")); >> + goto cleanup; >> + } >> + >> + if (!xmlStrEqual(root->name, BAD_CAST "domainsnapshot")) { >> + virDomainReportError(VIR_ERR_INTERNAL_ERROR, >> + "%s", _("incorrect root element")); >> + goto cleanup; >> + } >> + >> + ctxt = xmlXPathNewContext(xml); >> + if (ctxt == NULL) { >> + virReportOOMError(); >> + goto cleanup; >> + } >> + >> + if (VIR_ALLOC(def) < 0) { >> + virReportOOMError(); >> + goto cleanup; >> + } >> + >> + ctxt->node = root; >> + >> + def->name = virXPathString("string(./name)", ctxt); >> + if (def->name == NULL) { >> + /* make up a name */ >> + gettimeofday(&tv, NULL); >> + localtime_r(&tv.tv_sec, &time_info); >> + strftime(timestr, sizeof(timestr), "%F_%T", &time_info); >> + def->name = strdup(timestr); >> + } >> + if (def->name == NULL) { >> + virReportOOMError(); >> + goto cleanup; >> + } >> + >> + def->description = virXPathString("string(./description)", ctxt); >> + >> + if (!newSnapshot) { >> + creation = virXPathString("string(./creationTime)", ctxt); > > I think it should be creationtime or creation_time, but not creationTime. Taking the domain XML as an example, all 3 styles are used (e.g. currentMemory, on_poweroff, and seclabel). I don't really care too much, so I'll do whatever is more comfortable. <snip> >> +char *virDomainSnapshotDefFormat(char *domain_uuid, >> + virDomainSnapshotDefPtr def) >> +{ >> + virBuffer buf = VIR_BUFFER_INITIALIZER; >> + char timestr[100]; >> + struct tm time_info; >> + >> + virBufferAddLit(&buf, "<domainsnapshot>\n"); >> + virBufferVSprintf(&buf, " <name>%s</name>\n", def->name); >> + if (def->description) >> + virBufferVSprintf(&buf, " <description>%s</description>\n", >> + def->description); >> + virBufferVSprintf(&buf, " <state>%s</state>\n", >> + virDomainStateTypeToString(def->state)); >> + if (def->parent) { >> + virBufferAddLit(&buf, " <parent>\n"); >> + virBufferVSprintf(&buf, " <name>%s</name>\n", def->parent); >> + virBufferAddLit(&buf, " </parent>\n"); >> + } >> + localtime_r(&def->creationTime, &time_info); >> + strftime(timestr, sizeof(timestr), "%F_%T", &time_info); > > Again, you handle the time in local time. You could use %F_%T%z to > include the local time zone and then handle that in the parsing > function to get a correct UTC time back. > > Maybe a better solution is to just store the Unix time in seconds in > UTC (as returned by the time() function) in the XML and let > applications do the conversion into a more human readable format and > take care of timezone stuff. This way we get rid of the timezone > problem at the libvirt level at all. Well, I was sort of shooting for that by defining the field to be UTC (which I obviously mis-implemented with localtime_r). It would be nice to have a human-readable string in the XML, though, which is why I didn't just use seconds since the Epoch. Can I just use gmtime_r() here to get the time in UTC, and then strptime and mktime above will do the right thing? -- Chris Lalancette -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list