コード例 #1
0
ファイル: libvirtdconftest.c プロジェクト: emaste/libvirt
static int
mymain(void)
{
    int ret = 0;
    char *filedata = NULL;
    char *filename = NULL;
    size_t i;
    size_t *params = NULL;

    if (virAsprintf(&filename, "%s/../daemon/libvirtd.conf",
                    abs_srcdir) < 0) {
        perror("Format filename");
        return EXIT_FAILURE;
    }

    if (virFileReadAll(filename, 1024*1024, &filedata) < 0) {
        virErrorPtr err = virGetLastError();
        fprintf(stderr, "Cannot load %s for testing: %s", filename, err->message);
        ret = -1;
        goto cleanup;
    }

    if (uncomment_all_params(filedata, &params) < 0){
        perror("Find params");
        ret = -1;
        goto cleanup;
    }
    VIR_DEBUG("Initial config [%s]", filedata);
    for (i = 0 ; params[i] != 0 ; i++) {
        const struct testCorruptData data = { params, filedata, filename, i };
        if (virtTestRun("Test corruption", 1, testCorrupt, &data) < 0)
            ret = -1;
    }

cleanup:
    VIR_FREE(filename);
    VIR_FREE(filedata);
    VIR_FREE(params);
    return ret==0 ? EXIT_SUCCESS : EXIT_FAILURE;
}
コード例 #2
0
ファイル: virnetdevip.c プロジェクト: RWTH-OS/libvirt
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;
}
コード例 #3
0
ファイル: conf.c プロジェクト: foomango/libvirt
/**
 * virConfReadFile:
 * @filename: the path to the configuration file.
 * @flags: combination of virConfFlag(s)
 *
 * Reads a configuration file.
 *
 * Returns a handle to lookup settings or NULL if it failed to
 *         read or parse the file, use virConfFree() to free the data.
 */
virConfPtr
virConfReadFile(const char *filename, unsigned int flags)
{
    char *content;
    int len;
    virConfPtr conf;

    if (filename == NULL) {
        virConfError(NULL, VIR_ERR_INVALID_ARG, __FUNCTION__);
        return NULL;
    }

    if ((len = virFileReadAll(filename, MAX_CONFIG_FILE_SIZE, &content)) < 0) {
        return NULL;
    }

    conf = virConfParse(filename, content, len, flags);

    VIR_FREE(content);

    return conf;
}
コード例 #4
0
ファイル: nodeinfo.c プロジェクト: emaste/libvirt
/*
 * Linux maintains cpu bit map under cpu/online. For example, if
 * cpuid=5's flag is not set and max cpu is 7, the map file shows
 * 0-4,6-7. This function parses it and returns cpumap.
 */
static virBitmapPtr
linuxParseCPUmap(int max_cpuid, const char *path)
{
    virBitmapPtr map = NULL;
    char *str = NULL;

    if (virFileReadAll(path, 5 * VIR_DOMAIN_CPUMASK_LEN, &str) < 0) {
        virReportOOMError();
        goto error;
    }

    if (virBitmapParse(str, 0, &map, max_cpuid) < 0)
        goto error;

    VIR_FREE(str);
    return map;

error:
    VIR_FREE(str);
    virBitmapFree(map);
    return NULL;
}
コード例 #5
0
ファイル: vircaps2xmltest.c プロジェクト: 6WIND/libvirt
static int
test_virCapabilitiesFormat(const void *opaque)
{
    struct virCapabilitiesFormatData *data = (struct virCapabilitiesFormatData *) opaque;
    virCapsPtr caps = NULL;
    char *capsXML = NULL;
    char *capsFromFile = NULL;
    char *path = NULL;
    int ret = -1;

    if (!(caps = buildVirCapabilities(data->max_cells, data->max_cpus_in_cell,
                                      data->max_mem_in_cell)))
        goto cleanup;

    if (!(capsXML = virCapabilitiesFormatXML(caps)))
        goto cleanup;

    if (virAsprintf(&path, "%s/vircaps2xmldata/vircaps-%s.xml",
                    abs_srcdir, data->filename) < 0)
        goto cleanup;

    if (virFileReadAll(path, 8192, &capsFromFile) < 0)
        goto cleanup;


    if (STRNEQ(capsXML, capsFromFile)) {
        virtTestDifference(stderr, capsFromFile, capsXML);
        goto cleanup;
    }

    ret = 0;

 cleanup:
    VIR_FREE(path);
    VIR_FREE(capsFromFile);
    VIR_FREE(capsXML);
    virObjectUnref(caps);
    return ret;
}
コード例 #6
0
/*
 * profile_status_file returns '-1' on error, '0' if file on disk is in
 * complain mode and '1' if file on disk is in enforcing mode
 */
