Page Menu
Home
ClusterLabs Projects
Search
Configure Global Search
Log In
Files
F1841783
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
29 KB
Referenced Files
None
Subscribers
None
View Options
diff --git a/lib/services/systemd.c b/lib/services/systemd.c
index ebc11566dc..4581846c96 100644
--- a/lib/services/systemd.c
+++ b/lib/services/systemd.c
@@ -1,493 +1,497 @@
/*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU 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 software 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
* General Public License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Copyright (C) 2012 Andrew Beekhof <andrew@beekhof.net>
*/
#include <crm_internal.h>
#include <crm/crm.h>
#include <crm/services.h>
#include <crm/common/mainloop.h>
#include <gio/gio.h>
#include <services_private.h>
#include <systemd.h>
#define BUS_NAME "org.freedesktop.systemd1"
#define BUS_PATH "/org/freedesktop/systemd1"
#define BUS_PROPERTY_IFACE "org.freedesktop.DBus.Properties"
/*
/usr/share/dbus-1/interfaces/org.freedesktop.systemd1.Manager.xml
*/
struct unit_info {
const char *id;
const char *description;
const char *load_state;
const char *active_state;
const char *sub_state;
const char *following;
const char *unit_path;
uint32_t job_id;
const char *job_type;
const char *job_path;
};
static GDBusProxy *systemd_proxy = NULL;
static GDBusProxy *
get_proxy(const char *path, const char *interface)
{
GError *error = NULL;
GDBusProxy *proxy = NULL;
g_type_init();
if(path == NULL) {
path = BUS_PATH;
}
proxy = g_dbus_proxy_new_for_bus_sync (
G_BUS_TYPE_SYSTEM, G_DBUS_PROXY_FLAGS_NONE, NULL, /* GDBusInterfaceInfo */
BUS_NAME, path, interface,
NULL, /* GCancellable */ &error);
if (error) {
crm_err("Can't connect obtain proxy to %s interface: %s", interface, error->message);
g_error_free(error);
proxy = NULL;
}
return proxy;
}
static gboolean
systemd_init(void)
{
- if(systemd_proxy == NULL) {
+ static int need_init = 1;
+ if(need_init) {
+ need_init = 0;
systemd_proxy = get_proxy(NULL, BUS_NAME".Manager");
}
if(systemd_proxy == NULL) {
return FALSE;
}
return TRUE;
}
void systemd_cleanup(void)
{
if (systemd_proxy) {
g_object_unref(systemd_proxy);
systemd_proxy = NULL;
}
}
static char *
systemd_service_name(const char *name)
{
if(name == NULL) {
return NULL;
} else if(strstr(name, ".service")) {
return strdup(name);
}
return g_strdup_printf("%s.service", name);
}
static void
systemd_daemon_reload (GDBusProxy *proxy, GError **error)
{
GVariant *_ret = g_dbus_proxy_call_sync (
proxy, "Reload", g_variant_new ("()"),
G_DBUS_CALL_FLAGS_NONE, -1, NULL, error);
if (_ret) {
g_variant_unref (_ret);
}
}
static gboolean
systemd_unit_by_name (
GDBusProxy *proxy,
const gchar *arg_name,
gchar **out_unit,
GCancellable *cancellable,
GError **error)
{
GError *reload_error = NULL;
GVariant *_ret = NULL;
char *name = NULL;
int retry = 0;
/*
" <method name=\"GetUnit\">\n" \
" <arg name=\"name\" type=\"s\" direction=\"in\"/>\n" \
" <arg name=\"unit\" type=\"o\" direction=\"out\"/>\n" \
" </method>\n" \
*/
name = systemd_service_name(arg_name);
crm_debug("Calling GetUnit");
_ret = g_dbus_proxy_call_sync (
proxy, "GetUnit", g_variant_new ("(s)", name),
G_DBUS_CALL_FLAGS_NONE, -1, cancellable, error);
if (_ret) {
crm_debug("Checking output");
g_variant_get (_ret, "(o)", out_unit);
crm_debug("%s = %s", arg_name, *out_unit);
g_variant_unref (_ret);
goto done;
}
crm_debug("Reloading the systemd manager configuration");
systemd_daemon_reload (proxy, &reload_error);
retry++;
if (reload_error) {
crm_err("Cannot reload the systemd manager configuration: %s", reload_error->message);
g_error_free(reload_error);
goto done;
}
if(*error) {
crm_debug("Cannot find %s: %s", name, (*error)->message);
g_error_free(*error);
*error = NULL;
}
/*
<method name="LoadUnit">
<arg name="name" type="s" direction="in"/>
<arg name="unit" type="o" direction="out"/>
</method>
*/
crm_debug("Calling LoadUnit");
_ret = g_dbus_proxy_call_sync (
proxy, "LoadUnit", g_variant_new ("(s)", name),
G_DBUS_CALL_FLAGS_NONE, -1, cancellable, error);
if (_ret) {
crm_debug("Checking output");
g_variant_get (_ret, "(o)", out_unit);
crm_debug("%s = %s", arg_name, *out_unit);
g_variant_unref (_ret);
}
done:
free(name);
return _ret != NULL;
}
static char *
systemd_unit_property(const char *obj, const gchar *iface, const char *name)
{
GError *error = NULL;
GDBusProxy *proxy;
GVariant *asv = NULL;
GVariant *value = NULL;
GVariant *_ret = NULL;
char *output = NULL;
crm_info("Calling GetAll on %s", obj);
proxy = get_proxy(obj, BUS_PROPERTY_IFACE);
if (!proxy) {
return NULL;
}
_ret = g_dbus_proxy_call_sync (
proxy, "GetAll", g_variant_new ("(s)", iface),
G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
if (error) {
crm_err("Cannot get properties for %s: %s", g_dbus_proxy_get_object_path(proxy), error->message);
g_error_free(error);
g_object_unref(proxy);
return NULL;
}
crm_info("Call to GetAll passed: type '%s' %d\n", g_variant_get_type_string (_ret), g_variant_n_children (_ret));
asv = g_variant_get_child_value(_ret, 0);
crm_trace("asv type '%s' %d\n", g_variant_get_type_string (asv), g_variant_n_children (asv));
value = g_variant_lookup_value(asv, name, NULL);
if(value && g_variant_is_of_type(value, G_VARIANT_TYPE_STRING)) {
crm_debug("Got value '%s' for %s[%s]", g_variant_get_string(value, NULL), obj, name);
output = g_variant_dup_string(value, NULL);
} else {
crm_info("No value for %s[%s]", obj, name);
}
g_object_unref(proxy);
g_variant_unref(_ret);
return output;
}
GList *
systemd_unit_listall(void)
{
int lpc = 0;
GList *units = NULL;
GError *error = NULL;
GVariant *out_units = NULL;
GVariantIter iter;
struct unit_info u;
GVariant *_ret = NULL;
- CRM_ASSERT(systemd_init());
+ if(systemd_init() == FALSE) {
+ return NULL;
+ }
/*
" <method name=\"ListUnits\">\n" \
" <arg name=\"units\" type=\"a(ssssssouso)\" direction=\"out\"/>\n" \
" </method>\n" \
*/
_ret = g_dbus_proxy_call_sync (
systemd_proxy, "ListUnits", g_variant_new ("()"),
G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
if (error || _ret == NULL) {
crm_info("Call to ListUnits failed: %s", error->message);
g_error_free(error);
return NULL;
}
g_variant_get (_ret, "(@a(ssssssouso))", &out_units);
g_variant_iter_init (&iter, out_units);
while (g_variant_iter_loop (&iter, "(ssssssouso)",
&u.id,
&u.description,
&u.load_state,
&u.active_state,
&u.sub_state,
&u.following,
&u.unit_path,
&u.job_id,
&u.job_type,
&u.job_path))
{
char *match = strstr(u.id, ".service");
if(match) {
lpc++;
match[0] = 0;
crm_trace("Got %s[%s] = %s", u.id, u.active_state, u.description);
units = g_list_append(units, strdup(u.id));
}
}
crm_info("Call to ListUnits passed: type '%s' count %d", g_variant_get_type_string (out_units), lpc);
g_variant_unref (_ret);
return units;
}
gboolean
systemd_unit_exists(const char *name)
{
char *path = NULL;
GError *error = NULL;
gboolean pass = FALSE;
CRM_ASSERT(systemd_init());
pass = systemd_unit_by_name(systemd_proxy, name, &path, NULL, &error);
if (error || pass == FALSE) {
crm_err("Call to ListUnits failed: %s", error->message);
g_error_free(error);
pass = FALSE;
} else {
crm_trace("Got %s", path);
}
/* free(path) */
return pass;
}
static char *
systemd_unit_metadata(const char *name)
{
char *path = NULL;
char *meta = NULL;
GError *error = NULL;
CRM_ASSERT(systemd_init());
if(systemd_unit_by_name(systemd_proxy, name, &path, NULL, &error)) {
char *desc = systemd_unit_property(path, BUS_NAME".Unit", "Description");
meta = g_strdup_printf(
"<?xml version=\"1.0\"?>\n"
"<!DOCTYPE resource-agent SYSTEM \"ra-api-1.dtd\">\n"
"<resource-agent name=\"%s\" version=\"0.1\">\n"
" <version>1.0</version>\n"
" <longdesc lang=\"en\">\n"
" %s\n"
" </longdesc>\n"
" <shortdesc lang=\"en\">systemd unit file for %s</shortdesc>\n"
" <parameters>\n"
" </parameters>\n"
" <actions>\n"
" <action name=\"start\" timeout=\"15\" />\n"
" <action name=\"stop\" timeout=\"15\" />\n"
" <action name=\"status\" timeout=\"15\" />\n"
" <action name=\"restart\" timeout=\"15\" />\n"
" <action name=\"monitor\" timeout=\"15\" interval=\"15\" start-delay=\"15\" />\n"
" <action name=\"meta-data\" timeout=\"5\" />\n"
" </actions>\n"
" <special tag=\"upstart\">\n"
" </special>\n"
"</resource-agent>\n",
name, desc, name);
free(desc);
}
return meta;
}
static void
systemd_unit_exec_done(GObject *source_object, GAsyncResult *res, gpointer user_data)
{
GError *error = NULL;
GVariant *_ret = NULL;
svc_action_t* op = user_data;
GDBusProxy *proxy = G_DBUS_PROXY (source_object);
/* Obtain rc and stderr/out */
_ret = g_dbus_proxy_call_finish (proxy, res, &error);
if (error) {
/* ignore "already started" or "not running" errors */
if (safe_str_eq(op->action, "stop")
&& strstr(error->message, "systemd1.InvalidName")) {
crm_trace("Masking Stop failure for %s: unknown services are stopped", op->rsc);
op->rc = PCMK_EXECRA_OK;
} else {
crm_err("Could not issue %s for %s: %s (%s)", op->action, op->rsc, error->message, "");
}
g_error_free(error);
} else {
char *path = NULL;
g_variant_get(_ret, "(o)", &path);
crm_info("Call to %s passed: type '%s' %s", op->action, g_variant_get_type_string (_ret), path);
op->rc = PCMK_EXECRA_OK;
}
operation_finalize(op);
if (_ret) {
g_variant_unref(_ret);
}
}
gboolean
systemd_unit_exec(svc_action_t* op, gboolean synchronous)
{
char *unit = NULL;
GError *error = NULL;
gboolean pass = FALSE;
GVariant *_ret = NULL;
const char *action = op->action;
char *name = systemd_service_name(op->agent);
op->rc = PCMK_EXECRA_UNKNOWN_ERROR;
CRM_ASSERT(systemd_init());
crm_debug("Performing %s op on systemd unit %s named '%s'", op->action, op->agent, op->rsc);
pass = systemd_unit_by_name (systemd_proxy, op->agent, &unit, NULL, &error);
if (error || pass == FALSE) {
crm_debug("Could not obtain unit named '%s': %s", op->agent, error->message);
if(strstr(error->message, "systemd1.NoSuchUnit")) {
op->rc = PCMK_EXECRA_NOT_INSTALLED;
}
g_error_free(error);
free(name);
return FALSE;
}
if (safe_str_eq(op->action, "meta-data")) {
op->stdout_data = systemd_unit_metadata(op->agent);
op->rc = PCMK_EXECRA_OK;
goto cleanup;
}
if (safe_str_eq(op->action, "monitor") || safe_str_eq(action, "status")) {
char *state = systemd_unit_property(unit, BUS_NAME".Unit", "ActiveState");
if ( !g_strcmp0(state, "active")) {
op->rc = PCMK_EXECRA_OK;
} else {
op->rc = PCMK_EXECRA_NOT_RUNNING;
}
if(synchronous == FALSE) {
operation_finalize(op);
}
free(state);
goto cleanup;
} else if (!g_strcmp0(action, "start")) {
action = "StartUnit";
} else if (!g_strcmp0(action, "stop")) {
action = "StopUnit";
} else if (!g_strcmp0(action, "restart")) {
action = "RestartUnit";
} else {
return PCMK_EXECRA_UNIMPLEMENT_FEATURE;
}
crm_debug("Calling %s for %s: %s", action, op->rsc, unit);
if(synchronous == FALSE) {
g_dbus_proxy_call(
systemd_proxy, action, g_variant_new ("(ss)", name, "replace"),
G_DBUS_CALL_FLAGS_NONE, op->timeout, NULL, systemd_unit_exec_done, op);
free(unit);
free(name);
return TRUE;
}
_ret = g_dbus_proxy_call_sync (
systemd_proxy, action, g_variant_new ("(ss)", name, "replace"),
G_DBUS_CALL_FLAGS_NONE, op->timeout, NULL, &error);
if (error) {
/* ignore "already started" or "not running" errors */
if (safe_str_eq(op->action, "stop")
&& strstr(error->message, "systemd1.InvalidName")) {
crm_trace("Masking Stop failure for %s: unknown services are stopped", op->rsc);
op->rc = PCMK_EXECRA_OK;
} else {
crm_err("Could not issue %s for %s: %s (%s)", action, op->rsc, error->message, unit);
}
g_error_free(error);
} else {
char *path = NULL;
g_variant_get(_ret, "(o)", &path);
crm_info("Call to %s passed: type '%s' %s", action, g_variant_get_type_string (_ret), path);
op->rc = PCMK_EXECRA_OK;
}
cleanup:
free(unit);
free(name);
if (_ret) {
g_variant_unref(_ret);
}
return op->rc == PCMK_EXECRA_OK;
}
diff --git a/lib/services/upstart.c b/lib/services/upstart.c
index d0bc66ad75..b698aca80e 100644
--- a/lib/services/upstart.c
+++ b/lib/services/upstart.c
@@ -1,464 +1,468 @@
/*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU 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 software 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
* General Public License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* File: upstart-dbus.c
* Copyright (C) 2010 Senko Rasic <senko.rasic@dobarkod.hr>
* Copyright (c) 2010 Ante Karamatic <ivoks@init.hr>
*
*
* Each exported function is standalone, and creates a new connection to
* the upstart daemon. This is because lrmd plugins fork off for exec,
* and if we try and share the connection, the whole thing blocks
* indefinitely.
*/
#include <crm_internal.h>
#include <stdio.h>
#include <crm/crm.h>
#include <crm/services.h>
#include <crm/common/mainloop.h>
#include <services_private.h>
#include <upstart.h>
#include <glib.h>
#include <gio/gio.h>
#define BUS_NAME "com.ubuntu.Upstart"
#define BUS_PATH "/com/ubuntu/Upstart"
#define BUS_MANAGER_IFACE BUS_NAME"0_6"
#define BUS_PROPERTY_IFACE "org.freedesktop.DBus.Properties"
/*
http://upstart.ubuntu.com/wiki/DBusInterface
*/
static GDBusProxy *upstart_proxy = NULL;
static GDBusProxy *
get_proxy(const char *path, const char *interface)
{
GError *error = NULL;
GDBusProxy *proxy = NULL;
g_type_init();
if(path == NULL) {
path = BUS_PATH;
}
proxy = g_dbus_proxy_new_for_bus_sync (
G_BUS_TYPE_SYSTEM, G_DBUS_PROXY_FLAGS_NONE, NULL, /* GDBusInterfaceInfo */
BUS_NAME, path, interface,
NULL, /* GCancellable */ &error);
if (error) {
crm_err("Can't connect obtain proxy to %s interface: %s", interface, error->message);
g_error_free(error);
proxy = NULL;
}
return proxy;
}
static gboolean
upstart_init(void)
{
- if(upstart_proxy == NULL) {
+ static int need_init = 1;
+ if(need_init) {
+ need_init = 0;
upstart_proxy = get_proxy(NULL, BUS_MANAGER_IFACE);
}
if(upstart_proxy == NULL) {
return FALSE;
}
return TRUE;
}
void upstart_cleanup(void)
{
if (upstart_proxy) {
g_object_unref(upstart_proxy);
upstart_proxy = NULL;
}
}
static gboolean
upstart_job_by_name (
GDBusProxy *proxy,
const gchar *arg_name,
gchar **out_unit,
GCancellable *cancellable,
GError **error)
{
/*
com.ubuntu.Upstart0_6.GetJobByName (in String name, out ObjectPath job)
*/
GVariant *_ret = g_dbus_proxy_call_sync (
proxy, "GetJobByName", g_variant_new ("(s)", arg_name),
G_DBUS_CALL_FLAGS_NONE, -1, cancellable, error);
if (_ret) {
g_variant_get (_ret, "(o)", out_unit);
g_variant_unref (_ret);
}
return _ret != NULL;
}
GList *
upstart_job_listall(void)
{
GList *units = NULL;
GError *error = NULL;
GVariantIter *iter;
char *path = NULL;
GVariant *_ret = NULL;
int lpc = 0;
- CRM_ASSERT(upstart_init());
+ if(upstart_init() == FALSE) {
+ return NULL;
+ }
/*
com.ubuntu.Upstart0_6.GetAllJobs (out <Array of ObjectPath> jobs)
*/
_ret = g_dbus_proxy_call_sync (
upstart_proxy, "GetAllJobs", g_variant_new ("()"),
G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
if (error) {
crm_info("Call to GetAllJobs failed: %s", error->message);
g_error_free(error);
return NULL;
}
g_variant_get (_ret, "(ao)", &iter);
while (g_variant_iter_loop (iter, "o", &path)) {
int llpc = 0;
const char *job = path;
while(path[llpc] != 0) {
if(path[llpc] == '/') {
job = path+llpc+1;
}
llpc++;
}
lpc++;
crm_trace("%s\n", path);
units = g_list_append(units, strdup(job));
}
crm_info("Call to GetAllJobs passed: type '%s', count %d", g_variant_get_type_string (_ret), lpc);
g_variant_iter_free(iter);
g_variant_unref(_ret);
return units;
}
gboolean
upstart_job_exists(const char *name)
{
char *path = NULL;
GError *error = NULL;
gboolean pass = FALSE;
CRM_ASSERT(upstart_init());
pass = upstart_job_by_name (upstart_proxy, name, &path, NULL, &error);
if (error || pass == FALSE) {
crm_trace("Call to ListUnits failed: %s", error->message);
g_error_free(error);
pass = FALSE;
} else {
crm_trace("Got %s", path);
}
/* free(path) */
return pass;
}
static char *
upstart_job_property(const char *obj, const gchar *iface, const char *name)
{
GError *error = NULL;
GDBusProxy *proxy;
GVariant *asv = NULL;
GVariant *value = NULL;
GVariant *_ret = NULL;
char *output = NULL;
crm_info("Calling GetAll on %s", obj);
proxy = get_proxy(obj, BUS_PROPERTY_IFACE);
if (!proxy) {
return NULL;
}
_ret = g_dbus_proxy_call_sync (
proxy, "GetAll", g_variant_new ("(s)", iface),
G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
if (error) {
crm_err("Cannot get properties for %s: %s", g_dbus_proxy_get_object_path(proxy), error->message);
g_error_free(error);
g_object_unref(proxy);
return NULL;
}
crm_info("Call to GetAll passed: type '%s' %d\n", g_variant_get_type_string (_ret), g_variant_n_children (_ret));
asv = g_variant_get_child_value(_ret, 0);
crm_trace("asv type '%s' %d\n", g_variant_get_type_string (asv), g_variant_n_children (asv));
value = g_variant_lookup_value(asv, name, NULL);
if(value && g_variant_is_of_type(value, G_VARIANT_TYPE_STRING)) {
crm_info("Got value '%s' for %s[%s]", g_variant_get_string(value, NULL), obj, name);
output = g_variant_dup_string(value, NULL);
} else {
crm_info("No value for %s[%s]", obj, name);
}
g_object_unref(proxy);
g_variant_unref(_ret);
return output;
}
static char *
get_first_instance(const gchar *job)
{
char *instance = NULL;
GError *error = NULL;
GDBusProxy *proxy = get_proxy(job, BUS_MANAGER_IFACE".Job");
GVariant *_ret = g_dbus_proxy_call_sync (
proxy, "GetAllInstances", g_variant_new ("()"),
G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
if (error) {
crm_err("Cannot call GetAllInstances for %s: %s", job, error->message);
g_error_free(error);
return NULL;
}
crm_trace("Call to GetAllInstances passed: type '%s' %d\n", g_variant_get_type_string (_ret), g_variant_n_children (_ret));
if(g_variant_n_children (_ret)) {
GVariant *tmp1 = g_variant_get_child_value(_ret, 0);
if(g_variant_n_children (tmp1)) {
GVariant *tmp2 = g_variant_get_child_value(tmp1, 0);
instance = g_variant_dup_string(tmp2, NULL);
}
}
crm_info("Result: %s", instance);
g_variant_unref(_ret);
return instance;
}
gboolean
upstart_job_running(const gchar *name)
{
char *job = NULL;
GError *error = NULL;
gboolean pass = FALSE;
pass = upstart_job_by_name (upstart_proxy, name, &job, NULL, &error);
if (error || pass == FALSE) {
crm_err("Call to ListUnits failed: %s", error->message);
g_error_free(error);
} else {
char *instance = get_first_instance(job);
pass = FALSE;
if(instance) {
if (instance) {
char *state = upstart_job_property(instance, BUS_MANAGER_IFACE".Instance", "state");
crm_info("State of %s: %s", name, state);
if(state) {
pass = !g_strcmp0(state, "running");
}
free(state);
}
}
free(instance);
}
crm_info("%s is%s running", name, pass?"":" not");
return pass;
}
static char *
upstart_job_metadata(const char *name)
{
return g_strdup_printf(
"<?xml version=\"1.0\"?>\n"
"<!DOCTYPE resource-agent SYSTEM \"ra-api-1.dtd\">\n"
"<resource-agent name=\"%s\" version=\"0.1\">\n"
" <version>1.0</version>\n"
" <longdesc lang=\"en\">\n"
" Upstart agent for controlling the system %s service"
" </longdesc>\n"
" <shortdesc lang=\"en\">%s upstart agent</shortdesc>\n"
" <parameters>\n"
" </parameters>\n"
" <actions>\n"
" <action name=\"start\" timeout=\"15\" />\n"
" <action name=\"stop\" timeout=\"15\" />\n"
" <action name=\"status\" timeout=\"15\" />\n"
" <action name=\"restart\" timeout=\"15\" />\n"
" <action name=\"monitor\" timeout=\"15\" interval=\"15\" start-delay=\"15\" />\n"
" <action name=\"meta-data\" timeout=\"5\" />\n"
" </actions>\n"
" <special tag=\"upstart\">\n"
" </special>\n"
"</resource-agent>\n",
name, name, name);
}
static void
upstart_job_exec_done(GObject *source_object, GAsyncResult *res, gpointer user_data)
{
GError *error = NULL;
GVariant *_ret = NULL;
svc_action_t* op = user_data;
GDBusProxy *proxy = G_DBUS_PROXY (source_object);
/* Obtain rc and stderr/out */
_ret = g_dbus_proxy_call_finish (proxy, res, &error);
if (error) {
/* ignore "already started" or "not running" errors */
if (safe_str_eq(op->action, "start")
&& strstr(error->message, BUS_MANAGER_IFACE".Error.AlreadyStarted")) {
crm_trace("Masking Start failure for %s: already started", op->rsc);
op->rc = PCMK_EXECRA_OK;
} else if (safe_str_eq(op->action, "stop")
&& strstr(error->message, BUS_MANAGER_IFACE".Error.UnknownInstance")) {
crm_trace("Masking Stop failure for %s: unknown services are stopped", op->rsc);
op->rc = PCMK_EXECRA_OK;
} else {
crm_err("Could not issue %s for %s: %s", op->action, op->rsc, error->message);
}
g_error_free(error);
} else {
char *path = NULL;
g_variant_get(_ret, "(o)", &path);
crm_info("Call to %s passed: type '%s' %s", op->action, g_variant_get_type_string (_ret), path);
op->rc = PCMK_EXECRA_OK;
}
operation_finalize(op);
g_object_unref(proxy);
if (_ret) {
g_variant_unref(_ret);
}
}
gboolean
upstart_job_exec(svc_action_t* op, gboolean synchronous)
{
char *job = NULL;
GError *error = NULL;
gboolean pass = FALSE;
gchar *no_args[] = { NULL };
const char *action = op->action;
GVariant *_ret = NULL;
GDBusProxy *job_proxy = NULL;
op->rc = PCMK_EXECRA_UNKNOWN_ERROR;
CRM_ASSERT(upstart_init());
pass = upstart_job_by_name (upstart_proxy, op->agent, &job, NULL, &error);
if (error || pass == FALSE) {
crm_debug("Could not obtain job named '%s': %s", op->agent, error->message);
op->rc = PCMK_EXECRA_NOT_INSTALLED;
g_error_free(error);
return FALSE;
}
if (safe_str_eq(op->action, "meta-data")) {
op->stdout_data = upstart_job_metadata(op->agent);
op->rc = PCMK_EXECRA_OK;
goto cleanup;
}
if (safe_str_eq(op->action, "monitor") || safe_str_eq(action, "status")) {
if (upstart_job_running (op->agent)) {
op->rc = PCMK_EXECRA_OK;
} else {
op->rc = PCMK_EXECRA_NOT_RUNNING;
}
if(synchronous == FALSE) {
operation_finalize(op);
}
goto cleanup;
} else if (!g_strcmp0(action, "start")) {
action = "Start";
} else if (!g_strcmp0(action, "stop")) {
action = "Stop";
} else if (!g_strcmp0(action, "restart")) {
action = "Restart";
} else {
return PCMK_EXECRA_UNIMPLEMENT_FEATURE;
}
job_proxy = get_proxy(job, BUS_MANAGER_IFACE".Job");
crm_debug("Calling %s for %s: %s", action, op->rsc, job);
if(synchronous == FALSE) {
g_dbus_proxy_call(
job_proxy, action, g_variant_new ("(^asb)", no_args, TRUE),
G_DBUS_CALL_FLAGS_NONE, op->timeout, NULL, upstart_job_exec_done, op);
free(job);
return TRUE;
}
_ret = g_dbus_proxy_call_sync (
job_proxy, action, g_variant_new ("(^asb)", no_args, TRUE),
G_DBUS_CALL_FLAGS_NONE, op->timeout, NULL, &error);
if (error) {
/* ignore "already started" or "not running" errors */
if (safe_str_eq(action, "Start")
&& strstr(error->message, BUS_MANAGER_IFACE".Error.AlreadyStarted")) {
crm_trace("Masking Start failure for %s: already started", op->rsc);
op->rc = PCMK_EXECRA_OK;
} else if (safe_str_eq(action, "Stop")
&& strstr(error->message, BUS_MANAGER_IFACE".Error.UnknownInstance")) {
crm_trace("Masking Stop failure for %s: unknown services are stopped", op->rsc);
op->rc = PCMK_EXECRA_OK;
} else {
crm_err("Could not issue %s for %s: %s (%s)", action, op->rsc, error->message, job);
}
g_error_free(error);
} else {
char *path = NULL;
g_variant_get(_ret, "(o)", &path);
crm_info("Call to %s passed: type '%s' %s", action, g_variant_get_type_string (_ret), path);
op->rc = PCMK_EXECRA_OK;
}
cleanup:
free(job);
if(job_proxy) {
g_object_unref(job_proxy);
}
if (_ret) {
g_variant_unref(_ret);
}
return op->rc == PCMK_EXECRA_OK;
}
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Sat, Nov 23, 7:28 AM (1 d, 3 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1018450
Default Alt Text
(29 KB)
Attached To
Mode
rP Pacemaker
Attached
Detach File
Event Timeline
Log In to Comment