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; }
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; }
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; }
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; }
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; }