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: Daniel P. Berrange <berrange@redhat.com>
This commit is contained in:
Daniel P. Berrange 2012-12-11 19:10:51 +00:00
parent f6b5ed5ef0
commit 41ac222e52
2 changed files with 53 additions and 27 deletions

View File

@ -1218,62 +1218,75 @@ int virStorageFileIsClusterFS(const char *path)
} }
#ifdef LVS #ifdef LVS
char *virStorageFileGetLVMKey(const char *path) int virStorageFileGetLVMKey(const char *path,
char **key)
{ {
/* /*
* # lvs --noheadings --unbuffered --nosuffix --options "uuid" LVNAME * # lvs --noheadings --unbuffered --nosuffix --options "uuid" LVNAME
* 06UgP5-2rhb-w3Bo-3mdR-WeoL-pytO-SAa2ky * 06UgP5-2rhb-w3Bo-3mdR-WeoL-pytO-SAa2ky
*/ */
char *key = NULL; int status;
virCommandPtr cmd = virCommandNewArgList( virCommandPtr cmd = virCommandNewArgList(
LVS, LVS,
"--noheadings", "--unbuffered", "--nosuffix", "--noheadings", "--unbuffered", "--nosuffix",
"--options", "uuid", path, "--options", "uuid", path,
NULL NULL
); );
int ret = -1;
*key = NULL;
/* Run the program and capture its output */ /* Run the program and capture its output */
virCommandSetOutputBuffer(cmd, &key); virCommandSetOutputBuffer(cmd, key);
if (virCommandRun(cmd, NULL) < 0) if (virCommandRun(cmd, &status) < 0)
goto cleanup; 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 *nl;
char *tmp = key; char *tmp = *key;
/* Find first non-space character */ /* Find first non-space character */
while (*tmp && c_isspace(*tmp)) { while (*tmp && c_isspace(*tmp)) {
tmp++; tmp++;
} }
/* Kill leading spaces */ /* Kill leading spaces */
if (tmp != key) if (tmp != *key)
memmove(key, tmp, strlen(tmp)+1); memmove(*key, tmp, strlen(tmp)+1);
/* Kill trailing newline */ /* Kill trailing newline */
if ((nl = strchr(key, '\n'))) if ((nl = strchr(*key, '\n')))
*nl = '\0'; *nl = '\0';
} }
if (key && STREQ(key, "")) ret = 0;
VIR_FREE(key);
cleanup: cleanup:
if (*key && STREQ(*key, ""))
VIR_FREE(*key);
virCommandFree(cmd); virCommandFree(cmd);
return key; return ret;
} }
#else #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); virReportSystemError(ENOSYS, _("Unable to get LVM key for %s"), path);
return NULL; return -1;
} }
#endif #endif
#ifdef HAVE_UDEV #ifdef HAVE_UDEV
char *virStorageFileGetSCSIKey(const char *path) int virStorageFileGetSCSIKey(const char *path,
char **key)
{ {
char *key = NULL; int status;
virCommandPtr cmd = virCommandNewArgList( virCommandPtr cmd = virCommandNewArgList(
"/lib/udev/scsi_id", "/lib/udev/scsi_id",
"--replace-whitespace", "--replace-whitespace",
@ -1281,30 +1294,41 @@ char *virStorageFileGetSCSIKey(const char *path)
"--device", path, "--device", path,
NULL NULL
); );
int ret = -1;
*key = NULL;
/* Run the program and capture its output */ /* Run the program and capture its output */
virCommandSetOutputBuffer(cmd, &key); virCommandSetOutputBuffer(cmd, key);
if (virCommandRun(cmd, NULL) < 0) if (virCommandRun(cmd, &status) < 0)
goto cleanup; goto cleanup;
if (key && STRNEQ(key, "")) { /* Explicitly check status == 0, rather than passing NULL
char *nl = strchr(key, '\n'); * 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) if (nl)
*nl = '\0'; *nl = '\0';
} else {
VIR_FREE(key);
} }
ret = 0;
cleanup: cleanup:
if (*key && STREQ(*key, ""))
VIR_FREE(*key);
virCommandFree(cmd); virCommandFree(cmd);
return key; return ret;
} }
#else #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); virReportSystemError(ENOSYS, _("Unable to get SCSI key for %s"), path);
return NULL; return -1;
} }
#endif #endif

View File

@ -101,7 +101,9 @@ int virStorageFileIsClusterFS(const char *path);
int virStorageFileIsSharedFSType(const char *path, int virStorageFileIsSharedFSType(const char *path,
int fstypes); int fstypes);
char *virStorageFileGetLVMKey(const char *path); int virStorageFileGetLVMKey(const char *path,
char *virStorageFileGetSCSIKey(const char *path); char **key);
int virStorageFileGetSCSIKey(const char *path,
char **key);
#endif /* __VIR_STORAGE_FILE_H__ */ #endif /* __VIR_STORAGE_FILE_H__ */