Statistics
| Branch: | Revision:

root / migration-fd.c @ 1de7afc9

History | View | Annotate | Download (2.5 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 "buffered_file.h"
21
#include "block/block.h"
22
#include "qemu/sockets.h"
23

    
24
//#define DEBUG_MIGRATION_FD
25

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

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

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

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

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

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

    
79
    fcntl(s->fd, F_SETFL, O_NONBLOCK);
80
    s->get_error = fd_errno;
81
    s->write = fd_write;
82
    s->close = fd_close;
83

    
84
    migrate_fd_connect(s);
85
}
86

    
87
static void fd_accept_incoming_migration(void *opaque)
88
{
89
    QEMUFile *f = opaque;
90

    
91
    qemu_set_fd_handler2(qemu_get_fd(f), NULL, NULL, NULL, NULL);
92
    process_incoming_migration(f);
93
}
94

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

    
100
    DPRINTF("Attempting to start an incoming migration via fd\n");
101

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

    
109
    qemu_set_fd_handler2(fd, NULL, fd_accept_incoming_migration, NULL, f);
110
}