예제 #1
0
파일: viriscsi.c 프로젝트: RWTH-OS/libvirt
static int
virISCSIConnection(const char *portal,
                   const char *initiatoriqn,
                   const char *target,
                   const char **extraargv)
{
    int ret = -1;
    const char *const baseargv[] = {
        ISCSIADM,
        "--mode", "node",
        "--portal", portal,
        "--targetname", target,
        NULL
    };
    virCommandPtr cmd;
    char *ifacename = NULL;

    cmd = virCommandNewArgs(baseargv);
    virCommandAddArgSet(cmd, extraargv);

    if (initiatoriqn) {
        switch (virStorageBackendIQNFound(initiatoriqn, &ifacename)) {
        case IQN_FOUND:
            VIR_DEBUG("ifacename: '%s'", ifacename);
            break;
        case IQN_MISSING:
            if (virStorageBackendCreateIfaceIQN(initiatoriqn, &ifacename) != 0)
                goto cleanup;
            /*
             * iscsiadm doesn't let you send commands to the Interface IQN,
             * unless you've first issued a 'sendtargets' command to the
             * portal. Without the sendtargets all that is received is a
             * "iscsiadm: No records found"
             */
            if (virISCSIScanTargets(portal, NULL, NULL) < 0)
                goto cleanup;

            break;
        case IQN_ERROR:
        default:
            goto cleanup;
        }
        virCommandAddArgList(cmd, "--interface", ifacename, NULL);
    }

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

    ret = 0;

 cleanup:
    virCommandFree(cmd);
    VIR_FREE(ifacename);

    return ret;
}
예제 #2
0
static int
virStorageBackendISCSIConnectionIQN(virStoragePoolObjPtr pool,
                                    const char *portal,
                                    const char *action)
{
    int ret = -1;
    char *ifacename = NULL;

    switch (virStorageBackendIQNFound(pool, &ifacename)) {
    case IQN_FOUND:
        VIR_DEBUG("ifacename: '%s'", ifacename);
        break;
    case IQN_MISSING:
        if (virStorageBackendCreateIfaceIQN(pool, &ifacename) != 0) {
            goto out;
        }
        break;
    case IQN_ERROR:
    default:
        goto out;
    }

    const char *const sendtargets[] = {
        ISCSIADM, "--mode", "discovery", "--type", "sendtargets", "--portal", portal, NULL
    };
    if (virRun(sendtargets, NULL) < 0) {
        virStorageReportError(VIR_ERR_INTERNAL_ERROR,
                              _("Failed to run %s to get target list"),
                              sendtargets[0]);
        goto out;
    }

    const char *const cmdargv[] = {
        ISCSIADM, "--mode", "node", "--portal", portal,
        "--targetname", pool->def->source.devices[0].path, "--interface",
        ifacename, action, NULL
    };

    if (virRun(cmdargv, NULL) < 0) {
        virStorageReportError(VIR_ERR_INTERNAL_ERROR,
                              _("Failed to run command '%s' with action '%s'"),
                              cmdargv[0], action);
        goto out;
    }

    ret = 0;

out:
    VIR_FREE(ifacename);
    return ret;
}
예제 #3
0
static int
virStorageBackendISCSIConnection(const char *portal,
                                 const char *initiatoriqn,
                                 const char *target,
                                 const char **extraargv)
{
    int ret = -1;
    const char *const baseargv[] = {
        ISCSIADM,
        "--mode", "node",
        "--portal", portal,
        "--targetname", target,
        NULL
    };
    virCommandPtr cmd;
    char *ifacename = NULL;

    cmd = virCommandNewArgs(baseargv);
    virCommandAddArgSet(cmd, extraargv);

    if (initiatoriqn) {
        switch (virStorageBackendIQNFound(initiatoriqn, &ifacename)) {
        case IQN_FOUND:
            VIR_DEBUG("ifacename: '%s'", ifacename);
            break;
        case IQN_MISSING:
            if (virStorageBackendCreateIfaceIQN(initiatoriqn,
                                                &ifacename) != 0) {
                goto cleanup;
            }
            break;
        case IQN_ERROR:
        default:
            goto cleanup;
        }
        virCommandAddArgList(cmd, "--interface", ifacename, NULL);
    }

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

    ret = 0;

cleanup:
    virCommandFree(cmd);
    VIR_FREE(ifacename);

    return ret;
}
예제 #4
0
static int
virStorageBackendCreateIfaceIQN(const char *initiatoriqn,
                                char **ifacename)
{
    int ret = -1, exitstatus = -1;
    char temp_ifacename[32];
    const char *const cmdargv1[] = {
        ISCSIADM, "--mode", "iface", "--interface",
        temp_ifacename, "--op", "new", NULL
    };
    const char *const cmdargv2[] = {
        ISCSIADM, "--mode", "iface", "--interface", temp_ifacename,
        "--op", "update", "--name", "iface.initiatorname", "--value",
        initiatoriqn, NULL
    };

    if (virRandomInitialize(time(NULL) ^ getpid()) == -1) {
        virStorageReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                              _("Failed to initialize random generator "
                                "when creating iscsi interface"));
        goto out;
    }

    snprintf(temp_ifacename, sizeof(temp_ifacename), "libvirt-iface-%08x",
             virRandom(1024 * 1024 * 1024));

    VIR_DEBUG("Attempting to create interface '%s' with IQN '%s'",
              &temp_ifacename[0], initiatoriqn);

    /* Note that we ignore the exitstatus.  Older versions of iscsiadm
     * tools returned an exit status of > 0, even if they succeeded.
     * We will just rely on whether the interface got created
     * properly. */
    if (virRun(cmdargv1, &exitstatus) < 0) {
        virStorageReportError(VIR_ERR_INTERNAL_ERROR,
                              _("Failed to run command '%s' to create new iscsi interface"),
                              cmdargv1[0]);
        goto out;
    }

    /* Note that we ignore the exitstatus.  Older versions of iscsiadm tools
     * returned an exit status of > 0, even if they succeeded.  We will just
     * rely on whether iface file got updated properly. */
    if (virRun(cmdargv2, &exitstatus) < 0) {
        virStorageReportError(VIR_ERR_INTERNAL_ERROR,
                              _("Failed to run command '%s' to update iscsi interface with IQN '%s'"),
                              cmdargv2[0], initiatoriqn);
        goto out;
    }

    /* Check again to make sure the interface was created. */
    if (virStorageBackendIQNFound(initiatoriqn, ifacename) != IQN_FOUND) {
        VIR_DEBUG("Failed to find interface '%s' with IQN '%s' "
                  "after attempting to create it",
                  &temp_ifacename[0], initiatoriqn);
        goto out;
    } else {
        VIR_DEBUG("Interface '%s' with IQN '%s' was created successfully",
                  *ifacename, initiatoriqn);
    }

    ret = 0;

