qemu-file.h 9.3 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
/*
 * QEMU System Emulator
 *
 * Copyright (c) 2003-2008 Fabrice Bellard
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */
#ifndef QEMU_FILE_H
#define QEMU_FILE_H 1
M
Michael R. Hines 已提交
26
#include "exec/cpu-common.h"
27

28 29
#include <stdint.h>

30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52
/* This function writes a chunk of data to a file at the given position.
 * The pos argument can be ignored if the file is only being used for
 * streaming.  The handler should try to write all of the data it can.
 */
typedef int (QEMUFilePutBufferFunc)(void *opaque, const uint8_t *buf,
                                    int64_t pos, int size);

/* Read a chunk of data from a file at the given position.  The pos argument
 * can be ignored if the file is only be used for streaming.  The number of
 * bytes actually read should be returned.
 */
typedef int (QEMUFileGetBufferFunc)(void *opaque, uint8_t *buf,
                                    int64_t pos, int size);

/* Close a file
 *
 * Return negative error number on error, 0 or positive value on success.
 *
 * The meaning of return value on success depends on the specific back-end being
 * used.
 */
typedef int (QEMUFileCloseFunc)(void *opaque);

P
Paolo Bonzini 已提交
53 54 55 56
/* Called to return the OS file descriptor associated to the QEMUFile.
 */
typedef int (QEMUFileGetFD)(void *opaque);

57 58 59 60
/*
 * This function writes an iovec to file.
 */
typedef ssize_t (QEMUFileWritevBufferFunc)(void *opaque, struct iovec *iov,
61
                                           int iovcnt, int64_t pos);
62

M
Michael R. Hines 已提交
63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84
/*
 * This function provides hooks around different
 * stages of RAM migration.
 */
typedef int (QEMURamHookFunc)(QEMUFile *f, void *opaque, uint64_t flags);

/*
 * Constants used by ram_control_* hooks
 */
#define RAM_CONTROL_SETUP    0
#define RAM_CONTROL_ROUND    1
#define RAM_CONTROL_HOOK     2
#define RAM_CONTROL_FINISH   3

/*
 * This function allows override of where the RAM page
 * is saved (such as RDMA, for example.)
 */
typedef size_t (QEMURamSaveFunc)(QEMUFile *f, void *opaque,
                               ram_addr_t block_offset,
                               ram_addr_t offset,
                               size_t size,
85
                               uint64_t *bytes_sent);
M
Michael R. Hines 已提交
86

D
Dr. David Alan Gilbert 已提交
87 88 89 90 91 92 93 94
/*
 * Stop any read or write (depending on flags) on the underlying
 * transport on the QEMUFile.
 * Existing blocking reads/writes must be woken
 * Returns 0 on success, -err on error
 */
typedef int (QEMUFileShutdownFunc)(void *opaque, bool rd, bool wr);

95 96 97 98
typedef struct QEMUFileOps {
    QEMUFilePutBufferFunc *put_buffer;
    QEMUFileGetBufferFunc *get_buffer;
    QEMUFileCloseFunc *close;
P
Paolo Bonzini 已提交
99
    QEMUFileGetFD *get_fd;
100
    QEMUFileWritevBufferFunc *writev_buffer;
M
Michael R. Hines 已提交
101 102 103 104
    QEMURamHookFunc *before_ram_iterate;
    QEMURamHookFunc *after_ram_iterate;
    QEMURamHookFunc *hook_ram_load;
    QEMURamSaveFunc *save_page;
D
Dr. David Alan Gilbert 已提交
105
    QEMUFileShutdownFunc *shut_down;
106 107
} QEMUFileOps;

108 109 110 111 112 113 114
struct QEMUSizedBuffer {
    struct iovec *iov;
    size_t n_iov;
    size_t size; /* total allocated size in all iov's */
    size_t used; /* number of used bytes */
};

