source: trunk/packages/xen-3.1/xen-3.1/tools/libxc/xg_private.c @ 34

Last change on this file since 34 was 34, checked in by hartmans, 18 years ago

Add xen and xen-common

File size: 4.5 KB
Line 
1/******************************************************************************
2 * xg_private.c
3 *
4 * Helper functions for the rest of the library.
5 */
6
7#include <stdlib.h>
8#include <unistd.h>
9#include <zlib.h>
10#include <strings.h>
11
12#include "xg_private.h"
13
14int lock_pages(void *addr, size_t len)
15{
16    int e = 0;
17#ifndef __sun__
18    e = mlock(addr, len);
19#endif
20    return (e);
21}
22
23void unlock_pages(void *addr, size_t len)
24{
25#ifndef __sun__
26    safe_munlock(addr, len);
27#endif
28}
29
30char *xc_read_image(const char *filename, unsigned long *size)
31{
32    int kernel_fd = -1;
33    gzFile kernel_gfd = NULL;
34    char *image = NULL, *tmp;
35    unsigned int bytes;
36
37    if ( (filename == NULL) || (size == NULL) )
38        return NULL;
39
40    if ( (kernel_fd = open(filename, O_RDONLY)) < 0 )
41    {
42        PERROR("Could not open kernel image");
43        goto out;
44    }
45
46    if ( (kernel_gfd = gzdopen(kernel_fd, "rb")) == NULL )
47    {
48        PERROR("Could not allocate decompression state for state file");
49        goto out;
50    }
51
52    *size = 0;
53
54#define CHUNK 1*1024*1024
55    while(1)
56    {
57        if ( (tmp = realloc(image, *size + CHUNK)) == NULL )
58        {
59            PERROR("Could not allocate memory for kernel image");
60            free(image);
61            image = NULL;
62            goto out;
63        }
64        image = tmp;
65
66        bytes = gzread(kernel_gfd, image + *size, CHUNK);
67        switch (bytes)
68        {
69        case -1:
70            PERROR("Error reading kernel image");
71            free(image);
72            image = NULL;
73            goto out;
74        case 0: /* EOF */
75            goto out;
76        default:
77            *size += bytes;
78            break;
79        }
80    }
81#undef CHUNK
82
83 out:
84    if ( *size == 0 )
85    {
86        PERROR("Could not read kernel image");
87        free(image);
88        image = NULL;
89    }
90    else if ( image )
91    {
92        /* Shrink allocation to fit image. */
93        tmp = realloc(image, *size);
94        if ( tmp )
95            image = tmp;
96    }
97
98    if ( kernel_gfd != NULL )
99        gzclose(kernel_gfd);
100    else if ( kernel_fd >= 0 )
101        close(kernel_fd);
102    return image;
103}
104
105char *xc_inflate_buffer(const char *in_buf, unsigned long in_size,
106                        unsigned long *out_size)
107{
108    int           sts;
109    z_stream      zStream;
110    unsigned long out_len;
111    char         *out_buf;
112
113    /* Not compressed? Then return the original buffer. */
114    if ( ((unsigned char)in_buf[0] != 0x1F) ||
115         ((unsigned char)in_buf[1] != 0x8B) )
116    {
117        if ( out_size != NULL )
118            *out_size = in_size;
119        return (char *)in_buf;
120    }
121
122    out_len = (unsigned char)in_buf[in_size-4] +
123        (256 * ((unsigned char)in_buf[in_size-3] +
124                (256 * ((unsigned char)in_buf[in_size-2] +
125                        (256 * (unsigned char)in_buf[in_size-1])))));
126
127    bzero(&zStream, sizeof(zStream));
128    out_buf = malloc(out_len + 16);        /* Leave a little extra space */
129    if ( out_buf == NULL )
130    {
131        ERROR("Error mallocing buffer\n");
132        return NULL;
133    }
134
135    zStream.next_in = (unsigned char *)in_buf;
136    zStream.avail_in = in_size;
137    zStream.next_out = (unsigned char *)out_buf;
138    zStream.avail_out = out_len+16;
139    sts = inflateInit2(&zStream, (MAX_WBITS+32)); /* +32 means "handle gzip" */
140    if ( sts != Z_OK )
141    {
142        ERROR("inflateInit failed, sts %d\n", sts);
143        free(out_buf);
144        return NULL;
145    }
146
147    /* Inflate in one pass/call */
148    sts = inflate(&zStream, Z_FINISH);
149    if ( sts != Z_STREAM_END )
150    {
151        ERROR("inflate failed, sts %d\n", sts);
152        free(out_buf);
153        return NULL;
154    }
155
156    if ( out_size != NULL )
157        *out_size = out_len;
158
159    return out_buf;
160}
161
162/*******************/
163
164int pin_table(
165    int xc_handle, unsigned int type, unsigned long mfn, domid_t dom)
166{
167    struct mmuext_op op;
168
169    op.cmd = type;
170    op.arg1.mfn = mfn;
171
172    if ( xc_mmuext_op(xc_handle, &op, 1, dom) < 0 )
173        return 1;
174
175    return 0;
176}
177
178/* This is shared between save and restore, and may generally be useful. */
179unsigned long csum_page(void *page)
180{
181    int i;
182    unsigned long *p = page;
183    unsigned long long sum=0;
184
185    for ( i = 0; i < (PAGE_SIZE/sizeof(unsigned long)); i++ )
186        sum += p[i];
187
188    return sum ^ (sum>>32);
189}
190
191__attribute__((weak)) 
192    int xc_hvm_build(int xc_handle,
193                     uint32_t domid,
194                     int memsize,
195                     const char *image_name)
196{
197    errno = ENOSYS;
198    return -1;
199}
200
201/*
202 * Local variables:
203 * mode: C
204 * c-set-style: "BSD"
205 * c-basic-offset: 4
206 * tab-width: 4
207 * indent-tabs-mode: nil
208 * End:
209 */
Note: See TracBrowser for help on using the repository browser.