[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] [PATCH,RFC]: Introduce libxl_domain_create()



This patch is my initial attempt to re-factor the libxl domain creation
paths to make them more suitable for external users and in particular
the python bindings.

The patch is very rough and dirty at the moment, but that said it works
for creating and restoring hvm domains at least. Migrate is not tested
and I haven't made sure all the error handling and such like is correct.

Any thoughts or suggestions?

Gianni

# HG changeset patch
# Parent 190c37e0eb307858c6cdf1bf5a0a5548babd2b34

diff -r 190c37e0eb30 tools/libxl/Makefile
--- a/tools/libxl/Makefile      Tue Dec 14 18:00:35 2010 +0000
+++ b/tools/libxl/Makefile      Tue Dec 14 18:54:20 2010 +0000
@@ -20,7 +20,7 @@ ifeq ($(CONFIG_Linux),y)
 LIBS += -luuid
 endif
 
-LIBXL_OBJS-y = osdeps.o libxl_paths.o libxl_bootloader.o
+LIBXL_OBJS-y = osdeps.o libxl_paths.o libxl_bootloader.o flexarray.o
 ifeq ($(LIBXL_BLKTAP),y)
 LIBXL_OBJS-y += libxl_blktap2.o
 else
@@ -29,7 +29,7 @@ endif
 LIBXL_OBJS-$(CONFIG_X86) += libxl_cpuid.o
 LIBXL_OBJS-$(CONFIG_IA64) += libxl_nocpuid.o
 
-LIBXL_OBJS = flexarray.o libxl.o libxl_pci.o libxl_dom.o libxl_exec.o 
libxl_xshelp.o libxl_device.o libxl_internal.o libxl_utils.o $(LIBXL_OBJS-y)
+LIBXL_OBJS = libxl.o libxl_create.o libxl_pci.o libxl_dom.o libxl_exec.o 
libxl_xshelp.o libxl_device.o libxl_internal.o libxl_utils.o $(LIBXL_OBJS-y)
 LIBXL_OBJS += _libxl_types.o
 
 AUTOINCS= libxlu_cfg_y.h libxlu_cfg_l.h
