Beispiel #1
0
int
xenapiUtil_ParseQuery(virConnectPtr conn, virURIPtr uri, int *noVerify)
{
    int result = 0;
    size_t i;

    for (i = 0; i < uri->paramsCount; i++) {
        virURIParamPtr queryParam = &uri->params[i];
        if (STRCASEEQ(queryParam->name, "no_verify")) {
            if (noVerify == NULL) {
                continue;
            }
            if (virStrToLong_i(queryParam->value, NULL, 10, noVerify) < 0 ||
                    (*noVerify != 0 && *noVerify != 1)) {
                xenapiSessionErrorHandler(conn, VIR_ERR_INVALID_ARG,
                                          _("Query parameter 'no_verify' has unexpected value (should be 0 or 1)"));
                goto failure;
            }
        }
    }

cleanup:

    return result;

failure:
    result = -1;

    goto cleanup;
}
Beispiel #2
0
static int openvzAssignUUIDs(void)
{
    DIR *dp;
    struct dirent *dent;
    char *conf_dir;
    int vpsid;
    char *ext;
    int ret = 0;

    conf_dir = openvzLocateConfDir();
    if (conf_dir == NULL)
        return -1;

    dp = opendir(conf_dir);
    if (dp == NULL) {
        VIR_FREE(conf_dir);
        return 0;
    }

    while ((ret = virDirRead(dp, &dent, conf_dir)) > 0) {
        if (virStrToLong_i(dent->d_name, &ext, 10, &vpsid) < 0 ||
            *ext++ != '.' ||
            STRNEQ(ext, "conf"))
            continue;
        if (vpsid > 0) /* '0.conf' belongs to the host, ignore it */
            openvzSetUUID(vpsid);
    }

    closedir(dp);
    VIR_FREE(conf_dir);
    return ret;
}
Beispiel #3
0
/* Determine the maximum cpu id from a Linux sysfs cpu/present file. */
static int
linuxParseCPUmax(const char *path)
{
    char *str = NULL;
    char *tmp;
    int ret = -1;

    if (virFileReadAll(path, 5 * VIR_DOMAIN_CPUMASK_LEN, &str) < 0)
        goto cleanup;

    tmp = str;
    do {
        if (virStrToLong_i(tmp, &tmp, 10, &ret) < 0 ||
            !strchr(",-\n", *tmp)) {
            virReportError(VIR_ERR_NO_SUPPORT,
                           _("failed to parse %s"), path);
            ret = -1;
            goto cleanup;
        }
    } while (*tmp++ != '\n');
    ret++;

cleanup:
    VIR_FREE(str);
    return ret;
}
int
virStorageBackendSheepdogParseVdiList(virStorageVolDefPtr vol,
                                      char *output)
{
    /* fields:
     * current/clone/snapshot, name, id, size, used, shared, creation time, vdi id, [tag]
     *
     * example output:
     * s test 1 10 0 0 1336556634 7c2b25
     * s test 2 10 0 0 1336557203 7c2b26
     * = test 3 10 0 0 1336557216 7c2b27
     */

    int id;
    const char *p, *next;

    vol->allocation = vol->capacity = 0;

    p = output;
    do {
        char *end;

        if ((next = strchr(p, '\n')))
            ++next;

        /* ignore snapshots */
        if (*p != '=')
            continue;

        /* skip space */
        if (p + 2 < next)
            p += 2;
        else
            return -1;

        /* skip name */
        while (*p != '\0' && *p != ' ') {
            if (*p == '\\')
                ++p;
            ++p;
        }

        if (virStrToLong_i(p, &end, 10, &id) < 0)
            return -1;

        p = end + 1;

        if (virStrToLong_ull(p, &end, 10, &vol->capacity) < 0)
            return -1;

        p = end + 1;

        if (virStrToLong_ull(p, &end, 10, &vol->allocation) < 0)
            return -1;

        return 0;
    } while ((p = next));

    return -1;
}
Beispiel #5
0
static int
disk_re_match(const char *regex, const char *path, int *part)
{
    regex_t myreg;
    int err;
    int retval;
    regmatch_t pmatch[3];

    retval = 0;

    err = regcomp(&myreg, regex, REG_EXTENDED);
    if (err != 0)
        return 0;

    err = regexec(&myreg, path, 3, pmatch, 0);

    if (err == 0) {
        /* OK, we have a match; see if we have a partition */
        *part = 0;
        retval = 1;
        if (pmatch[1].rm_so != -1) {
            if (virStrToLong_i(path + pmatch[1].rm_so, NULL, 10, part) < 0)
                retval = 0;
        }
    }

    regfree(&myreg);

    return retval;
}
Beispiel #6
0
int virJSONValueGetNumberInt(virJSONValuePtr number, int *value)
{
    if (number->type != VIR_JSON_TYPE_NUMBER)
        return -1;

    return virStrToLong_i(number->data.number, NULL, 10, value);
}
Beispiel #7
0
int openvzGetVEID(const char *name)
{
    virCommandPtr cmd;
    char *outbuf;
    char *temp;
    int veid;
    bool ok;

    cmd = virCommandNewArgList(VZLIST, name, "-ovpsid", "-H", NULL);
    virCommandSetOutputBuffer(cmd, &outbuf);
    if (virCommandRun(cmd, NULL) < 0) {
        virCommandFree(cmd);
        VIR_FREE(outbuf);
        return -1;
    }

    virCommandFree(cmd);
    ok = virStrToLong_i(outbuf, &temp, 10, &veid) == 0 && *temp == '\n';
    VIR_FREE(outbuf);

    if (ok && veid >= 0)
        return veid;

    virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                   _("Failed to parse vzlist output"));
    return -1;
}
Beispiel #8
0
/* Function to check if the type file in the given sysfs_path is a
 * Direct-Access device (i.e. type 0).  Return -1 on failure, type of
 * the device otherwise.
 */
