libvirt/src/locking/sanlock_helper.c
Jiri Denemark 893647671b locking: Implement lock failure action in sanlock driver
While the changes to sanlock driver should be stable, the actual
implementation of sanlock_helper is supposed to be replaced in the
future. However, before we can implement a better sanlock_helper, we
need an administrative interface to libvirtd so that the helper can just
pass a "leases lost" event to the particular libvirt driver and
everything else will be taken care of internally. This approach will
also allow libvirt to pass such event to applications and use
appropriate reasons when changing domain states.

The temporary implementation handles all actions directly by calling
appropriate libvirt APIs (which among other things means that it needs
to know the credentials required to connect to libvirtd).
2012-10-11 14:41:42 +02:00

139 lines
3.2 KiB
C

#include <config.h>
#include <stdio.h>
#include <stdlib.h>
#include <locale.h>
#include "configmake.h"
#include "internal.h"
#include "conf.h"
#include "memory.h"
#include "domain_conf.h"
static int
getArgs(int argc,
char **argv,
const char **uri,
const char **uuid,
virDomainLockFailureAction *action)
{
int act;
if (argc != 4) {
fprintf(stderr, _("%s uri uuid action\n"), argv[0]);
return -1;
}
*uri = argv[1];
*uuid = argv[2];
act = virDomainLockFailureTypeFromString(argv[3]);
if (act < 0) {
fprintf(stderr, _("invalid failure action: '%s'\n"), argv[3]);
return -1;
}
*action = act;
return 0;
}
static int
authCallback(virConnectCredentialPtr cred ATTRIBUTE_UNUSED,
unsigned int ncred ATTRIBUTE_UNUSED,
void *cbdata ATTRIBUTE_UNUSED)
{
return -1;
}
int
main(int argc, char **argv)
{
const char *uri;
const char *uuid;
virDomainLockFailureAction action;
char *xml = NULL;
virConnectPtr conn = NULL;
virDomainPtr dom = NULL;
int ret = EXIT_FAILURE;
int authTypes[] = {
VIR_CRED_AUTHNAME,
VIR_CRED_ECHOPROMPT,
VIR_CRED_PASSPHRASE,
VIR_CRED_NOECHOPROMPT,
};
virConnectAuth auth = {
.credtype = authTypes,
.ncredtype = ARRAY_CARDINALITY(authTypes),
.cb = authCallback,
};
if (setlocale(LC_ALL, "") == NULL ||
bindtextdomain(PACKAGE, LOCALEDIR) == NULL ||
textdomain(PACKAGE) == NULL) {
fprintf(stderr, _("%s: initialization failed\n"), argv[0]);
exit(EXIT_FAILURE);
}
if (getArgs(argc, argv, &uri, &uuid, &action) < 0)
goto cleanup;
if (!(conn = virConnectOpenAuth(uri, &auth, 0)) ||
!(dom = virDomainLookupByUUIDString(conn, uuid)))
goto cleanup;
switch (action) {
case VIR_DOMAIN_LOCK_FAILURE_POWEROFF:
if (virDomainDestroy(dom) == 0 ||
virDomainIsActive(dom) == 0)
ret = EXIT_SUCCESS;
break;
case VIR_DOMAIN_LOCK_FAILURE_RESTART:
if (virDomainIsPersistent(dom)) {
if ((virDomainDestroy(dom) == 0 ||
virDomainIsActive(dom) == 0) &&
virDomainCreate(dom) == 0)
ret = EXIT_SUCCESS;
} else {
xml = virDomainGetXMLDesc(dom,
VIR_DOMAIN_XML_SECURE |
VIR_DOMAIN_XML_INACTIVE);
if (!xml ||
(virDomainDestroy(dom) < 0 &&
virDomainIsActive(dom) != 0))
goto cleanup;
virDomainFree(dom);
if ((dom = virDomainCreateXML(conn, xml, 0)))
ret = EXIT_SUCCESS;
}
break;
case VIR_DOMAIN_LOCK_FAILURE_PAUSE:
if (virDomainSuspend(dom) == 0)
ret = EXIT_SUCCESS;
break;
case VIR_DOMAIN_LOCK_FAILURE_IGNORE:
ret = EXIT_SUCCESS;
break;
default:
fprintf(stderr, _("unsupported failure action: '%s'\n"),
virDomainLockFailureTypeToString(action));
break;
}
cleanup:
if (dom)
virDomainFree(dom);
if (conn)
virConnectClose(conn);
VIR_FREE(xml);
return ret;
}