Exemplo n.º 1
0
/*
 * the script needs the following env & args
 * $vifname
 * $XENBUS_PATH (/libxl/<domid>/remus/netbuf/<devid>/)
 * $REMUS_IFB (for teardown)
 * setup/teardown as command line arg.
 */
static void setup_async_exec(libxl__checkpoint_device *dev, char *op)
{
    int arraysize, nr = 0;
    char **env = NULL, **args = NULL;
    libxl__remus_device_nic *remus_nic = dev->concrete_data;
    libxl__checkpoint_devices_state *cds = dev->cds;
    libxl__async_exec_state *aes = &dev->aodev.aes;
    libxl__remus_state *rs = cds->concrete_data;

    STATE_AO_GC(cds->ao);

    /* Convenience aliases */
    char *const script = libxl__strdup(gc, rs->netbufscript);
    const uint32_t domid = cds->domid;
    const int dev_id = remus_nic->devid;
    const char *const vif = remus_nic->vif;
    const char *const ifb = remus_nic->ifb;

    arraysize = 7;
    GCNEW_ARRAY(env, arraysize);
    env[nr++] = "vifname";
    env[nr++] = libxl__strdup(gc, vif);
    env[nr++] = "XENBUS_PATH";
    env[nr++] = GCSPRINTF("%s/remus/netbuf/%d",
                          libxl__xs_libxl_path(gc, domid), dev_id);
    if (!strcmp(op, "teardown") && ifb) {
        env[nr++] = "REMUS_IFB";
        env[nr++] = libxl__strdup(gc, ifb);
    }
    env[nr++] = NULL;
    assert(nr <= arraysize);

    arraysize = 3; nr = 0;
    GCNEW_ARRAY(args, arraysize);
    args[nr++] = script;
    args[nr++] = op;
    args[nr++] = NULL;
    assert(nr == arraysize);

    aes->ao = dev->cds->ao;
    aes->what = GCSPRINTF("%s %s", args[0], args[1]);
    aes->env = env;
    aes->args = args;
    aes->timeout_ms = LIBXL_HOTPLUG_TIMEOUT * 1000;
    aes->stdfds[0] = -1;
    aes->stdfds[1] = -1;
    aes->stdfds[2] = -1;

    if (!strcmp(op, "teardown"))
        aes->callback = netbuf_teardown_script_cb;
    else
        aes->callback = netbuf_setup_script_cb;
}
Exemplo n.º 2
0
/* Hotplug scripts caller functions */
static int libxl__hotplug(libxl__gc *gc, libxl__device *dev, char ***args,
                          libxl__device_action action)
{
    char *be_path = libxl__device_backend_path(gc, dev);
    char *script;
    int nr = 0, rc = 0, arraysize = 4;

    script = libxl__xs_read(gc, XBT_NULL,
                            GCSPRINTF("%s/%s", be_path, "script"));
    if (!script) {
        LOGEV(ERROR, errno, "unable to read script from %s", be_path);
        rc = ERROR_FAIL;
        goto out;
    }

    GCNEW_ARRAY(*args, arraysize);
    (*args)[nr++] = script;
    (*args)[nr++] = be_path;
    (*args)[nr++] = GCSPRINTF("%d", action == LIBXL__DEVICE_ACTION_ADD ?
                                    XenbusStateInitWait : XenbusStateClosed);
    (*args)[nr++] = NULL;
    assert(nr == arraysize);

out:
    return rc;
}
Exemplo n.º 3
0
static int libxl__hotplug_disk(libxl__gc *gc, libxl__device *dev,
                               char ***args, char ***env,
                               libxl__device_action action)
{
    char *be_path = libxl__device_backend_path(gc, dev);
    char *script;
    int nr = 0, rc = 0;

    script = libxl__xs_read(gc, XBT_NULL,
                            GCSPRINTF("%s/%s", be_path, "script"));
    if (!script) {
        LOGEV(ERROR, errno, "unable to read script from %s", be_path);
        rc = ERROR_FAIL;
        goto error;
    }

    *env = get_hotplug_env(gc, script, dev);
    if (!*env) {
        rc = ERROR_FAIL;
        goto error;
    }

    const int arraysize = 3;
    GCNEW_ARRAY(*args, arraysize);
    (*args)[nr++] = script;
    (*args)[nr++] = action == DEVICE_CONNECT ? "add" : "remove";
    (*args)[nr++] = NULL;
    assert(nr == arraysize);

    rc = 1;

error:
    return rc;
}
Exemplo n.º 4
0
/* Set the RTDS scheduling parameters of vcpu(s) */
static int sched_rtds_vcpu_set(libxl__gc *gc, uint32_t domid,
                               const libxl_vcpu_sched_params *scinfo)
{
    int r, rc;
    int i;
    uint16_t max_vcpuid;
    xc_dominfo_t info;
    struct xen_domctl_schedparam_vcpu *vcpus;

    r = xc_domain_getinfo(CTX->xch, domid, 1, &info);
    if (r < 0) {
        LOGED(ERROR, domid, "Getting domain info");
        rc = ERROR_FAIL;
        goto out;
    }
    max_vcpuid = info.max_vcpu_id;

    if (scinfo->num_vcpus <= 0) {
        rc = ERROR_INVAL;
        goto out;
    }
    for (i = 0; i < scinfo->num_vcpus; i++) {
        if (scinfo->vcpus[i].vcpuid < 0 ||
            scinfo->vcpus[i].vcpuid > max_vcpuid) {
            LOGD(ERROR, domid, "Invalid VCPU %d: valid range is [0, %d]",
                        scinfo->vcpus[i].vcpuid, max_vcpuid);
            rc = ERROR_INVAL;
            goto out;
        }
        rc = sched_rtds_validate_params(gc, scinfo->vcpus[i].period,
                                        scinfo->vcpus[i].budget);
        if (rc) {
            rc = ERROR_INVAL;
            goto out;
        }
    }
    GCNEW_ARRAY(vcpus, scinfo->num_vcpus);
    for (i = 0; i < scinfo->num_vcpus; i++) {
        vcpus[i].vcpuid = scinfo->vcpus[i].vcpuid;
        vcpus[i].u.rtds.period = scinfo->vcpus[i].period;
        vcpus[i].u.rtds.budget = scinfo->vcpus[i].budget;
    }

    r = xc_sched_rtds_vcpu_set(CTX->xch, domid,
                               vcpus, scinfo->num_vcpus);
    if (r != 0) {
        LOGED(ERROR, domid, "Setting vcpu sched rtds");
        rc = ERROR_FAIL;
        goto out;
    }
    rc = 0;
out:
    return rc;
}
Exemplo n.º 5
0
static int libxl__hotplug_nic(libxl__gc *gc, libxl__device *dev,
                               char ***args, char ***env,
                               libxl__device_action action, int num_exec)
{
    char *be_path = libxl__device_backend_path(gc, dev);
    char *script;
    int nr = 0, rc = 0;
    libxl_nic_type nictype;

    script = libxl__xs_read(gc, XBT_NULL, GCSPRINTF("%s/%s", be_path,
                                                             "script"));
    if (!script) {
        LOGE(ERROR, "unable to read script from %s", be_path);
        rc = ERROR_FAIL;
        goto out;
    }

    rc = libxl__nic_type(gc, dev, &nictype);
    if (rc) {
        LOG(ERROR, "error when fetching nic type");
        rc = ERROR_FAIL;
        goto out;
    }
    if (nictype == LIBXL_NIC_TYPE_VIF && num_exec != 0) {
        rc = 0;
        goto out;
    }

    *env = get_hotplug_env(gc, script, dev);
    if (!env) {
        rc = ERROR_FAIL;
        goto out;
    }

    const int arraysize = 4;
    GCNEW_ARRAY(*args, arraysize);
    (*args)[nr++] = script;

    if (nictype == LIBXL_NIC_TYPE_VIF_IOEMU && num_exec) {
        (*args)[nr++] = action == DEVICE_CONNECT ? "add" : "remove";
        (*args)[nr++] = "type_if=tap";
        (*args)[nr++] = NULL;
    } else {
        (*args)[nr++] = action == DEVICE_CONNECT ? "online" : "offline";
        (*args)[nr++] = "type_if=vif";
        (*args)[nr++] = NULL;
    }
    assert(nr == arraysize);
    rc = 1;

out:
    return rc;
}
Exemplo n.º 6
0
static void match_async_exec(libxl__egc *egc, libxl__remus_device *dev)
{
    int arraysize, nr = 0, rc;
    const libxl_device_disk *disk = dev->backend_dev;
    libxl__async_exec_state *aes = &dev->aodev.aes;
    STATE_AO_GC(dev->rds->ao);

    /* setup env & args */
    arraysize = 1;
    GCNEW_ARRAY(aes->env, arraysize);
    aes->env[nr++] = NULL;
    assert(nr <= arraysize);

    arraysize = 3;
    nr = 0;
    GCNEW_ARRAY(aes->args, arraysize);
    aes->args[nr++] = dev->rds->drbd_probe_script;
    aes->args[nr++] = disk->pdev_path;
    aes->args[nr++] = NULL;
    assert(nr <= arraysize);

    aes->ao = dev->rds->ao;
    aes->what = GCSPRINTF("%s %s", aes->args[0], aes->args[1]);
    aes->timeout_ms = LIBXL_HOTPLUG_TIMEOUT * 1000;
    aes->callback = match_async_exec_cb;
    aes->stdfds[0] = -1;
    aes->stdfds[1] = -1;
    aes->stdfds[2] = -1;

    rc = libxl__async_exec_start(gc, aes);
    if (rc)
        goto out;

    return;

out:
    dev->aodev.rc = rc;
    dev->aodev.callback(egc, &dev->aodev);
}
Exemplo n.º 7
0
/* Get the RTDS scheduling parameters of vcpu(s) */
static int sched_rtds_vcpu_get(libxl__gc *gc, uint32_t domid,
                               libxl_vcpu_sched_params *scinfo)
{
    uint32_t num_vcpus;
    int i, r, rc;
    xc_dominfo_t info;
    struct xen_domctl_schedparam_vcpu *vcpus;

    r = xc_domain_getinfo(CTX->xch, domid, 1, &info);
    if (r < 0) {
        LOGED(ERROR, domid, "Getting domain info");
        rc = ERROR_FAIL;
        goto out;
    }

    if (scinfo->num_vcpus <= 0) {
        rc = ERROR_INVAL;
        goto out;
    } else {
        num_vcpus = scinfo->num_vcpus;
        GCNEW_ARRAY(vcpus, num_vcpus);
        for (i = 0; i < num_vcpus; i++) {
            if (scinfo->vcpus[i].vcpuid < 0 ||
                scinfo->vcpus[i].vcpuid > info.max_vcpu_id) {
                LOGD(ERROR, domid, "VCPU index is out of range, "
                            "valid values are within range from 0 to %d",
                            info.max_vcpu_id);
                rc = ERROR_INVAL;
                goto out;
            }
            vcpus[i].vcpuid = scinfo->vcpus[i].vcpuid;
        }
    }

    r = xc_sched_rtds_vcpu_get(CTX->xch, domid, vcpus, num_vcpus);
    if (r != 0) {
        LOGED(ERROR, domid, "Getting vcpu sched rtds");
        rc = ERROR_FAIL;
        goto out;
    }
    scinfo->sched = LIBXL_SCHEDULER_RTDS;
    for (i = 0; i < num_vcpus; i++) {
        scinfo->vcpus[i].period = vcpus[i].u.rtds.period;
        scinfo->vcpus[i].budget = vcpus[i].u.rtds.budget;
        scinfo->vcpus[i].vcpuid = vcpus[i].vcpuid;
    }
    rc = 0;
out:
    return rc;
}
Exemplo n.º 8
0
/* Set the RTDS scheduling parameters of all vcpus of a domain */
static int sched_rtds_vcpu_set_all(libxl__gc *gc, uint32_t domid,
                                   const libxl_vcpu_sched_params *scinfo)
{
    int r, rc;
    int i;
    uint16_t max_vcpuid;
    xc_dominfo_t info;
    struct xen_domctl_schedparam_vcpu *vcpus;
    uint32_t num_vcpus;

    r = xc_domain_getinfo(CTX->xch, domid, 1, &info);
    if (r < 0) {
        LOGED(ERROR, domid, "Getting domain info");
        rc = ERROR_FAIL;
        goto out;
    }
    max_vcpuid = info.max_vcpu_id;

    if (scinfo->num_vcpus != 1) {
        rc = ERROR_INVAL;
        goto out;
    }
    if (sched_rtds_validate_params(gc, scinfo->vcpus[0].period,
                                   scinfo->vcpus[0].budget)) {
        rc = ERROR_INVAL;
        goto out;
    }
    num_vcpus = max_vcpuid + 1;
    GCNEW_ARRAY(vcpus, num_vcpus);
    for (i = 0; i < num_vcpus; i++) {
        vcpus[i].vcpuid = i;
        vcpus[i].u.rtds.period = scinfo->vcpus[0].period;
        vcpus[i].u.rtds.budget = scinfo->vcpus[0].budget;
    }

    r = xc_sched_rtds_vcpu_set(CTX->xch, domid,
                               vcpus, num_vcpus);
    if (r != 0) {
        LOGED(ERROR, domid, "Setting vcpu sched rtds");
        rc = ERROR_FAIL;
        goto out;
    }
    rc = 0;
out:
    return rc;
}
Exemplo n.º 9
0
/* Get the RTDS scheduling parameters of all vcpus of a domain */
static int sched_rtds_vcpu_get_all(libxl__gc *gc, uint32_t domid,
                                   libxl_vcpu_sched_params *scinfo)
{
    uint32_t num_vcpus;
    int i, r, rc;
    xc_dominfo_t info;
    struct xen_domctl_schedparam_vcpu *vcpus;

    r = xc_domain_getinfo(CTX->xch, domid, 1, &info);
    if (r < 0) {
        LOGED(ERROR, domid, "Getting domain info");
        rc = ERROR_FAIL;
        goto out;
    }

    if (scinfo->num_vcpus > 0) {
        rc = ERROR_INVAL;
        goto out;
    } else {
        num_vcpus = info.max_vcpu_id + 1;
        GCNEW_ARRAY(vcpus, num_vcpus);
        for (i = 0; i < num_vcpus; i++)
            vcpus[i].vcpuid = i;
    }

    r = xc_sched_rtds_vcpu_get(CTX->xch, domid, vcpus, num_vcpus);
    if (r != 0) {
        LOGED(ERROR, domid, "Getting vcpu sched rtds");
        rc = ERROR_FAIL;
        goto out;
    }
    scinfo->sched = LIBXL_SCHEDULER_RTDS;
    scinfo->num_vcpus = num_vcpus;
    scinfo->vcpus = libxl__calloc(NOGC, num_vcpus,
                                  sizeof(libxl_sched_params));

    for (i = 0; i < num_vcpus; i++) {
        scinfo->vcpus[i].period = vcpus[i].u.rtds.period;
        scinfo->vcpus[i].budget = vcpus[i].u.rtds.budget;
        scinfo->vcpus[i].vcpuid = vcpus[i].vcpuid;
    }
    rc = 0;
out:
    return rc;
}
Exemplo n.º 10
0
Arquivo: libxl_dm.c Projeto: jsgf/xen
static void libxl__dm_vifs_from_hvm_guest_config(libxl__gc *gc,
                                    libxl_domain_config * const guest_config,
                                    libxl_domain_config *dm_config)
{
    int i, nr = guest_config->num_nics;

    GCNEW_ARRAY(dm_config->nics, nr);

    for (i=0; i<nr; i++) {
        dm_config->nics[i] = guest_config->nics[i];
        dm_config->nics[i].nictype = LIBXL_NIC_TYPE_VIF;
        if (dm_config->nics[i].ifname)
            dm_config->nics[i].ifname = GCSPRINTF("%s" TAP_DEVICE_SUFFIX,
                                                  dm_config->nics[i].ifname);
    }

    dm_config->num_nics = nr;
}
Exemplo n.º 11
0
void libxl__remus_devices_setup(libxl__egc *egc, libxl__remus_devices_state *rds)
{
    int i, rc;

    STATE_AO_GC(rds->ao);

    rc = init_device_subkind(rds);
    if (rc)
        goto out;

    rds->num_devices = 0;
    rds->num_nics = 0;
    rds->num_disks = 0;

    if (rds->device_kind_flags & (1 << LIBXL__DEVICE_KIND_VIF))
        rds->nics = libxl_device_nic_list(CTX, rds->domid, &rds->num_nics);

    if (rds->device_kind_flags & (1 << LIBXL__DEVICE_KIND_VBD))
        rds->disks = libxl_device_disk_list(CTX, rds->domid, &rds->num_disks);

    if (rds->num_nics == 0 && rds->num_disks == 0)
        goto out;

    GCNEW_ARRAY(rds->devs, rds->num_nics + rds->num_disks);

    for (i = 0; i < rds->num_nics; i++) {
        rds->devs[rds->num_devices++] = remus_device_init(egc, rds,
                                                LIBXL__DEVICE_KIND_VIF,
                                                &rds->nics[i]);
    }

    for (i = 0; i < rds->num_disks; i++) {
        rds->devs[rds->num_devices++] = remus_device_init(egc, rds,
                                                LIBXL__DEVICE_KIND_VBD,
                                                &rds->disks[i]);
    }

    remus_devices_setup(egc, rds);

    return;

out:
    rds->callback(egc, rds, rc);
}
Exemplo n.º 12
0
void libxl__checkpoint_devices_setup(libxl__egc *egc,
                                     libxl__checkpoint_devices_state *cds)
{
    int i;

    STATE_AO_GC(cds->ao);

    cds->num_devices = 0;
    cds->num_nics = 0;
    cds->num_disks = 0;

    if (cds->device_kind_flags & (1 << LIBXL__DEVICE_KIND_VIF))
        cds->nics = libxl_device_nic_list(CTX, cds->domid, &cds->num_nics);

    if (cds->device_kind_flags & (1 << LIBXL__DEVICE_KIND_VBD))
        cds->disks = libxl_device_disk_list(CTX, cds->domid, &cds->num_disks);

    if (cds->num_nics == 0 && cds->num_disks == 0)
        goto out;

    GCNEW_ARRAY(cds->devs, cds->num_nics + cds->num_disks);

    for (i = 0; i < cds->num_nics; i++) {
        cds->devs[cds->num_devices++] = checkpoint_device_init(egc, cds,
                                                LIBXL__DEVICE_KIND_VIF,
                                                &cds->nics[i]);
    }

    for (i = 0; i < cds->num_disks; i++) {
        cds->devs[cds->num_devices++] = checkpoint_device_init(egc, cds,
                                                LIBXL__DEVICE_KIND_VBD,
                                                &cds->disks[i]);
    }

    checkpoint_devices_setup(egc, cds);

    return;

out:
    cds->callback(egc, cds, 0);
}
Exemplo n.º 13
0
static void make_bootloader_args(libxl__gc *gc, libxl__bootloader_state *bl,
                                 const char *bootloader_path)
{
    const libxl_domain_build_info *info = bl->info;

    bl->argsspace = 7 + libxl_string_list_length(&info->u.pv.bootloader_args);

    GCNEW_ARRAY(bl->args, bl->argsspace);

#define ARG(arg) bootloader_arg(bl, (arg))

    ARG(bootloader_path);

    if (info->u.pv.kernel)
        ARG(libxl__sprintf(gc, "--kernel=%s", info->u.pv.kernel));
    if (info->u.pv.ramdisk)
        ARG(libxl__sprintf(gc, "--ramdisk=%s", info->u.pv.ramdisk));
    if (info->u.pv.cmdline && *info->u.pv.cmdline != '\0')
        ARG(libxl__sprintf(gc, "--args=%s", info->u.pv.cmdline));

    ARG(libxl__sprintf(gc, "--output=%s", bl->outputpath));
    ARG("--output-format=simple0");
    ARG(libxl__sprintf(gc, "--output-directory=%s", bl->outputdir));

    if (info->u.pv.bootloader_args) {
        char **p = info->u.pv.bootloader_args;
        while (*p) {
            ARG(*p);
            p++;
        }
    }

    ARG(bl->dls.diskpath);

    /* Sentinel for execv */
    ARG(NULL);

#undef ARG
}