static int
getDeviceType(uint32_t host,
              uint32_t bus,
              uint32_t target,
              uint32_t lun,
              int *type)
{
    char *type_path = NULL;
    char typestr[3];
    char *gottype, *p;
    FILE *typefile;
    int retval = 0;

    if (virAsprintf(&type_path, "/sys/bus/scsi/devices/%u:%u:%u:%u/type",
                    host, bus, target, lun) < 0) {
        virReportOOMError();
        goto out;
    }

    typefile = fopen(type_path, "r");
    if (typefile == NULL) {
        virReportSystemError(errno,
                             _("Could not find typefile '%s'"),
                             type_path);
        /* there was no type file; that doesn't seem right */
        retval = -1;
        goto out;
    }

    gottype = fgets(typestr, 3, typefile);
    VIR_FORCE_FCLOSE(typefile);

    if (gottype == NULL) {
        virReportSystemError(errno,
                             _("Could not read typefile '%s'"),
                             type_path);
        /* we couldn't read the type file; have to give up */
        retval = -1;
        goto out;
    }

    /* we don't actually care about p, but if you pass NULL and the last
     * character is not \0, virStrToLong_i complains
     */
    if (virStrToLong_i(typestr, &p, 10, type) < 0) {
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("Device type '%s' is not an integer"),
                       typestr);
        /* Hm, type wasn't an integer; seems strange */
        retval = -1;
        goto out;
    }

    VIR_DEBUG("Device type is %d", *type);

out:
    VIR_FREE(type_path);
    return retval;
}
Beispiel #9
0
/* Some hosts can run guests in compatibility mode, but not all
 * host CPUs support this and not all combinations are valid.
 * This function performs the necessary checks */
static virCPUCompareResult
ppc64CheckCompatibilityMode(const char *host_model,
                            const char *compat_mode)
{
    int host;
    int compat;
    char *tmp;
    virCPUCompareResult ret = VIR_CPU_COMPARE_ERROR;

    if (!compat_mode)
        return VIR_CPU_COMPARE_IDENTICAL;

    /* Valid host CPUs: POWER6, POWER7, POWER8 */
    if (!STRPREFIX(host_model, "POWER") ||
        !(tmp = (char *) host_model + strlen("POWER")) ||
        virStrToLong_i(tmp, NULL, 10, &host) < 0 ||
        host < 6 || host > 8) {
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       "%s",
                       _("Host CPU does not support compatibility modes"));
        goto out;
    }

    /* Valid compatibility modes: power6, power7, power8 */
    if (!STRPREFIX(compat_mode, "power") ||
        !(tmp = (char *) compat_mode + strlen("power")) ||
        virStrToLong_i(tmp, NULL, 10, &compat) < 0 ||
        compat < 6 || compat > 8) {
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("Unknown compatibility mode %s"),
                       compat_mode);
        goto out;
    }

    /* Version check */
    if (compat > host)
        ret = VIR_CPU_COMPARE_INCOMPATIBLE;
    else
        ret = VIR_CPU_COMPARE_IDENTICAL;

 out:
    return ret;
}
Beispiel #10
0
int
strtoI(const char *str)
{
    int val;

    if (virStrToLong_i(str, NULL, 10, &val) < 0)
        return 0;

    return val;
}
Beispiel #11
0
static int openvzListDefinedDomains(virConnectPtr conn ATTRIBUTE_UNUSED,
                                    char **const names, int nnames) {
    int got = 0;
    int veid, outfd = -1, ret;
    int rc = -1;
    char vpsname[32];
    char buf[32];
    char *endptr;
    virCommandPtr cmd = virCommandNewArgList(VZLIST,
                                             "-ovpsid", "-H", "-S", NULL);

    /* the -S options lists only stopped domains */
    virCommandSetOutputFD(cmd, &outfd);
    if (virCommandRunAsync(cmd, NULL) < 0)
        goto out;

    while (got < nnames) {
        ret = openvz_readline(outfd, buf, 32);
        if (!ret)
            break;
        if (virStrToLong_i(buf, &endptr, 10, &veid) < 0) {
            openvzError(VIR_ERR_INTERNAL_ERROR,
                        _("Could not parse VPS ID %s"), buf);
            continue;
        }
        snprintf(vpsname, sizeof(vpsname), "%d", veid);
        if (!(names[got] = strdup(vpsname))) {
            virReportOOMError();
            goto out;
        }
        got ++;
    }

    if (virCommandWait(cmd, NULL) < 0)
        goto out;

    if (VIR_CLOSE(outfd) < 0) {
        virReportSystemError(errno, "%s", _("failed to close file"));
        goto out;
    }

    rc = got;
out:
    VIR_FORCE_CLOSE(outfd);
    virCommandFree(cmd);
    if (rc < 0) {
        for ( ; got >= 0 ; got--)
            VIR_FREE(names[got]);
    }
    return rc;
}
Beispiel #12
0
int
vmwareExtractPid(const char * vmxPath)
{
    char *vmxDir = NULL;
    char *logFilePath = NULL;
    FILE *logFile = NULL;
    char line[1024];
    char *tmp = NULL;
    int pid_value = -1;

    if ((vmxDir = mdir_name(vmxPath)) == NULL)
        goto cleanup;

    if (virAsprintf(&logFilePath, "%s/vmware.log",
                    vmxDir) < 0) {
        virReportOOMError();
        goto cleanup;
    }

    if ((logFile = fopen(logFilePath, "r")) == NULL)
        goto cleanup;

    if (!fgets(line, sizeof(line), logFile)) {
        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                       _("unable to read vmware log file"));
        goto cleanup;
    }

    if ((tmp = strstr(line, " pid=")) == NULL) {
        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                       _("cannot find pid in vmware log file"));
        goto cleanup;
    }

    tmp += strlen(" pid=");

    /* Although 64-bit windows allows 64-bit pid_t, a domain id has to be
     * 32 bits.  For now, we just reject pid values that overflow int.  */
    if (virStrToLong_i(tmp, &tmp, 10, &pid_value) < 0 || *tmp != ' ') {
        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                       _("cannot parse pid in vmware log file"));
        goto cleanup;
    }

