예제 #1
0
파일: libxl_dom_save.c 프로젝트: MrVan/xen
static void switch_logdirty_xswatch(libxl__egc *egc, libxl__ev_xswatch *watch,
                            const char *watch_path, const char *event_path)
{
    libxl__logdirty_switch *lds = CONTAINER_OF(watch, *lds, watch);
    STATE_AO_GC(lds->ao);
    const char *got;
    xs_transaction_t t = 0;
    int rc;

    for (;;) {
        rc = libxl__xs_transaction_start(gc, &t);
        if (rc) goto out;

        rc = libxl__xs_read_checked(gc, t, lds->ret_path, &got);
        if (rc) goto out;

        if (!got) {
            rc = +1;
            goto out;
        }

        if (strcmp(got, lds->cmd)) {
            LOG(ERROR,"logdirty switch: sent command `%s' but got reply `%s'"
                " (xenstore paths `%s' / `%s')", lds->cmd, got,
                lds->cmd_path, lds->ret_path);
            rc = ERROR_FAIL;
            goto out;
        }

        rc = libxl__xs_rm_checked(gc, t, lds->cmd_path);
        if (rc) goto out;

        rc = libxl__xs_rm_checked(gc, t, lds->ret_path);
        if (rc) goto out;

        rc = libxl__xs_transaction_commit(gc, &t);
        if (!rc) break;
        if (rc<0) goto out;
    }

 out:
    /* rc < 0: error
     * rc == 0: ok, we are done
     * rc == +1: need to keep waiting
     */
    libxl__xs_transaction_abort(gc, &t);

    if (rc <= 0) {
        if (rc < 0)
            LOG(ERROR,"logdirty switch: failed (rc=%d)",rc);
        switch_logdirty_done(egc,lds,rc);
    }
}
예제 #2
0
파일: libxl_aoutils.c 프로젝트: 0day-ci/xen
void xswait_xswatch_callback(libxl__egc *egc, libxl__ev_xswatch *xsw,
                             const char *watch_path, const char *event_path)
{
    EGC_GC;
    libxl__xswait_state *xswa = CONTAINER_OF(xsw, *xswa, watch_ev);
    int rc;
    const char *data;

    if (xswa->path[0] == '@') {
        data = 0;
    } else {
        rc = libxl__xs_read_checked(gc, XBT_NULL, xswa->path, &data);
        if (rc) { xswait_report_error(egc, xswa, rc); return; }
    }

    xswa->callback(egc, xswa, 0, data);
}
예제 #3
0
/*
 * If the device has a vifname, then use that instead of
 * the vifX.Y format.
 * it must ONLY be used for remus because if driver domains
 * were in use it would constitute a security vulnerability.
 */
static const char *get_vifname(libxl__checkpoint_device *dev,
                               const libxl_device_nic *nic)
{
    const char *vifname = NULL;
    const char *path;
    int rc;

    STATE_AO_GC(dev->cds->ao);

    /* Convenience aliases */
    const uint32_t domid = dev->cds->domid;

    path = GCSPRINTF("%s/backend/vif/%d/%d/vifname",
                     libxl__xs_get_dompath(gc, 0), domid, nic->devid);
    rc = libxl__xs_read_checked(gc, XBT_NULL, path, &vifname);
    if (!rc && !vifname) {
        vifname = libxl__device_nic_devname(gc, domid,
                                            nic->devid,
                                            nic->nictype);
    }

    return vifname;
}
예제 #4
0
파일: libxl_dom_save.c 프로젝트: MrVan/xen
static void domain_suspend_switch_qemu_xen_traditional_logdirty
                               (libxl__egc *egc, int domid, unsigned enable,
                                libxl__logdirty_switch *lds)
{
    STATE_AO_GC(lds->ao);
    int rc;
    xs_transaction_t t = 0;
    const char *got;

    if (!lds->cmd_path) {
        uint32_t dm_domid = libxl_get_stubdom_id(CTX, domid);
        lds->cmd_path = DEVICE_MODEL_XS_PATH(gc, dm_domid, domid,
                                             "/logdirty/cmd");
        lds->ret_path = DEVICE_MODEL_XS_PATH(gc, dm_domid, domid,
                                             "/logdirty/ret");
    }
    lds->cmd = enable ? "enable" : "disable";

    rc = libxl__ev_xswatch_register(gc, &lds->watch,
                                switch_logdirty_xswatch, lds->ret_path);
    if (rc) goto out;

    rc = libxl__ev_time_register_rel(ao, &lds->timeout,
                                switch_logdirty_timeout, 10*1000);
    if (rc) goto out;

    for (;;) {
        rc = libxl__xs_transaction_start(gc, &t);
        if (rc) goto out;

        rc = libxl__xs_read_checked(gc, t, lds->cmd_path, &got);
        if (rc) goto out;

        if (got) {
            const char *got_ret;
            rc = libxl__xs_read_checked(gc, t, lds->ret_path, &got_ret);
            if (rc) goto out;

            if (!got_ret || strcmp(got, got_ret)) {
                LOG(ERROR,"controlling logdirty: qemu was already sent"
                    " command `%s' (xenstore path `%s') but result is `%s'",
                    got, lds->cmd_path, got_ret ? got_ret : "<none>");
                rc = ERROR_FAIL;
                goto out;
            }
            rc = libxl__xs_rm_checked(gc, t, lds->cmd_path);
            if (rc) goto out;
        }

        rc = libxl__xs_rm_checked(gc, t, lds->ret_path);
        if (rc) goto out;

        rc = libxl__xs_write_checked(gc, t, lds->cmd_path, lds->cmd);
        if (rc) goto out;

        rc = libxl__xs_transaction_commit(gc, &t);
        if (!rc) break;
        if (rc<0) goto out;
    }

    /* OK, wait for some callback */
    return;

 out:
    LOG(ERROR,"logdirty switch failed (rc=%d), abandoning suspend",rc);
    libxl__xs_transaction_abort(gc, &t);
    switch_logdirty_done(egc,lds,rc);
}
예제 #5
0
/*
 * In return, the script writes the name of REMUS_IFB device (during setup)
 * to be used for output buffering into XENBUS_PATH/ifb
 */
