[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Minios-devel] [UNIKRAFT/LIBWAMR PATCH 2/3] Add Makefile.uk
Hi Justin, Please see inline. -- Felipe On 18.09.19, 05:05, "Minios-devel on behalf of Jia He" <minios-devel-bounces@xxxxxxxxxxxxxxxxxxxx on behalf of jiakernel2@xxxxxxxxx> wrote: On 2019/8/29 7:03, Felipe Huici wrote: > This is a port of wamr to Unikraft as an external library. It requires > libc, a network stack and pthread support, so in your application > Makefile the library dependency list should read: > > LIBS := ...:$(UK_LIBS)/pthread-embedded:$(UK_LIBS)/lwip: > $(UK_LIBS)/newlib:$(UK_LIBS)/wamr:... > > Please refer to README.md for information on running it. > > Signed-off-by: Felipe Huici <felipe.huici@xxxxxxxxx> > --- > Makefile.uk | 105 +++++++++ > include/bh_platform.h | 129 +++++++++++ > main.c | 236 +++++++++++++++++++++ > ...m-log-fix-pthread-embedded-pthread-t-type.patch | 15 ++ > ...hread-fix-pthread-embedded-pthread-t-type.patch | 16 ++ > ...3-bh-thread-use-wasm-log-insteadof-bh-log.patch | 11 + > 6 files changed, 512 insertions(+) > create mode 100644 Makefile.uk > create mode 100644 include/bh_platform.h > create mode 100644 main.c > create mode 100644 patches/0001-wasm-log-fix-pthread-embedded-pthread-t-type.patch > create mode 100644 patches/0002-bh-thread-fix-pthread-embedded-pthread-t-type.patch > create mode 100644 patches/0003-bh-thread-use-wasm-log-insteadof-bh-log.patch > > diff --git a/Makefile.uk b/Makefile.uk > new file mode 100644 > index 0000000..a9f9a53 > --- /dev/null > +++ b/Makefile.uk > @@ -0,0 +1,105 @@ > +# wamr Makefile.uk > +# > +# Authors: Felipe Huici <felipe.huici@xxxxxxxxx> > +# > +# > +# Copyright (c) 2019, NEC Europe Ltd., NEC Corporation. All rights reserved. > +# > +# Redistribution and use in source and binary forms, with or without > +# modification, are permitted provided that the following conditions > +# are met: > +# > +# 1. Redistributions of source code must retain the above copyright > +# notice, this list of conditions and the following disclaimer. > +# 2. Redistributions in binary form must reproduce the above copyright > +# notice, this list of conditions and the following disclaimer in the > +# documentation and/or other materials provided with the distribution. > +# 3. Neither the name of the copyright holder nor the names of its > +# contributors may be used to endorse or promote products derived from > +# this software without specific prior written permission. > +# > +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" > +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE > +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE > +# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE > +# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR > +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF > +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS > +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN > +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) > +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE > +# POSSIBILITY OF SUCH DAMAGE. > +# > +# THIS HEADER MAY NOT BE EXTRACTED OR MODIFIED IN ANY WAY. > +# > + > +################################################################################ > +# Library registration > +################################################################################ > +$(eval $(call addlib_s,libwamr,$(CONFIG_LIBWAMR))) > + > +################################################################################ > +# Sources > +################################################################################ > +LIBWAMR_VERSION=master > +LIBWAMR_URL=https://github.com/intel/wasm-micro-runtime/archive/$(LIBWAMR_VERSION).zip > +LIBWAMR_DIR=wasm-micro-runtime-master > +LIBWAMR_PATCHDIR=$(LIBWAMR_BASE)/patches > +$(eval $(call fetch,libwamr,$(LIBWAMR_URL),$(LIBWAMR_DIR).zip)) > +$(eval $(call patch,libwamr,$(LIBWAMR_PATCHDIR),$(LIBWAMR_DIR))) > + > +################################################################################ > +# Helpers > +################################################################################ > +LIBWAMR_SRC=$(LIBWAMR_ORIGIN)/$(LIBWAMR_DIR) > + > +################################################################################ > +# Library includes > +################################################################################ > +CINCLUDES-$(CONFIG_LIBWAMR) += -I$(LIBWAMR_BASE)/include \ > + -I$(LIBWAMR_SRC)/core/iwasm/runtime/vmcore-wasm \ > + -I$(LIBWAMR_SRC)/core/iwasm/runtime/platform/include \ > + -I$(LIBWAMR_SRC)/core/iwasm/runtime/include \ > + -I$(LIBWAMR_SRC)/core/shared-lib/platform/include \ > + -I$(LIBWAMR_SRC)/core/shared-lib/include \ > + > +################################################################################ > +# Library flags > +################################################################################ > +LIBWAMR_SUPPRESS_FLAGS += -Wno-implicit-function-declaration \ > + -Wno-sign-compare \ > + -Wno-pointer-to-int-cast \ > + -Wno-unused-parameter \ > + -Wno-int-conversion \ > + -Wno-unused-label \ > + -Wno-unused-but-set-variable > + > +LIBWAMR_CFLAGS-y += -DNVALGRIND $(LIBWAMR_SUPPRESS_FLAGS) > +LIBWAMR_CXXFLAGS-y += -DNVALGRIND $(LIBWAMR_SUPPRESS_FLAGS) > + > +################################################################################ > +# Glue code > +################################################################################ > +LIBWAMR_SRCS-y += $(LIBWAMR_BASE)/main.c > + > +################################################################################ > +# Sources > +################################################################################ > +LIBWAMR_SRCS-y += $(LIBWAMR_SRC)/core/iwasm/runtime/vmcore-wasm/invokeNative_general.c > +LIBWAMR_SRCS-y += $(LIBWAMR_SRC)/core/iwasm/runtime/vmcore-wasm/wasm_application.c > +LIBWAMR_SRCS-y += $(LIBWAMR_SRC)/core/iwasm/runtime/vmcore-wasm/wasm_interp.c > +LIBWAMR_SRCS-y += $(LIBWAMR_SRC)/core/iwasm/runtime/vmcore-wasm/wasm_loader.c > +LIBWAMR_SRCS-y += $(LIBWAMR_SRC)/core/iwasm/runtime/vmcore-wasm/wasm_runtime.c > +LIBWAMR_SRCS-y += $(LIBWAMR_SRC)/core/shared-lib/mem-alloc/bh_memory.c > +LIBWAMR_SRCS-y += $(LIBWAMR_SRC)/core/iwasm/runtime/utils/wasm_log.c > +LIBWAMR_SRCS-y += $(LIBWAMR_SRC)/core/shared-lib/platform/linux/bh_thread.c > +LIBWAMR_SRCS-y += $(LIBWAMR_SRC)/core/iwasm/runtime/utils/wasm_hashmap.c > +LIBWAMR_SRCS-y += $(LIBWAMR_SRC)/core/iwasm/lib/native/libc/libc_wrapper.c > +LIBWAMR_SRCS-y += $(LIBWAMR_SRC)/core/iwasm/runtime/utils/wasm_dlfcn.c > +LIBWAMR_SRCS-y += $(LIBWAMR_SRC)/core/shared-lib/mem-alloc/mem_alloc.c > +LIBWAMR_SRCS-y += $(LIBWAMR_SRC)/core/shared-lib/platform/linux/bh_platform.c > +LIBWAMR_SRCS-y += $(LIBWAMR_SRC)/core/iwasm/runtime/platform/zephyr/wasm_native.c > +LIBWAMR_SRCS-y += $(LIBWAMR_SRC)/core/iwasm/lib/native/base/base_lib_export.c > +LIBWAMR_SRCS-y += $(LIBWAMR_SRC)/core/iwasm/products/linux/ext_lib_export.c > +LIBWAMR_SRCS-y += $(LIBWAMR_SRC)/core/shared-lib/mem-alloc/ems/ems_kfc.c > +LIBWAMR_SRCS-y += $(LIBWAMR_SRC)/core/shared-lib/mem-alloc/ems/ems_alloc.c > diff --git a/include/bh_platform.h b/include/bh_platform.h > new file mode 100644 > index 0000000..00c25b4 > --- /dev/null > +++ b/include/bh_platform.h I saw lots of errors and warnings by support/scripts/check_patch.pl in this file Ok, I'll have a look. > @@ -0,0 +1,129 @@ > +/* > + * Copyright (C) 2019 Intel Corporation. All rights reserved. > + * > + * Licensed under the Apache License, Version 2.0 (the "License"); > + * you may not use this file except in compliance with the License. > + * You may obtain a copy of the License at > + * > + * http://www.apache.org/licenses/LICENSE-2.0 > + * > + * Unless required by applicable law or agreed to in writing, software > + * distributed under the License is distributed on an "AS IS" BASIS, > + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. > + * See the License for the specific language governing permissions and > + * limitations under the License. > + */ > + > +#ifndef _BH_PLATFORM_H > +#define _BH_PLATFORM_H > + > +#include "bh_config.h" > +#include "bh_types.h" > +#include "bh_memory.h" > +#include <inttypes.h> > +#include <stdbool.h> > +#include <assert.h> > +#include <time.h> > +#include <string.h> > +#include <stdio.h> > +#include <assert.h> redudant assert.h, > + > +#ifndef __cplusplus > +int snprintf(char *buffer, size_t count, const char *format, ...); > +#endif > + > +#ifdef __cplusplus > +extern "C" { > +#endif > + > +typedef uint64_t uint64; > +typedef int64_t int64; > + > +extern void DEBUGME(void); > + > +#define DIE do{bh_debug("Die here\n\n\n\n\n\n\n\n\n\n\n\n\n\n"); DEBUGME(void); while(1);}while(0) > + > +#define BH_PLATFORM "Linux" > + > +/* NEED qsort */ > + > +#include <stdarg.h> > +#include <ctype.h> > +#include <pthread.h> > +#include <limits.h> > +#include <semaphore.h> > +#include <errno.h> > +#include <sys/socket.h> > +#include <netinet/in.h> > + > +#define _STACK_SIZE_ADJUSTMENT (32 * 1024) > + > +/* Stack size of applet manager thread. */ > +#define BH_APPLET_MANAGER_THREAD_STACK_SIZE (8 * 1024 + _STACK_SIZE_ADJUSTMENT) > + > +/* Stack size of HMC thread. */ > +#define BH_HMC_THREAD_STACK_SIZE (4 * 1024 + _STACK_SIZE_ADJUSTMENT) > + > +/* Stack size of watchdog thread. */ > +#define BH_WATCHDOG_THREAD_SIZE (4 * 1024 + _STACK_SIZE_ADJUSTMENT) > + > +/* Stack size of applet threads's native part. */ > +#define BH_APPLET_PRESERVED_STACK_SIZE (8 * 1024 + _STACK_SIZE_ADJUSTMENT) > + > +/* Stack size of remote invoke listen thread. */ > +#define BH_REMOTE_INVOKE_THREAD_STACK_SIZE (4 * 1024 + _STACK_SIZE_ADJUSTMENT) > + > +/* Stack size of remote post listen thread. */ > +#define BH_REMOTE_POST_THREAD_STACK_SIZE (4 * 1024 + _STACK_SIZE_ADJUSTMENT) > + > +/* Maximal recursion depth of interpreter. */ > +#define BH_MAX_INTERP_RECURSION_DEPTH 8 > + > +/* Default thread priority */ > +#define BH_THREAD_DEFAULT_PRIORITY 0 > + > +#define BH_ROUTINE_MODIFIER > +#define BHT_TIMEDOUT ETIMEDOUT > + > +#define INVALID_THREAD_ID 0xFFffFFff > +#define INVALID_SEM_ID SEM_FAILED > + > +typedef pthread_t korp_tid; > +typedef pthread_mutex_t korp_mutex; > +typedef sem_t korp_sem; > +typedef pthread_cond_t korp_cond; > +typedef pthread_t korp_thread; > +typedef void* (*thread_start_routine_t)(void*); > + > +#define wa_malloc bh_malloc > +#define wa_free bh_free > +#define wa_strdup bh_strdup > + > +double fmod(double x, double y); > +float fmodf(float x, float y); > + > +/* Definitions for applet debugging */ > +#define APPLET_DEBUG_LISTEN_PORT 8000 > +#define BH_SOCKET_INVALID_SOCK -1 > +#define BH_WAIT_FOREVER 0xFFFFFFFF > +typedef int bh_socket_t; > + > +#ifndef NULL > +# define NULL ((void*) 0) > +#endif > + > +#define bh_assert assert > + > +extern int b_memcpy_s(void * s1, unsigned int s1max, const void * s2, > + unsigned int n); > +extern int b_strcat_s(char * s1, size_t s1max, const char * s2); > +extern int b_strcpy_s(char * s1, size_t s1max, const char * s2); > +extern int fopen_s(FILE ** pFile, const char *filename, const char *mode); > + > +extern char *bh_strdup(const char *s); > + > +#ifdef __cplusplus > +} > +#endif > + > +#endif > diff --git a/main.c b/main.c Seems this main.c is also from opensource https://raw.githubusercontent.com/intel/wasm-micro-runtime/master/core/iwasm/products/linux/main.c How about also use the way original +patch? Sounds good, will do in the next version. > new file mode 100644 > index 0000000..91f2148 > --- /dev/null > +++ b/main.c > @@ -0,0 +1,236 @@ > +/* > + * Copyright (C) 2019 Intel Corporation. All rights reserved. > + * > + * Licensed under the Apache License, Version 2.0 (the "License"); > + * you may not use this file except in compliance with the License. > + * You may obtain a copy of the License at > + * > + * http://www.apache.org/licenses/LICENSE-2.0 > + * > + * Unless required by applicable law or agreed to in writing, software > + * distributed under the License is distributed on an "AS IS" BASIS, > + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. > + * See the License for the specific language governing permissions and > + * limitations under the License. > + */ > + > +#ifndef _GNU_SOURCE > +#define _GNU_SOURCE > +#endif > +#include <stdlib.h> > +#include <string.h> > +#include "bh_platform.h" > +#include "wasm_assert.h" > +#include "wasm_log.h" > +#include "wasm_platform_log.h" > +#include "wasm_thread.h" > +#include "wasm_export.h" > +#include "wasm_memory.h" > +#include "bh_memory.h" > + > +#include <uk/plat/memory.h> > + > +static int app_argc; > +static char **app_argv; > + > +static int print_help() > +{ > + wasm_printf("Usage: iwasm [-options] wasm_file [args...]\n"); > + wasm_printf("options:\n"); > + wasm_printf(" -f|--function name Specify function name to run in module\n" > + " rather than main\n"); > +#if WASM_ENABLE_LOG != 0 > + wasm_printf(" -v=X Set log verbose level (0 to 2, default is 1),\n" > + " larger level with more log\n"); > +#endif > + wasm_printf(" --repl Start a very simple REPL (read-eval-print-loop) mode\n" > + " that runs commands in the form of `FUNC ARG...`\n"); > + return 1; > +} > + > +static void* > +app_instance_main(wasm_module_inst_t module_inst) > +{ > + const char *exception; > + > + wasm_application_execute_main(module_inst, app_argc, app_argv); > + if ((exception = wasm_runtime_get_exception(module_inst))) > + wasm_printf("%s\n", exception); > + return NULL; > +} > + > +static void* > +app_instance_func(wasm_module_inst_t module_inst, const char *func_name) > +{ > + const char *exception; > + > + wasm_application_execute_func(module_inst, func_name, app_argc - 1, > + app_argv + 1); > + if ((exception = wasm_runtime_get_exception(module_inst))) > + wasm_printf("%s\n", exception); > + return NULL; > +} > + > +/** > + * Split a space separated strings into an array of strings > + * Returns NULL on failure > + * Memory must be freed by caller > + * Based on: http://stackoverflow.com/a/11198630/471795 > + */ > +static char ** > +split_string(char *str, int *count) > +{ > + char **res = NULL; > + char *p; > + int idx = 0; > + > + /* split string and append tokens to 'res' */ > + do { > + p = strtok(str, " "); > + str = NULL; > + res = (char**) realloc(res, sizeof(char*) * (idx + 1)); > + if (res == NULL) { > + return NULL; > + } > + res[idx++] = p; > + } while (p); > + > + if (count) { > + *count = idx - 1; > + } > + return res; > +} > + > +static void* > +app_instance_repl(wasm_module_inst_t module_inst) > +{ > + char *cmd = NULL; > + size_t len = 0; > + ssize_t n; > + > + while ((wasm_printf("webassembly> "), n = getline(&cmd, &len, stdin)) != -1) { > + wasm_assert(n > 0); > + if (cmd[n - 1] == '\n') { > + if (n == 1) > + continue; > + else > + cmd[n - 1] = '\0'; > + } > + app_argv = split_string(cmd, &app_argc); > + if (app_argv == NULL) { > + LOG_ERROR("Wasm prepare param failed: split string failed.\n"); > + break; > + } > + if (app_argc != 0) { > + wasm_application_execute_func(module_inst, app_argv[0], > + app_argc - 1, app_argv + 1); > + } > + free(app_argv); > + } > + free(cmd); > + return NULL; > +} > + > +static char global_heap_buf[512 * 1024] = { 0 }; > + > +int wasm_main(int argc, char *argv[]) > +{ > + char *wasm_file = NULL; > + const char *func_name = NULL; > + uint8 *wasm_file_buf = NULL; > + int wasm_file_size; > + wasm_module_t wasm_module = NULL; > + wasm_module_inst_t wasm_module_inst = NULL; > + char error_buf[128]; > +#if WASM_ENABLE_LOG != 0 > + int log_verbose_level = 1; > +#endif > + bool is_repl_mode = false; > + > + /* Process options. */ > + for (argc--, argv++; argc > 0 && argv[0][0] == '-'; argc--, argv++) { > + if (!strcmp(argv[0], "-f") || !strcmp(argv[0], "--function")) { > + argc--, argv++; > + func_name = argv[0]; > + } > +#if WASM_ENABLE_LOG != 0 > + else if (!strncmp(argv[0], "-v=", 3)) { > + log_verbose_level = atoi(argv[0] + 3); > + if (log_verbose_level < 0 || log_verbose_level > 2) > + return print_help(); > + } > +#endif > + > + else if (!strcmp(argv[0], "--repl")) > + is_repl_mode = true; > + } > + > + wasm_file = argv[0]; > + app_argc = argc; > + app_argv = argv; > + > + if (bh_memory_init_with_pool(global_heap_buf, sizeof(global_heap_buf)) > + != 0) { > + wasm_printf("Init global heap failed.\n"); > + return -1; > + } > + > + /* initialize runtime environment */ > + if (!wasm_runtime_init()) > + goto fail1; > + > + wasm_log_set_verbose_level(log_verbose_level); > + > + /* load from initrd */ > + struct ukplat_memregion_desc img; > + if (ukplat_memregion_find_initrd0(&img) >= 0) { You'd better handle the case ukplat_memregion_find_initrd0(&img)<0 Otherwise you will expose latter codes with NULL wasm_module Ok, thanks, will fix. -- Felipe --- Cheers, Justin (Jia He) > + wasm_file_buf = (uint8*)img.base; > + wasm_file_size = img.len; > + > + /* load WASM module */ > + if (!(wasm_module = wasm_runtime_load(wasm_file_buf, wasm_file_size, > + error_buf, sizeof(error_buf)))) { > + wasm_printf("%s\n", error_buf); > + goto fail3; > + } > + > + /* instantiate the module */ > + if (!(wasm_module_inst = wasm_runtime_instantiate(wasm_module, > + 16 * 1024, /* stack size */ > + 8 * 1024, /* heap size */ > + error_buf, > + sizeof(error_buf)))) { > + wasm_printf("%s\n", error_buf); > + goto fail4; > + } > + } > + > + if (is_repl_mode) { > + printf("Entering REPL mode...\n"); > + app_instance_repl(wasm_module_inst); > + } > + else if (func_name) > + app_instance_func(wasm_module_inst, func_name); > + else > + app_instance_main(wasm_module_inst); > + > + /* destroy the module instance */ > + wasm_runtime_deinstantiate(wasm_module_inst); > + > +fail4: > + /* unload the module */ > + wasm_runtime_unload(wasm_module); > + > +fail3: > + /* free the file buffer */ > + wasm_free(wasm_file_buf); > + > +fail2: > + /* destroy runtime environment */ > + wasm_runtime_destroy(); > + > +fail1: > + bh_memory_destroy(); > + return 0; > +} > + > diff --git a/patches/0001-wasm-log-fix-pthread-embedded-pthread-t-type.patch b/patches/0001-wasm-log-fix-pthread-embedded-pthread-t-type.patch > new file mode 100644 > index 0000000..8630539 > --- /dev/null > +++ b/patches/0001-wasm-log-fix-pthread-embedded-pthread-t-type.patch > @@ -0,0 +1,15 @@ > +--- /core/iwasm/runtime/utils/wasm_log.c.orig 2019-07-30 10:01:46.715217329 +0200 > ++++ /core/iwasm/runtime/utils/wasm_log.c 2019-07-30 10:07:26.891746359 +0200 > +@@ -57,8 +57,11 @@ > + /* Try to own the log stream and start the log output. */ > + ws_mutex_lock (&log_stream_lock); > + self = ws_self_thread (); > ++#ifdef CONFIG_LIBPTHREAD_EMBEDDED > ++ wasm_printf ("[%X]: ", (int)self.p); > ++#else > + wasm_printf ("[%X]: ", (int)self); > +- > ++#endif > + return true; > + } > + > diff --git a/patches/0002-bh-thread-fix-pthread-embedded-pthread-t-type.patch b/patches/0002-bh-thread-fix-pthread-embedded-pthread-t-type.patch > new file mode 100644 > index 0000000..7101ce2 > --- /dev/null > +++ b/patches/0002-bh-thread-fix-pthread-embedded-pthread-t-type.patch > @@ -0,0 +1,16 @@ > +--- /core/shared-lib/platform/linux/bh_thread.c.orig 2019-07-30 10:08:21.243191688 +0200 > ++++ /core/shared-lib/platform/linux/bh_thread.c 2019-07-30 10:08:55.110846278 +0200 > +@@ -93,8 +93,12 @@ > + bh_assert(tid); > + bh_assert(start); > + > ++#ifdef CONFIG_LIBPTHREAD_EMBEDDED > ++ tid->p = INVALID_THREAD_ID; > ++#else > + *tid = INVALID_THREAD_ID; > +- > ++#endif > ++ > + pthread_attr_init(&tattr); > + pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_JOINABLE); > + if (pthread_attr_setstacksize(&tattr, stack_size) != 0) { > diff --git a/patches/0003-bh-thread-use-wasm-log-insteadof-bh-log.patch b/patches/0003-bh-thread-use-wasm-log-insteadof-bh-log.patch > new file mode 100644 > index 0000000..6a5e923 > --- /dev/null > +++ b/patches/0003-bh-thread-use-wasm-log-insteadof-bh-log.patch > @@ -0,0 +1,11 @@ > +--- /core/shared-lib/platform/linux/bh_thread.c.orig 2019-07-30 11:10:57.884821508 +0200 > ++++ /core/shared-lib/platform/linux/bh_thread.c 2019-07-30 11:11:54.492244787 +0200 > +@@ -16,7 +16,7 @@ > + > + #include "bh_thread.h" > + #include "bh_assert.h" > +-#include "bh_log.h" > ++#include "wasm_log.h" > + #include "bh_memory.h" > + #include <stdio.h> > + #include <stdlib.h> _______________________________________________ Minios-devel mailing list Minios-devel@xxxxxxxxxxxxxxxxxxxx https://lists.xenproject.org/mailman/listinfo/minios-devel _______________________________________________ Minios-devel mailing list Minios-devel@xxxxxxxxxxxxxxxxxxxx https://lists.xenproject.org/mailman/listinfo/minios-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |