Add initial code.
authorMatthias Bolte <matthias.bolte@googlemail.com>
Wed, 18 Mar 2009 19:13:27 +0000 (20:13 +0100)
committerMatthias Bolte <matthias.bolte@googlemail.com>
Wed, 18 Mar 2009 19:13:27 +0000 (20:13 +0100)
Signed-off-by: Matthias Bolte <matthias.bolte@googlemail.com>

25 files changed:
Makefile [new file with mode: 0644]
README [new file with mode: 0644]
cli/Makefile [new file with mode: 0644]
cli/cli.c [new file with mode: 0644]
config.mk [new file with mode: 0644]
daemon/Makefile [new file with mode: 0644]
daemon/daemon.c [new file with mode: 0644]
include/libvscmgmt/libvscmgmt.h [new file with mode: 0644]
lib/Makefile [new file with mode: 0644]
lib/global.c [new file with mode: 0644]
lib/host.c [new file with mode: 0644]
proxy/Makefile [new file with mode: 0644]
proxy/proxy.c [new file with mode: 0644]
tests/Makefile [new file with mode: 0644]
tests/ipv4.c [new file with mode: 0644]
tests/uuid.c [new file with mode: 0644]
util/Makefile [new file with mode: 0644]
util/assert.c [new file with mode: 0644]
util/error.c [new file with mode: 0644]
util/host_type.c [new file with mode: 0644]
util/internal.h [new file with mode: 0644]
util/ipv4.c [new file with mode: 0644]
util/memory.c [new file with mode: 0644]
util/string.c [new file with mode: 0644]
util/uuid.c [new file with mode: 0644]

