[Libvir] [PATCH] Add bus attribute to disk target definition
by Soren Hansen
Hi!
I'd like to propose that the following patch gets applied against
libvirt. It adds the option of putting a bus attribute on a disk target.
To acommodate this, it also changes the way drives are defined for kvm
from the old "-hda /path/to/file -boot c" style to the new "-drive
file=/path/to/file,if=ide,boot=on". This makes it possible to specify
virtio, scsi, and ide disks.
=== modified file 'src/qemu_conf.c'
--- src/qemu_conf.c 2008-04-28 15:14:59 +0000
+++ src/qemu_conf.c 2008-04-29 07:43:11 +0000
@@ -568,6 +568,7 @@
xmlChar *source = NULL;
xmlChar *target = NULL;
xmlChar *type = NULL;
+ xmlChar *bus = NULL;
int typ = 0;
type = xmlGetProp(node, BAD_CAST "type");
@@ -598,6 +599,7 @@
} else if ((target == NULL) &&
(xmlStrEqual(cur->name, BAD_CAST "target"))) {
target = xmlGetProp(cur, BAD_CAST "dev");
+ bus = xmlGetProp(cur, BAD_CAST "bus");
} else if (xmlStrEqual(cur->name, BAD_CAST "readonly")) {
disk->readonly = 1;
}
@@ -646,7 +648,9 @@
strcmp((const char *)target, "hda") &&
strcmp((const char *)target, "hdb") &&
strcmp((const char *)target, "hdc") &&
- strcmp((const char *)target, "hdd")) {
+ strcmp((const char *)target, "hdd") &&
+ strcmp((const char *)target, "hdd") &&
+ strncmp((const char *)target, "vd", 2)) {
qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
_("Invalid harddisk device name: %s"), target);
goto error;
@@ -673,6 +677,20 @@
goto error;
}
+ if (!bus)
+ disk->bus = QEMUD_DISK_BUS_IDE;
+ else if (!strcmp((const char *)bus, "ide"))
+ disk->bus = QEMUD_DISK_BUS_IDE;
+ else if (!strcmp((const char *)bus, "scsi"))
+ disk->bus = QEMUD_DISK_BUS_SCSI;
+ else if (!strcmp((const char *)bus, "virtio"))
+ disk->bus = QEMUD_DISK_BUS_VIRTIO;
+ else {
+ qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR, "Invalid bus type: %s", bus);
+ goto error;
+ }
+
+ xmlFree(bus);
xmlFree(device);
xmlFree(target);
xmlFree(source);
@@ -688,6 +706,8 @@
xmlFree(source);
if (device)
xmlFree(device);
+ if (bus)
+ xmlFree(bus);
return -1;
}
@@ -1350,6 +1370,68 @@
return -1;
}
+static int qemudDiskCompare(const void *aptr, const void *bptr) {
+ struct qemud_vm_disk_def *a = (struct qemud_vm_disk_def *) aptr;
+ struct qemud_vm_disk_def *b = (struct qemud_vm_disk_def *) bptr;
+ if (a->device == b->device)
+ return virDiskNameToIndex(a->dst) - virDiskNameToIndex(b->dst);
+ else
+ return a->device - b->device;
+}
+
+static const char *qemudBusIdToName(int busId) {
+ const char *busnames[] = { "ide",
+ "scsi",
+ "virtio" };
+
+ if (busId >= 0 && busId < 3)
+ return busnames[busId];
+ else
+ return 0;
+}
+
+static char *qemudDriveOpt(struct qemud_vm_disk_def *disk, int boot)
+{
+ char opt[PATH_MAX];
+
+ switch (disk->device) {
+ case QEMUD_DISK_CDROM:
+ snprintf(opt, PATH_MAX, "file=%s,if=ide,media=cdrom%s",
+ disk->src, boot ? ",boot=on" : "");
+ break;
+ case QEMUD_DISK_FLOPPY:
+ snprintf(opt, PATH_MAX, "file=%s,if=floppy%s",
+ disk->src, boot ? ",boot=on" : "");
+ break;
+ case QEMUD_DISK_DISK:
+ snprintf(opt, PATH_MAX, "file=%s,if=%s%s",
+ disk->src, qemudBusIdToName(disk->bus), boot ? ",boot=on" : "");
+ break;
+ default:
+ return 0;
+ }
+ return strdup(opt);
+}
+
+static char *qemudAddBootDrive(virConnectPtr conn,
+ struct qemud_vm_def *def,
+ char *handledDisks,
+ int type) {
+ int j = 0;
+ struct qemud_vm_disk_def *disk = def->disks;
+
+ while (disk) {
+ if (!handledDisks[j] && disk->device == type) {
+ handledDisks[j] = 1;
+ return qemudDriveOpt(disk, 1);
+ }
+ j++;
+ disk = disk->next;
+ }
+ qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
+ "Requested boot device type %d, but no such device defined.", type);
+ return 0;
+}
/*
* Parses a libvirt XML definition of a guest, and populates the
@@ -1739,7 +1821,6 @@
obj = xmlXPathEval(BAD_CAST "/domain/devices/disk", ctxt);
if ((obj != NULL) && (obj->type == XPATH_NODESET) &&
(obj->nodesetval != NULL) && (obj->nodesetval->nodeNr >= 0)) {
- struct qemud_vm_disk_def *prev = NULL;
for (i = 0; i < obj->nodesetval->nodeNr; i++) {
struct qemud_vm_disk_def *disk = calloc(1, sizeof(*disk));
if (!disk) {
@@ -1752,13 +1833,20 @@
goto error;
}
def->ndisks++;
- disk->next = NULL;
if (i == 0) {
+ disk->next = NULL;
def->disks = disk;
} else {
- prev->next = disk;
+ struct qemud_vm_disk_def *ptr = def->disks;
+ while (ptr) {
+ if (!ptr->next || qemudDiskCompare(ptr->next, disk) < 0) {
+ disk->next = ptr->next;
+ ptr->next = disk;
+ break;
+ }
+ ptr = ptr->next;
+ }
}
- prev = disk;
}
}
xmlXPathFreeObject(obj);
@@ -2207,30 +2295,32 @@
goto no_memory;
}
- for (i = 0 ; i < vm->def->os.nBootDevs ; i++) {
- switch (vm->def->os.bootDevs[i]) {
- case QEMUD_BOOT_CDROM:
- boot[i] = 'd';
- break;
- case QEMUD_BOOT_FLOPPY:
- boot[i] = 'a';
- break;
- case QEMUD_BOOT_DISK:
- boot[i] = 'c';
- break;
- case QEMUD_BOOT_NET:
- boot[i] = 'n';
- break;
- default:
- boot[i] = 'c';
- break;
+ if (vm->def->virtType != QEMUD_VIRT_KVM) {
+ for (i = 0 ; i < vm->def->os.nBootDevs ; i++) {
+ switch (vm->def->os.bootDevs[i]) {
+ case QEMUD_BOOT_CDROM:
+ boot[i] = 'd';
+ break;
+ case QEMUD_BOOT_FLOPPY:
+ boot[i] = 'a';
+ break;
+ case QEMUD_BOOT_DISK:
+ boot[i] = 'c';
+ break;
+ case QEMUD_BOOT_NET:
+ boot[i] = 'n';
+ break;
+ default:
+ boot[i] = 'c';
+ break;
+ }
}
+ boot[vm->def->os.nBootDevs] = '\0';
+ if (!((*argv)[++n] = strdup("-boot")))
+ goto no_memory;
+ if (!((*argv)[++n] = strdup(boot)))
+ goto no_memory;
}
- boot[vm->def->os.nBootDevs] = '\0';
- if (!((*argv)[++n] = strdup("-boot")))
- goto no_memory;
- if (!((*argv)[++n] = strdup(boot)))
- goto no_memory;
if (vm->def->os.kernel[0]) {
if (!((*argv)[++n] = strdup("-kernel")))
@@ -2251,28 +2341,74 @@
goto no_memory;
}
- while (disk) {
- char dev[NAME_MAX];
- char file[PATH_MAX];
- if (!strcmp(disk->dst, "hdc") &&
- disk->device == QEMUD_DISK_CDROM) {
- if (disk->src[0])
- snprintf(dev, NAME_MAX, "-%s", "cdrom");
- else {
- /* Don't put anything on the cmdline for an empty cdrom*/
- disk = disk->next;
- continue;
- }
- } else
- snprintf(dev, NAME_MAX, "-%s", disk->dst);
- snprintf(file, PATH_MAX, "%s", disk->src);
-
- if (!((*argv)[++n] = strdup(dev)))
- goto no_memory;
- if (!((*argv)[++n] = strdup(file)))
- goto no_memory;
-
- disk = disk->next;
+ if (vm->def->virtType == QEMUD_VIRT_KVM) {
+ char *handledDisks = NULL;
+ int j;
+
+ handledDisks = calloc(sizeof(*handledDisks), vm->def->ndisks);
+
+ if (!handledDisks)
+ goto no_memory;
+
+ /* When using -drive notation, we need to provide the devices in boot
+ * preference order. */
+ for (i = 0 ; i < vm->def->os.nBootDevs ; i++) {
+ if (!((*argv)[++n] = strdup("-drive")))
+ goto no_memory;
+
+ switch (vm->def->os.bootDevs[i]) {
+ case QEMUD_BOOT_CDROM:
+ if (!((*argv)[++n] = qemudAddBootDrive(conn, vm->def, handledDisks, QEMUD_DISK_CDROM)))
+ goto error;
+ break;
+ case QEMUD_BOOT_FLOPPY:
+ if (!((*argv)[++n] = qemudAddBootDrive(conn, vm->def, handledDisks, QEMUD_DISK_FLOPPY)))
+ goto error;
+ break;
+ case QEMUD_BOOT_DISK:
+ if (!((*argv)[++n] = qemudAddBootDrive(conn, vm->def, handledDisks, QEMUD_DISK_DISK)))
+ goto error;
+ break;
+ }
+ }
+
+ /* Pick up the rest of the devices */
+ j=0;
+ while (disk) {
+ if (!handledDisks[j]) {
+ handledDisks[j] = 1;
+ if (!((*argv)[++n] = strdup("-drive")))
+ goto no_memory;
+ if (!((*argv)[++n] = qemudDriveOpt(disk, 0)))
+ goto no_memory;
+ }
+ disk = disk->next;
+ j++;
+ }
+ } else {
+ while (disk) {
+ char dev[NAME_MAX];
+ char file[PATH_MAX];
+
+ if (!strcmp(disk->dst, "hdc") &&
+ disk->device == QEMUD_DISK_CDROM)
+ if (disk->src[0])
+ snprintf(dev, NAME_MAX, "-%s", "cdrom");
+ else {
+ disk = disk->next;
+ continue;
+ }
+ else
+ snprintf(dev, NAME_MAX, "-%s", disk->dst);
+ snprintf(file, PATH_MAX, "%s", disk->src);
+
+ if (!((*argv)[++n] = strdup(dev)))
+ goto no_memory;
+ if (!((*argv)[++n] = strdup(file)))
+ goto no_memory;
+
+ disk = disk->next;
+ }
}
if (!net) {
@@ -3565,6 +3701,7 @@
virBufferVSprintf(&buf, " <source %s='%s'/>\n",
typeAttrs[disk->type], disk->src);
+ virBufferVSprintf(&buf, " <target dev='%s' bus='%s'/>\n", disk->dst, qemudBusIdToName(disk->bus));
virBufferVSprintf(&buf, " <target dev='%s'/>\n", disk->dst);
if (disk->readonly)
=== modified file 'src/qemu_conf.h'
--- src/qemu_conf.h 2008-04-25 20:46:13 +0000
+++ src/qemu_conf.h 2008-04-29 07:13:16 +0000
@@ -56,10 +56,17 @@
QEMUD_DISK_FLOPPY,
};
+enum qemud_vm_disk_bus {
+ QEMUD_DISK_BUS_IDE,
+ QEMUD_DISK_BUS_SCSI,
+ QEMUD_DISK_BUS_VIRTIO
+};
+
/* Stores the virtual disk configuration */
struct qemud_vm_disk_def {
int type;
int device;
+ int bus;
char src[PATH_MAX];
char dst[NAME_MAX];
int readonly;
=== modified file 'src/util.c'
--- src/util.c 2008-04-25 14:53:05 +0000
+++ src/util.c 2008-04-29 06:59:49 +0000
@@ -771,3 +771,43 @@
return -1;
}
+
+/* Translates a device name of the form (regex) "[fhv]d[a-z]+" into
+ * the corresponding index (e.g. sda => 1, hdz => 26, vdaa => 27)
+ * @param name The name of the device
+ * @return name's index, or 0 on failure
+ */
+int virDiskNameToIndex(const char *name) {
+ const char *ptr = NULL;
+ int idx = 0;
+
+ if (strlen(name) < 3)
+ return 0;
+
+ switch (*name) {
+ case 'f':
+ case 'h':
+ case 'v':
+ break;
+ default:
+ return 0;
+ }
+
+ if (*(name + 1) != 'd')
+ return 0;
+
+ ptr = name+2;
+
+ while (*ptr) {
+ idx = idx * 26;
+
+ if ('a' > *ptr || 'z' < *ptr)
+ return 0;
+
+ idx += *ptr - 'a' + 1;
+ ptr++;
+ }
+
+ return idx;
+}
+
=== modified file 'src/util.h'
--- src/util.h 2008-04-25 14:53:05 +0000
+++ src/util.h 2008-04-29 06:59:57 +0000
@@ -92,4 +92,6 @@
int virParseMacAddr(const char* str, unsigned char *addr);
+int virDiskNameToIndex(const char* str);
+
#endif /* __VIR_UTIL_H__ */
--
Soren Hansen |
Virtualisation specialist | Ubuntu Server Team
Canonical Ltd. | http://www.ubuntu.com/
16 years, 3 months
[libvirt] [PATCH] Return VIR_ERR_NO_SUPPORT in qemu SetMemory()/SetVcpus() if domain is active.
by Kaitlin Rupert
qemu doesn't support setting the memory or vcpus of an active guest. In
this case, use the VIR_ERR_NO_SUPPORT return code to indicate that the
action failed because its not supported.
Index: src/qemu_driver.c
===================================================================
RCS file: /data/cvs/libvirt/src/qemu_driver.c,v
retrieving revision 1.85
diff -u -p -r1.85 qemu_driver.c
--- src/qemu_driver.c 10 Jun 2008 10:43:28 -0000 1.85
+++ src/qemu_driver.c 11 Jun 2008 20:35:09 -0000
@@ -2148,7 +2148,7 @@ static int qemudDomainSetMemory(virDomai
}
if (qemudIsActiveVM(vm)) {
- qemudReportError(dom->conn, dom, NULL, VIR_ERR_INTERNAL_ERROR,
+ qemudReportError(dom->conn, dom, NULL, VIR_ERR_NO_SUPPORT,
"%s", _("cannot set memory of an active
domain"));
return -1;
}
@@ -2404,7 +2404,7 @@ static int qemudDomainSetVcpus(virDomain
}
if (qemudIsActiveVM(vm)) {
- qemudReportError(dom->conn, dom, NULL, VIR_ERR_INTERNAL_ERROR,
"%s",
+ qemudReportError(dom->conn, dom, NULL, VIR_ERR_NO_SUPPORT, "%s",
_("cannot change vcpu count of an active
domain"));
return -1;
}
--
Kaitlin Rupert
IBM Linux Technology Center
kaitlin(a)linux.vnet.ibm.com
16 years, 4 months
[Libvir] Re: libvirt on mingw
by Richard W.M. Jones
Brecht Sanders wrote:
> Hi,
> I saw on the following link:
> http://www.mail-archive.com/libvir-list@redhat.com/msg04103.html
> that you are also trying to compile libvirt on win32.
> I'm also attempting to do this, and I guess I got stuck at the same
> point your post was about.
> Have you in the mean time found an XDR implementation that compiles on
> MinGW and that implements xdr_u_quad_t?
> If you did, can you please tell me where to find it?
You'll find the answer to this question and more if you look through the
libvir-list archives for the current month:
https://www.redhat.com/archives/libvir-list/2008-January/thread.html
Rich.
--
Emerging Technologies, Red Hat - http://et.redhat.com/~rjones/
Registered Address: Red Hat UK Ltd, Amberley Place, 107-111 Peascod
Street, Windsor, Berkshire, SL4 1TE, United Kingdom. Registered in
England and Wales under Company Registration No. 03798903
16 years, 4 months
[libvirt] PATCH: Generic internal API for network XML parser/formatter
by Daniel P. Berrange
We currently have two drivers which handle the networking XML containing
duplicated parsers and formatters for the XML, and very similar structs.
This patch introduces a new general purpose internal API for parsing and
formatting network XML, and representing it as a series of structs.
This code is derived from the current equivalent code in the QEMU driver
for networks.
The naming conventions I'm adopting in this patch follow those in the
storage driver:
- virNetworkPtr - the public opaque object in libvirt.h
- virNetworkObjPtr - the primary internal object for network state
- virNetworkDefPtr - the configuration data for a network
A virNetworkObjPtr contains a reference to one or two virNetworkDefPtr
objects - the current live config, and potentially a secondary inactive
config which will become live at the next restart.
The structs are defined in network_conf.h, along with a bunch of APIs for
dealing with them. These APIs are the same as similarly named ones from
the current qemu driver, but I'll go over them again for a reminder:
virNetworkObjPtr virNetworkFindByUUID(const virNetworkObjPtr nets,
const unsigned char *uuid);
virNetworkObjPtr virNetworkFindByName(const virNetworkObjPtr nets,
const char *name);
Allow lookup of a virNetworkObjPtr object based on its name or UUID, as
typically obtained from the public virNetworkPtr object.
The 'nets' parameter to both of thse is a linked list of networks which
are currently known to the driver using this API.
void virNetworkDefFree(virNetworkDefPtr def);
void virNetworkObjFree(virNetworkObjPtr net);
Convenience APIs to totally free the memory associated with these
objects.
virNetworkObjPtr virNetworkAssignDef(virConnectPtr conn,
virNetworkObjPtr *nets,
const virNetworkDefPtr def);
Given a virNetworkDefPtr object, it'll search for a pre-existing
virNetworkObjPtr object with matching config. If one is found, its
config will be updated, otherwise a new object will be allocated.
void virNetworkRemoveInactive(virNetworkObjPtr *nets,
const virNetworkObjPtr net);
Convenience for removing and free'ing a virNetworkObjPtr object in
the current list of active networks.
virNetworkDefPtr virNetworkDefParse(virConnectPtr conn,
const char *xmlStr,
const char *displayName);
Given an XML document describing a network, parses the doc and generates
a virNetworkDefPtr to represent it in memory.
char *virNetworkDefFormat(virConnectPtr conn,
const virNetworkDefPtr def);
Given a virNetworkDefPtr object, generate a XML document describing the
network.
As a mentioned earlier, the impl of these APIs is just copied from the QEMU
driver, but instead of using pre-declared char[PATH_MAX] fields, we allocate
memory for strings as required.
Regards,
Daniel
diff -r a6e5acdd23df src/Makefile.am
--- a/src/Makefile.am Tue Jun 24 15:07:21 2008 +0100
+++ b/src/Makefile.am Tue Jun 24 15:07:23 2008 +0100
@@ -52,6 +52,7 @@
driver.h \
proxy_internal.c proxy_internal.h \
conf.c conf.h \
+ network_conf.c network_conf.h \
xm_internal.c xm_internal.h \
remote_internal.c remote_internal.h \
bridge.c bridge.h \
diff -r a6e5acdd23df src/network_conf.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/network_conf.c Tue Jun 24 15:07:23 2008 +0100
@@ -0,0 +1,467 @@
+/*
+ * network_conf.h: network XML handling
+ *
+ * Copyright (C) 2006-2008 Red Hat, Inc.
+ * Copyright (C) 2006-2008 Daniel P. Berrange
+ *
+ * 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
+ *
+ * Author: Daniel P. Berrange <berrange(a)redhat.com>
+ */
+
+
+
+#include <config.h>
+
+#include <arpa/inet.h>
+
+#include "internal.h"
+
+#include "network_conf.h"
+#include "memory.h"
+#include "xml.h"
+#include "uuid.h"
+#include "util.h"
+#include "buf.h"
+
+VIR_ENUM_DECL(virNetworkForward)
+
+VIR_ENUM_IMPL(virNetworkForward,
+ VIR_NETWORK_FORWARD_LAST,
+ "none", "nat", "route" )
+
+static void virNetworkReportError(virConnectPtr conn,
+ int code, const char *fmt, ...)
+{
+ va_list args;
+ char errorMessage[1024];
+ const char *virerr;
+
+ if (fmt) {
+ va_start(args, fmt);
+ vsnprintf(errorMessage, sizeof(errorMessage)-1, fmt, args);
+ va_end(args);
+ } else {
+ errorMessage[0] = '\0';
+ }
+
+ virerr = __virErrorMsg(code, (errorMessage[0] ? errorMessage : NULL));
+ __virRaiseError(conn, NULL, NULL, VIR_FROM_QEMU, code, VIR_ERR_ERROR,
+ virerr, errorMessage, NULL, -1, -1, virerr, errorMessage);
+}
+
+
+virNetworkObjPtr virNetworkFindByUUID(const virNetworkObjPtr nets,
+ const unsigned char *uuid)
+{
+ virNetworkObjPtr net = nets;
+ while (net) {
+ if (!memcmp(net->def->uuid, uuid, VIR_UUID_BUFLEN))
+ return net;
+ net = net->next;
+ }
+
+ return NULL;
+}
+
+virNetworkObjPtr virNetworkFindByName(const virNetworkObjPtr nets,
+ const char *name)
+{
+ virNetworkObjPtr net = nets;
+ while (net) {
+ if (STREQ(net->def->name, name))
+ return net;
+ net = net->next;
+ }
+
+ return NULL;
+}
+
+
+void virNetworkDefFree(virNetworkDefPtr def)
+{
+ int i;
+
+ if (!def)
+ return;
+
+ VIR_FREE(def->name);
+ VIR_FREE(def->bridge);
+ VIR_FREE(def->forwardDev);
+ VIR_FREE(def->ipAddress);
+ VIR_FREE(def->network);
+ VIR_FREE(def->netmask);
+
+ for (i = 0 ; i < def->nranges && def->ranges ; i++) {
+ VIR_FREE(def->ranges[i].start);
+ VIR_FREE(def->ranges[i].end);
+ }
+ VIR_FREE(def->ranges);
+
+ VIR_FREE(def);
+}
+
+void virNetworkObjFree(virNetworkObjPtr net)
+{
+ if (!net)
+ return;
+
+ virNetworkDefFree(net->def);
+ virNetworkDefFree(net->newDef);
+
+ VIR_FREE(net->configFile);
+ VIR_FREE(net->autostartLink);
+
+ VIR_FREE(net);
+}
+
+virNetworkObjPtr virNetworkAssignDef(virConnectPtr conn,
+ virNetworkObjPtr *nets,
+ const virNetworkDefPtr def)
+{
+ virNetworkObjPtr network;
+
+ if ((network = virNetworkFindByName(*nets, def->name))) {
+ if (!virNetworkIsActive(network)) {
+ virNetworkDefFree(network->def);
+ network->def = def;
+ } else {
+ if (network->newDef)
+ virNetworkDefFree(network->newDef);
+ network->newDef = def;
+ }
+
+ return network;
+ }
+
+ if (VIR_ALLOC(network) < 0) {
+ virNetworkReportError(conn, VIR_ERR_NO_MEMORY, NULL);
+ return NULL;
+ }
+
+ network->def = def;
+ network->next = *nets;
+
+ *nets = network;
+
+ return network;
+
+}
+
+void virNetworkRemoveInactive(virNetworkObjPtr *nets,
+ const virNetworkObjPtr net)
+{
+ virNetworkObjPtr prev = NULL;
+ virNetworkObjPtr curr = *nets;
+
+ while (curr &&
+ curr != net) {
+ prev = curr;
+ curr = curr->next;
+ }
+
+ if (curr) {
+ if (prev)
+ prev->next = curr->next;
+ else
+ *nets = curr->next;
+ }
+
+ virNetworkObjFree(net);
+}
+
+
+static int
+virNetworkDHCPRangeDefParseXML(virConnectPtr conn,
+ virNetworkDefPtr def,
+ xmlNodePtr node) {
+
+ xmlNodePtr cur;
+
+ cur = node->children;
+ while (cur != NULL) {
+ xmlChar *start, *end;
+
+ if (cur->type != XML_ELEMENT_NODE ||
+ !xmlStrEqual(cur->name, BAD_CAST "range")) {
+ cur = cur->next;
+ continue;
+ }
+
+ if (!(start = xmlGetProp(cur, BAD_CAST "start"))) {
+ cur = cur->next;
+ continue;
+ }
+ if (!(end = xmlGetProp(cur, BAD_CAST "end"))) {
+ cur = cur->next;
+ xmlFree(start);
+ continue;
+ }
+
+ if (VIR_REALLOC_N(def->ranges, def->nranges + 1) < 0) {
+ xmlFree(start);
+ xmlFree(end);
+ virNetworkReportError(conn, VIR_ERR_NO_MEMORY, NULL);
+ return -1;
+ }
+ def->ranges[def->nranges].start = (char *)start;
+ def->ranges[def->nranges].end = (char *)end;
+ def->nranges++;
+
+ cur = cur->next;
+ }
+
+ return 0;
+}
+
+static virNetworkDefPtr
+virNetworkDefParseXML(virConnectPtr conn,
+ xmlDocPtr xml)
+{
+ xmlNodePtr root = NULL;
+ xmlXPathContextPtr ctxt = NULL;
+ virNetworkDefPtr def;
+ char *tmp;
+
+ if (VIR_ALLOC(def) < 0) {
+ virNetworkReportError(conn, VIR_ERR_NO_MEMORY, NULL);
+ return NULL;
+ }
+
+ /* Prepare parser / xpath context */
+ root = xmlDocGetRootElement(xml);
+ if ((root == NULL) || (!xmlStrEqual(root->name, BAD_CAST "network"))) {
+ virNetworkReportError(conn, VIR_ERR_INTERNAL_ERROR,
+ "%s", _("incorrect root element"));
+ goto error;
+ }
+
+ ctxt = xmlXPathNewContext(xml);
+ if (ctxt == NULL) {
+ virNetworkReportError(conn, VIR_ERR_NO_MEMORY,
+ "%s", _("failed to allocate space for xmlXPathContext string"));
+ goto error;
+ }
+
+
+ /* Extract network name */
+ def->name = virXPathString("string(/network/name[1])", ctxt);
+ if (!def->name) {
+ virNetworkReportError(conn, VIR_ERR_NO_NAME, NULL);
+ goto error;
+ }
+
+ /* Extract network uuid */
+ tmp = virXPathString("string(/network/uuid[1])", ctxt);
+ if (!tmp) {
+ int err;
+ if ((err = virUUIDGenerate(def->uuid))) {
+ virNetworkReportError(conn, VIR_ERR_INTERNAL_ERROR,
+ _("Failed to generate UUID: %s"), strerror(err));
+ goto error;
+ }
+ } else {
+ if (virUUIDParse(tmp, def->uuid) < 0) {
+ VIR_FREE(tmp);
+ virNetworkReportError(conn, VIR_ERR_INTERNAL_ERROR,
+ "%s", _("malformed uuid element"));
+ goto error;
+ }
+ VIR_FREE(tmp);
+ }
+
+ /* Parse bridge information */
+ def->bridge = virXPathString("string(/network/bridge[1]/@name)", ctxt);
+ tmp = virXPathString("string(/network/bridge[1]/@stp)", ctxt);
+ if (tmp && STREQ(tmp, "off"))
+ def->stp = 0;
+ else
+ def->stp = 1;
+ VIR_FREE(tmp);
+
+ if (virXPathLong("string(/network/bridge[1]/@delay)", ctxt, &def->delay) < 0)
+ def->delay = 0;
+
+ def->ipAddress = virXPathString("string(/network/ip[1]/@address)", ctxt);
+ def->netmask = virXPathString("string(/network/ip[1]/@netmask)", ctxt);
+ if (def->ipAddress &&
+ def->netmask) {
+ /* XXX someday we want IPv6 too, so inet_aton won't work there */
+ struct in_addr inaddress, innetmask;
+ char *netaddr;
+ int netlen;
+ xmlNodePtr dhcp;
+
+ if (!inet_aton(def->ipAddress, &inaddress)) {
+ virNetworkReportError(conn, VIR_ERR_INTERNAL_ERROR,
+ _("cannot parse IP address '%s'"),
+ def->ipAddress);
+ goto error;
+ }
+ if (!inet_aton(def->netmask, &innetmask)) {
+ virNetworkReportError(conn, VIR_ERR_INTERNAL_ERROR,
+ _("cannot parse netmask '%s'"),
+ def->netmask);
+ goto error;
+ }
+
+ inaddress.s_addr &= innetmask.s_addr;
+ netaddr = inet_ntoa(inaddress);
+
+ netlen = strlen(netaddr) + 1 + strlen(def->netmask) + 1;
+ if (VIR_ALLOC_N(def->network, netlen) < 0) {
+ virNetworkReportError(conn, VIR_ERR_NO_MEMORY, NULL);
+ goto error;
+ }
+ strcpy(def->network, netaddr);
+ strcat(def->network, "/");
+ strcat(def->network, def->netmask);
+
+
+ if ((dhcp = virXPathNode("/network/ip[1]/dhcp[1]", ctxt)) &&
+ virNetworkDHCPRangeDefParseXML(conn, def, dhcp) < 0)
+ goto error;
+ }
+
+
+ /* IPv4 forwarding setup */
+ if (virXPathBoolean("count(/network/forward) > 0", ctxt)) {
+ if (!def->ipAddress ||
+ !def->netmask) {
+ virNetworkReportError(conn, VIR_ERR_INTERNAL_ERROR,
+ "%s", _("Forwarding requested, but no IPv4 address/netmask provided"));
+ goto error;
+ }
+
+ tmp = virXPathString("string(/network/forward[1]/@mode)", ctxt);
+ if (tmp) {
+ if ((def->forwardType = virNetworkForwardTypeFromString(tmp)) < 0) {
+ virNetworkReportError(conn, VIR_ERR_INTERNAL_ERROR,
+ _("unknown forwarding type '%s'"), tmp);
+ VIR_FREE(tmp);
+ }
+ VIR_FREE(tmp);
+ } else {
+ def->forwardType = VIR_NETWORK_FORWARD_NAT;
+ }
+
+
+ def->forwardDev = virXPathString("string(/network/forward[1]/@dev)", ctxt);
+ } else {
+ def->forwardType = VIR_NETWORK_FORWARD_NONE;
+ }
+
+ xmlXPathFreeContext(ctxt);
+
+ return def;
+
+ error:
+ xmlXPathFreeContext(ctxt);
+ virNetworkDefFree(def);
+ return NULL;
+}
+
+virNetworkDefPtr virNetworkDefParse(virConnectPtr conn,
+ const char *xmlStr,
+ const char *displayName)
+{
+ xmlDocPtr xml;
+ virNetworkDefPtr def;
+
+ if (!(xml = xmlReadDoc(BAD_CAST xmlStr, displayName ? displayName : "network.xml", NULL,
+ XML_PARSE_NOENT | XML_PARSE_NONET |
+ XML_PARSE_NOERROR | XML_PARSE_NOWARNING))) {
+ virNetworkReportError(conn, VIR_ERR_XML_ERROR, NULL);
+ return NULL;
+ }
+
+ def = virNetworkDefParseXML(conn, xml);
+
+ xmlFreeDoc(xml);
+
+ return def;
+}
+
+char *virNetworkDefFormat(virConnectPtr conn,
+ const virNetworkDefPtr def)
+{
+ virBuffer buf = VIR_BUFFER_INITIALIZER;
+ unsigned char *uuid;
+ char *tmp;
+ char uuidstr[VIR_UUID_STRING_BUFLEN];
+
+ virBufferAddLit(&buf, "<network>\n");
+ virBufferVSprintf(&buf, " <name>%s</name>\n", def->name);
+
+ uuid = def->uuid;
+ virUUIDFormat(uuid, uuidstr);
+ virBufferVSprintf(&buf, " <uuid>%s</uuid>\n", uuidstr);
+
+ if (def->forwardType != VIR_NETWORK_FORWARD_NONE) {
+ const char *mode = virNetworkForwardTypeToString(def->forwardType);
+ if (mode) {
+ if (def->forwardDev) {
+ virBufferVSprintf(&buf, " <forward dev='%s' mode='%s'/>\n",
+ def->forwardDev, mode);
+ } else {
+ virBufferVSprintf(&buf, " <forward mode='%s'/>\n", mode);
+ }
+ }
+ }
+
+ virBufferAddLit(&buf, " <bridge");
+ if (def->bridge)
+ virBufferVSprintf(&buf, " name='%s'", def->bridge);
+ virBufferVSprintf(&buf, " stp='%s' forwardDelay='%ld' />\n",
+ def->stp ? "on" : "off",
+ def->delay);
+
+ if (def->ipAddress || def->netmask) {
+ virBufferAddLit(&buf, " <ip");
+
+ if (def->ipAddress)
+ virBufferVSprintf(&buf, " address='%s'", def->ipAddress);
+
+ if (def->netmask)
+ virBufferVSprintf(&buf, " netmask='%s'", def->netmask);
+
+ virBufferAddLit(&buf, ">\n");
+
+ if (def->nranges) {
+ int i;
+ virBufferAddLit(&buf, " <dhcp>\n");
+ for (i = 0 ; i < def->nranges ; i++)
+ virBufferVSprintf(&buf, " <range start='%s' end='%s' />\n",
+ def->ranges[i].start, def->ranges[i].end);
+ virBufferAddLit(&buf, " </dhcp>\n");
+ }
+
+ virBufferAddLit(&buf, " </ip>\n");
+ }
+
+ virBufferAddLit(&buf, "</network>\n");
+
+ if (virBufferError(&buf))
+ goto no_memory;
+
+ return virBufferContentAndReset(&buf);
+
+ no_memory:
+ virNetworkReportError(conn, VIR_ERR_NO_MEMORY, NULL);
+ tmp = virBufferContentAndReset(&buf);
+ VIR_FREE(tmp);
+ return NULL;
+}
+
diff -r a6e5acdd23df src/network_conf.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/network_conf.h Tue Jun 24 15:07:23 2008 +0100
@@ -0,0 +1,114 @@
+/*
+ * network_conf.h: network XML handling
+ *
+ * Copyright (C) 2006-2008 Red Hat, Inc.
+ * Copyright (C) 2006-2008 Daniel P. Berrange
+ *
+ * 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
+ *
+ * Author: Daniel P. Berrange <berrange(a)redhat.com>
+ */
+
+#ifndef __NETWORK_CONF_H__
+#define __NETWORK_CONF_H__
+
+#include "internal.h"
+
+/* 2 possible types of forwarding */
+enum virNetworkForwardType {
+ VIR_NETWORK_FORWARD_NONE = 0,
+ VIR_NETWORK_FORWARD_NAT,
+ VIR_NETWORK_FORWARD_ROUTE,
+
+ VIR_NETWORK_FORWARD_LAST,
+};
+
+typedef struct _virNetworkDHCPRangeDef virNetworkDHCPRangeDef;
+typedef virNetworkDHCPRangeDef *virNetworkDHCPRangeDefPtr;
+struct _virNetworkDHCPRangeDef {
+ char *start;
+ char *end;
+};
+
+typedef struct _virNetworkDef virNetworkDef;
+typedef virNetworkDef *virNetworkDefPtr;
+struct _virNetworkDef {
+ unsigned char uuid[VIR_UUID_BUFLEN];
+ char *name;
+
+ char *bridge; /* Name of bridge device */
+ int stp : 1; /* Spanning tree protocol */
+ long delay; /* Bridge forward delay (ms) */
+
+ int forwardType; /* One of virNetworkForwardType constants */
+ char *forwardDev; /* Destination device for forwarding */
+
+ char *ipAddress; /* Bridge IP address */
+ char *netmask;
+ char *network;
+
+ int nranges; /* Zero or more dhcp ranges */
+ virNetworkDHCPRangeDefPtr ranges;
+};
+
+typedef struct _virNetworkObj virNetworkObj;
+typedef virNetworkObj *virNetworkObjPtr;
+struct _virNetworkObj {
+ int dnsmasqPid;
+ unsigned int active : 1;
+ unsigned int autostart : 1;
+ unsigned int persistent : 1;
+
+ char *configFile; /* Persistent config file path */
+ char *autostartLink; /* Symlink path for autostart */
+
+ virNetworkDefPtr def; /* The current definition */
+ virNetworkDefPtr newDef; /* New definition to activate at shutdown */
+
+ virNetworkObjPtr next;
+};
+
+static inline int
+virNetworkIsActive(const virNetworkObjPtr net)
+{
+ return net->active;
+}
+
+
+virNetworkObjPtr virNetworkFindByUUID(const virNetworkObjPtr nets,
+ const unsigned char *uuid);
+virNetworkObjPtr virNetworkFindByName(const virNetworkObjPtr nets,
+ const char *name);
+
+
+void virNetworkDefFree(virNetworkDefPtr def);
+void virNetworkObjFree(virNetworkObjPtr net);
+
+virNetworkObjPtr virNetworkAssignDef(virConnectPtr conn,
+ virNetworkObjPtr *nets,
+ const virNetworkDefPtr def);
+void virNetworkRemoveInactive(virNetworkObjPtr *nets,
+ const virNetworkObjPtr net);
+
+virNetworkDefPtr virNetworkDefParse(virConnectPtr conn,
+ const char *xmlStr,
+ const char *displayName);
+
+char *virNetworkDefFormat(virConnectPtr conn,
+ const virNetworkDefPtr def);
+
+
+#endif /* __NETWORK_CONF_H__ */
+
--
|: Red Hat, Engineering, London -o- http://people.redhat.com/berrange/ :|
|: http://libvirt.org -o- http://virt-manager.org -o- http://ovirt.org :|
|: http://autobuild.org -o- http://search.cpan.org/~danberr/ :|
|: GnuPG: 7D3B9505 -o- F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :|
16 years, 4 months
[libvirt] libvirt-java patch
by Tóth István
This patch contains:
-random bugfixes
-gcc -Wall "fixes"
-a few new constants for 4.x
-Implementation of virConnectAuth
-javah build fixes (One .class file can generate many .h files.)
It is NOT a full update for 4.x, the only major new feature is
authentication support.
I've attached the patch, and the new files. (Is there some way to
generate patches with new files?)
Please remove the
/src/jni/org_libvirt_VirDomain_CreateFlags.h
/src/jni/org_libvirt_VirDomain_MigrateFlags.h
files from the CVS, as these are auto-generated.
regards
István
? .project
? src/jni/VirConnectAuthCallbackBridge.c
? src/jni/VirConnectAuthCallbackBridge.h
? src/org/libvirt/VirConnectAuth.java
? src/org/libvirt/VirConnectAuthDefault.java
? src/org/libvirt/VirConnectCredential.java
Index: src/Makefile.am
===================================================================
RCS file: /data/cvs/libvirt-java/src/Makefile.am,v
retrieving revision 1.2
diff -u -p -r1.2 Makefile.am
--- src/Makefile.am 25 Jun 2008 13:02:30 -0000 1.2
+++ src/Makefile.am 29 Jun 2008 17:22:35 -0000
@@ -4,6 +4,9 @@ SUBDIRS=. jni
java_libvirt_source_files = \
org/libvirt/LibvirtException.java \
org/libvirt/VirConnect.java \
+ org/libvirt/VirConnectAuthDefault.java \
+ org/libvirt/VirConnectAuth.java \
+ org/libvirt/VirConnectCredential.java \
org/libvirt/VirDomainBlockStats.java \
org/libvirt/VirDomainInfo.java \
org/libvirt/VirDomainInterfaceStats.java \
Index: src/test.java
===================================================================
RCS file: /data/cvs/libvirt-java/src/test.java,v
retrieving revision 1.1
diff -u -p -r1.1 test.java
--- src/test.java 24 Jun 2008 16:32:24 -0000 1.1
+++ src/test.java 29 Jun 2008 17:22:35 -0000
@@ -16,6 +16,19 @@ public class test {
Integer.decode("0xc3"), Integer.decode("0x0f"),
Integer.decode("0x5a"), Integer.decode("0xa5"),
Integer.decode("0xf0"), Integer.decode("0x3c"), Integer.decode("0x87"), Integer.decode("0xd2"), Integer.decode("0x1e"), Integer.decode("0x69")} ;
+
+ //For testing the authentication
+ VirConnectAuth defaultAuth = new VirConnectAuthDefault();
+
+ //You need to configure your libvirtd for remote/authenticated connections, and adjust the URL below
+ //for this to work. Otherwise, you'll get an error
+ try{
+ conn = new VirConnect("test+tcp://localhost/default", defaultAuth, 0);
+ System.out.println("Encrypted connection successful!");
+ } catch (LibvirtException e){
+ System.out.println("exception caught:"+e);
+ System.out.println(e.getVirError());
+ }
try{
conn = new VirConnect("test:///default", false);
Index: src/jni/Makefile.am
===================================================================
RCS file: /data/cvs/libvirt-java/src/jni/Makefile.am,v
retrieving revision 1.2
diff -u -p -r1.2 Makefile.am
--- src/jni/Makefile.am 25 Jun 2008 13:02:30 -0000 1.2
+++ src/jni/Makefile.am 29 Jun 2008 17:22:35 -0000
@@ -5,12 +5,17 @@ SOURCES = \
org_libvirt_VirConnect.c \
org_libvirt_VirDomain.c \
VirErrorHandler.c \
- VirErrorHandler.h
+ VirErrorHandler.h \
+ VirConnectAuthCallbackBridge.c \
+ VirConnectAuthCallbackBridge.h
GENERATED = \
org_libvirt_VirConnect.h \
org_libvirt_VirNetwork.h \
- org_libvirt_VirDomain.h
+ org_libvirt_VirDomain.h \
+ org_libvirt_VirDomain_CreateFlags.h \
+ org_libvirt_VirDomain_MigrateFlags.h \
+ org_libvirt_VirDomain_XMLFlags.h
BUILT_SOURCES = $(GENERATED)
@@ -20,7 +25,7 @@ org_libvirt_VirConnect.h : $(JAVA_CLASS_
org_libvirt_VirNetwork.h: $(JAVA_CLASS_ROOT)/org/libvirt/VirNetwork.class
$(JAVAH) -classpath $(JAVA_CLASS_ROOT) org.libvirt.VirNetwork
-org_libvirt_VirDomain.h: $(JAVA_CLASS_ROOT)/org/libvirt/VirDomain.class
+org_libvirt_VirDomain.h org_libvirt_VirDomain_CreateFlags.h org_libvirt_VirDomain_MigrateFlags.h org_libvirt_VirDomain_XMLFlags.h : $(JAVA_CLASS_ROOT)/org/libvirt/VirDomain.class
$(JAVAH) -classpath $(JAVA_CLASS_ROOT) org.libvirt.VirDomain
lib_LTLIBRARIES = libvirt_jni.la
@@ -31,4 +36,4 @@ libvirt_jni_la_LDFLAGS = -version-info
CLEANFILES = \
- $(GENERATED)
+ $(GENERATED) $(GENERATED_SUB_1)
Index: src/jni/org_libvirt_VirConnect.c
===================================================================
RCS file: /data/cvs/libvirt-java/src/jni/org_libvirt_VirConnect.c,v
retrieving revision 1.1
diff -u -p -r1.1 org_libvirt_VirConnect.c
--- src/jni/org_libvirt_VirConnect.c 24 Jun 2008 16:32:24 -0000 1.1
+++ src/jni/org_libvirt_VirConnect.c 29 Jun 2008 17:22:35 -0000
@@ -2,14 +2,20 @@
#include <libvirt/libvirt.h>
#include <stdlib.h>
#include "VirErrorHandler.h"
+#include "VirConnectAuthCallbackBridge.h"
+
+#include <assert.h>
+
+//TODO We are leaking UTFChars all over the place. We need to strcpy, then release every string we get from JAVA, and not use them directly!
JNIEXPORT jint JNICALL Java_org_libvirt_VirConnect__1virInitialize
(JNIEnv *env, jclass cls){
int result;
result=virInitialize();
- //The connection-less errors go to the initializing thread as an aexception.
+ //The connection-less errors go to the initializing thread as an exception.
//Not ideal, but better than just dropping the errors.
virSetErrorFunc(env, virErrorHandler);
+ return result;
}
JNIEXPORT void JNICALL Java_org_libvirt_VirConnect__1close
@@ -22,7 +28,7 @@ JNIEXPORT jstring JNICALL Java_org_libvi
//All this gymnastics is so that we can free() the hostname string
jstring j_hostname=NULL;
char *hostname;
- if(hostname = virConnectGetHostname((virConnectPtr)VCP)){
+ if((hostname = virConnectGetHostname((virConnectPtr)VCP))){
j_hostname = (*env)->NewStringUTF(env, hostname);
free(hostname);
}
@@ -33,7 +39,7 @@ JNIEXPORT jstring JNICALL Java_org_libvi
(JNIEnv *env, jobject obj, jlong VCP){
jstring j_capabilities=NULL;
char *capabilities;
- if(capabilities = virConnectGetCapabilities((virConnectPtr)VCP)){
+ if((capabilities = virConnectGetCapabilities((virConnectPtr)VCP))){
j_capabilities = (*env)->NewStringUTF(env, capabilities);
free(capabilities);
}
@@ -49,7 +55,7 @@ JNIEXPORT jstring JNICALL Java_org_libvi
(JNIEnv *env, jobject obj, jlong VCP){
const char *type;
//Here we get a static string, no need to free()
- if(type=virConnectGetType((virConnectPtr)VCP)){
+ if((type=virConnectGetType((virConnectPtr)VCP))){
return (*env)->NewStringUTF(env, type);
} else {
return NULL;
@@ -60,7 +66,7 @@ JNIEXPORT jstring JNICALL Java_org_libvi
(JNIEnv *env, jobject obj, jlong VCP){
jstring j_uri=NULL;
char *uri;
- if(uri = virConnectGetURI((virConnectPtr)VCP)){
+ if((uri = virConnectGetURI((virConnectPtr)VCP))){
j_uri = (*env)->NewStringUTF(env, uri);
free(uri);
}
@@ -150,7 +156,7 @@ JNIEXPORT jlong JNICALL Java_org_libvirt
if(vc==NULL){
virCopyLastError(&error);
virErrorHandler(env, &error);
- return (long)NULL;
+ return (jlong)NULL;
}
//Initialized the error handler for this connection
@@ -170,7 +176,7 @@ JNIEXPORT jlong JNICALL Java_org_libvirt
if(vc==NULL){
virCopyLastError(&error);
virErrorHandler(env, &error);
- return (long)NULL;
+ return (jlong)NULL;
}
//Initialized the error handler for this connection
@@ -179,14 +185,67 @@ JNIEXPORT jlong JNICALL Java_org_libvirt
return (jlong)vc;
};
+JNIEXPORT jlong JNICALL Java_org_libvirt_VirConnect__1openAuth
+ (JNIEnv *env, jobject obj, jstring uri, jobject j_auth, jint flags){
+
+ virConnectPtr vc;
+ virError error;
+
+ virConnectAuth *auth = malloc(sizeof(virConnectAuth));
+
+ jobject j_credTypeElement;
+ int c;
+
+ //Prepare by computing the class and field IDs
+ jfieldID credTypeArray_id = (*env)->GetFieldID(env,
+ (*env)->FindClass(env, "org/libvirt/VirConnectAuth"),
+ "credType",
+ "[Lorg/libvirt/VirConnectCredential$VirConnectCredentialType;");
+ jmethodID credTypeMapToInt_id = (*env)->GetMethodID(env,
+ (*env)->FindClass(env, "org/libvirt/VirConnectCredential$VirConnectCredentialType"),
+ "mapToInt",
+ "()I");
+
+ //Copy the array of credtypes with the helper function
+ jarray j_credTypeArray=(*env)->GetObjectField(env, j_auth, credTypeArray_id);
+ auth->ncredtype = (*env)->GetArrayLength(env, j_credTypeArray);
+
+ auth->credtype = calloc(auth->ncredtype, sizeof(int));
+ for(c=0; c< auth->ncredtype; c++){
+ j_credTypeElement = (*env)->GetObjectArrayElement(env, j_credTypeArray, c);
+ auth->credtype[c]=(*env)->CallIntMethod(env, j_credTypeElement, credTypeMapToInt_id);
+ }
+
+ //The callback function is always VirConnectAuthCallbackBridge
+ auth->cb = &VirConnectAuthCallbackBridge;
+ //We pass the VirConnectAuth object and the JNI env in cdbata
+ CallBackStructType* cb_wrapper;
+ cb_wrapper = malloc(sizeof(CallBackStructType));
+ cb_wrapper->env = env;
+ cb_wrapper->auth = j_auth;
+ auth->cbdata=cb_wrapper;
+
+ vc=virConnectOpenAuth((*env)->GetStringUTFChars(env, uri, NULL), auth, flags);
+ if(vc==NULL){
+ virCopyLastError(&error);
+ virErrorHandler(env, &error);
+ return (jlong)NULL;
+ }
+
+ //Initialize the error handler for this connection
+ virConnSetErrorFunc(vc, env, virErrorHandler);
+
+ return (jlong)vc;
+}
+
JNIEXPORT jlong JNICALL Java_org_libvirt_VirConnect__1virNetworkCreateXML
(JNIEnv *env, jobject obj, jlong VCP, jstring xmlDesc){
- return(jlong)virNetworkCreateXML((virConnectPtr)VCP, (*env)->GetStringUTFChars(env, xmlDesc, NULL));
+ return (jlong)virNetworkCreateXML((virConnectPtr)VCP, (*env)->GetStringUTFChars(env, xmlDesc, NULL));
}
JNIEXPORT jlong JNICALL Java_org_libvirt_VirConnect__1virNetworkDefineXML
(JNIEnv *env, jobject obj, jlong VCP, jstring xmlDesc){
- return(jlong)virNetworkDefineXML((virConnectPtr)VCP, (*env)->GetStringUTFChars(env, xmlDesc, NULL));
+ return (jlong)virNetworkDefineXML((virConnectPtr)VCP, (*env)->GetStringUTFChars(env, xmlDesc, NULL));
}
JNIEXPORT jlong JNICALL Java_org_libvirt_VirConnect__1virNetworkLookupByName
@@ -202,7 +261,6 @@ JNIEXPORT jlong JNICALL Java_org_libvirt
//compact to bytes
for(c=0; c < VIR_UUID_BUFLEN; c++)
UUID[c]=UUID_int[c];
- (*env)->ExceptionDescribe(env);
return (jlong)virNetworkLookupByUUID((virConnectPtr)VCP, UUID);
}
@@ -266,8 +324,8 @@ JNIEXPORT jintArray JNICALL Java_org_lib
(JNIEnv *env, jobject obj, jlong VCP){
int maxids;
int *ids;
- int c;
jintArray j_ids=NULL;
+
if((maxids = virConnectNumOfDomains((virConnectPtr)VCP))<0)
return NULL;
ids= (int*)calloc(maxids, sizeof(int));
@@ -313,7 +371,7 @@ JNIEXPORT jlong JNICALL Java_org_libvirt
JNIEXPORT jlong JNICALL Java_org_libvirt_VirConnect__1virGetHypervisorVersion
(JNIEnv *env, jobject obj, jstring j_type){
- long libVer;
+ unsigned long libVer;
const char *type;
unsigned long typeVer;
Index: src/jni/org_libvirt_VirDomain.c
===================================================================
RCS file: /data/cvs/libvirt-java/src/jni/org_libvirt_VirDomain.c,v
retrieving revision 1.1
diff -u -p -r1.1 org_libvirt_VirDomain.c
--- src/jni/org_libvirt_VirDomain.c 24 Jun 2008 16:32:24 -0000 1.1
+++ src/jni/org_libvirt_VirDomain.c 29 Jun 2008 17:22:36 -0000
@@ -7,7 +7,7 @@ JNIEXPORT jstring JNICALL Java_org_libvi
(JNIEnv *env, jobject obj, jlong VDP, jint flags){
jstring j_xmlDesc;
char* xmlDesc = NULL;
- if(xmlDesc = virDomainGetXMLDesc((virDomainPtr)VDP, flags)){
+ if((xmlDesc = virDomainGetXMLDesc((virDomainPtr)VDP, flags))){
j_xmlDesc = (*env)->NewStringUTF(env, xmlDesc);
free(xmlDesc);
}
@@ -56,7 +56,7 @@ JNIEXPORT jstring JNICALL Java_org_libvi
jstring j_OSType;
char *OSType;
- if(OSType = virDomainGetOSType((virDomainPtr)VDP)){
+ if((OSType = virDomainGetOSType((virDomainPtr)VDP))){
j_OSType = (*env)->NewStringUTF(env, OSType);
free(OSType);
}
@@ -70,7 +70,7 @@ JNIEXPORT jobjectArray JNICALL Java_org_
int nparams;
//We don't return nparams
- if(schedulerType = virDomainGetSchedulerType((virDomainPtr)VDP, &nparams)){
+ if((schedulerType = virDomainGetSchedulerType((virDomainPtr)VDP, &nparams))){
j_schedulerType = (*env)->NewStringUTF(env, schedulerType);
free(schedulerType);
}
@@ -264,7 +264,6 @@ JNIEXPORT jobjectArray JNICALL Java_org_
jobject j_info;
jobjectArray j_infoArray=NULL;
- jobjectArray j_statusArray;
jfieldID number_id;
jfieldID state_id;
@@ -332,7 +331,7 @@ JNIEXPORT jintArray JNICALL Java_org_lib
int *i_cpumaps;
jintArray j_cpumaps;
int c;
- virNodeInfo nodeinfo;
+ virNodeInfoPtr nodeinfo;
virVcpuInfoPtr info;
//Check number of vcpus;
@@ -340,9 +339,9 @@ JNIEXPORT jintArray JNICALL Java_org_lib
return NULL;
//Get maplen
- if(VirNodeGetInfo( virDomainGetConnect( (virDomainPtr)VDP), nodeinfo )<0)
+ if(virNodeGetInfo( virDomainGetConnect( (virDomainPtr)VDP), nodeinfo )<0)
return NULL;
- maplen=VIR_CPU_MAPLEN( VIR_NODEINFO_MAXCPUS( nodeinfo ) );
+ maplen=VIR_CPU_MAPLEN( VIR_NODEINFO_MAXCPUS( *nodeinfo ) );
info=(virVcpuInfoPtr)calloc(maxinfo, sizeof(virVcpuInfo));
cpumaps=malloc(sizeof(int)*maxinfo*maplen);
@@ -368,6 +367,7 @@ JNIEXPORT jint JNICALL Java_org_libvirt_
unsigned char *cpumap;
jint *i_cpumap;
int c;
+ int retval;
//Get maplen
maplen=(*env)->GetArrayLength(env, j_cpumap);
@@ -382,10 +382,11 @@ JNIEXPORT jint JNICALL Java_org_libvirt_
cpumap[c]=i_cpumap[c];
//Call libvirt
- virDomainPinVcpu((virDomainPtr)VDP, vcpu, cpumap, maplen);
+ retval = virDomainPinVcpu((virDomainPtr)VDP, vcpu, cpumap, maplen);
free(cpumap);
free(i_cpumap);
+ return retval;
}
JNIEXPORT jint JNICALL Java_org_libvirt_VirDomain__1setVcpus
Index: src/jni/org_libvirt_VirNetwork.c
===================================================================
RCS file: /data/cvs/libvirt-java/src/jni/org_libvirt_VirNetwork.c,v
retrieving revision 1.1
diff -u -p -r1.1 org_libvirt_VirNetwork.c
--- src/jni/org_libvirt_VirNetwork.c 24 Jun 2008 16:32:24 -0000 1.1
+++ src/jni/org_libvirt_VirNetwork.c 29 Jun 2008 17:22:36 -0000
@@ -1,11 +1,12 @@
#include "org_libvirt_VirNetwork.h"
#include <libvirt/libvirt.h>
+#include <stdlib.h>
JNIEXPORT jstring JNICALL Java_org_libvirt_VirNetwork__1getXMLDesc
(JNIEnv *env, jobject obj, jlong VNP, jint flags){
jstring j_xmlDesc;
char* xmlDesc;
- if(xmlDesc = virNetworkGetXMLDesc((virNetworkPtr)VNP, flags)){
+ if((xmlDesc = virNetworkGetXMLDesc((virNetworkPtr)VNP, flags))){
j_xmlDesc = (*env)->NewStringUTF(env, xmlDesc);
free(xmlDesc);
}
@@ -36,15 +37,15 @@ JNIEXPORT jboolean JNICALL Java_org_libv
JNIEXPORT jint JNICALL Java_org_libvirt_VirNetwork__1setAutostart
(JNIEnv *env, jobject obj, jlong VNP, jboolean autostart){
- virNetworkSetAutostart((virNetworkPtr)VNP, autostart);
+ return virNetworkSetAutostart((virNetworkPtr)VNP, autostart);
}
JNIEXPORT jstring JNICALL Java_org_libvirt_VirNetwork__1getBridgeName
(JNIEnv *env, jobject obj, jlong VNP){
jstring j_bridgeName;
- char *bridgeName;
+ char *bridgeName=NULL;
- if(bridgeName = virNetworkGetBridgeName((virNetworkPtr)VNP)){
+ if((bridgeName = virNetworkGetBridgeName((virNetworkPtr)VNP))){
j_bridgeName = (*env)->NewStringUTF(env, bridgeName);
free(bridgeName);
}
Index: src/org/libvirt/VirConnect.java
===================================================================
RCS file: /data/cvs/libvirt-java/src/org/libvirt/VirConnect.java,v
retrieving revision 1.1
diff -u -p -r1.1 VirConnect.java
--- src/org/libvirt/VirConnect.java 24 Jun 2008 16:32:24 -0000 1.1
+++ src/org/libvirt/VirConnect.java 29 Jun 2008 17:22:36 -0000
@@ -49,16 +49,30 @@ public class VirConnect {
}
/**
+ * Constructs a VirConnect object from the supplied URI,
+ * using the supplied authentication callback
+ *
+ * @param uri The connection URI
+ * @param auth a VirConnectAuth object
+ * @param flags
+ * @throws LibvirtException
+ * @see <a href="http://libvirt.org/uri.html">The URI documentation</a>
+ */
+ public VirConnect(String uri, VirConnectAuth auth, int flags) throws LibvirtException {
+ VCP = _openAuth(uri, auth, flags);
+ }
+
+ /**
* Constructs a read-write VirConnect object from the supplied URI.
*
- * @param uri
+ * @param uri The connection URI
* @throws LibvirtException
* @see <a href="http://libvirt.org/uri.html">The URI documentation</a>
*/
public VirConnect(String uri) throws LibvirtException {
VCP = _open(uri);
}
-
+
public void finalize() throws LibvirtException {
close();
}
@@ -307,6 +321,9 @@ public class VirConnect {
// openReadOnly
private native long _openReadOnly(String uri) throws LibvirtException;
+ // openAuth
+ private native long _openAuth(String uri, VirConnectAuth auth, int flags) throws LibvirtException;
+
// virNetwork stuff
/**
Index: src/org/libvirt/VirDomain.java
===================================================================
RCS file: /data/cvs/libvirt-java/src/org/libvirt/VirDomain.java,v
retrieving revision 1.1
diff -u -p -r1.1 VirDomain.java
--- src/org/libvirt/VirDomain.java 24 Jun 2008 16:32:24 -0000 1.1
+++ src/org/libvirt/VirDomain.java 29 Jun 2008 17:22:36 -0000
@@ -7,9 +7,23 @@ public class VirDomain {
}
static final class MigrateFlags{
+ /**
+ * live migration
+ */
static final int VIR_MIGRATE_LIVE = 1;
}
+ static final class XMLFlags{
+ /**
+ * dump security sensitive information too
+ */
+ static final int VIR_DOMAIN_XML_SECURE = 1;
+ /**
+ * dump inactive domain information
+ */
+ static final int VIR_DOMAIN_XML_INACTIVE = 2;
+ }
+
/**
* the native virDomainPtr.
*/
Index: src/org/libvirt/VirError.java
===================================================================
RCS file: /data/cvs/libvirt-java/src/org/libvirt/VirError.java,v
retrieving revision 1.1
diff -u -p -r1.1 VirError.java
--- src/org/libvirt/VirError.java 24 Jun 2008 16:32:24 -0000 1.1
+++ src/org/libvirt/VirError.java 29 Jun 2008 17:22:37 -0000
@@ -59,7 +59,23 @@ public class VirError {
/**
* Error from OpenVZ driver
*/
- VIR_FROM_OPENVZ
+ VIR_FROM_OPENVZ,
+ /**
+ * Error at Xen XM layer
+ */
+ VIR_FROM_XENXM,
+ /**
+ * Error in the Linux Stats code
+ */
+ VIR_FROM_STATS_LINUX,
+ /**
+ * Error from Linux Container driver
+ */
+ VIR_FROM_LXC,
+ /**
+ * Error from storage driver
+ */
+ VIR_FROM_STORAGE
}
public static enum VirErrorLevel {
@@ -251,7 +267,31 @@ public class VirError {
/**
* invalid MAC adress
*/
- VIR_ERR_INVALID_MAC
+ VIR_ERR_INVALID_MAC,
+ /**
+ * authentication failed
+ */
+ VIR_ERR_AUTH_FAILED,
+ /**
+ * invalid storage pool object
+ */
+ VIR_ERR_INVALID_STORAGE_POOL,
+ /**
+ * invalid storage vol object
+ */
+ VIR_ERR_INVALID_STORAGE_VOL,
+ /**
+ * failed to start storage
+ */
+ VIR_WAR_NO_STORAGE,
+ /**
+ * storage pool not found
+ */
+ VIR_ERR_NO_STORAGE_POOL,
+ /**
+ * storage pool not found
+ */
+ VIR_ERR_NO_STORAGE_VOL
}
VirErrorNumber code;
@@ -328,7 +368,7 @@ public class VirError {
}
/**
- * Does this error has a valid Connection object atteched?
+ * Does this error has a valid Connection object attached?
* @return
*/
public boolean hasConn(){
@@ -416,7 +456,6 @@ public class VirError {
output.append("int1:" + int1 + "\n");
output.append("int2:" + int2 + "\n");
return output.toString();
-
}
}
Index: src/org/libvirt/VirSchedParameter.java
===================================================================
RCS file: /data/cvs/libvirt-java/src/org/libvirt/VirSchedParameter.java,v
retrieving revision 1.1
diff -u -p -r1.1 VirSchedParameter.java
--- src/org/libvirt/VirSchedParameter.java 24 Jun 2008 16:32:24 -0000 1.1
+++ src/org/libvirt/VirSchedParameter.java 29 Jun 2008 17:22:37 -0000
@@ -20,7 +20,7 @@ public abstract class VirSchedParameter
*/
public abstract String getValueAsString();
/**
- * Utility function for displayinf the type
+ * Utility function for displaying the type
*
* @return the Type of the parameter as string
*/
#include <jni.h>
#include <libvirt/libvirt.h>
#include <string.h>
#include "VirConnectAuthCallbackBridge.h"
#include <assert.h>
int VirConnectAuthCallbackBridge(virConnectCredentialPtr cred, unsigned int ncred, void * cbdata){
//cbdata contains the java object that contains tha callback, as well as the JNI environment
JNIEnv *env = ((CallBackStructType*)cbdata)->env;
jobject j_auth = ((CallBackStructType*)cbdata)->auth;
jclass j_auth_cls = (*env)->GetObjectClass(env, j_auth);
jmethodID j_auth_cb_id=(*env)->GetMethodID(env, (*env)->GetObjectClass(env, j_auth), "callback", "([Lorg/libvirt/VirConnectCredential;)I");
jclass j_cred_cls = (*env)->FindClass(env, "org/libvirt/VirConnectCredential");
jmethodID j_cred_constructor = (*env)->GetMethodID(env, j_cred_cls, "<init>", "(ILjava/lang/String;Ljava/lang/String;Ljava/lang/String;)V");
jfieldID j_cred_result_id = (*env)->GetFieldID(env, j_cred_cls, "result", "Ljava/lang/String;");
jobjectArray j_credArray = (*env)->NewObjectArray(env, ncred, j_cred_cls, NULL);
//copy the credentials array to the Java object.
int c;
jobject j_cred;
for(c=0; c<ncred; c++){
j_cred=(*env)->NewObject(env,
j_cred_cls,
j_cred_constructor,
cred[c].type,
(*env)->NewStringUTF(env, cred[c].prompt),
(*env)->NewStringUTF(env, cred[c].challenge),
(*env)->NewStringUTF(env, cred[c].defresult));
(*env)->SetObjectArrayElement(env, j_credArray, c, j_cred);
}
//Time to call the actual java callback function
int retval = (*env)->CallNonvirtualIntMethod(env,
j_auth,
j_auth_cls,
j_auth_cb_id,
j_credArray);
if(retval){
//The java callback function has failed, so we fail as well.
return -1;
}
//If we are still here, the java callback returned sucessfully, so copy the results back.
jstring j_cred_result;
const char* result;
for(c=0; c<ncred; c++){
j_cred = (*env)->GetObjectArrayElement(env, j_credArray, c);
j_cred_result = (*env)->GetObjectField(env, j_cred, j_cred_result_id);
//If this assert triggers, then the user-supplied VirConnectAuth.callback function is broken
assert(j_cred_result);
result = (*env)->GetStringUTFChars(env,
j_cred_result,
NULL);
cred[c].result = strdup(result);
cred[c].resultlen = strlen(result);
(*env)->ReleaseStringUTFChars(env, j_cred_result, result);
}
//All done, back to libvirt
return 0;
}
#include <jni.h>
#include <libvirt/libvirt.h>
typedef struct {
JNIEnv *env;
jobject auth;
} CallBackStructType;
int VirConnectAuthCallbackBridge(virConnectCredentialPtr cred, unsigned int ncred, void * cbdata);
package org.libvirt;
/**
* We diverge from the C implementation
* There is no explicit cbdata field, you should just add any extra data to the child class's instance.
*
* @author stoty
*
*/
public abstract class VirConnectAuth {
/**
* List of supported VirConnectCredential.VirConnectCredentialType values
*/
public VirConnectCredential.VirConnectCredentialType credType[];
/**
* The callback function that fills the credentials in
* @param cred the array of credentials passed by libvirt
* @return 0 if the defresult field contains a vailde response, -1 otherwise
*/
public abstract int callback(VirConnectCredential[] cred);
}
package org.libvirt;
import java.io.BufferedReader;
import java.io.InputStreamReader;
/**
* @author stoty
* Implements virConnectAuthPtrDefault functionality from libvirt.c without the external method support
* It's not officially a part of the libvirt API, but provided here for completeness, testing, and as an example
*/
public final class VirConnectAuthDefault extends VirConnectAuth {
{
credType= new VirConnectCredential.VirConnectCredentialType[] {
VirConnectCredential.VirConnectCredentialType.VIR_CRED_AUTHNAME,
VirConnectCredential.VirConnectCredentialType.VIR_CRED_ECHOPROMPT,
VirConnectCredential.VirConnectCredentialType.VIR_CRED_REALM,
VirConnectCredential.VirConnectCredentialType.VIR_CRED_PASSPHRASE,
VirConnectCredential.VirConnectCredentialType.VIR_CRED_NOECHOPROMPT
};
}
@Override
public int callback(VirConnectCredential[] cred) {
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
try{
for(VirConnectCredential c: cred){
String response="";
switch(c.type){
case VIR_CRED_USERNAME:
case VIR_CRED_AUTHNAME:
case VIR_CRED_ECHOPROMPT:
case VIR_CRED_REALM:
System.out.println(c.prompt);
response= in.readLine();
break;
case VIR_CRED_PASSPHRASE:
case VIR_CRED_NOECHOPROMPT:
System.out.println(c.prompt);
System.out.println("WARNING: THE ENTERED PASSWORD WILL NOT BE MASKED!");
response= in.readLine();
break;
}
if(response.equals("") && !c.defresult.equals("")){
c.result=c.defresult;
} else {
c.result=response;
}
if(c.result.equals("")){
return -1;
}
}
} catch (Exception e) {
return -1;
}
return 0;
}
}
package org.libvirt;
/**
* @author stoty
*
*/
public class VirConnectCredential {
public static enum VirConnectCredentialType {
//This is off by one, but we don't care, because we can't convert java Enum to C enum in a sane way anyway
/**
* Identity to act as
*/
VIR_CRED_USERNAME,
/**
* Identify to authorize as
*/
VIR_CRED_AUTHNAME,
/**
* RFC 1766 languages, comma separated
*/
VIR_CRED_LANGUAGE,
/**
* client supplies a nonce
*/
VIR_CRED_CNONCE,
/**
* Passphrase secret
*/
VIR_CRED_PASSPHRASE,
/**
* Challenge response
*/
VIR_CRED_ECHOPROMPT,
/**
* Challenge response
*/
VIR_CRED_NOECHOPROMPT,
/**
* Authentication realm
*/
VIR_CRED_REALM,
/**
* Externally managed credential More may be added - expect the unexpected
*/
VIR_CRED_EXTERNAL;
/**
* Maps the java VirConnectCredentialType Enum to libvirt's integer constant
*
* @return The integer equivalent
*/
private int mapToInt(){
switch(this){
case VIR_CRED_USERNAME: return 1;
case VIR_CRED_AUTHNAME: return 2;
case VIR_CRED_LANGUAGE: return 3;
case VIR_CRED_CNONCE: return 4;
case VIR_CRED_PASSPHRASE: return 5;
case VIR_CRED_ECHOPROMPT: return 6;
case VIR_CRED_NOECHOPROMPT: return 7;
case VIR_CRED_REALM: return 8;
case VIR_CRED_EXTERNAL: return 9;
}
//We may never reach this point
assert(false);
return 0;
}
}
/**
* One of virConnectCredentialType constants
*/
public VirConnectCredentialType type;
/**
* Prompt to show to user
*/
public String prompt;
/**
* Additional challenge to show
*/
public String challenge;
/**
* Optional default result
*/
public String defresult;
/**
* Result to be filled with user response (or defresult)
*/
public String result;
/**
* Convenience constructor to be called from the JNI side
*
* @param type
* @param prompt
* @param challenge
* @param defresult
*/
VirConnectCredential(int type, String prompt, String challenge, String defresult){
switch(type){
case 1: this.type=VirConnectCredentialType.VIR_CRED_USERNAME; break;
case 2: this.type=VirConnectCredentialType.VIR_CRED_AUTHNAME; break;
case 3: this.type=VirConnectCredentialType.VIR_CRED_LANGUAGE; break;
case 4: this.type=VirConnectCredentialType.VIR_CRED_CNONCE; break;
case 5: this.type=VirConnectCredentialType.VIR_CRED_PASSPHRASE; break;
case 6: this.type=VirConnectCredentialType.VIR_CRED_ECHOPROMPT; break;
case 7: this.type=VirConnectCredentialType.VIR_CRED_NOECHOPROMPT; break;
case 8: this.type=VirConnectCredentialType.VIR_CRED_REALM; break;
case 9: this.type=VirConnectCredentialType.VIR_CRED_EXTERNAL; break;
default: assert(false);
}
this.prompt = prompt;
this.challenge = challenge;
this.defresult = defresult;
}
}
16 years, 4 months
[libvirt] [PATCH] [LXC] Remove unused variable and fix uninitialized variable
by Dan Smith
Also remove a stale comment in the area. This makes libvirt compile when
passed --with-lxc and --enable-compiler-warnings=error
diff -r bd08a3f22fb2 -r fa048279476d src/veth.c
--- a/src/veth.c Thu Jun 26 16:09:48 2008 +0000
+++ b/src/veth.c Fri Jun 27 06:48:10 2008 -0700
@@ -192,14 +192,12 @@
*/
int moveInterfaceToNetNs(const char* interface, int pidInNs)
{
- int rc;
- /* offset of the pid field in the following args */
+ int rc = -1;
char *pid = NULL;
const char *argv[] = {
"ip", "link", "set", interface, "netns", NULL, NULL
};
int cmdResult;
- int len;
if (NULL == interface) {
goto error_out;
16 years, 5 months
[libvirt] HTTP-API for libvirt
by Stefan de Konink
New thread.
> Honnestly I'm still lost trying to understand what you wanted to do.
I have implemented a webserver plugin that allows (by mDNS) to access
all 'VMs' on the network.
http://xen.bot.nu/virt/ <- demo
> I didn't understand the point, I just noted you wanted to put things
> in libvirtd, something about event API while to me i don't see the even side
> of the proposal.
Using mDNS, mDNS events can be used on the network to subscribe to
certain VM changes. Reboot/Shutdown/etc.
> Now suggesting to convey this as part of Java *bindings* sounds even more
> confusing, how does that relate at all ?
You proposed (new) bindings for Java. I have written new bindings using
the HTTP protocol. I wonder what should be done to get it adapted into
libvirt, or standardize the format (like any other API).
Stefan
16 years, 5 months