diff -r 190c37e0eb30 tools/libxl/libxl.h
--- a/tools/libxl/libxl.h       Tue Dec 14 18:00:35 2010 +0000
+++ b/tools/libxl/libxl.h       Tue Dec 14 18:54:20 2010 +0000
@@ -246,6 +246,37 @@ enum {
 
 #define LIBXL_VERSION 0
 
+enum action_on_shutdown {
+    ACTION_DESTROY,
+
+    ACTION_RESTART,
+    ACTION_RESTART_RENAME,
+
+    ACTION_PRESERVE,
+
+    ACTION_COREDUMP_DESTROY,
+    ACTION_COREDUMP_RESTART,
+};
+
+typedef struct {
+    libxl_domain_create_info c_info;
+    libxl_domain_build_info b_info;
+
+    int num_disks, num_vifs, num_vif2s, num_pcidevs, num_vfbs, num_vkbs;
+
+    libxl_device_disk *disks;
+    libxl_device_nic *vifs;
+    libxl_device_net2 *vif2s;
+    libxl_device_pci *pcidevs;
+    libxl_device_vfb *vfbs;
+    libxl_device_vkb *vkbs;
+
+    enum action_on_shutdown on_poweroff;
+    enum action_on_shutdown on_reboot;
+    enum action_on_shutdown on_watchdog;
+    enum action_on_shutdown on_crash;
+} libxl_domain_config;
+
 /* context functions */
 int libxl_ctx_init(libxl_ctx *ctx, int version, xentoollog_logger*);
 int libxl_ctx_free(libxl_ctx *ctx);
@@ -253,6 +284,11 @@ int libxl_ctx_set_log(libxl_ctx *ctx, xe
 int libxl_ctx_postfork(libxl_ctx *ctx);
 
 /* domain related functions */
+#define LIBXL_CREATE_RESTORE            (1<<0)
+#define LIBXL_CREATE_RUN_BOOTLOADER     (1<<1)
+#define LIBXL_CREATE_CONSOLE_CONNECT    (1<<2)
+int libxl_domain_create(libxl_ctx *ctx, libxl_domain_config *d_config, 
libxl_device_model_info *dm_info,
+                        unsigned int flags, int restore_fd, uint32_t *domid);
 int libxl_domain_make(libxl_ctx *ctx, libxl_domain_create_info *info, uint32_t 
*domid);
 int libxl_domain_build(libxl_ctx *ctx, libxl_domain_build_info *info, uint32_t 
domid, /* out */ libxl_domain_build_state *state);
 int libxl_domain_restore(libxl_ctx *ctx, libxl_domain_build_info *info,
diff -r 190c37e0eb30 tools/libxl/libxl_create.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/libxl/libxl_create.c        Tue Dec 14 18:54:20 2010 +0000
@@ -0,0 +1,206 @@
+/*
+ * Copyright (C) 2010      Citrix Ltd.
+ * Author Vincent Hanquez <vincent.hanquez@xxxxxxxxxxxxx>
+ * Author Stefano Stabellini <stefano.stabellini@xxxxxxxxxxxxx>
+ * Author Gianni Tedesco <gianni.tedesco@xxxxxxxxxx>
+ *
+ * This program 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; version 2.1 only. with the special
+ * exception on linking described in file LICENSE.
+ *
+ * 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 Lesser General Public License for more details.
+ */
+
+#include "libxl_osdeps.h"
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include "libxl.h"
+#include "libxl_utils.h"
+#include "libxl_internal.h"
+#include "flexarray.h"
+
+#define MUST( call ) ({                                                 \
+        int must_rc = (call);                                           \
+        if (must_rc < 0) {                                                  \
+            fprintf(stderr,"xl: fatal error: %s:%d, rc=%d: %s\n",       \
+                    __FILE__,__LINE__, must_rc, #call);                 \
+            exit(-must_rc);                                             \
+        }                                                               \
+    })
+static void init_console_info(libxl_device_console *console, int dev_num, 
libxl_domain_build_state *state)
+{
+    memset(console, 0x00, sizeof(libxl_device_console));
+    console->devid = dev_num;
+    console->consback = LIBXL_CONSBACK_XENCONSOLED;
+    console->output = strdup("pty");
+    if (state)
+        console->build_state = state;
+}
+
+static pid_t autoconnect_console(libxl_ctx *ctx, int domid)
+{
+    pid_t pid;
+
+    pid = fork();
+    if (pid < 0) {
+        perror("unable to fork xenconsole");
+        return ERROR_FAIL;
+    } else if (pid > 0)
+        return pid;
+
+    libxl_ctx_postfork(ctx);
+
+    sleep(1);
+    libxl_primary_console_exec(ctx, domid);
+    /* Do not return. xl continued in child process */
+    fprintf(stderr, "Unable to attach console\n");
+    _exit(1);
+}
+
+int libxl_domain_create(libxl_ctx *ctx, libxl_domain_config *d_config, 
libxl_device_model_info *dm_info,
+                        unsigned int flags, int restore_fd, uint32_t 
*domid_out)
+{
+    libxl_device_model_starting *dm_starting = 0;
+    libxl_domain_build_state state;
+    pid_t child_console_pid = -1;
+    uint32_t domid;
+    int i, ret, status = 0;
+
+    domid = 0;
+
+    ret = libxl_domain_make(ctx, &d_config->c_info, &domid);
+    if (ret) {
+        fprintf(stderr, "cannot make domain: %d\n", ret);
+        ret = ERROR_FAIL;
+        goto error_out;
+    }
+
+    if ((flags & LIBXL_CREATE_CONSOLE_CONNECT) && !d_config->c_info.hvm) {
+        child_console_pid = autoconnect_console(ctx, domid);
+        if (child_console_pid < 0)
+            goto error_out;
+    }
+
+    if ( flags & LIBXL_CREATE_RUN_BOOTLOADER ) {
+        ret = libxl_run_bootloader(ctx, &d_config->b_info, d_config->num_disks 
> 0 ? &d_config->disks[0] : NULL, domid);
+        if (ret) {
+            fprintf(stderr, "failed to run bootloader: %d\n", ret);
+            goto error_out;
+        }
+    }
+
+    if ( flags & LIBXL_CREATE_RESTORE ) {
+        ret = libxl_domain_restore(ctx, &d_config->b_info, domid, restore_fd, 
&state, dm_info);
+    } else {
+        if (dm_info->saved_state) {
+            free(dm_info->saved_state);
+            dm_info->saved_state = NULL;
+        }
+        ret = libxl_domain_build(ctx, &d_config->b_info, domid, &state);
+    }
+
+    if (ret) {
+        fprintf(stderr, "cannot (re-)build domain: %d\n", ret);
+        ret = ERROR_FAIL;
+        goto error_out;
+    }
+
+    for (i = 0; i < d_config->num_disks; i++) {
+        d_config->disks[i].domid = domid;
+        ret = libxl_device_disk_add(ctx, domid, &d_config->disks[i]);
+        if (ret) {
+            fprintf(stderr, "cannot add disk %d to domain: %d\n", i, ret);
+            ret = ERROR_FAIL;
+            goto error_out;
+        }
+    }
+    for (i = 0; i < d_config->num_vifs; i++) {
+        d_config->vifs[i].domid = domid;
+        ret = libxl_device_nic_add(ctx, domid, &d_config->vifs[i]);
+        if (ret) {
+            fprintf(stderr, "cannot add nic %d to domain: %d\n", i, ret);
+            ret = ERROR_FAIL;
+            goto error_out;
+        }
+    }
+    if (!d_config->c_info.hvm) {
+        for (i = 0; i < d_config->num_vif2s; i++) {
+            d_config->vif2s[i].domid = domid;
+            ret = libxl_device_net2_add(ctx, domid, &d_config->vif2s[i]);
+            if (ret) {
+                fprintf(stderr, "cannot add net2 %d to domain: %d\n", i, ret);
+                ret = ERROR_FAIL;
+                goto error_out;
+            }
+        }
+    }
+    if (d_config->c_info.hvm) {
+        libxl_device_console console;
+
+        init_console_info(&console, 0, &state);
+        console.domid = domid;
+        libxl_device_console_add(ctx, domid, &console);
+        libxl_device_console_destroy(&console);
+
+        dm_info->domid = domid;
+        MUST( libxl_create_device_model(ctx, dm_info,
+                                        d_config->disks, d_config->num_disks,
+                                        d_config->vifs, d_config->num_vifs,
+                                        &dm_starting) );
+    } else {
+        libxl_device_console console;
+
+        for (i = 0; i < d_config->num_vfbs; i++) {
+            d_config->vfbs[i].domid = domid;
+            libxl_device_vfb_add(ctx, domid, &d_config->vfbs[i]);
+            d_config->vkbs[i].domid = domid;
+            libxl_device_vkb_add(ctx, domid, &d_config->vkbs[i]);
+        }
+
+        init_console_info(&console, 0, &state);
+        console.domid = domid;
+        if (d_config->num_vfbs)
+             console.consback = LIBXL_CONSBACK_IOEMU;
+        libxl_device_console_add(ctx, domid, &console);
+        libxl_device_console_destroy(&console);
+
+        if (d_config->num_vfbs)
+            libxl_create_xenpv_qemu(ctx, domid, d_config->vfbs, &dm_starting);
+    }
+
+    if (dm_starting)
+        MUST( libxl_confirm_device_model_startup(ctx, dm_starting) );
+
+    for (i = 0; i < d_config->num_pcidevs; i++)
+        libxl_device_pci_add(ctx, domid, &d_config->pcidevs[i]);
+
+    if ((flags & LIBXL_CREATE_CONSOLE_CONNECT) && d_config->c_info.hvm) {
+        child_console_pid = autoconnect_console(ctx, domid);
+        if (child_console_pid < 0)
+            goto error_out;
+    }
+
+    *domid_out = domid;
+    return ret;
+
+error_out:
+    if (domid)
+        libxl_domain_destroy(ctx, domid, 0);
+
+    libxl_device_model_info_destroy(dm_info);
+    //free_domain_config(&d_config);
+
+waitpid_out:
+    if (child_console_pid > 0 &&
+            waitpid(child_console_pid, &status, 0) < 0 && errno == EINTR)
+        goto waitpid_out;
+
+    return ret;
+}
diff -r 190c37e0eb30 tools/libxl/xl_cmdimpl.c
--- a/tools/libxl/xl_cmdimpl.c  Tue Dec 14 18:00:35 2010 +0000
+++ b/tools/libxl/xl_cmdimpl.c  Tue Dec 14 18:54:20 2010 +0000
@@ -100,18 +100,6 @@ struct save_file_header {
 };
 
 
-enum action_on_shutdown {
-    ACTION_DESTROY,
-
-    ACTION_RESTART,
-    ACTION_RESTART_RENAME,
-
-    ACTION_PRESERVE,
-
-    ACTION_COREDUMP_DESTROY,
-    ACTION_COREDUMP_RESTART,
-};
-
 static const char *action_on_shutdown_names[] = {
     [ACTION_DESTROY] = "destroy",
 
@@ -124,26 +112,7 @@ static const char *action_on_shutdown_na
     [ACTION_COREDUMP_RESTART] = "coredump-restart",
 };
 
-struct domain_config {
-    libxl_domain_create_info c_info;
-    libxl_domain_build_info b_info;
-
-    int num_disks, num_vifs, num_vif2s, num_pcidevs, num_vfbs, num_vkbs;
-
-    libxl_device_disk *disks;
-    libxl_device_nic *vifs;
-    libxl_device_net2 *vif2s;
-    libxl_device_pci *pcidevs;
-    libxl_device_vfb *vfbs;
-    libxl_device_vkb *vkbs;
-
-    enum action_on_shutdown on_poweroff;
-    enum action_on_shutdown on_reboot;
-    enum action_on_shutdown on_watchdog;
-    enum action_on_shutdown on_crash;
-};
-
-static void free_domain_config(struct domain_config *d_config)
+static void free_domain_config(libxl_domain_config *d_config)
 {
     int i;
 
@@ -457,18 +426,8 @@ static void init_vkb_info(libxl_device_v
     vkb->devid = dev_num;
 }
 
-static void init_console_info(libxl_device_console *console, int dev_num, 
libxl_domain_build_state *state)
-{
-    memset(console, 0x00, sizeof(libxl_device_console));
-    console->devid = dev_num;
-    console->consback = LIBXL_CONSBACK_XENCONSOLED;
-    console->output = strdup("pty");
-    if (state)
-        console->build_state = state;
-}
-
 static void printf_info(int domid,
-                        struct domain_config *d_config,
+                        libxl_domain_config *d_config,
                         libxl_device_model_info *dm_info)
 {
     int i;
@@ -644,7 +603,7 @@ static int parse_action_on_shutdown(cons
 static void parse_config_data(const char *configfile_filename_report,
                               const char *configfile_data,
                               int configfile_len,
-                              struct domain_config *d_config,
+                              libxl_domain_config *d_config,
                               libxl_device_model_info *dm_info)
 {
     const char *buf;
@@ -1233,29 +1192,9 @@ static void *xrealloc(void *ptr, size_t 
     return r;
 }
 
-static pid_t autoconnect_console(void)
-{
-    pid_t pid;
-
-    pid = fork();
-    if (pid < 0) {
-        perror("unable to fork xenconsole");
-        return ERROR_FAIL;
-    } else if (pid > 0)
-        return pid;
-
-    libxl_ctx_postfork(&ctx);
-
-    sleep(1);
-    libxl_primary_console_exec(&ctx, domid);
-    /* Do not return. xl continued in child process */
-    fprintf(stderr, "Unable to attach console\n");
-    _exit(1);
-}
-
 /* Returns 1 if domain should be restarted, 2 if domain should be renamed then 
restarted  */
 static int handle_domain_death(libxl_ctx *ctx, uint32_t domid, libxl_event 
*event,
-                               struct domain_config *d_config, libxl_dominfo 
*info)
+                               libxl_domain_config *d_config, libxl_dominfo 
*info)
 {
     int restart = 0;
     enum action_on_shutdown action;
@@ -1327,7 +1266,7 @@ static int handle_domain_death(libxl_ctx
 }
 
 static int preserve_domain(libxl_ctx *ctx, uint32_t domid, libxl_event *event,
-                           struct domain_config *d_config, libxl_dominfo *info)
+                           libxl_domain_config *d_config, libxl_dominfo *info)
 {
     time_t now;
     struct tm tm;
@@ -1420,9 +1359,7 @@ static int freemem(libxl_domain_build_in
 
 static int create_domain(struct domain_create *dom_info)
 {
-    struct domain_config d_config;
-
-    libxl_domain_build_state state;
+    libxl_domain_config d_config;
     libxl_device_model_info dm_info;
 
     int debug = dom_info->debug;
@@ -1432,18 +1369,17 @@ static int create_domain(struct domain_c
     const char *extra_config = dom_info->extra_config;
     const char *restore_file = dom_info->restore_file;
     int migrate_fd = dom_info->migrate_fd;
-
-    int i, fd;
+    unsigned int c_flags;
+
+    int fd;
     int need_daemon = 1;
     int ret, rc;
-    libxl_device_model_starting *dm_starting = 0;
     libxl_waiter *w1 = NULL, *w2 = NULL;
     void *config_data = 0;
     int config_len = 0;
     int restore_fd = -1;
+    int status = 0;
     struct save_file_header hdr;
-    pid_t child_console_pid = -1;
-    int status = 0;
 
     memset(&d_config, 0x00, sizeof(d_config));
     memset(&dm_info, 0x00, sizeof(dm_info));
@@ -1587,13 +1523,6 @@ start:
         goto error_out;
     }
 
-    ret = libxl_domain_make(&ctx, &d_config.c_info, &domid);
-    if (ret) {
-        fprintf(stderr, "cannot make domain: %d\n", ret);
-        ret = ERROR_FAIL;
-        goto error_out;
-    }
-
     ret = libxl_userdata_store(&ctx, domid, "xl",
                                     config_data, config_len);
     if (ret) {
@@ -1602,115 +1531,23 @@ start:
         goto error_out;
     }
 
-    if (dom_info->console_autoconnect && !d_config.c_info.hvm) {
-        child_console_pid = autoconnect_console();
-        if (child_console_pid < 0)
-            goto error_out;
-    }
-
-    if (!restore_file) {
-        ret = libxl_run_bootloader(&ctx, &d_config.b_info, d_config.num_disks 
> 0 ? &d_config.disks[0] : NULL, domid);
-        if (ret) {
-            fprintf(stderr, "failed to run bootloader: %d\n", ret);
-            goto error_out;
-        }
-    }
-
-    if (!restore_file || !need_daemon) {
-        if (dm_info.saved_state) {
-            free(dm_info.saved_state);
-            dm_info.saved_state = NULL;
-        }
-        ret = libxl_domain_build(&ctx, &d_config.b_info, domid, &state);
-    } else {
-        ret = libxl_domain_restore(&ctx, &d_config.b_info, domid, restore_fd, 
&state, &dm_info);
-    }
-
-    if (ret) {
-        fprintf(stderr, "cannot (re-)build domain: %d\n", ret);
-        ret = ERROR_FAIL;
+    c_flags = 0;
+    if ( dom_info->console_autoconnect )
+        c_flags |= LIBXL_CREATE_CONSOLE_CONNECT;
+    if (!restore_file)
+        c_flags |= LIBXL_CREATE_RUN_BOOTLOADER;
+    if (restore_file && need_daemon)
+        c_flags |= LIBXL_CREATE_RESTORE;
+
+    ret = libxl_domain_create(&ctx, &d_config, &dm_info, c_flags, restore_fd, 
&domid);
+    if ( ret )
         goto error_out;
-    }
-
-    for (i = 0; i < d_config.num_disks; i++) {
-        d_config.disks[i].domid = domid;
-        ret = libxl_device_disk_add(&ctx, domid, &d_config.disks[i]);
-        if (ret) {
-            fprintf(stderr, "cannot add disk %d to domain: %d\n", i, ret);
-            ret = ERROR_FAIL;
-            goto error_out;
-        }
-    }
-    for (i = 0; i < d_config.num_vifs; i++) {
-        d_config.vifs[i].domid = domid;
-        ret = libxl_device_nic_add(&ctx, domid, &d_config.vifs[i]);
-        if (ret) {
-            fprintf(stderr, "cannot add nic %d to domain: %d\n", i, ret);
-            ret = ERROR_FAIL;
-            goto error_out;
-        }
-    }
-    if (!d_config.c_info.hvm) {
-        for (i = 0; i < d_config.num_vif2s; i++) {
-            d_config.vif2s[i].domid = domid;
-            ret = libxl_device_net2_add(&ctx, domid, &d_config.vif2s[i]);
-            if (ret) {
-                fprintf(stderr, "cannot add net2 %d to domain: %d\n", i, ret);
-                ret = ERROR_FAIL;
-                goto error_out;
-            }
-        }
-    }
-    if (d_config.c_info.hvm) {
-        libxl_device_console console;
-
-        init_console_info(&console, 0, &state);
-        console.domid = domid;
-        libxl_device_console_add(&ctx, domid, &console);
-        libxl_device_console_destroy(&console);
-
-        dm_info.domid = domid;
-        MUST( libxl_create_device_model(&ctx, &dm_info,
-                                        d_config.disks, d_config.num_disks,
-                                        d_config.vifs, d_config.num_vifs,
-                                        &dm_starting) );
-    } else {
-        libxl_device_console console;
-
-        for (i = 0; i < d_config.num_vfbs; i++) {
-            d_config.vfbs[i].domid = domid;
-            libxl_device_vfb_add(&ctx, domid, &d_config.vfbs[i]);
-            d_config.vkbs[i].domid = domid;
-            libxl_device_vkb_add(&ctx, domid, &d_config.vkbs[i]);
-        }
-
-        init_console_info(&console, 0, &state);
-        console.domid = domid;
-        if (d_config.num_vfbs)
-             console.consback = LIBXL_CONSBACK_IOEMU;
-        libxl_device_console_add(&ctx, domid, &console);
-        libxl_device_console_destroy(&console);
-
-        if (d_config.num_vfbs)
-            libxl_create_xenpv_qemu(&ctx, domid, d_config.vfbs, &dm_starting);
-    }
-
-    if (dm_starting)
-        MUST( libxl_confirm_device_model_startup(&ctx, dm_starting) );
-    for (i = 0; i < d_config.num_pcidevs; i++)
-        libxl_device_pci_add(&ctx, domid, &d_config.pcidevs[i]);
-
-    if (dom_info->console_autoconnect && d_config.c_info.hvm) {
-        child_console_pid = autoconnect_console();
-        if (child_console_pid < 0)
-            goto error_out;
-    }
-
-    release_lock();
 
     if (!paused)
         libxl_domain_unpause(&ctx, domid);
 
+    release_lock();
+
     ret = domid; /* caller gets success in parent */
     if (!daemonize)
         goto out;
@@ -1866,10 +1703,12 @@ out:
 
     free(config_data);
 
+#if 0
 waitpid_out:
     if (child_console_pid > 0 &&
             waitpid(child_console_pid, &status, 0) < 0 && errno == EINTR)
         goto waitpid_out;
+#endif
 
     /*
      * If we have daemonized then do not return to the caller -- this has
@@ -2457,7 +2296,7 @@ static void reboot_domain(const char *p)
 
 static void list_domains_details(const libxl_dominfo *info, int nb_domain)
 {
-    struct domain_config d_config;
+    libxl_domain_config d_config;
 
     char *config_file;
     uint8_t *data;



_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.