cleanup:
    VIR_FREE(vmxDir);
    VIR_FREE(logFilePath);
    VIR_FORCE_FCLOSE(logFile);
    return pid_value;
}
Beispiel #13
0
int
qemuDomainDeviceAliasIndex(const virDomainDeviceInfo *info,
                           const char *prefix)
{
    int idx;

    if (!info->alias)
        return -1;
    if (!STRPREFIX(info->alias, prefix))
        return -1;

    if (virStrToLong_i(info->alias + strlen(prefix), NULL, 10, &idx) < 0)
        return -1;

    return idx;
}
Beispiel #14
0
static int udevStrToLong_i(char const *s,
                           char **end_ptr,
                           int base,
                           int *result)
{
    int ret = 0;

    ret = virStrToLong_i(s, end_ptr, base, result);
    if (ret != 0) {
        VIR_ERROR(_("Failed to convert '%s' to int"), s);
    } else {
        VIR_DEBUG("Converted '%s' to int %u", s, *result);
    }

    return ret;
}
Beispiel #15
0
int
xenapiUtil_ParseQuery(virConnectPtr conn, xmlURIPtr uri, int *noVerify)
{
    int result = 0;
    int i;
    struct qparam_set *queryParamSet = NULL;
    struct qparam *queryParam = NULL;

#ifdef HAVE_XMLURI_QUERY_RAW
    queryParamSet = qparam_query_parse(uri->query_raw);
#else
    queryParamSet = qparam_query_parse(uri->query);
#endif

    if (queryParamSet == NULL) {
        goto failure;
    }

    for (i = 0; i < queryParamSet->n; i++) {
        queryParam = &queryParamSet->p[i];
        if (STRCASEEQ(queryParam->name, "no_verify")) {
            if (noVerify == NULL) {
                continue;
            }
            if (virStrToLong_i(queryParam->value, NULL, 10, noVerify) < 0 ||
                (*noVerify != 0 && *noVerify != 1)) {
                xenapiSessionErrorHandler(conn, VIR_ERR_INVALID_ARG,
      _("Query parameter 'no_verify' has unexpected value (should be 0 or 1)"));
                goto failure;
            }
        }
    }

  cleanup:
    if (queryParamSet != NULL) {
        free_qparam_set(queryParamSet);
    }

    return result;

  failure:
    result = -1;

    goto cleanup;
}
Beispiel #16
0
/* obtains the CPU bitmap from the string passed */
void
getCpuBitMapfromString(char *mask, unsigned char *cpumap, int maplen)
{
    int pos;
    int max_bits = maplen * 8;
    char *num = NULL, *bp = NULL;
    bzero(cpumap, maplen);
    num = strtok_r(mask, ",", &bp);
    while (num != NULL) {
        if (virStrToLong_i(num, NULL, 10, &pos) < 0)
            return;
        if (pos < 0 || pos > max_bits - 1)
            VIR_WARN("number in str %d exceeds cpumap's max bits %d", pos, max_bits);
        else
            (cpumap)[pos / 8] |= (1 << (pos % 8));
        num = strtok_r(NULL, ",", &bp);
    }
}
Beispiel #17
0
static int
lxcCreateConsoles(virDomainDefPtr def, virConfPtr properties)
{
    VIR_AUTOFREE(char *) value = NULL;
    int nbttys = 0;
    virDomainChrDefPtr console;
    size_t i;

    if (virConfGetValueString(properties, "lxc.tty.max", &value) <= 0) {
        virResetLastError();

        /* Check for pre LXC 3.0 legacy key */
        if (virConfGetValueString(properties, "lxc.tty", &value) <= 0)
            return 0;
    }

    if (virStrToLong_i(value, NULL, 10, &nbttys) < 0) {
        virReportError(VIR_ERR_INTERNAL_ERROR, _("failed to parse int: '%s'"),
                       value);
        return -1;
    }

    if (VIR_ALLOC_N(def->consoles, nbttys) < 0)
        return -1;

    def->nconsoles = nbttys;
    for (i = 0; i < nbttys; i++) {
        if (!(console = virDomainChrDefNew(NULL)))
            goto error;

        console->deviceType = VIR_DOMAIN_CHR_DEVICE_TYPE_CONSOLE;
        console->targetType = VIR_DOMAIN_CHR_CONSOLE_TARGET_TYPE_LXC;
        console->target.port = i;
        console->source->type = VIR_DOMAIN_CHR_TYPE_PTY;

        def->consoles[i] = console;
    }

    return 0;

 error:
    virDomainChrDefFree(console);
    return -1;
}
Beispiel #18
0
static int openvzListDomains(virConnectPtr conn ATTRIBUTE_UNUSED,
                             int *ids, int nids) {
    int got = 0;
    int veid;
    int outfd = -1;
    int rc = -1;
    int ret;
    char buf[32];
    char *endptr;
    virCommandPtr cmd = virCommandNewArgList(VZLIST, "-ovpsid", "-H" , NULL);

    virCommandSetOutputFD(cmd, &outfd);
    if (virCommandRunAsync(cmd, NULL) < 0)
        goto cleanup;

    while (got < nids) {
        ret = openvz_readline(outfd, buf, 32);
        if (!ret)
            break;
        if (virStrToLong_i(buf, &endptr, 10, &veid) < 0) {
            openvzError(VIR_ERR_INTERNAL_ERROR,
                        _("Could not parse VPS ID %s"), buf);
            continue;
        }
        ids[got] = veid;
        got ++;
    }

    if (virCommandWait(cmd, NULL) < 0)
        goto cleanup;

    if (VIR_CLOSE(outfd) < 0) {
        virReportSystemError(errno, "%s", _("failed to close file"));
        goto cleanup;
    }

    rc = got;
cleanup:
    VIR_FORCE_CLOSE(outfd);
    virCommandFree(cmd);
    return rc;
}
Beispiel #19
0
/* Return the positive decimal contents of the given
 * DIR/cpu%u/FILE, or -1 on error.  If MISSING_OK and the
 * file could not be found, return 1 instead of an error; this is
 * because some machines cannot hot-unplug cpu0, or because
 * hot-unplugging is disabled.  */