out:
    if (ret != 0)
        VIR_FREE(*ifacename);
    return ret;
}
예제 #5
0
파일: viriscsi.c 프로젝트: RWTH-OS/libvirt
static int
virStorageBackendCreateIfaceIQN(const char *initiatoriqn,
                                char **ifacename)
{
    int ret = -1, exitstatus = -1;
    char *temp_ifacename;
    virCommandPtr cmd = NULL;

    if (virAsprintf(&temp_ifacename,
                    "libvirt-iface-%08llx",
                    (unsigned long long)virRandomBits(30)) < 0)
        return -1;

    VIR_DEBUG("Attempting to create interface '%s' with IQN '%s'",
              temp_ifacename, initiatoriqn);

    cmd = virCommandNewArgList(ISCSIADM,
                               "--mode", "iface",
                               "--interface", temp_ifacename,
                               "--op", "new",
                               NULL);
    /* Note that we ignore the exitstatus.  Older versions of iscsiadm
     * tools returned an exit status of > 0, even if they succeeded.
     * We will just rely on whether the interface got created
     * properly. */
    if (virCommandRun(cmd, &exitstatus) < 0) {
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("Failed to run command '%s' to create new iscsi interface"),
                       ISCSIADM);
        goto cleanup;
    }
    virCommandFree(cmd);

    cmd = virCommandNewArgList(ISCSIADM,
                               "--mode", "iface",
                               "--interface", temp_ifacename,
                               "--op", "update",
                               "--name", "iface.initiatorname",
                               "--value",
                               initiatoriqn,
                               NULL);
    /* Note that we ignore the exitstatus.  Older versions of iscsiadm tools
     * returned an exit status of > 0, even if they succeeded.  We will just
     * rely on whether iface file got updated properly. */
    if (virCommandRun(cmd, &exitstatus) < 0) {
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("Failed to run command '%s' to update iscsi interface with IQN '%s'"),
                       ISCSIADM, initiatoriqn);
        goto cleanup;
    }

    /* Check again to make sure the interface was created. */
    if (virStorageBackendIQNFound(initiatoriqn, ifacename) != IQN_FOUND) {
        VIR_DEBUG("Failed to find interface '%s' with IQN '%s' "
                  "after attempting to create it",
                  &temp_ifacename[0], initiatoriqn);
        goto cleanup;
    } else {
        VIR_DEBUG("Interface '%s' with IQN '%s' was created successfully",
                  *ifacename, initiatoriqn);
    }

    ret = 0;

 cleanup:
    virCommandFree(cmd);
    VIR_FREE(temp_ifacename);
    if (ret != 0)
        VIR_FREE(*ifacename);
    return ret;
}