static int
profile_status_file(const char *str)
{
    char *profile = NULL;
    char *content = NULL;
    char *tmp = NULL;
    int rc = -1;
    int len;

    if (virAsprintf(&profile, "%s/%s", APPARMOR_DIR "/libvirt", str) == -1)
        return rc;

    if (!virFileExists(profile))
        goto failed;

    if ((len = virFileReadAll(profile, MAX_FILE_LEN, &content)) < 0) {
        virReportSystemError(errno,
                             _("Failed to read \'%s\'"), profile);
        goto failed;
    }

    /* create string that is ' <str> flags=(complain)\0' */
    if (virAsprintf(&tmp, " %s flags=(complain)", str) == -1)
        goto failed;

    if (strstr(content, tmp) != NULL)
        rc = 0;
    else
        rc = 1;

 failed:
    VIR_FREE(tmp);
    VIR_FREE(profile);
    VIR_FREE(content);

    return rc;
}
コード例 #7
0
ファイル: virsh-volume.c プロジェクト: aurex-linux/libvirt
static bool
cmdVolCreate(vshControl *ctl, const vshCmd *cmd)
{
    virStoragePoolPtr pool;
    virStorageVolPtr vol;
    const char *from = NULL;
    bool ret = false;
    unsigned int flags = 0;
    char *buffer = NULL;

    if (vshCommandOptBool(cmd, "prealloc-metadata"))
        flags |= VIR_STORAGE_VOL_CREATE_PREALLOC_METADATA;
    if (!(pool = vshCommandOptPool(ctl, cmd, "pool", NULL)))
        return false;

    if (vshCommandOptStringReq(ctl, cmd, "file", &from) < 0)
        goto cleanup;

    if (virFileReadAll(from, VSH_MAX_XML_FILE, &buffer) < 0) {
        vshSaveLibvirtError();
        goto cleanup;
    }

    if ((vol = virStorageVolCreateXML(pool, buffer, flags))) {
        vshPrint(ctl, _("Vol %s created from %s\n"),
                 virStorageVolGetName(vol), from);
        virStorageVolFree(vol);
        ret = true;
    } else {
        vshError(ctl, _("Failed to create vol from %s"), from);
    }

 cleanup:
    VIR_FREE(buffer);
    virStoragePoolFree(pool);
    return ret;
}
コード例 #8
0
/*
 * Linux maintains cpu bit map. For example, if cpuid=5's flag is not set
 * and max cpu is 7. The map file shows 0-4,6-7. This function parses
 * it and returns cpumap.
 */
