source: trunk/packages/xen-3.1/xen-3.1/tools/ioemu/patches/ioemu-save-restore-logdirty @ 34

Last change on this file since 34 was 34, checked in by hartmans, 17 years ago

Add xen and xen-common

File size: 6.2 KB
Line 
1Index: ioemu/xenstore.c
2===================================================================
3--- ioemu.orig/xenstore.c       2007-05-03 10:42:11.000000000 +0100
4+++ ioemu/xenstore.c    2007-05-03 14:17:13.000000000 +0100
5@@ -11,6 +11,11 @@
6 #include "vl.h"
7 #include "block_int.h"
8 #include <unistd.h>
9+#include <sys/ipc.h>
10+#include <sys/shm.h>
11+#include <sys/types.h>
12+#include <sys/stat.h>
13+#include <fcntl.h>
14 
15 static struct xs_handle *xsh = NULL;
16 static char *media_filename[MAX_DISKS];
17@@ -173,6 +178,13 @@
18        }
19     }
20 
21+    /* Set a watch for log-dirty requests from the migration tools */
22+    if (pasprintf(&buf, "%s/logdirty/next-active", path) != -1) {
23+        xs_watch(xsh, buf, "logdirty");
24+        fprintf(logfile, "Watching %s\n", buf);
25+    }
26+
27+
28  out:
29     free(type);
30     free(params);
31@@ -191,6 +203,112 @@
32     return -1;
33 }
34 
35+unsigned long *logdirty_bitmap = NULL;
36+unsigned long logdirty_bitmap_size;
37+extern int vga_ram_size, bios_size;
38+
39+void xenstore_process_logdirty_event(void)
40+{
41+    char *act;
42+    static char *active_path = NULL;
43+    static char *next_active_path = NULL;
44+    static char *seg = NULL;
45+    unsigned int len;
46+    int i;
47+
48+    fprintf(logfile, "Triggered log-dirty buffer switch\n");
49+
50+    if (!seg) {
51+        char *path, *p, *key_ascii, key_terminated[17] = {0,};
52+        key_t key;
53+        int shmid;
54+
55+        /* Find and map the shared memory segment for log-dirty bitmaps */
56+        if (!(path = xs_get_domain_path(xsh, domid))) {           
57+            fprintf(logfile, "Log-dirty: can't get domain path in store\n");
58+            exit(1);
59+        }
60+        if (!(path = realloc(path, strlen(path)
61+                             + strlen("/logdirty/next-active") + 1))) {
62+            fprintf(logfile, "Log-dirty: out of memory\n");
63+            exit(1);
64+        }
65+        strcat(path, "/logdirty/");
66+        p = path + strlen(path);
67+        strcpy(p, "key");
68+       
69+        key_ascii = xs_read(xsh, XBT_NULL, path, &len);
70+        if (!key_ascii) {
71+            /* No key yet: wait for the next watch */
72+            free(path);
73+            return;
74+        }
75+        strncpy(key_terminated, key_ascii, 16);
76+        free(key_ascii);
77+        key = (key_t) strtoull(key_terminated, NULL, 16);
78+
79+        /* Figure out how bit the log-dirty bitmaps are */
80+        logdirty_bitmap_size = xc_memory_op(xc_handle,
81+                                            XENMEM_maximum_gpfn, &domid) + 1;
82+        logdirty_bitmap_size = ((logdirty_bitmap_size + HOST_LONG_BITS - 1)
83+                                / HOST_LONG_BITS); /* longs */
84+        logdirty_bitmap_size *= sizeof (unsigned long); /* bytes */
85+
86+        /* Map the shared-memory segment */
87+        if ((shmid = shmget(key,
88+                            2 * logdirty_bitmap_size,
89+                            S_IRUSR|S_IWUSR)) == -1
90+            || (seg = shmat(shmid, NULL, 0)) == (void *)-1) {
91+            fprintf(logfile, "Log-dirty: can't map segment %16.16llx (%s)\n",
92+                    (unsigned long long) key, strerror(errno));
93+            exit(1);
94+        }
95+
96+        fprintf(logfile, "Log-dirty: mapped segment at %p\n", seg);
97+
98+        /* Double-check that the bitmaps are the size we expect */
99+        if (logdirty_bitmap_size != *(uint32_t *)seg) {
100+            fprintf(logfile, "Log-dirty: got %u, calc %lu\n",
101+                    *(uint32_t *)seg, logdirty_bitmap_size);
102+            return;
103+        }
104+
105+        /* Remember the paths for the next-active and active entries */
106+        strcpy(p, "active");
107+        if (!(active_path = strdup(path))) {
108+            fprintf(logfile, "Log-dirty: out of memory\n");
109+            exit(1);
110+        }
111+        strcpy(p, "next-active");
112+        if (!(next_active_path = strdup(path))) {
113+            fprintf(logfile, "Log-dirty: out of memory\n");
114+            exit(1);
115+        }
116+        free(path);
117+    }
118+   
119+    /* Read the required active buffer from the store */
120+    act = xs_read(xsh, XBT_NULL, next_active_path, &len);
121+    if (!act) {
122+        fprintf(logfile, "Log-dirty: can't read next-active\n");
123+        exit(1);
124+    }
125+
126+    /* Switch buffers */
127+    i = act[0] - '0';
128+    if (i != 0 && i != 1) {
129+        fprintf(logfile, "Log-dirty: bad next-active entry: %s\n", act);
130+        exit(1);
131+    }
132+    logdirty_bitmap = (unsigned long *)(seg + i * logdirty_bitmap_size);
133+
134+    /* Ack that we've switched */
135+    xs_write(xsh, XBT_NULL, active_path, act, len);
136+    free(act);
137+}
138+
139+
140+
141 void xenstore_process_event(void *opaque)
142 {
143     char **vec, *image = NULL;
144@@ -200,6 +318,11 @@
145     if (!vec)
146        return;
147 
148+    if (!strcmp(vec[XS_WATCH_TOKEN], "logdirty")) {
149+        xenstore_process_logdirty_event();
150+        goto out;
151+    }
152+
153     if (strncmp(vec[XS_WATCH_TOKEN], "hd", 2) ||
154        strlen(vec[XS_WATCH_TOKEN]) != 3)
155        goto out;
156Index: ioemu/target-i386-dm/exec-dm.c
157===================================================================
158--- ioemu.orig/target-i386-dm/exec-dm.c 2007-05-03 14:13:38.000000000 +0100
159+++ ioemu/target-i386-dm/exec-dm.c      2007-05-03 14:18:14.000000000 +0100
160@@ -431,6 +431,9 @@
161 #define phys_ram_addr(x) ((addr < ram_size) ? (phys_ram_base + (x)) : NULL)
162 #endif
163 
164+extern unsigned long *logdirty_bitmap;
165+extern unsigned long logdirty_bitmap_size;
166+
167 void cpu_physical_memory_rw(target_phys_addr_t addr, uint8_t *buf,
168                             int len, int is_write)
169 {
170@@ -466,8 +469,19 @@
171                     l = 1;
172                 }
173             } else if ((ptr = phys_ram_addr(addr)) != NULL) {
174-                /* Reading from RAM */
175+                /* Writing to RAM */
176                 memcpy(ptr, buf, l);
177+                if (logdirty_bitmap != NULL) {
178+                    /* Record that we have dirtied this frame */
179+                    unsigned long pfn = addr >> TARGET_PAGE_BITS;
180+                    if (pfn / 8 >= logdirty_bitmap_size) {
181+                        fprintf(logfile, "dirtying pfn %lx >= bitmap "
182+                                "size %lx\n", pfn, logdirty_bitmap_size * 8);
183+                    } else {
184+                        logdirty_bitmap[pfn / HOST_LONG_BITS]
185+                            |= 1UL << pfn % HOST_LONG_BITS;
186+                    }
187+                }
188 #ifdef __ia64__
189                 sync_icache(ptr, l);
190 #endif
Note: See TracBrowser for help on using the repository browser.