aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorsos22@labyrinth.cl.cam.ac.uk <sos22@labyrinth.cl.cam.ac.uk>2003-07-10 10:33:47 +0000
committersos22@labyrinth.cl.cam.ac.uk <sos22@labyrinth.cl.cam.ac.uk>2003-07-10 10:33:47 +0000
commita7d80b646cf766772ba9b75aef6ed9e978ed6dd0 (patch)
tree0f5490194ce2f547dc3fc6b2258044c049ac51d5 /tools
parent4ad0f65987eca171ad7b96473ed6722bd2ae29d1 (diff)
downloadxen-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.c167
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;
}