static char *
linuxParseCPUmap(int *max_cpuid, const char *path)
{
    char *map = NULL;
    char *str = NULL;
    int max_id = 0, i;

    if (virFileReadAll(path, 5 * VIR_DOMAIN_CPUMASK_LEN, &str) < 0) {
        virReportOOMError();
        goto error;
    }

    if (VIR_ALLOC_N(map, VIR_DOMAIN_CPUMASK_LEN) < 0) {
        virReportOOMError();
        goto error;
    }
    if (virDomainCpuSetParse(str, 0, map,
                             VIR_DOMAIN_CPUMASK_LEN) < 0) {
        goto error;
    }

    for (i = 0; i < VIR_DOMAIN_CPUMASK_LEN; i++) {
        if (map[i]) {
            max_id = i;
        }
    }
    *max_cpuid = max_id;

    VIR_FREE(str);
    return map;

error:
    VIR_FREE(str);
    VIR_FREE(map);
    return NULL;
}
コード例 #9
0
ファイル: virnuma.c プロジェクト: AGSaidi/hacked-libvirt
int
virNumaSetPagePoolSize(int node,
                       unsigned int page_size,
                       unsigned long long page_count,
                       bool add)
{
    int ret = -1;
    char *nr_path = NULL, *nr_buf =  NULL;
    char *end;
    unsigned long long nr_count;

    if (page_size == virGetSystemPageSizeKB()) {
        /* Special case as kernel handles system pages
         * differently to huge pages. */
        virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
                       _("system pages pool can't be modified"));
        goto cleanup;
    }

    if (virNumaGetHugePageInfoPath(&nr_path, node, page_size, "nr_hugepages") < 0)
        goto cleanup;

    /* Firstly check, if there's anything for us to do */
    if (virFileReadAll(nr_path, 1024, &nr_buf) < 0)
        goto cleanup;

    if (virStrToLong_ull(nr_buf, &end, 10, &nr_count) < 0 ||
            *end != '\n') {
        virReportError(VIR_ERR_OPERATION_FAILED,
                       _("invalid number '%s' in '%s'"),
                       nr_buf, nr_path);
        goto cleanup;
    }

    if (add) {
        if (!page_count) {
            VIR_DEBUG("Nothing left to do: add = true page_count = 0");
            ret = 0;
            goto cleanup;
        }
        page_count += nr_count;
    } else {
        if (nr_count == page_count) {
            VIR_DEBUG("Nothing left to do: nr_count = page_count = %llu",
                      page_count);
            ret = 0;
            goto cleanup;
        }
    }

    /* Okay, page pool adjustment must be done in two steps. In
     * first we write the desired number into nr_hugepages file.
     * Kernel then starts to allocate the pages (return from
     * write should be postponed until the kernel is finished).
     * However, kernel may have not been successful and reserved
     * all the pages we wanted. So do the second read to check.
     */
    VIR_FREE(nr_buf);
    if (virAsprintf(&nr_buf, "%llu", page_count) < 0)
        goto cleanup;

    if (virFileWriteStr(nr_path, nr_buf, 0) < 0) {
        virReportSystemError(errno,
                             _("Unable to write to: %s"), nr_path);
        goto cleanup;
    }

    /* And now do the check. */

    VIR_FREE(nr_buf);
    if (virFileReadAll(nr_path, 1024, &nr_buf) < 0)
        goto cleanup;

    if (virStrToLong_ull(nr_buf, &end, 10, &nr_count) < 0 ||
            *end != '\n') {
        virReportError(VIR_ERR_OPERATION_FAILED,
                       _("invalid number '%s' in '%s'"),
                       nr_buf, nr_path);
        goto cleanup;
    }

    if (nr_count != page_count) {
        virReportError(VIR_ERR_OPERATION_FAILED,
                       _("Unable to allocate %llu pages. Allocated only %llu"),
                       page_count, nr_count);
        goto cleanup;
    }

    ret = 0;
