mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-01-08 14:05:19 +00:00
de1e0ae0e3
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>
429 lines
13 KiB
C
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;
|
|
}
|