115
QEMUFile *qemu_fopen_ops(void *opaque, const QEMUFileOps *ops);
116 117
QEMUFile *qemu_fopen(const char *filename, const char *mode);
QEMUFile *qemu_fdopen(int fd, const char *mode);
118
QEMUFile *qemu_fopen_socket(int fd, const char *mode);
119
QEMUFile *qemu_popen_cmd(const char *command, const char *mode);
120
QEMUFile *qemu_bufopen(const char *mode, QEMUSizedBuffer *input);
P
Paolo Bonzini 已提交
121
int qemu_get_fd(QEMUFile *f);
122
int qemu_fclose(QEMUFile *f);
123
int64_t qemu_ftell(QEMUFile *f);
124
int64_t qemu_ftell_fast(QEMUFile *f);
125 126
void qemu_put_buffer(QEMUFile *f, const uint8_t *buf, int size);
void qemu_put_byte(QEMUFile *f, int v);
O
Orit Wasserman 已提交
127 128 129 130 131
/*
 * put_buffer without copying the buffer.
 * The buffer should be available till it is sent asynchronously.
 */
void qemu_put_buffer_async(QEMUFile *f, const uint8_t *buf, int size);
132
bool qemu_file_mode_is_not_valid(const char *mode);
133
bool qemu_file_is_writable(QEMUFile *f);
134

135 136 137 138 139 140 141 142 143 144 145 146 147 148 149
QEMUSizedBuffer *qsb_create(const uint8_t *buffer, size_t len);
void qsb_free(QEMUSizedBuffer *);
size_t qsb_set_length(QEMUSizedBuffer *qsb, size_t length);
size_t qsb_get_length(const QEMUSizedBuffer *qsb);
ssize_t qsb_get_buffer(const QEMUSizedBuffer *, off_t start, size_t count,
                       uint8_t *buf);
ssize_t qsb_write_at(QEMUSizedBuffer *qsb, const uint8_t *buf,
                     off_t pos, size_t count);


/*
 * For use on files opened with qemu_bufopen
 */
const QEMUSizedBuffer *qemu_buf_get(QEMUFile *f);

150 151 152 153 154 155 156 157 158 159
static inline void qemu_put_ubyte(QEMUFile *f, unsigned int v)
{
    qemu_put_byte(f, (int)v);
}

#define qemu_put_sbyte qemu_put_byte

void qemu_put_be16(QEMUFile *f, unsigned int v);
void qemu_put_be32(QEMUFile *f, unsigned int v);
void qemu_put_be64(QEMUFile *f, uint64_t v);
160
int qemu_peek_buffer(QEMUFile *f, uint8_t **buf, int size, size_t offset);
161
int qemu_get_buffer(QEMUFile *f, uint8_t *buf, int size);
162 163 164
ssize_t qemu_put_compression_data(QEMUFile *f, const uint8_t *p, size_t size,
                                  int level);
int qemu_put_qemu_file(QEMUFile *f_des, QEMUFile *f_src);
165 166 167 168 169
/*
 * Note that you can only peek continuous bytes from where the current pointer
 * is; you aren't guaranteed to be able to peak to +n bytes unless you've
 * previously peeked +n-1.
 */
170
int qemu_peek_byte(QEMUFile *f, int offset);
171
int qemu_get_byte(QEMUFile *f);
172
void qemu_file_skip(QEMUFile *f, int size);
173
void qemu_update_position(QEMUFile *f, size_t size);
174 175 176 177 178 179 180 181 182 183 184 185 186

static inline unsigned int qemu_get_ubyte(QEMUFile *f)
{
    return (unsigned int)qemu_get_byte(f);
}

#define qemu_get_sbyte qemu_get_byte

unsigned int qemu_get_be16(QEMUFile *f);
unsigned int qemu_get_be32(QEMUFile *f);
uint64_t qemu_get_be64(QEMUFile *f);

