diff options
author | aliguori <aliguori@c046a42c-6fe2-441c-8c8c-71466251a162> | 2008-11-11 16:46:33 +0000 |
---|---|---|
committer | aliguori <aliguori@c046a42c-6fe2-441c-8c8c-71466251a162> | 2008-11-11 16:46:33 +0000 |
commit | 065e281356282f59386272aa50590b566a1809d9 (patch) | |
tree | 98f265501e5474327a5138bf9ca38736c15f4b38 /vl.c | |
parent | a74b4d2c23a5da45a5ef9eec18ce00923b6bab15 (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.c | 64 |
1 files changed, 64 insertions, 0 deletions
@@ -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)); |