libvirt/src/locking/lock_daemon.c

1197 lines
36 KiB
C
Raw Normal View History

/*
* lock_daemon.c: lock management daemon
*
* 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 <unistd.h>
#include <fcntl.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <getopt.h>
#include "lock_daemon.h"
#include "lock_daemon_config.h"
#include "admin/admin_server_dispatch.h"
2012-12-13 17:44:57 +00:00
#include "virutil.h"
#include "virfile.h"
#include "virpidfile.h"
#include "virprocess.h"
#include "virerror.h"
2012-12-12 17:59:27 +00:00
#include "virlog.h"
2012-12-12 18:06:53 +00:00
#include "viralloc.h"
2012-12-12 16:35:35 +00:00
#include "virconf.h"
#include "rpc/virnetdaemon.h"
#include "rpc/virnetserver.h"
#include "virrandom.h"
#include "virhash.h"
2012-12-13 18:01:25 +00:00
#include "viruuid.h"
#include "virstring.h"
#include "virgettext.h"
#include "virdaemon.h"
#include "locking/lock_daemon_dispatch.h"
#include "locking/lock_protocol.h"
#include "configmake.h"
#define VIR_FROM_THIS VIR_FROM_LOCKING
VIR_LOG_INIT("locking.lock_daemon");
struct _virLockDaemon {
GMutex lock;
virNetDaemonPtr dmn;
virHashTablePtr lockspaces;
virLockSpacePtr defaultLockspace;
};
virLockDaemonPtr lockDaemon = NULL;
static bool execRestart;
Add support for re-exec() of virtlockd upon SIGUSR1 The virtlockd daemon maintains file locks on behalf of libvirtd and any VMs it is running. These file locks must be held for as long as any VM is running. If virtlockd itself ever quits, then it is expected that a node would be fenced/rebooted. Thus to allow for software upgrads on live systemd, virtlockd needs the ability to re-exec() itself. Upon receipt of SIGUSR1, virtlockd will save its current live state out to a file /var/run/virtlockd-restart-exec.json It then re-exec()'s itself with exactly the same argv as it originally had, and loads the state file, reconstructing any objects as appropriate. The state file contains information about all locks held and all network services and clients currently active. An example state document is { "server": { "min_workers": 1, "max_workers": 20, "priority_workers": 0, "max_clients": 20, "keepaliveInterval": 4294967295, "keepaliveCount": 0, "keepaliveRequired": false, "services": [ { "auth": 0, "readonly": false, "nrequests_client_max": 1, "socks": [ { "fd": 6, "errfd": -1, "pid": 0, "isClient": false } ] } ], "clients": [ { "auth": 0, "readonly": false, "nrequests_max": 1, "sock": { "fd": 9, "errfd": -1, "pid": 0, "isClient": true }, "privateData": { "restricted": true, "ownerPid": 1722, "ownerId": 6, "ownerName": "f18x86_64", "ownerUUID": "97586ba9-df27-9459-c806-f016c8bbd224" } }, { "auth": 0, "readonly": false, "nrequests_max": 1, "sock": { "fd": 10, "errfd": -1, "pid": 0, "isClient": true }, "privateData": { "restricted": true, "ownerPid": 1784, "ownerId": 7, "ownerName": "f16x86_64", "ownerUUID": "7b8e5e42-b875-61e9-b981-91ad8fa46979" } } ] }, "defaultLockspace": { "resources": [ { "name": "/var/lib/libvirt/images/f16x86_64.raw", "path": "/var/lib/libvirt/images/f16x86_64.raw", "fd": 14, "lockHeld": true, "flags": 0, "owners": [ 1784 ] }, { "name": "/var/lib/libvirt/images/shared.img", "path": "/var/lib/libvirt/images/shared.img", "fd": 12, "lockHeld": true, "flags": 1, "owners": [ 1722, 1784 ] }, { "name": "/var/lib/libvirt/images/f18x86_64.img", "path": "/var/lib/libvirt/images/f18x86_64.img", "fd": 11, "lockHeld": true, "flags": 0, "owners": [ 1722 ] } ] }, "lockspaces": [ ], "magic": "30199" } Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2012-08-07 11:13:26 +00:00
static void *
virLockDaemonClientNew(virNetServerClientPtr client,
void *opaque);
static void
virLockDaemonClientFree(void *opaque);
Add support for re-exec() of virtlockd upon SIGUSR1 The virtlockd daemon maintains file locks on behalf of libvirtd and any VMs it is running. These file locks must be held for as long as any VM is running. If virtlockd itself ever quits, then it is expected that a node would be fenced/rebooted. Thus to allow for software upgrads on live systemd, virtlockd needs the ability to re-exec() itself. Upon receipt of SIGUSR1, virtlockd will save its current live state out to a file /var/run/virtlockd-restart-exec.json It then re-exec()'s itself with exactly the same argv as it originally had, and loads the state file, reconstructing any objects as appropriate. The state file contains information about all locks held and all network services and clients currently active. An example state document is { "server": { "min_workers": 1, "max_workers": 20, "priority_workers": 0, "max_clients": 20, "keepaliveInterval": 4294967295, "keepaliveCount": 0, "keepaliveRequired": false, "services": [ { "auth": 0, "readonly": false, "nrequests_client_max": 1, "socks": [ { "fd": 6, "errfd": -1, "pid": 0, "isClient": false } ] } ], "clients": [ { "auth": 0, "readonly": false, "nrequests_max": 1, "sock": { "fd": 9, "errfd": -1, "pid": 0, "isClient": true }, "privateData": { "restricted": true, "ownerPid": 1722, "ownerId": 6, "ownerName": "f18x86_64", "ownerUUID": "97586ba9-df27-9459-c806-f016c8bbd224" } }, { "auth": 0, "readonly": false, "nrequests_max": 1, "sock": { "fd": 10, "errfd": -1, "pid": 0, "isClient": true }, "privateData": { "restricted": true, "ownerPid": 1784, "ownerId": 7, "ownerName": "f16x86_64", "ownerUUID": "7b8e5e42-b875-61e9-b981-91ad8fa46979" } } ] }, "defaultLockspace": { "resources": [ { "name": "/var/lib/libvirt/images/f16x86_64.raw", "path": "/var/lib/libvirt/images/f16x86_64.raw", "fd": 14, "lockHeld": true, "flags": 0, "owners": [ 1784 ] }, { "name": "/var/lib/libvirt/images/shared.img", "path": "/var/lib/libvirt/images/shared.img", "fd": 12, "lockHeld": true, "flags": 1, "owners": [ 1722, 1784 ] }, { "name": "/var/lib/libvirt/images/f18x86_64.img", "path": "/var/lib/libvirt/images/f18x86_64.img", "fd": 11, "lockHeld": true, "flags": 0, "owners": [ 1722 ] } ] }, "lockspaces": [ ], "magic": "30199" } Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2012-08-07 11:13:26 +00:00
static void *
virLockDaemonClientNewPostExecRestart(virNetServerClientPtr client,
virJSONValuePtr object,
void *opaque);
static virJSONValuePtr
virLockDaemonClientPreExecRestart(virNetServerClientPtr client,
void *opaque);
static void
virLockDaemonFree(virLockDaemonPtr lockd)
{
if (!lockd)
return;
g_mutex_clear(&lockd->lock);
virObjectUnref(lockd->dmn);
virHashFree(lockd->lockspaces);
virLockSpaceFree(lockd->defaultLockspace);
VIR_FREE(lockd);
}
static inline void
virLockDaemonLock(virLockDaemonPtr lockd)
{
g_mutex_lock(&lockd->lock);
}
static inline void
virLockDaemonUnlock(virLockDaemonPtr lockd)
{
g_mutex_unlock(&lockd->lock);
}
static void virLockDaemonLockSpaceDataFree(void *data)
{
virLockSpaceFree(data);
}
static virLockDaemonPtr
virLockDaemonNew(virLockDaemonConfigPtr config, bool privileged)
{
virLockDaemonPtr lockd;
virNetServerPtr srv = NULL;
lockd = g_new0(virLockDaemon, 1);
g_mutex_init(&lockd->lock);
if (!(lockd->dmn = virNetDaemonNew()))
goto error;
if (!(srv = virNetServerNew("virtlockd", 1,
0, 0, 0, config->max_clients,
config->max_clients, -1, 0,
virLockDaemonClientNew,
virLockDaemonClientPreExecRestart,
virLockDaemonClientFree,
(void*)(intptr_t)(privileged ? 0x1 : 0x0))))
goto error;
if (virNetDaemonAddServer(lockd->dmn, srv) < 0)
goto error;
virObjectUnref(srv);
srv = NULL;
if (!(srv = virNetServerNew("admin", 1,
0, 0, 0, config->admin_max_clients,
config->admin_max_clients, -1, 0,
remoteAdmClientNew,
remoteAdmClientPreExecRestart,
remoteAdmClientFree,
lockd->dmn)))
goto error;
if (virNetDaemonAddServer(lockd->dmn, srv) < 0)
goto error;
virObjectUnref(srv);
srv = NULL;
if (!(lockd->lockspaces = virHashNew(virLockDaemonLockSpaceDataFree)))
goto error;
if (!(lockd->defaultLockspace = virLockSpaceNew(NULL)))
goto error;
return lockd;
error:
virObjectUnref(srv);
virLockDaemonFree(lockd);
return NULL;
}
static virNetServerPtr
virLockDaemonNewServerPostExecRestart(virNetDaemonPtr dmn G_GNUC_UNUSED,
const char *name,
virJSONValuePtr object,
void *opaque)
{
if (STREQ(name, "virtlockd")) {
return virNetServerNewPostExecRestart(object,
name,
virLockDaemonClientNew,
virLockDaemonClientNewPostExecRestart,
virLockDaemonClientPreExecRestart,
virLockDaemonClientFree,
opaque);
} else if (STREQ(name, "admin")) {
return virNetServerNewPostExecRestart(object,
name,
remoteAdmClientNew,
remoteAdmClientNewPostExecRestart,
remoteAdmClientPreExecRestart,
remoteAdmClientFree,
dmn);
} else {
virReportError(VIR_ERR_INTERNAL_ERROR,
_("Unexpected server name '%s' during restart"),
name);
return NULL;
}
}
Add support for re-exec() of virtlockd upon SIGUSR1 The virtlockd daemon maintains file locks on behalf of libvirtd and any VMs it is running. These file locks must be held for as long as any VM is running. If virtlockd itself ever quits, then it is expected that a node would be fenced/rebooted. Thus to allow for software upgrads on live systemd, virtlockd needs the ability to re-exec() itself. Upon receipt of SIGUSR1, virtlockd will save its current live state out to a file /var/run/virtlockd-restart-exec.json It then re-exec()'s itself with exactly the same argv as it originally had, and loads the state file, reconstructing any objects as appropriate. The state file contains information about all locks held and all network services and clients currently active. An example state document is { "server": { "min_workers": 1, "max_workers": 20, "priority_workers": 0, "max_clients": 20, "keepaliveInterval": 4294967295, "keepaliveCount": 0, "keepaliveRequired": false, "services": [ { "auth": 0, "readonly": false, "nrequests_client_max": 1, "socks": [ { "fd": 6, "errfd": -1, "pid": 0, "isClient": false } ] } ], "clients": [ { "auth": 0, "readonly": false, "nrequests_max": 1, "sock": { "fd": 9, "errfd": -1, "pid": 0, "isClient": true }, "privateData": { "restricted": true, "ownerPid": 1722, "ownerId": 6, "ownerName": "f18x86_64", "ownerUUID": "97586ba9-df27-9459-c806-f016c8bbd224" } }, { "auth": 0, "readonly": false, "nrequests_max": 1, "sock": { "fd": 10, "errfd": -1, "pid": 0, "isClient": true }, "privateData": { "restricted": true, "ownerPid": 1784, "ownerId": 7, "ownerName": "f16x86_64", "ownerUUID": "7b8e5e42-b875-61e9-b981-91ad8fa46979" } } ] }, "defaultLockspace": { "resources": [ { "name": "/var/lib/libvirt/images/f16x86_64.raw", "path": "/var/lib/libvirt/images/f16x86_64.raw", "fd": 14, "lockHeld": true, "flags": 0, "owners": [ 1784 ] }, { "name": "/var/lib/libvirt/images/shared.img", "path": "/var/lib/libvirt/images/shared.img", "fd": 12, "lockHeld": true, "flags": 1, "owners": [ 1722, 1784 ] }, { "name": "/var/lib/libvirt/images/f18x86_64.img", "path": "/var/lib/libvirt/images/f18x86_64.img", "fd": 11, "lockHeld": true, "flags": 0, "owners": [ 1722 ] } ] }, "lockspaces": [ ], "magic": "30199" } Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2012-08-07 11:13:26 +00:00
static virLockDaemonPtr
virLockDaemonNewPostExecRestart(virJSONValuePtr object, bool privileged)
{
virLockDaemonPtr lockd;
virJSONValuePtr child;
virJSONValuePtr lockspaces;
size_t i;
const char *serverNames[] = { "virtlockd" };
Add support for re-exec() of virtlockd upon SIGUSR1 The virtlockd daemon maintains file locks on behalf of libvirtd and any VMs it is running. These file locks must be held for as long as any VM is running. If virtlockd itself ever quits, then it is expected that a node would be fenced/rebooted. Thus to allow for software upgrads on live systemd, virtlockd needs the ability to re-exec() itself. Upon receipt of SIGUSR1, virtlockd will save its current live state out to a file /var/run/virtlockd-restart-exec.json It then re-exec()'s itself with exactly the same argv as it originally had, and loads the state file, reconstructing any objects as appropriate. The state file contains information about all locks held and all network services and clients currently active. An example state document is { "server": { "min_workers": 1, "max_workers": 20, "priority_workers": 0, "max_clients": 20, "keepaliveInterval": 4294967295, "keepaliveCount": 0, "keepaliveRequired": false, "services": [ { "auth": 0, "readonly": false, "nrequests_client_max": 1, "socks": [ { "fd": 6, "errfd": -1, "pid": 0, "isClient": false } ] } ], "clients": [ { "auth": 0, "readonly": false, "nrequests_max": 1, "sock": { "fd": 9, "errfd": -1, "pid": 0, "isClient": true }, "privateData": { "restricted": true, "ownerPid": 1722, "ownerId": 6, "ownerName": "f18x86_64", "ownerUUID": "97586ba9-df27-9459-c806-f016c8bbd224" } }, { "auth": 0, "readonly": false, "nrequests_max": 1, "sock": { "fd": 10, "errfd": -1, "pid": 0, "isClient": true }, "privateData": { "restricted": true, "ownerPid": 1784, "ownerId": 7, "ownerName": "f16x86_64", "ownerUUID": "7b8e5e42-b875-61e9-b981-91ad8fa46979" } } ] }, "defaultLockspace": { "resources": [ { "name": "/var/lib/libvirt/images/f16x86_64.raw", "path": "/var/lib/libvirt/images/f16x86_64.raw", "fd": 14, "lockHeld": true, "flags": 0, "owners": [ 1784 ] }, { "name": "/var/lib/libvirt/images/shared.img", "path": "/var/lib/libvirt/images/shared.img", "fd": 12, "lockHeld": true, "flags": 1, "owners": [ 1722, 1784 ] }, { "name": "/var/lib/libvirt/images/f18x86_64.img", "path": "/var/lib/libvirt/images/f18x86_64.img", "fd": 11, "lockHeld": true, "flags": 0, "owners": [ 1722 ] } ] }, "lockspaces": [ ], "magic": "30199" } Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2012-08-07 11:13:26 +00:00
lockd = g_new0(virLockDaemon, 1);
Add support for re-exec() of virtlockd upon SIGUSR1 The virtlockd daemon maintains file locks on behalf of libvirtd and any VMs it is running. These file locks must be held for as long as any VM is running. If virtlockd itself ever quits, then it is expected that a node would be fenced/rebooted. Thus to allow for software upgrads on live systemd, virtlockd needs the ability to re-exec() itself. Upon receipt of SIGUSR1, virtlockd will save its current live state out to a file /var/run/virtlockd-restart-exec.json It then re-exec()'s itself with exactly the same argv as it originally had, and loads the state file, reconstructing any objects as appropriate. The state file contains information about all locks held and all network services and clients currently active. An example state document is { "server": { "min_workers": 1, "max_workers": 20, "priority_workers": 0, "max_clients": 20, "keepaliveInterval": 4294967295, "keepaliveCount": 0, "keepaliveRequired": false, "services": [ { "auth": 0, "readonly": false, "nrequests_client_max": 1, "socks": [ { "fd": 6, "errfd": -1, "pid": 0, "isClient": false } ] } ], "clients": [ { "auth": 0, "readonly": false, "nrequests_max": 1, "sock": { "fd": 9, "errfd": -1, "pid": 0, "isClient": true }, "privateData": { "restricted": true, "ownerPid": 1722, "ownerId": 6, "ownerName": "f18x86_64", "ownerUUID": "97586ba9-df27-9459-c806-f016c8bbd224" } }, { "auth": 0, "readonly": false, "nrequests_max": 1, "sock": { "fd": 10, "errfd": -1, "pid": 0, "isClient": true }, "privateData": { "restricted": true, "ownerPid": 1784, "ownerId": 7, "ownerName": "f16x86_64", "ownerUUID": "7b8e5e42-b875-61e9-b981-91ad8fa46979" } } ] }, "defaultLockspace": { "resources": [ { "name": "/var/lib/libvirt/images/f16x86_64.raw", "path": "/var/lib/libvirt/images/f16x86_64.raw", "fd": 14, "lockHeld": true, "flags": 0, "owners": [ 1784 ] }, { "name": "/var/lib/libvirt/images/shared.img", "path": "/var/lib/libvirt/images/shared.img", "fd": 12, "lockHeld": true, "flags": 1, "owners": [ 1722, 1784 ] }, { "name": "/var/lib/libvirt/images/f18x86_64.img", "path": "/var/lib/libvirt/images/f18x86_64.img", "fd": 11, "lockHeld": true, "flags": 0, "owners": [ 1722 ] } ] }, "lockspaces": [ ], "magic": "30199" } Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2012-08-07 11:13:26 +00:00
g_mutex_init(&lockd->lock);
Add support for re-exec() of virtlockd upon SIGUSR1 The virtlockd daemon maintains file locks on behalf of libvirtd and any VMs it is running. These file locks must be held for as long as any VM is running. If virtlockd itself ever quits, then it is expected that a node would be fenced/rebooted. Thus to allow for software upgrads on live systemd, virtlockd needs the ability to re-exec() itself. Upon receipt of SIGUSR1, virtlockd will save its current live state out to a file /var/run/virtlockd-restart-exec.json It then re-exec()'s itself with exactly the same argv as it originally had, and loads the state file, reconstructing any objects as appropriate. The state file contains information about all locks held and all network services and clients currently active. An example state document is { "server": { "min_workers": 1, "max_workers": 20, "priority_workers": 0, "max_clients": 20, "keepaliveInterval": 4294967295, "keepaliveCount": 0, "keepaliveRequired": false, "services": [ { "auth": 0, "readonly": false, "nrequests_client_max": 1, "socks": [ { "fd": 6, "errfd": -1, "pid": 0, "isClient": false } ] } ], "clients": [ { "auth": 0, "readonly": false, "nrequests_max": 1, "sock": { "fd": 9, "errfd": -1, "pid": 0, "isClient": true }, "privateData": { "restricted": true, "ownerPid": 1722, "ownerId": 6, "ownerName": "f18x86_64", "ownerUUID": "97586ba9-df27-9459-c806-f016c8bbd224" } }, { "auth": 0, "readonly": false, "nrequests_max": 1, "sock": { "fd": 10, "errfd": -1, "pid": 0, "isClient": true }, "privateData": { "restricted": true, "ownerPid": 1784, "ownerId": 7, "ownerName": "f16x86_64", "ownerUUID": "7b8e5e42-b875-61e9-b981-91ad8fa46979" } } ] }, "defaultLockspace": { "resources": [ { "name": "/var/lib/libvirt/images/f16x86_64.raw", "path": "/var/lib/libvirt/images/f16x86_64.raw", "fd": 14, "lockHeld": true, "flags": 0, "owners": [ 1784 ] }, { "name": "/var/lib/libvirt/images/shared.img", "path": "/var/lib/libvirt/images/shared.img", "fd": 12, "lockHeld": true, "flags": 1, "owners": [ 1722, 1784 ] }, { "name": "/var/lib/libvirt/images/f18x86_64.img", "path": "/var/lib/libvirt/images/f18x86_64.img", "fd": 11, "lockHeld": true, "flags": 0, "owners": [ 1722 ] } ] }, "lockspaces": [ ], "magic": "30199" } Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2012-08-07 11:13:26 +00:00
if (!(lockd->lockspaces = virHashNew(virLockDaemonLockSpaceDataFree)))
Add support for re-exec() of virtlockd upon SIGUSR1 The virtlockd daemon maintains file locks on behalf of libvirtd and any VMs it is running. These file locks must be held for as long as any VM is running. If virtlockd itself ever quits, then it is expected that a node would be fenced/rebooted. Thus to allow for software upgrads on live systemd, virtlockd needs the ability to re-exec() itself. Upon receipt of SIGUSR1, virtlockd will save its current live state out to a file /var/run/virtlockd-restart-exec.json It then re-exec()'s itself with exactly the same argv as it originally had, and loads the state file, reconstructing any objects as appropriate. The state file contains information about all locks held and all network services and clients currently active. An example state document is { "server": { "min_workers": 1, "max_workers": 20, "priority_workers": 0, "max_clients": 20, "keepaliveInterval": 4294967295, "keepaliveCount": 0, "keepaliveRequired": false, "services": [ { "auth": 0, "readonly": false, "nrequests_client_max": 1, "socks": [ { "fd": 6, "errfd": -1, "pid": 0, "isClient": false } ] } ], "clients": [ { "auth": 0, "readonly": false, "nrequests_max": 1, "sock": { "fd": 9, "errfd": -1, "pid": 0, "isClient": true }, "privateData": { "restricted": true, "ownerPid": 1722, "ownerId": 6, "ownerName": "f18x86_64", "ownerUUID": "97586ba9-df27-9459-c806-f016c8bbd224" } }, { "auth": 0, "readonly": false, "nrequests_max": 1, "sock": { "fd": 10, "errfd": -1, "pid": 0, "isClient": true }, "privateData": { "restricted": true, "ownerPid": 1784, "ownerId": 7, "ownerName": "f16x86_64", "ownerUUID": "7b8e5e42-b875-61e9-b981-91ad8fa46979" } } ] }, "defaultLockspace": { "resources": [ { "name": "/var/lib/libvirt/images/f16x86_64.raw", "path": "/var/lib/libvirt/images/f16x86_64.raw", "fd": 14, "lockHeld": true, "flags": 0, "owners": [ 1784 ] }, { "name": "/var/lib/libvirt/images/shared.img", "path": "/var/lib/libvirt/images/shared.img", "fd": 12, "lockHeld": true, "flags": 1, "owners": [ 1722, 1784 ] }, { "name": "/var/lib/libvirt/images/f18x86_64.img", "path": "/var/lib/libvirt/images/f18x86_64.img", "fd": 11, "lockHeld": true, "flags": 0, "owners": [ 1722 ] } ] }, "lockspaces": [ ], "magic": "30199" } Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2012-08-07 11:13:26 +00:00
goto error;
if (!(child = virJSONValueObjectGet(object, "defaultLockspace"))) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("Missing defaultLockspace data from JSON file"));
goto error;
}
if (!(lockd->defaultLockspace =
virLockSpaceNewPostExecRestart(child)))
goto error;
if (!(lockspaces = virJSONValueObjectGet(object, "lockspaces"))) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("Missing lockspaces data from JSON file"));
goto error;
}
if (!virJSONValueIsArray(lockspaces)) {
Add support for re-exec() of virtlockd upon SIGUSR1 The virtlockd daemon maintains file locks on behalf of libvirtd and any VMs it is running. These file locks must be held for as long as any VM is running. If virtlockd itself ever quits, then it is expected that a node would be fenced/rebooted. Thus to allow for software upgrads on live systemd, virtlockd needs the ability to re-exec() itself. Upon receipt of SIGUSR1, virtlockd will save its current live state out to a file /var/run/virtlockd-restart-exec.json It then re-exec()'s itself with exactly the same argv as it originally had, and loads the state file, reconstructing any objects as appropriate. The state file contains information about all locks held and all network services and clients currently active. An example state document is { "server": { "min_workers": 1, "max_workers": 20, "priority_workers": 0, "max_clients": 20, "keepaliveInterval": 4294967295, "keepaliveCount": 0, "keepaliveRequired": false, "services": [ { "auth": 0, "readonly": false, "nrequests_client_max": 1, "socks": [ { "fd": 6, "errfd": -1, "pid": 0, "isClient": false } ] } ], "clients": [ { "auth": 0, "readonly": false, "nrequests_max": 1, "sock": { "fd": 9, "errfd": -1, "pid": 0, "isClient": true }, "privateData": { "restricted": true, "ownerPid": 1722, "ownerId": 6, "ownerName": "f18x86_64", "ownerUUID": "97586ba9-df27-9459-c806-f016c8bbd224" } }, { "auth": 0, "readonly": false, "nrequests_max": 1, "sock": { "fd": 10, "errfd": -1, "pid": 0, "isClient": true }, "privateData": { "restricted": true, "ownerPid": 1784, "ownerId": 7, "ownerName": "f16x86_64", "ownerUUID": "7b8e5e42-b875-61e9-b981-91ad8fa46979" } } ] }, "defaultLockspace": { "resources": [ { "name": "/var/lib/libvirt/images/f16x86_64.raw", "path": "/var/lib/libvirt/images/f16x86_64.raw", "fd": 14, "lockHeld": true, "flags": 0, "owners": [ 1784 ] }, { "name": "/var/lib/libvirt/images/shared.img", "path": "/var/lib/libvirt/images/shared.img", "fd": 12, "lockHeld": true, "flags": 1, "owners": [ 1722, 1784 ] }, { "name": "/var/lib/libvirt/images/f18x86_64.img", "path": "/var/lib/libvirt/images/f18x86_64.img", "fd": 11, "lockHeld": true, "flags": 0, "owners": [ 1722 ] } ] }, "lockspaces": [ ], "magic": "30199" } Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2012-08-07 11:13:26 +00:00
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("Malformed lockspaces array"));
Add support for re-exec() of virtlockd upon SIGUSR1 The virtlockd daemon maintains file locks on behalf of libvirtd and any VMs it is running. These file locks must be held for as long as any VM is running. If virtlockd itself ever quits, then it is expected that a node would be fenced/rebooted. Thus to allow for software upgrads on live systemd, virtlockd needs the ability to re-exec() itself. Upon receipt of SIGUSR1, virtlockd will save its current live state out to a file /var/run/virtlockd-restart-exec.json It then re-exec()'s itself with exactly the same argv as it originally had, and loads the state file, reconstructing any objects as appropriate. The state file contains information about all locks held and all network services and clients currently active. An example state document is { "server": { "min_workers": 1, "max_workers": 20, "priority_workers": 0, "max_clients": 20, "keepaliveInterval": 4294967295, "keepaliveCount": 0, "keepaliveRequired": false, "services": [ { "auth": 0, "readonly": false, "nrequests_client_max": 1, "socks": [ { "fd": 6, "errfd": -1, "pid": 0, "isClient": false } ] } ], "clients": [ { "auth": 0, "readonly": false, "nrequests_max": 1, "sock": { "fd": 9, "errfd": -1, "pid": 0, "isClient": true }, "privateData": { "restricted": true, "ownerPid": 1722, "ownerId": 6, "ownerName": "f18x86_64", "ownerUUID": "97586ba9-df27-9459-c806-f016c8bbd224" } }, { "auth": 0, "readonly": false, "nrequests_max": 1, "sock": { "fd": 10, "errfd": -1, "pid": 0, "isClient": true }, "privateData": { "restricted": true, "ownerPid": 1784, "ownerId": 7, "ownerName": "f16x86_64", "ownerUUID": "7b8e5e42-b875-61e9-b981-91ad8fa46979" } } ] }, "defaultLockspace": { "resources": [ { "name": "/var/lib/libvirt/images/f16x86_64.raw", "path": "/var/lib/libvirt/images/f16x86_64.raw", "fd": 14, "lockHeld": true, "flags": 0, "owners": [ 1784 ] }, { "name": "/var/lib/libvirt/images/shared.img", "path": "/var/lib/libvirt/images/shared.img", "fd": 12, "lockHeld": true, "flags": 1, "owners": [ 1722, 1784 ] }, { "name": "/var/lib/libvirt/images/f18x86_64.img", "path": "/var/lib/libvirt/images/f18x86_64.img", "fd": 11, "lockHeld": true, "flags": 0, "owners": [ 1722 ] } ] }, "lockspaces": [ ], "magic": "30199" } Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2012-08-07 11:13:26 +00:00
goto error;
}
for (i = 0; i < virJSONValueArraySize(lockspaces); i++) {
Add support for re-exec() of virtlockd upon SIGUSR1 The virtlockd daemon maintains file locks on behalf of libvirtd and any VMs it is running. These file locks must be held for as long as any VM is running. If virtlockd itself ever quits, then it is expected that a node would be fenced/rebooted. Thus to allow for software upgrads on live systemd, virtlockd needs the ability to re-exec() itself. Upon receipt of SIGUSR1, virtlockd will save its current live state out to a file /var/run/virtlockd-restart-exec.json It then re-exec()'s itself with exactly the same argv as it originally had, and loads the state file, reconstructing any objects as appropriate. The state file contains information about all locks held and all network services and clients currently active. An example state document is { "server": { "min_workers": 1, "max_workers": 20, "priority_workers": 0, "max_clients": 20, "keepaliveInterval": 4294967295, "keepaliveCount": 0, "keepaliveRequired": false, "services": [ { "auth": 0, "readonly": false, "nrequests_client_max": 1, "socks": [ { "fd": 6, "errfd": -1, "pid": 0, "isClient": false } ] } ], "clients": [ { "auth": 0, "readonly": false, "nrequests_max": 1, "sock": { "fd": 9, "errfd": -1, "pid": 0, "isClient": true }, "privateData": { "restricted": true, "ownerPid": 1722, "ownerId": 6, "ownerName": "f18x86_64", "ownerUUID": "97586ba9-df27-9459-c806-f016c8bbd224" } }, { "auth": 0, "readonly": false, "nrequests_max": 1, "sock": { "fd": 10, "errfd": -1, "pid": 0, "isClient": true }, "privateData": { "restricted": true, "ownerPid": 1784, "ownerId": 7, "ownerName": "f16x86_64", "ownerUUID": "7b8e5e42-b875-61e9-b981-91ad8fa46979" } } ] }, "defaultLockspace": { "resources": [ { "name": "/var/lib/libvirt/images/f16x86_64.raw", "path": "/var/lib/libvirt/images/f16x86_64.raw", "fd": 14, "lockHeld": true, "flags": 0, "owners": [ 1784 ] }, { "name": "/var/lib/libvirt/images/shared.img", "path": "/var/lib/libvirt/images/shared.img", "fd": 12, "lockHeld": true, "flags": 1, "owners": [ 1722, 1784 ] }, { "name": "/var/lib/libvirt/images/f18x86_64.img", "path": "/var/lib/libvirt/images/f18x86_64.img", "fd": 11, "lockHeld": true, "flags": 0, "owners": [ 1722 ] } ] }, "lockspaces": [ ], "magic": "30199" } Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2012-08-07 11:13:26 +00:00
virLockSpacePtr lockspace;
child = virJSONValueArrayGet(lockspaces, i);
if (!(lockspace = virLockSpaceNewPostExecRestart(child)))
goto error;
if (virHashAddEntry(lockd->lockspaces,
virLockSpaceGetDirectory(lockspace),
lockspace) < 0) {
virLockSpaceFree(lockspace);
}
}
if (virJSONValueObjectHasKey(object, "daemon")) {
if (!(child = virJSONValueObjectGet(object, "daemon"))) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("Malformed daemon data from JSON file"));
goto error;
}
} else {
if (!(child = virJSONValueObjectGet(object, "server"))) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("Missing server data from JSON file"));
goto error;
}
Add support for re-exec() of virtlockd upon SIGUSR1 The virtlockd daemon maintains file locks on behalf of libvirtd and any VMs it is running. These file locks must be held for as long as any VM is running. If virtlockd itself ever quits, then it is expected that a node would be fenced/rebooted. Thus to allow for software upgrads on live systemd, virtlockd needs the ability to re-exec() itself. Upon receipt of SIGUSR1, virtlockd will save its current live state out to a file /var/run/virtlockd-restart-exec.json It then re-exec()'s itself with exactly the same argv as it originally had, and loads the state file, reconstructing any objects as appropriate. The state file contains information about all locks held and all network services and clients currently active. An example state document is { "server": { "min_workers": 1, "max_workers": 20, "priority_workers": 0, "max_clients": 20, "keepaliveInterval": 4294967295, "keepaliveCount": 0, "keepaliveRequired": false, "services": [ { "auth": 0, "readonly": false, "nrequests_client_max": 1, "socks": [ { "fd": 6, "errfd": -1, "pid": 0, "isClient": false } ] } ], "clients": [ { "auth": 0, "readonly": false, "nrequests_max": 1, "sock": { "fd": 9, "errfd": -1, "pid": 0, "isClient": true }, "privateData": { "restricted": true, "ownerPid": 1722, "ownerId": 6, "ownerName": "f18x86_64", "ownerUUID": "97586ba9-df27-9459-c806-f016c8bbd224" } }, { "auth": 0, "readonly": false, "nrequests_max": 1, "sock": { "fd": 10, "errfd": -1, "pid": 0, "isClient": true }, "privateData": { "restricted": true, "ownerPid": 1784, "ownerId": 7, "ownerName": "f16x86_64", "ownerUUID": "7b8e5e42-b875-61e9-b981-91ad8fa46979" } } ] }, "defaultLockspace": { "resources": [ { "name": "/var/lib/libvirt/images/f16x86_64.raw", "path": "/var/lib/libvirt/images/f16x86_64.raw", "fd": 14, "lockHeld": true, "flags": 0, "owners": [ 1784 ] }, { "name": "/var/lib/libvirt/images/shared.img", "path": "/var/lib/libvirt/images/shared.img", "fd": 12, "lockHeld": true, "flags": 1, "owners": [ 1722, 1784 ] }, { "name": "/var/lib/libvirt/images/f18x86_64.img", "path": "/var/lib/libvirt/images/f18x86_64.img", "fd": 11, "lockHeld": true, "flags": 0, "owners": [ 1722 ] } ] }, "lockspaces": [ ], "magic": "30199" } Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2012-08-07 11:13:26 +00:00
}
if (!(lockd->dmn = virNetDaemonNewPostExecRestart(child,
G_N_ELEMENTS(serverNames),
serverNames,
virLockDaemonNewServerPostExecRestart,
(void*)(intptr_t)(privileged ? 0x1 : 0x0))))
Add support for re-exec() of virtlockd upon SIGUSR1 The virtlockd daemon maintains file locks on behalf of libvirtd and any VMs it is running. These file locks must be held for as long as any VM is running. If virtlockd itself ever quits, then it is expected that a node would be fenced/rebooted. Thus to allow for software upgrads on live systemd, virtlockd needs the ability to re-exec() itself. Upon receipt of SIGUSR1, virtlockd will save its current live state out to a file /var/run/virtlockd-restart-exec.json It then re-exec()'s itself with exactly the same argv as it originally had, and loads the state file, reconstructing any objects as appropriate. The state file contains information about all locks held and all network services and clients currently active. An example state document is { "server": { "min_workers": 1, "max_workers": 20, "priority_workers": 0, "max_clients": 20, "keepaliveInterval": 4294967295, "keepaliveCount": 0, "keepaliveRequired": false, "services": [ { "auth": 0, "readonly": false, "nrequests_client_max": 1, "socks": [ { "fd": 6, "errfd": -1, "pid": 0, "isClient": false } ] } ], "clients": [ { "auth": 0, "readonly": false, "nrequests_max": 1, "sock": { "fd": 9, "errfd": -1, "pid": 0, "isClient": true }, "privateData": { "restricted": true, "ownerPid": 1722, "ownerId": 6, "ownerName": "f18x86_64", "ownerUUID": "97586ba9-df27-9459-c806-f016c8bbd224" } }, { "auth": 0, "readonly": false, "nrequests_max": 1, "sock": { "fd": 10, "errfd": -1, "pid": 0, "isClient": true }, "privateData": { "restricted": true, "ownerPid": 1784, "ownerId": 7, "ownerName": "f16x86_64", "ownerUUID": "7b8e5e42-b875-61e9-b981-91ad8fa46979" } } ] }, "defaultLockspace": { "resources": [ { "name": "/var/lib/libvirt/images/f16x86_64.raw", "path": "/var/lib/libvirt/images/f16x86_64.raw", "fd": 14, "lockHeld": true, "flags": 0, "owners": [ 1784 ] }, { "name": "/var/lib/libvirt/images/shared.img", "path": "/var/lib/libvirt/images/shared.img", "fd": 12, "lockHeld": true, "flags": 1, "owners": [ 1722, 1784 ] }, { "name": "/var/lib/libvirt/images/f18x86_64.img", "path": "/var/lib/libvirt/images/f18x86_64.img", "fd": 11, "lockHeld": true, "flags": 0, "owners": [ 1722 ] } ] }, "lockspaces": [ ], "magic": "30199" } Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2012-08-07 11:13:26 +00:00
goto error;
return lockd;
error:
Add support for re-exec() of virtlockd upon SIGUSR1 The virtlockd daemon maintains file locks on behalf of libvirtd and any VMs it is running. These file locks must be held for as long as any VM is running. If virtlockd itself ever quits, then it is expected that a node would be fenced/rebooted. Thus to allow for software upgrads on live systemd, virtlockd needs the ability to re-exec() itself. Upon receipt of SIGUSR1, virtlockd will save its current live state out to a file /var/run/virtlockd-restart-exec.json It then re-exec()'s itself with exactly the same argv as it originally had, and loads the state file, reconstructing any objects as appropriate. The state file contains information about all locks held and all network services and clients currently active. An example state document is { "server": { "min_workers": 1, "max_workers": 20, "priority_workers": 0, "max_clients": 20, "keepaliveInterval": 4294967295, "keepaliveCount": 0, "keepaliveRequired": false, "services": [ { "auth": 0, "readonly": false, "nrequests_client_max": 1, "socks": [ { "fd": 6, "errfd": -1, "pid": 0, "isClient": false } ] } ], "clients": [ { "auth": 0, "readonly": false, "nrequests_max": 1, "sock": { "fd": 9, "errfd": -1, "pid": 0, "isClient": true }, "privateData": { "restricted": true, "ownerPid": 1722, "ownerId": 6, "ownerName": "f18x86_64", "ownerUUID": "97586ba9-df27-9459-c806-f016c8bbd224" } }, { "auth": 0, "readonly": false, "nrequests_max": 1, "sock": { "fd": 10, "errfd": -1, "pid": 0, "isClient": true }, "privateData": { "restricted": true, "ownerPid": 1784, "ownerId": 7, "ownerName": "f16x86_64", "ownerUUID": "7b8e5e42-b875-61e9-b981-91ad8fa46979" } } ] }, "defaultLockspace": { "resources": [ { "name": "/var/lib/libvirt/images/f16x86_64.raw", "path": "/var/lib/libvirt/images/f16x86_64.raw", "fd": 14, "lockHeld": true, "flags": 0, "owners": [ 1784 ] }, { "name": "/var/lib/libvirt/images/shared.img", "path": "/var/lib/libvirt/images/shared.img", "fd": 12, "lockHeld": true, "flags": 1, "owners": [ 1722, 1784 ] }, { "name": "/var/lib/libvirt/images/f18x86_64.img", "path": "/var/lib/libvirt/images/f18x86_64.img", "fd": 11, "lockHeld": true, "flags": 0, "owners": [ 1722 ] } ] }, "lockspaces": [ ], "magic": "30199" } Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2012-08-07 11:13:26 +00:00
virLockDaemonFree(lockd);
return NULL;
}
int virLockDaemonAddLockSpace(virLockDaemonPtr lockd,
const char *path,
virLockSpacePtr lockspace)
{
int ret;
virLockDaemonLock(lockd);
ret = virHashAddEntry(lockd->lockspaces, path, lockspace);
virLockDaemonUnlock(lockd);
return ret;
}
virLockSpacePtr virLockDaemonFindLockSpace(virLockDaemonPtr lockd,
const char *path)
{
virLockSpacePtr lockspace;
virLockDaemonLock(lockd);
if (path && STRNEQ(path, ""))
lockspace = virHashLookup(lockd->lockspaces, path);
else
lockspace = lockd->defaultLockspace;
virLockDaemonUnlock(lockd);
return lockspace;
}
static void
virLockDaemonErrorHandler(void *opaque G_GNUC_UNUSED,
virErrorPtr err G_GNUC_UNUSED)
{
/* Don't do anything, since logging infrastructure already
* took care of reporting the error */
}
/* Display version information. */
static void
virLockDaemonVersion(const char *argv0)
{
printf("%s (%s) %s\n", argv0, PACKAGE_NAME, PACKAGE_VERSION);
}
static void
virLockDaemonShutdownHandler(virNetDaemonPtr dmn,
siginfo_t *sig G_GNUC_UNUSED,
void *opaque G_GNUC_UNUSED)
{
virNetDaemonQuit(dmn);
}
Add support for re-exec() of virtlockd upon SIGUSR1 The virtlockd daemon maintains file locks on behalf of libvirtd and any VMs it is running. These file locks must be held for as long as any VM is running. If virtlockd itself ever quits, then it is expected that a node would be fenced/rebooted. Thus to allow for software upgrads on live systemd, virtlockd needs the ability to re-exec() itself. Upon receipt of SIGUSR1, virtlockd will save its current live state out to a file /var/run/virtlockd-restart-exec.json It then re-exec()'s itself with exactly the same argv as it originally had, and loads the state file, reconstructing any objects as appropriate. The state file contains information about all locks held and all network services and clients currently active. An example state document is { "server": { "min_workers": 1, "max_workers": 20, "priority_workers": 0, "max_clients": 20, "keepaliveInterval": 4294967295, "keepaliveCount": 0, "keepaliveRequired": false, "services": [ { "auth": 0, "readonly": false, "nrequests_client_max": 1, "socks": [ { "fd": 6, "errfd": -1, "pid": 0, "isClient": false } ] } ], "clients": [ { "auth": 0, "readonly": false, "nrequests_max": 1, "sock": { "fd": 9, "errfd": -1, "pid": 0, "isClient": true }, "privateData": { "restricted": true, "ownerPid": 1722, "ownerId": 6, "ownerName": "f18x86_64", "ownerUUID": "97586ba9-df27-9459-c806-f016c8bbd224" } }, { "auth": 0, "readonly": false, "nrequests_max": 1, "sock": { "fd": 10, "errfd": -1, "pid": 0, "isClient": true }, "privateData": { "restricted": true, "ownerPid": 1784, "ownerId": 7, "ownerName": "f16x86_64", "ownerUUID": "7b8e5e42-b875-61e9-b981-91ad8fa46979" } } ] }, "defaultLockspace": { "resources": [ { "name": "/var/lib/libvirt/images/f16x86_64.raw", "path": "/var/lib/libvirt/images/f16x86_64.raw", "fd": 14, "lockHeld": true, "flags": 0, "owners": [ 1784 ] }, { "name": "/var/lib/libvirt/images/shared.img", "path": "/var/lib/libvirt/images/shared.img", "fd": 12, "lockHeld": true, "flags": 1, "owners": [ 1722, 1784 ] }, { "name": "/var/lib/libvirt/images/f18x86_64.img", "path": "/var/lib/libvirt/images/f18x86_64.img", "fd": 11, "lockHeld": true, "flags": 0, "owners": [ 1722 ] } ] }, "lockspaces": [ ], "magic": "30199" } Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2012-08-07 11:13:26 +00:00
static void
virLockDaemonExecRestartHandler(virNetDaemonPtr dmn,
siginfo_t *sig G_GNUC_UNUSED,
void *opaque G_GNUC_UNUSED)
Add support for re-exec() of virtlockd upon SIGUSR1 The virtlockd daemon maintains file locks on behalf of libvirtd and any VMs it is running. These file locks must be held for as long as any VM is running. If virtlockd itself ever quits, then it is expected that a node would be fenced/rebooted. Thus to allow for software upgrads on live systemd, virtlockd needs the ability to re-exec() itself. Upon receipt of SIGUSR1, virtlockd will save its current live state out to a file /var/run/virtlockd-restart-exec.json It then re-exec()'s itself with exactly the same argv as it originally had, and loads the state file, reconstructing any objects as appropriate. The state file contains information about all locks held and all network services and clients currently active. An example state document is { "server": { "min_workers": 1, "max_workers": 20, "priority_workers": 0, "max_clients": 20, "keepaliveInterval": 4294967295, "keepaliveCount": 0, "keepaliveRequired": false, "services": [ { "auth": 0, "readonly": false, "nrequests_client_max": 1, "socks": [ { "fd": 6, "errfd": -1, "pid": 0, "isClient": false } ] } ], "clients": [ { "auth": 0, "readonly": false, "nrequests_max": 1, "sock": { "fd": 9, "errfd": -1, "pid": 0, "isClient": true }, "privateData": { "restricted": true, "ownerPid": 1722, "ownerId": 6, "ownerName": "f18x86_64", "ownerUUID": "97586ba9-df27-9459-c806-f016c8bbd224" } }, { "auth": 0, "readonly": false, "nrequests_max": 1, "sock": { "fd": 10, "errfd": -1, "pid": 0, "isClient": true }, "privateData": { "restricted": true, "ownerPid": 1784, "ownerId": 7, "ownerName": "f16x86_64", "ownerUUID": "7b8e5e42-b875-61e9-b981-91ad8fa46979" } } ] }, "defaultLockspace": { "resources": [ { "name": "/var/lib/libvirt/images/f16x86_64.raw", "path": "/var/lib/libvirt/images/f16x86_64.raw", "fd": 14, "lockHeld": true, "flags": 0, "owners": [ 1784 ] }, { "name": "/var/lib/libvirt/images/shared.img", "path": "/var/lib/libvirt/images/shared.img", "fd": 12, "lockHeld": true, "flags": 1, "owners": [ 1722, 1784 ] }, { "name": "/var/lib/libvirt/images/f18x86_64.img", "path": "/var/lib/libvirt/images/f18x86_64.img", "fd": 11, "lockHeld": true, "flags": 0, "owners": [ 1722 ] } ] }, "lockspaces": [ ], "magic": "30199" } Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2012-08-07 11:13:26 +00:00
{
execRestart = true;
virNetDaemonQuit(dmn);
Add support for re-exec() of virtlockd upon SIGUSR1 The virtlockd daemon maintains file locks on behalf of libvirtd and any VMs it is running. These file locks must be held for as long as any VM is running. If virtlockd itself ever quits, then it is expected that a node would be fenced/rebooted. Thus to allow for software upgrads on live systemd, virtlockd needs the ability to re-exec() itself. Upon receipt of SIGUSR1, virtlockd will save its current live state out to a file /var/run/virtlockd-restart-exec.json It then re-exec()'s itself with exactly the same argv as it originally had, and loads the state file, reconstructing any objects as appropriate. The state file contains information about all locks held and all network services and clients currently active. An example state document is { "server": { "min_workers": 1, "max_workers": 20, "priority_workers": 0, "max_clients": 20, "keepaliveInterval": 4294967295, "keepaliveCount": 0, "keepaliveRequired": false, "services": [ { "auth": 0, "readonly": false, "nrequests_client_max": 1, "socks": [ { "fd": 6, "errfd": -1, "pid": 0, "isClient": false } ] } ], "clients": [ { "auth": 0, "readonly": false, "nrequests_max": 1, "sock": { "fd": 9, "errfd": -1, "pid": 0, "isClient": true }, "privateData": { "restricted": true, "ownerPid": 1722, "ownerId": 6, "ownerName": "f18x86_64", "ownerUUID": "97586ba9-df27-9459-c806-f016c8bbd224" } }, { "auth": 0, "readonly": false, "nrequests_max": 1, "sock": { "fd": 10, "errfd": -1, "pid": 0, "isClient": true }, "privateData": { "restricted": true, "ownerPid": 1784, "ownerId": 7, "ownerName": "f16x86_64", "ownerUUID": "7b8e5e42-b875-61e9-b981-91ad8fa46979" } } ] }, "defaultLockspace": { "resources": [ { "name": "/var/lib/libvirt/images/f16x86_64.raw", "path": "/var/lib/libvirt/images/f16x86_64.raw", "fd": 14, "lockHeld": true, "flags": 0, "owners": [ 1784 ] }, { "name": "/var/lib/libvirt/images/shared.img", "path": "/var/lib/libvirt/images/shared.img", "fd": 12, "lockHeld": true, "flags": 1, "owners": [ 1722, 1784 ] }, { "name": "/var/lib/libvirt/images/f18x86_64.img", "path": "/var/lib/libvirt/images/f18x86_64.img", "fd": 11, "lockHeld": true, "flags": 0, "owners": [ 1722 ] } ] }, "lockspaces": [ ], "magic": "30199" } Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2012-08-07 11:13:26 +00:00
}
static int
virLockDaemonSetupSignals(virNetDaemonPtr dmn)
{
if (virNetDaemonAddSignalHandler(dmn, SIGINT, virLockDaemonShutdownHandler, NULL) < 0)
return -1;
if (virNetDaemonAddSignalHandler(dmn, SIGQUIT, virLockDaemonShutdownHandler, NULL) < 0)
return -1;
if (virNetDaemonAddSignalHandler(dmn, SIGTERM, virLockDaemonShutdownHandler, NULL) < 0)
return -1;
if (virNetDaemonAddSignalHandler(dmn, SIGUSR1, virLockDaemonExecRestartHandler, NULL) < 0)
Add support for re-exec() of virtlockd upon SIGUSR1 The virtlockd daemon maintains file locks on behalf of libvirtd and any VMs it is running. These file locks must be held for as long as any VM is running. If virtlockd itself ever quits, then it is expected that a node would be fenced/rebooted. Thus to allow for software upgrads on live systemd, virtlockd needs the ability to re-exec() itself. Upon receipt of SIGUSR1, virtlockd will save its current live state out to a file /var/run/virtlockd-restart-exec.json It then re-exec()'s itself with exactly the same argv as it originally had, and loads the state file, reconstructing any objects as appropriate. The state file contains information about all locks held and all network services and clients currently active. An example state document is { "server": { "min_workers": 1, "max_workers": 20, "priority_workers": 0, "max_clients": 20, "keepaliveInterval": 4294967295, "keepaliveCount": 0, "keepaliveRequired": false, "services": [ { "auth": 0, "readonly": false, "nrequests_client_max": 1, "socks": [ { "fd": 6, "errfd": -1, "pid": 0, "isClient": false } ] } ], "clients": [ { "auth": 0, "readonly": false, "nrequests_max": 1, "sock": { "fd": 9, "errfd": -1, "pid": 0, "isClient": true }, "privateData": { "restricted": true, "ownerPid": 1722, "ownerId": 6, "ownerName": "f18x86_64", "ownerUUID": "97586ba9-df27-9459-c806-f016c8bbd224" } }, { "auth": 0, "readonly": false, "nrequests_max": 1, "sock": { "fd": 10, "errfd": -1, "pid": 0, "isClient": true }, "privateData": { "restricted": true, "ownerPid": 1784, "ownerId": 7, "ownerName": "f16x86_64", "ownerUUID": "7b8e5e42-b875-61e9-b981-91ad8fa46979" } } ] }, "defaultLockspace": { "resources": [ { "name": "/var/lib/libvirt/images/f16x86_64.raw", "path": "/var/lib/libvirt/images/f16x86_64.raw", "fd": 14, "lockHeld": true, "flags": 0, "owners": [ 1784 ] }, { "name": "/var/lib/libvirt/images/shared.img", "path": "/var/lib/libvirt/images/shared.img", "fd": 12, "lockHeld": true, "flags": 1, "owners": [ 1722, 1784 ] }, { "name": "/var/lib/libvirt/images/f18x86_64.img", "path": "/var/lib/libvirt/images/f18x86_64.img", "fd": 11, "lockHeld": true, "flags": 0, "owners": [ 1722 ] } ] }, "lockspaces": [ ], "magic": "30199" } Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2012-08-07 11:13:26 +00:00
return -1;
return 0;
}
struct virLockDaemonClientReleaseData {
virLockDaemonClientPtr client;
bool hadSomeLeases;
bool gotError;
};
static int
virLockDaemonClientReleaseLockspace(void *payload,
const char *name G_GNUC_UNUSED,
void *opaque)
{
virLockSpacePtr lockspace = payload;
struct virLockDaemonClientReleaseData *data = opaque;
int rc;
rc = virLockSpaceReleaseResourcesForOwner(lockspace,
data->client->clientPid);
if (rc > 0)
data->hadSomeLeases = true;
else if (rc < 0)
data->gotError = true;
return 0;
}
static void
virLockDaemonClientFree(void *opaque)
{
virLockDaemonClientPtr priv = opaque;
if (!priv)
return;
VIR_DEBUG("priv=%p client=%lld owner=%lld",
priv,
(unsigned long long)priv->clientPid,
(unsigned long long)priv->ownerPid);
/* If client & owner match, this is the lock holder */
if (priv->clientPid == priv->ownerPid) {
size_t i;
struct virLockDaemonClientReleaseData data = {
.client = priv, .hadSomeLeases = false, .gotError = false
};
/* Release all locks associated with this
* owner in all lockspaces */
virLockDaemonLock(lockDaemon);
virHashForEach(lockDaemon->lockspaces,
virLockDaemonClientReleaseLockspace,
&data);
virLockDaemonClientReleaseLockspace(lockDaemon->defaultLockspace,
"",
&data);
virLockDaemonUnlock(lockDaemon);
/* If the client had some active leases when it
* closed the connection, we must kill it off
* to make sure it doesn't do nasty stuff */
if (data.gotError || data.hadSomeLeases) {
for (i = 0; i < 15; i++) {
int signum;
if (i == 0)
signum = SIGTERM;
else if (i == 8)
signum = SIGKILL;
else
signum = 0;
if (priv->clientPid != 0 && virProcessKill(priv->clientPid, signum) < 0) {
if (errno == ESRCH)
break;
VIR_WARN("Failed to kill off pid %lld",
(unsigned long long)priv->clientPid);
}
g_usleep(200 * 1000);
}
}
}
g_mutex_clear(&priv->lock);
lock_daemon: Fix some memleaks 28 bytes in 1 blocks are definitely lost in loss record 26 of 66 at 0x4C2CF0F: malloc (vg_replace_malloc.c:299) by 0x7A02719: strdup (strdup.c:42) by 0x197DC1: virStrdup (virstring.c:961) by 0x12B478: virLockDaemonConfigFilePath (lock_daemon_config.c:44) by 0x12A759: main (lock_daemon.c:1270) 62 (32 direct, 30 indirect) bytes in 1 blocks are definitely lost in loss record 41 of 66 at 0x4C2EF26: calloc (vg_replace_malloc.c:711) by 0x151B61: virAlloc (viralloc.c:144) by 0x12B56C: virLockDaemonConfigNew (lock_daemon_config.c:71) by 0x12A491: main (lock_daemon.c:1262) 13 bytes in 1 blocks are definitely lost in loss record 21 of 70 at 0x4C2CF0F: malloc (vg_replace_malloc.c:299) by 0x7A02719: strdup (strdup.c:42) by 0x197E3F: virStrdup (virstring.c:961) by 0x12C86B: virLockSpaceProtocolDispatchRegister (lock_daemon_dispatch.c:291) by 0x12BB73: virLockSpaceProtocolDispatchRegisterHelper (lock_daemon_dispatch_stubs.h:152) by 0x1336AA: virNetServerProgramDispatchCall (virnetserverprogram.c:437) by 0x13320D: virNetServerProgramDispatch (virnetserverprogram.c:304) by 0x139E3E: virNetServerProcessMsg (virnetserver.c:144) by 0x13A1A2: virNetServerDispatchNewMessage (virnetserver.c:230) by 0x1350F5: virNetServerClientDispatchMessage (virnetserverclient.c:343) by 0x137680: virNetServerClientDispatchEvent (virnetserverclient.c:1498) by 0x147704: virNetSocketEventHandle (virnetsocket.c:2140) Signed-off-by: Michal Privoznik <mprivozn@redhat.com> Reviewed-by: John Ferlan <jferlan@redhat.com>
2018-08-26 06:48:47 +00:00
VIR_FREE(priv->ownerName);
VIR_FREE(priv);
}
static void *
virLockDaemonClientNew(virNetServerClientPtr client,
void *opaque)
{
virLockDaemonClientPtr priv;
uid_t clientuid;
gid_t clientgid;
unsigned long long timestamp;
bool privileged = opaque != NULL;
priv = g_new0(virLockDaemonClient, 1);
g_mutex_init(&priv->lock);
if (virNetServerClientGetUNIXIdentity(client,
&clientuid,
&clientgid,
&priv->clientPid,
&timestamp) < 0)
goto error;
VIR_DEBUG("New client pid %llu uid %llu",
(unsigned long long)priv->clientPid,
(unsigned long long)clientuid);
if (!privileged) {
if (geteuid() != clientuid) {
2013-12-20 14:02:49 +00:00
virReportRestrictedError(_("Disallowing client %llu with uid %llu"),
(unsigned long long)priv->clientPid,
(unsigned long long)clientuid);
goto error;
}
} else {
if (clientuid != 0) {
2013-12-20 14:02:49 +00:00
virReportRestrictedError(_("Disallowing client %llu with uid %llu"),
(unsigned long long)priv->clientPid,
(unsigned long long)clientuid);
goto error;
}
}
/* there's no closing handshake in the locking protocol */
virNetServerClientSetQuietEOF(client);
return priv;
error:
g_mutex_clear(&priv->lock);
VIR_FREE(priv);
return NULL;
}
Add support for re-exec() of virtlockd upon SIGUSR1 The virtlockd daemon maintains file locks on behalf of libvirtd and any VMs it is running. These file locks must be held for as long as any VM is running. If virtlockd itself ever quits, then it is expected that a node would be fenced/rebooted. Thus to allow for software upgrads on live systemd, virtlockd needs the ability to re-exec() itself. Upon receipt of SIGUSR1, virtlockd will save its current live state out to a file /var/run/virtlockd-restart-exec.json It then re-exec()'s itself with exactly the same argv as it originally had, and loads the state file, reconstructing any objects as appropriate. The state file contains information about all locks held and all network services and clients currently active. An example state document is { "server": { "min_workers": 1, "max_workers": 20, "priority_workers": 0, "max_clients": 20, "keepaliveInterval": 4294967295, "keepaliveCount": 0, "keepaliveRequired": false, "services": [ { "auth": 0, "readonly": false, "nrequests_client_max": 1, "socks": [ { "fd": 6, "errfd": -1, "pid": 0, "isClient": false } ] } ], "clients": [ { "auth": 0, "readonly": false, "nrequests_max": 1, "sock": { "fd": 9, "errfd": -1, "pid": 0, "isClient": true }, "privateData": { "restricted": true, "ownerPid": 1722, "ownerId": 6, "ownerName": "f18x86_64", "ownerUUID": "97586ba9-df27-9459-c806-f016c8bbd224" } }, { "auth": 0, "readonly": false, "nrequests_max": 1, "sock": { "fd": 10, "errfd": -1, "pid": 0, "isClient": true }, "privateData": { "restricted": true, "ownerPid": 1784, "ownerId": 7, "ownerName": "f16x86_64", "ownerUUID": "7b8e5e42-b875-61e9-b981-91ad8fa46979" } } ] }, "defaultLockspace": { "resources": [ { "name": "/var/lib/libvirt/images/f16x86_64.raw", "path": "/var/lib/libvirt/images/f16x86_64.raw", "fd": 14, "lockHeld": true, "flags": 0, "owners": [ 1784 ] }, { "name": "/var/lib/libvirt/images/shared.img", "path": "/var/lib/libvirt/images/shared.img", "fd": 12, "lockHeld": true, "flags": 1, "owners": [ 1722, 1784 ] }, { "name": "/var/lib/libvirt/images/f18x86_64.img", "path": "/var/lib/libvirt/images/f18x86_64.img", "fd": 11, "lockHeld": true, "flags": 0, "owners": [ 1722 ] } ] }, "lockspaces": [ ], "magic": "30199" } Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2012-08-07 11:13:26 +00:00
static void *
virLockDaemonClientNewPostExecRestart(virNetServerClientPtr client,
virJSONValuePtr object,
void *opaque)
{
virLockDaemonClientPtr priv = virLockDaemonClientNew(client, opaque);
unsigned int ownerPid;
const char *ownerUUID;
const char *ownerName;
if (!priv)
return NULL;
if (virJSONValueObjectGetBoolean(object, "restricted", &priv->restricted) < 0) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("Missing restricted data in JSON document"));
goto error;
}
if (virJSONValueObjectGetNumberUint(object, "ownerPid", &ownerPid) < 0) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("Missing ownerPid data in JSON document"));
goto error;
}
priv->ownerPid = (pid_t)ownerPid;
if (virJSONValueObjectGetNumberUint(object, "ownerId", &priv->ownerId) < 0) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("Missing ownerId data in JSON document"));
goto error;
}
if (!(ownerName = virJSONValueObjectGetString(object, "ownerName"))) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("Missing ownerName data in JSON document"));
goto error;
}
priv->ownerName = g_strdup(ownerName);
Add support for re-exec() of virtlockd upon SIGUSR1 The virtlockd daemon maintains file locks on behalf of libvirtd and any VMs it is running. These file locks must be held for as long as any VM is running. If virtlockd itself ever quits, then it is expected that a node would be fenced/rebooted. Thus to allow for software upgrads on live systemd, virtlockd needs the ability to re-exec() itself. Upon receipt of SIGUSR1, virtlockd will save its current live state out to a file /var/run/virtlockd-restart-exec.json It then re-exec()'s itself with exactly the same argv as it originally had, and loads the state file, reconstructing any objects as appropriate. The state file contains information about all locks held and all network services and clients currently active. An example state document is { "server": { "min_workers": 1, "max_workers": 20, "priority_workers": 0, "max_clients": 20, "keepaliveInterval": 4294967295, "keepaliveCount": 0, "keepaliveRequired": false, "services": [ { "auth": 0, "readonly": false, "nrequests_client_max": 1, "socks": [ { "fd": 6, "errfd": -1, "pid": 0, "isClient": false } ] } ], "clients": [ { "auth": 0, "readonly": false, "nrequests_max": 1, "sock": { "fd": 9, "errfd": -1, "pid": 0, "isClient": true }, "privateData": { "restricted": true, "ownerPid": 1722, "ownerId": 6, "ownerName": "f18x86_64", "ownerUUID": "97586ba9-df27-9459-c806-f016c8bbd224" } }, { "auth": 0, "readonly": false, "nrequests_max": 1, "sock": { "fd": 10, "errfd": -1, "pid": 0, "isClient": true }, "privateData": { "restricted": true, "ownerPid": 1784, "ownerId": 7, "ownerName": "f16x86_64", "ownerUUID": "7b8e5e42-b875-61e9-b981-91ad8fa46979" } } ] }, "defaultLockspace": { "resources": [ { "name": "/var/lib/libvirt/images/f16x86_64.raw", "path": "/var/lib/libvirt/images/f16x86_64.raw", "fd": 14, "lockHeld": true, "flags": 0, "owners": [ 1784 ] }, { "name": "/var/lib/libvirt/images/shared.img", "path": "/var/lib/libvirt/images/shared.img", "fd": 12, "lockHeld": true, "flags": 1, "owners": [ 1722, 1784 ] }, { "name": "/var/lib/libvirt/images/f18x86_64.img", "path": "/var/lib/libvirt/images/f18x86_64.img", "fd": 11, "lockHeld": true, "flags": 0, "owners": [ 1722 ] } ] }, "lockspaces": [ ], "magic": "30199" } Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2012-08-07 11:13:26 +00:00
if (!(ownerUUID = virJSONValueObjectGetString(object, "ownerUUID"))) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("Missing ownerUUID data in JSON document"));
goto error;
}
if (virUUIDParse(ownerUUID, priv->ownerUUID) < 0) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("Missing ownerUUID data in JSON document"));
goto error;
}
return priv;
error:
Add support for re-exec() of virtlockd upon SIGUSR1 The virtlockd daemon maintains file locks on behalf of libvirtd and any VMs it is running. These file locks must be held for as long as any VM is running. If virtlockd itself ever quits, then it is expected that a node would be fenced/rebooted. Thus to allow for software upgrads on live systemd, virtlockd needs the ability to re-exec() itself. Upon receipt of SIGUSR1, virtlockd will save its current live state out to a file /var/run/virtlockd-restart-exec.json It then re-exec()'s itself with exactly the same argv as it originally had, and loads the state file, reconstructing any objects as appropriate. The state file contains information about all locks held and all network services and clients currently active. An example state document is { "server": { "min_workers": 1, "max_workers": 20, "priority_workers": 0, "max_clients": 20, "keepaliveInterval": 4294967295, "keepaliveCount": 0, "keepaliveRequired": false, "services": [ { "auth": 0, "readonly": false, "nrequests_client_max": 1, "socks": [ { "fd": 6, "errfd": -1, "pid": 0, "isClient": false } ] } ], "clients": [ { "auth": 0, "readonly": false, "nrequests_max": 1, "sock": { "fd": 9, "errfd": -1, "pid": 0, "isClient": true }, "privateData": { "restricted": true, "ownerPid": 1722, "ownerId": 6, "ownerName": "f18x86_64", "ownerUUID": "97586ba9-df27-9459-c806-f016c8bbd224" } }, { "auth": 0, "readonly": false, "nrequests_max": 1, "sock": { "fd": 10, "errfd": -1, "pid": 0, "isClient": true }, "privateData": { "restricted": true, "ownerPid": 1784, "ownerId": 7, "ownerName": "f16x86_64", "ownerUUID": "7b8e5e42-b875-61e9-b981-91ad8fa46979" } } ] }, "defaultLockspace": { "resources": [ { "name": "/var/lib/libvirt/images/f16x86_64.raw", "path": "/var/lib/libvirt/images/f16x86_64.raw", "fd": 14, "lockHeld": true, "flags": 0, "owners": [ 1784 ] }, { "name": "/var/lib/libvirt/images/shared.img", "path": "/var/lib/libvirt/images/shared.img", "fd": 12, "lockHeld": true, "flags": 1, "owners": [ 1722, 1784 ] }, { "name": "/var/lib/libvirt/images/f18x86_64.img", "path": "/var/lib/libvirt/images/f18x86_64.img", "fd": 11, "lockHeld": true, "flags": 0, "owners": [ 1722 ] } ] }, "lockspaces": [ ], "magic": "30199" } Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2012-08-07 11:13:26 +00:00
virLockDaemonClientFree(priv);
return NULL;
}
static virJSONValuePtr
virLockDaemonClientPreExecRestart(virNetServerClientPtr client G_GNUC_UNUSED,
Add support for re-exec() of virtlockd upon SIGUSR1 The virtlockd daemon maintains file locks on behalf of libvirtd and any VMs it is running. These file locks must be held for as long as any VM is running. If virtlockd itself ever quits, then it is expected that a node would be fenced/rebooted. Thus to allow for software upgrads on live systemd, virtlockd needs the ability to re-exec() itself. Upon receipt of SIGUSR1, virtlockd will save its current live state out to a file /var/run/virtlockd-restart-exec.json It then re-exec()'s itself with exactly the same argv as it originally had, and loads the state file, reconstructing any objects as appropriate. The state file contains information about all locks held and all network services and clients currently active. An example state document is { "server": { "min_workers": 1, "max_workers": 20, "priority_workers": 0, "max_clients": 20, "keepaliveInterval": 4294967295, "keepaliveCount": 0, "keepaliveRequired": false, "services": [ { "auth": 0, "readonly": false, "nrequests_client_max": 1, "socks": [ { "fd": 6, "errfd": -1, "pid": 0, "isClient": false } ] } ], "clients": [ { "auth": 0, "readonly": false, "nrequests_max": 1, "sock": { "fd": 9, "errfd": -1, "pid": 0, "isClient": true }, "privateData": { "restricted": true, "ownerPid": 1722, "ownerId": 6, "ownerName": "f18x86_64", "ownerUUID": "97586ba9-df27-9459-c806-f016c8bbd224" } }, { "auth": 0, "readonly": false, "nrequests_max": 1, "sock": { "fd": 10, "errfd": -1, "pid": 0, "isClient": true }, "privateData": { "restricted": true, "ownerPid": 1784, "ownerId": 7, "ownerName": "f16x86_64", "ownerUUID": "7b8e5e42-b875-61e9-b981-91ad8fa46979" } } ] }, "defaultLockspace": { "resources": [ { "name": "/var/lib/libvirt/images/f16x86_64.raw", "path": "/var/lib/libvirt/images/f16x86_64.raw", "fd": 14, "lockHeld": true, "flags": 0, "owners": [ 1784 ] }, { "name": "/var/lib/libvirt/images/shared.img", "path": "/var/lib/libvirt/images/shared.img", "fd": 12, "lockHeld": true, "flags": 1, "owners": [ 1722, 1784 ] }, { "name": "/var/lib/libvirt/images/f18x86_64.img", "path": "/var/lib/libvirt/images/f18x86_64.img", "fd": 11, "lockHeld": true, "flags": 0, "owners": [ 1722 ] } ] }, "lockspaces": [ ], "magic": "30199" } Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2012-08-07 11:13:26 +00:00
void *opaque)
{
virLockDaemonClientPtr priv = opaque;
virJSONValuePtr object = virJSONValueNewObject();
char uuidstr[VIR_UUID_STRING_BUFLEN];
if (virJSONValueObjectAppendBoolean(object, "restricted", priv->restricted) < 0) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("Cannot set restricted data in JSON document"));
goto error;
}
if (virJSONValueObjectAppendNumberUint(object, "ownerPid", priv->ownerPid) < 0) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("Cannot set ownerPid data in JSON document"));
goto error;
}
if (virJSONValueObjectAppendNumberUint(object, "ownerId", priv->ownerId) < 0) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("Cannot set ownerId data in JSON document"));
goto error;
}
if (virJSONValueObjectAppendString(object, "ownerName", priv->ownerName) < 0) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("Cannot set ownerName data in JSON document"));
goto error;
}
virUUIDFormat(priv->ownerUUID, uuidstr);
if (virJSONValueObjectAppendString(object, "ownerUUID", uuidstr) < 0) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("Cannot set ownerUUID data in JSON document"));
goto error;
}
return object;
error:
Add support for re-exec() of virtlockd upon SIGUSR1 The virtlockd daemon maintains file locks on behalf of libvirtd and any VMs it is running. These file locks must be held for as long as any VM is running. If virtlockd itself ever quits, then it is expected that a node would be fenced/rebooted. Thus to allow for software upgrads on live systemd, virtlockd needs the ability to re-exec() itself. Upon receipt of SIGUSR1, virtlockd will save its current live state out to a file /var/run/virtlockd-restart-exec.json It then re-exec()'s itself with exactly the same argv as it originally had, and loads the state file, reconstructing any objects as appropriate. The state file contains information about all locks held and all network services and clients currently active. An example state document is { "server": { "min_workers": 1, "max_workers": 20, "priority_workers": 0, "max_clients": 20, "keepaliveInterval": 4294967295, "keepaliveCount": 0, "keepaliveRequired": false, "services": [ { "auth": 0, "readonly": false, "nrequests_client_max": 1, "socks": [ { "fd": 6, "errfd": -1, "pid": 0, "isClient": false } ] } ], "clients": [ { "auth": 0, "readonly": false, "nrequests_max": 1, "sock": { "fd": 9, "errfd": -1, "pid": 0, "isClient": true }, "privateData": { "restricted": true, "ownerPid": 1722, "ownerId": 6, "ownerName": "f18x86_64", "ownerUUID": "97586ba9-df27-9459-c806-f016c8bbd224" } }, { "auth": 0, "readonly": false, "nrequests_max": 1, "sock": { "fd": 10, "errfd": -1, "pid": 0, "isClient": true }, "privateData": { "restricted": true, "ownerPid": 1784, "ownerId": 7, "ownerName": "f16x86_64", "ownerUUID": "7b8e5e42-b875-61e9-b981-91ad8fa46979" } } ] }, "defaultLockspace": { "resources": [ { "name": "/var/lib/libvirt/images/f16x86_64.raw", "path": "/var/lib/libvirt/images/f16x86_64.raw", "fd": 14, "lockHeld": true, "flags": 0, "owners": [ 1784 ] }, { "name": "/var/lib/libvirt/images/shared.img", "path": "/var/lib/libvirt/images/shared.img", "fd": 12, "lockHeld": true, "flags": 1, "owners": [ 1722, 1784 ] }, { "name": "/var/lib/libvirt/images/f18x86_64.img", "path": "/var/lib/libvirt/images/f18x86_64.img", "fd": 11, "lockHeld": true, "flags": 0, "owners": [ 1722 ] } ] }, "lockspaces": [ ], "magic": "30199" } Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2012-08-07 11:13:26 +00:00
virJSONValueFree(object);
return NULL;
}
static int
virLockDaemonExecRestartStatePath(bool privileged,
char **state_file)
{
if (privileged) {
*state_file = g_strdup(RUNSTATEDIR "/virtlockd-restart-exec.json");
} else {
g_autofree char *rundir = NULL;
mode_t old_umask;
rundir = virGetUserRuntimeDirectory();
old_umask = umask(077);
if (virFileMakePath(rundir) < 0) {
umask(old_umask);
return -1;
}
umask(old_umask);
*state_file = g_strdup_printf("%s/virtlockd-restart-exec.json", rundir);
}
return 0;
}
Add support for re-exec() of virtlockd upon SIGUSR1 The virtlockd daemon maintains file locks on behalf of libvirtd and any VMs it is running. These file locks must be held for as long as any VM is running. If virtlockd itself ever quits, then it is expected that a node would be fenced/rebooted. Thus to allow for software upgrads on live systemd, virtlockd needs the ability to re-exec() itself. Upon receipt of SIGUSR1, virtlockd will save its current live state out to a file /var/run/virtlockd-restart-exec.json It then re-exec()'s itself with exactly the same argv as it originally had, and loads the state file, reconstructing any objects as appropriate. The state file contains information about all locks held and all network services and clients currently active. An example state document is { "server": { "min_workers": 1, "max_workers": 20, "priority_workers": 0, "max_clients": 20, "keepaliveInterval": 4294967295, "keepaliveCount": 0, "keepaliveRequired": false, "services": [ { "auth": 0, "readonly": false, "nrequests_client_max": 1, "socks": [ { "fd": 6, "errfd": -1, "pid": 0, "isClient": false } ] } ], "clients": [ { "auth": 0, "readonly": false, "nrequests_max": 1, "sock": { "fd": 9, "errfd": -1, "pid": 0, "isClient": true }, "privateData": { "restricted": true, "ownerPid": 1722, "ownerId": 6, "ownerName": "f18x86_64", "ownerUUID": "97586ba9-df27-9459-c806-f016c8bbd224" } }, { "auth": 0, "readonly": false, "nrequests_max": 1, "sock": { "fd": 10, "errfd": -1, "pid": 0, "isClient": true }, "privateData": { "restricted": true, "ownerPid": 1784, "ownerId": 7, "ownerName": "f16x86_64", "ownerUUID": "7b8e5e42-b875-61e9-b981-91ad8fa46979" } } ] }, "defaultLockspace": { "resources": [ { "name": "/var/lib/libvirt/images/f16x86_64.raw", "path": "/var/lib/libvirt/images/f16x86_64.raw", "fd": 14, "lockHeld": true, "flags": 0, "owners": [ 1784 ] }, { "name": "/var/lib/libvirt/images/shared.img", "path": "/var/lib/libvirt/images/shared.img", "fd": 12, "lockHeld": true, "flags": 1, "owners": [ 1722, 1784 ] }, { "name": "/var/lib/libvirt/images/f18x86_64.img", "path": "/var/lib/libvirt/images/f18x86_64.img", "fd": 11, "lockHeld": true, "flags": 0, "owners": [ 1722 ] } ] }, "lockspaces": [ ], "magic": "30199" } Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2012-08-07 11:13:26 +00:00
static char *
virLockDaemonGetExecRestartMagic(void)
{
char *ret;
ret = g_strdup_printf("%lld", (long long int)getpid());
Add support for re-exec() of virtlockd upon SIGUSR1 The virtlockd daemon maintains file locks on behalf of libvirtd and any VMs it is running. These file locks must be held for as long as any VM is running. If virtlockd itself ever quits, then it is expected that a node would be fenced/rebooted. Thus to allow for software upgrads on live systemd, virtlockd needs the ability to re-exec() itself. Upon receipt of SIGUSR1, virtlockd will save its current live state out to a file /var/run/virtlockd-restart-exec.json It then re-exec()'s itself with exactly the same argv as it originally had, and loads the state file, reconstructing any objects as appropriate. The state file contains information about all locks held and all network services and clients currently active. An example state document is { "server": { "min_workers": 1, "max_workers": 20, "priority_workers": 0, "max_clients": 20, "keepaliveInterval": 4294967295, "keepaliveCount": 0, "keepaliveRequired": false, "services": [ { "auth": 0, "readonly": false, "nrequests_client_max": 1, "socks": [ { "fd": 6, "errfd": -1, "pid": 0, "isClient": false } ] } ], "clients": [ { "auth": 0, "readonly": false, "nrequests_max": 1, "sock": { "fd": 9, "errfd": -1, "pid": 0, "isClient": true }, "privateData": { "restricted": true, "ownerPid": 1722, "ownerId": 6, "ownerName": "f18x86_64", "ownerUUID": "97586ba9-df27-9459-c806-f016c8bbd224" } }, { "auth": 0, "readonly": false, "nrequests_max": 1, "sock": { "fd": 10, "errfd": -1, "pid": 0, "isClient": true }, "privateData": { "restricted": true, "ownerPid": 1784, "ownerId": 7, "ownerName": "f16x86_64", "ownerUUID": "7b8e5e42-b875-61e9-b981-91ad8fa46979" } } ] }, "defaultLockspace": { "resources": [ { "name": "/var/lib/libvirt/images/f16x86_64.raw", "path": "/var/lib/libvirt/images/f16x86_64.raw", "fd": 14, "lockHeld": true, "flags": 0, "owners": [ 1784 ] }, { "name": "/var/lib/libvirt/images/shared.img", "path": "/var/lib/libvirt/images/shared.img", "fd": 12, "lockHeld": true, "flags": 1, "owners": [ 1722, 1784 ] }, { "name": "/var/lib/libvirt/images/f18x86_64.img", "path": "/var/lib/libvirt/images/f18x86_64.img", "fd": 11, "lockHeld": true, "flags": 0, "owners": [ 1722 ] } ] }, "lockspaces": [ ], "magic": "30199" } Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2012-08-07 11:13:26 +00:00
return ret;
}
static int
virLockDaemonPostExecRestart(const char *state_file,
const char *pid_file,
int *pid_file_fd,
bool privileged)
Add support for re-exec() of virtlockd upon SIGUSR1 The virtlockd daemon maintains file locks on behalf of libvirtd and any VMs it is running. These file locks must be held for as long as any VM is running. If virtlockd itself ever quits, then it is expected that a node would be fenced/rebooted. Thus to allow for software upgrads on live systemd, virtlockd needs the ability to re-exec() itself. Upon receipt of SIGUSR1, virtlockd will save its current live state out to a file /var/run/virtlockd-restart-exec.json It then re-exec()'s itself with exactly the same argv as it originally had, and loads the state file, reconstructing any objects as appropriate. The state file contains information about all locks held and all network services and clients currently active. An example state document is { "server": { "min_workers": 1, "max_workers": 20, "priority_workers": 0, "max_clients": 20, "keepaliveInterval": 4294967295, "keepaliveCount": 0, "keepaliveRequired": false, "services": [ { "auth": 0, "readonly": false, "nrequests_client_max": 1, "socks": [ { "fd": 6, "errfd": -1, "pid": 0, "isClient": false } ] } ], "clients": [ { "auth": 0, "readonly": false, "nrequests_max": 1, "sock": { "fd": 9, "errfd": -1, "pid": 0, "isClient": true }, "privateData": { "restricted": true, "ownerPid": 1722, "ownerId": 6, "ownerName": "f18x86_64", "ownerUUID": "97586ba9-df27-9459-c806-f016c8bbd224" } }, { "auth": 0, "readonly": false, "nrequests_max": 1, "sock": { "fd": 10, "errfd": -1, "pid": 0, "isClient": true }, "privateData": { "restricted": true, "ownerPid": 1784, "ownerId": 7, "ownerName": "f16x86_64", "ownerUUID": "7b8e5e42-b875-61e9-b981-91ad8fa46979" } } ] }, "defaultLockspace": { "resources": [ { "name": "/var/lib/libvirt/images/f16x86_64.raw", "path": "/var/lib/libvirt/images/f16x86_64.raw", "fd": 14, "lockHeld": true, "flags": 0, "owners": [ 1784 ] }, { "name": "/var/lib/libvirt/images/shared.img", "path": "/var/lib/libvirt/images/shared.img", "fd": 12, "lockHeld": true, "flags": 1, "owners": [ 1722, 1784 ] }, { "name": "/var/lib/libvirt/images/f18x86_64.img", "path": "/var/lib/libvirt/images/f18x86_64.img", "fd": 11, "lockHeld": true, "flags": 0, "owners": [ 1722 ] } ] }, "lockspaces": [ ], "magic": "30199" } Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2012-08-07 11:13:26 +00:00
{
const char *gotmagic;
char *wantmagic = NULL;
int ret = -1;
char *state = NULL;
virJSONValuePtr object = NULL;
VIR_DEBUG("Running post-restart exec");
if (!virFileExists(state_file)) {
VIR_DEBUG("No restart state file %s present",
state_file);
Add support for re-exec() of virtlockd upon SIGUSR1 The virtlockd daemon maintains file locks on behalf of libvirtd and any VMs it is running. These file locks must be held for as long as any VM is running. If virtlockd itself ever quits, then it is expected that a node would be fenced/rebooted. Thus to allow for software upgrads on live systemd, virtlockd needs the ability to re-exec() itself. Upon receipt of SIGUSR1, virtlockd will save its current live state out to a file /var/run/virtlockd-restart-exec.json It then re-exec()'s itself with exactly the same argv as it originally had, and loads the state file, reconstructing any objects as appropriate. The state file contains information about all locks held and all network services and clients currently active. An example state document is { "server": { "min_workers": 1, "max_workers": 20, "priority_workers": 0, "max_clients": 20, "keepaliveInterval": 4294967295, "keepaliveCount": 0, "keepaliveRequired": false, "services": [ { "auth": 0, "readonly": false, "nrequests_client_max": 1, "socks": [ { "fd": 6, "errfd": -1, "pid": 0, "isClient": false } ] } ], "clients": [ { "auth": 0, "readonly": false, "nrequests_max": 1, "sock": { "fd": 9, "errfd": -1, "pid": 0, "isClient": true }, "privateData": { "restricted": true, "ownerPid": 1722, "ownerId": 6, "ownerName": "f18x86_64", "ownerUUID": "97586ba9-df27-9459-c806-f016c8bbd224" } }, { "auth": 0, "readonly": false, "nrequests_max": 1, "sock": { "fd": 10, "errfd": -1, "pid": 0, "isClient": true }, "privateData": { "restricted": true, "ownerPid": 1784, "ownerId": 7, "ownerName": "f16x86_64", "ownerUUID": "7b8e5e42-b875-61e9-b981-91ad8fa46979" } } ] }, "defaultLockspace": { "resources": [ { "name": "/var/lib/libvirt/images/f16x86_64.raw", "path": "/var/lib/libvirt/images/f16x86_64.raw", "fd": 14, "lockHeld": true, "flags": 0, "owners": [ 1784 ] }, { "name": "/var/lib/libvirt/images/shared.img", "path": "/var/lib/libvirt/images/shared.img", "fd": 12, "lockHeld": true, "flags": 1, "owners": [ 1722, 1784 ] }, { "name": "/var/lib/libvirt/images/f18x86_64.img", "path": "/var/lib/libvirt/images/f18x86_64.img", "fd": 11, "lockHeld": true, "flags": 0, "owners": [ 1722 ] } ] }, "lockspaces": [ ], "magic": "30199" } Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2012-08-07 11:13:26 +00:00
ret = 0;
goto cleanup;
}
if (virFileReadAll(state_file,
Add support for re-exec() of virtlockd upon SIGUSR1 The virtlockd daemon maintains file locks on behalf of libvirtd and any VMs it is running. These file locks must be held for as long as any VM is running. If virtlockd itself ever quits, then it is expected that a node would be fenced/rebooted. Thus to allow for software upgrads on live systemd, virtlockd needs the ability to re-exec() itself. Upon receipt of SIGUSR1, virtlockd will save its current live state out to a file /var/run/virtlockd-restart-exec.json It then re-exec()'s itself with exactly the same argv as it originally had, and loads the state file, reconstructing any objects as appropriate. The state file contains information about all locks held and all network services and clients currently active. An example state document is { "server": { "min_workers": 1, "max_workers": 20, "priority_workers": 0, "max_clients": 20, "keepaliveInterval": 4294967295, "keepaliveCount": 0, "keepaliveRequired": false, "services": [ { "auth": 0, "readonly": false, "nrequests_client_max": 1, "socks": [ { "fd": 6, "errfd": -1, "pid": 0, "isClient": false } ] } ], "clients": [ { "auth": 0, "readonly": false, "nrequests_max": 1, "sock": { "fd": 9, "errfd": -1, "pid": 0, "isClient": true }, "privateData": { "restricted": true, "ownerPid": 1722, "ownerId": 6, "ownerName": "f18x86_64", "ownerUUID": "97586ba9-df27-9459-c806-f016c8bbd224" } }, { "auth": 0, "readonly": false, "nrequests_max": 1, "sock": { "fd": 10, "errfd": -1, "pid": 0, "isClient": true }, "privateData": { "restricted": true, "ownerPid": 1784, "ownerId": 7, "ownerName": "f16x86_64", "ownerUUID": "7b8e5e42-b875-61e9-b981-91ad8fa46979" } } ] }, "defaultLockspace": { "resources": [ { "name": "/var/lib/libvirt/images/f16x86_64.raw", "path": "/var/lib/libvirt/images/f16x86_64.raw", "fd": 14, "lockHeld": true, "flags": 0, "owners": [ 1784 ] }, { "name": "/var/lib/libvirt/images/shared.img", "path": "/var/lib/libvirt/images/shared.img", "fd": 12, "lockHeld": true, "flags": 1, "owners": [ 1722, 1784 ] }, { "name": "/var/lib/libvirt/images/f18x86_64.img", "path": "/var/lib/libvirt/images/f18x86_64.img", "fd": 11, "lockHeld": true, "flags": 0, "owners": [ 1722 ] } ] }, "lockspaces": [ ], "magic": "30199" } Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2012-08-07 11:13:26 +00:00
1024 * 1024 * 10, /* 10 MB */
&state) < 0)
goto cleanup;
VIR_DEBUG("Loading state %s", state);
if (!(object = virJSONValueFromString(state)))
goto cleanup;
gotmagic = virJSONValueObjectGetString(object, "magic");
if (!gotmagic) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("Missing magic data in JSON document"));
goto cleanup;
}
if (!(wantmagic = virLockDaemonGetExecRestartMagic()))
goto cleanup;
if (STRNEQ(gotmagic, wantmagic)) {
VIR_WARN("Found restart exec file with old magic %s vs wanted %s",
gotmagic, wantmagic);
ret = 0;
goto cleanup;
}
/* Re-claim PID file now as we will not be daemonizing */
if (pid_file &&
(*pid_file_fd = virPidFileAcquirePath(pid_file, false, getpid())) < 0)
goto cleanup;
Add support for re-exec() of virtlockd upon SIGUSR1 The virtlockd daemon maintains file locks on behalf of libvirtd and any VMs it is running. These file locks must be held for as long as any VM is running. If virtlockd itself ever quits, then it is expected that a node would be fenced/rebooted. Thus to allow for software upgrads on live systemd, virtlockd needs the ability to re-exec() itself. Upon receipt of SIGUSR1, virtlockd will save its current live state out to a file /var/run/virtlockd-restart-exec.json It then re-exec()'s itself with exactly the same argv as it originally had, and loads the state file, reconstructing any objects as appropriate. The state file contains information about all locks held and all network services and clients currently active. An example state document is { "server": { "min_workers": 1, "max_workers": 20, "priority_workers": 0, "max_clients": 20, "keepaliveInterval": 4294967295, "keepaliveCount": 0, "keepaliveRequired": false, "services": [ { "auth": 0, "readonly": false, "nrequests_client_max": 1, "socks": [ { "fd": 6, "errfd": -1, "pid": 0, "isClient": false } ] } ], "clients": [ { "auth": 0, "readonly": false, "nrequests_max": 1, "sock": { "fd": 9, "errfd": -1, "pid": 0, "isClient": true }, "privateData": { "restricted": true, "ownerPid": 1722, "ownerId": 6, "ownerName": "f18x86_64", "ownerUUID": "97586ba9-df27-9459-c806-f016c8bbd224" } }, { "auth": 0, "readonly": false, "nrequests_max": 1, "sock": { "fd": 10, "errfd": -1, "pid": 0, "isClient": true }, "privateData": { "restricted": true, "ownerPid": 1784, "ownerId": 7, "ownerName": "f16x86_64", "ownerUUID": "7b8e5e42-b875-61e9-b981-91ad8fa46979" } } ] }, "defaultLockspace": { "resources": [ { "name": "/var/lib/libvirt/images/f16x86_64.raw", "path": "/var/lib/libvirt/images/f16x86_64.raw", "fd": 14, "lockHeld": true, "flags": 0, "owners": [ 1784 ] }, { "name": "/var/lib/libvirt/images/shared.img", "path": "/var/lib/libvirt/images/shared.img", "fd": 12, "lockHeld": true, "flags": 1, "owners": [ 1722, 1784 ] }, { "name": "/var/lib/libvirt/images/f18x86_64.img", "path": "/var/lib/libvirt/images/f18x86_64.img", "fd": 11, "lockHeld": true, "flags": 0, "owners": [ 1722 ] } ] }, "lockspaces": [ ], "magic": "30199" } Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2012-08-07 11:13:26 +00:00
if (!(lockDaemon = virLockDaemonNewPostExecRestart(object, privileged)))
goto cleanup;
ret = 1;
cleanup:
unlink(state_file);
Add support for re-exec() of virtlockd upon SIGUSR1 The virtlockd daemon maintains file locks on behalf of libvirtd and any VMs it is running. These file locks must be held for as long as any VM is running. If virtlockd itself ever quits, then it is expected that a node would be fenced/rebooted. Thus to allow for software upgrads on live systemd, virtlockd needs the ability to re-exec() itself. Upon receipt of SIGUSR1, virtlockd will save its current live state out to a file /var/run/virtlockd-restart-exec.json It then re-exec()'s itself with exactly the same argv as it originally had, and loads the state file, reconstructing any objects as appropriate. The state file contains information about all locks held and all network services and clients currently active. An example state document is { "server": { "min_workers": 1, "max_workers": 20, "priority_workers": 0, "max_clients": 20, "keepaliveInterval": 4294967295, "keepaliveCount": 0, "keepaliveRequired": false, "services": [ { "auth": 0, "readonly": false, "nrequests_client_max": 1, "socks": [ { "fd": 6, "errfd": -1, "pid": 0, "isClient": false } ] } ], "clients": [ { "auth": 0, "readonly": false, "nrequests_max": 1, "sock": { "fd": 9, "errfd": -1, "pid": 0, "isClient": true }, "privateData": { "restricted": true, "ownerPid": 1722, "ownerId": 6, "ownerName": "f18x86_64", "ownerUUID": "97586ba9-df27-9459-c806-f016c8bbd224" } }, { "auth": 0, "readonly": false, "nrequests_max": 1, "sock": { "fd": 10, "errfd": -1, "pid": 0, "isClient": true }, "privateData": { "restricted": true, "ownerPid": 1784, "ownerId": 7, "ownerName": "f16x86_64", "ownerUUID": "7b8e5e42-b875-61e9-b981-91ad8fa46979" } } ] }, "defaultLockspace": { "resources": [ { "name": "/var/lib/libvirt/images/f16x86_64.raw", "path": "/var/lib/libvirt/images/f16x86_64.raw", "fd": 14, "lockHeld": true, "flags": 0, "owners": [ 1784 ] }, { "name": "/var/lib/libvirt/images/shared.img", "path": "/var/lib/libvirt/images/shared.img", "fd": 12, "lockHeld": true, "flags": 1, "owners": [ 1722, 1784 ] }, { "name": "/var/lib/libvirt/images/f18x86_64.img", "path": "/var/lib/libvirt/images/f18x86_64.img", "fd": 11, "lockHeld": true, "flags": 0, "owners": [ 1722 ] } ] }, "lockspaces": [ ], "magic": "30199" } Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2012-08-07 11:13:26 +00:00
VIR_FREE(wantmagic);
VIR_FREE(state);
virJSONValueFree(object);
return ret;
}
static int
virLockDaemonPreExecRestart(const char *state_file,
virNetDaemonPtr dmn,
Add support for re-exec() of virtlockd upon SIGUSR1 The virtlockd daemon maintains file locks on behalf of libvirtd and any VMs it is running. These file locks must be held for as long as any VM is running. If virtlockd itself ever quits, then it is expected that a node would be fenced/rebooted. Thus to allow for software upgrads on live systemd, virtlockd needs the ability to re-exec() itself. Upon receipt of SIGUSR1, virtlockd will save its current live state out to a file /var/run/virtlockd-restart-exec.json It then re-exec()'s itself with exactly the same argv as it originally had, and loads the state file, reconstructing any objects as appropriate. The state file contains information about all locks held and all network services and clients currently active. An example state document is { "server": { "min_workers": 1, "max_workers": 20, "priority_workers": 0, "max_clients": 20, "keepaliveInterval": 4294967295, "keepaliveCount": 0, "keepaliveRequired": false, "services": [ { "auth": 0, "readonly": false, "nrequests_client_max": 1, "socks": [ { "fd": 6, "errfd": -1, "pid": 0, "isClient": false } ] } ], "clients": [ { "auth": 0, "readonly": false, "nrequests_max": 1, "sock": { "fd": 9, "errfd": -1, "pid": 0, "isClient": true }, "privateData": { "restricted": true, "ownerPid": 1722, "ownerId": 6, "ownerName": "f18x86_64", "ownerUUID": "97586ba9-df27-9459-c806-f016c8bbd224" } }, { "auth": 0, "readonly": false, "nrequests_max": 1, "sock": { "fd": 10, "errfd": -1, "pid": 0, "isClient": true }, "privateData": { "restricted": true, "ownerPid": 1784, "ownerId": 7, "ownerName": "f16x86_64", "ownerUUID": "7b8e5e42-b875-61e9-b981-91ad8fa46979" } } ] }, "defaultLockspace": { "resources": [ { "name": "/var/lib/libvirt/images/f16x86_64.raw", "path": "/var/lib/libvirt/images/f16x86_64.raw", "fd": 14, "lockHeld": true, "flags": 0, "owners": [ 1784 ] }, { "name": "/var/lib/libvirt/images/shared.img", "path": "/var/lib/libvirt/images/shared.img", "fd": 12, "lockHeld": true, "flags": 1, "owners": [ 1722, 1784 ] }, { "name": "/var/lib/libvirt/images/f18x86_64.img", "path": "/var/lib/libvirt/images/f18x86_64.img", "fd": 11, "lockHeld": true, "flags": 0, "owners": [ 1722 ] } ] }, "lockspaces": [ ], "magic": "30199" } Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2012-08-07 11:13:26 +00:00
char **argv)
{
virJSONValuePtr child;
char *state = NULL;
virJSONValuePtr object = virJSONValueNewObject();
Add support for re-exec() of virtlockd upon SIGUSR1 The virtlockd daemon maintains file locks on behalf of libvirtd and any VMs it is running. These file locks must be held for as long as any VM is running. If virtlockd itself ever quits, then it is expected that a node would be fenced/rebooted. Thus to allow for software upgrads on live systemd, virtlockd needs the ability to re-exec() itself. Upon receipt of SIGUSR1, virtlockd will save its current live state out to a file /var/run/virtlockd-restart-exec.json It then re-exec()'s itself with exactly the same argv as it originally had, and loads the state file, reconstructing any objects as appropriate. The state file contains information about all locks held and all network services and clients currently active. An example state document is { "server": { "min_workers": 1, "max_workers": 20, "priority_workers": 0, "max_clients": 20, "keepaliveInterval": 4294967295, "keepaliveCount": 0, "keepaliveRequired": false, "services": [ { "auth": 0, "readonly": false, "nrequests_client_max": 1, "socks": [ { "fd": 6, "errfd": -1, "pid": 0, "isClient": false } ] } ], "clients": [ { "auth": 0, "readonly": false, "nrequests_max": 1, "sock": { "fd": 9, "errfd": -1, "pid": 0, "isClient": true }, "privateData": { "restricted": true, "ownerPid": 1722, "ownerId": 6, "ownerName": "f18x86_64", "ownerUUID": "97586ba9-df27-9459-c806-f016c8bbd224" } }, { "auth": 0, "readonly": false, "nrequests_max": 1, "sock": { "fd": 10, "errfd": -1, "pid": 0, "isClient": true }, "privateData": { "restricted": true, "ownerPid": 1784, "ownerId": 7, "ownerName": "f16x86_64", "ownerUUID": "7b8e5e42-b875-61e9-b981-91ad8fa46979" } } ] }, "defaultLockspace": { "resources": [ { "name": "/var/lib/libvirt/images/f16x86_64.raw", "path": "/var/lib/libvirt/images/f16x86_64.raw", "fd": 14, "lockHeld": true, "flags": 0, "owners": [ 1784 ] }, { "name": "/var/lib/libvirt/images/shared.img", "path": "/var/lib/libvirt/images/shared.img", "fd": 12, "lockHeld": true, "flags": 1, "owners": [ 1722, 1784 ] }, { "name": "/var/lib/libvirt/images/f18x86_64.img", "path": "/var/lib/libvirt/images/f18x86_64.img", "fd": 11, "lockHeld": true, "flags": 0, "owners": [ 1722 ] } ] }, "lockspaces": [ ], "magic": "30199" } Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2012-08-07 11:13:26 +00:00
char *magic;
virHashKeyValuePairPtr pairs = NULL, tmp;
virJSONValuePtr lockspaces;
VIR_DEBUG("Running pre-restart exec");
if (!(child = virNetDaemonPreExecRestart(dmn)))
Add support for re-exec() of virtlockd upon SIGUSR1 The virtlockd daemon maintains file locks on behalf of libvirtd and any VMs it is running. These file locks must be held for as long as any VM is running. If virtlockd itself ever quits, then it is expected that a node would be fenced/rebooted. Thus to allow for software upgrads on live systemd, virtlockd needs the ability to re-exec() itself. Upon receipt of SIGUSR1, virtlockd will save its current live state out to a file /var/run/virtlockd-restart-exec.json It then re-exec()'s itself with exactly the same argv as it originally had, and loads the state file, reconstructing any objects as appropriate. The state file contains information about all locks held and all network services and clients currently active. An example state document is { "server": { "min_workers": 1, "max_workers": 20, "priority_workers": 0, "max_clients": 20, "keepaliveInterval": 4294967295, "keepaliveCount": 0, "keepaliveRequired": false, "services": [ { "auth": 0, "readonly": false, "nrequests_client_max": 1, "socks": [ { "fd": 6, "errfd": -1, "pid": 0, "isClient": false } ] } ], "clients": [ { "auth": 0, "readonly": false, "nrequests_max": 1, "sock": { "fd": 9, "errfd": -1, "pid": 0, "isClient": true }, "privateData": { "restricted": true, "ownerPid": 1722, "ownerId": 6, "ownerName": "f18x86_64", "ownerUUID": "97586ba9-df27-9459-c806-f016c8bbd224" } }, { "auth": 0, "readonly": false, "nrequests_max": 1, "sock": { "fd": 10, "errfd": -1, "pid": 0, "isClient": true }, "privateData": { "restricted": true, "ownerPid": 1784, "ownerId": 7, "ownerName": "f16x86_64", "ownerUUID": "7b8e5e42-b875-61e9-b981-91ad8fa46979" } } ] }, "defaultLockspace": { "resources": [ { "name": "/var/lib/libvirt/images/f16x86_64.raw", "path": "/var/lib/libvirt/images/f16x86_64.raw", "fd": 14, "lockHeld": true, "flags": 0, "owners": [ 1784 ] }, { "name": "/var/lib/libvirt/images/shared.img", "path": "/var/lib/libvirt/images/shared.img", "fd": 12, "lockHeld": true, "flags": 1, "owners": [ 1722, 1784 ] }, { "name": "/var/lib/libvirt/images/f18x86_64.img", "path": "/var/lib/libvirt/images/f18x86_64.img", "fd": 11, "lockHeld": true, "flags": 0, "owners": [ 1722 ] } ] }, "lockspaces": [ ], "magic": "30199" } Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2012-08-07 11:13:26 +00:00
goto cleanup;
if (virJSONValueObjectAppend(object, "daemon", child) < 0) {
Add support for re-exec() of virtlockd upon SIGUSR1 The virtlockd daemon maintains file locks on behalf of libvirtd and any VMs it is running. These file locks must be held for as long as any VM is running. If virtlockd itself ever quits, then it is expected that a node would be fenced/rebooted. Thus to allow for software upgrads on live systemd, virtlockd needs the ability to re-exec() itself. Upon receipt of SIGUSR1, virtlockd will save its current live state out to a file /var/run/virtlockd-restart-exec.json It then re-exec()'s itself with exactly the same argv as it originally had, and loads the state file, reconstructing any objects as appropriate. The state file contains information about all locks held and all network services and clients currently active. An example state document is { "server": { "min_workers": 1, "max_workers": 20, "priority_workers": 0, "max_clients": 20, "keepaliveInterval": 4294967295, "keepaliveCount": 0, "keepaliveRequired": false, "services": [ { "auth": 0, "readonly": false, "nrequests_client_max": 1, "socks": [ { "fd": 6, "errfd": -1, "pid": 0, "isClient": false } ] } ], "clients": [ { "auth": 0, "readonly": false, "nrequests_max": 1, "sock": { "fd": 9, "errfd": -1, "pid": 0, "isClient": true }, "privateData": { "restricted": true, "ownerPid": 1722, "ownerId": 6, "ownerName": "f18x86_64", "ownerUUID": "97586ba9-df27-9459-c806-f016c8bbd224" } }, { "auth": 0, "readonly": false, "nrequests_max": 1, "sock": { "fd": 10, "errfd": -1, "pid": 0, "isClient": true }, "privateData": { "restricted": true, "ownerPid": 1784, "ownerId": 7, "ownerName": "f16x86_64", "ownerUUID": "7b8e5e42-b875-61e9-b981-91ad8fa46979" } } ] }, "defaultLockspace": { "resources": [ { "name": "/var/lib/libvirt/images/f16x86_64.raw", "path": "/var/lib/libvirt/images/f16x86_64.raw", "fd": 14, "lockHeld": true, "flags": 0, "owners": [ 1784 ] }, { "name": "/var/lib/libvirt/images/shared.img", "path": "/var/lib/libvirt/images/shared.img", "fd": 12, "lockHeld": true, "flags": 1, "owners": [ 1722, 1784 ] }, { "name": "/var/lib/libvirt/images/f18x86_64.img", "path": "/var/lib/libvirt/images/f18x86_64.img", "fd": 11, "lockHeld": true, "flags": 0, "owners": [ 1722 ] } ] }, "lockspaces": [ ], "magic": "30199" } Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2012-08-07 11:13:26 +00:00
virJSONValueFree(child);
goto cleanup;
}
if (!(child = virLockSpacePreExecRestart(lockDaemon->defaultLockspace)))
goto cleanup;
if (virJSONValueObjectAppend(object, "defaultLockspace", child) < 0) {
virJSONValueFree(child);
goto cleanup;
}
lockspaces = virJSONValueNewArray();
Add support for re-exec() of virtlockd upon SIGUSR1 The virtlockd daemon maintains file locks on behalf of libvirtd and any VMs it is running. These file locks must be held for as long as any VM is running. If virtlockd itself ever quits, then it is expected that a node would be fenced/rebooted. Thus to allow for software upgrads on live systemd, virtlockd needs the ability to re-exec() itself. Upon receipt of SIGUSR1, virtlockd will save its current live state out to a file /var/run/virtlockd-restart-exec.json It then re-exec()'s itself with exactly the same argv as it originally had, and loads the state file, reconstructing any objects as appropriate. The state file contains information about all locks held and all network services and clients currently active. An example state document is { "server": { "min_workers": 1, "max_workers": 20, "priority_workers": 0, "max_clients": 20, "keepaliveInterval": 4294967295, "keepaliveCount": 0, "keepaliveRequired": false, "services": [ { "auth": 0, "readonly": false, "nrequests_client_max": 1, "socks": [ { "fd": 6, "errfd": -1, "pid": 0, "isClient": false } ] } ], "clients": [ { "auth": 0, "readonly": false, "nrequests_max": 1, "sock": { "fd": 9, "errfd": -1, "pid": 0, "isClient": true }, "privateData": { "restricted": true, "ownerPid": 1722, "ownerId": 6, "ownerName": "f18x86_64", "ownerUUID": "97586ba9-df27-9459-c806-f016c8bbd224" } }, { "auth": 0, "readonly": false, "nrequests_max": 1, "sock": { "fd": 10, "errfd": -1, "pid": 0, "isClient": true }, "privateData": { "restricted": true, "ownerPid": 1784, "ownerId": 7, "ownerName": "f16x86_64", "ownerUUID": "7b8e5e42-b875-61e9-b981-91ad8fa46979" } } ] }, "defaultLockspace": { "resources": [ { "name": "/var/lib/libvirt/images/f16x86_64.raw", "path": "/var/lib/libvirt/images/f16x86_64.raw", "fd": 14, "lockHeld": true, "flags": 0, "owners": [ 1784 ] }, { "name": "/var/lib/libvirt/images/shared.img", "path": "/var/lib/libvirt/images/shared.img", "fd": 12, "lockHeld": true, "flags": 1, "owners": [ 1722, 1784 ] }, { "name": "/var/lib/libvirt/images/f18x86_64.img", "path": "/var/lib/libvirt/images/f18x86_64.img", "fd": 11, "lockHeld": true, "flags": 0, "owners": [ 1722 ] } ] }, "lockspaces": [ ], "magic": "30199" } Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2012-08-07 11:13:26 +00:00
if (virJSONValueObjectAppend(object, "lockspaces", lockspaces) < 0) {
virJSONValueFree(lockspaces);
goto cleanup;
}
tmp = pairs = virHashGetItems(lockDaemon->lockspaces, NULL);
while (tmp && tmp->key) {
virLockSpacePtr lockspace = (virLockSpacePtr)tmp->value;
if (!(child = virLockSpacePreExecRestart(lockspace)))
goto cleanup;
if (virJSONValueArrayAppend(lockspaces, child) < 0) {
virJSONValueFree(child);
goto cleanup;
}
tmp++;
}
if (!(magic = virLockDaemonGetExecRestartMagic()))
goto cleanup;
if (virJSONValueObjectAppendString(object, "magic", magic) < 0) {
VIR_FREE(magic);
goto cleanup;
}
if (!(state = virJSONValueToString(object, true)))
goto cleanup;
VIR_DEBUG("Saving state %s", state);
if (virFileWriteStr(state_file,
Add support for re-exec() of virtlockd upon SIGUSR1 The virtlockd daemon maintains file locks on behalf of libvirtd and any VMs it is running. These file locks must be held for as long as any VM is running. If virtlockd itself ever quits, then it is expected that a node would be fenced/rebooted. Thus to allow for software upgrads on live systemd, virtlockd needs the ability to re-exec() itself. Upon receipt of SIGUSR1, virtlockd will save its current live state out to a file /var/run/virtlockd-restart-exec.json It then re-exec()'s itself with exactly the same argv as it originally had, and loads the state file, reconstructing any objects as appropriate. The state file contains information about all locks held and all network services and clients currently active. An example state document is { "server": { "min_workers": 1, "max_workers": 20, "priority_workers": 0, "max_clients": 20, "keepaliveInterval": 4294967295, "keepaliveCount": 0, "keepaliveRequired": false, "services": [ { "auth": 0, "readonly": false, "nrequests_client_max": 1, "socks": [ { "fd": 6, "errfd": -1, "pid": 0, "isClient": false } ] } ], "clients": [ { "auth": 0, "readonly": false, "nrequests_max": 1, "sock": { "fd": 9, "errfd": -1, "pid": 0, "isClient": true }, "privateData": { "restricted": true, "ownerPid": 1722, "ownerId": 6, "ownerName": "f18x86_64", "ownerUUID": "97586ba9-df27-9459-c806-f016c8bbd224" } }, { "auth": 0, "readonly": false, "nrequests_max": 1, "sock": { "fd": 10, "errfd": -1, "pid": 0, "isClient": true }, "privateData": { "restricted": true, "ownerPid": 1784, "ownerId": 7, "ownerName": "f16x86_64", "ownerUUID": "7b8e5e42-b875-61e9-b981-91ad8fa46979" } } ] }, "defaultLockspace": { "resources": [ { "name": "/var/lib/libvirt/images/f16x86_64.raw", "path": "/var/lib/libvirt/images/f16x86_64.raw", "fd": 14, "lockHeld": true, "flags": 0, "owners": [ 1784 ] }, { "name": "/var/lib/libvirt/images/shared.img", "path": "/var/lib/libvirt/images/shared.img", "fd": 12, "lockHeld": true, "flags": 1, "owners": [ 1722, 1784 ] }, { "name": "/var/lib/libvirt/images/f18x86_64.img", "path": "/var/lib/libvirt/images/f18x86_64.img", "fd": 11, "lockHeld": true, "flags": 0, "owners": [ 1722 ] } ] }, "lockspaces": [ ], "magic": "30199" } Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2012-08-07 11:13:26 +00:00
state, 0700) < 0) {
virReportSystemError(errno,
_("Unable to save state file %s"),
state_file);
Add support for re-exec() of virtlockd upon SIGUSR1 The virtlockd daemon maintains file locks on behalf of libvirtd and any VMs it is running. These file locks must be held for as long as any VM is running. If virtlockd itself ever quits, then it is expected that a node would be fenced/rebooted. Thus to allow for software upgrads on live systemd, virtlockd needs the ability to re-exec() itself. Upon receipt of SIGUSR1, virtlockd will save its current live state out to a file /var/run/virtlockd-restart-exec.json It then re-exec()'s itself with exactly the same argv as it originally had, and loads the state file, reconstructing any objects as appropriate. The state file contains information about all locks held and all network services and clients currently active. An example state document is { "server": { "min_workers": 1, "max_workers": 20, "priority_workers": 0, "max_clients": 20, "keepaliveInterval": 4294967295, "keepaliveCount": 0, "keepaliveRequired": false, "services": [ { "auth": 0, "readonly": false, "nrequests_client_max": 1, "socks": [ { "fd": 6, "errfd": -1, "pid": 0, "isClient": false } ] } ], "clients": [ { "auth": 0, "readonly": false, "nrequests_max": 1, "sock": { "fd": 9, "errfd": -1, "pid": 0, "isClient": true }, "privateData": { "restricted": true, "ownerPid": 1722, "ownerId": 6, "ownerName": "f18x86_64", "ownerUUID": "97586ba9-df27-9459-c806-f016c8bbd224" } }, { "auth": 0, "readonly": false, "nrequests_max": 1, "sock": { "fd": 10, "errfd": -1, "pid": 0, "isClient": true }, "privateData": { "restricted": true, "ownerPid": 1784, "ownerId": 7, "ownerName": "f16x86_64", "ownerUUID": "7b8e5e42-b875-61e9-b981-91ad8fa46979" } } ] }, "defaultLockspace": { "resources": [ { "name": "/var/lib/libvirt/images/f16x86_64.raw", "path": "/var/lib/libvirt/images/f16x86_64.raw", "fd": 14, "lockHeld": true, "flags": 0, "owners": [ 1784 ] }, { "name": "/var/lib/libvirt/images/shared.img", "path": "/var/lib/libvirt/images/shared.img", "fd": 12, "lockHeld": true, "flags": 1, "owners": [ 1722, 1784 ] }, { "name": "/var/lib/libvirt/images/f18x86_64.img", "path": "/var/lib/libvirt/images/f18x86_64.img", "fd": 11, "lockHeld": true, "flags": 0, "owners": [ 1722 ] } ] }, "lockspaces": [ ], "magic": "30199" } Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2012-08-07 11:13:26 +00:00
goto cleanup;
}
if (execvp(argv[0], argv) < 0) {
Add support for re-exec() of virtlockd upon SIGUSR1 The virtlockd daemon maintains file locks on behalf of libvirtd and any VMs it is running. These file locks must be held for as long as any VM is running. If virtlockd itself ever quits, then it is expected that a node would be fenced/rebooted. Thus to allow for software upgrads on live systemd, virtlockd needs the ability to re-exec() itself. Upon receipt of SIGUSR1, virtlockd will save its current live state out to a file /var/run/virtlockd-restart-exec.json It then re-exec()'s itself with exactly the same argv as it originally had, and loads the state file, reconstructing any objects as appropriate. The state file contains information about all locks held and all network services and clients currently active. An example state document is { "server": { "min_workers": 1, "max_workers": 20, "priority_workers": 0, "max_clients": 20, "keepaliveInterval": 4294967295, "keepaliveCount": 0, "keepaliveRequired": false, "services": [ { "auth": 0, "readonly": false, "nrequests_client_max": 1, "socks": [ { "fd": 6, "errfd": -1, "pid": 0, "isClient": false } ] } ], "clients": [ { "auth": 0, "readonly": false, "nrequests_max": 1, "sock": { "fd": 9, "errfd": -1, "pid": 0, "isClient": true }, "privateData": { "restricted": true, "ownerPid": 1722, "ownerId": 6, "ownerName": "f18x86_64", "ownerUUID": "97586ba9-df27-9459-c806-f016c8bbd224" } }, { "auth": 0, "readonly": false, "nrequests_max": 1, "sock": { "fd": 10, "errfd": -1, "pid": 0, "isClient": true }, "privateData": { "restricted": true, "ownerPid": 1784, "ownerId": 7, "ownerName": "f16x86_64", "ownerUUID": "7b8e5e42-b875-61e9-b981-91ad8fa46979" } } ] }, "defaultLockspace": { "resources": [ { "name": "/var/lib/libvirt/images/f16x86_64.raw", "path": "/var/lib/libvirt/images/f16x86_64.raw", "fd": 14, "lockHeld": true, "flags": 0, "owners": [ 1784 ] }, { "name": "/var/lib/libvirt/images/shared.img", "path": "/var/lib/libvirt/images/shared.img", "fd": 12, "lockHeld": true, "flags": 1, "owners": [ 1722, 1784 ] }, { "name": "/var/lib/libvirt/images/f18x86_64.img", "path": "/var/lib/libvirt/images/f18x86_64.img", "fd": 11, "lockHeld": true, "flags": 0, "owners": [ 1722 ] } ] }, "lockspaces": [ ], "magic": "30199" } Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2012-08-07 11:13:26 +00:00
virReportSystemError(errno, "%s",
_("Unable to restart self"));
goto cleanup;
}
abort(); /* This should be impossible to reach */
cleanup:
Add support for re-exec() of virtlockd upon SIGUSR1 The virtlockd daemon maintains file locks on behalf of libvirtd and any VMs it is running. These file locks must be held for as long as any VM is running. If virtlockd itself ever quits, then it is expected that a node would be fenced/rebooted. Thus to allow for software upgrads on live systemd, virtlockd needs the ability to re-exec() itself. Upon receipt of SIGUSR1, virtlockd will save its current live state out to a file /var/run/virtlockd-restart-exec.json It then re-exec()'s itself with exactly the same argv as it originally had, and loads the state file, reconstructing any objects as appropriate. The state file contains information about all locks held and all network services and clients currently active. An example state document is { "server": { "min_workers": 1, "max_workers": 20, "priority_workers": 0, "max_clients": 20, "keepaliveInterval": 4294967295, "keepaliveCount": 0, "keepaliveRequired": false, "services": [ { "auth": 0, "readonly": false, "nrequests_client_max": 1, "socks": [ { "fd": 6, "errfd": -1, "pid": 0, "isClient": false } ] } ], "clients": [ { "auth": 0, "readonly": false, "nrequests_max": 1, "sock": { "fd": 9, "errfd": -1, "pid": 0, "isClient": true }, "privateData": { "restricted": true, "ownerPid": 1722, "ownerId": 6, "ownerName": "f18x86_64", "ownerUUID": "97586ba9-df27-9459-c806-f016c8bbd224" } }, { "auth": 0, "readonly": false, "nrequests_max": 1, "sock": { "fd": 10, "errfd": -1, "pid": 0, "isClient": true }, "privateData": { "restricted": true, "ownerPid": 1784, "ownerId": 7, "ownerName": "f16x86_64", "ownerUUID": "7b8e5e42-b875-61e9-b981-91ad8fa46979" } } ] }, "defaultLockspace": { "resources": [ { "name": "/var/lib/libvirt/images/f16x86_64.raw", "path": "/var/lib/libvirt/images/f16x86_64.raw", "fd": 14, "lockHeld": true, "flags": 0, "owners": [ 1784 ] }, { "name": "/var/lib/libvirt/images/shared.img", "path": "/var/lib/libvirt/images/shared.img", "fd": 12, "lockHeld": true, "flags": 1, "owners": [ 1722, 1784 ] }, { "name": "/var/lib/libvirt/images/f18x86_64.img", "path": "/var/lib/libvirt/images/f18x86_64.img", "fd": 11, "lockHeld": true, "flags": 0, "owners": [ 1722 ] } ] }, "lockspaces": [ ], "magic": "30199" } Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2012-08-07 11:13:26 +00:00
VIR_FREE(pairs);
VIR_FREE(state);
virJSONValueFree(object);
return -1;
Add support for re-exec() of virtlockd upon SIGUSR1 The virtlockd daemon maintains file locks on behalf of libvirtd and any VMs it is running. These file locks must be held for as long as any VM is running. If virtlockd itself ever quits, then it is expected that a node would be fenced/rebooted. Thus to allow for software upgrads on live systemd, virtlockd needs the ability to re-exec() itself. Upon receipt of SIGUSR1, virtlockd will save its current live state out to a file /var/run/virtlockd-restart-exec.json It then re-exec()'s itself with exactly the same argv as it originally had, and loads the state file, reconstructing any objects as appropriate. The state file contains information about all locks held and all network services and clients currently active. An example state document is { "server": { "min_workers": 1, "max_workers": 20, "priority_workers": 0, "max_clients": 20, "keepaliveInterval": 4294967295, "keepaliveCount": 0, "keepaliveRequired": false, "services": [ { "auth": 0, "readonly": false, "nrequests_client_max": 1, "socks": [ { "fd": 6, "errfd": -1, "pid": 0, "isClient": false } ] } ], "clients": [ { "auth": 0, "readonly": false, "nrequests_max": 1, "sock": { "fd": 9, "errfd": -1, "pid": 0, "isClient": true }, "privateData": { "restricted": true, "ownerPid": 1722, "ownerId": 6, "ownerName": "f18x86_64", "ownerUUID": "97586ba9-df27-9459-c806-f016c8bbd224" } }, { "auth": 0, "readonly": false, "nrequests_max": 1, "sock": { "fd": 10, "errfd": -1, "pid": 0, "isClient": true }, "privateData": { "restricted": true, "ownerPid": 1784, "ownerId": 7, "ownerName": "f16x86_64", "ownerUUID": "7b8e5e42-b875-61e9-b981-91ad8fa46979" } } ] }, "defaultLockspace": { "resources": [ { "name": "/var/lib/libvirt/images/f16x86_64.raw", "path": "/var/lib/libvirt/images/f16x86_64.raw", "fd": 14, "lockHeld": true, "flags": 0, "owners": [ 1784 ] }, { "name": "/var/lib/libvirt/images/shared.img", "path": "/var/lib/libvirt/images/shared.img", "fd": 12, "lockHeld": true, "flags": 1, "owners": [ 1722, 1784 ] }, { "name": "/var/lib/libvirt/images/f18x86_64.img", "path": "/var/lib/libvirt/images/f18x86_64.img", "fd": 11, "lockHeld": true, "flags": 0, "owners": [ 1722 ] } ] }, "lockspaces": [ ], "magic": "30199" } Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2012-08-07 11:13:26 +00:00
}
static void
virLockDaemonUsage(const char *argv0, bool privileged)
{
fprintf(stderr,
_("\n"
"Usage:\n"
" %s [options]\n"
"\n"
"Options:\n"
" -h | --help Display program help:\n"
" -v | --verbose Verbose messages.\n"
" -d | --daemon Run as a daemon & write PID file.\n"
" -t | --timeout <secs> Exit after timeout period.\n"
" -f | --config <file> Configuration file.\n"
" -V | --version Display version information.\n"
" -p | --pid-file <file> Change name of PID file.\n"
"\n"
"libvirt lock management daemon:\n"), argv0);
if (privileged) {
fprintf(stderr,
_("\n"
" Default paths:\n"
"\n"
" Configuration file (unless overridden by -f):\n"
" %s/libvirt/virtlockd.conf\n"
"\n"
" Sockets:\n"
" %s/libvirt/virtlockd-sock\n"
"\n"
" PID file (unless overridden by -p):\n"
" %s/virtlockd.pid\n"
"\n"),
SYSCONFDIR,
RUNSTATEDIR,
RUNSTATEDIR);
} else {
fprintf(stderr, "%s",
_("\n"
" Default paths:\n"
"\n"
" Configuration file (unless overridden by -f):\n"
" $XDG_CONFIG_HOME/libvirt/virtlockd.conf\n"
"\n"
" Sockets:\n"
" $XDG_RUNTIME_DIR/libvirt/virtlockd-sock\n"
"\n"
" PID file:\n"
" $XDG_RUNTIME_DIR/libvirt/virtlockd.pid\n"
"\n"));
}
}
int main(int argc, char **argv) {
virNetServerPtr lockSrv = NULL;
virNetServerPtr adminSrv = NULL;
virNetServerProgramPtr lockProgram = NULL;
virNetServerProgramPtr adminProgram = NULL;
char *remote_config_file = NULL;
int statuswrite = -1;
int ret = 1;
int verbose = 0;
int godaemon = 0;
char *run_dir = NULL;
char *pid_file = NULL;
int pid_file_fd = -1;
char *sock_file = NULL;
char *admin_sock_file = NULL;
int timeout = 0; /* -t: Shutdown timeout */
char *state_file = NULL;
bool implicit_conf = false;
mode_t old_umask;
bool privileged = false;
virLockDaemonConfigPtr config = NULL;
int rv;
struct option opts[] = {
{ "verbose", no_argument, &verbose, 'v'},
{ "daemon", no_argument, &godaemon, 'd'},
{ "config", required_argument, NULL, 'f'},
{ "timeout", required_argument, NULL, 't'},
{ "pid-file", required_argument, NULL, 'p'},
{ "version", no_argument, NULL, 'V' },
{ "help", no_argument, NULL, 'h' },
{0, 0, 0, 0}
};
privileged = geteuid() == 0;
if (virGettextInitialize() < 0 ||
virErrorInitialize() < 0) {
fprintf(stderr, _("%s: initialization failed\n"), argv[0]);
exit(EXIT_FAILURE);
}
while (1) {
int optidx = 0;
int c;
char *tmp;
c = getopt_long(argc, argv, "df:p:t:vVh", opts, &optidx);
if (c == -1)
break;
switch (c) {
case 0:
/* Got one of the flags */
break;
case 'v':
verbose = 1;
break;
case 'd':
godaemon = 1;
break;
case 't':
if (virStrToLong_i(optarg, &tmp, 10, &timeout) != 0
|| timeout < 0
/* Ensure that we can multiply by 1000 without overflowing. */
|| timeout > INT_MAX / 1000) {
VIR_ERROR(_("Invalid value for timeout"));
exit(EXIT_FAILURE);
}
break;
case 'p':
VIR_FREE(pid_file);
pid_file = g_strdup(optarg);
break;
case 'f':
VIR_FREE(remote_config_file);
remote_config_file = g_strdup(optarg);
break;
case 'V':
virLockDaemonVersion(argv[0]);
exit(EXIT_SUCCESS);
case 'h':
virLockDaemonUsage(argv[0], privileged);
exit(EXIT_SUCCESS);
case '?':
default:
virLockDaemonUsage(argv[0], privileged);
exit(EXIT_FAILURE);
}
}
virFileActivateDirOverrideForProg(argv[0]);
if (!(config = virLockDaemonConfigNew(privileged))) {
VIR_ERROR(_("Can't create initial configuration"));
exit(EXIT_FAILURE);
}
/* No explicit config, so try and find a default one */
if (remote_config_file == NULL) {
implicit_conf = true;
if (virLockDaemonConfigFilePath(privileged,
&remote_config_file) < 0) {
VIR_ERROR(_("Can't determine config path"));
exit(EXIT_FAILURE);
}
}
/* Read the config file if it exists */
if (remote_config_file &&
virLockDaemonConfigLoadFile(config, remote_config_file, implicit_conf) < 0) {
VIR_ERROR(_("Can't load config file: %s: %s"),
virGetLastErrorMessage(), remote_config_file);
exit(EXIT_FAILURE);
}
lock_daemon: Fix some memleaks 28 bytes in 1 blocks are definitely lost in loss record 26 of 66 at 0x4C2CF0F: malloc (vg_replace_malloc.c:299) by 0x7A02719: strdup (strdup.c:42) by 0x197DC1: virStrdup (virstring.c:961) by 0x12B478: virLockDaemonConfigFilePath (lock_daemon_config.c:44) by 0x12A759: main (lock_daemon.c:1270) 62 (32 direct, 30 indirect) bytes in 1 blocks are definitely lost in loss record 41 of 66 at 0x4C2EF26: calloc (vg_replace_malloc.c:711) by 0x151B61: virAlloc (viralloc.c:144) by 0x12B56C: virLockDaemonConfigNew (lock_daemon_config.c:71) by 0x12A491: main (lock_daemon.c:1262) 13 bytes in 1 blocks are definitely lost in loss record 21 of 70 at 0x4C2CF0F: malloc (vg_replace_malloc.c:299) by 0x7A02719: strdup (strdup.c:42) by 0x197E3F: virStrdup (virstring.c:961) by 0x12C86B: virLockSpaceProtocolDispatchRegister (lock_daemon_dispatch.c:291) by 0x12BB73: virLockSpaceProtocolDispatchRegisterHelper (lock_daemon_dispatch_stubs.h:152) by 0x1336AA: virNetServerProgramDispatchCall (virnetserverprogram.c:437) by 0x13320D: virNetServerProgramDispatch (virnetserverprogram.c:304) by 0x139E3E: virNetServerProcessMsg (virnetserver.c:144) by 0x13A1A2: virNetServerDispatchNewMessage (virnetserver.c:230) by 0x1350F5: virNetServerClientDispatchMessage (virnetserverclient.c:343) by 0x137680: virNetServerClientDispatchEvent (virnetserverclient.c:1498) by 0x147704: virNetSocketEventHandle (virnetsocket.c:2140) Signed-off-by: Michal Privoznik <mprivozn@redhat.com> Reviewed-by: John Ferlan <jferlan@redhat.com>
2018-08-26 06:48:47 +00:00
VIR_FREE(remote_config_file);
virDaemonSetupLogging("virtlockd",
config->log_level,
config->log_filters,
config->log_outputs,
privileged,
verbose,
godaemon);
if (!pid_file &&
virPidFileConstructPath(privileged,
RUNSTATEDIR,
"virtlockd",
&pid_file) < 0) {
VIR_ERROR(_("Can't determine pid file path."));
exit(EXIT_FAILURE);
}
VIR_DEBUG("Decided on pid file path '%s'", NULLSTR(pid_file));
if (virDaemonUnixSocketPaths("virtlockd",
privileged,
NULL,
&sock_file,
NULL,
&admin_sock_file) < 0) {
VIR_ERROR(_("Can't determine socket paths"));
exit(EXIT_FAILURE);
}
VIR_DEBUG("Decided on socket paths '%s' and '%s'",
sock_file, admin_sock_file);
if (virLockDaemonExecRestartStatePath(privileged,
&state_file) < 0) {
VIR_ERROR(_("Can't determine restart state file path"));
exit(EXIT_FAILURE);
}
VIR_DEBUG("Decided on restart state file path '%s'",
state_file);
/* Ensure the rundir exists (on tmpfs on some systems) */
if (privileged) {
run_dir = g_strdup(RUNSTATEDIR "/libvirt");
} else {
run_dir = virGetUserRuntimeDirectory();
}
if (privileged)
old_umask = umask(022);
else
old_umask = umask(077);
VIR_DEBUG("Ensuring run dir '%s' exists", run_dir);
if (virFileMakePath(run_dir) < 0) {
VIR_ERROR(_("unable to create rundir %s: %s"), run_dir,
g_strerror(errno));
ret = VIR_DAEMON_ERR_RUNDIR;
umask(old_umask);
goto cleanup;
}
umask(old_umask);
if ((rv = virLockDaemonPostExecRestart(state_file,
pid_file,
&pid_file_fd,
privileged)) < 0) {
ret = VIR_DAEMON_ERR_INIT;
goto cleanup;
}
virtlockd: Don't SIGSEGV on SIGUSR1 So we have this mechanism that on SIGUSR1 the virtlockd dumps its internal state into a JSON file, reexec itself and the reloads the internal state back. However, there's a bug in our implementation: (gdb) signal SIGUSR1 Continuing with signal SIGUSR1. [Thread 0x7fd094f7b700 (LWP 10602) exited] process 10600 is executing new program: /home/zippy/work/libvirt/libvirt.git/src/virtlockd warning: Could not load shared library symbols for linux-vdso.so.1. Do you need "set solib-search-path" or "set sysroot"? [Thread debugging using libthread_db enabled] Using host libthread_db library "/lib64/libthread_db.so.1". [New Thread 0x7fb28bc3c700 (LWP 14501)] Program received signal SIGSEGV, Segmentation fault. 0x00007fb29133d530 in virExpandN (ptrptr=0x70, size=8, countptr=0x68, add=1, report=true, domcode=7, filename=0x7fb29138aeab "rpc/virnetserver.c", funcname=0x7fb29138b680 <__FUNCTION__.15821> "virNetServerAddProgram", linenr=661) at util/viralloc.c:288 288 if (*countptr + add < *countptr) { (gdb) bt #0 0x00007fb29133d530 in virExpandN (ptrptr=0x70, size=8, countptr=0x68, add=1, report=true, domcode=7, filename=0x7fb29138aeab "rpc/virnetserver.c", funcname=0x7fb29138b680 <__FUNCTION__.15821> "virNetServerAddProgram", linenr=661) at util/viralloc.c:288 #1 0x00007fb29132a267 in virNetServerAddProgram (srv=0x0, prog=0x7fb2915d08b0) at rpc/virnetserver.c:661 #2 0x00007fb29131f27f in main (argc=1, argv=0x7fff8f771298) at locking/lock_daemon.c:1445 Notice the NULL @srv passed to frame 2? Usually, the @srv variable is initialized on fresh start. However, in case of daemon reload, the code path that is responsible for initializing the value was not triggered and therefore we crashed immediately. Fix this by always setting the variable. Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
2015-10-12 07:58:05 +00:00
/* rv == 1 means we successfully restored from the saved internal state
* (but still need to add @lockProgram into @srv). rv == 0 means that no
* saved state is present, therefore initialize from scratch here. */
Add support for re-exec() of virtlockd upon SIGUSR1 The virtlockd daemon maintains file locks on behalf of libvirtd and any VMs it is running. These file locks must be held for as long as any VM is running. If virtlockd itself ever quits, then it is expected that a node would be fenced/rebooted. Thus to allow for software upgrads on live systemd, virtlockd needs the ability to re-exec() itself. Upon receipt of SIGUSR1, virtlockd will save its current live state out to a file /var/run/virtlockd-restart-exec.json It then re-exec()'s itself with exactly the same argv as it originally had, and loads the state file, reconstructing any objects as appropriate. The state file contains information about all locks held and all network services and clients currently active. An example state document is { "server": { "min_workers": 1, "max_workers": 20, "priority_workers": 0, "max_clients": 20, "keepaliveInterval": 4294967295, "keepaliveCount": 0, "keepaliveRequired": false, "services": [ { "auth": 0, "readonly": false, "nrequests_client_max": 1, "socks": [ { "fd": 6, "errfd": -1, "pid": 0, "isClient": false } ] } ], "clients": [ { "auth": 0, "readonly": false, "nrequests_max": 1, "sock": { "fd": 9, "errfd": -1, "pid": 0, "isClient": true }, "privateData": { "restricted": true, "ownerPid": 1722, "ownerId": 6, "ownerName": "f18x86_64", "ownerUUID": "97586ba9-df27-9459-c806-f016c8bbd224" } }, { "auth": 0, "readonly": false, "nrequests_max": 1, "sock": { "fd": 10, "errfd": -1, "pid": 0, "isClient": true }, "privateData": { "restricted": true, "ownerPid": 1784, "ownerId": 7, "ownerName": "f16x86_64", "ownerUUID": "7b8e5e42-b875-61e9-b981-91ad8fa46979" } } ] }, "defaultLockspace": { "resources": [ { "name": "/var/lib/libvirt/images/f16x86_64.raw", "path": "/var/lib/libvirt/images/f16x86_64.raw", "fd": 14, "lockHeld": true, "flags": 0, "owners": [ 1784 ] }, { "name": "/var/lib/libvirt/images/shared.img", "path": "/var/lib/libvirt/images/shared.img", "fd": 12, "lockHeld": true, "flags": 1, "owners": [ 1722, 1784 ] }, { "name": "/var/lib/libvirt/images/f18x86_64.img", "path": "/var/lib/libvirt/images/f18x86_64.img", "fd": 11, "lockHeld": true, "flags": 0, "owners": [ 1722 ] } ] }, "lockspaces": [ ], "magic": "30199" } Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2012-08-07 11:13:26 +00:00
if (rv == 0) {
g_autoptr(virSystemdActivation) act = NULL;
virSystemdActivationMap actmap[] = {
{ .name = "virtlockd.socket", .family = AF_UNIX, .path = sock_file },
{ .name = "virtlockd-admin.socket", .family = AF_UNIX, .path = admin_sock_file },
};
if (godaemon) {
if (chdir("/") < 0) {
VIR_ERROR(_("cannot change to root directory: %s"),
g_strerror(errno));
goto cleanup;
}
if ((statuswrite = virDaemonForkIntoBackground(argv[0])) < 0) {
VIR_ERROR(_("Failed to fork as daemon: %s"),
g_strerror(errno));
goto cleanup;
}
}
/* If we have a pidfile set, claim it now, exiting if already taken */
if ((pid_file_fd = virPidFileAcquirePath(pid_file, false, getpid())) < 0) {
ret = VIR_DAEMON_ERR_PIDFILE;
goto cleanup;
}
if (!(lockDaemon = virLockDaemonNew(config, privileged))) {
ret = VIR_DAEMON_ERR_INIT;
Add support for re-exec() of virtlockd upon SIGUSR1 The virtlockd daemon maintains file locks on behalf of libvirtd and any VMs it is running. These file locks must be held for as long as any VM is running. If virtlockd itself ever quits, then it is expected that a node would be fenced/rebooted. Thus to allow for software upgrads on live systemd, virtlockd needs the ability to re-exec() itself. Upon receipt of SIGUSR1, virtlockd will save its current live state out to a file /var/run/virtlockd-restart-exec.json It then re-exec()'s itself with exactly the same argv as it originally had, and loads the state file, reconstructing any objects as appropriate. The state file contains information about all locks held and all network services and clients currently active. An example state document is { "server": { "min_workers": 1, "max_workers": 20, "priority_workers": 0, "max_clients": 20, "keepaliveInterval": 4294967295, "keepaliveCount": 0, "keepaliveRequired": false, "services": [ { "auth": 0, "readonly": false, "nrequests_client_max": 1, "socks": [ { "fd": 6, "errfd": -1, "pid": 0, "isClient": false } ] } ], "clients": [ { "auth": 0, "readonly": false, "nrequests_max": 1, "sock": { "fd": 9, "errfd": -1, "pid": 0, "isClient": true }, "privateData": { "restricted": true, "ownerPid": 1722, "ownerId": 6, "ownerName": "f18x86_64", "ownerUUID": "97586ba9-df27-9459-c806-f016c8bbd224" } }, { "auth": 0, "readonly": false, "nrequests_max": 1, "sock": { "fd": 10, "errfd": -1, "pid": 0, "isClient": true }, "privateData": { "restricted": true, "ownerPid": 1784, "ownerId": 7, "ownerName": "f16x86_64", "ownerUUID": "7b8e5e42-b875-61e9-b981-91ad8fa46979" } } ] }, "defaultLockspace": { "resources": [ { "name": "/var/lib/libvirt/images/f16x86_64.raw", "path": "/var/lib/libvirt/images/f16x86_64.raw", "fd": 14, "lockHeld": true, "flags": 0, "owners": [ 1784 ] }, { "name": "/var/lib/libvirt/images/shared.img", "path": "/var/lib/libvirt/images/shared.img", "fd": 12, "lockHeld": true, "flags": 1, "owners": [ 1722, 1784 ] }, { "name": "/var/lib/libvirt/images/f18x86_64.img", "path": "/var/lib/libvirt/images/f18x86_64.img", "fd": 11, "lockHeld": true, "flags": 0, "owners": [ 1722 ] } ] }, "lockspaces": [ ], "magic": "30199" } Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2012-08-07 11:13:26 +00:00
goto cleanup;
}
if (virSystemdGetActivation(actmap,
G_N_ELEMENTS(actmap),
&act) < 0) {
ret = VIR_DAEMON_ERR_NETWORK;
goto cleanup;
}
lockSrv = virNetDaemonGetServer(lockDaemon->dmn, "virtlockd");
adminSrv = virNetDaemonGetServer(lockDaemon->dmn, "admin");
if (virNetServerAddServiceUNIX(lockSrv,
act, "virtlockd.socket",
sock_file, 0700, 0, 0,
NULL,
false, 0, 1) < 0) {
ret = VIR_DAEMON_ERR_NETWORK;
goto cleanup;
}
if (virNetServerAddServiceUNIX(adminSrv,
act, "virtlockd-admin.socket",
admin_sock_file, 0700, 0, 0,
NULL,
false, 0, 1) < 0) {
ret = VIR_DAEMON_ERR_NETWORK;
Add support for re-exec() of virtlockd upon SIGUSR1 The virtlockd daemon maintains file locks on behalf of libvirtd and any VMs it is running. These file locks must be held for as long as any VM is running. If virtlockd itself ever quits, then it is expected that a node would be fenced/rebooted. Thus to allow for software upgrads on live systemd, virtlockd needs the ability to re-exec() itself. Upon receipt of SIGUSR1, virtlockd will save its current live state out to a file /var/run/virtlockd-restart-exec.json It then re-exec()'s itself with exactly the same argv as it originally had, and loads the state file, reconstructing any objects as appropriate. The state file contains information about all locks held and all network services and clients currently active. An example state document is { "server": { "min_workers": 1, "max_workers": 20, "priority_workers": 0, "max_clients": 20, "keepaliveInterval": 4294967295, "keepaliveCount": 0, "keepaliveRequired": false, "services": [ { "auth": 0, "readonly": false, "nrequests_client_max": 1, "socks": [ { "fd": 6, "errfd": -1, "pid": 0, "isClient": false } ] } ], "clients": [ { "auth": 0, "readonly": false, "nrequests_max": 1, "sock": { "fd": 9, "errfd": -1, "pid": 0, "isClient": true }, "privateData": { "restricted": true, "ownerPid": 1722, "ownerId": 6, "ownerName": "f18x86_64", "ownerUUID": "97586ba9-df27-9459-c806-f016c8bbd224" } }, { "auth": 0, "readonly": false, "nrequests_max": 1, "sock": { "fd": 10, "errfd": -1, "pid": 0, "isClient": true }, "privateData": { "restricted": true, "ownerPid": 1784, "ownerId": 7, "ownerName": "f16x86_64", "ownerUUID": "7b8e5e42-b875-61e9-b981-91ad8fa46979" } } ] }, "defaultLockspace": { "resources": [ { "name": "/var/lib/libvirt/images/f16x86_64.raw", "path": "/var/lib/libvirt/images/f16x86_64.raw", "fd": 14, "lockHeld": true, "flags": 0, "owners": [ 1784 ] }, { "name": "/var/lib/libvirt/images/shared.img", "path": "/var/lib/libvirt/images/shared.img", "fd": 12, "lockHeld": true, "flags": 1, "owners": [ 1722, 1784 ] }, { "name": "/var/lib/libvirt/images/f18x86_64.img", "path": "/var/lib/libvirt/images/f18x86_64.img", "fd": 11, "lockHeld": true, "flags": 0, "owners": [ 1722 ] } ] }, "lockspaces": [ ], "magic": "30199" } Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2012-08-07 11:13:26 +00:00
goto cleanup;
}
if (act &&
virSystemdActivationComplete(act) < 0) {
ret = VIR_DAEMON_ERR_NETWORK;
goto cleanup;
Add support for re-exec() of virtlockd upon SIGUSR1 The virtlockd daemon maintains file locks on behalf of libvirtd and any VMs it is running. These file locks must be held for as long as any VM is running. If virtlockd itself ever quits, then it is expected that a node would be fenced/rebooted. Thus to allow for software upgrads on live systemd, virtlockd needs the ability to re-exec() itself. Upon receipt of SIGUSR1, virtlockd will save its current live state out to a file /var/run/virtlockd-restart-exec.json It then re-exec()'s itself with exactly the same argv as it originally had, and loads the state file, reconstructing any objects as appropriate. The state file contains information about all locks held and all network services and clients currently active. An example state document is { "server": { "min_workers": 1, "max_workers": 20, "priority_workers": 0, "max_clients": 20, "keepaliveInterval": 4294967295, "keepaliveCount": 0, "keepaliveRequired": false, "services": [ { "auth": 0, "readonly": false, "nrequests_client_max": 1, "socks": [ { "fd": 6, "errfd": -1, "pid": 0, "isClient": false } ] } ], "clients": [ { "auth": 0, "readonly": false, "nrequests_max": 1, "sock": { "fd": 9, "errfd": -1, "pid": 0, "isClient": true }, "privateData": { "restricted": true, "ownerPid": 1722, "ownerId": 6, "ownerName": "f18x86_64", "ownerUUID": "97586ba9-df27-9459-c806-f016c8bbd224" } }, { "auth": 0, "readonly": false, "nrequests_max": 1, "sock": { "fd": 10, "errfd": -1, "pid": 0, "isClient": true }, "privateData": { "restricted": true, "ownerPid": 1784, "ownerId": 7, "ownerName": "f16x86_64", "ownerUUID": "7b8e5e42-b875-61e9-b981-91ad8fa46979" } } ] }, "defaultLockspace": { "resources": [ { "name": "/var/lib/libvirt/images/f16x86_64.raw", "path": "/var/lib/libvirt/images/f16x86_64.raw", "fd": 14, "lockHeld": true, "flags": 0, "owners": [ 1784 ] }, { "name": "/var/lib/libvirt/images/shared.img", "path": "/var/lib/libvirt/images/shared.img", "fd": 12, "lockHeld": true, "flags": 1, "owners": [ 1722, 1784 ] }, { "name": "/var/lib/libvirt/images/f18x86_64.img", "path": "/var/lib/libvirt/images/f18x86_64.img", "fd": 11, "lockHeld": true, "flags": 0, "owners": [ 1722 ] } ] }, "lockspaces": [ ], "magic": "30199" } Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2012-08-07 11:13:26 +00:00
}
} else {
lockSrv = virNetDaemonGetServer(lockDaemon->dmn, "virtlockd");
/* If exec-restarting from old virtlockd, we won't have an
* admin server present */
if (virNetDaemonHasServer(lockDaemon->dmn, "admin"))
adminSrv = virNetDaemonGetServer(lockDaemon->dmn, "admin");
}
if (timeout > 0) {
VIR_DEBUG("Registering shutdown timeout %d", timeout);
virNetDaemonAutoShutdown(lockDaemon->dmn,
timeout);
}
if ((virLockDaemonSetupSignals(lockDaemon->dmn)) < 0) {
ret = VIR_DAEMON_ERR_SIGNAL;
goto cleanup;
}
if (!(lockProgram = virNetServerProgramNew(VIR_LOCK_SPACE_PROTOCOL_PROGRAM,
VIR_LOCK_SPACE_PROTOCOL_PROGRAM_VERSION,
virLockSpaceProtocolProcs,
virLockSpaceProtocolNProcs))) {
ret = VIR_DAEMON_ERR_INIT;
goto cleanup;
}
if (virNetServerAddProgram(lockSrv, lockProgram) < 0) {
ret = VIR_DAEMON_ERR_INIT;
goto cleanup;
}
if (adminSrv != NULL) {
if (!(adminProgram = virNetServerProgramNew(ADMIN_PROGRAM,
ADMIN_PROTOCOL_VERSION,
adminProcs,
adminNProcs))) {
ret = VIR_DAEMON_ERR_INIT;
goto cleanup;
}
if (virNetServerAddProgram(adminSrv, adminProgram) < 0) {
ret = VIR_DAEMON_ERR_INIT;
goto cleanup;
}
}
/* Disable error func, now logging is setup */
virSetErrorFunc(NULL, virLockDaemonErrorHandler);
/* Tell parent of daemon that basic initialization is complete
* In particular we're ready to accept net connections & have
* written the pidfile
*/
if (statuswrite != -1) {
char status = 0;
while (write(statuswrite, &status, 1) == -1 &&
errno == EINTR)
;
VIR_FORCE_CLOSE(statuswrite);
}
/* Start accepting new clients from network */
virNetDaemonUpdateServices(lockDaemon->dmn, true);
virNetDaemonRun(lockDaemon->dmn);
Add support for re-exec() of virtlockd upon SIGUSR1 The virtlockd daemon maintains file locks on behalf of libvirtd and any VMs it is running. These file locks must be held for as long as any VM is running. If virtlockd itself ever quits, then it is expected that a node would be fenced/rebooted. Thus to allow for software upgrads on live systemd, virtlockd needs the ability to re-exec() itself. Upon receipt of SIGUSR1, virtlockd will save its current live state out to a file /var/run/virtlockd-restart-exec.json It then re-exec()'s itself with exactly the same argv as it originally had, and loads the state file, reconstructing any objects as appropriate. The state file contains information about all locks held and all network services and clients currently active. An example state document is { "server": { "min_workers": 1, "max_workers": 20, "priority_workers": 0, "max_clients": 20, "keepaliveInterval": 4294967295, "keepaliveCount": 0, "keepaliveRequired": false, "services": [ { "auth": 0, "readonly": false, "nrequests_client_max": 1, "socks": [ { "fd": 6, "errfd": -1, "pid": 0, "isClient": false } ] } ], "clients": [ { "auth": 0, "readonly": false, "nrequests_max": 1, "sock": { "fd": 9, "errfd": -1, "pid": 0, "isClient": true }, "privateData": { "restricted": true, "ownerPid": 1722, "ownerId": 6, "ownerName": "f18x86_64", "ownerUUID": "97586ba9-df27-9459-c806-f016c8bbd224" } }, { "auth": 0, "readonly": false, "nrequests_max": 1, "sock": { "fd": 10, "errfd": -1, "pid": 0, "isClient": true }, "privateData": { "restricted": true, "ownerPid": 1784, "ownerId": 7, "ownerName": "f16x86_64", "ownerUUID": "7b8e5e42-b875-61e9-b981-91ad8fa46979" } } ] }, "defaultLockspace": { "resources": [ { "name": "/var/lib/libvirt/images/f16x86_64.raw", "path": "/var/lib/libvirt/images/f16x86_64.raw", "fd": 14, "lockHeld": true, "flags": 0, "owners": [ 1784 ] }, { "name": "/var/lib/libvirt/images/shared.img", "path": "/var/lib/libvirt/images/shared.img", "fd": 12, "lockHeld": true, "flags": 1, "owners": [ 1722, 1784 ] }, { "name": "/var/lib/libvirt/images/f18x86_64.img", "path": "/var/lib/libvirt/images/f18x86_64.img", "fd": 11, "lockHeld": true, "flags": 0, "owners": [ 1722 ] } ] }, "lockspaces": [ ], "magic": "30199" } Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2012-08-07 11:13:26 +00:00
if (execRestart &&
virLockDaemonPreExecRestart(state_file,
lockDaemon->dmn,
argv) < 0)
ret = VIR_DAEMON_ERR_REEXEC;
Add support for re-exec() of virtlockd upon SIGUSR1 The virtlockd daemon maintains file locks on behalf of libvirtd and any VMs it is running. These file locks must be held for as long as any VM is running. If virtlockd itself ever quits, then it is expected that a node would be fenced/rebooted. Thus to allow for software upgrads on live systemd, virtlockd needs the ability to re-exec() itself. Upon receipt of SIGUSR1, virtlockd will save its current live state out to a file /var/run/virtlockd-restart-exec.json It then re-exec()'s itself with exactly the same argv as it originally had, and loads the state file, reconstructing any objects as appropriate. The state file contains information about all locks held and all network services and clients currently active. An example state document is { "server": { "min_workers": 1, "max_workers": 20, "priority_workers": 0, "max_clients": 20, "keepaliveInterval": 4294967295, "keepaliveCount": 0, "keepaliveRequired": false, "services": [ { "auth": 0, "readonly": false, "nrequests_client_max": 1, "socks": [ { "fd": 6, "errfd": -1, "pid": 0, "isClient": false } ] } ], "clients": [ { "auth": 0, "readonly": false, "nrequests_max": 1, "sock": { "fd": 9, "errfd": -1, "pid": 0, "isClient": true }, "privateData": { "restricted": true, "ownerPid": 1722, "ownerId": 6, "ownerName": "f18x86_64", "ownerUUID": "97586ba9-df27-9459-c806-f016c8bbd224" } }, { "auth": 0, "readonly": false, "nrequests_max": 1, "sock": { "fd": 10, "errfd": -1, "pid": 0, "isClient": true }, "privateData": { "restricted": true, "ownerPid": 1784, "ownerId": 7, "ownerName": "f16x86_64", "ownerUUID": "7b8e5e42-b875-61e9-b981-91ad8fa46979" } } ] }, "defaultLockspace": { "resources": [ { "name": "/var/lib/libvirt/images/f16x86_64.raw", "path": "/var/lib/libvirt/images/f16x86_64.raw", "fd": 14, "lockHeld": true, "flags": 0, "owners": [ 1784 ] }, { "name": "/var/lib/libvirt/images/shared.img", "path": "/var/lib/libvirt/images/shared.img", "fd": 12, "lockHeld": true, "flags": 1, "owners": [ 1722, 1784 ] }, { "name": "/var/lib/libvirt/images/f18x86_64.img", "path": "/var/lib/libvirt/images/f18x86_64.img", "fd": 11, "lockHeld": true, "flags": 0, "owners": [ 1722 ] } ] }, "lockspaces": [ ], "magic": "30199" } Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2012-08-07 11:13:26 +00:00
else
ret = 0;
cleanup:
virObjectUnref(lockProgram);
virObjectUnref(adminProgram);
virObjectUnref(lockSrv);
virObjectUnref(adminSrv);
virLockDaemonFree(lockDaemon);
if (statuswrite != -1) {
if (ret != 0) {
/* Tell parent of daemon what failed */
char status = ret;
while (write(statuswrite, &status, 1) == -1 &&
errno == EINTR)
;
}
VIR_FORCE_CLOSE(statuswrite);
}
if (pid_file_fd != -1)
virPidFileReleasePath(pid_file, pid_file_fd);
VIR_FREE(pid_file);
VIR_FREE(sock_file);
VIR_FREE(admin_sock_file);
VIR_FREE(state_file);
VIR_FREE(run_dir);
lock_daemon: Fix some memleaks 28 bytes in 1 blocks are definitely lost in loss record 26 of 66 at 0x4C2CF0F: malloc (vg_replace_malloc.c:299) by 0x7A02719: strdup (strdup.c:42) by 0x197DC1: virStrdup (virstring.c:961) by 0x12B478: virLockDaemonConfigFilePath (lock_daemon_config.c:44) by 0x12A759: main (lock_daemon.c:1270) 62 (32 direct, 30 indirect) bytes in 1 blocks are definitely lost in loss record 41 of 66 at 0x4C2EF26: calloc (vg_replace_malloc.c:711) by 0x151B61: virAlloc (viralloc.c:144) by 0x12B56C: virLockDaemonConfigNew (lock_daemon_config.c:71) by 0x12A491: main (lock_daemon.c:1262) 13 bytes in 1 blocks are definitely lost in loss record 21 of 70 at 0x4C2CF0F: malloc (vg_replace_malloc.c:299) by 0x7A02719: strdup (strdup.c:42) by 0x197E3F: virStrdup (virstring.c:961) by 0x12C86B: virLockSpaceProtocolDispatchRegister (lock_daemon_dispatch.c:291) by 0x12BB73: virLockSpaceProtocolDispatchRegisterHelper (lock_daemon_dispatch_stubs.h:152) by 0x1336AA: virNetServerProgramDispatchCall (virnetserverprogram.c:437) by 0x13320D: virNetServerProgramDispatch (virnetserverprogram.c:304) by 0x139E3E: virNetServerProcessMsg (virnetserver.c:144) by 0x13A1A2: virNetServerDispatchNewMessage (virnetserver.c:230) by 0x1350F5: virNetServerClientDispatchMessage (virnetserverclient.c:343) by 0x137680: virNetServerClientDispatchEvent (virnetserverclient.c:1498) by 0x147704: virNetSocketEventHandle (virnetsocket.c:2140) Signed-off-by: Michal Privoznik <mprivozn@redhat.com> Reviewed-by: John Ferlan <jferlan@redhat.com>
2018-08-26 06:48:47 +00:00
virLockDaemonConfigFree(config);
return ret;
}