diff options
author | sos22@labyrinth.cl.cam.ac.uk <sos22@labyrinth.cl.cam.ac.uk> | 2003-07-10 10:33:47 +0000 |
---|---|---|
committer | sos22@labyrinth.cl.cam.ac.uk <sos22@labyrinth.cl.cam.ac.uk> | 2003-07-10 10:33:47 +0000 |
commit | a7d80b646cf766772ba9b75aef6ed9e978ed6dd0 (patch) | |
tree | 0f5490194ce2f547dc3fc6b2258044c049ac51d5 /tools | |
parent | 4ad0f65987eca171ad7b96473ed6722bd2ae29d1 (diff) | |
download | xen-a7d80b646cf766772ba9b75aef6ed9e978ed6dd0.tar.gz xen-a7d80b646cf766772ba9b75aef6ed9e978ed6dd0.tar.bz2 xen-a7d80b646cf766772ba9b75aef6ed9e978ed6dd0.zip |
bitkeeper revision 1.329.1.3 (3f0d410bYxnFPtx6TnK6YhiMvdqkdA)
Slight tidy ups.
Diffstat (limited to 'tools')
-rw-r--r-- | tools/internal/xi_build.c | 167 |
1 files changed, 84 insertions, 83 deletions
diff --git a/tools/internal/xi_build.c b/tools/internal/xi_build.c index 59c4340db2..76c67651f1 100644 --- a/tools/internal/xi_build.c +++ b/tools/internal/xi_build.c @@ -53,7 +53,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 +91,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,10 +144,9 @@ 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; @@ -171,9 +155,14 @@ static dom_meminfo_t *setup_guestos(int dom, int kernel_fd, int initrd_fd, 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 +253,52 @@ 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(cmd_path, O_WRONLY)) < 0 ) + { + dberr ("Could not open /proc/" PROC_XENO_ROOT "/" PROC_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,10 +307,15 @@ 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) @@ -342,37 +346,39 @@ static int get_domain_info (int domain_id, 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 - ); + sprintf (domains_path, "%s%s%s%s", "/proc/", PROC_XENO_ROOT, "/", + PROC_DOMAINS); f = fopen (domains_path, "r"); - if (f == NULL) goto out; + 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/" PROC_XENO_ROOT "/" PROC_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 +389,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 +412,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 +444,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 +475,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; } |