static void netbuf_setup_script_cb(libxl__egc *egc,
                                   libxl__async_exec_state *aes,
                                   int rc, int status)
{
    libxl__ao_device *aodev = CONTAINER_OF(aes, *aodev, aes);
    libxl__checkpoint_device *dev = CONTAINER_OF(aodev, *dev, aodev);
    libxl__remus_device_nic *remus_nic = dev->concrete_data;
    libxl__checkpoint_devices_state *cds = dev->cds;
    libxl__remus_state *rs = cds->concrete_data;
    const char *out_path_base, *hotplug_error = NULL;

    STATE_AO_GC(cds->ao);

    /* Convenience aliases */
    const uint32_t domid = cds->domid;
    const int devid = remus_nic->devid;
    const char *const vif = remus_nic->vif;
    const char **const ifb = &remus_nic->ifb;

    if (status && !rc)
        rc = ERROR_FAIL;
    if (rc)
        goto out;

    /*
     * we need to get ifb first because it's needed for teardown
     */
    rc = libxl__xs_read_checked(gc, XBT_NULL,
                                GCSPRINTF("%s/remus/netbuf/%d/ifb",
                                          libxl__xs_libxl_path(gc, domid),
                                          devid),
                                ifb);
    if (rc)
        goto out;

    if (!(*ifb)) {
        LOGD(ERROR, domid, "Cannot get ifb dev name for domain %u dev %s",
             domid, vif);
        rc = ERROR_FAIL;
        goto out;
    }

    out_path_base = GCSPRINTF("%s/remus/netbuf/%d",
                              libxl__xs_libxl_path(gc, domid), devid);

    rc = libxl__xs_read_checked(gc, XBT_NULL,
                                GCSPRINTF("%s/hotplug-error", out_path_base),
                                &hotplug_error);
    if (rc)
        goto out;

    if (hotplug_error) {
        LOGD(ERROR, domid, "netbuf script %s setup failed for vif %s: %s",
             rs->netbufscript, vif, hotplug_error);
        rc = ERROR_FAIL;
        goto out;
    }

    if (status) {
        rc = ERROR_FAIL;
        goto out;
    }

    LOGD(DEBUG, domid, "%s will buffer packets from vif %s", *ifb, vif);
    rc = init_qdisc(cds, remus_nic);

out:
    aodev->rc = rc;
    aodev->callback(egc, aodev);
}
예제 #6
0
파일: libxl_nic.c 프로젝트: TressaOrg/xen
static int libxl__device_nic_from_xenstore(libxl__gc *gc,
                                           const char *libxl_path,
                                           libxl_device_nic *nic)
{
    const char *tmp;
    int rc;

    libxl_device_nic_init(nic);

    rc = libxl__xs_read_checked(gc, XBT_NULL,
                                GCSPRINTF("%s/handle", libxl_path), &tmp);
    if (rc) goto out;
    if (tmp)
        nic->devid = atoi(tmp);
    else
        nic->devid = 0;

    /* nic->mtu = */

    rc = libxl__xs_read_checked(gc, XBT_NULL,
                                GCSPRINTF("%s/mac", libxl_path), &tmp);
    if (rc) goto out;
    if (tmp) {
        rc = libxl__parse_mac(tmp, nic->mac);
        if (rc) goto out;
    } else {
        memset(nic->mac, 0, sizeof(nic->mac));
    }

    rc = libxl__xs_read_checked(NOGC, XBT_NULL,
                                GCSPRINTF("%s/ip", libxl_path),
                                (const char **)(&nic->ip));
    if (rc) goto out;
    rc = libxl__xs_read_checked(NOGC, XBT_NULL,
                                GCSPRINTF("%s/bridge", libxl_path),
                                (const char **)(&nic->bridge));
    if (rc) goto out;
    rc = libxl__xs_read_checked(NOGC, XBT_NULL,
                                GCSPRINTF("%s/script", libxl_path),
                                (const char **)(&nic->script));
    if (rc) goto out;
    rc = libxl__xs_read_checked(NOGC, XBT_NULL,
                                GCSPRINTF("%s/forwarddev", libxl_path),
                                (const char **)(&nic->coloft_forwarddev));
    if (rc) goto out;

    /* vif_ioemu nics use the same xenstore entries as vif interfaces */
    rc = libxl__xs_read_checked(gc, XBT_NULL,
                                GCSPRINTF("%s/type", libxl_path), &tmp);
    if (rc) goto out;
    if (tmp) {
        rc = libxl_nic_type_from_string(tmp, &nic->nictype);
        if (rc) goto out;
    } else {
        nic->nictype = LIBXL_NIC_TYPE_VIF;
    }
    nic->model = NULL; /* XXX Only for TYPE_IOEMU */
    nic->ifname = NULL; /* XXX Only for TYPE_IOEMU */

    rc = 0;
 out:
    return rc;
}