[libvirt] virDomainInterfaceStats why is there a size?
by Stefan de Konink
Another simple question, what is the reasoning about the size field in
this call. I would really be a happy boy if anyone said:
if you put in path == NULL, it will fill your stats structure up to size
interfaces.
...but since this is not the case (yet) what is the reason behind it?
Stefan
15 years, 11 months
[libvirt] Re: [PATCH/RFC] kvm/qemu vs libvirtd restarts
by Daniel P. Berrange
Moving thread to libvir-list....
On Tue, Oct 07, 2008 at 06:12:33PM +0200, Guido G?nther wrote:
> On Fri, Sep 26, 2008 at 04:47:05PM +0100, Daniel P. Berrange wrote:
> > On Fri, Sep 26, 2008 at 05:41:02PM +0200, Guido G?nther wrote:
> >
> > We've got this problem sorted in the 'lxc' driver and need to apply
> > the same approach to the QEMU driver. The problem was always finding
> > the Pseduo-TTY/PID for the monitor after restart, and associating the
> > live config with it. We've "solved" that in LXC driver by savingt the
> > live XML & PID to /var/run/libvirt/lxc/. It basically needs the same
> > approach to be applied to the QEMU daemons. In addition the DNSmasq
> > deamon needs adapting for simiarl reasons.
>
> Attached is a very early patch. It keeps the qemu instances running and
> writes out their states upon shutdown. Reconnecting (and therefore sending
> monitor commands, etc.) works but since stdout/stderr don't get picked
> up again yet we don't handle virEventAddhandle. I'll grab them from
> /proc/<pid>/fd/{1,2} later. Network state is missing too, but since this
> is moving into a separate file it's becoming a different matter anyway.
First off, thanks for working on this! A few general comments, and then
I'll put rest inline..
For stdout/err, it need to be setup so that the logfile is dup()'d onto
the QEMU process' file descriptors directly, and get libvirt outof the
business of I/O forwarding. This avoids any complications with re-attaching
to stdout/err, and loosing any log data while libvirt isn't running.
This also needs to be implemented with the assumption that the daemon
can & will crash any time. So putting the state-saving hooks into the
qemudShutdown() method won't be sufficient. We need to write out the
state we need when initially starting the VM, and then update it any
time we hot-plug/unplug devices.
Ignoring network state is fine - we can address that separately..
> Subject: [PATCH] let qemu/kvm survive libvirtd restarts
>
> ---
> src/domain_conf.c | 1 +
> src/domain_conf.h | 1 +
> src/qemu_conf.h | 1 +
> src/qemu_driver.c | 264 +++++++++++++++++++++++++++++++++++++++++++++++++----
> src/util.c | 4 +-
> src/util.h | 1 +
> 6 files changed, 254 insertions(+), 18 deletions(-)
>
> diff --git a/src/domain_conf.c b/src/domain_conf.c
> index 6a35064..aa102f6 100644
> --- a/src/domain_conf.c
> +++ b/src/domain_conf.c
> @@ -420,6 +420,7 @@ void virDomainObjFree(virDomainObjPtr dom)
> virDomainDefFree(dom->def);
> virDomainDefFree(dom->newDef);
>
> + VIR_FREE(dom->monitorpath);
> VIR_FREE(dom->vcpupids);
>
> VIR_FREE(dom);
> diff --git a/src/domain_conf.h b/src/domain_conf.h
> index 632e5ad..1ac1561 100644
> --- a/src/domain_conf.h
> +++ b/src/domain_conf.h
> @@ -448,6 +448,7 @@ struct _virDomainObj {
> int stdout_fd;
> int stderr_fd;
> int monitor;
> + char *monitorpath;
I think we can avoid needing this. If we write out the staste the
moment the VM is started, we don't need to carry this around in
memory. Alternatively, since we're writing all stdout/err data to
the logfile, we could simply re-parse the log to extract the
monitor path upon restart.
> int logfile;
> int pid;
> int state;
> diff --git a/src/qemu_conf.h b/src/qemu_conf.h
> index 88dfade..f47582e 100644
> --- a/src/qemu_conf.h
> +++ b/src/qemu_conf.h
> @@ -62,6 +62,7 @@ struct qemud_driver {
> char *networkConfigDir;
> char *networkAutostartDir;
> char *logDir;
> + char *stateDir;
> unsigned int vncTLS : 1;
> unsigned int vncTLSx509verify : 1;
> char *vncTLSx509certdir;
> diff --git a/src/qemu_driver.c b/src/qemu_driver.c
> index 806608d..87789a9 100644
> --- a/src/qemu_driver.c
> +++ b/src/qemu_driver.c
> @@ -172,6 +172,181 @@ void qemudAutostartConfigs(struct qemud_driver *driver) {
> }
>
> #ifdef WITH_LIBVIRTD
> +
> +static int
> +qemudFileWriteMonitor(const char *dir,
> + const char *name,
> + const char *path)
> +{
> + int rc;
> + int fd;
> + FILE *file = NULL;
> + char *monitorfile = NULL;
> +
> + if ((rc = virFileMakePath(dir)))
> + goto cleanup;
> +
> + if (asprintf(&monitorfile, "%s/%s.monitor", dir, name) < 0) {
> + rc = ENOMEM;
> + goto cleanup;
> + }
> +
> + if ((fd = open(monitorfile,
> + O_WRONLY | O_CREAT | O_TRUNC,
> + S_IRUSR | S_IWUSR)) < 0) {
> + rc = errno;
> + goto cleanup;
> + }
> +
> + if (!(file = fdopen(fd, "w"))) {
> + rc = errno;
> + close(fd);
> + goto cleanup;
> + }
> +
> + if (fprintf(file, "%s", path) < 0) {
> + rc = errno;
> + goto cleanup;
> + }
> +
> + rc = 0;
> +
> +cleanup:
> + if (file &&
> + fclose(file) < 0) {
> + rc = errno;
> + }
> +
> + VIR_FREE(monitorfile);
> + return rc;
> +}
> +
> +static int
> +qemudFileReadMonitor(const char *dir,
> + const char *name,
> + char **path)
> +{
> + int rc;
> + FILE *file;
> + char *monitorfile = NULL;
> +
> + if (asprintf(&monitorfile, "%s/%s.monitor", dir, name) < 0) {
> + rc = ENOMEM;
> + goto cleanup;
> + }
> +
> + if (!(file = fopen(monitorfile, "r"))) {
> + rc = errno;
> + goto cleanup;
> + }
> +
> + if (fscanf(file, "%as", path) != 1) {
> + rc = EINVAL;
> + goto cleanup;
> + }
> +
> + if (fclose(file) < 0) {
> + rc = errno;
> + goto cleanup;
> + }
> +
> + rc = 0;
> +
> + cleanup:
> + VIR_FREE(monitorfile);
> + return rc;
> +}
If we re-parse the logfile to extract the monitiro PTY path, this is
unneccessary. If not, this can be simplied by just calling the
convenient virFileReadAll() method.
> +
> +static int
> +qemudFileDeleteMonitor(const char *dir,
> + const char *name)
> +{
> + int rc = 0;
> + char *pidfile = NULL;
> +
> + if (asprintf(&pidfile, "%s/%s.monitor", dir, name) < 0) {
> + rc = errno;
> + goto cleanup;
> + }
> +
> + if (unlink(pidfile) < 0 && errno != ENOENT)
> + rc = errno;
> +
> +cleanup:
> + VIR_FREE(pidfile);
> + return rc;
> +}
> +
> +
> +static int qemudOpenMonitor(virConnectPtr conn,
> + struct qemud_driver *driver,
> + virDomainObjPtr vm,
> + const char *monitor,
> + int reconnect);
> +/**
> + * qemudReconnectVMs
> + *
> + * Reconnect running vms to the daemon process
> + */
> +static int
> +qemudReconnectVMs(struct qemud_driver *driver)
> +{
> + virDomainObjPtr vm = driver->domains;
> +
> + while (vm) {
> + virDomainDefPtr tmp;
> + char *config = NULL;
> + char *monitor = NULL;
> + int rc;
> +
> + /* Read pid */
> + if ((rc = virFileReadPid(driver->stateDir, vm->def->name, &vm->pid)) == 0) {
> + virFileDeletePid(driver->stateDir, vm->def->name);
> + DEBUG("Found pid %d for '%s'", vm->pid, vm->def->name);
> + } else
> + goto next;
> +
> + if ((config = virDomainConfigFile(NULL,
> + driver->stateDir,
> + vm->def->name)) == NULL) {
> + qemudLog(QEMUD_ERR, _("Failed to read back domain config for %s\n"),
> + vm->def->name);
> + goto next;
> + }
> +
> + /* Try and load the config */
> + tmp = virDomainDefParseFile(NULL, driver->caps, config);
> + unlink(config);
> + if (tmp) {
> + vm->newDef = vm->def;
> + vm->def = tmp;
> + }
> +
> + /* read back monitor path */
> + if ((rc = qemudFileReadMonitor(driver->stateDir, vm->def->name, &monitor)) != 0) {
> + qemudLog(QEMUD_ERR, _("Failed to read back monitor path for %s: %s\n"),
> + vm->def->name, strerror(rc));
> + goto next;
> + }
> + qemudFileDeleteMonitor(driver->stateDir, vm->def->name);
> +
> + /* FIXME: reconnect stdout/stderr via /proc/pid/fd/ */
> +
> + if ((rc = qemudOpenMonitor(NULL, driver, vm, monitor, 1)) != 0) {
> + qemudLog(QEMUD_ERR, _("Failed to reconnect to monitor for %s: %d\n"),
> + vm->def->name, rc);
> + goto next;
> + }
> + vm->def->id = driver->nextvmid++;
The ID of a vm must never change for until it is rebooted. Simply
don't overwrite the existing vm->def->id that we jjust loaded off
disk. And instead adjust the nextvmid field, eg
if (vm->def->id >= driver->nextvmid)
driver->nextvmid = vm->def->id + 1;
> + vm->state = VIR_DOMAIN_RUNNING;
> +next:
> + VIR_FREE(config);
> + VIR_FREE(monitor);
> + vm = vm->next;
> + }
> + return 0;
> +}
> +
> /**
> * qemudStartup:
> *
> @@ -197,6 +372,10 @@ qemudStartup(void) {
>
> if ((base = strdup (SYSCONF_DIR "/libvirt")) == NULL)
> goto out_of_memory;
> +
> + if (asprintf (&qemu_driver->stateDir,
> + "%s/run/libvirt/qemu/", LOCAL_STATE_DIR) == -1)
> + goto out_of_memory;
> } else {
> if (!(pw = getpwuid(uid))) {
> qemudLog(QEMUD_ERR, _("Failed to find user record for uid '%d': %s\n"),
> @@ -210,6 +389,10 @@ qemudStartup(void) {
>
> if (asprintf (&base, "%s/.libvirt", pw->pw_dir) == -1)
> goto out_of_memory;
> +
> + if (asprintf (&qemu_driver->stateDir,
> + "%s/run/libvirt/qemu/", base) == -1)
> + goto out_of_memory;
> }
>
> /* Configuration paths are either ~/.libvirt/qemu/... (session) or
> @@ -250,6 +433,8 @@ qemudStartup(void) {
> qemudShutdown();
> return -1;
> }
> + qemudReconnectVMs(qemu_driver);
> +
> if (virNetworkLoadAllConfigs(NULL,
> &qemu_driver->networks,
> qemu_driver->networkConfigDir,
> @@ -329,6 +514,34 @@ qemudActive(void) {
> return 0;
> }
>
> +/**
> + * qemudSaveDomainState
> + *
> + * Save the full state of a running domain to statedir
> + *
> + * Returns 0 on success
> + */
> +static int
> +qemudSaveDomainState(struct qemud_driver * driver, virDomainObjPtr vm) {
> + int ret;
> +
> + if ((ret = virFileWritePid(driver->stateDir, vm->def->name, vm->pid)) != 0) {
> + qemudLog(QEMUD_ERR, _("Unable to safe pidfile for %s: %s\n"),
> + vm->def->name, strerror(ret));
> + return ret;
> + }
> + if ((ret = virDomainSaveConfig(NULL, driver->stateDir, vm->def))) {
> + qemudLog(QEMUD_ERR, _("Unable to save domain %s\n"), vm->def->name);
> + return ret;
> + }
> + if ((ret = qemudFileWriteMonitor(driver->stateDir, vm->def->name, vm->monitorpath)) != 0) {
> + qemudLog(QEMUD_ERR, _("Unable to monitor file for %s: %s\n"),
> + vm->def->name, strerror(ret));
> + return ret;
> + }
> + return 0;
> +}
> +
This will need to be called at time of VM creation, and the
XSL config will need updating whether live config changes.
> /**
> * qemudShutdown:
> *
> @@ -349,10 +562,14 @@ qemudShutdown(void) {
> while (vm) {
> virDomainObjPtr next = vm->next;
> if (virDomainIsActive(vm))
> +#if 1
> + qemudSaveDomainState(qemu_driver, vm);
> +#else
> qemudShutdownVMDaemon(NULL, qemu_driver, vm);
> if (!vm->persistent)
> virDomainRemoveInactive(&qemu_driver->domains,
> vm);
> +#endif
> vm = next;
> }
>
> @@ -389,6 +606,7 @@ qemudShutdown(void) {
> VIR_FREE(qemu_driver->networkConfigDir);
> VIR_FREE(qemu_driver->networkAutostartDir);
> VIR_FREE(qemu_driver->vncTLSx509certdir);
> + VIR_FREE(qemu_driver->stateDir);
>
> if (qemu_driver->brctl)
> brShutdown(qemu_driver->brctl);
> @@ -499,7 +717,7 @@ qemudCheckMonitorPrompt(virConnectPtr conn ATTRIBUTE_UNUSED,
> static int qemudOpenMonitor(virConnectPtr conn,
> struct qemud_driver *driver,
> virDomainObjPtr vm,
> - const char *monitor) {
> + const char *monitor, int reconnect) {
> int monfd;
> char buf[1024];
> int ret = -1;
> @@ -520,11 +738,26 @@ static int qemudOpenMonitor(virConnectPtr conn,
> goto error;
> }
>
> - ret = qemudReadMonitorOutput(conn,
> - driver, vm, monfd,
> - buf, sizeof(buf),
> - qemudCheckMonitorPrompt,
> - "monitor");
> + if (!reconnect) {
> + ret = qemudReadMonitorOutput(conn,
> + driver, vm, monfd,
> + buf, sizeof(buf),
> + qemudCheckMonitorPrompt,
> + "monitor");
> +
> + } else {
> + vm->monitor = monfd;
> + ret = 0;
> + }
> +
> + if (ret != 0)
> + goto error;
> +
> + if (!(vm->monitorpath = strdup(monitor))) {
> + qemudReportError(conn, NULL, NULL, VIR_ERR_NO_MEMORY,
> + "%s", _("failed to allocate space for monitor path"));
> + goto error;
> + }
>
> /* Keep monitor open upon success */
> if (ret == 0)
> @@ -623,7 +856,7 @@ qemudFindCharDevicePTYs(virConnectPtr conn,
> }
>
> /* Got them all, so now open the monitor console */
> - ret = qemudOpenMonitor(conn, driver, vm, monitor);
> + ret = qemudOpenMonitor(conn, driver, vm, monitor, 0);
>
> cleanup:
> VIR_FREE(monitor);
> @@ -966,12 +1199,11 @@ static int qemudStartVMDaemon(virConnectPtr conn,
>
> ret = virExec(conn, argv, NULL, &keepfd, &vm->pid,
> vm->stdin_fd, &vm->stdout_fd, &vm->stderr_fd,
> - VIR_EXEC_NONBLOCK);
> + VIR_EXEC_NONBLOCK | VIR_EXEC_SETSID);
> if (ret == 0) {
> vm->def->id = driver->nextvmid++;
> vm->state = migrateFrom ? VIR_DOMAIN_PAUSED : VIR_DOMAIN_RUNNING;
> }
> -
> for (i = 0 ; argv[i] ; i++)
> VIR_FREE(argv[i]);
> VIR_FREE(argv);
> @@ -1037,7 +1269,9 @@ static void qemudShutdownVMDaemon(virConnectPtr conn ATTRIBUTE_UNUSED,
>
> qemudLog(QEMUD_INFO, _("Shutting down VM '%s'\n"), vm->def->name);
>
> - kill(vm->pid, SIGTERM);
> + if (kill(vm->pid, SIGTERM) < 0)
> + qemudLog(QEMUD_ERROR, _("Failed to send SIGTERM to %s (%d): %s\n"),
> + vm->def->name, vm->pid, strerror(errno));
>
> qemudVMData(driver, vm, vm->stdout_fd);
> qemudVMData(driver, vm, vm->stderr_fd);
> @@ -1057,13 +1291,9 @@ static void qemudShutdownVMDaemon(virConnectPtr conn ATTRIBUTE_UNUSED,
> vm->stderr_fd = -1;
> vm->monitor = -1;
>
> - if (waitpid(vm->pid, NULL, WNOHANG) != vm->pid) {
> - kill(vm->pid, SIGKILL);
> - if (waitpid(vm->pid, NULL, 0) != vm->pid) {
> - qemudLog(QEMUD_WARN,
> - "%s", _("Got unexpected pid, damn\n"));
> - }
> - }
> + /* shut if off for sure */
> + kill(vm->pid, SIGKILL);
> + virFileDeletePid(driver->stateDir, vm->def->name);
>
> vm->pid = -1;
> vm->def->id = -1;
> diff --git a/src/util.c b/src/util.c
> index ca14be1..442c810 100644
> --- a/src/util.c
> +++ b/src/util.c
> @@ -299,14 +299,16 @@ virExec(virConnectPtr conn,
> !FD_ISSET(i, keepfd)))
> close(i);
>
> - if (flags & VIR_EXEC_DAEMON) {
> + if (flags & VIR_EXEC_DAEMON || flags & VIR_EXEC_SETSID) {
> if (setsid() < 0) {
> ReportError(conn, VIR_ERR_INTERNAL_ERROR,
> _("cannot become session leader: %s"),
> strerror(errno));
> _exit(1);
> }
> + }
>
> + if (flags & VIR_EXEC_DAEMON) {
> if (chdir("/") < 0) {
> ReportError(conn, VIR_ERR_INTERNAL_ERROR,
> _("cannot change to root directory: %s"),
> diff --git a/src/util.h b/src/util.h
> index 093ef46..8fbe2cd 100644
> --- a/src/util.h
> +++ b/src/util.h
> @@ -32,6 +32,7 @@ enum {
> VIR_EXEC_NONE = 0,
> VIR_EXEC_NONBLOCK = (1 << 0),
> VIR_EXEC_DAEMON = (1 << 1),
> + VIR_EXEC_SETSID = (1 << 2),
> };
Shouldn't we simply be starting all the QEMU VMs with VIR_EXEC_DAEMON
so they totally disassociate themselves from libvirtd right away. They
will be disassociated anyway if the libvirtd is ever restarted, so best
to daemonize from time they are started, to avoid any surprising changes
in behaviour
Regards,
Daniel
--
|: 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 :|
15 years, 11 months
[libvirt] [PATCH] 0/7 host ("node") device enumeration - completed submission
by David Lively
Since the version of this I posted last week still had some outstaning
TODO items that I have since finished, I'm re-submitting the whole
thing. I consider this a "complete submission" since I don't think it's
necessary to implement any additional functionality to make this
acceptable. (The two remaining unimplemented items are
virNodeDeviceCreate / Destroy and a real Devkit impl, neither of which
needs to be done immediately, for reasons discussed earlier.)
These patches implement the node device enumeration functionality, as
discussed here:
https://www.redhat.com/archives/libvir-list/2008-September/msg00398.html
I've broken it into the following pieces:
1-public-api additions to the public API
2-internal-api additions to the internal API
3-local-node-drivers the HAL & DeviceKit implementations
4-remote-node-driver the remote driver
5-virsh-support virsh support
6-python-bindings python bindings
7-java-bindings Java bindings (for libvirt-java)
Dave
16 years
[libvirt] one more warning
by Jim Meyering
One more warning question:
Compiling with all storage backends disabled, I get this:
storage_backend.c:91: warning: comparison of unsigned expression < 0 is always false
That's because of this code:
static virStorageBackendPtr backends[] = {
#if WITH_STORAGE_DIR
&virStorageBackendDirectory,
#endif
#if WITH_STORAGE_FS
&virStorageBackendFileSystem,
&virStorageBackendNetFileSystem,
#endif
#if WITH_STORAGE_LVM
&virStorageBackendLogical,
#endif
#if WITH_STORAGE_ISCSI
&virStorageBackendISCSI,
#endif
#if WITH_STORAGE_DISK
&virStorageBackendDisk,
#endif
};
virStorageBackendPtr
virStorageBackendForType(int type) {
unsigned int i;
for (i = 0 ; i < ARRAY_CARDINALITY(backends); i++)
if (backends[i]->type == type)
return backends[i];
virStorageReportError(NULL, VIR_ERR_INTERNAL_ERROR,
_("missing backend for pool type %d"), type);
return NULL;
}
The above loses because ARRAY_CARDINALITY(backends) is 0.
One solution is to always have at least one backend,
e.g., the first one, in which case, this patch works fine:
[but if you like this (i don't), it'd make sense also to remove the
configure-time option ]
diff --git a/src/storage_backend.c b/src/storage_backend.c
index e33f98c..264cc53 100644
--- a/src/storage_backend.c
+++ b/src/storage_backend.c
@@ -56,9 +56,7 @@
#if WITH_STORAGE_DISK
#include "storage_backend_disk.h"
#endif
-#if WITH_STORAGE_DIR
#include "storage_backend_fs.h"
-#endif
VIR_ENUM_IMPL(virStorageBackendPartTable,
VIR_STORAGE_POOL_DISK_LAST,
@@ -66,9 +64,7 @@ VIR_ENUM_IMPL(virStorageBackendPartTable,
"mac", "bsd", "pc98", "sun", "lvm2");
static virStorageBackendPtr backends[] = {
-#if WITH_STORAGE_DIR
&virStorageBackendDirectory,
-#endif
#if WITH_STORAGE_FS
&virStorageBackendFileSystem,
&virStorageBackendNetFileSystem,
Another way is to add a NULL pointer at the end
and change the loop not to use the array size at all:
for (i = 0; backends[i]; i++)
if (backends[i]->type == type)
return backends[i];
I chose the latter:
diff --git a/src/storage_backend.c b/src/storage_backend.c
index e33f98c..1f4ed10 100644
--- a/src/storage_backend.c
+++ b/src/storage_backend.c
@@ -82,13 +82,14 @@ static virStorageBackendPtr backends[] = {
#if WITH_STORAGE_DISK
&virStorageBackendDisk,
#endif
+ NULL
};
virStorageBackendPtr
virStorageBackendForType(int type) {
unsigned int i;
- for (i = 0 ; i < ARRAY_CARDINALITY(backends); i++)
+ for (i = 0; backends[i]; i++)
if (backends[i]->type == type)
return backends[i];
16 years
[libvirt] [PATCH]: Allow arbitrary paths to virStorageVolLookupByPath
by Chris Lalancette
In ovirt, we have to scan iSCSI LUN's for LVM storage when they are first added
to the database. To do this, we do roughly the following:
iscsi_pool = libvirt.define_and_start_iscsi_pool("/dev/disk/by-id")
iscsi_pool.add_luns_to_db
logical = conn.discover_storage_pool_sources("logical")
for each logical_volume_group in logical:
for each device in logical_volume_group:
iscsi_pool.lookup_vol_by_path(device.path)
And then we use that information to associate an iSCSI LUN with this volume
group. The problem is that there is an mis-match between how we define the
iscsi pool (with /dev/disk/by-id devices), and what data the
discover_storage_pool_sources() returns (/dev devices), so we can't easily
associate the two.
The following patch implements stable path naming when the
virStorageVolLookupByPath method is called. Basically, it tries to convert
whatever path it is given (say /dev/sdc) into the form currently used by the
Pool (say /dev/disk/by-id). It then goes and looks up the form in the pool, and
returns the storageVolume object as appropriate. Note that it only tries to do
this for the Pool types where it makes sense, namely iSCSI and disk; all other
pool types stay exactly the same.
With this in place, we can solve the mis-match in the above code, and LVM
scanning seems to work in ovirt.
Signed-off-by: Chris Lalancette <clalance(a)redhat.com>
16 years
[libvirt] [Q]Why does libvirt check size of memory in xenStoreDriver?
by S.Sakamoto
Hi,
I have a question.
Why does libvirt check size of memory in xenStoreDomainSetMemory of xs_internal.c?
In the xen not exclude lifecycle,
when I do the following command for the domain that is shutoff,
error message is output and return value is 0 and the definition file(=/etc/xen/XXX) is updated.
--------------------
# virsh setmem(or setmaxmem) guestdom 65535(4096-65535)
libvir: Xen Store error : invalid argument in xenStoreDomainSetMemory
# echo $?
0
--------------------
As a result that I research this,
this error message is output by the check of the memory size in xenStoreDriver.
Because libvirt checks the memory size of under 4096 in libvirt.c,
I think that libvirt should check memory size range of 4096-65535 in libvirt.c.
Thanks,
Shigeki Sakamoto.
16 years
[libvirt] [PATCH]: Implement ruby-libvirt storage pool discovery binding
by Chris Lalancette
Attached is a pretty simple patch to implement the
virConnectFindStoragePoolSources() binding for ruby-libvirt.This capability went
into libvirt-0.4.5, so any version of libvirt that has storage API support
should have support for this call. There's not much more to say; it works in my
testing, and the implementation is pretty straightforward.
Signed-off-by: Chris Lalancette <clalance(a)redhat.com>
16 years