ia64/xen-unstable
changeset 594:e421961ce0bc
bitkeeper revision 1.329.1.3 (3f0d410bYxnFPtx6TnK6YhiMvdqkdA)
Slight tidy ups.
Slight tidy ups.
author | sos22@labyrinth.cl.cam.ac.uk |
---|---|
date | Thu Jul 10 10:33:47 2003 +0000 (2003-07-10) |
parents | 74a0503a5f5a |
children | 884c96cebace |
files | tools/internal/xi_build.c |
line diff
1.1 --- a/tools/internal/xi_build.c Thu Jul 10 10:31:06 2003 +0000 1.2 +++ b/tools/internal/xi_build.c Thu Jul 10 10:33:47 2003 +0000 1.3 @@ -53,7 +53,8 @@ static void dom_mem_cleanup(dom_mem_t * 1.4 1.5 fd = open("/proc/xeno/dom0_cmd", O_WRONLY); 1.6 if(fd < 0){ 1.7 - perror(PERR_STRING); 1.8 + perror("openning /proc/xeno/dom0_cmd"); 1.9 + return; 1.10 } 1.11 1.12 argbuf.vaddr = dom_mem->vaddr; 1.13 @@ -90,62 +91,46 @@ static int map_dom_mem(unsigned long pfn 1.14 1.15 if (dom_mem->vaddr == -1) { 1.16 perror("mapping domain memory"); 1.17 + close(fd); 1.18 return -1; 1.19 } 1.20 + close(fd); 1.21 1.22 return 0; 1.23 } 1.24 1.25 -/* open kernel image and do some sanity checks */ 1.26 -static int do_kernel_chcks(char *image, long dom_size, 1.27 - unsigned long * load_addr, size_t * ksize) 1.28 +/* read the kernel header, extracting the image size and load address. */ 1.29 +static int read_kernel_header(int fd, long dom_size, 1.30 + unsigned long * load_addr, size_t * ksize) 1.31 { 1.32 char signature[8]; 1.33 char status[MAX_PATH]; 1.34 struct stat stat; 1.35 - int fd; 1.36 - int ret; 1.37 1.38 - fd = open(image, O_RDONLY); 1.39 - if(fd < 0){ 1.40 - perror(PERR_STRING); 1.41 - ret = -1; 1.42 - goto out; 1.43 - } 1.44 - 1.45 if(fstat(fd, &stat) < 0){ 1.46 perror(PERR_STRING); 1.47 - ret = -1; 1.48 - close(fd); 1.49 - goto out; 1.50 + return -1; 1.51 } 1.52 1.53 if(stat.st_size > (dom_size << 10)){ 1.54 sprintf(status, "Kernel image size %ld larger than requested " 1.55 "domain size %ld\n Terminated.\n", stat.st_size, dom_size); 1.56 dberr(status); 1.57 - ret = -1; 1.58 - close(fd); 1.59 - goto out; 1.60 + return -1; 1.61 } 1.62 1.63 read(fd, signature, SIG_LEN); 1.64 if(strncmp(signature, GUEST_SIG, SIG_LEN)){ 1.65 dberr("Kernel image does not contain required signature. " 1.66 "Terminating.\n"); 1.67 - ret = -1; 1.68 - close(fd); 1.69 - goto out; 1.70 + return -1; 1.71 } 1.72 1.73 read(fd, load_addr, sizeof(unsigned long)); 1.74 1.75 *ksize = stat.st_size - SIG_LEN - sizeof(unsigned long); 1.76 1.77 - ret = fd; 1.78 - 1.79 - out: 1.80 - return ret; 1.81 + return 0; 1.82 } 1.83 1.84 /* this is the main guestos setup function, 1.85 @@ -159,10 +144,9 @@ static int do_kernel_chcks(char *image, 1.86 static dom_meminfo_t *setup_guestos(int dom, int kernel_fd, int initrd_fd, 1.87 unsigned long virt_load_addr, size_t ksize, dom_mem_t *dom_mem) 1.88 { 1.89 - dom_meminfo_t *meminfo; 1.90 - unsigned long *page_array; 1.91 - page_update_request_t *pgt_updates; 1.92 - dom_meminfo_t *ret = NULL; 1.93 + dom_meminfo_t *meminfo = NULL; 1.94 + unsigned long *page_array = NULL; 1.95 + page_update_request_t *pgt_updates = NULL; 1.96 int alloc_index, num_pt_pages; 1.97 unsigned long l2tab; 1.98 unsigned long l1tab = 0; 1.99 @@ -171,9 +155,14 @@ static dom_meminfo_t *setup_guestos(int 1.100 struct dom0_dopgupdates_args pgupdate_req; 1.101 char cmd_path[MAX_PATH]; 1.102 int cmd_fd; 1.103 + int result; 1.104 1.105 meminfo = (dom_meminfo_t *)malloc(sizeof(dom_meminfo_t)); 1.106 page_array = malloc(dom_mem->tot_pages * 4); 1.107 + if (!meminfo || !page_array) { 1.108 + dberr ("Could not allocate memory"); 1.109 + goto error_out; 1.110 + } 1.111 pgt_updates = (page_update_request_t *)dom_mem->vaddr; 1.112 alloc_index = dom_mem->tot_pages - 1; 1.113 1.114 @@ -264,42 +253,52 @@ static dom_meminfo_t *setup_guestos(int 1.115 meminfo->virt_startinfo_addr = virt_load_addr + nr_2_page(alloc_index - 1); 1.116 meminfo->domain = dom; 1.117 1.118 + free(page_array); 1.119 + 1.120 /* 1.121 * Send the page update requests down to the hypervisor. 1.122 * NB. We must do this before loading the guest OS image! 1.123 */ 1.124 sprintf(cmd_path, "%s%s%s%s", "/proc/", PROC_XENO_ROOT, "/", PROC_CMD); 1.125 - if ( (cmd_fd = open(cmd_path, O_WRONLY)) < 0 ) goto out; 1.126 + if ( (cmd_fd = open(cmd_path, O_WRONLY)) < 0 ) 1.127 + { 1.128 + dberr ("Could not open /proc/" PROC_XENO_ROOT "/" PROC_CMD "."); 1.129 + goto error_out; 1.130 + } 1.131 + 1.132 pgupdate_req.pgt_update_arr = (unsigned long)dom_mem->vaddr; 1.133 pgupdate_req.num_pgt_updates = num_pgt_updates; 1.134 - if (ioctl(cmd_fd, IOCTL_DOM0_DOPGUPDATES, &pgupdate_req) < 0) goto out; 1.135 + result = ioctl(cmd_fd, IOCTL_DOM0_DOPGUPDATES, &pgupdate_req); 1.136 close(cmd_fd); 1.137 + if (result < 0) { 1.138 + dberr ("Could not build domain page tables."); 1.139 + goto error_out; 1.140 + } 1.141 1.142 /* Load the guest OS image. */ 1.143 if( read(kernel_fd, (char *)dom_mem->vaddr, ksize) != ksize ) 1.144 { 1.145 dberr("Error reading kernel image, could not" 1.146 - " read the whole image. Terminating.\n"); 1.147 - goto out; 1.148 + " read the whole image."); 1.149 + goto error_out; 1.150 } 1.151 1.152 - if( initrd_fd ) 1.153 + if( initrd_fd >= 0) 1.154 { 1.155 struct stat stat; 1.156 unsigned long isize; 1.157 1.158 if(fstat(initrd_fd, &stat) < 0){ 1.159 perror(PERR_STRING); 1.160 - close(initrd_fd); 1.161 - goto out; 1.162 + goto error_out; 1.163 } 1.164 isize = stat.st_size; 1.165 1.166 if( read(initrd_fd, ((char *)dom_mem->vaddr)+ksize, isize) != isize ) 1.167 { 1.168 dberr("Error reading initrd image, could not" 1.169 - " read the whole image. Terminating.\n"); 1.170 - goto out; 1.171 + " read the whole image. Terminating."); 1.172 + goto error_out; 1.173 } 1.174 1.175 meminfo->virt_mod_addr = virt_load_addr + ksize; 1.176 @@ -308,10 +307,15 @@ static dom_meminfo_t *setup_guestos(int 1.177 } 1.178 1.179 1.180 - ret = meminfo; 1.181 - out: 1.182 + return meminfo; 1.183 1.184 - return ret; 1.185 + error_out: 1.186 + if (meminfo) 1.187 + free(meminfo); 1.188 + if (page_array) 1.189 + free(page_array); 1.190 + 1.191 + return NULL; 1.192 } 1.193 1.194 static int launch_domain(dom_meminfo_t * meminfo) 1.195 @@ -342,37 +346,39 @@ static int get_domain_info (int domain_i 1.196 FILE *f; 1.197 char domains_path[MAX_PATH]; 1.198 char domains_line[256]; 1.199 - int rc = -1; 1.200 int read_id; 1.201 1.202 - sprintf (domains_path, "%s%s%s%s", "/proc/", PROC_XENO_ROOT, "/", PROC_DOMAINS 1.203 - ); 1.204 + sprintf (domains_path, "%s%s%s%s", "/proc/", PROC_XENO_ROOT, "/", 1.205 + PROC_DOMAINS); 1.206 1.207 f = fopen (domains_path, "r"); 1.208 - if (f == NULL) goto out; 1.209 + if (f == NULL) return -1; 1.210 1.211 read_id = -1; 1.212 while (fgets (domains_line, 256, f) != 0) 1.213 { 1.214 int trans; 1.215 + read_id = -1; 1.216 trans = sscanf (domains_line, "%d %*d %*d %*d %*d %*d %x %d %*s", &read_id 1.217 , pg_head, tot_pages); 1.218 - if (trans == 3) { 1.219 - if (read_id == domain_id) { 1.220 - rc = 0; 1.221 - break; 1.222 - } 1.223 + if (trans != 3) { 1.224 + dberr ("format of /proc/" PROC_XENO_ROOT "/" PROC_DOMAINS " changed -- wrong kernel version?"); 1.225 + read_id = -1; 1.226 + break; 1.227 + } 1.228 + 1.229 + if (read_id == domain_id) { 1.230 + break; 1.231 } 1.232 } 1.233 1.234 + fclose (f); 1.235 + 1.236 if (read_id == -1) { 1.237 errno = ESRCH; 1.238 } 1.239 1.240 - fclose (f); 1.241 - 1.242 - out: 1.243 - return rc; 1.244 + return 0; 1.245 } 1.246 1.247 1.248 @@ -383,15 +389,15 @@ int main(int argc, char **argv) 1.249 dom_meminfo_t * meminfo; 1.250 size_t ksize; 1.251 unsigned long load_addr; 1.252 - int kernel_fd, initrd_fd = 0; 1.253 + int kernel_fd, initrd_fd = -1; 1.254 int count; 1.255 int cmd_len; 1.256 - int rc = -1; 1.257 int args_start = 4; 1.258 char initrd_name[1024]; 1.259 int domain_id; 1.260 int pg_head; 1.261 int tot_pages; 1.262 + int rc; 1.263 1.264 /**** this argument parsing code is really _gross_. rewrite me! ****/ 1.265 1.266 @@ -406,21 +412,26 @@ int main(int argc, char **argv) 1.267 if ( get_domain_info (domain_id, &pg_head, &tot_pages) != 0 ) 1.268 { 1.269 perror ("Could not find domain information"); 1.270 - rc = -1; 1.271 - goto out; 1.272 + return -1; 1.273 } 1.274 1.275 - kernel_fd = do_kernel_chcks(argv[2], 1.276 - tot_pages << (PAGE_SHIFT - 10), 1.277 - &load_addr, &ksize); 1.278 - if ( kernel_fd < 0 ) 1.279 + kernel_fd = open(argv[2], O_RDONLY); 1.280 + if (kernel_fd < 0) { 1.281 + perror ("Could not open kernel image"); 1.282 + return -1; 1.283 + } 1.284 + 1.285 + rc = read_kernel_header(kernel_fd, 1.286 + tot_pages << (PAGE_SHIFT - 10), 1.287 + &load_addr, &ksize); 1.288 + if ( rc < 0 ) 1.289 return -1; 1.290 1.291 1.292 /* map domain's memory */ 1.293 if ( map_dom_mem(pg_head, tot_pages, 1.294 domain_id, &dom_os_image) ) 1.295 - goto out; 1.296 + return -1; 1.297 1.298 if( (argc > args_start) && 1.299 (strncmp("initrd=", argv[args_start], 7) == 0) ) 1.300 @@ -433,22 +444,23 @@ int main(int argc, char **argv) 1.301 initrd_fd = open(initrd_name, O_RDONLY); 1.302 if(initrd_fd < 0){ 1.303 perror(PERR_STRING); 1.304 - goto out; 1.305 + return -1; 1.306 } 1.307 } 1.308 1.309 /* the following code does the actual domain building */ 1.310 meminfo = setup_guestos(domain_id, kernel_fd, initrd_fd, load_addr, 1.311 ksize, &dom_os_image); 1.312 - 1.313 + if (!meminfo) 1.314 + return -1; 1.315 + 1.316 + if (initrd_fd >= 0) 1.317 + close(initrd_fd); 1.318 + close(kernel_fd); 1.319 + 1.320 /* and unmap the new domain's memory image since we no longer need it */ 1.321 dom_mem_cleanup(&dom_os_image); 1.322 1.323 - if(!meminfo) { 1.324 - printf("Domain Builder: debug: meminfo NULL\n"); 1.325 - goto out; 1.326 - } 1.327 - 1.328 meminfo->virt_load_addr = load_addr; 1.329 meminfo->num_vifs = atoi(argv[3]); 1.330 meminfo->cmd_line[0] = '\0'; 1.331 @@ -463,19 +475,8 @@ int main(int argc, char **argv) 1.332 cmd_len += strlen(argv[count] + 1); 1.333 } 1.334 1.335 - /* sprintf(status, 1.336 - "About to launch new domain %d with folowing parameters:\n" 1.337 - " * page table base: %lx \n * load address: %lx \n" 1.338 - " * shared info address: %lx \n * start info address: %lx \n" 1.339 - " * number of vifs: %d \n * cmd line: %s \n", meminfo->domain, 1.340 - meminfo->l2_pgt_addr, meminfo->virt_load_addr, 1.341 - meminfo->virt_shinfo_addr, meminfo->virt_startinfo_addr, 1.342 - meminfo->num_vifs, meminfo->cmd_line); 1.343 - dbstatus(status);*/ 1.344 - 1.345 /* and launch the domain */ 1.346 rc = launch_domain(meminfo); 1.347 1.348 - out: 1.349 - return rc; 1.350 + return 0; 1.351 }