static int
virNodeGetCpuValue(const char *dir, unsigned int cpu, const char *file,
                   bool missing_ok)
{
    char *path;
    FILE *pathfp;
    int value = -1;
    char value_str[INT_BUFSIZE_BOUND(value)];
    char *tmp;

    if (virAsprintf(&path, "%s/cpu%u/%s", dir, cpu, file) < 0) {
        virReportOOMError();
        return -1;
    }

    pathfp = fopen(path, "r");
    if (pathfp == NULL) {
        if (missing_ok && errno == ENOENT)
            value = 1;
        else
            virReportSystemError(errno, _("cannot open %s"), path);
        goto cleanup;
    }

    if (fgets(value_str, sizeof(value_str), pathfp) == NULL) {
        virReportSystemError(errno, _("cannot read from %s"), path);
        goto cleanup;
    }
    if (virStrToLong_i(value_str, &tmp, 10, &value) < 0) {
        nodeReportError(VIR_ERR_INTERNAL_ERROR,
                        _("could not convert '%s' to an integer"),
                        value_str);
        goto cleanup;
    }

cleanup:
    VIR_FORCE_FCLOSE(pathfp);
    VIR_FREE(path);

    return value;
}
Beispiel #20
0
static int openvzAssignUUIDs(void)
{
    DIR *dp;
    struct dirent *dent;
    char *conf_dir;
    int vpsid;
    char *ext;
    int ret = 0;

    conf_dir = openvzLocateConfDir();
    if (conf_dir == NULL)
        return -1;

    dp = opendir(conf_dir);
    if (dp == NULL) {
        VIR_FREE(conf_dir);
        return 0;
    }

    errno = 0;
    while ((dent = readdir(dp))) {
        if (virStrToLong_i(dent->d_name, &ext, 10, &vpsid) < 0 ||
            *ext++ != '.' ||
            STRNEQ(ext, "conf"))
            continue;
        if (vpsid > 0) /* '0.conf' belongs to the host, ignore it */
            openvzSetUUID(vpsid);
        errno = 0;
    }
    if (errno) {
        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                       _("Failed to scan configuration directory"));
        ret = -1;
    }

    closedir(dp);
    VIR_FREE(conf_dir);
    return ret;
}
Beispiel #21
0
int virIdentityGetUNIXUserID(virIdentityPtr ident,
                             uid_t *uid)
{
    int val;
    const char *userid;

    *uid = -1;
    if (virIdentityGetAttr(ident,
                           VIR_IDENTITY_ATTR_UNIX_USER_ID,
                           &userid) < 0)
        return -1;

    if (!userid)
        return -1;

    if (virStrToLong_i(userid, NULL, 10, &val) < 0)
        return -1;

    *uid = (uid_t)val;

    return 0;
}
Beispiel #22
0
int virIdentityGetUNIXGroupID(virIdentityPtr ident,
                              gid_t *gid)
{
    int val;
    const char *groupid;

    *gid = -1;
    if (virIdentityGetAttr(ident,
                           VIR_IDENTITY_ATTR_UNIX_GROUP_ID,
                           &groupid) < 0)
        return -1;

    if (!groupid)
        return -1;

    if (virStrToLong_i(groupid, NULL, 10, &val) < 0)
        return -1;

    *gid = (gid_t)val;

    return 0;
}
Beispiel #23
0
static int
virNetDevIPGetAcceptRA(const char *ifname)
{
    char *path = NULL;
    char *buf = NULL;
    char *suffix;
    int accept_ra = -1;

    if (virAsprintf(&path, "/proc/sys/net/ipv6/conf/%s/accept_ra",
                    ifname ? ifname : "all") < 0)
        goto cleanup;

    if ((virFileReadAll(path, 512, &buf) < 0) ||
        (virStrToLong_i(buf, &suffix, 10, &accept_ra) < 0))
        goto cleanup;

 cleanup:
    VIR_FREE(path);
    VIR_FREE(buf);

    return accept_ra;
}
Beispiel #24
0
static int
lxcCreateConsoles(virDomainDefPtr def, virConfPtr properties)
{
    virConfValuePtr value;
    int nbttys = 0;
    virDomainChrDefPtr console;
    size_t i;

    if (!(value = virConfGetValue(properties, "lxc.tty")) || !value->str)
        return 0;

    if (virStrToLong_i(value->str, NULL, 10, &nbttys) < 0) {
        virReportError(VIR_ERR_INTERNAL_ERROR, _("failed to parse int: '%s'"),
                       value->str);
        return -1;
    }

    if (VIR_ALLOC_N(def->consoles, nbttys) < 0)
        return -1;

    def->nconsoles = nbttys;
    for (i = 0; i < nbttys; i++) {
        if (!(console = virDomainChrDefNew()))
            goto error;

        console->deviceType = VIR_DOMAIN_CHR_DEVICE_TYPE_CONSOLE;
        console->targetType = VIR_DOMAIN_CHR_CONSOLE_TARGET_TYPE_LXC;
        console->target.port = i;
        console->source.type = VIR_DOMAIN_CHR_TYPE_PTY;

        def->consoles[i] = console;
    }

    return 0;

 error:
    virDomainChrDefFree(console);
    return -1;
}
static int
virStorageBackendLogicalMakeVol(virStoragePoolObjPtr pool,
                                char **const groups,
                                void *data)
{
    virStorageVolDefPtr vol = NULL;
    bool is_new_vol = false;
    unsigned long long offset, size, length;
    const char *regex_unit = "(\\S+)\\((\\S+)\\)";
    char *regex = NULL;
    regex_t *reg = NULL;
    regmatch_t *vars = NULL;
    char *p = NULL;
    size_t i;
    int err, nextents, nvars, ret = -1;
    const char *attrs = groups[9];

    /* Skip inactive volume */
    if (attrs[4] != 'a')
        return 0;

    /*
     * Skip thin pools(t). These show up in normal lvs output
     * but do not have a corresponding /dev/$vg/$lv device that
     * is created by udev. This breaks assumptions in later code.
     */
    if (attrs[0] == 't')
        return 0;

    /* See if we're only looking for a specific volume */
    if (data != NULL) {
        vol = data;
        if (STRNEQ(vol->name, groups[0]))
            return 0;
    }

    /* Or filling in more data on an existing volume */
    if (vol == NULL)
        vol = virStorageVolDefFindByName(pool, groups[0]);

    /* Or a completely new volume */
    if (vol == NULL) {
        if (VIR_ALLOC(vol) < 0)
            return -1;

        is_new_vol = true;
        vol->type = VIR_STORAGE_VOL_BLOCK;

        if (VIR_STRDUP(vol->name, groups[0]) < 0)
            goto cleanup;

        if (VIR_REALLOC_N(pool->volumes.objs,
                          pool->volumes.count + 1))
            goto cleanup;
    }

    if (vol->target.path == NULL) {
        if (virAsprintf(&vol->target.path, "%s/%s",
                        pool->def->target.path, vol->name) < 0)
            goto cleanup;
    }

    /* Skips the backingStore of lv created with "--virtualsize",
     * its original device "/dev/$vgname/$lvname_vorigin" is
     * just for lvm internal use, one should never use it.
     *
     * (lvs outputs "[$lvname_vorigin] for field "origin" if the
     *  lv is created with "--virtualsize").
     */
    if (groups[1] && !STREQ(groups[1], "") && (groups[1][0] != '[')) {
        if (virAsprintf(&vol->backingStore.path, "%s/%s",
                        pool->def->target.path, groups[1]) < 0)
            goto cleanup;

        vol->backingStore.format = VIR_STORAGE_POOL_LOGICAL_LVM2;
    }

    if (!vol->key && VIR_STRDUP(vol->key, groups[2]) < 0)
        goto cleanup;

    if (virStorageBackendUpdateVolInfo(vol, 1) < 0)
        goto cleanup;

    nextents = 1;
    if (STREQ(groups[4], VIR_STORAGE_VOL_LOGICAL_SEGTYPE_STRIPED)) {
        if (virStrToLong_i(groups[5], NULL, 10, &nextents) < 0) {
            virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                           _("malformed volume extent stripes value"));
            goto cleanup;
        }
    }

    /* Finally fill in extents information */
    if (VIR_REALLOC_N(vol->source.extents,
                      vol->source.nextent + nextents) < 0)
        goto cleanup;

    if (virStrToLong_ull(groups[6], NULL, 10, &length) < 0) {
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       "%s", _("malformed volume extent length value"));
        goto cleanup;
    }
    if (virStrToLong_ull(groups[7], NULL, 10, &size) < 0) {
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       "%s", _("malformed volume extent size value"));
        goto cleanup;
    }
    if (virStrToLong_ull(groups[8], NULL, 10, &vol->allocation) < 0) {
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       "%s", _("malformed volume allocation value"));
        goto cleanup;
    }

    /* Now parse the "devices" field separately */
    if (VIR_STRDUP(regex, regex_unit) < 0)
        goto cleanup;

    for (i = 1; i < nextents; i++) {
        if (VIR_REALLOC_N(regex, strlen(regex) + strlen(regex_unit) + 2) < 0)
            goto cleanup;
        /* "," is the separator of "devices" field */
        strcat(regex, ",");
        strncat(regex, regex_unit, strlen(regex_unit));
    }

    if (VIR_ALLOC(reg) < 0)
        goto cleanup;

    /* Each extent has a "path:offset" pair, and vars[0] will
     * be the whole matched string.
     */
    nvars = (nextents * 2) + 1;
    if (VIR_ALLOC_N(vars, nvars) < 0)
        goto cleanup;

    err = regcomp(reg, regex, REG_EXTENDED);
    if (err != 0) {
        char error[100];
        regerror(err, reg, error, sizeof(error));
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("Failed to compile regex %s"),
                       error);
        goto cleanup;
    }

    err = regexec(reg, groups[3], nvars, vars, 0);
    regfree(reg);
    if (err != 0) {
        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                       _("malformed volume extent devices value"));
        goto cleanup;
    }

    p = groups[3];

    /* vars[0] is skipped */
    for (i = 0; i < nextents; i++) {
        size_t j;
        int len;
        char *offset_str = NULL;

        j = (i * 2) + 1;
        len = vars[j].rm_eo - vars[j].rm_so;
        p[vars[j].rm_eo] = '\0';

        if (VIR_STRNDUP(vol->source.extents[vol->source.nextent].path,
                        p + vars[j].rm_so, len) < 0)
            goto cleanup;

        len = vars[j + 1].rm_eo - vars[j + 1].rm_so;
        if (VIR_STRNDUP(offset_str, p + vars[j + 1].rm_so, len) < 0)
            goto cleanup;

        if (virStrToLong_ull(offset_str, NULL, 10, &offset) < 0) {
            virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                           _("malformed volume extent offset value"));
            VIR_FREE(offset_str);
            goto cleanup;
        }

        VIR_FREE(offset_str);

        vol->source.extents[vol->source.nextent].start = offset * size;
        vol->source.extents[vol->source.nextent].end = (offset * size) + length;
        vol->source.nextent++;
    }

    if (is_new_vol)
        pool->volumes.objs[pool->volumes.count++] = vol;

    ret = 0;

