# HG changeset patch
# User cl349@xxxxxxxxxxxxxxxxxxxx
# Node ID 219d96d545fcb918d1abc45688975af86728b408
# Parent cdaaaa027bf843a62627e61bfa9351c3991d57c9
# Parent 888094e5ac07dcefe91fc69abf57295744b96deb
merge?
diff -r cdaaaa027bf8 -r 219d96d545fc tools/libxc/xc_linux_restore.c
--- a/tools/libxc/xc_linux_restore.c Mon Sep 12 19:59:40 2005
+++ b/tools/libxc/xc_linux_restore.c Mon Sep 12 20:00:41 2005
@@ -42,18 +42,18 @@
unsigned char *b = buf;
while (r < count) {
- s = read(fd, &b[r], count - r);
- if (s <= 0)
- break;
- r += s;
+ s = read(fd, &b[r], count - r);
+ if (s <= 0)
+ break;
+ r += s;
}
return r;
}
int xc_linux_restore(int xc_handle, int io_fd, u32 dom, unsigned long nr_pfns,
- unsigned int store_evtchn, unsigned long *store_mfn,
- unsigned int console_evtchn, unsigned long *console_mfn)
+ unsigned int store_evtchn, unsigned long *store_mfn,
+ unsigned int console_evtchn, unsigned long *console_mfn)
{
dom0_op_t op;
int rc = 1, i, n, k;
@@ -91,6 +91,8 @@
/* A temporary mapping of the guest's start_info page. */
start_info_t *start_info;
+ int pt_levels = 2; /* XXX auto-detect this */
+
char *region_base;
xc_mmu_t *mmu = NULL;
@@ -112,8 +114,8 @@
}
if (read_exact(io_fd, pfn_to_mfn_frame_list, PAGE_SIZE) != PAGE_SIZE) {
- ERR("read pfn_to_mfn_frame_list failed");
- goto out;
+ ERR("read pfn_to_mfn_frame_list failed");
+ goto out;
}
/* We want zeroed memory so use calloc rather than malloc. */
@@ -289,10 +291,10 @@
if ( xpfn >= nr_pfns )
{
ERR("Frame number in type %lu page "
- "table is out of range. i=%d k=%d "
- "pfn=0x%lx nr_pfns=%lu",
- region_pfn_type[i]>>28, i,
- k, xpfn, nr_pfns);
+ "table is out of range. i=%d k=%d "
+ "pfn=0x%lx nr_pfns=%lu",
+ region_pfn_type[i]>>28, i,
+ k, xpfn, nr_pfns);
goto out;
}
@@ -317,10 +319,10 @@
if ( xpfn >= nr_pfns )
{
ERR("Frame number in type %lu page"
- " table is out of range. i=%d k=%d "
- "pfn=%lu nr_pfns=%lu",
- region_pfn_type[i]>>28, i, k,
- xpfn, nr_pfns);
+ " table is out of range. i=%d k=%d "
+ "pfn=%lu nr_pfns=%lu",
+ region_pfn_type[i]>>28, i, k,
+ xpfn, nr_pfns);
goto out;
}
@@ -334,8 +336,8 @@
default:
ERR("Bogus page type %lx page table is "
- "out of range. i=%d nr_pfns=%lu",
- region_pfn_type[i], i, nr_pfns);
+ "out of range. i=%d nr_pfns=%lu",
+ region_pfn_type[i], i, nr_pfns);
goto out;
} /* end of page type switch statement */
@@ -362,8 +364,8 @@
}
if ( xc_add_mmu_update(xc_handle, mmu,
- (mfn<<PAGE_SHIFT) | MMU_MACHPHYS_UPDATE,
- pfn) )
+ (mfn<<PAGE_SHIFT) | MMU_MACHPHYS_UPDATE,
+ pfn) )
{
printf("machpys mfn=%ld pfn=%ld\n",mfn,pfn);
goto out;
@@ -376,6 +378,33 @@
}
DPRINTF("Received all pages\n");
+
+ if ( pt_levels == 3 )
+ {
+ /* Get all PGDs below 4GB. */
+ for ( i = 0; i < nr_pfns; i++ )
+ {
+ if ( ((pfn_type[i] & LTABTYPE_MASK) == L3TAB) &&
+ (pfn_to_mfn_table[i] > 0xfffffUL) )
+ {
+ unsigned long new_mfn = xc_make_page_below_4G(
+ xc_handle, dom, pfn_to_mfn_table[i]);
+ if ( new_mfn == 0 )
+ {
+ fprintf(stderr, "Couldn't get a page below 4GB :-(\n");
+ goto out;
+ }
+ pfn_to_mfn_table[i] = new_mfn;
+ if ( xc_add_mmu_update(
+ xc_handle, mmu, (new_mfn << PAGE_SHIFT) |
+ MMU_MACHPHYS_UPDATE, i) )
+ {
+ fprintf(stderr, "Couldn't m2p on PAE root pgdir\n");
+ goto out;
+ }
+ }
+ }
+ }
if ( xc_finish_mmu_updates(xc_handle, mmu) )
goto out;
@@ -410,57 +439,57 @@
/* Get the list of PFNs that are not in the psuedo-phys map */
{
- unsigned int count;
+ unsigned int count;
unsigned long *pfntab;
- int rc;
-
- if ( read_exact(io_fd, &count, sizeof(count)) != sizeof(count) )
- {
- ERR("Error when reading pfn count");
- goto out;
- }
-
- pfntab = malloc( sizeof(unsigned int) * count );
- if ( pfntab == NULL )
- {
- ERR("Out of memory");
- goto out;
- }
-
- if ( read_exact(io_fd, pfntab, sizeof(unsigned int)*count) !=
+ int rc;
+
+ if ( read_exact(io_fd, &count, sizeof(count)) != sizeof(count) )
+ {
+ ERR("Error when reading pfn count");
+ goto out;
+ }
+
+ pfntab = malloc( sizeof(unsigned int) * count );
+ if ( pfntab == NULL )
+ {
+ ERR("Out of memory");
+ goto out;
+ }
+
+ if ( read_exact(io_fd, pfntab, sizeof(unsigned int)*count) !=
sizeof(unsigned int)*count )
- {
- ERR("Error when reading pfntab");
- goto out;
- }
-
- for ( i = 0; i < count; i++ )
- {
- unsigned long pfn = pfntab[i];
- pfntab[i]=pfn_to_mfn_table[pfn];
- pfn_to_mfn_table[pfn] = 0x80000001; // not in pmap
- }
-
- if ( count > 0 )
- {
+ {
+ ERR("Error when reading pfntab");
+ goto out;
+ }
+
+ for ( i = 0; i < count; i++ )
+ {
+ unsigned long pfn = pfntab[i];
+ pfntab[i]=pfn_to_mfn_table[pfn];
+ pfn_to_mfn_table[pfn] = 0x80000001; // not in pmap
+ }
+
+ if ( count > 0 )
+ {
struct xen_memory_reservation reservation = {
.extent_start = pfntab,
.nr_extents = count,
.extent_order = 0,
.domid = dom
};
- if ( (rc = xc_memory_op(xc_handle,
+ if ( (rc = xc_memory_op(xc_handle,
XENMEM_decrease_reservation,
&reservation)) != count )
- {
- ERR("Could not decrease reservation : %d",rc);
- goto out;
- }
- else
- {
- printf("Decreased reservation by %d pages\n", count);
- }
- }
+ {
+ ERR("Could not decrease reservation : %d",rc);
+ goto out;
+ }
+ else
+ {
+ printf("Decreased reservation by %d pages\n", count);
+ }
+ }
}
if ( read_exact(io_fd, &ctxt, sizeof(ctxt)) != sizeof(ctxt) ||
@@ -484,10 +513,10 @@
start_info->shared_info = shared_info_frame << PAGE_SHIFT;
start_info->flags = 0;
*store_mfn = start_info->store_mfn =
- pfn_to_mfn_table[start_info->store_mfn];
+ pfn_to_mfn_table[start_info->store_mfn];
start_info->store_evtchn = store_evtchn;
*console_mfn = start_info->console_mfn =
- pfn_to_mfn_table[start_info->console_mfn];
+ pfn_to_mfn_table[start_info->console_mfn];
start_info->console_evtchn = console_evtchn;
munmap(start_info, PAGE_SIZE);
@@ -522,7 +551,7 @@
/* clear any pending events and the selector */
memset(&(shared_info->evtchn_pending[0]), 0,
- sizeof (shared_info->evtchn_pending));
+ sizeof (shared_info->evtchn_pending));
for ( i = 0; i < MAX_VIRT_CPUS; i++ )
shared_info->vcpu_data[i].evtchn_pending_sel = 0;
@@ -548,7 +577,7 @@
}
if ( (live_pfn_to_mfn_table =
- xc_map_foreign_batch(xc_handle, dom,
+ xc_map_foreign_batch(xc_handle, dom,
PROT_WRITE,
pfn_to_mfn_frame_list,
(nr_pfns+1023)/1024 )) == 0 )
diff -r cdaaaa027bf8 -r 219d96d545fc tools/libxc/xc_vmx_build.c
--- a/tools/libxc/xc_vmx_build.c Mon Sep 12 19:59:40 2005
+++ b/tools/libxc/xc_vmx_build.c Mon Sep 12 20:00:41 2005
@@ -578,15 +578,6 @@
sp->sp_global.eport = control_evtchn;
munmap(sp, PAGE_SIZE);
- /*
- * Pin down l2tab addr as page dir page - causes hypervisor to provide
- * correct protection for the page
- */
-#ifdef __i386__
- if ( pin_table(xc_handle, MMUEXT_PIN_L2_TABLE, l2tab>>PAGE_SHIFT, dom) )
- goto error_out;
-#endif
-
/* Send the page update requests down to the hypervisor. */
if ( xc_finish_mmu_updates(xc_handle, mmu) )
goto error_out;
diff -r cdaaaa027bf8 -r 219d96d545fc xen/arch/x86/domain.c
--- a/xen/arch/x86/domain.c Mon Sep 12 19:59:40 2005
+++ b/xen/arch/x86/domain.c Mon Sep 12 20:00:41 2005
@@ -461,14 +461,11 @@
if ( !get_page(&frame_table[phys_basetab>>PAGE_SHIFT], d) )
return -EINVAL;
}
- else
- {
-#ifdef __x86_64__
- if ( !(c->flags & VGCF_VMX_GUEST) )
-#endif
- if ( !get_page_and_type(&frame_table[phys_basetab>>PAGE_SHIFT], d,
- PGT_base_page_table) )
- return -EINVAL;
+ else if ( !(c->flags & VGCF_VMX_GUEST) )
+ {
+ if ( !get_page_and_type(&frame_table[phys_basetab>>PAGE_SHIFT], d,
+ PGT_base_page_table) )
+ return -EINVAL;
}
if ( (rc = (int)set_gdt(v, c->gdt_frames, c->gdt_ents)) != 0 )
diff -r cdaaaa027bf8 -r 219d96d545fc xen/arch/x86/vmx.c
--- a/xen/arch/x86/vmx.c Mon Sep 12 19:59:40 2005
+++ b/xen/arch/x86/vmx.c Mon Sep 12 20:00:41 2005
@@ -1082,11 +1082,6 @@
VMX_DBG_LOG(DBG_LEVEL_1, "enable PAE on cr4\n");
__vmwrite(GUEST_CR4, crn | X86_CR4_PAE);
}
-#elif defined( __i386__)
- unsigned long old_base_mfn;
- old_base_mfn = pagetable_get_pfn(d->arch.guest_table);
- if (old_base_mfn)
- put_page(pfn_to_page(old_base_mfn));
#endif
/*
* Now arch.guest_table points to machine physical.
diff -r cdaaaa027bf8 -r 219d96d545fc tools/vnet/Make.env
--- /dev/null Mon Sep 12 19:59:40 2005
+++ b/tools/vnet/Make.env Mon Sep 12 20:00:41 2005
@@ -0,0 +1,20 @@
+# -*- mode: Makefile; -*-
+
+export XEN_ROOT = $(shell cd $(VNET_ROOT)/../.. && pwd)
+export LINUX_SERIES ?= 2.6
+
+DISTDIR ?= $(XEN_ROOT)/dist
+export DESTDIR ?= $(DISTDIR)/install
+
+export VNET_MODULE_DIR = $(VNET_ROOT)/vnet-module
+export VNETD_DIR = $(VNET_ROOT)/vnetd
+export LIBXUTIL_DIR = $(VNET_ROOT)/libxutil
+
+export GC_DIR = $(VNET_ROOT)/build/gc
+export GC_INCLUDE = $(GC_DIR)/include
+export GC_LIB_DIR = $(GC_DIR)/lib
+export GC_LIB_A = $(GC_LIB_DIR)/libgc.a
+export GC_LIB_SO = $(GC_LIB_DIR)/libgc.so
+
+#$(warning XEN_ROOT = $(XEN_ROOT))
+#$(warning DESTDIR = $(DESTDIR))
diff -r cdaaaa027bf8 -r 219d96d545fc tools/vnet/examples/vnet-insert
--- /dev/null Mon Sep 12 19:59:40 2005
+++ b/tools/vnet/examples/vnet-insert Mon Sep 12 20:00:41 2005
@@ -0,0 +1,28 @@
+#!/bin/bash
+
+# Insert the vnet module if it can be found and
+# it's not already there.
+vnet_insert () {
+ local module="vnet_module"
+ local mod_dir=/lib/modules/$(uname -r)
+ local mod_obj=""
+
+ if lsmod | grep -q ${module} ; then
+ echo "VNET: ${module} loaded"
+ return
+ fi
+ local mods=$(find ${mod_dir} -name "${module}.*o")
+ if [[ ${mods} ]] ; then
+ for mod_obj in ${mods} ; do
+ break
+ done
+ fi
+ if [ -z "${mod_obj}" ] ; then
+ echo "VNET: ${module} not found"
+ exit 1
+ fi
+ echo "VNET: Loading ${module} from ${mod_obj}"
+ insmod ${mod_obj} "$@"
+}
+
+vnet_insert "$@"
diff -r cdaaaa027bf8 -r 219d96d545fc tools/vnet/libxutil/mem_stream.c
--- /dev/null Mon Sep 12 19:59:40 2005
+++ b/tools/vnet/libxutil/mem_stream.c Mon Sep 12 20:00:41 2005
@@ -0,0 +1,319 @@
+/*
+ * Copyright (C) 2005 Mike Wray <mike.wray@xxxxxx>
+ *
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/** @file
+ * IOStream subtype for input and output to memory.
+ * Usable from user or kernel code (with __KERNEL__ defined).
+ */
+
+#include "sys_string.h"
+#include "mem_stream.h"
+#include "allocate.h"
+
+/** Internal state for a memory stream.
+ *
+ * The memory stream buffer is treated as a circular buffer.
+ * The lo and hi markers indicate positions in the buffer, but
+ * are not reduced modulo the buffer size. This avoids the ambiguity
+ * between a full and empty buffer when using reduced values.
+ *
+ * If x is a marker, then buf + (x % buf_n) is the corresponding
+ * pointer into the buffer. When the buffer is empty, lo == hi,
+ * and the corresponding pointers are equal. When the buffer is
+ * full, hi == lo + buf_n, and the corresponding pointers
+ * are also equal.
+ *
+ * Data is written after the high pointer and read from the lo pointer.
+ * The value hi - lo is the number of bytes in the buffer.
+ */
+typedef struct MemData {
+ /** Data buffer. */
+ char *buf;
+ /** Low marker - start of readable area. */
+ unsigned long lo;
+ /** High marker - end of readable area, start of writeable area. */
+ unsigned long hi;
+ /** Size of the buffer. */
+ unsigned int buf_n;
+ /** Maximum size the buffer can grow to. */
+ unsigned int buf_max;
+ /** Error code. */
+ int err;
+} MemData;
+
+/** Get number of bytes available to read.
+ *
+ * @param data mem stream
+ * @return bytes
+ */
+static inline int mem_len(struct MemData *data){
+ return data->hi - data->lo;
+}
+
+/** Get available space left in the buffer.
+ *
+ * @param data mem stream
+ * @return bytes
+ */
+static inline int mem_room(struct MemData *data){
+ return data->buf_n - mem_len(data);
+}
+
+/** Get a pointer to the start of the data in the buffer.
+ *
+ * @param data mem stream
+ * @return lo pointer
+ */
+static inline char * mem_lo(struct MemData *data){
+ return data->buf + (data->lo % data->buf_n);
+}
+
+/** Get a pointer to the end of the data in the buffer.
+ *
+ * @param data mem stream
+ * @return hi pointer
+ */
+static inline char * mem_hi(struct MemData *data){
+ return data->buf + (data->hi % data->buf_n);
+}
+
+/** Get a pointer to the end of the buffer.
+ *
+ * @param data mem stream
+ * @return end pointer
+ */
+static inline char * mem_end(struct MemData *data){
+ return data->buf + data->buf_n;
+}
+
+static int mem_error(IOStream *io);
+static int mem_close(IOStream *io);
+static void mem_free(IOStream *io);
+static int mem_write(IOStream *io, const void *msg, size_t n);
+static int mem_read(IOStream *io, void *buf, size_t n);
+
+/** Minimum delta used to increment the buffer. */
+static int delta_min = 256;
+
+/** Methods for a memory stream. */
+static IOMethods mem_methods = {
+ read: mem_read,
+ write: mem_write,
+ error: mem_error,
+ close: mem_close,
+ free: mem_free,
+};
+
+/** Get the memory stream state.
+ *
+ * @param io memory stream
+ * @return state
+ */
+static inline MemData *get_mem_data(IOStream *io){
+ return (MemData*)io->data;
+}
+
+/** Get the number of bytes available to read.
+ *
+ * @param io memory stream
+ * @return number of bytes
+ */
+int mem_stream_avail(IOStream *io){
+ MemData *data = get_mem_data(io);
+ return (data->err ? -data->err : mem_len(data));
+}
+
+/** Copy bytes from a memory stream into a buffer.
+ *
+ * @param data mem stream
+ * @param buf buffer
+ * @param n number of bytes to copy
+ */
+static void mem_get(MemData *data, char *buf, size_t n){
+ char *start = mem_lo(data);
+ char *end = mem_end(data);
+ if (start + n < end) {
+ memcpy(buf, start, n);
+ } else {
+ int k = end - start;
+ memcpy(buf, start, k);
+ memcpy(buf + k, data->buf, n - k);
+ }
+}
+
+/** Copy bytes from a buffer into a memory stream.
+ *
+ * @param data mem stream
+ * @param buf buffer
+ * @param n number of bytes to copy
+ */
+static void mem_put(MemData *data, const char *buf, size_t n){
+ char *start = mem_hi(data);
+ char *end = mem_end(data);
+ if(start + n < end){
+ memcpy(start, buf, n);
+ } else {
+ int k = end - start;
+ memcpy(start, buf, k);
+ memcpy(data->buf, buf + k, n - k);
+ }
+}
+
+/** Expand the buffer used by a memory stream.
+ *
+ * @param data mem stream
+ * @param extra number of bytes to expand by
+ * @return 0 on success, negative error otherwise
+ */
+static int mem_expand(MemData *data, size_t extra){
+ int err = -ENOMEM;
+ int delta = (extra < delta_min ? delta_min : extra);
+ if(data->buf_max > 0){
+ int delta_max = data->buf_max - data->buf_n;
+ if(delta > delta_max){
+ delta = extra;
+ if(delta > delta_max) goto exit;
+ }
+ }
+ int buf_n = data->buf_n + delta;
+ char *buf = allocate(buf_n);
+ if(!buf) goto exit;
+ mem_get(data, buf, mem_len(data));
+ data->hi = mem_len(data);
+ data->lo = 0;
+ deallocate(data->buf);
+ data->buf = buf;
+ data->buf_n = buf_n;
+ err = 0;
+ exit:
+ if(err){
+ data->err = -err;
+ }
+ return err;
+}
+
+/** Write bytes from a buffer into a memory stream.
+ * The internal buffer is expanded as needed to hold the data,
+ * up to the stream maximum (if specified). If the buffer cannot
+ * be expanded -ENOMEM is returned.
+ *
+ * @param io mem stream
+ * @param buf buffer
+ * @param n number of bytes to write
+ * @return number of bytes written on success, negative error code otherwise
+ */
+static int mem_write(IOStream *io, const void *msg, size_t n){
+ MemData *data = get_mem_data(io);
+ if(data->err) return -data->err;
+ int room = mem_room(data);
+ if(n > room){
+ int err = mem_expand(data, n - room);
+ if(err) return err;
+ }
+ mem_put(data, msg, n);
+ data->hi += n;
+ return n;
+}
+
+/** Read bytes from a memory stream into a buffer.
+ *
+ * @param io mem stream
+ * @param buf buffer
+ * @param n maximum number of bytes to read
+ * @return number of bytes read on success, negative error code otherwise
+ */
+static int mem_read(IOStream *io, void *buf, size_t n){
+ MemData *data = get_mem_data(io);
+ if(data->err) return -data->err;
+ int k = mem_len(data);
+ if(n > k){
+ n = k;
+ }
+ mem_get(data, buf, n);
+ data->lo += n;
+ return n;
+}
+
+/** Test if a memory stream has an error.
+ *
+ * @param io mem stream
+ * @return 0 if ok, error code otherwise
+ */
+static int mem_error(IOStream *io){
+ MemData *data = get_mem_data(io);
+ return data->err;
+}
+
+/** Close a memory stream.
+ *
+ * @param io mem stream
+ * @return 0
+ */
+static int mem_close(IOStream *io){
+ MemData *data = get_mem_data(io);
+ if(!data->err){
+ data->err = ENOTCONN;
+ }
+ return 0;
+}
+
+/** Free a memory stream.
+ *
+ * @param io mem stream
+ */
+static void mem_free(IOStream *io){
+ MemData *data = get_mem_data(io);
+ deallocate(data->buf);
+ memzero(data, sizeof(*data));
+ deallocate(data);
+}
+
+/** Allocate and initialise a memory stream.
+ *
+ * @param buf_n initial buffer size (0 means default)
+ * @param buf_max maximum buffer size (0 means no max)
+ * @return new stream (free using IOStream_close)
+ */
+IOStream *mem_stream_new_size(size_t buf_n, size_t buf_max){
+ int err = -ENOMEM;
+ MemData *data = ALLOCATE(MemData);
+ if(!data) goto exit;
+ IOStream *io = ALLOCATE(IOStream);
+ if(!io) goto exit;
+ if(buf_n <= delta_min){
+ buf_n = delta_min;
+ }
+ if(buf_max > 0 && buf_max < buf_n){
+ buf_max = buf_n;
+ }
+ data->buf = allocate(buf_n);
+ if(!data->buf) goto exit;
+ data->buf_n = buf_n;
+ data->buf_max = buf_max;
+ io->methods = &mem_methods;
+ io->data = data;
+ io->nofree = 0;
+ err = 0;
+ exit:
+ if(err){
+ deallocate(data);
+ deallocate(io);
+ io = NULL;
+ }
+ return io;
+}
diff -r cdaaaa027bf8 -r 219d96d545fc tools/vnet/libxutil/mem_stream.h
--- /dev/null Mon Sep 12 19:59:40 2005
+++ b/tools/vnet/libxutil/mem_stream.h Mon Sep 12 20:00:41 2005
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2005 Mike Wray <mike.wray@xxxxxx>
+ *
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef _XUTIL_MEM_STREAM_H_
+#define _XUTIL_MEM_STREAM_H_
+
+#include "iostream.h"
+
+extern IOStream *mem_stream_new_size(size_t buf_n, size_t buf_max);
+
+extern int mem_stream_avail(IOStream *io);
+
+static inline IOStream *mem_stream_new(void){
+ return mem_stream_new_size(0, 0);
+}
+
+#endif /* !_XUTIL_MEM_STREAM_H_ */
diff -r cdaaaa027bf8 -r 219d96d545fc tools/vnet/vnet-module/varp_util.c
--- /dev/null Mon Sep 12 19:59:40 2005
+++ b/tools/vnet/vnet-module/varp_util.c Mon Sep 12 20:00:41 2005
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2005 Mike Wray <mike.wray@xxxxxx>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free software Foundation, Inc.,
+ * 59 Temple Place, suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+static int hex16(char *s, uint16_t *val)
+{
+ int err = -EINVAL;
+ uint16_t v = 0;
+
+ for( ; *s; s++){
+ v <<= 4;
+ if('0' <= *s && *s <= '9'){
+ v |= *s - '0';
+ } else if('A' <= *s && *s <= 'F'){
+ v |= *s - 'A' + 10;
+ } else if('a' <= *s && *s <= 'f'){
+ v |= *s - 'a' + 10;
+ } else {
+ goto exit;
+ }
+ }
+ err = 0;
+ exit:
+ *val = (err ? 0 : v);
+ return err;
+}
+
+int VnetId_aton(const char *s, VnetId *vnet){
+ int err = -EINVAL;
+ const char *p, *q;
+ uint16_t v;
+ char buf[5];
+ int buf_n = sizeof(buf) - 1;
+ int i, n;
+ const int elts_n = 8;
+
+ q = s;
+ p = strchr(q, ':');
+ i = (p ? 0 : elts_n - 1);
+ do {
+ if(!p){
+ if(i < elts_n - 1) goto exit;
+ p = s + strlen(s);
+ }
+ n = p - q;
+ if(n > buf_n) goto exit;
+ memcpy(buf, q, n);
+ buf[n] = '\0';
+ err = hex16(buf, &v);
+ if(err) goto exit;
+ vnet->u.vnet16[i] = htons(v);
+ q = p+1;
+ p = strchr(q, ':');
+ i++;
+ } while(i < elts_n);
+ err = 0;
+ exit:
+ if(err){
+ *vnet = (VnetId){};
+ }
+ return err;
+}
diff -r cdaaaa027bf8 -r 219d96d545fc tools/vnet/vnet-module/varp_util.h
--- /dev/null Mon Sep 12 19:59:40 2005
+++ b/tools/vnet/vnet-module/varp_util.h Mon Sep 12 20:00:41 2005
@@ -0,0 +1,142 @@
+/*
+ * Copyright (C) 2004 Mike Wray <mike.wray@xxxxxx>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free software Foundation, Inc.,
+ * 59 Temple Place, suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+#ifndef _VNET_VARP_UTIL_H
+#define _VNET_VARP_UTIL_H
+
+#include "hash_table.h"
+
+/** Size of a string buffer to store a varp address. */
+#define VARP_ADDR_BUF 56
+
+/** Size of a string buffer to store a vnet id. */
+#define VNET_ID_BUF 56
+
+#ifndef NIPQUAD
+#define NIPQUAD(addr) \
+ ((unsigned char *)&addr)[0], \
+ ((unsigned char *)&addr)[1], \
+ ((unsigned char *)&addr)[2], \
+ ((unsigned char *)&addr)[3]
+#endif
+
+#ifndef NIP6
+#define NIP6(addr) \
+ ntohs((addr).s6_addr16[0]), \
+ ntohs((addr).s6_addr16[1]), \
+ ntohs((addr).s6_addr16[2]), \
+ ntohs((addr).s6_addr16[3]), \
+ ntohs((addr).s6_addr16[4]), \
+ ntohs((addr).s6_addr16[5]), \
+ ntohs((addr).s6_addr16[6]), \
+ ntohs((addr).s6_addr16[7])
+#endif
+
+
+static inline const char *VarpAddr_ntoa(VarpAddr *addr, char
buf[VARP_ADDR_BUF])
+{
+ switch(addr->family){
+ default:
+ case AF_INET:
+ sprintf(buf, "%u.%u.%u.%u",
+ NIPQUAD(addr->u.ip4));
+ break;
+ case AF_INET6:
+ sprintf(buf, "%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x",
+ NIP6(addr->u.ip6));
+ break;
+ }
+ return buf;
+}
+
+static inline const char *VnetId_ntoa(VnetId *vnet, char buf[VNET_ID_BUF])
+{
+ sprintf(buf, "%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x",
+ ntohs(vnet->u.vnet16[0]), \
+ ntohs(vnet->u.vnet16[1]), \
+ ntohs(vnet->u.vnet16[2]), \
+ ntohs(vnet->u.vnet16[3]), \
+ ntohs(vnet->u.vnet16[4]), \
+ ntohs(vnet->u.vnet16[5]), \
+ ntohs(vnet->u.vnet16[6]), \
+ ntohs(vnet->u.vnet16[7]));
+ return buf;
+}
+
+extern int VnetId_aton(const char *s, VnetId *vnet);
+
+/** Convert an unsigned in host order to a vnet id.
+ */
+static inline struct VnetId toVnetId(uint32_t vnetid){
+ struct VnetId vnet = {};
+ vnet.u.vnet32[3] = htonl(vnetid);
+ return vnet;
+}
+
+static inline uint32_t VnetId_hash(uint32_t h, VnetId *vnet)
+{
+ h = hash_hul(h, vnet->u.vnet32[0]);
+ h = hash_hul(h, vnet->u.vnet32[1]);
+ h = hash_hul(h, vnet->u.vnet32[2]);
+ h = hash_hul(h, vnet->u.vnet32[3]);
+ return h;
+}
+
+static inline int VnetId_eq(VnetId *vnet1, VnetId *vnet2)
+{
+ return memcmp(vnet1, vnet2, sizeof(VnetId)) == 0;
+}
+
+static inline uint32_t VarpAddr_hash(uint32_t h, VarpAddr *addr)
+{
+ h = hash_hul(h, addr->family);
+ if(addr->family == AF_INET6){
+ h = hash_hul(h, addr->u.ip6.s6_addr32[0]);
+ h = hash_hul(h, addr->u.ip6.s6_addr32[1]);
+ h = hash_hul(h, addr->u.ip6.s6_addr32[2]);
+ h = hash_hul(h, addr->u.ip6.s6_addr32[3]);
+ } else {
+ h = hash_hul(h, addr->u.ip4.s_addr);
+ }
+ return h;
+}
+
+static inline int VarpAddr_eq(VarpAddr *addr1, VarpAddr*addr2)
+{
+ return memcmp(addr1, addr2, sizeof(VarpAddr)) == 0;
+}
+
+static inline uint32_t Vmac_hash(uint32_t h, Vmac *vmac)
+{
+ h = hash_hul(h,
+ (vmac->mac[0] << 24) |
+ (vmac->mac[1] << 16) |
+ (vmac->mac[2] << 8) |
+ (vmac->mac[3] ));
+ h = hash_hul(h,
+ (vmac->mac[4] << 8) |
+ (vmac->mac[5] ));
+ return h;
+}
+
+static inline int Vmac_eq(Vmac *vmac1, Vmac *vmac2)
+{
+ return memcmp(vmac1, vmac2, sizeof(Vmac)) == 0;
+}
+
+#endif /* _VNET_VARP_UTIL_H */
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|