Ejemplo n.º 1
0
void libxl__bootloader_init(libxl__bootloader_state *bl)
{
    assert(bl->ao);
    bl->rc = 0;
    bl->dls.diskpath = NULL;
    bl->openpty.ao = bl->ao;
    bl->dls.ao = bl->ao;
    bl->ptys[0].master = bl->ptys[0].slave = 0;
    bl->ptys[1].master = bl->ptys[1].slave = 0;
    libxl__ev_child_init(&bl->child);
    libxl__domaindeathcheck_init(&bl->deathcheck);
    bl->keystrokes.ao = bl->ao;
    libxl__datacopier_init(&bl->keystrokes);
    bl->display.ao = bl->ao;
    libxl__datacopier_init(&bl->display);
    bl->got_pollhup = 0;
}
Ejemplo n.º 2
0
void libxl__async_exec_init(libxl__async_exec_state *aes)
{
    libxl__ev_time_init(&aes->time);
    libxl__ev_child_init(&aes->child);
}
Ejemplo n.º 3
0
static void run_helper(libxl__egc *egc, libxl__save_helper_state *shs,
                       const char *mode_arg, int stream_fd,
                       const int *preserve_fds, int num_preserve_fds,
                       const unsigned long *argnums, int num_argnums)
{
    STATE_AO_GC(shs->ao);
    const char *args[4 + num_argnums];
    const char **arg = args;
    int i, rc;

    /* Resources we must free */
    libxl__carefd *childs_pipes[2] = { 0,0 };

    /* Convenience aliases */
    const uint32_t domid = shs->domid;

    shs->rc = 0;
    shs->completed = 0;
    shs->pipes[0] = shs->pipes[1] = 0;
    libxl__ev_fd_init(&shs->readable);
    libxl__ev_child_init(&shs->child);

    shs->stdin_what = GCSPRINTF("domain %"PRIu32" save/restore helper"
                                " stdin pipe", domid);
    shs->stdout_what = GCSPRINTF("domain %"PRIu32" save/restore helper"
                                 " stdout pipe", domid);

    *arg++ = getenv("LIBXL_SAVE_HELPER") ?: PRIVATE_BINDIR "/" "libxl-save-helper";
    *arg++ = mode_arg;
    const char **stream_fd_arg = arg++;
    for (i=0; i<num_argnums; i++)
        *arg++ = GCSPRINTF("%lu", argnums[i]);
    *arg++ = 0;
    assert(arg == args + ARRAY_SIZE(args));

    libxl__carefd_begin();
    int childfd;
    for (childfd=0; childfd<2; childfd++) {
        /* Setting up the pipe for the child's fd childfd */
        int fds[2];
        if (libxl_pipe(CTX,fds)) {
            rc = ERROR_FAIL;
            libxl__carefd_unlock();
            goto out;
        }
        int childs_end = childfd==0 ? 0 /*read*/  : 1 /*write*/;
        int our_end    = childfd==0 ? 1 /*write*/ : 0 /*read*/;
        childs_pipes[childfd] = libxl__carefd_record(CTX, fds[childs_end]);
        shs->pipes[childfd] =   libxl__carefd_record(CTX, fds[our_end]);
    }
    libxl__carefd_unlock();

    pid_t pid = libxl__ev_child_fork(gc, &shs->child, helper_exited);
    if (!pid) {
        if (stream_fd <= 2) {
            stream_fd = dup(stream_fd);
            if (stream_fd < 0) {
                LOGE(ERROR,"dup migration stream fd");
                exit(-1);
            }
        }
        libxl_fd_set_cloexec(CTX, stream_fd, 0);
        *stream_fd_arg = GCSPRINTF("%d", stream_fd);

        for (i=0; i<num_preserve_fds; i++)
            if (preserve_fds[i] >= 0) {
                assert(preserve_fds[i] > 2);
                libxl_fd_set_cloexec(CTX, preserve_fds[i], 0);
            }

        libxl__exec(gc,
                    libxl__carefd_fd(childs_pipes[0]),
                    libxl__carefd_fd(childs_pipes[1]),
                    -1,
                    args[0], (char**)args, 0);
    }

    libxl__carefd_close(childs_pipes[0]);
    libxl__carefd_close(childs_pipes[1]);

    rc = libxl__ev_fd_register(gc, &shs->readable, helper_stdout_readable,
                               libxl__carefd_fd(shs->pipes[1]), POLLIN|POLLPRI);
    if (rc) goto out;
    return;

 out:
    libxl__carefd_close(childs_pipes[0]);
    libxl__carefd_close(childs_pipes[1]);
    helper_failed(egc, shs, rc);;
}
Ejemplo n.º 4
0
void libxl__colo_save_setup(libxl__egc *egc, libxl__colo_save_state *css)
{
    libxl__domain_save_state *dss = CONTAINER_OF(css, *dss, css);

    /* Convenience aliases */
    libxl__checkpoint_devices_state *const cds = &dss->cds;
    libxl__srm_save_autogen_callbacks *const callbacks =
        &dss->sws.shs.callbacks.save.a;

    STATE_AO_GC(dss->ao);

    if (dss->type != LIBXL_DOMAIN_TYPE_HVM) {
        LOGD(ERROR, dss->domid, "COLO only supports hvm now");
        goto out;
    }

    css->send_fd = dss->fd;
    css->recv_fd = dss->recv_fd;
    css->svm_running = false;
    css->paused = true;
    css->qdisk_setuped = false;
    css->qdisk_used = false;
    libxl__ev_child_init(&css->child);
    css->cps.is_userspace_proxy =
        libxl_defbool_val(dss->remus->userspace_colo_proxy);

    if (dss->remus->netbufscript)
        css->colo_proxy_script = libxl__strdup(gc, dss->remus->netbufscript);
    else
        css->colo_proxy_script = GCSPRINTF("%s/colo-proxy-setup",
                                           libxl__xen_script_dir_path());

    cds->ops = colo_ops;
    cds->callback = colo_save_setup_done;
    cds->ao = ao;
    cds->domid = dss->domid;
    cds->concrete_data = css;

    /* If enable userspace proxy mode, we don't need VIF */
    if (css->cps.is_userspace_proxy) {
        cds->device_kind_flags = (1 << LIBXL__DEVICE_KIND_VBD);

        /* Use this args we can connect to qemu colo-compare */
        cds->nics = libxl__device_list(gc, &libxl__nic_devtype,
                                       cds->domid, &cds->num_nics);
        if (cds->num_nics > 0) {
            css->cps.checkpoint_host = cds->nics[0].colo_checkpoint_host;
            css->cps.checkpoint_port = cds->nics[0].colo_checkpoint_port;
        }
    } else {
        cds->device_kind_flags = (1 << LIBXL__DEVICE_KIND_VIF) |
                                 (1 << LIBXL__DEVICE_KIND_VBD);
    }

    css->srs.ao = ao;
    css->srs.fd = css->recv_fd;
    css->srs.back_channel = true;
    libxl__stream_read_start(egc, &css->srs);
    css->cps.ao = ao;
    if (colo_proxy_setup(&css->cps)) {
        LOGD(ERROR, cds->domid, "COLO: failed to setup colo proxy for guest");
        goto out;
    }

    if (init_device_subkind(cds))
        goto out;

    callbacks->suspend = libxl__colo_save_domain_suspend_callback;
    callbacks->checkpoint = libxl__colo_save_domain_checkpoint_callback;
    callbacks->postcopy = libxl__colo_save_domain_resume_callback;
    callbacks->wait_checkpoint = libxl__colo_save_domain_wait_checkpoint_callback;

    libxl__checkpoint_devices_setup(egc, &dss->cds);

    return;

out:
    dss->callback(egc, dss, ERROR_FAIL);
}
Ejemplo n.º 5
0
void libxl__conversion_helper_init(libxl__conversion_helper_state *chs)
{
    libxl__ev_child_init(&chs->child);
}
Ejemplo n.º 6
0
void libxl__save_helper_init(libxl__save_helper_state *shs)
{
    libxl__ao_abortable_init(&shs->abrt);
    libxl__ev_fd_init(&shs->readable);
    libxl__ev_child_init(&shs->child);
}