cleanup:
    VIR_FREE(nr_buf);
    VIR_FREE(nr_path);
    return ret;
}
コード例 #10
0
ファイル: vmware_conf.c プロジェクト: hzguanqiang/libvirt
int
vmwareLoadDomains(struct vmware_driver *driver)
{
    virDomainDefPtr vmdef = NULL;
    virDomainObjPtr vm = NULL;
    char *vmxPath = NULL;
    char *vmx = NULL;
    vmwareDomainPtr pDomain;
    char *directoryName = NULL;
    char *fileName = NULL;
    int ret = -1;
    virVMXContext ctx;
    char *outbuf = NULL;
    char *str;
    char *saveptr = NULL;
    virCommandPtr cmd;

    ctx.parseFileName = vmwareCopyVMXFileName;

    cmd = virCommandNewArgList(VMRUN, "-T",
                               driver->type == TYPE_PLAYER ? "player" : "ws",
                               "list", NULL);
    virCommandSetOutputBuffer(cmd, &outbuf);
    if (virCommandRun(cmd, NULL) < 0)
        goto cleanup;

    for (str = outbuf; (vmxPath = strtok_r(str, "\n", &saveptr)) != NULL;
        str = NULL) {

        if (vmxPath[0] != '/')
            continue;

        if (virFileReadAll(vmxPath, 10000, &vmx) < 0)
            goto cleanup;

        if ((vmdef =
             virVMXParseConfig(&ctx, driver->xmlopt, vmx)) == NULL) {
            goto cleanup;
        }

        if (!(vm = virDomainObjListAdd(driver->domains, vmdef,
                                       driver->xmlopt,
                                       0, NULL)))
            goto cleanup;

        pDomain = vm->privateData;

        if (VIR_STRDUP(pDomain->vmxPath, vmxPath) < 0)
            goto cleanup;

        vmwareDomainConfigDisplay(pDomain, vmdef);

        if ((vm->def->id = vmwareExtractPid(vmxPath)) < 0)
            goto cleanup;
        /* vmrun list only reports running vms */
        virDomainObjSetState(vm, VIR_DOMAIN_RUNNING,
                             VIR_DOMAIN_RUNNING_UNKNOWN);
        vm->persistent = 1;

        virObjectUnlock(vm);

        vmdef = NULL;
        vm = NULL;
    }

    ret = 0;

cleanup:
    virCommandFree(cmd);
    VIR_FREE(outbuf);
    virDomainDefFree(vmdef);
    VIR_FREE(directoryName);
    VIR_FREE(fileName);
    VIR_FREE(vmx);
    virObjectUnref(vm);
    return ret;
}
コード例 #11
0
/* XXX: This function can be a lot more exhaustive, there are certainly
 *      other scenarios where we can ruin host network connectivity.
 * XXX: Using a proper library is preferred over parsing /proc
 */
