Subject: Small changes to libxc (save/restore part 4)
To: None <>
From: Jed Davis <>
List: port-xen
Date: 09/08/2005 00:55:53

What I've been slowly leading up to: with this and the other three
changes I've posted about today, I can successfully (and consistently)
save and restore a Linux domU with a NetBSD dom0.  Save/restore of a
NetBSD domU would be nicer, but I'm not there yet.

libxc change #1 is to have xfrd's forked child munmap each 4MB batch
of foreign RAM after it's done writing it, rather than unmapping only
the last one and letting the process's exit clean up the rest.  This
really does look like a simple mistake, and strictly speaking it's not
that big a deal -- but on NetBSD, the foreign mappings count against
the process's locked memory rlimit as if it were the dom0's own RAM.

libxc change #2... I don't really understand the problem; it has
something to do with live migration and the domU releasing
pseudo-physical pages after they were sent but before it's suspended.
Except that, for non-live mode, I think it's reporting all the holes
in the pseudo-physical range, even though those pages haven't been
sent.  In any case, the result is that the restoring xfrd fails to
decrease_reservation the pages away.  And I distinctly recall this
working at least once under Linux with Xen 2, but I have little idea
what NetBSD might be doing differently.

This, then, is the patch:

Content-Type: text/x-patch
Content-Disposition: inline; filename=xc_linux_save.patch
Content-Description: Poorly understood, minor changes to libxc's linux domU saving routing.

--- tools/libxc/xc_linux_save.c.orig	2005-08-03 19:57:57.000000000 -0400
+++ tools/libxc/xc_linux_save.c	2005-09-06 23:23:44.000000000 -0400
@@ -850,11 +850,10 @@
             } /* end of the write out for this batch */
             sent_this_iter += batch;
+            munmap(region_base, batch*PAGE_SIZE);
         } /* end of this while loop for this iteration */
-        munmap(region_base, batch*PAGE_SIZE);
         total_sent += sent_this_iter;
@@ -950,7 +949,7 @@
 	for ( i = 0, j = 0; i < nr_pfns; i++ )
-	    if ( ! is_mapped(live_pfn_to_mfn_table[i]) )
+	    if ( ! is_mapped(live_pfn_to_mfn_table[i]) && !test_bit(i, to_fix) )
@@ -962,7 +961,7 @@
 	for ( i = 0, j = 0; i < nr_pfns; )
-	    if ( ! is_mapped(live_pfn_to_mfn_table[i]) )
+	    if ( ! is_mapped(live_pfn_to_mfn_table[i]) && !test_bit(i, to_fix) )
 		pfntab[j++] = i;


(let ((C call-with-current-continuation)) (apply (lambda (x y) (x y)) (map
((lambda (r) ((C C) (lambda (s) (r (lambda l (apply (s s) l))))))  (lambda
(f) (lambda (l) (if (null? l) C (lambda (k) (display (car l)) ((f (cdr l))
(C k)))))))    '((#\J #\d #\D #\v #\s) (#\e #\space #\a #\i #\newline)))))