[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH 3/3] libxenlight: check for early failures of qemu-dm (v3)
This patch doesn't correctly write the qemu pid on xenstore. Could you please fix and resend it? On Wed, 18 Nov 2009, Ian Jackson wrote: > This patch makes xl create check whether qemu-dm has started > correctly, and causes it to fail immediately with appropriate errors > if not. There are other bugfixes too. > > More specifically: > > * libxl_create_device_model forks twice rather than once so that the > process which calls libxl does not end up being the actual parent > of qemu. That avoids the need for the qemu-dm process to be reaped > at some indefinite time in the future. > > * The first fork generates an intermediate process which is > responsible for writing the qemu-dm pid to xenstore and then merely > waits to collect and report on qemu-dm's exit status during > startup. New arguments to libxl_create_device_model allow the > preservation of its pid so that a later call can check whether the > startup is successful. > > * The core of this functionality (the double fork, waitpid, signal > handling and so forth) is abstracted away into a new facility > libxl_spawn_... in libxl_exec.c. > > Consequential changes: > > * libxl_wait_for_device_model now takes a callback function parameter > which is called repeatedly in the loop iteration and allows the > caller to abort the wait. > > * libxl_exec no longer calls fork; there is a new libxl_fork. > > * There is a hook to override waitpid, which will be necessary for > some callers. > > Remaining problems and other issues I noticed or we found: > > * The error handling is rather inconsistent still and lacking in > places. > * destroy_device_model can kill random dom0 processes (!) > > Changes since v2 of this patch: > * Various other changes split out into earlier patches in this series > * xl.c's create_domain checking for errors in its libxl calls > deferred for a future patch to avoid rebase churn. > * New libxl_spawn_... abstraction. > > Signed-off-by: Ian Jackson <Ian.Jackson@xxxxxxxxxxxxx> > --- > tools/libxl/libxl.c | 94 +++++++++++++++++---- > tools/libxl/libxl.h | 20 ++++- > tools/libxl/libxl_device.c | 11 ++- > tools/libxl/libxl_exec.c | 189 > ++++++++++++++++++++++++++++++++++++++---- > tools/libxl/libxl_internal.h | 49 ++++++++++- > tools/libxl/osdeps.c | 2 + > tools/libxl/xl.c | 19 ++++- > 7 files changed, 344 insertions(+), 40 deletions(-) > > diff --git a/tools/libxl/libxl.c b/tools/libxl/libxl.c > index 421628c..29143cf 100644 > --- a/tools/libxl/libxl.c > +++ b/tools/libxl/libxl.c > @@ -23,10 +23,12 @@ > #include <sys/types.h> > #include <fcntl.h> > #include <sys/select.h> > +#include <sys/wait.h> > #include <signal.h> > #include <unistd.h> /* for write, unlink and close */ > #include <stdint.h> > #include <inttypes.h> > +#include <assert.h> > > #include "libxl.h" > #include "libxl_utils.h" > @@ -43,6 +45,8 @@ int libxl_ctx_init(struct libxl_ctx *ctx) > > ctx->xch = xc_interface_open(); > ctx->xsh = xs_daemon_open(); > + > + ctx->waitpid_instead= libxl_waitpid_instead_default; > return 0; > } > > @@ -520,16 +524,41 @@ static char ** libxl_build_device_model_args(struct > libxl_ctx *ctx, > return (char **) flexarray_contents(dm_args); > } > > +struct libxl_device_model_starting { > + struct libxl_spawn_starting for_spawn; /* first! */ > + char *dom_path; > + int domid; > +}; > + > +void dm_xenstore_record_pid(struct libxl_ctx *ctx, void *for_spawn, > + pid_t innerchild) { > + struct libxl_device_model_starting *starting = for_spawn; > + struct libxl_ctx clone; > + char *kvs[3]; > + > + clone = *ctx; > + clone.xsh = xs_daemon_open(); > + /* we mustn't use the parent's handle in the child */ > + > + kvs[0] = libxl_sprintf(ctx, "image/device-model-pid"); > + kvs[1] = libxl_sprintf(ctx, "%d", innerchild); > + kvs[2] = NULL; > + libxl_xs_writev(ctx, XBT_NULL, starting->dom_path, kvs); > +} > + > int libxl_create_device_model(struct libxl_ctx *ctx, > libxl_device_model_info *info, > - libxl_device_nic *vifs, int num_vifs) > + libxl_device_nic *vifs, int num_vifs, > + libxl_device_model_starting **starting_r) > { > char *dom_path, *path, *logfile, *logfile_new; > - char *kvs[3]; > struct stat stat_buf; > - int logfile_w, null, pid; > - int i; > + int logfile_w, null; > + int i, rc; > char **args; > + struct libxl_spawn_starting buf_spawn, *for_spawn; > + > + *starting_r= 0; > > args = libxl_build_device_model_args(ctx, info, vifs, num_vifs); > if (!args) > @@ -559,18 +588,50 @@ int libxl_create_device_model(struct libxl_ctx *ctx, > logfile = libxl_sprintf(ctx, "/var/log/xen/qemu-dm-%s.log", > info->dom_name); > logfile_w = open(logfile, O_WRONLY|O_CREAT, 0644); > null = open("/dev/null", O_RDONLY); > - pid = libxl_exec(ctx, null, logfile_w, logfile_w, info->device_model, > args); > + > + if (starting_r) { > + *starting_r= libxl_calloc(ctx, sizeof(**starting_r), 1); > + if (!*starting_r) return ERROR_NOMEM; > + (*starting_r)->domid= info->domid; > + for_spawn= &(*starting_r)->for_spawn; > + } else { > + for_spawn= &buf_spawn; > + } > + rc = libxl_spawn_spawn(ctx, for_spawn, "device model", > + dm_xenstore_record_pid); > + if (rc < 0) goto xit; > + if (!rc) { /* inner child */ > + libxl_exec(ctx, null, logfile_w, logfile_w, > + info->device_model, args); > + } > + > + rc = 0; > + xit: > close(null); > close(logfile_w); > > - kvs[0] = libxl_sprintf(ctx, "image/device-model-pid"); > - kvs[1] = libxl_sprintf(ctx, "%d", pid); > - kvs[2] = NULL; > - libxl_xs_writev(ctx, XBT_NULL, dom_path, kvs); > + return rc; > +} > > - return 0; > +int libxl_detach_device_model(struct libxl_ctx *ctx, > + libxl_device_model_starting *starting) { > + int rc; > + rc = libxl_spawn_detach(ctx, &starting->for_spawn); > + libxl_free(ctx, starting); > + return rc; > +} > + > + > +int libxl_confirm_device_model_startup(struct libxl_ctx *ctx, > + libxl_device_model_starting > *starting) { > + int problem = libxl_wait_for_device_model(ctx, starting->domid, > "running", > + libxl_spawn_check, > + &starting->for_spawn); > + int detach = libxl_detach_device_model(ctx, starting); > + return problem ? problem : detach; > } > > + > > /******************************************************************************/ > int libxl_device_disk_add(struct libxl_ctx *ctx, uint32_t domid, > libxl_device_disk *disk) > { > @@ -917,12 +978,13 @@ static int libxl_build_xenpv_qemu_args(struct libxl_ctx > *ctx, > } > > int libxl_create_xenpv_qemu(struct libxl_ctx *ctx, libxl_device_vfb *vfb, > - int num_console, libxl_device_console *console) > + int num_console, libxl_device_console *console, > + struct libxl_device_model_starting **starting_r) > { > libxl_device_model_info info; > > libxl_build_xenpv_qemu_args(ctx, vfb, num_console, console, &info); > - libxl_create_device_model(ctx, &info, NULL, 0); > + libxl_create_device_model(ctx, &info, NULL, 0, starting_r); > return 0; > } > > @@ -1195,7 +1257,7 @@ int libxl_device_pci_add(struct libxl_ctx *ctx, > uint32_t domid, libxl_device_pci > > hvm = is_hvm(ctx, domid); > if (hvm) { > - if (libxl_wait_for_device_model(ctx, domid, "running") < 0) { > + if (libxl_wait_for_device_model(ctx, domid, "running", 0,0) < 0) { > return -1; > } > snprintf(path, sizeof(path), > "/local/domain/0/device-model/%d/state", domid); > @@ -1209,7 +1271,7 @@ int libxl_device_pci_add(struct libxl_ctx *ctx, > uint32_t domid, libxl_device_pci > pcidev->bus, pcidev->dev, pcidev->func); > snprintf(path, sizeof(path), > "/local/domain/0/device-model/%d/command", domid); > xs_write(ctx->xsh, XBT_NULL, path, "pci-ins", strlen("pci-ins")); > - if (libxl_wait_for_device_model(ctx, domid, "pci-inserted") < 0) > + if (libxl_wait_for_device_model(ctx, domid, "pci-inserted", 0,0) < 0) > XL_LOG(ctx, XL_LOG_ERROR, "Device Model didn't respond in time"); > snprintf(path, sizeof(path), > "/local/domain/0/device-model/%d/parameter", domid); > vdevfn = libxl_xs_read(ctx, XBT_NULL, path); > @@ -1283,7 +1345,7 @@ int libxl_device_pci_remove(struct libxl_ctx *ctx, > uint32_t domid, libxl_device_ > > hvm = is_hvm(ctx, domid); > if (hvm) { > - if (libxl_wait_for_device_model(ctx, domid, "running") < 0) { > + if (libxl_wait_for_device_model(ctx, domid, "running", 0,0) < 0) { > return -1; > } > snprintf(path, sizeof(path), > "/local/domain/0/device-model/%d/state", domid); > @@ -1293,7 +1355,7 @@ int libxl_device_pci_remove(struct libxl_ctx *ctx, > uint32_t domid, libxl_device_ > pcidev->bus, pcidev->dev, pcidev->func); > snprintf(path, sizeof(path), > "/local/domain/0/device-model/%d/command", domid); > xs_write(ctx->xsh, XBT_NULL, path, "pci-rem", strlen("pci-rem")); > - if (libxl_wait_for_device_model(ctx, domid, "pci-removed") < 0) { > + if (libxl_wait_for_device_model(ctx, domid, "pci-removed", 0,0) < 0) > { > XL_LOG(ctx, XL_LOG_ERROR, "Device Model didn't respond in time"); > return -1; > } > diff --git a/tools/libxl/libxl.h b/tools/libxl/libxl.h > index ac4c79e..29ffde2 100644 > --- a/tools/libxl/libxl.h > +++ b/tools/libxl/libxl.h > @@ -41,6 +41,11 @@ struct libxl_ctx { > /* mini-GC */ > int alloc_maxsize; > void **alloc_ptrs; > + > + /* for callers who reap children willy-nilly; caller must only > + * set this after libxl_init and before any other call - or > + * may leave them untouched */ > + int (*waitpid_instead)(pid_t pid, int *status, int flags); > }; > > typedef struct { > @@ -235,11 +240,22 @@ int libxl_domain_unpause(struct libxl_ctx *ctx, > uint32_t domid); > struct libxl_dominfo * libxl_domain_list(struct libxl_ctx *ctx, int > *nb_domain); > xc_dominfo_t * libxl_domain_infolist(struct libxl_ctx *ctx, int *nb_domain); > > +typedef struct libxl_device_model_starting libxl_device_model_starting; > int libxl_create_device_model(struct libxl_ctx *ctx, > libxl_device_model_info *info, > - libxl_device_nic *vifs, int num_vifs); > + libxl_device_nic *vifs, int num_vifs, > + libxl_device_model_starting **starting_r); > int libxl_create_xenpv_qemu(struct libxl_ctx *ctx, libxl_device_vfb *vfb, > - int num_console, libxl_device_console *console); > + int num_console, libxl_device_console *console, > + libxl_device_model_starting **starting_r); > + /* Caller must either: pass starting_r==0, or on successful > + * return pass *starting_r (which will be non-0) to > + * libxl_confirm_device_model or libxl_detach_device_model. */ > +int libxl_confirm_device_model_startup(struct libxl_ctx *ctx, > + libxl_device_model_starting *starting); > +int libxl_detach_device_model(struct libxl_ctx *ctx, > + libxl_device_model_starting *starting); > + /* DM is detached even if error is returned */ > > int libxl_device_disk_add(struct libxl_ctx *ctx, uint32_t domid, > libxl_device_disk *disk); > int libxl_device_disk_clean_shutdown(struct libxl_ctx *ctx, uint32_t domid); > diff --git a/tools/libxl/libxl_device.c b/tools/libxl/libxl_device.c > index 451233f..39932a6 100644 > --- a/tools/libxl/libxl_device.c > +++ b/tools/libxl/libxl_device.c > @@ -287,12 +287,17 @@ int libxl_device_pci_flr(struct libxl_ctx *ctx, > unsigned int domain, unsigned in > return -1; > } > > -int libxl_wait_for_device_model(struct libxl_ctx *ctx, uint32_t domid, char > *state) > +int libxl_wait_for_device_model(struct libxl_ctx *ctx, > + uint32_t domid, char *state, > + int (*check_callback)(struct libxl_ctx *ctx, > + void *userdata), > + void *check_callback_userdata) > { > char path[50]; > char *p; > int watchdog = 100; > unsigned int len; > + int rc; > > snprintf(path, sizeof(path), "/local/domain/0/device-model/%d/state", > domid); > while (watchdog > 0) { > @@ -310,6 +315,10 @@ int libxl_wait_for_device_model(struct libxl_ctx *ctx, > uint32_t domid, char *sta > watchdog--; > } > } > + if (check_callback) { > + rc = check_callback(ctx, check_callback_userdata); > + if (rc) return rc; > + } > } > XL_LOG(ctx, XL_LOG_ERROR, "Device Model not ready"); > return -1; > diff --git a/tools/libxl/libxl_exec.c b/tools/libxl/libxl_exec.c > index 5186ac8..6a3373e 100644 > --- a/tools/libxl/libxl_exec.c > +++ b/tools/libxl/libxl_exec.c > @@ -18,34 +18,191 @@ > #include "libxl_osdeps.h" > > #include <stdio.h> > +#include <string.h> > #include <unistd.h> > #include <stdlib.h> > +#include <unistd.h> > +#include <assert.h> > +#include <sys/types.h> > +#include <sys/wait.h> > > #include "libxl.h" > #include "libxl_internal.h" > > -int libxl_exec(struct libxl_ctx *ctx, int stdinfd, int stdoutfd, int > stderrfd, > - char *arg0, char **args) > +pid_t libxl_fork(struct libxl_ctx *ctx) > { > - int pid, i; > + pid_t pid; > > pid = fork(); > if (pid == -1) { > XL_LOG_ERRNO(ctx, XL_LOG_ERROR, "fork failed"); > return -1; > } > - if (pid == 0) { > - /* child */ > - if (stdinfd != -1) > - dup2(stdinfd, STDIN_FILENO); > - if (stdoutfd != -1) > - dup2(stdoutfd, STDOUT_FILENO); > - if (stderrfd != -1) > - dup2(stderrfd, STDERR_FILENO); > - for (i = 4; i < 256; i++) > - close(i); > - execv(arg0, args); > - exit(256); > - } > + > return pid; > } > + > +void libxl_exec(struct libxl_ctx *ctx, int stdinfd, int stdoutfd, int > stderrfd, > + char *arg0, char **args) > + /* call this in the child */ > +{ > + int i; > + > + if (stdinfd != -1) > + dup2(stdinfd, STDIN_FILENO); > + if (stdoutfd != -1) > + dup2(stdoutfd, STDOUT_FILENO); > + if (stderrfd != -1) > + dup2(stderrfd, STDERR_FILENO); > + for (i = 4; i < 256; i++) > + close(i); > + execv(arg0, args); > + XL_LOG_ERRNO(ctx, XL_LOG_ERROR, "exec %s failed", arg0); > + _exit(-1); > +} > + > +void libxl_report_child_exitstatus(struct libxl_ctx *ctx, > + const char *what, pid_t pid, int status) { > + /* treats all exit statuses as errors; if that's not what you want, > + * check status yourself first */ > + > + if (WIFEXITED(status)) { > + int st= WEXITSTATUS(status); > + if (st) > + XL_LOG(ctx, XL_LOG_ERROR, "%s [%ld] exited" > + " with error status %d", what, (unsigned long)pid, st); > + else > + XL_LOG(ctx, XL_LOG_ERROR, "%s [%ld] unexpectedly" > + " exited status zero", what, (unsigned long)pid); > + } else if (WIFSIGNALED(status)) { > + int sig= WTERMSIG(status); > + const char *str= strsignal(sig); > + const char *coredump= WCOREDUMP(status) ? " (core dumped)" : ""; > + if (str) > + XL_LOG(ctx, XL_LOG_ERROR, "%s [%ld] died due to" > + " fatal signal %s%s", what, (unsigned long)pid, > + str, coredump); > + else > + XL_LOG(ctx, XL_LOG_ERROR, "%s [%ld] died due to unknown" > + " fatal signal number %d%s", what, (unsigned long)pid, > + sig, coredump); > + } else { > + XL_LOG(ctx, XL_LOG_ERROR, "%s [%ld] gave unknown" > + " wait status 0x%x", what, (unsigned long)pid, status); > + } > +} > + > +pid_t libxl_waitpid_instead_default(pid_t pid, int *status, int flags) { > + return waitpid(pid,status,flags); > +} > + > + > + > +int libxl_spawn_spawn(struct libxl_ctx *ctx, > + struct libxl_spawn_starting *for_spawn, > + const char *what, > + void (*intermediate_hook)(struct libxl_ctx *ctx, > + void *for_spawn, > + pid_t innerchild)) { > + pid_t child, got; > + int status; > + pid_t intermediate; > + > + if (for_spawn) { > + for_spawn->what= strdup(what); > + if (!for_spawn->what) return ERROR_NOMEM; > + } > + > + intermediate = libxl_fork(ctx); > + if (intermediate==-1) { > + if (for_spawn) free(for_spawn->what); > + return ERROR_FAIL; > + } > + if (intermediate) { > + /* parent */ > + if (for_spawn) for_spawn->intermediate= intermediate; > + return 1; > + } > + > + /* we are now the intermediate process */ > + > + child = libxl_fork(ctx); > + if (!child) return 0; /* caller runs child code */ > + if (child<0) exit(255); > + > + intermediate_hook(ctx, for_spawn, child); > + > + if (!for_spawn) _exit(0); /* just detach then */ > + > + got = ctx->waitpid_instead(child, &status, 0); > + assert(got == child); > + > + libxl_report_child_exitstatus(ctx, what, child, status); > + _exit(WIFEXITED(status) ? WEXITSTATUS(status) : > + WIFSIGNALED(status) && WTERMSIG(status)<127 > + ? WTERMSIG(status)+128 : -1); > +} > + > +static void report_spawn_intermediate_status(struct libxl_ctx *ctx, > + struct libxl_spawn_starting *for_spawn, > + int status) { > + if (!WIFEXITED(status)) { > + /* intermediate process did the logging itself if it exited */ > + char *intermediate_what= > + libxl_sprintf(ctx, > + "%s intermediate process (startup monitor)", > + for_spawn->what); > + libxl_report_child_exitstatus(ctx, intermediate_what, > + for_spawn->intermediate, status); > + } > +} > + > +int libxl_spawn_detach(struct libxl_ctx *ctx, > + struct libxl_spawn_starting *for_spawn) { > + int r, status; > + pid_t got; > + int rc = 0; > + > + if (!for_spawn) return 0; > + > + if (for_spawn->intermediate) { > + r = kill(for_spawn->intermediate, SIGKILL); > + if (r) { > + XL_LOG_ERRNO(ctx, XL_LOG_ERROR, > + "could not kill %s intermediate process [%ld]", > + for_spawn->what, > + (unsigned long)for_spawn->intermediate); > + abort(); /* things are very wrong */ > + } > + got = ctx->waitpid_instead(for_spawn->intermediate, &status, 0); > + assert(got == for_spawn->intermediate); > + if (!(WIFSIGNALED(status) && WTERMSIG(status)==SIGKILL)) { > + report_spawn_intermediate_status(ctx, for_spawn, status); > + rc = ERROR_FAIL; > + } > + for_spawn->intermediate = 0; > + } > + > + free(for_spawn->what); > + for_spawn->what = 0; > + > + return rc; > +} > + > +int libxl_spawn_check(struct libxl_ctx *ctx, void *for_spawn_void) { > + struct libxl_spawn_starting *for_spawn = for_spawn_void; > + pid_t got; > + int status; > + > + if (!for_spawn) return 0; > + > + assert(for_spawn->intermediate); > + got = ctx->waitpid_instead(for_spawn->intermediate, &status, WNOHANG); > + if (!got) return 0; > + > + assert(got == for_spawn->intermediate); > + report_spawn_intermediate_status(ctx, for_spawn, status); > + > + for_spawn->intermediate= 0; > + return ERROR_FAIL; > +} > diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h > index 046e51d..957bd9e 100644 > --- a/tools/libxl/libxl_internal.h > +++ b/tools/libxl/libxl_internal.h > @@ -135,7 +135,11 @@ int libxl_device_generic_add(struct libxl_ctx *ctx, > libxl_device *device, > char **bents, char **fents); > int libxl_device_destroy(struct libxl_ctx *ctx, char *be_path, int force); > int libxl_devices_destroy(struct libxl_ctx *ctx, uint32_t domid, int force); > -int libxl_wait_for_device_model(struct libxl_ctx *ctx, uint32_t domid, char > *state); > +int libxl_wait_for_device_model(struct libxl_ctx *ctx, > + uint32_t domid, char *state, > + int (*check_callback)(struct libxl_ctx *ctx, > + void *userdata), > + void *check_callback_userdata); > int libxl_wait_for_backend(struct libxl_ctx *ctx, char *be_path, char > *state); > int libxl_device_pci_flr(struct libxl_ctx *ctx, unsigned int domain, > unsigned int bus, > unsigned int dev, unsigned int func); > @@ -146,8 +150,47 @@ int hvm_build_set_params(int handle, uint32_t domid, > int vcpus, int store_evtchn, unsigned long > *store_mfn); > > /* xl_exec */ > -int libxl_exec(struct libxl_ctx *ctx, int stdinfd, int stdoutfd, int > stderrfd, > - char *arg0, char **args); > + > + /* higher-level double-fork and separate detach eg as for device models */ > + > +struct libxl_spawn_starting { > + /* put this in your own stateu structure as returned to application */ > + /* all fields are private to libxl_spawn_... */ > + pid_t intermediate; > + char *what; /* malloc'd in spawn_spawn */ > +}; > + > +int libxl_spawn_spawn(struct libxl_ctx *ctx, > + struct libxl_spawn_starting *for_spawn, > + const char *what, > + void (*intermediate_hook)(struct libxl_ctx *ctx, > + void *for_spawn, > + pid_t innerchild)); > + /* Logs errors. A copy of "what" is taken. Return values: > + * < 0 error, for_spawn need not be detached > + * +1 caller is now the inner child, should probably call libxl_exec > + * 0 caller is the parent, must call detach on *for_spawn eventually > + * Caller, may pass 0 for for_spawn, in which case no need to detach. > + */ > +int libxl_spawn_detach(struct libxl_ctx *ctx, > + struct libxl_spawn_starting *for_spawn); > + /* Logs errors. Idempotent, but only permitted after successful > + * call to libxl_spawn_spawn, and no point calling it again if it fails. */ > +int libxl_spawn_check(struct libxl_ctx *ctx, > + void *for_spawn); > + /* Logs errors but also returns them. > + * for_spawn must actually be a struct libxl_spawn_starting* but > + * we take void* so you can pass this function directly to > + * libxl_wait_for_device_model. Caller must still call detach. */ > + > + /* low-level stuff, for synchronous subprocesses etc. */ > + > +pid_t libxl_fork(struct libxl_ctx *ctx); // logs errors > +void libxl_exec(struct libxl_ctx *ctx, int stdinfd, int stdoutfd, int > stderrfd, > + char *arg0, char **args); // logs errors, never returns > +void libxl_log_child_exitstatus(struct libxl_ctx *ctx, > + const char *what, pid_t pid, int status); > +pid_t libxl_waitpid_instead_default(pid_t pid, int *status, int flags); > > #endif > > diff --git a/tools/libxl/osdeps.c b/tools/libxl/osdeps.c > index ad96480..b146a9d 100644 > --- a/tools/libxl/osdeps.c > +++ b/tools/libxl/osdeps.c > @@ -13,6 +13,8 @@ > * GNU Lesser General Public License for more details. > */ > > +#include "libxl_osdeps.h" > + > #include <unistd.h> > #include <stdarg.h> > #include <stdio.h> > diff --git a/tools/libxl/xl.c b/tools/libxl/xl.c > index 727fe4a..6d43f8b 100644 > --- a/tools/libxl/xl.c > +++ b/tools/libxl/xl.c > @@ -699,6 +699,15 @@ skip_pci: > config_destroy(&config); > } > > +#define MUST( call ) ({ \ > + int must_rc = (call); \ > + if (must_rc) { \ > + fprintf(stderr,"xl: fatal error: %s:%d, rc=%d: %s\n", \ > + __FILE__,__LINE__, must_rc, #call); \ > + exit(-must_rc); \ > + } \ > + }) > + > static void create_domain(int debug, const char *filename) > { > struct libxl_ctx ctx; > @@ -715,6 +724,7 @@ static void create_domain(int debug, const char *filename) > libxl_device_console console; > int num_disks = 0, num_vifs = 0, num_pcidevs = 0, num_vfbs = 0, num_vkbs > = 0; > int i; > + libxl_device_model_starting *dm_starting = 0; > > printf("Parsing config file %s\n", filename); > parse_config_file(filename, &info1, &info2, &disks, &num_disks, &vifs, > &num_vifs, &pcidevs, &num_pcidevs, &vfbs, &num_vfbs, &vkbs, &num_vkbs, > &dm_info); > @@ -736,7 +746,8 @@ static void create_domain(int debug, const char *filename) > } > if (info1.hvm) { > device_model_info_domid_fixup(&dm_info, domid); > - libxl_create_device_model(&ctx, &dm_info, vifs, num_vifs); > + MUST( libxl_create_device_model(&ctx, &dm_info, vifs, num_vifs, > + &dm_starting) ); > } else { > for (i = 0; i < num_vfbs; i++) { > vfb_info_domid_fixup(vfbs + i, domid); > @@ -750,10 +761,14 @@ static void create_domain(int debug, const char > *filename) > console.constype = CONSTYPE_IOEMU; > libxl_device_console_add(&ctx, domid, &console); > if (num_vfbs) > - libxl_create_xenpv_qemu(&ctx, vfbs, 1, &console); > + libxl_create_xenpv_qemu(&ctx, vfbs, 1, &console, &dm_starting); > } > + > for (i = 0; i < num_pcidevs; i++) > libxl_device_pci_add(&ctx, domid, &pcidevs[i]); > + if (dm_starting) > + MUST( libxl_confirm_device_model_startup(&ctx, dm_starting) ); > + > libxl_domain_unpause(&ctx, domid); > > } > -- > 1.5.6.5 > > > _______________________________________________ > Xen-devel mailing list > Xen-devel@xxxxxxxxxxxxxxxxxxx > http://lists.xensource.com/xen-devel > _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |