1
0
mirror of https://gitlab.com/libvirt/libvirt.git synced 2025-03-07 17:28:15 +00:00

virStorageBackendIQNFound: Rework iscsiadm output parsing

Firstly, we can utilize virCommandSetOutputBuffer() API which
will collect the command output for us. Secondly, sscanf()-ing
through each line is easier to understand (and more robust) than
jumping over a string with strchr().

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: John Ferlan <jferlan@redhat.com>
This commit is contained in:
Michal Privoznik 2018-06-29 11:34:23 +02:00
parent adeadc53a7
commit f28099ddd7

View File

@ -108,7 +108,6 @@ virISCSIGetSession(const char *devpath,
#define LINE_SIZE 4096
#define IQN_FOUND 1 #define IQN_FOUND 1
#define IQN_MISSING 0 #define IQN_MISSING 0
#define IQN_ERROR -1 #define IQN_ERROR -1
@ -117,71 +116,56 @@ static int
virStorageBackendIQNFound(const char *initiatoriqn, virStorageBackendIQNFound(const char *initiatoriqn,
char **ifacename) char **ifacename)
{ {
int ret = IQN_ERROR, fd = -1; int ret = IQN_ERROR;
char ebuf[64]; char *outbuf = NULL;
FILE *fp = NULL; char *line = NULL;
char *line = NULL, *newline = NULL, *iqn = NULL, *token = NULL; char *iface = NULL;
char *iqn = NULL;
virCommandPtr cmd = virCommandNewArgList(ISCSIADM, virCommandPtr cmd = virCommandNewArgList(ISCSIADM,
"--mode", "iface", NULL); "--mode", "iface", NULL);
*ifacename = NULL; *ifacename = NULL;
if (VIR_ALLOC_N(line, LINE_SIZE) != 0) { virCommandSetOutputBuffer(cmd, &outbuf);
virReportError(VIR_ERR_INTERNAL_ERROR, if (virCommandRun(cmd, NULL) < 0)
_("Could not allocate memory for output of '%s'"),
ISCSIADM);
goto cleanup;
}
memset(line, 0, LINE_SIZE);
virCommandSetOutputFD(cmd, &fd);
if (virCommandRunAsync(cmd, NULL) < 0)
goto cleanup; goto cleanup;
if ((fp = VIR_FDOPEN(fd, "r")) == NULL) { /* Example of data we are dealing with:
virReportError(VIR_ERR_INTERNAL_ERROR, * default tcp,<empty>,<empty>,<empty>,<empty>
_("Failed to open stream for file descriptor " * iser iser,<empty>,<empty>,<empty>,<empty>
"when reading output from '%s': '%s'"), * libvirt-iface-253db048 tcp,<empty>,<empty>,<empty>,iqn.2017-03.com.user:client
ISCSIADM, virStrerror(errno, ebuf, sizeof(ebuf))); */
goto cleanup;
} line = outbuf;
while (line && *line) {
char *newline;
int num;
if (!(newline = strchr(line, '\n')))
break;
while (fgets(line, LINE_SIZE, fp) != NULL) {
newline = strrchr(line, '\n');
if (newline == NULL) {
virReportError(VIR_ERR_INTERNAL_ERROR,
_("Unexpected line > %d characters "
"when parsing output of '%s'"),
LINE_SIZE, ISCSIADM);
goto cleanup;
}
*newline = '\0'; *newline = '\0';
iqn = strrchr(line, ','); VIR_FREE(iface);
if (iqn == NULL) VIR_FREE(iqn);
continue; num = sscanf(line, "%ms %*[^,],%*[^,],%*[^,],%*[^,],%ms", &iface, &iqn);
iqn++;
if (STREQ(iqn, initiatoriqn)) { if (num != 2) {
token = strchr(line, ' ');
if (!token) {
virReportError(VIR_ERR_INTERNAL_ERROR, virReportError(VIR_ERR_INTERNAL_ERROR,
_("Missing space when parsing output " _("malformed output of %s: %s"),
"of '%s'"), ISCSIADM); ISCSIADM, line);
goto cleanup; goto cleanup;
} }
if (VIR_STRNDUP(*ifacename, line, token - line) < 0) if (STREQ(iqn, initiatoriqn)) {
goto cleanup; VIR_STEAL_PTR(*ifacename, iface);
VIR_DEBUG("Found interface '%s' with IQN '%s'", *ifacename, iqn); VIR_DEBUG("Found interface '%s' with IQN '%s'", *ifacename, iqn);
break; break;
} }
}
if (virCommandWait(cmd, NULL) < 0) line = newline + 1;
goto cleanup; }
ret = *ifacename ? IQN_FOUND : IQN_MISSING; ret = *ifacename ? IQN_FOUND : IQN_MISSING;
@ -189,11 +173,10 @@ virStorageBackendIQNFound(const char *initiatoriqn,
if (ret == IQN_MISSING) if (ret == IQN_MISSING)
VIR_DEBUG("Could not find interface with IQN '%s'", iqn); VIR_DEBUG("Could not find interface with IQN '%s'", iqn);
VIR_FREE(line); VIR_FREE(iqn);
VIR_FORCE_FCLOSE(fp); VIR_FREE(iface);
VIR_FORCE_CLOSE(fd); VIR_FREE(outbuf);
virCommandFree(cmd); virCommandFree(cmd);
return ret; return ret;
} }