aboutsummaryrefslogtreecommitdiffstats
path: root/tools/xc/lib/xc_linux_restore.c
diff options
context:
space:
mode:
authoriap10@labyrinth.cl.cam.ac.uk <iap10@labyrinth.cl.cam.ac.uk>2004-05-04 16:24:42 +0000
committeriap10@labyrinth.cl.cam.ac.uk <iap10@labyrinth.cl.cam.ac.uk>2004-05-04 16:24:42 +0000
commit19c472bc9f66da83cbadbd3d14be99007b013035 (patch)
tree65a64082bf07fd8d09a9c239f1a33af68d0e7f03 /tools/xc/lib/xc_linux_restore.c
parent0720bf34a431e000c7e02d5f7f55c2374637fceb (diff)
parent7b2eb5ed360b124204f8a216bd1c0e3b6f04eaba (diff)
downloadxen-19c472bc9f66da83cbadbd3d14be99007b013035.tar.gz
xen-19c472bc9f66da83cbadbd3d14be99007b013035.tar.bz2
xen-19c472bc9f66da83cbadbd3d14be99007b013035.zip
bitkeeper revision 1.889 (4097c3catd8FeHBrQzC16T5v8TLJKg)
Merge labyrinth.cl.cam.ac.uk:/auto/groups/xeno/BK/xeno.bk into labyrinth.cl.cam.ac.uk:/auto/groups/xeno/users/iap10/xeno-clone/xeno.bk
Diffstat (limited to 'tools/xc/lib/xc_linux_restore.c')
-rw-r--r--tools/xc/lib/xc_linux_restore.c86
1 files changed, 44 insertions, 42 deletions
diff --git a/tools/xc/lib/xc_linux_restore.c b/tools/xc/lib/xc_linux_restore.c
index e27221281a..65ba875aef 100644
--- a/tools/xc/lib/xc_linux_restore.c
+++ b/tools/xc/lib/xc_linux_restore.c
@@ -45,25 +45,20 @@ static int get_pfn_list(int xc_handle,
return (ret < 0) ? -1 : op.u.getmemlist.num_pfns;
}
-static int checked_read(gzFile fd, void *buf, size_t count)
-{
- int rc;
- while ( ((rc = gzread(fd, buf, count)) == -1) && (errno == EINTR) )
- continue;
- return rc == count;
-}
int xc_linux_restore(int xc_handle,
u64 dom,
- const char *state_file,
- int verbose,
+ unsigned int flags,
+ int (*readerfn)(void *, void *, size_t),
+ void *readerst,
u64 *pdomid)
{
dom0_op_t op;
int rc = 1, i, j, n, k;
unsigned long mfn, pfn, xpfn;
unsigned int prev_pc, this_pc;
-
+ int verbose = flags & XCFLAGS_VERBOSE;
+
/* Number of page frames in use by this Linux session. */
unsigned long nr_pfns;
@@ -98,26 +93,10 @@ int xc_linux_restore(int xc_handle,
mfn_mapper_t *region_mapper, *mapper_handle1;
char *region_base;
- /* The name and descriptor of the file that we are reading from. */
- int fd;
- gzFile gfd;
-
mmu_t *mmu = NULL;
int pm_handle = -1;
- if ( (fd = open(state_file, O_RDONLY)) == -1 )
- {
- PERROR("Could not open state file for reading");
- return 1;
- }
-
- if ( (gfd = gzdopen(fd, "rb")) == NULL )
- {
- ERROR("Could not allocate decompression state for state file");
- close(fd);
- return 1;
- }
if ( mlock(&ctxt, sizeof(ctxt) ) )
{
@@ -128,18 +107,18 @@ int xc_linux_restore(int xc_handle,
}
/* Start writing out the saved-domain record. */
- if ( !checked_read(gfd, signature, 16) ||
+ if ( (*readerfn)(readerst, signature, 16) ||
(memcmp(signature, "LinuxGuestRecord", 16) != 0) )
{
ERROR("Unrecognised state format -- no signature found");
goto out;
}
- if ( !checked_read(gfd, name, sizeof(name)) ||
- !checked_read(gfd, &nr_pfns, sizeof(unsigned long)) ||
- !checked_read(gfd, &ctxt, sizeof(ctxt)) ||
- !checked_read(gfd, shared_info, PAGE_SIZE) ||
- !checked_read(gfd, pfn_to_mfn_frame_list, PAGE_SIZE) )
+ if ( (*readerfn)(readerst, name, sizeof(name)) ||
+ (*readerfn)(readerst, &nr_pfns, sizeof(unsigned long)) ||
+ (*readerfn)(readerst, &ctxt, sizeof(ctxt)) ||
+ (*readerfn)(readerst, shared_info, PAGE_SIZE) ||
+ (*readerfn)(readerst, pfn_to_mfn_frame_list, PAGE_SIZE) )
{
ERROR("Error when reading from state file");
goto out;
@@ -250,7 +229,7 @@ int xc_linux_restore(int xc_handle,
prev_pc = this_pc;
}
- if ( !checked_read(gfd, &j, sizeof(int)) )
+ if ( (*readerfn)(readerst, &j, sizeof(int)) )
{
ERROR("Error when reading from state file");
goto out;
@@ -260,7 +239,7 @@ int xc_linux_restore(int xc_handle,
if(j==0) break; // our work here is done
- if ( !checked_read(gfd, region_pfn_type, j*sizeof(unsigned long)) )
+ if ( (*readerfn)(readerst, region_pfn_type, j*sizeof(unsigned long)) )
{
ERROR("Error when reading from state file");
goto out;
@@ -306,21 +285,31 @@ int xc_linux_restore(int xc_handle,
ppage = (unsigned long*) (region_base + i*PAGE_SIZE);
- if ( !checked_read(gfd, ppage, PAGE_SIZE) )
+ if ( (*readerfn)(readerst, ppage, PAGE_SIZE) )
{
ERROR("Error when reading from state file");
goto out;
}
- if ( region_pfn_type[i] == L1TAB )
+ switch( region_pfn_type[i] )
+ {
+ case 0:
+ break;
+
+ case L1TAB:
{
for ( k = 0; k < 1024; k++ )
{
if ( ppage[k] & _PAGE_PRESENT )
{
- if ( (xpfn = ppage[k] >> PAGE_SHIFT) >= nr_pfns )
+ xpfn = ppage[k] >> PAGE_SHIFT;
+
+/*printf("L1 i=%d pfn=%d mfn=%d k=%d pte=%08lx xpfn=%d\n",
+ i,pfn,mfn,k,ppage[k],xpfn);*/
+
+ if ( xpfn >= nr_pfns )
{
- ERROR("Frame number in type %d page table is out of range. i=%d k=%d pfn=%d nr_pfns=%d",region_pfn_type[i],i,k,xpfn,nr_pfns);
+ ERROR("Frame number in type %d page table is out of range. i=%d k=%d pfn=%d nr_pfns=%d",region_pfn_type[i]>>29,i,k,xpfn,nr_pfns);
goto out;
}
#if 0
@@ -335,15 +324,23 @@ int xc_linux_restore(int xc_handle,
}
}
}
- else if ( region_pfn_type[i] == L2TAB )
+ break;
+
+ case L2TAB:
{
for ( k = 0; k < (HYPERVISOR_VIRT_START>>L2_PAGETABLE_SHIFT); k++ )
{
if ( ppage[k] & _PAGE_PRESENT )
{
- if ( (xpfn = ppage[k] >> PAGE_SHIFT) >= nr_pfns )
+ xpfn = ppage[k] >> PAGE_SHIFT;
+
+/*printf("L2 i=%d pfn=%d mfn=%d k=%d pte=%08lx xpfn=%d\n",
+ i,pfn,mfn,k,ppage[k],xpfn);*/
+
+ if ( xpfn >= nr_pfns )
{
- ERROR("Frame number in page table is out of range");
+ ERROR("Frame number in type %d page table is out of range. i=%d k=%d pfn=%d nr_pfns=%d",region_pfn_type[i]>>29,i,k,xpfn,nr_pfns);
+
goto out;
}
#if 0
@@ -358,6 +355,12 @@ int xc_linux_restore(int xc_handle,
}
}
}
+ break;
+
+ default:
+ ERROR("Bogus page type %x page table is out of range. i=%d nr_pfns=%d",region_pfn_type[i],i,nr_pfns);
+ goto out;
+ }
if ( add_mmu_update(xc_handle, mmu,
(mfn<<PAGE_SHIFT) | MMU_MACHPHYS_UPDATE, pfn) )
@@ -545,7 +548,6 @@ int xc_linux_restore(int xc_handle,
if ( pfn_type != NULL )
free(pfn_type);
- gzclose(gfd);
if ( rc == 0 )
*pdomid = dom;