mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-05 00:33:55 -06:00
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
This commit is contained in:
parent
a74b4d2c23
commit
065e281356
7 changed files with 453 additions and 171 deletions
64
vl.c
64
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));
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue