maint: improve VIR_ERR_OPERATION_DENIED usage

Some of our operation denied messages are outright stupid; for
example, if virIdentitySetAttr fails:

error: operation Identity attribute is already set forbidden for read only access

This patch fixes things to a saner:

error: operation forbidden: Identity attribute is already set

It also consolidates the most common usage pattern for operation
denied errors: read-only connections preventing a public API.  In
this case, 'virsh -r -c test:///default destroy test' changes from:

error: operation virDomainDestroy forbidden for read only access

to:

error: operation forbidden: read only access prevents virDomainDestroy

Note that we were previously inconsistent on which APIs used
VIR_FROM_DOM (such as virDomainDestroy) vs. VIR_FROM_NONE (such as
virDomainPMSuspendForDuration).  After this patch, all uses
consistently use VIR_FROM_NONE, on the grounds that it is unlikely
that a caller learning that a call is denied can do anything in
particular with extra knowledge which error domain the call belongs
to (similar to what we did in commit baa7244).

* src/util/virerror.c (virErrorMsg): Rework OPERATION_DENIED error
message.
* src/internal.h (virCheckReadOnlyGoto): New macro.
* src/util/virerror.h (virReportRestrictedError): New macro.
* src/libvirt-lxc.c: Use new macros.
* src/libvirt-qemu.c: Likewise.
* src/libvirt.c: Likewise.
* src/locking/lock_daemon.c (virLockDaemonClientNew): Likewise.

Signed-off-by: Eric Blake <eblake@redhat.com>
This commit is contained in:
Eric Blake 2013-12-20 07:02:49 -07:00
parent 6e7490c734
commit d219826c65
7 changed files with 176 additions and 633 deletions

View File

@ -1,7 +1,7 @@
/*
* internal.h: internal definitions just used by code from the library
*
* Copyright (C) 2006-2013 Red Hat, Inc.
* Copyright (C) 2006-2014 Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@ -350,6 +350,15 @@
goto label; \
} \
} while (0)
# define virCheckReadOnlyGoto(flags, label) \
do { \
if ((flags) & VIR_CONNECT_RO) { \
virReportRestrictedError(_("read only access prevents %s"), \
__FUNCTION__); \
goto label; \
} \
} while (0)
/* divide value by size, rounding up */

View File

@ -83,11 +83,7 @@ virDomainLxcOpenNamespace(virDomainPtr domain,
conn = domain->conn;
virCheckNonNullArgGoto(fdlist, error);
if (conn->flags & VIR_CONNECT_RO) {
virLibDomainError(domain, VIR_ERR_OPERATION_DENIED, __FUNCTION__);
goto error;
}
virCheckReadOnlyGoto(conn->flags, error);
if (conn->driver->domainLxcOpenNamespace) {
int ret;

View File

@ -90,11 +90,7 @@ virDomainQemuMonitorCommand(virDomainPtr domain, const char *cmd,
conn = domain->conn;
virCheckNonNullArgGoto(result, error);
if (conn->flags & VIR_CONNECT_RO) {
virLibDomainError(domain, VIR_ERR_OPERATION_DENIED, __FUNCTION__);
goto error;
}
virCheckReadOnlyGoto(conn->flags, error);
if (conn->driver->domainQemuMonitorCommand) {
int ret;
@ -167,10 +163,7 @@ virDomainQemuAttach(virConnectPtr conn,
goto error;
}
if (conn->flags & VIR_CONNECT_RO) {
virLibDomainError(domain, VIR_ERR_OPERATION_DENIED, __FUNCTION__);
goto error;
}
virCheckReadOnlyGoto(conn->flags, error);
if (conn->driver->domainQemuAttach) {
virDomainPtr ret;
@ -229,10 +222,7 @@ virDomainQemuAgentCommand(virDomainPtr domain,
conn = domain->conn;
if (conn->flags & VIR_CONNECT_RO) {
virLibDomainError(NULL, VIR_ERR_OPERATION_DENIED, __FUNCTION__);
goto error;
}
virCheckReadOnlyGoto(conn->flags, error);
if (conn->driver->domainQemuAgentCommand) {
ret = conn->driver->domainQemuAgentCommand(domain, cmd,

File diff suppressed because it is too large Load Diff

View File

@ -1,7 +1,7 @@
/*
* lock_daemon.c: lock management daemon
*
* Copyright (C) 2006-2012 Red Hat, Inc.
* Copyright (C) 2006-2014 Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@ -800,18 +800,16 @@ virLockDaemonClientNew(virNetServerClientPtr client,
if (!privileged) {
if (geteuid() != clientuid) {
virReportError(VIR_ERR_OPERATION_DENIED,
_("Disallowing client %llu with uid %llu"),
(unsigned long long)priv->clientPid,
(unsigned long long)clientuid);
virReportRestrictedError(_("Disallowing client %llu with uid %llu"),
(unsigned long long)priv->clientPid,
(unsigned long long)clientuid);
goto error;
}
} else {
if (clientuid != 0) {
virReportError(VIR_ERR_OPERATION_DENIED,
_("Disallowing client %llu with uid %llu"),
(unsigned long long)priv->clientPid,
(unsigned long long)clientuid);
virReportRestrictedError(_("Disallowing client %llu with uid %llu"),
(unsigned long long)priv->clientPid,
(unsigned long long)clientuid);
goto error;
}
}

View File

@ -1,7 +1,7 @@
/*
* virerror.c: error handling and reporting code for libvirt
*
* Copyright (C) 2006, 2008-2013 Red Hat, Inc.
* Copyright (C) 2006, 2008-2014 Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@ -888,7 +888,7 @@ virErrorMsg(virErrorNumber error, const char *info)
if (info == NULL)
errmsg = _("operation forbidden for read only access");
else
errmsg = _("operation %s forbidden for read only access");
errmsg = _("operation forbidden: %s");
break;
case VIR_ERR_OPEN_FAILED:
if (info == NULL)

View File

@ -159,6 +159,9 @@ void virReportSystemErrorFull(int domcode,
# define virReportUnsupportedError() \
virReportErrorHelper(VIR_FROM_THIS, VIR_ERR_NO_SUPPORT, \
__FILE__, __FUNCTION__, __LINE__, __FUNCTION__)
# define virReportRestrictedError(...) \
virReportErrorHelper(VIR_FROM_THIS, VIR_ERR_OPERATION_DENIED, \
__FILE__, __FUNCTION__, __LINE__, __VA_ARGS__)
void virReportOOMErrorFull(int domcode,