libvirt/src/locking/lock_daemon_dispatch.c
Jim Fehlig de1e0ae0e3 virtlockd: Don't report error if lockspace exists
When the qemu or libxl driver is configured to use lockd and
file_lockspace_dir is set, virtlockd emits an error when libvirtd
is retarted

May 25 15:44:31 virt81 virtlockd[7723]: Requested operation is not
valid: Lockspace for path /data/libvirtd/lockspace already exists

There is really no need to fail when the lockspace already exists,
paricularly since the user is expected to create the lockspace
specified in file_lockspace_dir. Failure to do so will prevent
starting any domains

virsh start test
error: Failed to start domain 'test'
error: Unable to open/create resource /data/libvirtd/lockspace/de22c4bf931e7c48b49e8ca64b477d44e78a51543e534df488b05ccd08ec5caa: No such file or directory

Also, virLockManagerLockDaemonSetupLockspace already has logic to ignore
the error. Since callers are not interested in the error, change
virtlockd to not report or return an error when the specified lockspace
already exists.

Signed-off-by: Jim Fehlig <jfehlig@suse.com>
Reviewed-by: Daniel Henrique Barboza <danielhb413@gmail.com>
2021-07-07 09:40:38 -06:00

429 lines
13 KiB
C

/*
* lock_daemon_dispatch.c: lock management daemon dispatch
*
* Copyright (C) 2006-2015 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
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; If not, see
* <http://www.gnu.org/licenses/>.
*/
#include <config.h>
#include "rpc/virnetdaemon.h"
#include "rpc/virnetserverclient.h"
#include "virlog.h"
#include "virstring.h"
#include "lock_daemon.h"
#include "lock_protocol.h"
#include "virerror.h"
#include "virthreadjob.h"
#define VIR_FROM_THIS VIR_FROM_RPC
VIR_LOG_INIT("locking.lock_daemon_dispatch");
#include "lock_daemon_dispatch_stubs.h"
static int
virLockSpaceProtocolDispatchAcquireResource(virNetServer *server G_GNUC_UNUSED,
virNetServerClient *client,
virNetMessage *msg G_GNUC_UNUSED,
struct virNetMessageError *rerr,
virLockSpaceProtocolAcquireResourceArgs *args)
{
int rv = -1;
unsigned int flags = args->flags;
virLockDaemonClient *priv =
virNetServerClientGetPrivateData(client);
virLockSpace *lockspace;
unsigned int newFlags;
g_mutex_lock(&priv->lock);
virCheckFlagsGoto(VIR_LOCK_SPACE_PROTOCOL_ACQUIRE_RESOURCE_SHARED |
VIR_LOCK_SPACE_PROTOCOL_ACQUIRE_RESOURCE_AUTOCREATE, cleanup);
if (priv->restricted) {
virReportError(VIR_ERR_OPERATION_DENIED, "%s",
_("lock manager connection has been restricted"));
goto cleanup;
}
if (!priv->ownerId) {
virReportError(VIR_ERR_OPERATION_INVALID, "%s",
_("lock owner details have not been registered"));
goto cleanup;
}
if (!(lockspace = virLockDaemonFindLockSpace(lockDaemon, args->path))) {
virReportError(VIR_ERR_INTERNAL_ERROR,
_("Lockspace for path %s does not exist"),
args->path);
goto cleanup;
}
newFlags = 0;
if (flags & VIR_LOCK_SPACE_PROTOCOL_ACQUIRE_RESOURCE_SHARED)
newFlags |= VIR_LOCK_SPACE_ACQUIRE_SHARED;
if (flags & VIR_LOCK_SPACE_PROTOCOL_ACQUIRE_RESOURCE_AUTOCREATE)
newFlags |= VIR_LOCK_SPACE_ACQUIRE_AUTOCREATE;
if (virLockSpaceAcquireResource(lockspace,
args->name,
priv->ownerPid,
newFlags) < 0)
goto cleanup;
rv = 0;
cleanup:
if (rv < 0)
virNetMessageSaveError(rerr);
g_mutex_unlock(&priv->lock);
return rv;
}
static int
virLockSpaceProtocolDispatchCreateResource(virNetServer *server G_GNUC_UNUSED,
virNetServerClient *client,
virNetMessage *msg G_GNUC_UNUSED,
struct virNetMessageError *rerr,
virLockSpaceProtocolCreateResourceArgs *args)
{
int rv = -1;
unsigned int flags = args->flags;
virLockDaemonClient *priv =
virNetServerClientGetPrivateData(client);
virLockSpace *lockspace;
g_mutex_lock(&priv->lock);
virCheckFlagsGoto(0, cleanup);
if (priv->restricted) {
virReportError(VIR_ERR_OPERATION_DENIED, "%s",
_("lock manager connection has been restricted"));
goto cleanup;
}
if (!priv->ownerId) {
virReportError(VIR_ERR_OPERATION_INVALID, "%s",
_("lock owner details have not been registered"));
goto cleanup;
}
if (!(lockspace = virLockDaemonFindLockSpace(lockDaemon, args->path))) {
virReportError(VIR_ERR_INTERNAL_ERROR,
_("Lockspace for path %s does not exist"),
args->path);
goto cleanup;
}
if (virLockSpaceCreateResource(lockspace, args->name) < 0)
goto cleanup;
rv = 0;
cleanup:
if (rv < 0)
virNetMessageSaveError(rerr);
g_mutex_unlock(&priv->lock);
return rv;
}
static int
virLockSpaceProtocolDispatchDeleteResource(virNetServer *server G_GNUC_UNUSED,
virNetServerClient *client,
virNetMessage *msg G_GNUC_UNUSED,
struct virNetMessageError *rerr,
virLockSpaceProtocolDeleteResourceArgs *args)
{
int rv = -1;
unsigned int flags = args->flags;
virLockDaemonClient *priv =
virNetServerClientGetPrivateData(client);
virLockSpace *lockspace;
g_mutex_lock(&priv->lock);
virCheckFlagsGoto(0, cleanup);
if (priv->restricted) {
virReportError(VIR_ERR_OPERATION_DENIED, "%s",
_("lock manager connection has been restricted"));
goto cleanup;
}
if (!priv->ownerId) {
virReportError(VIR_ERR_OPERATION_INVALID, "%s",
_("lock owner details have not been registered"));
goto cleanup;
}
if (!(lockspace = virLockDaemonFindLockSpace(lockDaemon, args->path))) {
virReportError(VIR_ERR_INTERNAL_ERROR,
_("Lockspace for path %s does not exist"),
args->path);
goto cleanup;
}
if (virLockSpaceDeleteResource(lockspace, args->name) < 0)
goto cleanup;
rv = 0;
cleanup:
if (rv < 0)
virNetMessageSaveError(rerr);
g_mutex_unlock(&priv->lock);
return rv;
}
static int
virLockSpaceProtocolDispatchNew(virNetServer *server G_GNUC_UNUSED,
virNetServerClient *client,
virNetMessage *msg G_GNUC_UNUSED,
struct virNetMessageError *rerr,
virLockSpaceProtocolNewArgs *args)
{
int rv = -1;
unsigned int flags = args->flags;
virLockDaemonClient *priv =
virNetServerClientGetPrivateData(client);
virLockSpace *lockspace;
g_mutex_lock(&priv->lock);
virCheckFlagsGoto(0, cleanup);
if (priv->restricted) {
virReportError(VIR_ERR_OPERATION_DENIED, "%s",
_("lock manager connection has been restricted"));
goto cleanup;
}
if (!priv->ownerId) {
virReportError(VIR_ERR_OPERATION_INVALID, "%s",
_("lock owner details have not been registered"));
goto cleanup;
}
if (!args->path || STREQ(args->path, "")) {
virReportError(VIR_ERR_OPERATION_INVALID, "%s",
_("the default lockspace already exists"));
goto cleanup;
}
if (virLockDaemonFindLockSpace(lockDaemon, args->path) != NULL) {
virReportError(VIR_ERR_INTERNAL_ERROR,
_("Lockspace for path %s already exists"),
args->path);
goto cleanup;
}
virResetLastError();
lockspace = virLockSpaceNew(args->path);
virLockDaemonAddLockSpace(lockDaemon, args->path, lockspace);
rv = 0;
cleanup:
if (rv < 0)
virNetMessageSaveError(rerr);
g_mutex_unlock(&priv->lock);
return rv;
}
static int
virLockSpaceProtocolDispatchRegister(virNetServer *server G_GNUC_UNUSED,
virNetServerClient *client,
virNetMessage *msg G_GNUC_UNUSED,
struct virNetMessageError *rerr,
virLockSpaceProtocolRegisterArgs *args)
{
int rv = -1;
unsigned int flags = args->flags;
virLockDaemonClient *priv =
virNetServerClientGetPrivateData(client);
g_mutex_lock(&priv->lock);
virCheckFlagsGoto(0, cleanup);
if (priv->restricted) {
virReportError(VIR_ERR_OPERATION_DENIED, "%s",
_("lock manager connection has been restricted"));
goto cleanup;
}
if (!args->owner.id) {
virReportError(VIR_ERR_OPERATION_INVALID, "%s",
_("lock owner details have not been registered"));
goto cleanup;
}
priv->ownerName = g_strdup(args->owner.name);
memcpy(priv->ownerUUID, args->owner.uuid, VIR_UUID_BUFLEN);
priv->ownerId = args->owner.id;
priv->ownerPid = args->owner.pid;
VIR_DEBUG("ownerName=%s ownerId=%d ownerPid=%lld",
priv->ownerName, priv->ownerId, (unsigned long long)priv->ownerPid);
rv = 0;
cleanup:
if (rv < 0)
virNetMessageSaveError(rerr);
g_mutex_unlock(&priv->lock);
return rv;
}
static int
virLockSpaceProtocolDispatchReleaseResource(virNetServer *server G_GNUC_UNUSED,
virNetServerClient *client,
virNetMessage *msg G_GNUC_UNUSED,
struct virNetMessageError *rerr,
virLockSpaceProtocolReleaseResourceArgs *args)
{
int rv = -1;
unsigned int flags = args->flags;
virLockDaemonClient *priv =
virNetServerClientGetPrivateData(client);
virLockSpace *lockspace;
g_mutex_lock(&priv->lock);
virCheckFlagsGoto(0, cleanup);
if (priv->restricted) {
virReportError(VIR_ERR_OPERATION_DENIED, "%s",
_("lock manager connection has been restricted"));
goto cleanup;
}
if (!priv->ownerId) {
virReportError(VIR_ERR_OPERATION_INVALID, "%s",
_("lock owner details have not been registered"));
goto cleanup;
}
if (!(lockspace = virLockDaemonFindLockSpace(lockDaemon, args->path))) {
virReportError(VIR_ERR_INTERNAL_ERROR,
_("Lockspace for path %s does not exist"),
args->path);
goto cleanup;
}
if (virLockSpaceReleaseResource(lockspace,
args->name,
priv->ownerPid) < 0)
goto cleanup;
rv = 0;
cleanup:
if (rv < 0)
virNetMessageSaveError(rerr);
g_mutex_unlock(&priv->lock);
return rv;
}
static int
virLockSpaceProtocolDispatchRestrict(virNetServer *server G_GNUC_UNUSED,
virNetServerClient *client,
virNetMessage *msg G_GNUC_UNUSED,
struct virNetMessageError *rerr,
virLockSpaceProtocolRestrictArgs *args)
{
int rv = -1;
unsigned int flags = args->flags;
virLockDaemonClient *priv =
virNetServerClientGetPrivateData(client);
g_mutex_lock(&priv->lock);
virCheckFlagsGoto(0, cleanup);
if (priv->restricted) {
virReportError(VIR_ERR_OPERATION_DENIED, "%s",
_("lock manager connection has been restricted"));
goto cleanup;
}
if (!priv->ownerId) {
virReportError(VIR_ERR_OPERATION_INVALID, "%s",
_("lock owner details have not been registered"));
goto cleanup;
}
priv->restricted = true;
rv = 0;
cleanup:
if (rv < 0)
virNetMessageSaveError(rerr);
g_mutex_unlock(&priv->lock);
return rv;
}
static int
virLockSpaceProtocolDispatchCreateLockSpace(virNetServer *server G_GNUC_UNUSED,
virNetServerClient *client,
virNetMessage *msg G_GNUC_UNUSED,
struct virNetMessageError *rerr,
virLockSpaceProtocolCreateLockSpaceArgs *args)
{
int rv = -1;
virLockDaemonClient *priv =
virNetServerClientGetPrivateData(client);
virLockSpace *lockspace;
g_mutex_lock(&priv->lock);
if (priv->restricted) {
virReportError(VIR_ERR_OPERATION_DENIED, "%s",
_("lock manager connection has been restricted"));
goto cleanup;
}
if (virLockDaemonFindLockSpace(lockDaemon, args->path) != NULL) {
VIR_DEBUG("Lockspace for path %s already exists", args->path);
rv = 0;
goto cleanup;
}
if (!(lockspace = virLockSpaceNew(args->path)))
goto cleanup;
if (virLockDaemonAddLockSpace(lockDaemon, args->path, lockspace) < 0) {
virLockSpaceFree(lockspace);
goto cleanup;
}
rv = 0;
cleanup:
if (rv < 0)
virNetMessageSaveError(rerr);
g_mutex_unlock(&priv->lock);
return rv;
}