Statistics
| Branch: | Revision:

root / migration-fd.c @ 396d2cfc

History | View | Annotate | Download (2.4 kB)

1
/*
2
 * QEMU live migration via generic fd
3
 *
4
 * Copyright Red Hat, Inc. 2009
5
 *
6
 * Authors:
7
 *  Chris Lalancette <clalance@redhat.com>
8
 *
9
 * This work is licensed under the terms of the GNU GPL, version 2.  See
10
 * the COPYING file in the top-level directory.
11
 *
12
 * Contributions after 2012-01-13 are licensed under the terms of the
13
 * GNU GPL, version 2 or (at your option) any later version.
14
 */
15

    
16
#include "qemu-common.h"
17
#include "qemu/sockets.h"
18
#include "migration/migration.h"
19
#include "monitor/monitor.h"
20
#include "migration/qemu-file.h"
21
#include "block/block.h"
22

    
23
//#define DEBUG_MIGRATION_FD
24

    
25
#ifdef DEBUG_MIGRATION_FD
26
#define DPRINTF(fmt, ...) \
27
    do { printf("migration-fd: " fmt, ## __VA_ARGS__); } while (0)
28
#else
29
#define DPRINTF(fmt, ...) \
30
    do { } while (0)
31
#endif
32

    
33
static int fd_errno(MigrationState *s)
34
{
35
    return errno;
36
}
37

    
38
static int fd_write(MigrationState *s, const void * buf, size_t size)
39
{
40
    return write(s->fd, buf, size);
41
}
42

    
43
static int fd_close(MigrationState *s)
44
{
45
    struct stat st;
46
    int ret;
47

    
48
    DPRINTF("fd_close\n");
49
    ret = fstat(s->fd, &st);
50
    if (ret == 0 && S_ISREG(st.st_mode)) {
51
        /*
52
         * If the file handle is a regular file make sure the
53
         * data is flushed to disk before signaling success.
54
         */
55
        ret = fsync(s->fd);
56
        if (ret != 0) {
57
            ret = -errno;
58
            perror("migration-fd: fsync");
59
            return ret;
60
        }
61
    }
62
    ret = close(s->fd);
63
    s->fd = -1;
64
    if (ret != 0) {
65
        ret = -errno;
66
        perror("migration-fd: close");
67
    }
68
    return ret;
69
}
70

    
71
void fd_start_outgoing_migration(MigrationState *s, const char *fdname, Error **errp)
72
{
73
    s->fd = monitor_get_fd(cur_mon, fdname, errp);
74
    if (s->fd == -1) {
75
        return;
76
    }
77

    
78
    s->get_error = fd_errno;
79
    s->write = fd_write;
80
    s->close = fd_close;
81

    
82
    migrate_fd_connect(s);
83
}
84

    
85
static void fd_accept_incoming_migration(void *opaque)
86
{
87
    QEMUFile *f = opaque;
88

    
89
    qemu_set_fd_handler2(qemu_get_fd(f), NULL, NULL, NULL, NULL);
90
    process_incoming_migration(f);
91
}
92

    
93
void fd_start_incoming_migration(const char *infd, Error **errp)
94
{
95
    int fd;
96
    QEMUFile *f;
97

    
98
    DPRINTF("Attempting to start an incoming migration via fd\n");
99

    
100
    fd = strtol(infd, NULL, 0);
101
    f = qemu_fdopen(fd, "rb");
102
    if(f == NULL) {
103
        error_setg_errno(errp, errno, "failed to open the source descriptor");
104
        return;
105
    }
106

    
107
    qemu_set_fd_handler2(fd, NULL, fd_accept_incoming_migration, NULL, f);
108
}