提交 41ac222e 编写于 作者: D Daniel P. Berrange

Fix error reporting when fetching SCSI/LVM keys

The current  virStorageFileGet{LVM,SCSI}Key methods return
the key as the return value. Unfortunately it is desirable
for "NULL" to be a valid return value, as well as an error
indicator. Thus the returned key must instead be provided
as an out-parameter.

When we invoke lvs or scsi_id to extract ID for block devices,
we don't want virCommandWait logging errors messages. Thus we
must explicitly check 'status != 0', rather than letting
virCommandWait do it.
Signed-off-by: NDaniel P. Berrange <berrange@redhat.com>
上级 f6b5ed5e
......@@ -1218,62 +1218,75 @@ int virStorageFileIsClusterFS(const char *path)
}
#ifdef LVS
char *virStorageFileGetLVMKey(const char *path)
int virStorageFileGetLVMKey(const char *path,
char **key)
{
/*
* # lvs --noheadings --unbuffered --nosuffix --options "uuid" LVNAME
* 06UgP5-2rhb-w3Bo-3mdR-WeoL-pytO-SAa2ky
*/
char *key = NULL;
int status;
virCommandPtr cmd = virCommandNewArgList(
LVS,
"--noheadings", "--unbuffered", "--nosuffix",
"--options", "uuid", path,
NULL
);
int ret = -1;
*key = NULL;
/* Run the program and capture its output */
virCommandSetOutputBuffer(cmd, &key);
if (virCommandRun(cmd, NULL) < 0)
virCommandSetOutputBuffer(cmd, key);
if (virCommandRun(cmd, &status) < 0)
goto cleanup;
if (key) {
/* Explicitly check status == 0, rather than passing NULL
* to virCommandRun because we don't want to raise an actual
* error in this scenario, just return a NULL key.
*/
if (status == 0 && *key) {
char *nl;
char *tmp = key;
char *tmp = *key;
/* Find first non-space character */
while (*tmp && c_isspace(*tmp)) {
tmp++;
}
/* Kill leading spaces */
if (tmp != key)
memmove(key, tmp, strlen(tmp)+1);
if (tmp != *key)
memmove(*key, tmp, strlen(tmp)+1);
/* Kill trailing newline */
if ((nl = strchr(key, '\n')))
if ((nl = strchr(*key, '\n')))
*nl = '\0';
}
if (key && STREQ(key, ""))
VIR_FREE(key);
ret = 0;
cleanup:
if (*key && STREQ(*key, ""))
VIR_FREE(*key);
virCommandFree(cmd);
return key;
return ret;
}
#else
char *virStorageFileGetLVMKey(const char *path)
int virStorageFileGetLVMKey(const char *path,
char **key ATTRIBUTE_UNUSED)
{
virReportSystemError(ENOSYS, _("Unable to get LVM key for %s"), path);
return NULL;
return -1;
}
#endif
#ifdef HAVE_UDEV
char *virStorageFileGetSCSIKey(const char *path)
int virStorageFileGetSCSIKey(const char *path,
char **key)
{
char *key = NULL;
int status;
virCommandPtr cmd = virCommandNewArgList(
"/lib/udev/scsi_id",
"--replace-whitespace",
......@@ -1281,30 +1294,41 @@ char *virStorageFileGetSCSIKey(const char *path)
"--device", path,
NULL
);
int ret = -1;
*key = NULL;
/* Run the program and capture its output */
virCommandSetOutputBuffer(cmd, &key);
if (virCommandRun(cmd, NULL) < 0)
virCommandSetOutputBuffer(cmd, key);
if (virCommandRun(cmd, &status) < 0)
goto cleanup;
if (key && STRNEQ(key, "")) {
char *nl = strchr(key, '\n');
/* Explicitly check status == 0, rather than passing NULL
* to virCommandRun because we don't want to raise an actual
* error in this scenario, just return a NULL key.
*/
if (status == 0 && *key) {
char *nl = strchr(*key, '\n');
if (nl)
*nl = '\0';
} else {
VIR_FREE(key);
}
ret = 0;
cleanup:
if (*key && STREQ(*key, ""))
VIR_FREE(*key);
virCommandFree(cmd);
return key;
return ret;
}
#else
char *virStorageFileGetSCSIKey(const char *path)
int virStorageFileGetSCSIKey(const char *path,
char **key ATTRIBUTE_UNUSED)
{
virReportSystemError(ENOSYS, _("Unable to get SCSI key for %s"), path);
return NULL;
return -1;
}
#endif
......
......@@ -101,7 +101,9 @@ int virStorageFileIsClusterFS(const char *path);
int virStorageFileIsSharedFSType(const char *path,
int fstypes);
char *virStorageFileGetLVMKey(const char *path);
char *virStorageFileGetSCSIKey(const char *path);
int virStorageFileGetLVMKey(const char *path,
char **key);
int virStorageFileGetSCSIKey(const char *path,
char **key);
#endif /* __VIR_STORAGE_FILE_H__ */
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册