cleanup:
    VIR_FREE(regex);
    VIR_FREE(reg);
    VIR_FREE(vars);
    if (is_new_vol && (ret == -1))
        virStorageVolDefFree(vol);
    return ret;
}
Beispiel #26
0
/**
 * virBitmapParse:
 * @str: points to a string representing a human-readable bitmap
 * @terminator: character separating the bitmap to parse
 * @bitmap: a bitmap created from @str
 * @bitmapSize: the upper limit of num of bits in created bitmap
 *
 * This function is the counterpart of virBitmapFormat. This function creates
 * a bitmap, in which bits are set according to the content of @str.
 *
 * @str is a comma separated string of fields N, which means a number of bit
 * to set, and ^N, which means to unset the bit, and N-M for ranges of bits
 * to set.
 *
 * To allow parsing of bitmaps within larger strings it is possible to set
 * a termination character in the argument @terminator. When the character
 * in @terminator is encountered in @str, the parsing of the bitmap stops.
 * Pass 0 as @terminator if it is not needed. Whitespace characters may not
 * be used as terminators.
 *
 * Returns the number of bits set in @bitmap, or -1 in case of error.
 */
int
virBitmapParse(const char *str,
               char terminator,
               virBitmapPtr *bitmap,
               size_t bitmapSize)
{
    bool neg = false;
    const char *cur = str;
    char *tmp;
    size_t i;
    int start, last;

    if (!(*bitmap = virBitmapNew(bitmapSize)))
        return -1;

    if (!str)
        goto error;

    virSkipSpaces(&cur);

    if (*cur == '\0')
        goto error;

    while (*cur != 0 && *cur != terminator) {
        /*
         * 3 constructs are allowed:
         *     - N   : a single CPU number
         *     - N-M : a range of CPU numbers with N < M
         *     - ^N  : remove a single CPU number from the current set
         */
        if (*cur == '^') {
            cur++;
            neg = true;
        }

        if (!c_isdigit(*cur))
            goto error;

        if (virStrToLong_i(cur, &tmp, 10, &start) < 0)
            goto error;
        if (start < 0)
            goto error;

        cur = tmp;

        virSkipSpaces(&cur);

        if (*cur == ',' || *cur == 0 || *cur == terminator) {
            if (neg) {
                if (virBitmapClearBit(*bitmap, start) < 0)
                    goto error;
            } else {
                if (virBitmapSetBit(*bitmap, start) < 0)
                    goto error;
            }
        } else if (*cur == '-') {
            if (neg)
                goto error;

            cur++;
            virSkipSpaces(&cur);

            if (virStrToLong_i(cur, &tmp, 10, &last) < 0)
                goto error;
            if (last < start)
                goto error;

            cur = tmp;

            for (i = start; i <= last; i++) {
                if (virBitmapSetBit(*bitmap, i) < 0)
                    goto error;
            }

            virSkipSpaces(&cur);
        }

        if (*cur == ',') {
            cur++;
            virSkipSpaces(&cur);
            neg = false;
        } else if (*cur == 0 || *cur == terminator) {
            break;
        } else {
            goto error;
        }
    }

    if (virBitmapIsAllClear(*bitmap))
        goto error;

    return virBitmapCountBits(*bitmap);

 error:
    virReportError(VIR_ERR_INVALID_ARG,
                   _("Failed to parse bitmap '%s'"), str);
    virBitmapFree(*bitmap);
    *bitmap = NULL;
    return -1;
}
Beispiel #27
0
static int
xenParseXLUSB(virConfPtr conf, virDomainDefPtr def)
{
    virConfValuePtr list = virConfGetValue(conf, "usbdev");
    virDomainHostdevDefPtr hostdev = NULL;

    if (list && list->type == VIR_CONF_LIST) {
        list = list->list;
        while (list) {
            char bus[3];
            char device[3];
            char *key;
            int busNum;
            int devNum;

            bus[0] = device[0] = '\0';

            if ((list->type != VIR_CONF_STRING) || (list->str == NULL))
                goto skipusb;
            /* usbdev=['hostbus=1,hostaddr=3'] */
            key = list->str;
            while (key) {
                char *data;
                char *nextkey = strchr(key, ',');

                if (!(data = strchr(key, '=')))
                    goto skipusb;
                data++;

                if (STRPREFIX(key, "hostbus=")) {
                    int len = nextkey ? (nextkey - data) : sizeof(bus) - 1;
                    if (virStrncpy(bus, data, len, sizeof(bus)) == NULL) {
                        virReportError(VIR_ERR_INTERNAL_ERROR,
                                       _("bus %s too big for destination"),
                                       data);
                        goto skipusb;
                    }
                } else if (STRPREFIX(key, "hostaddr=")) {
                    int len = nextkey ? (nextkey - data) : sizeof(device) - 1;
                    if (virStrncpy(device, data, len, sizeof(device)) == NULL) {
                        virReportError(VIR_ERR_INTERNAL_ERROR,
                                       _("device %s too big for destination"),
                                       data);
                        goto skipusb;
                    }
                }

                while (nextkey && (nextkey[0] == ',' ||
                                   nextkey[0] == ' ' ||
                                   nextkey[0] == '\t'))
                    nextkey++;
                key = nextkey;
            }

            if (virStrToLong_i(bus, NULL, 16, &busNum) < 0)
                goto skipusb;
            if (virStrToLong_i(device, NULL, 16, &devNum) < 0)
                goto skipusb;
            if (!(hostdev = virDomainHostdevDefAlloc(NULL)))
               return -1;

            hostdev->managed = false;
            hostdev->source.subsys.type = VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB;
            hostdev->source.subsys.u.usb.bus = busNum;
            hostdev->source.subsys.u.usb.device = devNum;

            if (VIR_APPEND_ELEMENT(def->hostdevs, def->nhostdevs, hostdev) < 0) {
                virDomainHostdevDefFree(hostdev);
                return -1;
            }

        skipusb:
            list = list->next;
        }
    }

    return 0;
}
int
detect_scsi_host_caps(union _virNodeDevCapData *d)
{
    char *max_vports = NULL;
    char *vports = NULL;
    int ret = -1;

    VIR_DEBUG("Checking if host%d is an FC HBA", d->scsi_host.host);

    if (virIsCapableFCHost(NULL, d->scsi_host.host)) {
        d->scsi_host.flags |= VIR_NODE_DEV_CAP_FLAG_HBA_FC_HOST;

        if (virReadFCHost(NULL,
                          d->scsi_host.host,
                          "port_name",
                          &d->scsi_host.wwpn) < 0) {
            VIR_ERROR(_("Failed to read WWPN for host%d"), d->scsi_host.host);
            goto cleanup;
        }

        if (virReadFCHost(NULL,
                          d->scsi_host.host,
                          "node_name",
                          &d->scsi_host.wwnn) < 0) {
            VIR_ERROR(_("Failed to read WWNN for host%d"), d->scsi_host.host);
            goto cleanup;
        }

        if (virReadFCHost(NULL,
                          d->scsi_host.host,
                          "fabric_name",
                          &d->scsi_host.fabric_wwn) < 0) {
            VIR_ERROR(_("Failed to read fabric WWN for host%d"),
                      d->scsi_host.host);
            goto cleanup;
        }
    }

    if (virIsCapableVport(NULL, d->scsi_host.host)) {
        d->scsi_host.flags |= VIR_NODE_DEV_CAP_FLAG_HBA_VPORT_OPS;

        if (virReadFCHost(NULL,
                          d->scsi_host.host,
                          "max_npiv_vports",
                          &max_vports) < 0) {
            VIR_ERROR(_("Failed to read max_npiv_vports for host%d"),
                      d->scsi_host.host);
            goto cleanup;
        }

         if (virReadFCHost(NULL,
                          d->scsi_host.host,
                          "npiv_vports_inuse",
                          &vports) < 0) {
            VIR_ERROR(_("Failed to read npiv_vports_inuse for host%d"),
                      d->scsi_host.host);
            goto cleanup;
        }

        if (virStrToLong_i(max_vports, NULL, 10,
                           &d->scsi_host.max_vports) < 0) {
            VIR_ERROR(_("Failed to parse value of max_npiv_vports '%s'"),
                      max_vports);
            goto cleanup;
        }

        if (virStrToLong_i(vports, NULL, 10,
                           &d->scsi_host.vports) < 0) {
            VIR_ERROR(_("Failed to parse value of npiv_vports_inuse '%s'"),
                      vports);
            goto cleanup;
        }
    }

    ret = 0;
cleanup:
    if (ret < 0) {
        /* Clear the two flags in case of producing confusing XML output */
        d->scsi_host.flags &= ~(VIR_NODE_DEV_CAP_FLAG_HBA_FC_HOST |
                                VIR_NODE_DEV_CAP_FLAG_HBA_VPORT_OPS);

        VIR_FREE(d->scsi_host.wwnn);
        VIR_FREE(d->scsi_host.wwpn);
        VIR_FREE(d->scsi_host.fabric_wwn);
    }
    VIR_FREE(max_vports);
    VIR_FREE(vports);
    return ret;
}
static int daemonSetupNetworking(virNetServerPtr srv,
                                 struct daemonConfig *config,
                                 const char *sock_path,
                                 const char *sock_path_ro,
                                 bool ipsock,
                                 bool privileged)
{
    virNetServerServicePtr svc = NULL;
    virNetServerServicePtr svcRO = NULL;
    virNetServerServicePtr svcTCP = NULL;
    virNetServerServicePtr svcTLS = NULL;
    gid_t unix_sock_gid = 0;
    int unix_sock_ro_mask = 0;
    int unix_sock_rw_mask = 0;

    if (config->unix_sock_group) {
        if (virGetGroupID(config->unix_sock_group, &unix_sock_gid) < 0)
            return -1;
    }

    if (virStrToLong_i(config->unix_sock_ro_perms, NULL, 8, &unix_sock_ro_mask) != 0) {
        VIR_ERROR(_("Failed to parse mode '%s'"), config->unix_sock_ro_perms);
        goto error;
    }

    if (virStrToLong_i(config->unix_sock_rw_perms, NULL, 8, &unix_sock_rw_mask) != 0) {
        VIR_ERROR(_("Failed to parse mode '%s'"), config->unix_sock_rw_perms);
        goto error;
    }

    if (!(svc = virNetServerServiceNewUNIX(sock_path,
                                           unix_sock_rw_mask,
                                           unix_sock_gid,
                                           config->auth_unix_rw,
                                           false,
                                           config->max_client_requests,
                                           NULL)))
        goto error;
    if (sock_path_ro &&
        !(svcRO = virNetServerServiceNewUNIX(sock_path_ro,
                                             unix_sock_ro_mask,
                                             unix_sock_gid,
                                             config->auth_unix_ro,
                                             true,
                                             config->max_client_requests,
                                             NULL)))
        goto error;

    if (virNetServerAddService(srv, svc,
                               config->mdns_adv && !ipsock ?
                               "_libvirt._tcp" :
                               NULL) < 0)
        goto error;

    if (svcRO &&
        virNetServerAddService(srv, svcRO, NULL) < 0)
        goto error;

    if (ipsock) {
        if (config->listen_tcp) {
            if (!(svcTCP = virNetServerServiceNewTCP(config->listen_addr,
                                                     config->tcp_port,
                                                     config->auth_tcp,
                                                     false,
                                                     config->max_client_requests,
                                                     NULL)))
                goto error;

            if (virNetServerAddService(srv, svcTCP,
                                       config->mdns_adv ? "_libvirt._tcp" : NULL) < 0)
                goto error;
        }

        if (config->listen_tls) {
            virNetTLSContextPtr ctxt = NULL;

            if (config->ca_file ||
                config->cert_file ||
                config->key_file) {
                if (!(ctxt = virNetTLSContextNewServer(config->ca_file,
                                                       config->crl_file,
                                                       config->cert_file,
                                                       config->key_file,
                                                       (const char *const*)config->tls_allowed_dn_list,
                                                       config->tls_no_sanity_certificate ? false : true,
                                                       config->tls_no_verify_certificate ? false : true)))
                    goto error;
            } else {
                if (!(ctxt = virNetTLSContextNewServerPath(NULL,
                                                           !privileged,
                                                           (const char *const*)config->tls_allowed_dn_list,
                                                           config->tls_no_sanity_certificate ? false : true,
                                                           config->tls_no_verify_certificate ? false : true)))
                    goto error;
            }

            if (!(svcTLS =
                  virNetServerServiceNewTCP(config->listen_addr,
                                            config->tls_port,
                                            config->auth_tls,
                                            false,
                                            config->max_client_requests,
                                            ctxt))) {
                virNetTLSContextFree(ctxt);
                goto error;
            }
            if (virNetServerAddService(srv, svcTLS,
                                       config->mdns_adv &&
                                       !config->listen_tcp ? "_libvirt._tcp" : NULL) < 0)
                goto error;

            virNetTLSContextFree(ctxt);
        }
    }

#if HAVE_SASL
    if (config->auth_unix_rw == REMOTE_AUTH_SASL ||
        config->auth_unix_ro == REMOTE_AUTH_SASL ||
        config->auth_tcp == REMOTE_AUTH_SASL ||
        config->auth_tls == REMOTE_AUTH_SASL) {
        saslCtxt = virNetSASLContextNewServer(
            (const char *const*)config->sasl_allowed_username_list);
        if (!saslCtxt)
            goto error;
    }
#endif

    return 0;

error:
    virNetServerServiceFree(svcTLS);
    virNetServerServiceFree(svcTCP);
    virNetServerServiceFree(svc);
    virNetServerServiceFree(svcRO);
    return -1;
}
Beispiel #30
0
static int daemonSetupNetworking(virNetServerPtr srv,
                                 struct daemonConfig *config,
                                 const char *sock_path,
                                 const char *sock_path_ro,
                                 bool ipsock,
                                 bool privileged)
{
    virNetServerServicePtr svc = NULL;
    virNetServerServicePtr svcRO = NULL;
    virNetServerServicePtr svcTCP = NULL;
#if WITH_GNUTLS
    virNetServerServicePtr svcTLS = NULL;
#endif
    gid_t unix_sock_gid = 0;
    int unix_sock_ro_mask = 0;
    int unix_sock_rw_mask = 0;

    if (config->unix_sock_group) {
        if (virGetGroupID(config->unix_sock_group, &unix_sock_gid) < 0)
            return -1;
    }

    if (virStrToLong_i(config->unix_sock_ro_perms, NULL, 8, &unix_sock_ro_mask) != 0) {
        VIR_ERROR(_("Failed to parse mode '%s'"), config->unix_sock_ro_perms);
        goto error;
    }

    if (virStrToLong_i(config->unix_sock_rw_perms, NULL, 8, &unix_sock_rw_mask) != 0) {
        VIR_ERROR(_("Failed to parse mode '%s'"), config->unix_sock_rw_perms);
        goto error;
    }

    VIR_DEBUG("Registering unix socket %s", sock_path);
    if (!(svc = virNetServerServiceNewUNIX(sock_path,
                                           unix_sock_rw_mask,
                                           unix_sock_gid,
                                           config->auth_unix_rw,
#if WITH_GNUTLS
                                           NULL,
#endif
                                           false,
                                           config->max_queued_clients,
                                           config->max_client_requests)))
        goto error;
    if (sock_path_ro) {
        VIR_DEBUG("Registering unix socket %s", sock_path_ro);
        if (!(svcRO = virNetServerServiceNewUNIX(sock_path_ro,
                                                 unix_sock_ro_mask,
                                                 unix_sock_gid,
                                                 config->auth_unix_ro,
#if WITH_GNUTLS
                                                 NULL,
#endif
                                                 true,
                                                 config->max_queued_clients,
                                                 config->max_client_requests)))
            goto error;
    }

    if (virNetServerAddService(srv, svc,
                               config->mdns_adv && !ipsock ?
                               "_libvirt._tcp" :
                               NULL) < 0)
        goto error;

    if (svcRO &&
        virNetServerAddService(srv, svcRO, NULL) < 0)
        goto error;

    if (ipsock) {
        if (config->listen_tcp) {
            VIR_DEBUG("Registering TCP socket %s:%s",
                      config->listen_addr, config->tcp_port);
            if (!(svcTCP = virNetServerServiceNewTCP(config->listen_addr,
                                                     config->tcp_port,
                                                     config->auth_tcp,
#if WITH_GNUTLS
                                                     NULL,
#endif
                                                     false,
                                                     config->max_queued_clients,
                                                     config->max_client_requests)))
                goto error;

            if (virNetServerAddService(srv, svcTCP,
                                       config->mdns_adv ? "_libvirt._tcp" : NULL) < 0)
                goto error;
        }

#if WITH_GNUTLS
        if (config->listen_tls) {
            virNetTLSContextPtr ctxt = NULL;

            if (config->ca_file ||
                config->cert_file ||
                config->key_file) {
                if (!(ctxt = virNetTLSContextNewServer(config->ca_file,
                                                       config->crl_file,
                                                       config->cert_file,
                                                       config->key_file,
                                                       (const char *const*)config->tls_allowed_dn_list,
                                                       config->tls_no_sanity_certificate ? false : true,
                                                       config->tls_no_verify_certificate ? false : true)))
                    goto error;
            } else {
                if (!(ctxt = virNetTLSContextNewServerPath(NULL,
                                                           !privileged,
                                                           (const char *const*)config->tls_allowed_dn_list,
                                                           config->tls_no_sanity_certificate ? false : true,
                                                           config->tls_no_verify_certificate ? false : true)))
                    goto error;
            }

            VIR_DEBUG("Registering TLS socket %s:%s",
                      config->listen_addr, config->tls_port);
            if (!(svcTLS =
                  virNetServerServiceNewTCP(config->listen_addr,
                                            config->tls_port,
                                            config->auth_tls,
                                            ctxt,
                                            false,
                                            config->max_queued_clients,
                                            config->max_client_requests))) {
                virObjectUnref(ctxt);
                goto error;
            }
            if (virNetServerAddService(srv, svcTLS,
                                       config->mdns_adv &&
                                       !config->listen_tcp ? "_libvirt._tcp" : NULL) < 0)
                goto error;

            virObjectUnref(ctxt);
        }
#else
        (void)privileged;
        if (config->listen_tls) {
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                           _("This libvirtd build does not support TLS"));
            goto error;
        }
#endif
    }

#if WITH_SASL
    if (config->auth_unix_rw == REMOTE_AUTH_SASL ||
        config->auth_unix_ro == REMOTE_AUTH_SASL ||
# if WITH_GNUTLS
        config->auth_tls == REMOTE_AUTH_SASL ||
# endif
        config->auth_tcp == REMOTE_AUTH_SASL) {
        saslCtxt = virNetSASLContextNewServer(
            (const char *const*)config->sasl_allowed_username_list);
        if (!saslCtxt)
            goto error;
    }
#endif

    return 0;

 error:
#if WITH_GNUTLS
    virObjectUnref(svcTLS);
#endif
    virObjectUnref(svcTCP);
    virObjectUnref(svc);
    virObjectUnref(svcRO);
    return -1;
}