int networkCheckRouteCollision(virNetworkDefPtr def)
{
    int ret = 0, len;
    char *cur, *buf = NULL;
    /* allow for up to 100000 routes (each line is 128 bytes) */
    enum {MAX_ROUTE_SIZE = 128*100000};

    /* Read whole routing table into memory */
    if ((len = virFileReadAll(PROC_NET_ROUTE, MAX_ROUTE_SIZE, &buf)) < 0)
        goto out;

    /* Dropping the last character shouldn't hurt */
    if (len > 0)
        buf[len-1] = '\0';

    VIR_DEBUG("%s output:\n%s", PROC_NET_ROUTE, buf);

    if (!STRPREFIX(buf, "Iface"))
        goto out;

    /* First line is just headings, skip it */
    cur = strchr(buf, '\n');
    if (cur)
        cur++;

    while (cur) {
        char iface[17], dest[128], mask[128];
        unsigned int addr_val, mask_val;
        virNetworkIpDefPtr ipdef;
        int num;
        size_t i;

        /* NUL-terminate the line, so sscanf doesn't go beyond a newline.  */
        char *nl = strchr(cur, '\n');
        if (nl)
            *nl++ = '\0';

        num = sscanf(cur, "%16s %127s %*s %*s %*s %*s %*s %127s",
                     iface, dest, mask);
        cur = nl;

        if (num != 3) {
            VIR_DEBUG("Failed to parse %s", PROC_NET_ROUTE);
            continue;
        }

        if (virStrToLong_ui(dest, NULL, 16, &addr_val) < 0) {
            VIR_DEBUG("Failed to convert network address %s to uint", dest);
            continue;
        }

        if (virStrToLong_ui(mask, NULL, 16, &mask_val) < 0) {
            VIR_DEBUG("Failed to convert network mask %s to uint", mask);
            continue;
        }

        addr_val &= mask_val;

        for (i = 0;
             (ipdef = virNetworkDefGetIpByIndex(def, AF_INET, i));
             i++) {

            unsigned int net_dest;
            virSocketAddr netmask;

            if (virNetworkIpDefNetmask(ipdef, &netmask) < 0) {
                VIR_WARN("Failed to get netmask of '%s'",
                         def->bridge);
                continue;
            }

            net_dest = (ipdef->address.data.inet4.sin_addr.s_addr &
                        netmask.data.inet4.sin_addr.s_addr);

            if ((net_dest == addr_val) &&
                (netmask.data.inet4.sin_addr.s_addr == mask_val)) {
                virReportError(VIR_ERR_INTERNAL_ERROR,
                               _("Network is already in use by interface %s"),
                               iface);
                ret = -1;
                goto out;
            }
        }
    }

 out:
    VIR_FREE(buf);
    return ret;
}
コード例 #12
0
static int testExecRestart(const void *opaque)
{
    int ret = -1;
    virNetServerPtr srv = NULL;
    const struct testExecRestartData *data = opaque;
    char *infile = NULL, *outfile = NULL;
    char *injsonstr = NULL, *outjsonstr = NULL;
    virJSONValuePtr injson = NULL, outjson = NULL;
    int fdclient[2] = { -1, -1 }, fdserver[2] = { -1, -1 };

    if (socketpair(PF_UNIX, SOCK_STREAM, 0, fdclient) < 0) {
        virReportSystemError(errno, "%s",
                             "Cannot create socket pair");
        goto cleanup;
    }

    if (socketpair(PF_UNIX, SOCK_STREAM, 0, fdserver) < 0) {
        virReportSystemError(errno, "%s",
                             "Cannot create socket pair");
        goto cleanup;
    }

    /* We're blindly assuming the test case isn't using
     * fds 100->103 for something else, which is probably
     * fairly reasonable in general
     */
    dup2(fdserver[0], 100);
    dup2(fdserver[1], 101);
    dup2(fdclient[0], 102);
    dup2(fdclient[1], 103);

    if (virAsprintf(&infile, "%s/virnetserverdata/input-data-%s.json",
                    abs_srcdir, data->jsonfile) < 0)
        goto cleanup;

    if (virAsprintf(&outfile, "%s/virnetserverdata/output-data-%s.json",
                    abs_srcdir, data->jsonfile) < 0)
        goto cleanup;

    if (virFileReadAll(infile, 8192, &injsonstr) < 0)
        goto cleanup;

    if (!(injson = virJSONValueFromString(injsonstr)))
        goto cleanup;

    if (!(srv = virNetServerNewPostExecRestart(injson,
                                               NULL, NULL, NULL,
                                               NULL, NULL)))
        goto cleanup;

    if (!(outjson = virNetServerPreExecRestart(srv)))
        goto cleanup;

    if (!(outjsonstr = virJSONValueToString(outjson, true)))
        goto cleanup;

    if (virtTestCompareToFile(outjsonstr, outfile) < 0)
        goto fail;

    ret = 0;

 cleanup:
    if (ret < 0) {
        virErrorPtr err = virGetLastError();
        /* Rather be safe, we have lot of missing errors */
        if (err)
            fprintf(stderr, "%s\n", err->message);
        else
            fprintf(stderr, "%s\n", "Unknown error");
    }
 fail:
    VIR_FREE(infile);
    VIR_FREE(outfile);
    VIR_FREE(injsonstr);
    VIR_FREE(outjsonstr);
    virJSONValueFree(injson);
    virJSONValueFree(outjson);
    virObjectUnref(srv);
    VIR_FORCE_CLOSE(fdserver[0]);
    VIR_FORCE_CLOSE(fdserver[1]);
    VIR_FORCE_CLOSE(fdclient[0]);
    VIR_FORCE_CLOSE(fdclient[1]);
    return ret;
}
コード例 #13
0
ファイル: parallels_network.c プロジェクト: bigclouds/libvirt
static int parallelsGetBridgedNetInfo(virNetworkDefPtr def, virJSONValuePtr jobj)
{
    const char *ifname;
    char *bridgeLink = NULL;
    char *bridgePath = NULL;
    char *bridgeAddressPath = NULL;
    char *bridgeAddress = NULL;
    int len = 0;
    int ret = -1;

    if (!(ifname = virJSONValueObjectGetString(jobj, "Bound To"))) {
        parallelsParseError();
        goto cleanup;
    }

    if (virAsprintf(&bridgeLink, "%s/%s/brport/bridge",
                    SYSFS_NET_DIR, ifname) < 0) {
        virReportOOMError();
        goto cleanup;
    }

    if (virFileResolveLink(bridgeLink, &bridgePath) < 0) {
        virReportSystemError(errno, _("cannot read link '%s'"), bridgeLink);
        goto cleanup;
    }

    if (!(def->bridge = strdup(basename(bridgePath)))) {
        virReportOOMError();
        goto cleanup;
    }

    if (virAsprintf(&bridgeAddressPath, "%s/%s/brport/bridge/address",
                    SYSFS_NET_DIR, ifname) < 0) {
        virReportOOMError();
        goto cleanup;
    }

    if ((len = virFileReadAll(bridgeAddressPath, 18, &bridgeAddress)) < 0) {
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("Error reading file '%s'"), bridgeAddressPath);

        goto cleanup;
    }

    if (len < VIR_MAC_STRING_BUFLEN) {
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("Error reading MAC from '%s'"), bridgeAddressPath);
    }

    bridgeAddress[VIR_MAC_STRING_BUFLEN - 1] = '\0';
    if (virMacAddrParse(bridgeAddress, &def->mac) < 0) {
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("Can't parse MAC '%s'"), bridgeAddress);
        goto cleanup;
    }
    def->mac_specified = 1;

    ret = 0;

