aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorsos22@labyrinth.cl.cam.ac.uk <sos22@labyrinth.cl.cam.ac.uk>2003-07-10 11:04:02 +0000
committersos22@labyrinth.cl.cam.ac.uk <sos22@labyrinth.cl.cam.ac.uk>2003-07-10 11:04:02 +0000
commit19786bd474eb68aae77716ec7717c3d189ec59cb (patch)
tree6674739858473cbe08c36f803942d090bd8afa34 /tools
parentd40db2be59d7a7b26b904993d6ac071d94c3f2eb (diff)
parent4ce58154e14467fcb9bc9fbf72e2fd049ffe27e4 (diff)
downloadxen-19786bd474eb68aae77716ec7717c3d189ec59cb.tar.gz
xen-19786bd474eb68aae77716ec7717c3d189ec59cb.tar.bz2
xen-19786bd474eb68aae77716ec7717c3d189ec59cb.zip
bitkeeper revision 1.331 (3f0d4822DGZPrG8hjrH_59XaPHWQGA)
Merge labyrinth.cl.cam.ac.uk:/auto/groups/xeno/users/rac61/xeno.bk into labyrinth.cl.cam.ac.uk:/auto/groups/xeno/users/sos22/xeno.bk
Diffstat (limited to 'tools')
-rw-r--r--tools/internal/xi_build.c179
1 files changed, 88 insertions, 91 deletions
diff --git a/tools/internal/xi_build.c b/tools/internal/xi_build.c
index 59c4340db2..805ab22a2a 100644
--- a/tools/internal/xi_build.c
+++ b/tools/internal/xi_build.c
@@ -24,6 +24,10 @@
#define GUEST_SIG "XenoGues"
#define SIG_LEN 8
+/* Watch for precedence when using thses ones... */
+#define PROC_XENO_DOM0_CMD "/proc/" PROC_XENO_ROOT "/" PROC_CMD
+#define PROC_XENO_DOMAINS "/proc" PROC_XENO_ROOT "/" PROC_DOMAINS
+
/*
* NB. No ring-3 access in initial guestOS pagetables. Note that we allow
* ring-3 privileges in the page directories, so that the guestOS may later
@@ -53,7 +57,8 @@ static void dom_mem_cleanup(dom_mem_t * dom_mem)
fd = open("/proc/xeno/dom0_cmd", O_WRONLY);
if(fd < 0){
- perror(PERR_STRING);
+ perror("openning /proc/xeno/dom0_cmd");
+ return;
}
argbuf.vaddr = dom_mem->vaddr;
@@ -90,62 +95,46 @@ static int map_dom_mem(unsigned long pfn, int pages, int dom,
if (dom_mem->vaddr == -1) {
perror("mapping domain memory");
+ close(fd);
return -1;
}
+ close(fd);
return 0;
}
-/* open kernel image and do some sanity checks */
-static int do_kernel_chcks(char *image, long dom_size,
- unsigned long * load_addr, size_t * ksize)
+/* read the kernel header, extracting the image size and load address. */
+static int read_kernel_header(int fd, long dom_size,
+ unsigned long * load_addr, size_t * ksize)
{
char signature[8];
char status[MAX_PATH];
struct stat stat;
- int fd;
- int ret;
- fd = open(image, O_RDONLY);
- if(fd < 0){
- perror(PERR_STRING);
- ret = -1;
- goto out;
- }
-
if(fstat(fd, &stat) < 0){
perror(PERR_STRING);
- ret = -1;
- close(fd);
- goto out;
+ return -1;
}
if(stat.st_size > (dom_size << 10)){
sprintf(status, "Kernel image size %ld larger than requested "
"domain size %ld\n Terminated.\n", stat.st_size, dom_size);
dberr(status);
- ret = -1;
- close(fd);
- goto out;
+ return -1;
}
read(fd, signature, SIG_LEN);
if(strncmp(signature, GUEST_SIG, SIG_LEN)){
dberr("Kernel image does not contain required signature. "
"Terminating.\n");
- ret = -1;
- close(fd);
- goto out;
+ return -1;
}
read(fd, load_addr, sizeof(unsigned long));
*ksize = stat.st_size - SIG_LEN - sizeof(unsigned long);
- ret = fd;
-
- out:
- return ret;
+ return 0;
}
/* this is the main guestos setup function,
@@ -159,21 +148,24 @@ static int do_kernel_chcks(char *image, long dom_size,
static dom_meminfo_t *setup_guestos(int dom, int kernel_fd, int initrd_fd,
unsigned long virt_load_addr, size_t ksize, dom_mem_t *dom_mem)
{
- dom_meminfo_t *meminfo;
- unsigned long *page_array;
- page_update_request_t *pgt_updates;
- dom_meminfo_t *ret = NULL;
+ dom_meminfo_t *meminfo = NULL;
+ unsigned long *page_array = NULL;
+ page_update_request_t *pgt_updates = NULL;
int alloc_index, num_pt_pages;
unsigned long l2tab;
unsigned long l1tab = 0;
unsigned long num_pgt_updates = 0;
unsigned long count, pt_start;
struct dom0_dopgupdates_args pgupdate_req;
- char cmd_path[MAX_PATH];
int cmd_fd;
+ int result;
meminfo = (dom_meminfo_t *)malloc(sizeof(dom_meminfo_t));
page_array = malloc(dom_mem->tot_pages * 4);
+ if (!meminfo || !page_array) {
+ dberr ("Could not allocate memory");
+ goto error_out;
+ }
pgt_updates = (page_update_request_t *)dom_mem->vaddr;
alloc_index = dom_mem->tot_pages - 1;
@@ -264,42 +256,51 @@ static dom_meminfo_t *setup_guestos(int dom, int kernel_fd, int initrd_fd,
meminfo->virt_startinfo_addr = virt_load_addr + nr_2_page(alloc_index - 1);
meminfo->domain = dom;
+ free(page_array);
+
/*
* Send the page update requests down to the hypervisor.
* NB. We must do this before loading the guest OS image!
*/
- sprintf(cmd_path, "%s%s%s%s", "/proc/", PROC_XENO_ROOT, "/", PROC_CMD);
- if ( (cmd_fd = open(cmd_path, O_WRONLY)) < 0 ) goto out;
+ if ( (cmd_fd = open(PROC_XENO_DOM0_CMD, O_WRONLY)) < 0 )
+ {
+ dberr ("Could not open " PROC_XENO_DOM0_CMD);
+ goto error_out;
+ }
+
pgupdate_req.pgt_update_arr = (unsigned long)dom_mem->vaddr;
pgupdate_req.num_pgt_updates = num_pgt_updates;
- if (ioctl(cmd_fd, IOCTL_DOM0_DOPGUPDATES, &pgupdate_req) < 0) goto out;
+ result = ioctl(cmd_fd, IOCTL_DOM0_DOPGUPDATES, &pgupdate_req);
close(cmd_fd);
+ if (result < 0) {
+ dberr ("Could not build domain page tables.");
+ goto error_out;
+ }
/* Load the guest OS image. */
if( read(kernel_fd, (char *)dom_mem->vaddr, ksize) != ksize )
{
dberr("Error reading kernel image, could not"
- " read the whole image. Terminating.\n");
- goto out;
+ " read the whole image.");
+ goto error_out;
}
- if( initrd_fd )
+ if( initrd_fd >= 0)
{
struct stat stat;
unsigned long isize;
if(fstat(initrd_fd, &stat) < 0){
perror(PERR_STRING);
- close(initrd_fd);
- goto out;
+ goto error_out;
}
isize = stat.st_size;
if( read(initrd_fd, ((char *)dom_mem->vaddr)+ksize, isize) != isize )
{
dberr("Error reading initrd image, could not"
- " read the whole image. Terminating.\n");
- goto out;
+ " read the whole image. Terminating.");
+ goto error_out;
}
meminfo->virt_mod_addr = virt_load_addr + ksize;
@@ -308,20 +309,23 @@ static dom_meminfo_t *setup_guestos(int dom, int kernel_fd, int initrd_fd,
}
- ret = meminfo;
- out:
+ return meminfo;
+
+ error_out:
+ if (meminfo)
+ free(meminfo);
+ if (page_array)
+ free(page_array);
- return ret;
+ return NULL;
}
static int launch_domain(dom_meminfo_t * meminfo)
{
- char cmd_path[MAX_PATH];
dom0_op_t dop;
int cmd_fd;
- sprintf(cmd_path, "%s%s%s%s", "/proc/", PROC_XENO_ROOT, "/", PROC_CMD);
- cmd_fd = open(cmd_path, O_WRONLY);
+ cmd_fd = open(PROC_XENO_DOM0_CMD, O_WRONLY);
if(cmd_fd < 0){
perror(PERR_STRING);
return -1;
@@ -340,39 +344,37 @@ static int get_domain_info (int domain_id,
int *tot_pages)
{
FILE *f;
- char domains_path[MAX_PATH];
char domains_line[256];
- int rc = -1;
int read_id;
- sprintf (domains_path, "%s%s%s%s", "/proc/", PROC_XENO_ROOT, "/", PROC_DOMAINS
- );
-
- f = fopen (domains_path, "r");
- if (f == NULL) goto out;
+ f = fopen (PROC_XENO_DOMAINS, "r");
+ if (f == NULL) return -1;
read_id = -1;
while (fgets (domains_line, 256, f) != 0)
{
int trans;
+ read_id = -1;
trans = sscanf (domains_line, "%d %*d %*d %*d %*d %*d %x %d %*s", &read_id
, pg_head, tot_pages);
- if (trans == 3) {
- if (read_id == domain_id) {
- rc = 0;
- break;
- }
+ if (trans != 3) {
+ dberr ("format of " PROC_XENO_DOMAINS " changed -- wrong kernel version?");
+ read_id = -1;
+ break;
+ }
+
+ if (read_id == domain_id) {
+ break;
}
}
+ fclose (f);
+
if (read_id == -1) {
errno = ESRCH;
}
- fclose (f);
-
- out:
- return rc;
+ return 0;
}
@@ -383,15 +385,15 @@ int main(int argc, char **argv)
dom_meminfo_t * meminfo;
size_t ksize;
unsigned long load_addr;
- int kernel_fd, initrd_fd = 0;
+ int kernel_fd, initrd_fd = -1;
int count;
int cmd_len;
- int rc = -1;
int args_start = 4;
char initrd_name[1024];
int domain_id;
int pg_head;
int tot_pages;
+ int rc;
/**** this argument parsing code is really _gross_. rewrite me! ****/
@@ -406,21 +408,26 @@ int main(int argc, char **argv)
if ( get_domain_info (domain_id, &pg_head, &tot_pages) != 0 )
{
perror ("Could not find domain information");
- rc = -1;
- goto out;
+ return -1;
}
- kernel_fd = do_kernel_chcks(argv[2],
- tot_pages << (PAGE_SHIFT - 10),
- &load_addr, &ksize);
- if ( kernel_fd < 0 )
+ kernel_fd = open(argv[2], O_RDONLY);
+ if (kernel_fd < 0) {
+ perror ("Could not open kernel image");
+ return -1;
+ }
+
+ rc = read_kernel_header(kernel_fd,
+ tot_pages << (PAGE_SHIFT - 10),
+ &load_addr, &ksize);
+ if ( rc < 0 )
return -1;
/* map domain's memory */
if ( map_dom_mem(pg_head, tot_pages,
domain_id, &dom_os_image) )
- goto out;
+ return -1;
if( (argc > args_start) &&
(strncmp("initrd=", argv[args_start], 7) == 0) )
@@ -433,22 +440,23 @@ int main(int argc, char **argv)
initrd_fd = open(initrd_name, O_RDONLY);
if(initrd_fd < 0){
perror(PERR_STRING);
- goto out;
+ return -1;
}
}
/* the following code does the actual domain building */
meminfo = setup_guestos(domain_id, kernel_fd, initrd_fd, load_addr,
ksize, &dom_os_image);
-
+ if (!meminfo)
+ return -1;
+
+ if (initrd_fd >= 0)
+ close(initrd_fd);
+ close(kernel_fd);
+
/* and unmap the new domain's memory image since we no longer need it */
dom_mem_cleanup(&dom_os_image);
- if(!meminfo) {
- printf("Domain Builder: debug: meminfo NULL\n");
- goto out;
- }
-
meminfo->virt_load_addr = load_addr;
meminfo->num_vifs = atoi(argv[3]);
meminfo->cmd_line[0] = '\0';
@@ -463,19 +471,8 @@ int main(int argc, char **argv)
cmd_len += strlen(argv[count] + 1);
}
- /* sprintf(status,
- "About to launch new domain %d with folowing parameters:\n"
- " * page table base: %lx \n * load address: %lx \n"
- " * shared info address: %lx \n * start info address: %lx \n"
- " * number of vifs: %d \n * cmd line: %s \n", meminfo->domain,
- meminfo->l2_pgt_addr, meminfo->virt_load_addr,
- meminfo->virt_shinfo_addr, meminfo->virt_startinfo_addr,
- meminfo->num_vifs, meminfo->cmd_line);
- dbstatus(status);*/
-
/* and launch the domain */
rc = launch_domain(meminfo);
- out:
- return rc;
+ return 0;
}