diff --git a/ChangeLog b/ChangeLog index c18f24c0aa..db24736d68 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +Mon Feb 26 15:31:23 IST 2007 Mark McLoughlin + + * qemud/uuid.[ch]: add uuid generation code + + * qemud/Makefile.am: build it + + * qemud/conf.c: generate a UUID if not specified in the XML + Mon Feb 26 15:20:56 IST 2007 Mark McLoughlin * qemud/conf.c: qemudAutostartConfigs(): print the detailed diff --git a/qemud/Makefile.am b/qemud/Makefile.am index 1a273363c0..e12dae7e0c 100644 --- a/qemud/Makefile.am +++ b/qemud/Makefile.am @@ -9,7 +9,8 @@ libvirt_qemud_SOURCES = qemud.c internal.h protocol.h \ dispatch.c dispatch.h \ conf.c conf.h \ bridge.c bridge.h \ - iptables.c iptables.h + iptables.c iptables.h \ + uuid.c uuid.h #-D_XOPEN_SOURCE=600 -D_XOPEN_SOURCE_EXTENDED=1 -D_POSIX_C_SOURCE=199506L libvirt_qemud_CFLAGS = \ -I$(top_srcdir)/include -I$(top_builddir)/include $(LIBXML_CFLAGS) \ diff --git a/qemud/conf.c b/qemud/conf.c index bd22d2551a..64be113079 100644 --- a/qemud/conf.c +++ b/qemud/conf.c @@ -45,6 +45,7 @@ #include "conf.h" #include "driver.h" #include "iptables.h" +#include "uuid.h" static int qemudParseUUID(const char *uuid, unsigned char *rawuuid) { @@ -689,11 +690,13 @@ static struct qemud_vm_def *qemudParseXML(struct qemud_server *server, obj = xmlXPathEval(BAD_CAST "string(/domain/uuid[1])", ctxt); if ((obj == NULL) || (obj->type != XPATH_STRING) || (obj->stringval == NULL) || (obj->stringval[0] == 0)) { - /* XXX auto-generate a UUID */ - qemudReportError(server, VIR_ERR_INTERNAL_ERROR, "%s", "missing uuid element"); - goto error; - } - if (qemudParseUUID((const char *)obj->stringval, def->uuid) < 0) { + int err; + if ((err = qemudGenerateUUID(def->uuid))) { + qemudReportError(server, VIR_ERR_INTERNAL_ERROR, + "Failed to generate UUID: %s", strerror(err)); + goto error; + } + } else if (qemudParseUUID((const char *)obj->stringval, def->uuid) < 0) { qemudReportError(server, VIR_ERR_INTERNAL_ERROR, "%s", "malformed uuid element"); goto error; } @@ -1650,11 +1653,13 @@ static struct qemud_network_def *qemudParseNetworkXML(struct qemud_server *serve obj = xmlXPathEval(BAD_CAST "string(/network/uuid[1])", ctxt); if ((obj == NULL) || (obj->type != XPATH_STRING) || (obj->stringval == NULL) || (obj->stringval[0] == 0)) { - /* XXX auto-generate a UUID */ - qemudReportError(server, VIR_ERR_INTERNAL_ERROR, "%s", "missing uuid element"); - goto error; - } - if (qemudParseUUID((const char *)obj->stringval, def->uuid) < 0) { + int err; + if ((err = qemudGenerateUUID(def->uuid))) { + qemudReportError(server, VIR_ERR_INTERNAL_ERROR, + "Failed to generate UUID: %s", strerror(err)); + goto error; + } + } else if (qemudParseUUID((const char *)obj->stringval, def->uuid) < 0) { qemudReportError(server, VIR_ERR_INTERNAL_ERROR, "%s", "malformed uuid element"); goto error; } diff --git a/qemud/uuid.c b/qemud/uuid.c new file mode 100644 index 0000000000..349a86abfc --- /dev/null +++ b/qemud/uuid.c @@ -0,0 +1,100 @@ +/* + * Copyright (C) 2007 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Authors: + * Mark McLoughlin + */ + +#include "config.h" + +#include "uuid.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "protocol.h" +#include "internal.h" + +static int +qemudGenerateRandomBytes(unsigned char *buf, + int buflen) +{ + int fd; + + if ((fd = open("/dev/urandom", O_RDONLY)) < 0) + return errno; + + while (buflen > 0) { + int n; + + if ((n = read(fd, buf, buflen)) <= 0) { + if (errno == EINTR) + continue; + close(fd); + return n < 0 ? errno : ENODATA; + } + + buf += n; + buflen -= n; + } + + close(fd); + + return 0; +} + +static int +qemudGeneratePseudoRandomBytes(unsigned char *buf, + int buflen) +{ + srand(time(NULL)); + while (buflen > 0) { + *buf = (int) (255.0 * (rand() / (double) RAND_MAX)); + buflen--; + } + + return 0; +} + +int +qemudGenerateUUID(unsigned char *uuid) +{ + int err; + + if ((err = qemudGenerateRandomBytes(uuid, QEMUD_UUID_RAW_LEN))) + qemudLog(QEMUD_WARN, + "Falling back to pseudorandom UUID, " + "failed to generate random bytes: %s", strerror(err)); + + return qemudGeneratePseudoRandomBytes(uuid, QEMUD_UUID_RAW_LEN); +} + +/* + * Local variables: + * indent-tabs-mode: nil + * c-indent-level: 4 + * c-basic-offset: 4 + * tab-width: 4 + * End: + */ + diff --git a/qemud/uuid.h b/qemud/uuid.h new file mode 100644 index 0000000000..a299388184 --- /dev/null +++ b/qemud/uuid.h @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2007 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Authors: + * Mark McLoughlin + */ + +#ifndef __QEMUD_UUID_H__ +#define __QEMUD_UUID_H__ + +int qemudGenerateUUID(unsigned char *uuid); + +#endif /* __QEMUD_UUID_H__ */