[Libvir] [PATCH 1/7] Fix memory leak

2007-08-12 Thread Jim Paris

Signed-off-by: Jim Paris [EMAIL PROTECTED]
---
 src/qemu_driver.c |1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/src/qemu_driver.c b/src/qemu_driver.c
index 7c75d9c..b05c3f6 100644
--- a/src/qemu_driver.c
+++ b/src/qemu_driver.c
@@ -204,6 +204,7 @@ qemudStartup(void) {
 qemudShutdown();
 qemudAutostartConfigs(qemu_driver);
 
+free(base);
 return 0;
 
  snprintf_error:
-- 
1.5.3.rc4

--
Libvir-list mailing list
Libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[Libvir] [PATCH 5/7] Add qemudEscapeShellArg for passing commandlines to qemu.

2007-08-12 Thread Jim Paris
Use this to escape a shell argument in a commandline passed to qemu.
First we need to escape certain characters to get them through the
qemu monitor interface.  On the shell side, the argument will be
enclosed in single quotes, so the only character that needs special
treatment is the single quote itself.

Signed-off-by: Jim Paris [EMAIL PROTECTED]
---
 src/qemu_driver.c |   66 +
 1 files changed, 66 insertions(+), 0 deletions(-)

diff --git a/src/qemu_driver.c b/src/qemu_driver.c
index e487640..5d310fe 100644
--- a/src/qemu_driver.c
+++ b/src/qemu_driver.c
@@ -1866,6 +1866,72 @@ static int qemudDomainGetInfo(virDomainPtr dom,
 }
 
 
+static char *qemudEscapeShellArg(const char *in)
+{
+int len = 0;
+int i, j;
+char *out;
+
+/* To pass through the QEMU monitor, we need to use escape
+   sequences: \r, \n, \, \\
+   
+   To pass through both QEMU + the shell, we need to escape
+   the single character ' as the five characters '\\''
+*/
+
+for (i = 0; in[i] != '\0'; i++) {
+switch(in[i]) {
+case '\r':
+case '\n':
+case '':
+case '\\':
+len += 2;
+break;
+case '\'':
+len += 5;
+break;
+default:
+len += 1;
+break;
+}
+}
+
+if ((out = (char *)malloc(len + 1)) == NULL)
+return NULL;
+
+for (i = j = 0; in[i] != '\0'; i++) {
+switch(in[i]) {
+case '\r':
+out[j++] = '\\';
+out[j++] = 'r';
+break;
+case '\n':
+out[j++] = '\\';
+out[j++] = 'n';
+break;
+case '':
+case '\\':
+out[j++] = '\\';
+out[j++] = in[i];
+break;
+case '\'':
+out[j++] = '\'';
+out[j++] = '\\';
+out[j++] = '\\';
+out[j++] = '\'';
+out[j++] = '\'';
+break;
+default:
+out[j++] = in[i];
+break;
+}
+}
+out[j] = '\0';
+
+return out;
+}
+
+
 static int qemudDomainSave(virDomainPtr dom,
 const char *path ATTRIBUTE_UNUSED) {
 struct qemud_driver *driver = (struct qemud_driver 
*)dom-conn-privateData;
-- 
1.5.3.rc4

--
Libvir-list mailing list
Libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[Libvir] [PATCH 4/7] Add migration support to QEMU startup.

2007-08-12 Thread Jim Paris
Adds new fields in qemu_vm structure.  vm-migrateFrom specifies the
argument to -incoming.  vm-stdinFd specifies the file descriptor to
pass to virExec as stdin, which will be used for the -incoming stdio
case.

Signed-off-by: Jim Paris [EMAIL PROTECTED]
---
 src/qemu_conf.c   |   12 +++-
 src/qemu_conf.h   |2 ++
 src/qemu_driver.c |4 ++--
 3 files changed, 15 insertions(+), 3 deletions(-)

diff --git a/src/qemu_conf.c b/src/qemu_conf.c
index 79dd180..f02d693 100644
--- a/src/qemu_conf.c
+++ b/src/qemu_conf.c
@@ -1518,7 +1518,8 @@ int qemudBuildCommandLine(virConnectPtr conn,
 (vm-def-os.initrd[0] ? 2 : 0) + /* initrd */
 (vm-def-os.cmdline[0] ? 2 : 0) + /* cmdline */
 (vm-def-graphicsType == QEMUD_GRAPHICS_VNC ? 2 :
- (vm-def-graphicsType == QEMUD_GRAPHICS_SDL ? 0 : 1)); /* graphics */
+ (vm-def-graphicsType == QEMUD_GRAPHICS_SDL ? 0 : 1)) + /* graphics 
*/
+(vm-migrateFrom[0] ? 3 : 0); /* migrateFrom */
 
 snprintf(memory, sizeof(memory), %d, vm-def-memory/1024);
 snprintf(vcpus, sizeof(vcpus), %d, vm-def-vcpus);
@@ -1767,6 +1768,15 @@ int qemudBuildCommandLine(virConnectPtr conn,
 /* SDL is the default. no args needed */
 }
 
+if (vm-migrateFrom[0]) {
+if (!((*argv)[++n] = strdup(-S)))
+goto no_memory;
+if (!((*argv)[++n] = strdup(-incoming)))
+goto no_memory;
+if (!((*argv)[++n] = strdup(vm-migrateFrom)))
+goto no_memory;
+}
+
 (*argv)[++n] = NULL;
 
 return 0;
diff --git a/src/qemu_conf.h b/src/qemu_conf.h
index 60a38b7..ba61264 100644
--- a/src/qemu_conf.h
+++ b/src/qemu_conf.h
@@ -212,6 +212,8 @@ struct qemud_vm {
 
 char configFile[PATH_MAX];
 char autostartLink[PATH_MAX];
+char migrateFrom[PATH_MAX];
+int stdinFd;
 
 struct qemud_vm_def *def; /* The current definition */
 struct qemud_vm_def *newDef; /* New definition to activate at shutdown */
diff --git a/src/qemu_driver.c b/src/qemu_driver.c
index 553aa21..e487640 100644
--- a/src/qemu_driver.c
+++ b/src/qemu_driver.c
@@ -656,9 +656,9 @@ static int qemudStartVMDaemon(virConnectPtr conn,
  errno, strerror(errno));
 
 if (virExecNonBlock(conn, argv, vm-pid, 
-0, vm-stdout, vm-stderr) == 0) {
+vm-stdinFd, vm-stdout, vm-stderr) == 0) {
 vm-id = driver-nextvmid++;
-vm-state = VIR_DOMAIN_RUNNING;
+vm-state = vm-migrateFrom[0] ? VIR_DOMAIN_PAUSED : 
VIR_DOMAIN_RUNNING;
 
 driver-ninactivevms--;
 driver-nactivevms++;
-- 
1.5.3.rc4

--
Libvir-list mailing list
Libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[Libvir] [PATCH 3/7] Add option to pass stdin fd to virExec

2007-08-12 Thread Jim Paris
If nonzero, uses the supplied fd instead of /dev/null.
Update callers accordingly.

Signed-off-by: Jim Paris [EMAIL PROTECTED]
---
 src/openvz_driver.c |4 ++--
 src/qemu_driver.c   |5 +++--
 src/util.c  |   12 ++--
 src/util.h  |4 ++--
 4 files changed, 13 insertions(+), 12 deletions(-)

diff --git a/src/openvz_driver.c b/src/openvz_driver.c
index 84d514c..b0788f6 100644
--- a/src/openvz_driver.c
+++ b/src/openvz_driver.c
@@ -342,7 +342,7 @@ static int openvzListDomains(virConnectPtr conn, int *ids, 
int nids) {
 char buf[32];
 const char *cmd[] = {VZLIST, -ovpsid, -H , NULL};
 
-ret = virExec(conn, (char **)cmd, pid, outfd, errfd);
+ret = virExec(conn, (char **)cmd, pid, 0, outfd, errfd);
 if(ret == -1) {
 error(conn, VIR_ERR_INTERNAL_ERROR, Could not exec  VZLIST);
 return (int)NULL;
@@ -373,7 +373,7 @@ static int openvzListDefinedDomains(virConnectPtr conn,
 const char *cmd[] = {VZLIST, -ovpsid, -H, NULL};
 
 /* the -S options lists only stopped domains */
-ret = virExec(conn, (char **)cmd, pid, outfd, errfd);
+ret = virExec(conn, (char **)cmd, pid, 0, outfd, errfd);
 if(ret == -1) {
 error(conn, VIR_ERR_INTERNAL_ERROR, Could not exec  VZLIST);
 return (int)NULL;
diff --git a/src/qemu_driver.c b/src/qemu_driver.c
index 8063ad2..553aa21 100644
--- a/src/qemu_driver.c
+++ b/src/qemu_driver.c
@@ -655,7 +655,8 @@ static int qemudStartVMDaemon(virConnectPtr conn,
 qemudLog(QEMUD_WARN, Unable to write argv to logfile %d: %s,
  errno, strerror(errno));
 
-if (virExecNonBlock(conn, argv, vm-pid, vm-stdout, vm-stderr) == 0) {
+if (virExecNonBlock(conn, argv, vm-pid, 
+0, vm-stdout, vm-stderr) == 0) {
 vm-id = driver-nextvmid++;
 vm-state = VIR_DOMAIN_RUNNING;
 
@@ -912,7 +913,7 @@ dhcpStartDhcpDaemon(virConnectPtr conn,
 if (qemudBuildDnsmasqArgv(conn, network, argv)  0)
 return -1;
 
-ret = virExecNonBlock(conn, argv, network-dnsmasqPid, NULL, NULL);
+ret = virExecNonBlock(conn, argv, network-dnsmasqPid, 0, NULL, NULL);
 
 for (i = 0; argv[i]; i++)
 free(argv[i]);
diff --git a/src/util.c b/src/util.c
index f53cfd2..546a7b8 100644
--- a/src/util.c
+++ b/src/util.c
@@ -79,7 +79,7 @@ static int virSetNonBlock(int fd) {
 static int
 _virExec(virConnectPtr conn,
   char **argv,
-  int *retpid, int *outfd, int *errfd, int non_block) {
+  int *retpid, int infd, int *outfd, int *errfd, int non_block) {
 int pid, null;
 int pipeout[2] = {-1,-1};
 int pipeerr[2] = {-1,-1};
@@ -140,7 +140,7 @@ _virExec(virConnectPtr conn,
 if (pipeerr[0]  0  close(pipeerr[0])  0)
 _exit(1);
 
-if (dup2(null, STDIN_FILENO)  0)
+if (dup2(infd  0 ? infd : null, STDIN_FILENO)  0)
 _exit(1);
 if (dup2(pipeout[1]  0 ? pipeout[1] : null, STDOUT_FILENO)  0)
 _exit(1);
@@ -176,16 +176,16 @@ _virExec(virConnectPtr conn,
 int
 virExec(virConnectPtr conn,
   char **argv,
-  int *retpid, int *outfd, int *errfd) {
+  int *retpid, int infd, int *outfd, int *errfd) {
 
-return(_virExec(conn, argv, retpid, outfd, errfd, 0));
+return(_virExec(conn, argv, retpid, infd, outfd, errfd, 0));
 }
 
 int
 virExecNonBlock(virConnectPtr conn,
   char **argv,
-  int *retpid, int *outfd, int *errfd) {
+  int *retpid, int infd, int *outfd, int *errfd) {
 
-return(_virExec(conn, argv, retpid, outfd, errfd, 1));
+return(_virExec(conn, argv, retpid, infd, outfd, errfd, 1));
 }
 
diff --git a/src/util.h b/src/util.h
index 5b84043..d11e6d9 100644
--- a/src/util.h
+++ b/src/util.h
@@ -21,6 +21,6 @@
  * File created Jul 18, 2007 - Shuveb Hussain [EMAIL PROTECTED]
  */
 
-int virExec(virConnectPtr conn, char **argv, int *retpid, int *outfd, int 
*errfd);
-int virExecNonBlock(virConnectPtr conn, char **argv, int *retpid, int *outfd, 
int *errfd);
+int virExec(virConnectPtr conn, char **argv, int *retpid, int infd, int 
*outfd, int *errfd);
+int virExecNonBlock(virConnectPtr conn, char **argv, int *retpid, int infd, 
int *outfd, int *errfd);
 
-- 
1.5.3.rc4

--
Libvir-list mailing list
Libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[Libvir] [PATCH 2/7] Fix issues with QEMU monitor interface.

2007-08-12 Thread Jim Paris
Due to the TTY layer, sending \n to the qemu monitor translates
into \r\n when received.  This triggers a bug in older versions of
QEMU (KVM = 33) because the same command is executed twice, and
still has problems with fixed QEMU because the (qemu) prompt is
printed twice.  Switch all monitor commands to end with \r which
avoids both issues.

The QEMU monitor sends frequent terminal escape sequences, typically
\033[D and \033[K.  At times, these interfere with the prompt
detection when they get sent between \n and (qemu) .  Fix the
issue by filtering out these sequences when they are received.

Signed-off-by: Jim Paris [EMAIL PROTECTED]
---
 src/qemu_driver.c |   21 -
 1 files changed, 16 insertions(+), 5 deletions(-)

diff --git a/src/qemu_driver.c b/src/qemu_driver.c
index b05c3f6..8063ad2 100644
--- a/src/qemu_driver.c
+++ b/src/qemu_driver.c
@@ -1306,12 +1306,14 @@ static int qemudMonitorCommand(struct qemud_driver 
*driver ATTRIBUTE_UNUSED,
 for (;;) {
 struct pollfd fd = { vm-monitor, POLLIN | POLLERR | POLLHUP, 0 };
 char *tmp;
+int skip = 0;
 
 /* Read all the data QEMU has sent thus far */
 for (;;) {
 char data[1024];
 int got = read(vm-monitor, data, sizeof(data));
 char *b;
+int i;
 
 if (got == 0) {
 if (buf)
@@ -1333,14 +1335,23 @@ static int qemudMonitorCommand(struct qemud_driver 
*driver ATTRIBUTE_UNUSED,
 return -1;
 }
 buf = b;
-memmove(buf+size, data, got);
-buf[size+got] = '\0';
-size += got;
+
+/* Copy data, skipping 3-byte escape sequences */
+for (i = 0; i  got; i++) {
+if (data[i] == '\033')
+skip = 3;
+if (skip)
+skip--;
+else
+buf[size++] = data[i];
+}
+buf[size] = '\0';
 }
 if (buf)
 qemudDebug(Mon [%s], buf);
 /* Look for QEMU prompt to indicate completion */
 if (buf  ((tmp = strstr(buf, \n(qemu) )) != NULL)) {
+fprintf(stderr,got qemu\n);
 tmp[0] = '\0';
 break;
 }
@@ -1755,7 +1766,7 @@ static int qemudDomainSuspend(virDomainPtr dom) {
 if (vm-state == VIR_DOMAIN_PAUSED)
 return 0;
 
-if (qemudMonitorCommand(driver, vm, stop\n, info)  0) {
+if (qemudMonitorCommand(driver, vm, stop\r, info)  0) {
 qemudReportError(dom-conn, dom, NULL, VIR_ERR_OPERATION_FAILED, 
suspend operation failed);
 return -1;
 }
@@ -1780,7 +1791,7 @@ static int qemudDomainResume(virDomainPtr dom) {
 }
 if (vm-state == VIR_DOMAIN_RUNNING)
 return 0;
-if (qemudMonitorCommand(driver, vm, cont\n, info)  0) {
+if (qemudMonitorCommand(driver, vm, cont\r, info)  0) {
 qemudReportError(dom-conn, dom, NULL, VIR_ERR_OPERATION_FAILED, 
resume operation failed);
 return -1;
 }
-- 
1.5.3.rc4

--
Libvir-list mailing list
Libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[Libvir] [PATCH 7/7] Add KVM restore support using migration.

2007-08-12 Thread Jim Paris

Signed-off-by: Jim Paris [EMAIL PROTECTED]
---
 src/qemu_driver.c |  106 +++--
 1 files changed, 102 insertions(+), 4 deletions(-)

diff --git a/src/qemu_driver.c b/src/qemu_driver.c
index 50ab702..c6de8a0 100644
--- a/src/qemu_driver.c
+++ b/src/qemu_driver.c
@@ -2047,10 +2047,108 @@ static int qemudDomainSave(virDomainPtr dom,
 
 
 static int qemudDomainRestore(virConnectPtr conn,
-   const char *path ATTRIBUTE_UNUSED) {
-/*struct qemud_driver *driver = (struct qemud_driver *)conn-privateData;*/
-qemudReportError(conn, NULL, NULL, VIR_ERR_OPERATION_FAILED, restore is 
not supported);
-return -1;
+   const char *path) {
+struct qemud_driver *driver = (struct qemud_driver *)conn-privateData;
+struct qemud_vm_def *def;
+struct qemud_vm *vm;
+int fd;
+char *xml;
+struct qemud_save_header header;
+
+/* Verify the header and read the XML */
+if ((fd = open(path, O_RDONLY))  0) {
+qemudReportError(conn, NULL, NULL, VIR_ERR_OPERATION_FAILED,
+ cannot read domain image);
+return -1;
+}
+
+if (read(fd, header, sizeof(header)) != sizeof(header)) {
+qemudReportError(conn, NULL, NULL, VIR_ERR_OPERATION_FAILED,
+ failed to read qemu header);
+close(fd);
+return -1;
+}
+
+if (memcmp(header.magic, QEMUD_SAVE_MAGIC, sizeof(header.magic)) != 0) {
+qemudReportError(conn, NULL, NULL, VIR_ERR_OPERATION_FAILED,
+ image magic is incorrect);
+close(fd);
+return -1;
+}
+
+if ((xml = (char *)malloc(header.xml_len + 1)) == NULL) {
+qemudReportError(conn, NULL, NULL, VIR_ERR_OPERATION_FAILED,
+ out of memory);
+close(fd);
+return -1;
+}
+
+if (read(fd, xml, header.xml_len) != header.xml_len) {
+qemudReportError(conn, NULL, NULL, VIR_ERR_OPERATION_FAILED,
+ failed to read XML);
+close(fd);
+free(xml);
+return -1;
+}
+xml[header.xml_len] = '\0';
+
+/* Create a domain from this XML */
+if (!(def = qemudParseVMDef(conn, driver, xml, NULL))) {
+qemudReportError(conn, NULL, NULL, VIR_ERR_OPERATION_FAILED,
+ failed to parse XML);
+close(fd);
+free(xml);
+return -1;
+}
+free(xml);
+
+/* Ensure the name and UUID don't already exist in an active VM */
+vm = qemudFindVMByUUID(driver, def-uuid);
+if (!vm) vm = qemudFindVMByName(driver, def-name);
+if (vm  qemudIsActiveVM(vm)) {
+qemudReportError(conn, NULL, NULL, VIR_ERR_OPERATION_FAILED,
+ domain to restore is already active);
+close(fd);
+return -1;
+}
+
+if (!(vm = qemudAssignVMDef(conn, driver, def))) {
+qemudReportError(conn, NULL, NULL, VIR_ERR_OPERATION_FAILED,
+ failed to assign new VM);
+qemudFreeVMDef(def);
+close(fd);
+return -1;
+}
+
+/* Set the migration source and start it up. */
+snprintf(vm-migrateFrom, sizeof(vm-migrateFrom), stdio);
+vm-stdinFd = fd;
+   
+if (qemudStartVMDaemon(conn, driver, vm)  0) {
+qemudReportError(conn, NULL, NULL, VIR_ERR_OPERATION_FAILED,
+ failed to start VM);
+if (!vm-configFile[0])
+qemudRemoveInactiveVM(driver, vm);
+close(fd);
+return -1;
+}
+close(fd);
+vm-migrateFrom[0] = '\0';
+vm-stdinFd = 0;
+
+/* If it was running before, resume it now. */
+if (header.was_running) {
+char *info;
+if (qemudMonitorCommand(driver, vm, cont\n, info)  0) {
+qemudReportError(conn, NULL, NULL, VIR_ERR_OPERATION_FAILED, 
+ failed to resume domain);
+return -1;
+}
+free(info);
+vm-state = VIR_DOMAIN_RUNNING;
+}
+
+return 0;
 }
 
 
-- 
1.5.3.rc4

--
Libvir-list mailing list
Libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[Libvir] [PATCH 6/7] Add KVM save support using migration.

2007-08-12 Thread Jim Paris
The save file format consists of a header, XML for the domain,
and the raw QEMU/KVM migration data stream.

Signed-off-by: Jim Paris [EMAIL PROTECTED]
---
 src/qemu_driver.c |  109 ++---
 1 files changed, 103 insertions(+), 6 deletions(-)

diff --git a/src/qemu_driver.c b/src/qemu_driver.c
index 5d310fe..50ab702 100644
--- a/src/qemu_driver.c
+++ b/src/qemu_driver.c
@@ -1932,20 +1932,117 @@ static char *qemudEscapeShellArg(const char *in)
 }
 
 
-static int qemudDomainSave(virDomainPtr dom,
-const char *path ATTRIBUTE_UNUSED) {
+#define QEMUD_SAVE_MAGIC LibvirtQemudSave
+struct qemud_save_header {
+char magic[sizeof(QEMUD_SAVE_MAGIC)-1];
+int xml_len;
+int was_running;
+};
+
+static int qemudDomainSave(virDomainPtr dom, 
+   const char *path) {
 struct qemud_driver *driver = (struct qemud_driver 
*)dom-conn-privateData;
 struct qemud_vm *vm = qemudFindVMByID(driver, dom-id);
+char *command, *info;
+int fd;
+char *safe_path;
+char *xml;
+struct qemud_save_header header;
+
+memset(header, 0, sizeof(header));
+memcpy(header.magic, QEMUD_SAVE_MAGIC, sizeof(header.magic));
+
 if (!vm) {
-qemudReportError(dom-conn, dom, NULL, VIR_ERR_INVALID_DOMAIN, no 
domain with matching id %d, dom-id);
+qemudReportError(dom-conn, dom, NULL, VIR_ERR_INVALID_DOMAIN,
+ no domain with matching id %d, dom-id);
 return -1;
 }
+
 if (!qemudIsActiveVM(vm)) {
-qemudReportError(dom-conn, dom, NULL, VIR_ERR_OPERATION_FAILED, 
domain is not running);
+qemudReportError(dom-conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
+ domain is not running);
 return -1;
 }
-qemudReportError(dom-conn, dom, NULL, VIR_ERR_OPERATION_FAILED, save is 
not supported);
-return -1;
+
+/* Pause */
+if (vm-state == VIR_DOMAIN_RUNNING) {
+header.was_running = 1;
+if (qemudDomainSuspend(dom) != 0) {
+qemudReportError(dom-conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
+ failed to pause domain);
+return -1;
+}
+}
+
+/* Get XML for the domain */
+xml = qemudGenerateXML(dom-conn, driver, vm, vm-def, 0);
+if (!xml) {
+qemudReportError(dom-conn, dom, NULL, VIR_ERR_OPERATION_FAILED, 
+ failed to get domain xml);
+return -1;
+}
+header.xml_len = strlen(xml);
+
+/* Write header to file, followed by XML */
+if ((fd = open(path, O_CREAT|O_TRUNC|O_WRONLY, S_IRUSR|S_IWUSR))  0) {
+qemudReportError(dom-conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
+ failed to create '%s', path);
+free(xml);
+return -1;
+}
+
+if (write(fd, header, sizeof(header)) != sizeof(header)) {
+qemudReportError(dom-conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
+ failed to write save header);
+close(fd);
+free(xml);
+return -1;
+}
+
+if (write(fd, xml, header.xml_len) != header.xml_len) {
+qemudReportError(dom-conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
+ failed to write xml);
+close(fd);
+free(xml);
+return -1;
+}
+
+close(fd);
+free(xml);
+
+/* Migrate to file */
+safe_path = qemudEscapeShellArg(path);
+if (!safe_path) {
+qemudReportError(dom-conn, dom, NULL, VIR_ERR_OPERATION_FAILED, 
+ out of memory);
+return -1;
+}
+if (asprintf (command, migrate \exec: 
+  dd of='%s' oflag=append conv=notrunc 2/dev/null
+  \\n, safe_path) == -1) {
+qemudReportError(dom-conn, dom, NULL, VIR_ERR_OPERATION_FAILED, 
+ out of memory);
+free(safe_path);
+return -1;
+}
+free(safe_path);
+
+if (qemudMonitorCommand(driver, vm, command, info)  0) {
+qemudReportError(dom-conn, dom, NULL, VIR_ERR_OPERATION_FAILED, 
+ migrate operation failed);
+free(command);
+return -1;
+}
+
+free(info);
+free(command);
+
+/* Shut it down */
+qemudShutdownVMDaemon(dom-conn, driver, vm);
+if (!vm-configFile[0])
+qemudRemoveInactiveVM(driver, vm);
+
+return 0;
 }
 
 
-- 
1.5.3.rc4

--
Libvir-list mailing list
Libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list