2 * This file is part of the Palacios Virtual Machine Monitor developed
3 * by the V3VEE Project with funding from the United States National
4 * Science Foundation and the Department of Energy.
6 * The V3VEE Project is a joint project between Northwestern University
7 * and the University of New Mexico. You can find out more at
10 * Copyright (c) 2011, Madhav Suresh <madhav@u.northwestern.edu>
11 * Copyright (c) 2011, The V3VEE Project <http://www.v3vee.org>
12 * All rights reserved.
14 * Authors: Madhav Suresh <madhav@u.northwestern.edu>
15 * Mark Cartwright <mcartwright@gmail.com> (live migration)
16 * Peter Dinda <pdinda@northwestern.edu> (store interface changes)
18 * This is free software. You are permitted to use,
19 * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
22 #ifndef __VMM_CHECKPOINT_H__
23 #define __VMM_CHECKPOINT_H__
27 #include <palacios/vmm.h>
31 This code implements both checkpointing and live migration. The
32 main difference between these two is how the memory of the VM is
35 A checkpoint is written to/read from a checkpoint store. A
36 checkpoint store is conceptually an unseekable stream. This allows
37 us to reuse the same model for things like:
39 - checkpoint to memory
40 - checkpoint to directory of files
42 - checkpoint to network
43 - live migrate over network
45 To save data to a checkpoint store, you first open a context on the
46 checkpoint store, then you save data to the context. The data
47 consists of blobs tagged with strings.
49 Only a single context can be open at a time, and a context cannot be
50 reopened once it has been closed. These invariants are also essential
51 to maximizing compatability with different implementations.
53 The result of these constraints is that the stream that the
54 checkpoint store records will look like:
56 [contextname1][tag1len][tag1]][datalen][data][tag2len][tag2][datalen][data]....
57 [contextname2][tag1len][tag1]][datalen][data][tag2len][tag2][datalen][data]....
60 The code implemented here assures that
61 [tag?len][tag?][datalen][data] is written as shown above. The
62 checkpoint store handles [contextname?] internally. For example, it
63 might use the context names as files for a checkpoint, or it might
64 communicate the context names over a network stream.
66 To add checkpointing to your code, the primary thing you need to do
67 is implement save and load functions. For a device, you then add them
68 to your dev_ops structure. The save function takes an context.
69 You then write on this context using one of the following functions/macros:
71 1. v3_chkpt_save(context, tag, datalen, dataptr);
72 2. V3_CHKPT_SAVE(context, tag, data, faillabel);
73 3. V3_CHKPT_SAVE_AUTOTAG(context, data, faillabel)
75 Here (2) is a macro that computes the data length from sizeof(data)
76 while (3) does the same, and uses as the tag the name of the variable data.
77 We strongly recommend the use of (2).
79 These functions and macros will return -1 if the save is unsuccessful.
80 The faillabel argumnent is optional, if supplied and an error occurs,
81 the macro will goto the label.
83 Some classes of devices, for example IDE HDs and CD-ROMs, and PCI
84 devices have a class-specific component and a device-specific
85 component. For such devices, the class implementation (e.g., IDE, PCI)
86 will provide a class-specific save function that should be called first
87 in the device's save function. For example:
89 #include <devices/pci.h>
91 static int my_device_save(struct v3_chkpt_ctx *ctx, void *priv)
93 struct my_device *dev = priv;
95 if (v3_pci_save(ctx, dev->pci)<0) {
99 V3_CHKPT_SAVE(ctx, "myfoo", dev->foo, failout),;
100 V3_CHKPT_SAVE(ctx, "mybar", dev->bar, failout);
107 PrintError(info->vm_info, info, "Failed to save device\n");
112 The load side is symmetric.
119 struct v3_chkpt_ctx {
120 struct v3_chkpt * chkpt;
127 * You do not need to look behind this curtain
129 #define SELECT(x,A,FUNC, ...) FUNC
130 #define V3_CHKPT_SAVE_BASE(context, tag, data) v3_chkpt_save(context,tag,sizeof(data),&(data))
131 #define V3_CHKPT_SAVE_LABELED(context, tag, data, faillabel) (({if (V3_CHKPT_SAVE_BASE(context,tag,data)<0) { goto faillabel; } 0; }), 0)
132 #define V3_CHKPT_LOAD_BASE(context, tag, data) v3_chkpt_load(context,tag,sizeof(data),&(data))
133 #define V3_CHKPT_LOAD_LABELED(context, tag, data, faillabel) (({if (V3_CHKPT_LOAD_BASE(context,tag,data)<0) { goto faillabel; } 0; }), 0)
135 * Safe to open your eyes again
140 // Functions and macros to save to a context
143 int v3_chkpt_save(struct v3_chkpt_ctx * ctx, char * tag, uint64_t len, void * buf);
144 #define V3_CHKPT_SAVE(context, tag, data, ...) SELECT(,##__VA_ARGS__,V3_CHKPT_SAVE_LABELED(context,tag,data,__VA_ARGS__),V3_CHKPT_SAVE_BASE(context,tag,data))
145 #define V3_CHKPT_SAVE_AUTOTAG(context, data, ...) V3_CHKPT_SAVE(context, #data ,data,__VA_ARGS__)
148 // Funtions and macros to load from a context
151 int v3_chkpt_load(struct v3_chkpt_ctx * ctx, char * tag, uint64_t len, void * buf);
152 #define V3_CHKPT_LOAD(context, tag, data, ...) SELECT(,##__VA_ARGS__,V3_CHKPT_LOAD_LABELED(context,tag,data,__VA_ARGS__),V3_CHKPT_LOAD_BASE(context,tag,data))
153 #define V3_CHKPT_LOAD_AUTOTAG(context, data, ...) V3_CHKPT_LOAD(context, #data ,data,__VA_ARGS__)
156 struct v3_chkpt_ctx * v3_chkpt_open_ctx(struct v3_chkpt * chkpt, char * name);
157 int v3_chkpt_close_ctx(struct v3_chkpt_ctx * ctx);
160 typedef uint64_t v3_chkpt_options_t;
161 // The options are a bitwise or of the following
162 #define V3_CHKPT_OPT_NONE 0
163 #define V3_CHKPT_OPT_SKIP_MEM 1 // don't write memory to store
164 #define V3_CHKPT_OPT_SKIP_DEVS 2 // don't write devices to store
165 #define V3_CHKPT_OPT_SKIP_CORES 4 // don't write core arch ind data to store
166 #define V3_CHKPT_OPT_SKIP_ARCHDEP 8 // don't write core arch dep data to store
168 int v3_chkpt_save_vm(struct v3_vm_info * vm, char * store, char * url, v3_chkpt_options_t opts);
169 int v3_chkpt_load_vm(struct v3_vm_info * vm, char * store, char * url, v3_chkpt_options_t opts);
171 #ifdef V3_CONFIG_LIVE_MIGRATION
172 int v3_chkpt_send_vm(struct v3_vm_info * vm, char * store, char * url, v3_chkpt_options_t opts);
173 int v3_chkpt_receive_vm(struct v3_vm_info * vm, char * store, char * url, v3_chkpt_options_t opts);
176 int V3_init_checkpoint();
177 int V3_deinit_checkpoint();