add chdir
[snitchaser:mainline.git] / oldcode / ckptutils.c
1 /* 
2  * ckptutils.c
3  * by WN @ Jul. 16, 2009
4  */
5
6 #include <errno.h>
7 #include <string.h>
8 #include <sys/stat.h>
9 #include <unistd.h>
10 #include <fcntl.h>
11 #include <sys/mman.h>
12
13 #include "debug.h"
14 #include "exception.h"
15 #include "ckptutils.h"
16 #include "checkpoint/checkpoint.h"
17
18 static void
19 ckpt_clup(struct cleanup * clup)
20 {
21         remove_cleanup(clup);
22         struct ckpt_file * s = container_of(clup, struct ckpt_file,
23                         clup);
24         if (s->regions != NULL) {
25                 free(s->regions);
26         }
27         if (s->cmdline != NULL) {
28                 free(s->cmdline);
29         }
30         if (s->environ != NULL) {
31                 free(s->environ);
32         }
33         free(s);
34 }
35
36 static char *
37 build_strlst(char *** array, char * ptr)
38 {
39         int len;
40         int nr_items = 0;
41
42         do {
43                 nr_items ++;
44                 *array = realloc(*array, nr_items * sizeof(char*));
45                 (*array)[nr_items - 1] = ptr;
46                 len = strlen(ptr);
47                 ptr += len + 1;
48         } while (len != 0);
49         /* set the last item to NULL */
50         (*array)[nr_items - 1] = NULL;
51         return ptr;
52 }
53
54 static void *
55 build_cmd_env(struct ckpt_file * s, void * cmdline)
56 {
57
58         char * ptr = cmdline;
59
60         ptr = build_strlst(&(s->cmdline), ptr);
61         ptr = build_strlst(&(s->environ), ptr);
62
63         return ptr;
64 }
65
66 struct ckpt_file *
67 load_ckpt_file(char * fn)
68 {
69         struct ckpt_file * s = calloc(1, sizeof(*s));
70         assert(s != NULL);
71         s->clup.function = ckpt_clup;
72
73         make_cleanup(&s->clup);
74
75         errno = 0;
76
77         /* map the ckpt file */
78         int fd;
79         errno = 0;
80         fd = open(fn, O_RDONLY);
81         ETHROW("open %s failed: %s", fn, strerror(errno));
82
83         struct stat st;
84         fstat(fd, &st);
85         ETHROW("fstat failed: %s", strerror(errno));
86
87         void * ckpt_img;
88         ckpt_img = mmap(NULL, st.st_size, PROT_READ,
89                         MAP_PRIVATE, fd, 0);
90         ETHROW("mmap failed: %s", strerror(errno));
91         close(fd);
92
93         s->ckpt_img = ckpt_img;
94
95         /* check magic */
96         if (*(uint32_t*)ckpt_img != CKPT_MAGIC)
97                 THROW(EXCEPTION_FATAL, "magic mismatch");
98
99         /* build cmdline */
100         void * p;
101         p = build_cmd_env(s, ckpt_img + sizeof(CKPT_MAGIC));
102
103         /* set the state */
104         s->state = p;
105         p += sizeof(*(s->state));
106
107         /* load mem regions */
108         uint32_t sz_m = 0;
109         s->nr_regions = 0;
110         sz_m = *(uint32_t *)p;
111         p += sizeof(sz_m);
112         while (sz_m != 0) {
113                 s->nr_regions ++;
114                 s->regions = realloc(s->regions,
115                                 s->nr_regions * sizeof(*s->regions));
116                 struct mem_region * mr = p;
117
118                 SYS_TRACE("region %d, start: 0x%x, end: 0x%x (p-img=0x%x)\n",
119                                 s->nr_regions, mr->start, mr->end, p - ckpt_img);
120
121                 s->regions[s->nr_regions - 1] = mr;
122                 p += sz_m;
123                 /* no vdso in ckpt */
124                 if (strncmp("[vdso]", mr->fn, 6) != 0)
125                         p += mr->end - mr->start;
126                 sz_m = *(uint32_t *)p;
127                 p += sizeof(sz_m);
128         }
129         return s;
130 }
131
132
133 void
134 close_ckpt_file(struct ckpt_file * f)
135 {
136         ckpt_clup(&f->clup);
137 }
138