These changes are the raw update to qemu-2.6.
[kvmfornfv.git] / qemu / tests / libqos / libqos.c
1 #include "qemu/osdep.h"
2 #include <glib.h>
3 #include <sys/wait.h>
4
5 #include "libqtest.h"
6 #include "libqos/libqos.h"
7 #include "libqos/pci.h"
8
9 /*** Test Setup & Teardown ***/
10
11 /**
12  * Launch QEMU with the given command line,
13  * and then set up interrupts and our guest malloc interface.
14  */
15 QOSState *qtest_vboot(QOSOps *ops, const char *cmdline_fmt, va_list ap)
16 {
17     char *cmdline;
18
19     struct QOSState *qs = g_malloc(sizeof(QOSState));
20
21     cmdline = g_strdup_vprintf(cmdline_fmt, ap);
22     qs->qts = qtest_start(cmdline);
23     qs->ops = ops;
24     qtest_irq_intercept_in(global_qtest, "ioapic");
25     if (ops && ops->init_allocator) {
26         qs->alloc = ops->init_allocator(ALLOC_NO_FLAGS);
27     }
28
29     g_free(cmdline);
30     return qs;
31 }
32
33 /**
34  * Launch QEMU with the given command line,
35  * and then set up interrupts and our guest malloc interface.
36  */
37 QOSState *qtest_boot(QOSOps *ops, const char *cmdline_fmt, ...)
38 {
39     QOSState *qs;
40     va_list ap;
41
42     va_start(ap, cmdline_fmt);
43     qs = qtest_vboot(ops, cmdline_fmt, ap);
44     va_end(ap);
45
46     return qs;
47 }
48
49 /**
50  * Tear down the QEMU instance.
51  */
52 void qtest_shutdown(QOSState *qs)
53 {
54     if (qs->alloc && qs->ops && qs->ops->uninit_allocator) {
55         qs->ops->uninit_allocator(qs->alloc);
56         qs->alloc = NULL;
57     }
58     qtest_quit(qs->qts);
59     g_free(qs);
60 }
61
62 void set_context(QOSState *s)
63 {
64     global_qtest = s->qts;
65 }
66
67 static QDict *qmp_execute(const char *command)
68 {
69     char *fmt;
70     QDict *rsp;
71
72     fmt = g_strdup_printf("{ 'execute': '%s' }", command);
73     rsp = qmp(fmt);
74     g_free(fmt);
75
76     return rsp;
77 }
78
79 void migrate(QOSState *from, QOSState *to, const char *uri)
80 {
81     const char *st;
82     char *s;
83     QDict *rsp, *sub;
84     bool running;
85
86     set_context(from);
87
88     /* Is the machine currently running? */
89     rsp = qmp_execute("query-status");
90     g_assert(qdict_haskey(rsp, "return"));
91     sub = qdict_get_qdict(rsp, "return");
92     g_assert(qdict_haskey(sub, "running"));
93     running = qdict_get_bool(sub, "running");
94     QDECREF(rsp);
95
96     /* Issue the migrate command. */
97     s = g_strdup_printf("{ 'execute': 'migrate',"
98                         "'arguments': { 'uri': '%s' } }",
99                         uri);
100     rsp = qmp(s);
101     g_free(s);
102     g_assert(qdict_haskey(rsp, "return"));
103     QDECREF(rsp);
104
105     /* Wait for STOP event, but only if we were running: */
106     if (running) {
107         qmp_eventwait("STOP");
108     }
109
110     /* If we were running, we can wait for an event. */
111     if (running) {
112         migrate_allocator(from->alloc, to->alloc);
113         set_context(to);
114         qmp_eventwait("RESUME");
115         return;
116     }
117
118     /* Otherwise, we need to wait: poll until migration is completed. */
119     while (1) {
120         rsp = qmp_execute("query-migrate");
121         g_assert(qdict_haskey(rsp, "return"));
122         sub = qdict_get_qdict(rsp, "return");
123         g_assert(qdict_haskey(sub, "status"));
124         st = qdict_get_str(sub, "status");
125
126         /* "setup", "active", "completed", "failed", "cancelled" */
127         if (strcmp(st, "completed") == 0) {
128             QDECREF(rsp);
129             break;
130         }
131
132         if ((strcmp(st, "setup") == 0) || (strcmp(st, "active") == 0)) {
133             QDECREF(rsp);
134             g_usleep(5000);
135             continue;
136         }
137
138         fprintf(stderr, "Migration did not complete, status: %s\n", st);
139         g_assert_not_reached();
140     }
141
142     migrate_allocator(from->alloc, to->alloc);
143     set_context(to);
144 }
145
146 bool have_qemu_img(void)
147 {
148     char *rpath;
149     const char *path = getenv("QTEST_QEMU_IMG");
150     if (!path) {
151         return false;
152     }
153
154     rpath = realpath(path, NULL);
155     if (!rpath) {
156         return false;
157     } else {
158         free(rpath);
159         return true;
160     }
161 }
162
163 void mkimg(const char *file, const char *fmt, unsigned size_mb)
164 {
165     gchar *cli;
166     bool ret;
167     int rc;
168     GError *err = NULL;
169     char *qemu_img_path;
170     gchar *out, *out2;
171     char *qemu_img_abs_path;
172
173     qemu_img_path = getenv("QTEST_QEMU_IMG");
174     g_assert(qemu_img_path);
175     qemu_img_abs_path = realpath(qemu_img_path, NULL);
176     g_assert(qemu_img_abs_path);
177
178     cli = g_strdup_printf("%s create -f %s %s %uM", qemu_img_abs_path,
179                           fmt, file, size_mb);
180     ret = g_spawn_command_line_sync(cli, &out, &out2, &rc, &err);
181     if (err) {
182         fprintf(stderr, "%s\n", err->message);
183         g_error_free(err);
184     }
185     g_assert(ret && !err);
186
187     /* In glib 2.34, we have g_spawn_check_exit_status. in 2.12, we don't.
188      * glib 2.43.91 implementation assumes that any non-zero is an error for
189      * windows, but uses extra precautions for Linux. However,
190      * 0 is only possible if the program exited normally, so that should be
191      * sufficient for our purposes on all platforms, here. */
192     if (rc) {
193         fprintf(stderr, "qemu-img returned status code %d\n", rc);
194     }
195     g_assert(!rc);
196
197     g_free(out);
198     g_free(out2);
199     g_free(cli);
200     free(qemu_img_abs_path);
201 }
202
203 void mkqcow2(const char *file, unsigned size_mb)
204 {
205     return mkimg(file, "qcow2", size_mb);
206 }
207
208 void prepare_blkdebug_script(const char *debug_fn, const char *event)
209 {
210     FILE *debug_file = fopen(debug_fn, "w");
211     int ret;
212
213     fprintf(debug_file, "[inject-error]\n");
214     fprintf(debug_file, "event = \"%s\"\n", event);
215     fprintf(debug_file, "errno = \"5\"\n");
216     fprintf(debug_file, "state = \"1\"\n");
217     fprintf(debug_file, "immediately = \"off\"\n");
218     fprintf(debug_file, "once = \"on\"\n");
219
220     fprintf(debug_file, "[set-state]\n");
221     fprintf(debug_file, "event = \"%s\"\n", event);
222     fprintf(debug_file, "new_state = \"2\"\n");
223     fflush(debug_file);
224     g_assert(!ferror(debug_file));
225
226     ret = fclose(debug_file);
227     g_assert(ret == 0);
228 }
229
230 void generate_pattern(void *buffer, size_t len, size_t cycle_len)
231 {
232     int i, j;
233     unsigned char *tx = (unsigned char *)buffer;
234     unsigned char p;
235     size_t *sx;
236
237     /* Write an indicative pattern that varies and is unique per-cycle */
238     p = rand() % 256;
239     for (i = 0; i < len; i++) {
240         tx[i] = p++ % 256;
241         if (i % cycle_len == 0) {
242             p = rand() % 256;
243         }
244     }
245
246     /* force uniqueness by writing an id per-cycle */
247     for (i = 0; i < len / cycle_len; i++) {
248         j = i * cycle_len;
249         if (j + sizeof(*sx) <= len) {
250             sx = (size_t *)&tx[j];
251             *sx = i;
252         }
253     }
254 }