aboutsummaryrefslogtreecommitdiff
path: root/vl.c
diff options
context:
space:
mode:
authoraliguori <aliguori@c046a42c-6fe2-441c-8c8c-71466251a162>2008-11-11 16:46:33 +0000
committeraliguori <aliguori@c046a42c-6fe2-441c-8c8c-71466251a162>2008-11-11 16:46:33 +0000
commit065e281356282f59386272aa50590b566a1809d9 (patch)
tree98f265501e5474327a5138bf9ca38736c15f4b38 /vl.c
parenta74b4d2c23a5da45a5ef9eec18ce00923b6bab15 (diff)
Reintroduce migrate-to-exec: support (Charles Duffy)
KVM's live migration support included support for exec: URLs, allowing system state to be written or received via an arbitrary popen()ed subprocess. This provides a convenient way to pipe state through a compression algorithm or an arbitrary network transport on its way to its destination, and a convenient way to write state to disk; libvirt's qemu driver currently uses migration to exec: targets for this latter purpose. This version of the patch refactors now-common code from migrate-tcp.c into migrate.c. Signed-off-by: Charles Duffy <Charles_Duffy@messageone.com> Signed-off-by: Anthony Liguori <aliguori@us.ibm.com> git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@5694 c046a42c-6fe2-441c-8c8c-71466251a162
Diffstat (limited to 'vl.c')
-rw-r--r--vl.c64
1 files changed, 64 insertions, 0 deletions
diff --git a/vl.c b/vl.c
index 7bcffd334a..daad89ffd8 100644
--- a/vl.c
+++ b/vl.c
@@ -2964,6 +2964,12 @@ struct QEMUFile {
int has_error;
};
+typedef struct QEMUFilePopen
+{
+ FILE *popen_file;
+ QEMUFile *file;
+} QEMUFilePopen;
+
typedef struct QEMUFileSocket
{
int fd;
@@ -2992,6 +2998,64 @@ static int socket_close(void *opaque)
return 0;
}
+static int popen_put_buffer(void *opaque, const uint8_t *buf, int64_t pos, int size)
+{
+ QEMUFilePopen *s = opaque;
+ return fwrite(buf, 1, size, s->popen_file);
+}
+
+static int popen_get_buffer(void *opaque, uint8_t *buf, int64_t pos, int size)
+{
+ QEMUFilePopen *s = opaque;
+ return fread(buf, 1, size, s->popen_file);
+}
+
+static int popen_close(void *opaque)
+{
+ QEMUFilePopen *s = opaque;
+ pclose(s->popen_file);
+ qemu_free(s);
+ return 0;
+}
+
+QEMUFile *qemu_popen(FILE *popen_file, const char *mode)
+{
+ QEMUFilePopen *s;
+
+ if (popen_file == NULL || mode == NULL || (mode[0] != 'r' && mode[0] != 'w') || mode[1] != 0) {
+ fprintf(stderr, "qemu_popen: Argument validity check failed\n");
+ return NULL;
+ }
+
+ s = qemu_mallocz(sizeof(QEMUFilePopen));
+ if (!s) {
+ fprintf(stderr, "qemu_popen: malloc failed\n");
+ return NULL;
+ }
+
+ s->popen_file = popen_file;
+
+ if(mode[0] == 'r') {
+ s->file = qemu_fopen_ops(s, NULL, popen_get_buffer, popen_close, NULL);
+ } else {
+ s->file = qemu_fopen_ops(s, popen_put_buffer, NULL, popen_close, NULL);
+ }
+ fprintf(stderr, "qemu_popen: returning result of qemu_fopen_ops\n");
+ return s->file;
+}
+
+QEMUFile *qemu_popen_cmd(const char *command, const char *mode)
+{
+ FILE *popen_file;
+
+ popen_file = popen(command, mode);
+ if(popen_file == NULL) {
+ return NULL;
+ }
+
+ return qemu_popen(popen_file, mode);
+}
+
QEMUFile *qemu_fopen_socket(int fd)
{
QEMUFileSocket *s = qemu_mallocz(sizeof(QEMUFileSocket));