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:
parent
adeadc53a7
commit
f28099ddd7
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user