[libvirt] dnsmasq-248 (CentOS/RHEL) compatibility
by Gene Czarcinski
There are currently three significant libvirt patches I am involved with:
1. Change so that dnsmasq parameters are in a conf file instead of on
the command line.
2. A small patch to add dnsmasq parameter interface=
3. A significant patch to add DHCPv6 support to libvirt.
A concern has been raised about the compatibility of my patches with
dnsmasq-2.48 which is the version on CentOS 6 and RHEL 6. While
something like libvirt-1.0.0 is not officially supported, there is a
strong desire not to get in the way of individuals back-porting it.
Plan A: Install CentOS 6.3 into a virtual guest. Apparently, the
current virt-manager has some problems running CentOS 6.3. Since I was
here to drain a swap, I decided not to go after this alligator.
Plan B: Get a the src.rpm for dnsmasq-2.48 from CentOS and build it on
Fedora 17. Then, using a Fedora 17 virtual guest, downgrade install
dnsmasq-2.48 on it.
I then took four of my virtual dnsmasq conf-files than I use, slightly
modify them to use interface=eth2 and common pid, hostsfile, addnhosts,
and leases files. I then fed each of these configuration files to
dnsmasq-2.48. Everything worked except for the one which had an IPv6
dhcp-range specified. That was not surprising dnsmasq-2.48 only
supports IPv6 for dns.
If someone has some additional tests they would like run, please say so.
My recommendation: Incorporate my patches [when I finish the DHCPv6 one
and resubmit the others]. Add (somewhere?) a warning to backporters
that they will need to update their dnsmasq packages to actually do
DHCPv6 but otherwise, earlier versions such as dnsmasq-2.48 will be
compatible.
Comments? Suggestions?
Gene
12 years
[libvirt] [PATCH] logging: Do not redefine mkostemp on uclibc
by Jiri Denemark
An obsolete version of the patch that fixed building on systems with
uclibc (4dbd6e96) was accidentally pushed as part of the release commit
(2b435c15). Since this obsolete patch made syntax-check, commit 30b398d5
was pushed to fix that issue. But the real fix is to actually remove the
offending code.
This patch reverts commit 30b398d5 and the relevant part of 2b435c15.
---
cfg.mk | 2 --
src/util/logging.c | 5 -----
2 files changed, 7 deletions(-)
diff --git a/cfg.mk b/cfg.mk
index 963f642..cda04e4 100644
--- a/cfg.mk
+++ b/cfg.mk
@@ -817,5 +817,3 @@ exclude_file_name_regexp--sc_unmarked_diagnostics = \
^(docs/apibuild.py|tests/virt-aa-helper-test)$$
exclude_file_name_regexp--sc_size_of_brackets = cfg.mk
-
-exclude_file_name_regexp--sc_prohibit_mkstemp = ^src/util/logging\.c$$
diff --git a/src/util/logging.c b/src/util/logging.c
index 27bd74c..dd43842 100644
--- a/src/util/logging.c
+++ b/src/util/logging.c
@@ -58,11 +58,6 @@
#define VIR_FROM_THIS VIR_FROM_NONE
-#ifdef __UCLIBC__
-/* uclibc does not implement mkostemp GNU extention */
-# define mkostemp(x,y) mkstemp(x)
-#endif
-
VIR_ENUM_DECL(virLogSource)
VIR_ENUM_IMPL(virLogSource, VIR_LOG_FROM_LAST,
"file",
--
1.7.12.4
12 years
[libvirt] Proposed: optionally enable dnsmasq logging
by Gene Czarcinski
Note: the solutions listed below will all work with dnsmasq-2.48.
Sometimes it is very difficult to determine what a dnsmasq problem is
when it does not work as expected. Dnsmasq has to options for logging:
log-quiries and log-dhcp. Either or both can be enabled. By default,
neither is enabled.
1. Add an option or options to libvirtd.conf which will enable the
logging on all started dnsmasq processes. While this is doable, it will
also produce a great deal of syslog mesages if more than one dnsmasq
process is running.
2. Add an option to libvirtd.conf which will enable the solutions given
below. By default, it will not be enabled.
3. Add dnsmasq parameter conf-dir= to specify a directory (under the
same directory as the leases file) where the administrator/user can add
a file which contains log-queries and/or log-dhcp.
4. Add the dnsmasq parameter conf-file= to specify an additional
configuration file. This would be under the same directory as the
leases file and have a name of something like: <network_name>.conf-2.
If the file already existed, nothing would be done. If the file did not
exist, a zero-length file would be created.
Currently, I favor ether 4 or the combination of 4 and 2.
Note: dnsmasq would only read this secondary configuration file when it
is started or restarted.
Comments? Suggestions? Whatever?
Gene
12 years
[libvirt] [PATCH 0/2] Add lock in libxl
by Bamvor Jian Zhang
These two patches implement a lock for long-running
job(save, dump and migration) and normal job which will
return in short time but maybe affect the state of virtual
machine.
With these patches, the normal job could not execute while
the long-ruuning job or other normal job is running.
In order to tracking these job, job type for normal job and
long-ruuning job(will be called as async job in code) is
defined.
The abort job is called while user want to cancel such async
job. Note that there is no cancellation function for async
job in xenlight stack. So, abort function just block the
cancellation of user.
Update compare to v1:
1, remove migration relative job functions from lock patch.
2, update comments according to upstream's comments.
Bamvor Jian Zhang (2):
Introduce a lock for libxl long-running api
Add lock for libxl api
src/libxl/libxl_conf.h | 56 +++++
src/libxl/libxl_driver.c | 638 ++++++++++++++++++++++++++++++++++++++++++-----
2 files changed, 633 insertions(+), 61 deletions(-)
--
1.7.12
12 years
[libvirt] Coverity on libvirt-1.0.0 release
by Alex Jia
Hi all,
This is a Coverity report on libvirt-1.0.0 release, for details, please check attachment.
Analysis summary report:
------------------------
Files analyzed : 294
Total LoC input to cov-analyze : 391588
Functions analyzed : 9762
Paths analyzed : 1146758
Time taken by Coverity analysis : 00:20:58
Defect occurrences found : 304 Total
5 ATOMICITY
53 BAD_SIZEOF
7 CHECKED_RETURN
1 CONSTANT_EXPRESSION_RESULT
7 DEADCODE
19 FORWARD_NULL
2 LOCK
1 MISSING_BREAK
8 NEGATIVE_RETURNS
1 NO_EFFECT
7 NULL_RETURNS
2 OVERRUN_STATIC
122 RESOURCE_LEAK
1 RETURN_LOCAL
17 REVERSE_INULL
2 SIZEOF_MISMATCH
1 STRING_NULL
1 STRING_OVERFLOW
4 TAINTED_SCALAR
25 TOCTOU
9 UNINIT
1 UNREACHABLE
8 UNUSED_VALUE
--
Regards,
Alex
12 years
[libvirt] [PATCH] logging.c: Properly indent and ignore one syntax-check rule
by Michal Privoznik
With our fix of mkostemp (pushed as 2b435c15) we define a macro
to compile with uclibc. However, this definition is conditional
and thus needs to be properly indented. Moreover, with this definition
sc_prohibit_mkstemp syntax-check rule keeps yelling:
src/util/logging.c:63:# define mkostemp(x,y) mkstemp(x)
maint.mk: use mkostemp with O_CLOEXEC instead of mkstemp
Therefore we should ignore this file for this rule.
---
Pushed under build-breaker rule.
cfg.mk | 2 ++
src/util/logging.c | 2 +-
2 files changed, 3 insertions(+), 1 deletions(-)
diff --git a/cfg.mk b/cfg.mk
index cda04e4..963f642 100644
--- a/cfg.mk
+++ b/cfg.mk
@@ -817,3 +817,5 @@ exclude_file_name_regexp--sc_unmarked_diagnostics = \
^(docs/apibuild.py|tests/virt-aa-helper-test)$$
exclude_file_name_regexp--sc_size_of_brackets = cfg.mk
+
+exclude_file_name_regexp--sc_prohibit_mkstemp = ^src/util/logging\.c$$
diff --git a/src/util/logging.c b/src/util/logging.c
index c0b2f0b..27bd74c 100644
--- a/src/util/logging.c
+++ b/src/util/logging.c
@@ -60,7 +60,7 @@
#ifdef __UCLIBC__
/* uclibc does not implement mkostemp GNU extention */
-#define mkostemp(x,y) mkstemp(x)
+# define mkostemp(x,y) mkstemp(x)
#endif
VIR_ENUM_DECL(virLogSource)
--
1.7.8.6
12 years
[libvirt] [PATCH 0/2] Add lock in libxl
by Bamvor Jian Zhang
These two patches implement a lock for long-running
job(save, dump and migration) and normal job which will
return in short time but maybe affect the state of virtual
machine.
With these patches, the normal job could not execute while
the long-ruuning job or other normal job is running.
In order to tracking these job, job type for normal job and
long-ruuning job(will be called as async job in code) is
defined.
The abort job is called while user want to cancel such async
job. Note that there is no cancellation function for async
job in xenlight stack. So, abort function just block the
cancellation of user.
Bamvor Jian Zhang (2):
Introduce a lock for libxl long-running api
Add lock for libxl api
src/libxl/libxl_conf.h | 58 +++++
src/libxl/libxl_driver.c | 665 ++++++++++++++++++++++++++++++++++++++++++-----
2 files changed, 662 insertions(+), 61 deletions(-)
--
1.7.12
12 years
[libvirt] [PATCH] qemu: use default machine type if missing it in qemu command line
by Guannan Ren
BZ:https://bugzilla.redhat.com/show_bug.cgi?id=871273
when using virsh qemu-attach to attach an existing qemu process,
if it misses the -M option in qemu command line, libvirtd crashed
because the NULL value of def->os.machine in later use.
Example:
/usr/libexec/qemu-kvm -name foo \
-cdrom /var/lib/libvirt/images/boot.img \
-monitor unix:/tmp/demo,server,nowait \
error: End of file while reading data: Input/output error
error: Failed to reconnect to the hypervisor
This patch tries to set default machine type if the value of
def->os.machine is still NULL after qemu command line parsing.
---
src/qemu/qemu_command.c | 11 +++++++++++
1 files changed, 11 insertions(+), 0 deletions(-)
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index fe99f5d..0b6d2f8 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -8768,6 +8768,17 @@ virDomainDefPtr qemuParseCommandLine(virCapsPtr caps,
}
}
+ if (!def->os.machine) {
+ const char *defaultMachine =
+ virCapabilitiesDefaultGuestMachine(caps,
+ def->os.type,
+ def->os.arch,
+ virDomainVirtTypeToString(def->virtType));
+ if (defaultMachine != NULL)
+ if (!(def->os.machine = strdup(defaultMachine)))
+ goto no_memory;
+ }
+
if (!nographics && def->ngraphics == 0) {
virDomainGraphicsDefPtr sdl;
const char *display = qemuFindEnv(progenv, "DISPLAY");
--
1.7.1
12 years
[libvirt] [PATCH v11] support offline migration
by liguang
original migration did not aware of offline case,
so, try to support offline migration quietly
(did not disturb original migration) by pass
VIR_MIGRATE_OFFLINE flag to migration APIs if only
the domain is really inactive, and
migration process will not puzzled by domain
offline and exit unexpectedly.
these changes did not take care of disk images the
domain required, for them could be transferred by
other APIs as suggested, then VIR_MIGRATE_OFFLINE
should not combined with VIR_MIGRATE_NON_SHARED_*.
if you want a persistent migration,
you should do "virsh migrate --persistent" youself.
Signed-off-by: liguang <lig.fnst(a)cn.fujitsu.com>
---
include/libvirt/libvirt.h.in | 1 +
src/qemu/qemu_driver.c | 15 ++++++++++
src/qemu/qemu_migration.c | 60 +++++++++++++++++++++++++++++++++++------
src/qemu/qemu_migration.h | 3 +-
tools/virsh-domain.c | 6 ++++
5 files changed, 75 insertions(+), 10 deletions(-)
diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in
index 81f12a4..1cebc21 100644
--- a/include/libvirt/libvirt.h.in
+++ b/include/libvirt/libvirt.h.in
@@ -995,6 +995,7 @@ typedef enum {
* whole migration process; this will be used automatically
* when supported */
VIR_MIGRATE_UNSAFE = (1 << 9), /* force migration even if it is considered unsafe */
+ VIR_MIGRATE_OFFLINE = (1 << 10), /* offline migrate */
} virDomainMigrateFlags;
/* Domain migration. */
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 97ad23e..38bfcab 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -9622,6 +9622,20 @@ qemuDomainMigrateBegin3(virDomainPtr domain,
}
if (!virDomainObjIsActive(vm)) {
+ if (flags & VIR_MIGRATE_OFFLINE) {
+ if (flags & (VIR_MIGRATE_NON_SHARED_DISK|
+ VIR_MIGRATE_NON_SHARED_INC)) {
+ virReportError(VIR_ERR_OPERATION_INVALID,
+ "%s", _("migrating storage handled by volume APIs"));
+ goto endjob;
+ }
+ if (!(flags & VIR_MIGRATE_PERSIST_DEST)) {
+ virReportError(VIR_ERR_OPERATION_INVALID,
+ "%s", _("VIR_MIGRATE_OFFLINE should combined with VIR_MIGRATE_PERSIST_DEST"));
+ goto endjob;
+ }
+ goto offline;
+ }
virReportError(VIR_ERR_OPERATION_INVALID,
"%s", _("domain is not running"));
goto endjob;
@@ -9634,6 +9648,7 @@ qemuDomainMigrateBegin3(virDomainPtr domain,
if (qemuDomainCheckEjectableMedia(driver, vm, asyncJob) < 0)
goto endjob;
+offline:
if (!(xml = qemuMigrationBegin(driver, vm, xmlin, dname,
cookieout, cookieoutlen,
flags)))
diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c
index db69a0a..b2f921e 100644
--- a/src/qemu/qemu_migration.c
+++ b/src/qemu/qemu_migration.c
@@ -70,6 +70,7 @@ enum qemuMigrationCookieFlags {
QEMU_MIGRATION_COOKIE_FLAG_GRAPHICS,
QEMU_MIGRATION_COOKIE_FLAG_LOCKSTATE,
QEMU_MIGRATION_COOKIE_FLAG_PERSISTENT,
+ QEMU_MIGRATION_COOKIE_FLAG_OFFLINE,
QEMU_MIGRATION_COOKIE_FLAG_LAST
};
@@ -77,12 +78,13 @@ enum qemuMigrationCookieFlags {
VIR_ENUM_DECL(qemuMigrationCookieFlag);
VIR_ENUM_IMPL(qemuMigrationCookieFlag,
QEMU_MIGRATION_COOKIE_FLAG_LAST,
- "graphics", "lockstate", "persistent");
+ "graphics", "lockstate", "persistent", "offline");
enum qemuMigrationCookieFeatures {
QEMU_MIGRATION_COOKIE_GRAPHICS = (1 << QEMU_MIGRATION_COOKIE_FLAG_GRAPHICS),
QEMU_MIGRATION_COOKIE_LOCKSTATE = (1 << QEMU_MIGRATION_COOKIE_FLAG_LOCKSTATE),
QEMU_MIGRATION_COOKIE_PERSISTENT = (1 << QEMU_MIGRATION_COOKIE_FLAG_PERSISTENT),
+ QEMU_MIGRATION_COOKIE_OFFLINE = (1 << QEMU_MIGRATION_COOKIE_FLAG_OFFLINE),
};
typedef struct _qemuMigrationCookieGraphics qemuMigrationCookieGraphics;
@@ -439,6 +441,9 @@ qemuMigrationCookieXMLFormat(struct qemud_driver *driver,
virBufferAdjustIndent(buf, -2);
}
+ if (mig->flags & QEMU_MIGRATION_COOKIE_OFFLINE)
+ virBufferAsprintf(buf, " <offline/>\n");
+
virBufferAddLit(buf, "</qemu-migration>\n");
return 0;
}
@@ -662,6 +667,11 @@ qemuMigrationCookieXMLParse(qemuMigrationCookiePtr mig,
VIR_FREE(nodes);
}
+ if ((flags & QEMU_MIGRATION_COOKIE_OFFLINE)) {
+ if (virXPathBoolean("count(./offline) > 0", ctxt))
+ mig->flags |= QEMU_MIGRATION_COOKIE_OFFLINE;
+ }
+
return 0;
error:
@@ -721,6 +731,10 @@ qemuMigrationBakeCookie(qemuMigrationCookiePtr mig,
qemuMigrationCookieAddPersistent(mig, dom) < 0)
return -1;
+ if (flags & QEMU_MIGRATION_COOKIE_OFFLINE) {
+ mig->flags |= QEMU_MIGRATION_COOKIE_OFFLINE;
+ }
+
if (!(*cookieout = qemuMigrationCookieXMLFormatStr(driver, mig)))
return -1;
@@ -1168,6 +1182,13 @@ char *qemuMigrationBegin(struct qemud_driver *driver,
QEMU_MIGRATION_COOKIE_LOCKSTATE) < 0)
goto cleanup;
+ if (flags & VIR_MIGRATE_OFFLINE) {
+ if (qemuMigrationBakeCookie(mig, driver, vm,
+ cookieout, cookieoutlen,
+ QEMU_MIGRATION_COOKIE_OFFLINE) < 0)
+ goto cleanup;
+ }
+
if (xmlin) {
if (!(def = virDomainDefParseString(driver->caps, xmlin,
QEMU_EXPECTED_VIRT_TYPES,
@@ -1331,6 +1352,15 @@ qemuMigrationPrepareAny(struct qemud_driver *driver,
goto endjob;
}
+ if (!(mig = qemuMigrationEatCookie(driver, vm, cookiein, cookieinlen,
+ QEMU_MIGRATION_COOKIE_OFFLINE)))
+ return ret;
+
+ if (mig->flags & QEMU_MIGRATION_COOKIE_OFFLINE) {
+ ret = 0;
+ goto cleanup;
+ }
+
/* Start the QEMU daemon, with the same command-line arguments plus
* -incoming $migrateFrom
*/
@@ -1873,7 +1903,8 @@ qemuMigrationRun(struct qemud_driver *driver,
virLockManagerPluginGetName(driver->lockManager));
return -1;
}
-
+ if (flags & VIR_MIGRATE_OFFLINE)
+ return 0;
if (!(mig = qemuMigrationEatCookie(driver, vm, cookiein, cookieinlen,
QEMU_MIGRATION_COOKIE_GRAPHICS)))
goto cleanup;
@@ -2389,6 +2420,8 @@ static int doPeer2PeerMigrate3(struct qemud_driver *driver,
qemuDomainObjExitRemoteWithDriver(driver, vm);
}
VIR_FREE(dom_xml);
+ if (flags & VIR_MIGRATE_OFFLINE)
+ goto cleanup;
if (ret == -1)
goto cleanup;
@@ -2494,7 +2527,7 @@ finish:
vm->def->name);
cleanup:
- if (ddomain) {
+ if (ddomain || (flags & VIR_MIGRATE_OFFLINE)) {
virObjectUnref(ddomain);
ret = 0;
} else {
@@ -2571,7 +2604,7 @@ static int doPeer2PeerMigrate(struct qemud_driver *driver,
}
/* domain may have been stopped while we were talking to remote daemon */
- if (!virDomainObjIsActive(vm)) {
+ if (!virDomainObjIsActive(vm) && !(flags & VIR_MIGRATE_OFFLINE)) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("guest unexpectedly quit"));
goto cleanup;
@@ -2634,7 +2667,7 @@ qemuMigrationPerformJob(struct qemud_driver *driver,
if (qemuMigrationJobStart(driver, vm, QEMU_ASYNC_JOB_MIGRATION_OUT) < 0)
goto cleanup;
- if (!virDomainObjIsActive(vm)) {
+ if (!virDomainObjIsActive(vm) && !(flags & VIR_MIGRATE_OFFLINE)) {
virReportError(VIR_ERR_OPERATION_INVALID,
"%s", _("domain is not running"));
goto endjob;
@@ -2958,6 +2991,8 @@ qemuMigrationFinish(struct qemud_driver *driver,
*/
if (retcode == 0) {
if (!virDomainObjIsActive(vm)) {
+ if (flags & VIR_MIGRATE_OFFLINE)
+ goto offline;
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("guest unexpectedly quit"));
goto endjob;
@@ -2973,6 +3008,7 @@ qemuMigrationFinish(struct qemud_driver *driver,
goto endjob;
}
+ offline:
if (flags & VIR_MIGRATE_PERSIST_DEST) {
virDomainDefPtr vmdef;
if (vm->persistent)
@@ -3020,7 +3056,7 @@ qemuMigrationFinish(struct qemud_driver *driver,
event = NULL;
}
- if (!(flags & VIR_MIGRATE_PAUSED)) {
+ if (!(flags & VIR_MIGRATE_PAUSED) && !(flags & VIR_MIGRATE_OFFLINE)) {
/* run 'cont' on the destination, which allows migration on qemu
* >= 0.10.6 to work properly. This isn't strictly necessary on
* older qemu's, but it also doesn't hurt anything there
@@ -3069,9 +3105,11 @@ qemuMigrationFinish(struct qemud_driver *driver,
VIR_DOMAIN_EVENT_SUSPENDED,
VIR_DOMAIN_EVENT_SUSPENDED_PAUSED);
}
- if (virDomainSaveStatus(driver->caps, driver->stateDir, vm) < 0) {
- VIR_WARN("Failed to save status on vm %s", vm->def->name);
- goto endjob;
+ if (virDomainObjIsActive(vm)) {
+ if (virDomainSaveStatus(driver->caps, driver->stateDir, vm) < 0) {
+ VIR_WARN("Failed to save status on vm %s", vm->def->name);
+ goto endjob;
+ }
}
/* Guest is successfully running, so cancel previous auto destroy */
@@ -3091,6 +3129,7 @@ qemuMigrationFinish(struct qemud_driver *driver,
endjob:
if (qemuMigrationJobFinish(driver, vm) == 0) {
vm = NULL;
+ } else if (flags & VIR_MIGRATE_OFFLINE) {
} else if (!vm->persistent && !virDomainObjIsActive(vm)) {
qemuDomainRemoveInactive(driver, vm);
vm = NULL;
@@ -3137,6 +3176,8 @@ int qemuMigrationConfirm(struct qemud_driver *driver,
if (!(mig = qemuMigrationEatCookie(driver, vm, cookiein, cookieinlen, 0)))
return -1;
+ if (flags & VIR_MIGRATE_OFFLINE)
+ goto offline;
/* Did the migration go as planned? If yes, kill off the
* domain object, but if no, resume CPUs
@@ -3173,6 +3214,7 @@ int qemuMigrationConfirm(struct qemud_driver *driver,
}
}
+offline:
qemuMigrationCookieFree(mig);
rv = 0;
diff --git a/src/qemu/qemu_migration.h b/src/qemu/qemu_migration.h
index 7a2269a..b4f6a77 100644
--- a/src/qemu/qemu_migration.h
+++ b/src/qemu/qemu_migration.h
@@ -36,7 +36,8 @@
VIR_MIGRATE_NON_SHARED_DISK | \
VIR_MIGRATE_NON_SHARED_INC | \
VIR_MIGRATE_CHANGE_PROTECTION | \
- VIR_MIGRATE_UNSAFE)
+ VIR_MIGRATE_UNSAFE | \
+ VIR_MIGRATE_OFFLINE)
enum qemuMigrationJobPhase {
QEMU_MIGRATION_PHASE_NONE = 0,
diff --git a/tools/virsh-domain.c b/tools/virsh-domain.c
index 505169b..2218379 100644
--- a/tools/virsh-domain.c
+++ b/tools/virsh-domain.c
@@ -6647,6 +6647,7 @@ static const vshCmdOptDef opts_migrate[] = {
{"dname", VSH_OT_DATA, 0, N_("rename to new name during migration (if supported)")},
{"timeout", VSH_OT_INT, 0, N_("force guest to suspend if live migration exceeds timeout (in seconds)")},
{"xml", VSH_OT_STRING, 0, N_("filename containing updated XML for the target")},
+ {"offline", VSH_OT_BOOL, 0, N_("for offline migration")},
{NULL, 0, 0, NULL}
};
@@ -6713,6 +6714,11 @@ doMigrate(void *opaque)
if (vshCommandOptBool(cmd, "unsafe"))
flags |= VIR_MIGRATE_UNSAFE;
+ if (vshCommandOptBool(cmd, "offline")) {
+ if (!virDomainIsActive(dom))
+ flags |= VIR_MIGRATE_OFFLINE;
+ }
+
if (xmlfile &&
virFileReadAll(xmlfile, 8192, &xml) < 0) {
vshError(ctl, _("file '%s' doesn't exist"), xmlfile);
--
1.7.2.5
12 years