cleanup:
    VIR_FREE(bridgeLink);
    VIR_FREE(bridgePath);
    VIR_FREE(bridgeAddress);
    VIR_FREE(bridgeAddressPath);
    return ret;
}
コード例 #14
0
ファイル: virperf.c プロジェクト: pythonran/libvirt
static int
virPerfRdtEnable(virPerfEventPtr event,
                 pid_t pid)
{
    struct perf_event_attr rdt_attr;
    char *buf = NULL;
    char *tmp = NULL;
    unsigned int event_type, scale;

    if (virFileReadAll("/sys/devices/intel_cqm/type",
                       10, &buf) < 0)
        goto error;

    if ((tmp = strchr(buf, '\n')))
        *tmp = '\0';

    if (virStrToLong_ui(buf, NULL, 10, &event_type) < 0) {
        virReportSystemError(errno, "%s",
                             _("failed to get rdt event type"));
        goto error;
    }
    VIR_FREE(buf);

    memset(&rdt_attr, 0, sizeof(rdt_attr));
    rdt_attr.size = sizeof(rdt_attr);
    rdt_attr.type = event_type;
    rdt_attr.inherit = 1;
    rdt_attr.disabled = 1;
    rdt_attr.enable_on_exec = 0;

    switch (event->type) {
    case VIR_PERF_EVENT_CMT:
        if (virFileReadAll("/sys/devices/intel_cqm/events/llc_occupancy.scale",
                           10, &buf) < 0)
            goto error;

        if (virStrToLong_ui(buf, NULL, 10, &scale) < 0) {
            virReportSystemError(errno, "%s",
                                 _("failed to get cmt scaling factor"));
            goto error;
        }
        event->efields.cmt.scale = scale;

        rdt_attr.config = 1;
        break;
    case VIR_PERF_EVENT_MBMT:
        rdt_attr.config = 2;
        break;
    case VIR_PERF_EVENT_MBML:
        rdt_attr.config = 3;
        break;
    }

    event->fd = syscall(__NR_perf_event_open, &rdt_attr, pid, -1, -1, 0);
    if (event->fd < 0) {
        virReportSystemError(errno,
                             _("Unable to open perf type=%d for pid=%d"),
                             event_type, pid);
        goto error;
    }

    if (ioctl(event->fd, PERF_EVENT_IOC_ENABLE) < 0) {
        virReportSystemError(errno,
                             _("Unable to enable perf event for %s"),
                             virPerfEventTypeToString(event->type));
        goto error;
    }

    event->enabled = true;
    return 0;

 error:
    VIR_FORCE_CLOSE(event->fd);
    VIR_FREE(buf);
    return -1;
}
コード例 #15
0
ファイル: virscsi.c プロジェクト: hzguanqiang/libvirt
virSCSIDevicePtr
virSCSIDeviceNew(const char *adapter,
                 unsigned int bus,
                 unsigned int target,
                 unsigned int unit,
                 bool readonly)
{
    virSCSIDevicePtr dev, ret = NULL;
    char *sg = NULL;
    char *vendor_path = NULL;
    char *model_path = NULL;
    char *vendor = NULL;
    char *model = NULL;

    if (VIR_ALLOC(dev) < 0)
        return NULL;

    dev->bus = bus;
    dev->target = target;
    dev->unit = unit;
    dev->readonly = readonly;

    if (!(sg = virSCSIDeviceGetSgName(adapter, bus, target, unit)))
        goto cleanup;

    if (virSCSIDeviceGetAdapterId(adapter, &dev->adapter) < 0)
        goto cleanup;

    if (virAsprintf(&dev->name, "%d:%d:%d:%d", dev->adapter,
                    dev->bus, dev->target, dev->unit) < 0 ||
        virAsprintf(&dev->sg_path, "/dev/%s", sg) < 0)
        goto cleanup;

    if (access(dev->sg_path, F_OK) != 0) {
        virReportSystemError(errno,
                             _("SCSI device '%s': could not access %s"),
                             dev->name, dev->sg_path);
        goto cleanup;
    }

    if (virAsprintf(&vendor_path,
                    SYSFS_SCSI_DEVICES "/%s/vendor", dev->name) < 0 ||
        virAsprintf(&model_path,
                    SYSFS_SCSI_DEVICES "/%s/model", dev->name) < 0)
        goto cleanup;

    if (virFileReadAll(vendor_path, 1024, &vendor) < 0)
        goto cleanup;

    if (virFileReadAll(model_path, 1024, &model) < 0)
        goto cleanup;

    virTrimSpaces(vendor, NULL);
    virTrimSpaces(model, NULL);

    if (virAsprintf(&dev->id, "%s:%s", vendor, model) < 0)
        goto cleanup;

    ret = dev;
cleanup:
    VIR_FREE(sg);
    VIR_FREE(vendor);
    VIR_FREE(model);
    VIR_FREE(vendor_path);
    VIR_FREE(model_path);
    if (!ret)
        virSCSIDeviceFree(dev);
    return ret;
}
コード例 #16
0
ファイル: virscsi.c プロジェクト: MountainWei/libvirt
virSCSIDevicePtr
virSCSIDeviceNew(const char *sysfs_prefix,
                 const char *adapter,
                 unsigned int bus,
                 unsigned int target,
                 unsigned long long unit,
                 bool readonly,
                 bool shareable)
{
    virSCSIDevicePtr dev, ret = NULL;
    char *sg = NULL;
    char *vendor_path = NULL;
    char *model_path = NULL;
    char *vendor = NULL;
    char *model = NULL;
    const char *prefix = sysfs_prefix ? sysfs_prefix : SYSFS_SCSI_DEVICES;

    if (VIR_ALLOC(dev) < 0)
        return NULL;

    dev->bus = bus;
    dev->target = target;
    dev->unit = unit;
    dev->readonly = readonly;
    dev->shareable = shareable;

    if (!(sg = virSCSIDeviceGetSgName(prefix, adapter, bus, target, unit)))
        goto cleanup;

    if (virSCSIDeviceGetAdapterId(adapter, &dev->adapter) < 0)
        goto cleanup;

    if (virAsprintf(&dev->name, "%d:%u:%u:%llu", dev->adapter,
                    dev->bus, dev->target, dev->unit) < 0 ||
        virAsprintf(&dev->sg_path, "%s/%s",
                    sysfs_prefix ? sysfs_prefix : "/dev", sg) < 0)
        goto cleanup;

    if (!virFileExists(dev->sg_path)) {
        virReportSystemError(errno,
                             _("SCSI device '%s': could not access %s"),
                             dev->name, dev->sg_path);
        goto cleanup;
    }

    if (virAsprintf(&vendor_path,
                    "%s/%s/vendor", prefix, dev->name) < 0 ||
        virAsprintf(&model_path,
                    "%s/%s/model", prefix, dev->name) < 0)
        goto cleanup;

    if (virFileReadAll(vendor_path, 1024, &vendor) < 0)
        goto cleanup;

    if (virFileReadAll(model_path, 1024, &model) < 0)
        goto cleanup;

    virTrimSpaces(vendor, NULL);
    virTrimSpaces(model, NULL);

    if (virAsprintf(&dev->id, "%s:%s", vendor, model) < 0)
        goto cleanup;

    ret = dev;
 cleanup:
    VIR_FREE(sg);
    VIR_FREE(vendor);
    VIR_FREE(model);
    VIR_FREE(vendor_path);
    VIR_FREE(model_path);
    if (!ret)
        virSCSIDeviceFree(dev);
    return ret;
}