Skip to content

Commit ed6eebf

Browse files
committed
tools/xenstore: dump the xenstore state for live update
Dump the complete Xenstore status to a file (daemon case) or memory (stubdom case). As we don't know the exact length of the needed area in advance we are using an anonymous rather large mapping in stubdom case, which will use only virtual address space until accessed. And as we are writing the area in a sequential manner this is fine. As the initial size we are choosing the double size of the memory allocated via talloc(), which should be more than enough. Signed-off-by: Juergen Gross <[email protected]> Reviewed-by: Paul Durrant <[email protected]> Acked-by: Julien Grall <[email protected]> Acked-by: Wei Liu <[email protected]>
1 parent 3fab4e4 commit ed6eebf

File tree

9 files changed

+512
-6
lines changed

9 files changed

+512
-6
lines changed

tools/xenstore/utils.c

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,3 +62,20 @@ void barf_perror(const char *fmt, ...)
6262
}
6363
exit(1);
6464
}
65+
66+
const char *dump_state_align(FILE *fp)
67+
{
68+
long len;
69+
static char nul[8] = {};
70+
71+
len = ftell(fp);
72+
if (len < 0)
73+
return "Dump state align error";
74+
len &= 7;
75+
if (!len)
76+
return NULL;
77+
78+
if (fwrite(nul, 8 - len, 1, fp) != 1)
79+
return "Dump state align error";
80+
return NULL;
81+
}

tools/xenstore/utils.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
#include <stdbool.h>
44
#include <string.h>
55
#include <stdint.h>
6+
#include <stdio.h>
67

78
#include <xen-tools/libs.h>
89

@@ -21,6 +22,11 @@ static inline bool strends(const char *a, const char *b)
2122
return streq(a + strlen(a) - strlen(b), b);
2223
}
2324

25+
/*
26+
* Write NUL bytes for aligning state data to 8 bytes.
27+
*/
28+
const char *dump_state_align(FILE *fp);
29+
2430
void barf(const char *fmt, ...) __attribute__((noreturn));
2531
void barf_perror(const char *fmt, ...) __attribute__((noreturn));
2632

tools/xenstore/xenstored_control.c

Lines changed: 101 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,21 @@ Interactive commands for Xen Store Daemon.
2525
#include <time.h>
2626
#include <sys/types.h>
2727
#include <sys/stat.h>
28+
#include <sys/mman.h>
29+
#include <fcntl.h>
2830
#include <unistd.h>
31+
#include <xenctrl.h>
2932

3033
#include "utils.h"
3134
#include "talloc.h"
3235
#include "xenstored_core.h"
3336
#include "xenstored_control.h"
37+
#include "xenstored_domain.h"
38+
39+
/* Mini-OS only knows about MAP_ANON. */
40+
#ifndef MAP_ANONYMOUS
41+
#define MAP_ANONYMOUS MAP_ANON
42+
#endif
3443

3544
struct live_update {
3645
/* For verification the correct connection is acting. */
@@ -40,6 +49,9 @@ struct live_update {
4049
void *kernel;
4150
unsigned int kernel_size;
4251
unsigned int kernel_off;
52+
53+
void *dump_state;
54+
unsigned long dump_size;
4355
#else
4456
char *filename;
4557
#endif
@@ -56,6 +68,10 @@ static struct live_update *lu_status;
5668

5769
static int lu_destroy(void *data)
5870
{
71+
#ifdef __MINIOS__
72+
if (lu_status->dump_state)
73+
munmap(lu_status->dump_state, lu_status->dump_size);
74+
#endif
5975
lu_status = NULL;
6076

6177
return 0;
@@ -274,6 +290,31 @@ static const char *lu_arch(const void *ctx, struct connection *conn,
274290
errno = EINVAL;
275291
return NULL;
276292
}
293+
294+
static FILE *lu_dump_open(const void *ctx)
295+
{
296+
lu_status->dump_size = ROUNDUP(talloc_total_size(NULL) * 2,
297+
XC_PAGE_SHIFT);
298+
lu_status->dump_state = mmap(NULL, lu_status->dump_size,
299+
PROT_READ | PROT_WRITE,
300+
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
301+
if (lu_status->dump_state == MAP_FAILED)
302+
return NULL;
303+
304+
return fmemopen(lu_status->dump_state, lu_status->dump_size, "w");
305+
}
306+
307+
static void lu_dump_close(FILE *fp)
308+
{
309+
size_t size;
310+
311+
size = ftell(fp);
312+
size = ROUNDUP(size, XC_PAGE_SHIFT);
313+
munmap(lu_status->dump_state + size, lu_status->dump_size - size);
314+
lu_status->dump_size = size;
315+
316+
fclose(fp);
317+
}
277318
#else
278319
static const char *lu_binary(const void *ctx, struct connection *conn,
279320
const char *filename)
@@ -308,6 +349,27 @@ static const char *lu_arch(const void *ctx, struct connection *conn,
308349
errno = EINVAL;
309350
return NULL;
310351
}
352+
353+
static FILE *lu_dump_open(const void *ctx)
354+
{
355+
char *filename;
356+
int fd;
357+
358+
filename = talloc_asprintf(ctx, "%s/state_dump", xs_daemon_rootdir());
359+
if (!filename)
360+
return NULL;
361+
362+
fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR);
363+
if (fd < 0)
364+
return NULL;
365+
366+
return fdopen(fd, "w");
367+
}
368+
369+
static void lu_dump_close(FILE *fp)
370+
{
371+
fclose(fp);
372+
}
311373
#endif
312374

313375
static bool lu_check_lu_allowed(void)
@@ -347,7 +409,45 @@ static const char *lu_reject_reason(const void *ctx)
347409

348410
static const char *lu_dump_state(const void *ctx, struct connection *conn)
349411
{
350-
return NULL;
412+
FILE *fp;
413+
const char *ret;
414+
struct xs_state_record_header end;
415+
struct xs_state_preamble pre;
416+
417+
fp = lu_dump_open(ctx);
418+
if (!fp)
419+
return "Dump state open error";
420+
421+
memcpy(pre.ident, XS_STATE_IDENT, sizeof(pre.ident));
422+
pre.version = htobe32(XS_STATE_VERSION);
423+
pre.flags = XS_STATE_FLAGS;
424+
if (fwrite(&pre, sizeof(pre), 1, fp) != 1) {
425+
ret = "Dump write error";
426+
goto out;
427+
}
428+
429+
ret = dump_state_global(fp);
430+
if (ret)
431+
goto out;
432+
ret = dump_state_connections(fp, conn);
433+
if (ret)
434+
goto out;
435+
ret = dump_state_special_nodes(fp);
436+
if (ret)
437+
goto out;
438+
ret = dump_state_nodes(fp, ctx);
439+
if (ret)
440+
goto out;
441+
442+
end.type = XS_STATE_TYPE_END;
443+
end.length = 0;
444+
if (fwrite(&end, sizeof(end), 1, fp) != 1)
445+
ret = "Dump write error";
446+
447+
out:
448+
lu_dump_close(fp);
449+
450+
return ret;
351451
}
352452

353453
static const char *lu_activate_binary(const void *ctx)

0 commit comments

Comments
 (0)