int qemu_file_rate_limit(QEMUFile *f);
187 188
void qemu_file_reset_rate_limit(QEMUFile *f);
void qemu_file_set_rate_limit(QEMUFile *f, int64_t new_rate);
189 190
int64_t qemu_file_get_rate_limit(QEMUFile *f);
int qemu_file_get_error(QEMUFile *f);
191
void qemu_file_set_error(QEMUFile *f, int ret);
D
Dr. David Alan Gilbert 已提交
192
int qemu_file_shutdown(QEMUFile *f);
M
Michael R. Hines 已提交
193
void qemu_fflush(QEMUFile *f);
194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314

static inline void qemu_put_be64s(QEMUFile *f, const uint64_t *pv)
{
    qemu_put_be64(f, *pv);
}

static inline void qemu_put_be32s(QEMUFile *f, const uint32_t *pv)
{
    qemu_put_be32(f, *pv);
}

static inline void qemu_put_be16s(QEMUFile *f, const uint16_t *pv)
{
    qemu_put_be16(f, *pv);
}

static inline void qemu_put_8s(QEMUFile *f, const uint8_t *pv)
{
    qemu_put_byte(f, *pv);
}

static inline void qemu_get_be64s(QEMUFile *f, uint64_t *pv)
{
    *pv = qemu_get_be64(f);
}

static inline void qemu_get_be32s(QEMUFile *f, uint32_t *pv)
{
    *pv = qemu_get_be32(f);
}

static inline void qemu_get_be16s(QEMUFile *f, uint16_t *pv)
{
    *pv = qemu_get_be16(f);
}

static inline void qemu_get_8s(QEMUFile *f, uint8_t *pv)
{
    *pv = qemu_get_byte(f);
}

// Signed versions for type safety
static inline void qemu_put_sbuffer(QEMUFile *f, const int8_t *buf, int size)
{
    qemu_put_buffer(f, (const uint8_t *)buf, size);
}

static inline void qemu_put_sbe16(QEMUFile *f, int v)
{
    qemu_put_be16(f, (unsigned int)v);
}

static inline void qemu_put_sbe32(QEMUFile *f, int v)
{
    qemu_put_be32(f, (unsigned int)v);
}

static inline void qemu_put_sbe64(QEMUFile *f, int64_t v)
{
    qemu_put_be64(f, (uint64_t)v);
}

static inline size_t qemu_get_sbuffer(QEMUFile *f, int8_t *buf, int size)
{
    return qemu_get_buffer(f, (uint8_t *)buf, size);
}

static inline int qemu_get_sbe16(QEMUFile *f)
{
    return (int)qemu_get_be16(f);
}

static inline int qemu_get_sbe32(QEMUFile *f)
{
    return (int)qemu_get_be32(f);
}

static inline int64_t qemu_get_sbe64(QEMUFile *f)
{
    return (int64_t)qemu_get_be64(f);
}

static inline void qemu_put_s8s(QEMUFile *f, const int8_t *pv)
{
    qemu_put_8s(f, (const uint8_t *)pv);
}

static inline void qemu_put_sbe16s(QEMUFile *f, const int16_t *pv)
{
    qemu_put_be16s(f, (const uint16_t *)pv);
}

static inline void qemu_put_sbe32s(QEMUFile *f, const int32_t *pv)
{
    qemu_put_be32s(f, (const uint32_t *)pv);
}

static inline void qemu_put_sbe64s(QEMUFile *f, const int64_t *pv)
{
    qemu_put_be64s(f, (const uint64_t *)pv);
}

static inline void qemu_get_s8s(QEMUFile *f, int8_t *pv)
{
    qemu_get_8s(f, (uint8_t *)pv);
}

static inline void qemu_get_sbe16s(QEMUFile *f, int16_t *pv)
{
    qemu_get_be16s(f, (uint16_t *)pv);
}

static inline void qemu_get_sbe32s(QEMUFile *f, int32_t *pv)
{
    qemu_get_be32s(f, (uint32_t *)pv);
}

static inline void qemu_get_sbe64s(QEMUFile *f, int64_t *pv)
{
    qemu_get_be64s(f, (uint64_t *)pv);
}
315 316 317

size_t qemu_get_counted_string(QEMUFile *f, char buf[256]);

318
#endif