diff --git a/Makefile b/Makefile
new file mode 100644 (file)
index 0000000..5bdb088
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,26 @@
+#!/usr/bin/make
+#
+# Makefile to build the Library for Virtualized Super Computer Management
+#
+# Copyright (C) 2009 Matthias Bolte <matthias.bolte@googlemail.com>
+#
+
+SUBDIRS = util lib daemon proxy cli tests
+
+#
+# Rules
+#
+
+.PHONY: all clean install check
+
+all:
+       @echo $(SUBDIRS) | sed 's,\([a-z]*\),$(MAKE) -C \1 all;,g' | sh
+
+clean:
+       @echo $(SUBDIRS) | sed 's,\([a-z]*\),$(MAKE) -C \1 clean;,g' | sh
+
+check:
+       $(MAKE) -C tests check
+
+install:
+       @echo $(SUBDIRS) | sed 's,\([a-z]*\),$(MAKE) -C \1 install;,g' | sh
diff --git a/README b/README
new file mode 100644 (file)
index 0000000..ecc403e
--- /dev/null
+++ b/README
@@ -0,0 +1,8 @@
+Install the XML-RPC-C advanced branch from SVN (at least version 1.17.7)
+
+    svn co https://xmlrpc-c.svn.sourceforge.net/svnroot/xmlrpc-c/advanced/ xmlrpc-c-advanced
+    cd xmlrpc-c-advanced
+    ./configure
+    make
+    sudo make install
+
diff --git a/cli/Makefile b/cli/Makefile
new file mode 100644 (file)
index 0000000..5508a87
--- /dev/null
@@ -0,0 +1,43 @@
+#!/usr/bin/make
+#
+# Makefile to build the CLI for Virtualized Super Computer Management
+#
+# Copyright (C) 2009 Matthias Bolte <matthias.bolte@googlemail.com>
+#
+
+include ../config.mk
+
+CFLAGS  += -fPIC
+OBJS     = cli.o
+CLI      = vscmgmt-cli
+
+#
+# Fancy gcc options
+#
+
+# libvscmgmt-proxy
+LDFLAGS += -L ../proxy -lvscmgmt-proxy
+
+# libvscmgmt-util
+LDFLAGS += -L ../util -lvscmgmt-util
+
+#
+# Rules
+#
+
+.PHONY: all clean install
+
+all: $(CLI)
+
+clean:
+       rm -rf $(CLI) $(OBJS)
+
+install:
+       mkdir -p $(PREFIX)
+       install -c -m 755 $(CLI) $(PREFIX)/bin/$(CLI)
+
+$(CLI): $(OBJS)
+       $(CC) -o $(CLI) $(OBJS) $(LDFLAGS)
+
+%.o: %.c
+       $(CC) $(CFLAGS) -c $<
diff --git a/cli/cli.c b/cli/cli.c
new file mode 100644 (file)
index 0000000..edd489e
--- /dev/null
+++ b/cli/cli.c
@@ -0,0 +1,73 @@
+/*
+ * cli.c: CLI for Virtualized Super Computer Management
+ *
+ * Copyright (C) 2009 Matthias Bolte <matthias.bolte@googlemail.com>
+ *
+ * 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
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "../util/internal.h"
+
+int
+main (int argc ATTR_UNUSED, const char **argv ATTR_UNUSED)
+{
+       int result = 0;
+       struct VscMgmtError error;
+       struct VscMgmtHostInfo host_info;
+       struct VscMgmtUuid host_uuid;
+
+       vsc_mgmt_error_init (&error);
+
+       vsc_mgmt_global_init (&error, "http://localhost:8080/RPC2");
+
+       if (error.occured) {
+               vsc_mgmt_error_fprint (&error, stderr);
+               goto failure;
+       }
+
+       vsc_mgmt_ipv4_parse (&error, "131.234.92.31", &host_info.ipv4);
+
+       if (error.occured) {
+               vsc_mgmt_error_fprint (&error, stderr);
+               goto failure;
+       }
+
+       host_info.host_type = VSC_MGMT__HOST_TYPE__ESX;
+       host_info.username = (char *) "root";
+       host_info.password = (char *) "blubb";
+
+       vsc_mgmt_host_add (&error, &host_info, &host_uuid);
+
+       if (error.occured) {
+               vsc_mgmt_error_fprint (&error, stderr);
+               goto failure;
+       }
+
+cleanup:
+       vsc_mgmt_error_cleanup (&error);
+
+       vsc_mgmt_global_cleanup();
+
+       return result;
+
+failure:
+       result = -1;
+
+       goto cleanup;
+}
+
diff --git a/config.mk b/config.mk
new file mode 100644 (file)
index 0000000..ac54976
--- /dev/null
+++ b/config.mk
@@ -0,0 +1,22 @@
+#
+# General config for all Makefile for Virtualized Super Computer Management
+#
+# Copyright (C) 2009 Matthias Bolte <matthias.bolte@googlemail.com>
+#
+
+CC       = gcc
+PREFIX   = /usr/local
+
+#
+# Fancy gcc options
+#
+
+# Daumenschrauben
+CFLAGS  += -std=gnu99 -Wall -Werror -W -Wextra -Wmissing-declarations \
+           -Wmissing-prototypes -Wcast-align -Wpointer-arith -Wreturn-type \
+           -Wformat -Wformat-security -Wnested-externs -Wshadow \
+           -Wwrite-strings -Waggregate-return -Wstrict-prototypes -Winline \
+           -Wno-sign-compare
+
+# Debugging
+CFLAGS  += -O0 -g -ggdb
diff --git a/daemon/Makefile b/daemon/Makefile
new file mode 100644 (file)
index 0000000..91c979b
--- /dev/null
@@ -0,0 +1,47 @@
+#!/usr/bin/make
+#
+# Makefile to build the Daemon for Virtualized Super Computer Management
+#
+# Copyright (C) 2009 Matthias Bolte <matthias.bolte@googlemail.com>
+#
+
+include ../config.mk
+
+CFLAGS  += -fPIC
+OBJS     = daemon.o
+DAEMON   = vscmgmtd
+
+#
+# Fancy gcc options
+#
+
+# libvscmgmt
+LDFLAGS += -L ../lib -lvscmgmt
+
+# libvscmgmt-util
+LDFLAGS += -L ../util -lvscmgmt-util
+
+# libxmlrpc-c
+CFLAGS  += $(shell xmlrpc-c-config abyss-server --cflags)
+LDFLAGS += $(shell xmlrpc-c-config abyss-server --libs)
+
+#
+# Rules
+#
+
+.PHONY: all clean install
+
+all: $(DAEMON)
+
+clean:
+       rm -rf $(DAEMON) $(OBJS)
+
+install:
+       mkdir -p $(PREFIX)
+       install -c -m 755 $(DAEMON) $(PREFIX)/bin/$(DAEMON)
+
+$(DAEMON): $(OBJS)
+       $(CC) -o $(DAEMON) $(OBJS) $(LDFLAGS)
+
+%.o: %.c
+       $(CC) $(CFLAGS) -c $<
diff --git a/daemon/daemon.c b/daemon/daemon.c
new file mode 100644 (file)
index 0000000..4eeeec5
--- /dev/null
@@ -0,0 +1,152 @@
+/*
+ * daemon.c: Daemon for Virtualized Super Computer Management
+ *
+ * Copyright (C) 2009 Matthias Bolte <matthias.bolte@googlemail.com>
+ *
+ * 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
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#include <xmlrpc-c/base.h>
+#include <xmlrpc-c/server.h>
+#include <xmlrpc-c/server_abyss.h>
+
+#include "../util/internal.h"
+
+#define _ERROR_TO_XMLRPC(error, env) \
+       xmlrpc_env_set_fault_formatted (env, XMLRPC_INTERNAL_ERROR, \
+                                       "libvscmgmt [%s] %s", \
+                                        vsc_mgmt_error_string ((error)->code), \
+                                        (error)->message != NULL ? (error)->message \
+                                                                 : "");
+
+static xmlrpc_value *
+xmlrpc_vsc_mgmt_get_version (xmlrpc_env *env,
+                             xmlrpc_value *param_list ATTR_UNUSED,
+                             void *server_info ATTR_UNUSED,
+                             void *channel_info ATTR_UNUSED)
+{
+       int major, minor, patch;
+
+       vsc_mgmt_get_version (&major, &minor, &patch);
+
+       return xmlrpc_build_value (env, "{s:i,s:i,s:i}",
+                                  "major", (xmlrpc_int32) major,
+                                  "minor", (xmlrpc_int32) minor,
+                                  "patch", (xmlrpc_int32) patch);
+}
+
+static xmlrpc_value *
+xmlrpc_vsc_mgmt_host_add (xmlrpc_env *env,
+                          xmlrpc_value *param_list,
+                          void *server_info ATTR_UNUSED,
+                          void *channel_info ATTR_UNUSED)
+{
+       struct VscMgmtError error;
+       char* ipv4_string = NULL;
+       char* host_type_string = NULL;
+       struct VscMgmtHostInfo host_info;
+       xmlrpc_value *result = NULL;
+
+       host_info.username = NULL;
+       host_info.password = NULL;
+
+       xmlrpc_decompose_value (env, param_list, "({s:{s:s,s:s,s:s,s:s,*},*})",
+                               "host_info",
+                               "ipv4", &ipv4_string,
+                               "host_type", &host_type_string,
+                               "username", &host_info.username,
+                               "password", &host_info.password);
+
+       if (env->fault_occurred) {
+               goto cleanup;
+       }
+
+       printf ("ipv4_string %s\n", ipv4_string);
+       printf ("host_type %s\n", host_type_string);
+       printf ("username %s\n", host_info.username);
+       printf ("password %s\n", host_info.password);
+
+       vsc_mgmt_error_init (&error);
+
+       vsc_mgmt_ipv4_parse (&error, ipv4_string, &host_info.ipv4);
+
+       if (error.occured) {
+               _ERROR_TO_XMLRPC (&error, env);
+               goto cleanup;
+       }
+
+       host_info.host_type = vsc_mgmt_host_type_parse (&error, host_type_string);
+
+       if (error.occured) {
+               _ERROR_TO_XMLRPC (&error, env);
+               goto cleanup;
+       }
+
+       //vsc_mgmt_host_add
+
+       result = xmlrpc_build_value (env, "{s:s}", "host_uuid",
+                                    "1b4e28ba-2fa1-11d2-883f-b9a761bde3fb");
+
+cleanup:
+       free (ipv4_string);
+       free (host_type_string);
+       free (host_info.username);
+       free (host_info.password);
+
+       vsc_mgmt_error_cleanup (&error);
+
+       return result;
+}
+
+static struct xmlrpc_method_info3 method_info_list[] = {
+       {
+               .methodName     = "vsc.mgmt.get_version",
+               .methodFunction = &xmlrpc_vsc_mgmt_get_version,
+       }, {
+               .methodName     = "vsc.mgmt.host.add",
+               .methodFunction = &xmlrpc_vsc_mgmt_host_add,
+       }
+};
+
+int
+main (int argc ATTR_UNUSED, const char **argv ATTR_UNUSED)
+{
+       xmlrpc_env env;
+       xmlrpc_registry *registry;
+       xmlrpc_server_abyss_parms server_parms;
+
+       xmlrpc_env_init (&env);
+
+       registry = xmlrpc_registry_new (&env);
+
+       xmlrpc_registry_add_method3 (&env, registry, &method_info_list[0]);
+       xmlrpc_registry_add_method3 (&env, registry, &method_info_list[1]);
+
+       server_parms.config_file_name = NULL;
+       server_parms.registryP = registry;
+       server_parms.port_number = 8080;
+       server_parms.log_file_name = "/tmp/vscmgmtd-xmlrpc.log";
+
+       printf("Running XML-RPC server...\n");
+
+       xmlrpc_server_abyss (&env, &server_parms, XMLRPC_APSIZE (log_file_name));
+
+       printf("...shutdown\n");
+
+       return 0;
+}
diff --git a/include/libvscmgmt/libvscmgmt.h b/include/libvscmgmt/libvscmgmt.h
new file mode 100644 (file)
index 0000000..9aac74b
--- /dev/null
@@ -0,0 +1,372 @@
+/*
+ * libvscmgmt.h: Library for Virtualized Super Computer Management
+ *
+ * Copyright (C) 2009 Matthias Bolte <matthias.bolte@googlemail.com>
+ *
+ * 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 __VSC_MGMT_H__
+#define __VSC_MGMT_H__
+
+#include <stdio.h> /* for FILE */
+#include <sys/time.h> /* for struct timeval */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define VSC_MGMT__VERION__MAJOR 0
+#define VSC_MGMT__VERION__MINOR 1
+#define VSC_MGMT__VERION__PATCH 0
+
+#define VSC_MGMT__UUID__SIZE 16
+#define VSC_MGMT__UUID__STRING_SIZE (36 + 1)
+
+#define VSC_MGMT__IPV4__SIZE 4
+#define VSC_MGMT__IPV4__STRING_SIZE (16 + 1)
+
+enum VscMgmtCode {
+       VSC_MGMT__CODE__UNDEFINED = 0,
+       VSC_MGMT__CODE__INTERNAL_ERROR,
+       VSC_MGMT__CODE__OUT_OF_MEMORY,
+       VSC_MGMT__CODE__XMLRPC_ERROR,
+       VSC_MGMT__CODE__INVALID_ARGUMENT,
+       VSC_MGMT__CODE__INVALID_CALL,
+       VSC_MGMT__CODE__INVALID_UUID_STRING,
+       VSC_MGMT__CODE__INVALID_IPV4_STRING,
+       VSC_MGMT__CODE__INVALID_HOST_TYPE_STRING,
+       VSC_MGMT__CODE__NOT_INITIALIZED,
+       VSC_MGMT__CODE__NOT_IMPLEMENTED_YET,
+};
+
+enum VscMgmtVmState {
+       VSC_MGMT__VM_STATE__UNDEFINED = 0,
+       VSC_MGMT__VM_STATE__RUNNING,
+       VSC_MGMT__VM_STATE__SUSPENDED,
+       VSC_MGMT__VM_STATE__ERROR,
+};
+
+enum VscMgmtHostType {
+       VSC_MGMT__HOST_TYPE__UNDEFINED = 0,
+       VSC_MGMT__HOST_TYPE__XEN,
+       VSC_MGMT__HOST_TYPE__ESX,
+       VSC_MGMT__HOST_TYPE__KVM,
+};
+
+enum VscMgmtUuidType {
+       VSC_MGMT__UUID_TYPE__UNDEFINED = 0,
+       VSC_MGMT__UUID_TYPE__INVALID,
+       VSC_MGMT__UUID_TYPE__VM,
+       VSC_MGMT__UUID_TYPE__HOST,
+       VSC_MGMT__UUID_TYPE__SUSPENSION,
+       VSC_MGMT__UUID_TYPE__CHECKPOINT,
+};
+
+struct VscMgmtError {
+       struct VscMgmtError *next;
+       int occured;
+       enum VscMgmtCode code;
+       char *message;
+       const char *file;
+       int line;
+       const char *function;
+       struct timeval timestamp;
+};
+
+struct VscMgmtUuid {
+       struct VscMgmtUuid *next;
+       unsigned char bytes[VSC_MGMT__UUID__SIZE];
+};
+
+struct VscMgmtIpv4 {
+       unsigned char bytes[VSC_MGMT__IPV4__SIZE];
+};
+
+struct VscMgmtVmResourceConfig {
+       int dummy;
+};
+
+struct VscMgmtVmNetworkConfig {
+       struct VscMgmtIpv4 subnet;
+       struct VscMgmtIpv4 subnetmask;
+};
+
+struct VscMgmtSuspensionInfo {
+       int dummy;
+};
+
+struct VscMgmtCheckpointInfo {
+       int dummy;
+};
+
+struct VscMgmtHostInfo {
+       struct VscMgmtIpv4 ipv4;
+       enum VscMgmtHostType host_type;
+       char *username;
+       char *password;
+};
+
+/*
+ * Error
+ */
+
+void
+vsc_mgmt_error_init (struct VscMgmtError *error);
+
+void
+vsc_mgmt_error_cleanup (struct VscMgmtError *error);
+
+/**
+ * Returns the string representaion of the given error code.
+ *
+ * The string must not be freed by the caller.
+ */
+const char *
+vsc_mgmt_error_string (enum VscMgmtCode code);
+
+void
+vsc_mgmt_error_fprint (struct VscMgmtError *error, FILE* stream);
+
+/*
+ * Memory
+ */
+
+void
+vsc_mgmt_free (void *memory);
+
+/*
+ * UUID
+ */
+
+/**
+ * Appends a copy of the given UUID to the linked list.
+ *
+ * Always returns the address of the first UUID item in the list, so that this
+ * function can be as an initialization function as well as an append function.
+ */
+struct VscMgmtUuid * /* uuid_list */
+vsc_mgmt_uuid_list_append (struct VscMgmtError *error,
+                           struct VscMgmtUuid *uuid_list,
+                           const struct VscMgmtUuid *uuid);
+
+/**
+ * Recursively frees the given linked UUID list.
+ */
+void
+vsc_mgmt_uuid_list_free (struct VscMgmtUuid *uuid_list);
+
+/**
+ * Parses a UUID from its string representation.
+ */
+void
+vsc_mgmt_uuid_parse (struct VscMgmtError *error, const char *uuid_string,
+                     struct VscMgmtUuid *uuid);
+
+/**
+ * Formats a UUID to its string representation.
+ */
+void
+vsc_mgmt_uuid_format (const struct VscMgmtUuid *uuid, char *uuid_string);
+
+/*
+ * IPv4
+ */
+
+/**
+ * Parses an IPv4 from its string representation.
+ */
+void
+vsc_mgmt_ipv4_parse (struct VscMgmtError *error, const char *ipv4_string,
+                     struct VscMgmtIpv4 *ipv4);
+
+/**
+ * Formats an IPv4 to its string representation.
+ */
+void
+vsc_mgmt_ipv4_format (const struct VscMgmtIpv4 *ipv4, char *ipv4_string);
+
+/*
+ * Global
+ */
+
+/*
+ * FIXME: Maybe remove the url argument and pass the url per envvar to the
+ *        proxy-lib. This way the API would the identical in use for both cases.
+ */
+void
+vsc_mgmt_global_init (struct VscMgmtError *error, const char *url);
+
+void
+vsc_mgmt_global_cleanup (void);
+
+void
+vsc_mgmt_global_checkpoint (struct VscMgmtError *error, const char *path);
+
+void
+vsc_mgmt_global_restore (struct VscMgmtError *error, const char *path);
+
+/*
+ * Virtual Machine
+ */
+
+struct VscMgmtUuid * /* vm_uuid_list */
+vsc_mgmt_vm_start (struct VscMgmtError *error, const char* image_path,
+                   const struct VscMgmtUuid *host_uuid_list,
+                   const struct VscMgmtVmResourceConfig *vm_resource_config,
+                   const struct VscMgmtVmNetworkConfig *vm_network_config);
+
+void
+vsc_mgmt_vm_stop (struct VscMgmtError *error, const struct VscMgmtUuid *vm_uuid);
+
+void
+vsc_mgmt_vm_reboot (struct VscMgmtError *error, const struct VscMgmtUuid *vm_uuid);
+
+void
+vsc_mgmt_vm_migrate (struct VscMgmtError *error, const struct VscMgmtUuid *vm_uuid,
+                     const struct VscMgmtUuid *host_uuid);
+
+enum VscMgmtVmState /* vm_state */
+vsc_mgmt_vm_get_state (struct VscMgmtError *error, const struct VscMgmtUuid *vm_uuid);
+
+void
+vsc_mgmt_vm_get_host (struct VscMgmtError *error, const struct VscMgmtUuid *vm_uuid,
+                      struct VscMgmtUuid *host_uuid);
+
+void
+vsc_mgmt_vm_set_resource_config (struct VscMgmtError *error,
+                                 const struct VscMgmtUuid *vm_uuid,
+                                 const struct VscMgmtVmResourceConfig *vm_resource_config);
+
+void
+vsc_mgmt_vm_get_resource_config (struct VscMgmtError *error,
+                                 const struct VscMgmtUuid *vm_uuid,
+                                 struct VscMgmtVmResourceConfig *vm_resource_config);
+
+void
+vsc_mgmt_vm_get_network_config (struct VscMgmtError *error,
+                                const struct VscMgmtUuid *vm_uuid,
+                                struct VscMgmtVmNetworkConfig *vm_network_config);
+
+/*
+ * Suspension
+ */
+
+void
+vsc_mgmt_suspension_create (struct VscMgmtError *error,
+                            const struct VscMgmtUuid *vm_uuid_list,
+                            struct VscMgmtUuid *suspension_uuid);
+
+void
+vsc_mgmt_suspension_resume (struct VscMgmtError *error,
+                            const struct VscMgmtUuid *suspension_uuid);
+
+void
+vsc_mgmt_suspension_get_info (struct VscMgmtError *error,
+                              const struct VscMgmtUuid *suspension_uuid,
+                              struct VscMgmtSuspensionInfo *suspension_info);
+
+/*
+ * Checkpoint
+ */
+
+void
+vsc_mgmt_checkpoint_create (struct VscMgmtError *error,
+                            const struct VscMgmtUuid *vm_uuid_list,
+                            struct VscMgmtUuid *checkpoint_uuid);
+
+void
+vsc_mgmt_checkpoint_delete (struct VscMgmtError *error,
+                            const struct VscMgmtUuid *checkpoint_uuid);
+
+struct VscMgmtUuid * /* vm_uuid_list */
+vsc_mgmt_checkpoint_restore (struct VscMgmtError *error,
+                             const struct VscMgmtUuid *checkpoint_uuid);
+
+void
+vsc_mgmt_checkpoint_get_info (struct VscMgmtError *error,
+                              const struct VscMgmtUuid *checkpoint_uuid,
+                              struct VscMgmtCheckpointInfo *checkpoint_info);
+
+/*
+ * Host
+ */
+
+void
+vsc_mgmt_host_add (struct VscMgmtError *error,
+                   const struct VscMgmtHostInfo *host_info,
+                   struct VscMgmtUuid *host_uuid);
+
+void
+vsc_mgmt_host_remove (struct VscMgmtError *error,
+                      const struct VscMgmtUuid *host_uuid);
+
+struct VscMgmtUuid * /* vm_uuid_list */
+vsc_mgmt_host_get_vm_list (struct VscMgmtError *error,
+                           const struct VscMgmtUuid *host_uuid);
+
+void
+vsc_mgmt_host_get_info (struct VscMgmtError *error,
+                        const struct VscMgmtUuid *host_uuid,
+                        struct VscMgmtHostInfo *host_info);
+
+/*
+ * Host Type
+ */
+
+/**
+ * Parses a host type from its string representation and returns it.
+ */
+enum VscMgmtHostType
+vsc_mgmt_host_type_parse (struct VscMgmtError *error,
+                          const char *host_type_string);
+
+/**
+ * Returns the string representaion of the given host type.
+ *
+ * The string must not be freed by the caller.
+ */
+const char *
+vsc_mgmt_host_type_string (enum VscMgmtHostType host_type);
+
+/*
+ * Misc
+ */
+
+struct VscMgmtUuid * /* host_uuid_list */
+vsc_mgmt_get_host_list (struct VscMgmtError *error);
+
+struct VscMgmtUuid * /* checkpoint_uuid_list */
+vsc_mgmt_get_checkpoint_list (struct VscMgmtError *error);
+
+enum VscMgmtUuidType /* uuid_type */
+vsc_mgmt_get_type (struct VscMgmtError *error, const struct VscMgmtUuid *uuid);
+
+void
+vsc_mgmt_get_ipv4 (struct VscMgmtError *error, const struct VscMgmtUuid *uuid,
+                   struct VscMgmtIpv4 *ipv4);
+
+void
+vsc_mgmt_get_uuid (struct VscMgmtError *error, const struct VscMgmtIpv4 *ipv4,
+                   struct VscMgmtUuid *uuid);
+
+void
+vsc_mgmt_get_version (int *major, int *minor, int *patch);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __VSC_MGMT_H__ */
diff --git a/lib/Makefile b/lib/Makefile
new file mode 100644 (file)
index 0000000..d198258
--- /dev/null
@@ -0,0 +1,47 @@
+#!/usr/bin/make
+#
+# Makefile to build the Library for Virtualized Super Computer Management
+#
+# Copyright (C) 2009 Matthias Bolte <matthias.bolte@googlemail.com>
+#
+
+include ../config.mk
+
+CFLAGS  += -fPIC
+OBJS     = global.o host.o
+LIB      = libvscmgmt.so
+
+#
+# Fancy gcc options
+#
+
+# Symbols
+#LDFLAGS += -Wl,--version-script=public.syms
+# -version-info 6:1:6
+
+LDFLAGS += -L ../util -lvscmgmt-util
+
+# libvirt
+CFLAGS  += $(shell pkg-config libvirt --cflags)
+LDFLAGS += $(shell pkg-config libvirt --libs)
+
+#
+# Rules
+#
+
+.PHONY: all clean install
+
+all: $(LIB)
+
+clean:
+       rm -rf $(LIB) $(OBJS)
+
+install:
+       mkdir -p $(PREFIX)
+       install -c -m 644 $(LIB) $(PREFIX)/lib/$(LIB)
+
+$(LIB): $(OBJS)
+       $(CC) -shared -o $(LIB) $(OBJS) $(LDFLAGS)
+
+%.o: %.c
+       $(CC) $(CFLAGS) -c $<
diff --git a/lib/global.c b/lib/global.c
new file mode 100644 (file)
index 0000000..9c73b52
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ * global.c: Library for Virtualized Super Computer Management
+ *
+ * Copyright (C) 2009 Matthias Bolte <matthias.bolte@googlemail.com>
+ *
+ * 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
+ */
+
+#include "../util/internal.h"
+
+/*
+ * Global
+ */
+
+void
+vsc_mgmt_global_init (struct VscMgmtError *error, const char *url)
+{
+       VSC_MGMT__ASSERT (error != NULL);
+       VSC_MGMT__ASSERT (! error->occured);
+
+       if (url != NULL) {
+               VSC_MGMT__ERROR0 (error, VSC_MGMT__CODE__INVALID_ARGUMENT);
+               return;
+       }
+}
+
+void
+vsc_mgmt_global_cleanup (void)
+{
+}
+
+/*
+ * Misc
+ */
+
+void
+vsc_mgmt_get_version (int *major, int *minor, int *patch)
+{
+       if (major != NULL) {
+               *major = VSC_MGMT__VERION__MAJOR;
+       }
+
+       if (minor != NULL) {
+               *minor = VSC_MGMT__VERION__MINOR;
+       }
+
+       if (patch != NULL) {
+               *patch = VSC_MGMT__VERION__PATCH;
+       }
+}
diff --git a/lib/host.c b/lib/host.c
new file mode 100644 (file)
index 0000000..8904144
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+ * host.c: Library for Virtualized Super Computer Management
+ *
+ * Copyright (C) 2009 Matthias Bolte <matthias.bolte@googlemail.com>
+ *
+ * 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
+ */
+
+#include "../util/internal.h"
+
+/*
+ * Host
+ */
+
+
+
diff --git a/proxy/Makefile b/proxy/Makefile
new file mode 100644 (file)
index 0000000..cd86587
--- /dev/null
@@ -0,0 +1,41 @@
+#!/usr/bin/make
+#
+# Makefile to build the Proxy for Virtualized Super Computer Management
+#
+# Copyright (C) 2009 Matthias Bolte <matthias.bolte@googlemail.com>
+#
+
+include ../config.mk
+
+CFLAGS  += -fPIC
+OBJS     = proxy.o
+PROXY    = libvscmgmt-proxy.so
+
+#
+# Fancy gcc options
+#
+
+# libxmlrpc-c
+CFLAGS  += $(shell xmlrpc-c-config client --cflags)
+LDFLAGS += $(shell xmlrpc-c-config client --libs)
+
+#
+# Rules
+#
+
+.PHONY: all clean install
+
+all: $(PROXY)
+
+clean:
+       rm -rf $(PROXY) $(OBJS)
+
+install:
+       mkdir -p $(PREFIX)
+       install -c -m 644 $(PROXY) $(PREFIX)/lib/$(PROXY)
+
+$(PROXY): $(OBJS)
+       $(CC) -shared -o $(PROXY) $(OBJS) $(LDFLAGS)
+
+%.o: %.c
+       $(CC) $(CFLAGS) -c $<
diff --git a/proxy/proxy.c b/proxy/proxy.c
new file mode 100644 (file)
index 0000000..586f167
--- /dev/null
@@ -0,0 +1,170 @@
+/*
+ * proxy.c: Proxy for Virtualized Super Computer Management
+ *
+ * Copyright (C) 2009 Matthias Bolte <matthias.bolte@googlemail.com>
+ *
+ * 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
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#include <xmlrpc-c/base.h>
+#include <xmlrpc-c/client.h>
+
+#include "../util/internal.h"
+
+
+/*
+ * Error
+ */
+
+static void
+_error_from_xmlrpc (struct VscMgmtError *error, const xmlrpc_env *env,
+                    const char *file, const char *function, int line)
+{
+       vsc_mgmt_error_report (error, VSC_MGMT__CODE__XMLRPC_ERROR, file, line,
+                              function, "%s (%d)", env->fault_string,
+                              env->fault_code);
+}
+
+#define _ERROR_FROM_XMLRPC(error, env) \
+       _error_from_xmlrpc (error, env, __FILE__, __FUNCTION__, __LINE__)
+
+/*
+ * Global
+ */
+
+static char *_global_url = NULL;
+
+void
+vsc_mgmt_global_init (struct VscMgmtError *error, const char *url)
+{
+       xmlrpc_env env;
+       char version[16];
+
+       VSC_MGMT__ASSERT (error != NULL);
+       VSC_MGMT__ASSERT (! error->occured);
+
+       if (url == NULL) {
+               VSC_MGMT__ERROR0 (error, VSC_MGMT__CODE__INVALID_ARGUMENT);
+               return;
+       }
+
+       if (_global_url != NULL) {
+               VSC_MGMT__ERROR0 (error, VSC_MGMT__CODE__INVALID_CALL);
+               return;
+       }
+
+       _global_url = vsc_mgmt_strdup (error, url);
+
+       if (error->occured) {
+               return;
+       }
+
+       xmlrpc_env_init (&env);
+
+       snprintf (version, sizeof (version), "%u.%u.%u",
+                 VSC_MGMT__VERION__MAJOR, VSC_MGMT__VERION__MINOR,
+                 VSC_MGMT__VERION__PATCH);
+
+       xmlrpc_client_init2 (&env, XMLRPC_CLIENT_NO_FLAGS, "libvscmgmt-proxy",
+                            version, NULL, 0);
+
+       if (env.fault_occurred) {
+               _ERROR_FROM_XMLRPC (error, &env);
+       }
+
+       xmlrpc_env_clean (&env);
+}
+
+void
+vsc_mgmt_global_cleanup (void)
+{
+       if (_global_url == NULL) {
+               return;
+       }
+
+       free (_global_url);
+       _global_url = NULL;
+
+       xmlrpc_client_cleanup();
+}
+
+/*
+ * Host
+ */
+
+void
+vsc_mgmt_host_add (struct VscMgmtError *error,
+                   const struct VscMgmtHostInfo *host_info,
+                   struct VscMgmtUuid *host_uuid)
+{
+       xmlrpc_env env;
+       char ipv4_string[VSC_MGMT__IPV4__STRING_SIZE] = "";
+       const char *host_type_string = NULL;
+       xmlrpc_value *result = NULL;
+       char *host_uuid_string = NULL;
+
+       VSC_MGMT__ASSERT (error != NULL);
+       VSC_MGMT__ASSERT (! error->occured);
+
+       if (_global_url == NULL) {
+               VSC_MGMT__ERROR0 (error, VSC_MGMT__CODE__NOT_INITIALIZED);
+               return;
+       }
+
+       xmlrpc_env_init (&env);
+
+       vsc_mgmt_ipv4_format (&host_info->ipv4, ipv4_string);
+
+       host_type_string = vsc_mgmt_host_type_string (host_info->host_type);
+
+       result = xmlrpc_client_call (&env, _global_url, "vsc.mgmt.host.add",
+                                    "({s:{s:s,s:s,s:s,s:s}})", "host_info",
+                                    "ipv4", ipv4_string,
+                                    "host_type", host_type_string,
+                                    "username", host_info->username,
+                                    "password", host_info->password);
+
+       if (env.fault_occurred) {
+               _ERROR_FROM_XMLRPC (error, &env);
+               goto cleanup;
+       }
+
+       xmlrpc_decompose_value (&env, result, "{s:s,*}", "host_uuid",
+                               &host_uuid_string);
+
+       if (env.fault_occurred) {
+               _ERROR_FROM_XMLRPC (error, &env);
+               goto cleanup;
+       }
+
+       vsc_mgmt_uuid_parse (error, host_uuid_string, host_uuid);
+
+       if (error->occured) {
+               VSC_MGMT__APPEND_ERROR0 (error, VSC_MGMT__CODE__INTERNAL_ERROR);
+               goto cleanup;
+       }
+
+cleanup:
+       if (result != NULL) {
+               xmlrpc_DECREF (result);
+       }
+
+       free (host_uuid_string);
+
+       xmlrpc_env_clean (&env);
+}
diff --git a/tests/Makefile b/tests/Makefile
new file mode 100644 (file)
index 0000000..a769220
--- /dev/null
@@ -0,0 +1,43 @@
+#!/usr/bin/make
+#
+# Makefile to build the Tests for Virtualized Super Computer Management
+#
+# Copyright (C) 2009 Matthias Bolte <matthias.bolte@googlemail.com>
+#
+
+include ../config.mk
+
+TESTS    = ipv4.test uuid.test
+
+#
+# Fancy gcc options
+#
+
+# check
+CFLAGS  += $(shell pkg-config check --cflags)
+LDFLAGS += $(shell pkg-config check --libs)
+
+# libvscmgmt-util
+LDFLAGS += -L ../util -lvscmgmt-util
+
+#
+# Rules
+#
+
+.PHONY: all clean install check
+
+all: $(TESTS)
+
+clean:
+       rm -rf $(TESTS) *.o
+
+check: all
+       @echo $(TESTS) | sed 's,^,./,g;s, ,\; ./,g' | sh
+
+install:
+
+%.o: %.c
+       $(CC) $(CFLAGS) -c $<
+
+%.test: %.o
+       $(CC) -o $@ $< $(LDFLAGS)
diff --git a/tests/ipv4.c b/tests/ipv4.c
new file mode 100644 (file)
index 0000000..8f3f4c6
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ * ipv4.c: Tests for Virtualized Super Computer Management
+ *
+ * Copyright (C) 2009 Matthias Bolte <matthias.bolte@googlemail.com>
+ *
+ * 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
+ */
+
+#include <check.h>
+
+#include "../util/internal.h"
+
+START_TEST (test_parse)
+{
+       struct VscMgmtError error;
+       struct VscMgmtIpv4 ipv4;
+
+       vsc_mgmt_error_init (&error);
+
+       vsc_mgmt_ipv4_parse (&error, "131.234.92.31", &ipv4);
+       fail_if (error.occured);
+
+       vsc_mgmt_error_cleanup (&error);
+}
+END_TEST
+
+static Suite *
+ipv4_suite (void)
+{
+       Suite *suite = suite_create ("IPv4");
+       TCase *tcase = tcase_create ("general");
+
+       suite_add_tcase (suite, tcase);
+       tcase_add_test (tcase, test_parse);
+
+       return suite;
+}
+
+int
+main (void)
+{
+       int failed;
+       SRunner *srunner = srunner_create (ipv4_suite());
+
+       srunner_run_all (srunner, CK_NORMAL);
+       failed = srunner_ntests_failed (srunner);
+       srunner_free (srunner);
+
+       return failed;
+}
diff --git a/tests/uuid.c b/tests/uuid.c
new file mode 100644 (file)
index 0000000..116c5e6
--- /dev/null
@@ -0,0 +1,76 @@
+/*
+ * uuid.c: Tests for Virtualized Super Computer Management
+ *
+ * Copyright (C) 2009 Matthias Bolte <matthias.bolte@googlemail.com>
+ *
+ * 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
+ */
+
+#include <check.h>
+
+#include "../util/internal.h"
+
+START_TEST (test_parse)
+{
+       struct VscMgmtError error;
+       struct VscMgmtUuid uuid;
+
+       vsc_mgmt_error_init (&error);
+
+       vsc_mgmt_uuid_parse (&error, "131.234.92.31", &uuid);
+       fail_unless (error.occured);
+
+       vsc_mgmt_error_cleanup (&error);
+
+       vsc_mgmt_error_init (&error);
+
+       vsc_mgmt_uuid_parse (&error, "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX", &uuid);
+       fail_unless (error.occured);
+
+       vsc_mgmt_error_cleanup (&error);
+
+       vsc_mgmt_error_init (&error);
+
+       vsc_mgmt_uuid_parse (&error, "1b4e28ba-2fa1-11d2-883f-b9a761bde3fb", &uuid);
+       fail_if (error.occured);
+
+       vsc_mgmt_error_cleanup (&error);
+}
+END_TEST
+
+static Suite *
+uuid_suite (void)
+{
+       Suite *suite = suite_create ("UUID");
+       TCase *tcase = tcase_create ("general");
+
+       suite_add_tcase (suite, tcase);
+       tcase_add_test (tcase, test_parse);
+
+       return suite;
+}
+
+int
+main (void)
+{
+       int failed;
+       SRunner *srunner = srunner_create (uuid_suite());
+
+       srunner_run_all (srunner, CK_NORMAL);
+       failed = srunner_ntests_failed (srunner);
+       srunner_free (srunner);
+
+       return failed;
+}
diff --git a/util/Makefile b/util/Makefile
new file mode 100644 (file)
index 0000000..5fe7fa9
--- /dev/null
@@ -0,0 +1,41 @@
+#!/usr/bin/make
+#
+# Makefile to build the Utilities for Virtualized Super Computer Management
+#
+# Copyright (C) 2009 Matthias Bolte <matthias.bolte@googlemail.com>
+#
+
+include ../config.mk
+
+CFLAGS  += -fPIC
+OBJS     = assert.o error.o host_type.o ipv4.o memory.o string.o uuid.o
+UTIL     = libvscmgmt-util.so
+
+#
+# Fancy gcc options
+#
+
+# libuuid
+CFLAGS  += $(shell pkg-config uuid --cflags)
+LDFLAGS += $(shell pkg-config uuid --libs)
+
+#
+# Rules
+#
+
+.PHONY: all clean install
+
+all: $(UTIL)
+
+clean:
+       rm -rf $(UTIL) $(OBJS)
+
+install:
+       mkdir -p $(PREFIX)
+       install -c -m 644 $(UTIL) $(PREFIX)/lib/$(UTIL)
+
+$(UTIL): $(OBJS)
+       $(CC) -shared -o $(UTIL) $(OBJS) $(LDFLAGS)
+
+%.o: %.c
+       $(CC) $(CFLAGS) -c $<
diff --git a/util/assert.c b/util/assert.c
new file mode 100644 (file)
index 0000000..fba48ea
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ * assert.c: Utilities for Virtualized Super Computer Management
+ *
+ * Copyright (C) 2009 Matthias Bolte <matthias.bolte@googlemail.com>
+ *
+ * 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
+ */
+
+#include "internal.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+
+/*
+ * Assert (Internal)
+ */
+
+void
+vsc_mgmt_assert_failed (const char *file, int line, const char *function,
+                        const char *condition)
+{
+       fprintf (stderr, "%s:%d %s : assertion '%s' failed\n",
+                file, line, function, condition);
+
+       abort();
+}
diff --git a/util/error.c b/util/error.c
new file mode 100644 (file)
index 0000000..7dfcba5
--- /dev/null
@@ -0,0 +1,282 @@
+/*
+ * error.c: Utilities for Virtualized Super Computer Management
+ *
+ * Copyright (C) 2009 Matthias Bolte <matthias.bolte@googlemail.com>
+ *
+ * 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
+ */
+
+#include "internal.h"
+
+#include <stdlib.h>
+#include <stdarg.h>
+#include <time.h>
+#include <string.h>
+
+#define ERROR__MESSAGE_SIZE 4096
+
+static const char *_error_default_message = "Could not allocate memory for error message";
+
+static struct VscMgmtError _error_default = {
+       .next = NULL,
+       .occured = 1,
+       .code = VSC_MGMT__CODE__OUT_OF_MEMORY,
+       .message = NULL,
+       .file = "none",
+       .line = -1,
+       .function = "none",
+};
+
+static struct VscMgmtError *
+_error_get_last (struct VscMgmtError *error)
+{
+       struct VscMgmtError *error_next;
+
+       VSC_MGMT__ASSERT (error != NULL);
+
+       error_next = error;
+
+       while (error_next->next != NULL) {
+               error_next = error_next->next;
+       }
+
+       return error_next;
+}
+
+static void
+_error_report_v (struct VscMgmtError *error, enum VscMgmtCode code,
+                 const char *file, int line, const char *function,
+                 const char *message, va_list args)
+{
+       VSC_MGMT__ASSERT (error != NULL);
+       VSC_MGMT__ASSERT (! error->occured);
+       VSC_MGMT__ASSERT (code != VSC_MGMT__CODE__UNDEFINED);
+
+       error->occured = 1;
+       error->code = code;
+       error->file = file;
+       error->line = line;
+       error->function = function;
+
+       if (message == NULL) {
+               error->message = NULL;
+       } else {
+               if (error->message == NULL) {
+                       error->message = malloc (ERROR__MESSAGE_SIZE);
+               } else {
+                       error->message = realloc (error->message, ERROR__MESSAGE_SIZE);
+               }
+
+               if (error->message == NULL) {
+                       error->message = (char *) _error_default_message;
+               } else {
+                       vsnprintf (error->message, ERROR__MESSAGE_SIZE, message, args);
+               }
+       }
+
+       gettimeofday (&error->timestamp, NULL);
+}
+
+/*
+ * Error
+ */
+
+const char *
+vsc_mgmt_error_string (enum VscMgmtCode code)
+{
+       switch (code) {
+       case VSC_MGMT__CODE__INTERNAL_ERROR:
+               return "Internal error";
+
+       case VSC_MGMT__CODE__OUT_OF_MEMORY:
+               return "Out of memory";
+
+       case VSC_MGMT__CODE__XMLRPC_ERROR:
+               return "XML-RPC error";
+
+       case VSC_MGMT__CODE__INVALID_ARGUMENT:
+               return "Invalid argument";
+
+       case VSC_MGMT__CODE__INVALID_CALL:
+               return "Invalid call";
+
+       case VSC_MGMT__CODE__INVALID_UUID_STRING:
+               return "Invalid UUID string";
+
+       case VSC_MGMT__CODE__INVALID_IPV4_STRING:
+               return "Invalid IPv4 string";
+
+       case VSC_MGMT__CODE__INVALID_HOST_TYPE_STRING:
+               return "Invalid host type string";
+
+       case VSC_MGMT__CODE__NOT_INITIALIZED:
+               return "Not initialized";
+
+       case VSC_MGMT__CODE__NOT_IMPLEMENTED_YET:
+               return "Not implemented yet";
+
+       default:
+               return "Undefined";
+       }
+}
+
+void
+vsc_mgmt_error_fprint (struct VscMgmtError *error, FILE* stream)
+{
+       struct tm time_info;
+       struct VscMgmtError *error_next = NULL;
+
+       VSC_MGMT__ASSERT (error != NULL);
+       VSC_MGMT__ASSERT (error->occured);
+       VSC_MGMT__ASSERT (stream != NULL);
+
+       if (! error->occured) {
+               return;
+       }
+
+       localtime_r (&error->timestamp.tv_sec, &time_info);
+
+       fprintf (stream, "%02d:%02d:%02d.%03d %s:%d %s : error [%s]",
+                time_info.tm_hour, time_info.tm_min, time_info.tm_sec,
+                (int) error->timestamp.tv_usec / 1000, error->file,
+                error->line, error->function,
+                vsc_mgmt_error_string (error->code));
+
+       if (error->message != NULL) {
+               fprintf (stream, " %s\n", error->message);
+       } else {
+               fprintf (stream, "\n");
+       }
+
+       for (error_next = error->next; error_next != NULL;
+            error_next = error_next->next) {
+               fprintf (stream, "             %s:%d %s : error [%s]",
+                        error_next->file, error_next->line, error_next->function,
+                        vsc_mgmt_error_string (error_next->code));
+
+               if (error_next->message != NULL) {
+                       fprintf (stream, " %s\n", error_next->message);
+               } else {
+                       fprintf (stream, "\n");
+               }
+       }
+}
+
+void
+vsc_mgmt_error_init (struct VscMgmtError *error)
+{
+       VSC_MGMT__ASSERT (error != NULL);
+
+       error->next = NULL;
+       error->occured = 0;
+       error->code = VSC_MGMT__CODE__UNDEFINED;
+       error->file = NULL;
+       error->line = -1;
+       error->function = NULL;
+       error->message = NULL;
+
+       memset (&error->timestamp, 0, sizeof (struct timeval));
+}
+
+void
+vsc_mgmt_error_cleanup (struct VscMgmtError *error)
+{
+       struct VscMgmtError *current;
+       struct VscMgmtError *next;
+
+       VSC_MGMT__ASSERT (error != NULL);
+
+       if (error->message != _error_default_message) {
+               free (error->message);
+       }
+
+       error->message = NULL;
+
+       /*
+        * Free the linked error list messages if they are allocated (not the
+        * default error message) and free the error structs too, if they are
+        * allocated (not the default error). But do not free the first element
+        * of the linked list because we do not "own" its memory.
+        */
+       current = error->next;
+
+       while (current != NULL) {
+               next = current->next;
+
+               if (current->message != _error_default_message) {
+                       free (current->message);
+               }
+
+               current->message = NULL;
+
+               if (current != &_error_default) {
+                       free (current);
+               }
+
+               current = next;
+       }
+}
+
+/*
+ * Error (Internal)
+ */
+
+void
+vsc_mgmt_error_report (struct VscMgmtError *error, enum VscMgmtCode code,
+                       const char *file, int line, const char *function,
+                       const char *message, ...)
+{
+       va_list args;
+
+       va_start (args, message);
+       _error_report_v (error, code, file, line, function, message, args);
+       va_end (args);
+}
+
+void
+vsc_mgmt_error_append_report (struct VscMgmtError *error, enum VscMgmtCode code,
+                              const char *file, int line, const char *function,
+                              const char *message, ...)
+{
+       va_list args;
+       struct VscMgmtError *error_last;
+       struct VscMgmtError *error_next;
+
+       VSC_MGMT__ASSERT (error != NULL);
+       VSC_MGMT__ASSERT (error->occured);
+       VSC_MGMT__ASSERT (code != VSC_MGMT__CODE__UNDEFINED);
+
+       error_last = _error_get_last (error);
+
+       /*
+        * Do not append to the default error, because if it is appended we are
+        * already in an out-of-memory situation.
+        */
+       if (error_last == &_error_default) {
+               return;
+       }
+
+       error_next = calloc (1, sizeof (struct VscMgmtError));
+
+       if (error_next == NULL) {
+               error_next = &_error_default;
+       } else {
+               va_start (args, message);
+               _error_report_v (error_next, code, file, line, function, message, args);
+               va_end (args);
+       }
+
+       error_last->next = error_next;
+}
diff --git a/util/host_type.c b/util/host_type.c
new file mode 100644 (file)
index 0000000..9c41fc3
--- /dev/null
@@ -0,0 +1,74 @@
+/*
+ * host_type.c: Library for Virtualized Super Computer Management
+ *
+ * Copyright (C) 2009 Matthias Bolte <matthias.bolte@googlemail.com>
+ *
+ * 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
+ */
+
+#include "../util/internal.h"
+
+#include <strings.h>
+
+/*
+ * Host Type
+ */
+
+/**
+ * Parses a host type from its string representation and returns it.
+ */
+enum VscMgmtHostType
+vsc_mgmt_host_type_parse (struct VscMgmtError *error,
+                          const char *host_type_string)
+{
+       VSC_MGMT__ASSERT (error != NULL);
+       VSC_MGMT__ASSERT (! error->occured);
+
+       if (strcasecmp (host_type_string, "Xen") == 0) {
+               return VSC_MGMT__HOST_TYPE__XEN;
+       } else if (strcasecmp (host_type_string, "ESX") == 0) {
+               return VSC_MGMT__HOST_TYPE__ESX;
+       } else if (strcasecmp (host_type_string, "KVM") == 0) {
+               return VSC_MGMT__HOST_TYPE__KVM;
+       }
+
+       VSC_MGMT__ERROR2 (error, VSC_MGMT__CODE__INVALID_HOST_TYPE_STRING, "'%s'",
+                         host_type_string);
+
+       return VSC_MGMT__HOST_TYPE__UNDEFINED;
+}
+
+/**
+ * Returns the string representaion of the given host type.
+ *
+ * The string must not be freed by the caller.
+ */
+const char *
+vsc_mgmt_host_type_string (enum VscMgmtHostType host_type)
+{
+       switch (host_type) {
+       case VSC_MGMT__HOST_TYPE__XEN:
+               return "Xen";
+
+       case VSC_MGMT__HOST_TYPE__ESX:
+               return "ESX";
+
+       case VSC_MGMT__HOST_TYPE__KVM:
+               return "KVM";
+
+       default:
+               return "Undefined";
+       }
+}
diff --git a/util/internal.h b/util/internal.h
new file mode 100644 (file)
index 0000000..c3e6c1d
--- /dev/null
@@ -0,0 +1,98 @@
+/*
+ * internal.h: Utilities for Virtualized Super Computer Management
+ *
+ * Copyright (C) 2009 Matthias Bolte <matthias.bolte@googlemail.com>
+ *
+ * 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 __VSC_MGMT__UTIL__INTERNAL_H__
+#define __VSC_MGMT__UTIL__INTERNAL_H__
+
+#include "../include/libvscmgmt/libvscmgmt.h"
+
+#define ATTR_UNUSED __attribute__((__unused__))
+
+#define ATTR_PRINTF(a, b) __attribute__ ((format (printf, a, b)))
+
+/*
+ * Assert (Internal)
+ */
+
+#ifndef NDEBUG
+#define VSC_MGMT__ASSERT(condition) \
+       do { \
+               if (! (condition)) { \
+                       vsc_mgmt_assert_failed (__FILE__, __LINE__, __FUNCTION__, #condition); \
+               } \
+       } while (0)
+#else
+#define VSC_MGMT__ASSERT(condition) do { } while (0)
+#endif
+
+void
+vsc_mgmt_assert_failed (const char *file, int line, const char *function,
+                        const char *condition);
+
+/*
+ * Error (Internal)
+ */
+
+#define VSC_MGMT__ERROR0(error, code) \
+       vsc_mgmt_error_report (error, code, __FILE__, __LINE__, __FUNCTION__, NULL)
+
+#define VSC_MGMT__ERROR1(error, code, message) \
+       vsc_mgmt_error_report (error, code, __FILE__, __LINE__, __FUNCTION__, message)
+
+#define VSC_MGMT__ERROR2(error, code, message, ...) \
+       vsc_mgmt_error_report (error, code, __FILE__, __LINE__, __FUNCTION__, message, __VA_ARGS__)
+
+void
+vsc_mgmt_error_report (struct VscMgmtError *error, enum VscMgmtCode code,
+                       const char *file, int line, const char *function,
+                       const char *message, ...) ATTR_PRINTF (6, 7);
+
+#define VSC_MGMT__APPEND_ERROR0(error, code) \
+       vsc_mgmt_error_append_report (error, code, __FILE__, __LINE__, __FUNCTION__, NULL)
+
+#define VSC_MGMT__APPEND_ERROR1(error, code, message) \
+       vsc_mgmt_error_append_report (error, code, __FILE__, __LINE__, __FUNCTION__, message)
+
+#define VSC_MGMT__APPEND_ERROR2(error, code, message, ...) \
+       vsc_mgmt_error_append_report (error, code, __FILE__, __LINE__, __FUNCTION__, message, __VA_ARGS__)
+
+void
+vsc_mgmt_error_append_report (struct VscMgmtError *error, enum VscMgmtCode code,
+                              const char *file, int line, const char *function,
+                              const char *message, ...) ATTR_PRINTF (6, 7);
+
+/*
+ * String (Internal)
+ */
+
+char *
+vsc_mgmt_strdup (struct VscMgmtError *error, const char *string);
+
+/**
+ * Stricter version of strtol, returning an int as result.
+ *
+ * If tail is NULL there must be no invalid character in string, otherwise an
+ * error occurs.
+ */
+int
+vsc_mgmt_strtoi (struct VscMgmtError *error, const char *string, char **tail,
+                 int base);
+
+#endif /* __VSC_MGMT__UTIL__INTERNAL_H__ */
diff --git a/util/ipv4.c b/util/ipv4.c
new file mode 100644 (file)
index 0000000..6c3c0d7
--- /dev/null
@@ -0,0 +1,87 @@
+/*
+ * ipv4.c: Utilities for Virtualized Super Computer Management
+ *
+ * Copyright (C) 2009 Matthias Bolte <matthias.bolte@googlemail.com>
+ *
+ * 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
+ */
+
+#include "internal.h"
+
+/*
+ * IPv4
+ */
+
+/**
+ * Parses an IPv4 from its string representation.
+ */
+void
+vsc_mgmt_ipv4_parse (struct VscMgmtError *error, const char *ipv4_string,
+                     struct VscMgmtIpv4 *ipv4)
+{
+       int i;
+       char *tail = (char *) ipv4_string;
+       int number = 0;
+
+       VSC_MGMT__ASSERT (error != NULL);
+       VSC_MGMT__ASSERT (! error->occured);
+
+       for (i = 0; i < 4; i++) {
+               number = vsc_mgmt_strtoi (error, tail, &tail, 10);
+
+               if (error->occured) {
+                       VSC_MGMT__APPEND_ERROR2 (error, VSC_MGMT__CODE__INVALID_IPV4_STRING,
+                                                "'%s'", ipv4_string);
+                       return;
+               }
+
+               if (i < 3) {
+                       if (tail == NULL || *tail != '.') {
+                               VSC_MGMT__ERROR2 (error, VSC_MGMT__CODE__INVALID_IPV4_STRING,
+                                                 "'%s' must consist of 4 elements separated "
+                                                 "by '.'", ipv4_string);
+                               return;
+                       }
+
+                       ++tail;
+               } else {
+                       if (*tail != '\0') {
+                               VSC_MGMT__ERROR2 (error, VSC_MGMT__CODE__INVALID_IPV4_STRING,
+                                                 "'%s' has invalid suffix '%s'", ipv4_string,
+                                                 tail);
+                               return;
+                       }
+               }
+
+               if (number < 0 || number > 255) {
+                       VSC_MGMT__ERROR2 (error, VSC_MGMT__CODE__INVALID_IPV4_STRING,
+                                         "Elements of '%s' must be in [0..255] reange",
+                                         ipv4_string);
+                       return;
+               }
+
+               ipv4->bytes[i] = number;
+       }
+}
+
+/**
+ * Formats an IPv4 to its string representation.
+ */
+void
+vsc_mgmt_ipv4_format (const struct VscMgmtIpv4 *ipv4, char *ipv4_string)
+{
+       snprintf (ipv4_string, VSC_MGMT__IPV4__STRING_SIZE, "%u.%u.%u.%u",
+                 ipv4->bytes[0], ipv4->bytes[1], ipv4->bytes[2], ipv4->bytes[3]);
+}
diff --git a/util/memory.c b/util/memory.c
new file mode 100644 (file)
index 0000000..64e829f
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+ * memory.c: Utilities for Virtualized Super Computer Management
+ *
+ * Copyright (C) 2009 Matthias Bolte <matthias.bolte@googlemail.com>
+ *
+ * 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
+ */
+
+#include "internal.h"
+
+#include <malloc.h>
+
+/*
+ * Memory
+ */
+
+void
+vsc_mgmt_free (void *memory)
+{
+       free (memory);
+}
diff --git a/util/string.c b/util/string.c
new file mode 100644 (file)
index 0000000..57cdd5a
--- /dev/null
@@ -0,0 +1,93 @@
+/*
+ * string.c: Utilities for Virtualized Super Computer Management
+ *
+ * Copyright (C) 2009 Matthias Bolte <matthias.bolte@googlemail.com>
+ *
+ * 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
+ */
+
+#include "internal.h"
+
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+
+/*
+ * String (Internal)
+ */
+
+char *
+vsc_mgmt_strdup (struct VscMgmtError *error, const char *string)
+{
+       char *string_duplicate = NULL;
+
+       VSC_MGMT__ASSERT (error != NULL);
+       VSC_MGMT__ASSERT (! error->occured);
+
+       string_duplicate = strdup (string);
+
+       if (string_duplicate == NULL) {
+               VSC_MGMT__ERROR0 (error, VSC_MGMT__CODE__OUT_OF_MEMORY);
+       }
+
+       return string_duplicate;
+}
+
+/**
+ * Stricter version of strtol, returning an int as result.
+ *
+ * If tail is NULL there must be no invalid character in string, otherwise an
+ * error occurs.
+ */
+int
+vsc_mgmt_strtoi (struct VscMgmtError *error, const char *string, char **tail,
+                 int base)
+{
+       long int value = 0;
+       char *temp = NULL;
+
+       VSC_MGMT__ASSERT (error != NULL);
+       VSC_MGMT__ASSERT (! error->occured);
+
+       errno = 0;
+       value = strtol (string, &temp, base);
+
+       if (errno != 0) {
+               VSC_MGMT__ERROR2 (error, VSC_MGMT__CODE__INVALID_ARGUMENT,
+                                 "Converting '%s' yields errno %s (%d)", string,
+                                 errno == EINVAL ? "EINVAL"
+                                                 : (errno == ERANGE ? "ERANGE"
+                                                                    : "?"), errno);
+       }
+       else if (tail == NULL && *temp != '\0') {
+               VSC_MGMT__ERROR2 (error, VSC_MGMT__CODE__INVALID_ARGUMENT,
+                                 "Expecting '\\0' after the last digit in '%s' "
+                                 "but found '%c'", string, *temp);
+       }
+       else if (temp == string) {
+               VSC_MGMT__ERROR2 (error, VSC_MGMT__CODE__INVALID_ARGUMENT,
+                                 "Nothing of '%s' was converted", string);
+       }
+       else if ((int) value != value) {
+               VSC_MGMT__ERROR2 (error, VSC_MGMT__CODE__INVALID_ARGUMENT,
+                                 "'%s' is not representable as int", string);
+       }
+
+       if (tail != NULL) {
+               *tail = temp;
+       }
+
+       return value;
+}
diff --git a/util/uuid.c b/util/uuid.c
new file mode 100644 (file)
index 0000000..4a54b22
--- /dev/null
@@ -0,0 +1,132 @@
+/*
+ * uuid.c: Utilities for Virtualized Super Computer Management
+ *
+ * Copyright (C) 2009 Matthias Bolte <matthias.bolte@googlemail.com>
+ *
+ * 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
+ */
+
+#include "internal.h"
+
+#include <memory.h>
+#include <malloc.h>
+#include <uuid.h>
+
+static struct VscMgmtUuid *
+_uuid_list_get_last (struct VscMgmtUuid *uuid_list)
+{
+       struct VscMgmtUuid *uuid;
+
+       if (uuid_list == NULL) {
+               return NULL;
+       }
+
+       uuid = uuid_list;
+
+       while (uuid->next != NULL) {
+               uuid = uuid->next;
+       }
+
+       return uuid;
+}
+
+/*
+ * UUID
+ */
+
+/**
+ * Appends a copy of the given UUID to the linked list.
+ *
+ * Always returns the address of the first UUID item in the list, so that this
+ * function can be as an initialization function as well as an append function.
+ */
+struct VscMgmtUuid * /* uuid_list */
+vsc_mgmt_uuid_list_append (struct VscMgmtError *error,
+                           struct VscMgmtUuid *uuid_list,
+                           const struct VscMgmtUuid *uuid)
+{
+       struct VscMgmtUuid *uuid_last = NULL;
+       struct VscMgmtUuid *uuid_duplicate = NULL;
+
+       VSC_MGMT__ASSERT (error != NULL);
+       VSC_MGMT__ASSERT (! error->occured);
+
+       uuid_duplicate = calloc (1, sizeof (struct VscMgmtUuid));
+
+       if (uuid_duplicate == NULL) {
+               VSC_MGMT__ERROR0 (error, VSC_MGMT__CODE__OUT_OF_MEMORY);
+               return NULL;
+       }
+
+       memcpy (uuid_duplicate->bytes, uuid->bytes, VSC_MGMT__UUID__SIZE);
+
+       if (uuid_list != NULL) {
+               uuid_last = _uuid_list_get_last (uuid_list);
+               uuid_last->next = uuid_duplicate;
+
+               return uuid_list;
+       }
+
+       return uuid_duplicate;
+}
+
+/**
+ * Recursively frees the given linked UUID list.
+ */
+void
+vsc_mgmt_uuid_list_free (struct VscMgmtUuid *uuid_list)
+{
+       struct VscMgmtUuid *uuid;
+       struct VscMgmtUuid *uuid_next;
+
+       if (uuid_list == NULL) {
+               return;
+       }
+
+       uuid = uuid_list;
+
+       do {
+               uuid_next = uuid->next;
+
+               free (uuid);
+
+               uuid = uuid_next;
+       } while (uuid != NULL);
+}
+
+/**
+ * Parses a UUID from string representation.
+ */
+void
+vsc_mgmt_uuid_parse (struct VscMgmtError *error, const char *uuid_string,
+                     struct VscMgmtUuid *uuid)
+{
+       VSC_MGMT__ASSERT (error != NULL);
+       VSC_MGMT__ASSERT (! error->occured);
+
+       if (uuid_parse (uuid_string, uuid->bytes) < 0) {
+               VSC_MGMT__ERROR2 (error, VSC_MGMT__CODE__INVALID_UUID_STRING,
+                                 "'%s'", uuid_string);
+       }
+}
+
+/**
+ * Formats a UUID to string representation.
+ */
+void
+vsc_mgmt_uuid_format (const struct VscMgmtUuid *uuid, char *uuid_string)
+{
+       uuid_unparse_lower (uuid->bytes, uuid_string);
+}