Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
7c7b6dd
add logging for services__execute_file function
semtagg Oct 31, 2022
bc62a2f
fix
semtagg Oct 31, 2022
d8398c2
wip
semtagg Nov 7, 2022
e03b863
wip
semtagg Nov 7, 2022
7cb9518
wip
semtagg Nov 7, 2022
d05b065
add new agent as shared library for tests with makefile
semtagg Nov 8, 2022
a457aec
add simple action for test
semtagg Nov 8, 2022
1c99ef1
added minimal working version
semtagg Nov 28, 2022
25388cf
wip
semtagg Dec 1, 2022
1934103
fixed recurring monitor action
semtagg Dec 4, 2022
650fcc3
removed test agent from main repo
semtagg Dec 4, 2022
fcae722
some code cleanup & moved agent to another repo
semtagg Dec 4, 2022
c5ecab8
wip
semtagg Dec 4, 2022
b14d3ca
fixed environment variable
semtagg Dec 8, 2022
510ba93
wip
semtagg Dec 8, 2022
21c00c5
wip
semtagg Feb 21, 2023
d53977a
wip
semtagg Feb 22, 2023
0a303b7
Merge branch 'resource-management-through-plugins' into dlopen
semtagg Feb 22, 2023
a100973
wip
semtagg Feb 22, 2023
fd4b339
added new agents class
semtagg Feb 23, 2023
9a9855d
added support for params instead of env
Mar 8, 2023
36490da
wip
semtagg Mar 8, 2023
13032c7
fix
semtagg Mar 8, 2023
0d0800f
fix
semtagg Mar 8, 2023
d3bb841
fix
semtagg Mar 8, 2023
12df80b
added RTLD_NODELETE flag
semtagg Mar 15, 2023
9f4286f
wip
Mar 15, 2023
54bfed4
wip
semtagg Mar 17, 2023
1f10387
ra_caps
semtagg Mar 17, 2023
d110afa
clean
semtagg Mar 17, 2023
bd1f189
wip
semtagg Mar 17, 2023
d608db9
clean
semtagg Mar 17, 2023
52638cf
clean
semtagg Mar 17, 2023
76b6a53
wip
semtagg Mar 21, 2023
a7bf2c4
fix
semtagg Mar 22, 2023
859321a
WIP
semtagg Mar 24, 2023
0b9d315
WIP
semtagg Mar 24, 2023
14900e7
wip
semtagg Apr 13, 2023
5103bad
wip
semtagg Apr 13, 2023
69387f4
fix
semtagg Apr 13, 2023
85d6c29
wip
semtagg Apr 13, 2023
620e08b
fix not running
semtagg Apr 18, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -485,6 +485,13 @@ AC_ARG_WITH([logdir],
[ CRM_LOG_DIR="$withval" ]
)

DLOPEN_ROOT_DIR=""
AC_ARG_WITH([dlopen-root-dir],
[AS_HELP_STRING([--with-dlopen-root-dir=DIR],
[directory for dlopen plugins @<:@/usr/lib/dlopen@:>@])],
[ DLOPEN_ROOT_DIR="$withval" ]
)

CRM_BUNDLE_DIR=""
AC_ARG_WITH([bundledir],
[AS_HELP_STRING([--with-bundledir=DIR],
Expand Down Expand Up @@ -693,6 +700,10 @@ expand_path_option CRM_LOG_DIR "${localstatedir}/log/pacemaker"
AC_DEFINE_UNQUOTED(CRM_LOG_DIR,"$CRM_LOG_DIR", Location for Pacemaker log file)
AC_SUBST(CRM_LOG_DIR)

expand_path_option DLOPEN_ROOT_DIR "/usr/lib/dlopen"
AC_DEFINE_UNQUOTED(DLOPEN_ROOT_DIR, "$DLOPEN_ROOT_DIR", Directory for dlopen plugins)
AC_SUBST(DLOPEN_ROOT_DIR)

expand_path_option CRM_BUNDLE_DIR "${localstatedir}/log/pacemaker/bundles"
AC_DEFINE_UNQUOTED(CRM_BUNDLE_DIR,"$CRM_BUNDLE_DIR", Location for Pacemaker bundle logs)
AC_SUBST(CRM_BUNDLE_DIR)
Expand Down
14 changes: 14 additions & 0 deletions daemons/execd/execd_commands.c
Original file line number Diff line number Diff line change
Expand Up @@ -902,6 +902,20 @@ action_complete(svc_action_t * action)
}
#endif

if (rsc && pcmk__str_eq(rsc->class, PCMK_RESOURCE_CLASS_DLOPEN, pcmk__str_casei)) {
if (action_matches(cmd, "monitor", 0)
&& pcmk__result_ok(&(cmd->result))) {
/* Successfully executed --version for the nagios plugin */
cmd->result.exit_status = PCMK_OCF_NOT_RUNNING;

} else if (pcmk__str_eq(cmd->action, "start", pcmk__str_casei)
&& !pcmk__result_ok(&(cmd->result))) {
#ifdef PCMK__TIME_USE_CGT
goagain = true;
#endif
}
}

#ifdef PCMK__TIME_USE_CGT
if (goagain) {
int time_sum = time_diff_ms(NULL, &(cmd->t_first_run));
Expand Down
1 change: 1 addition & 0 deletions include/crm/services.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ extern "C" {
#define PCMK_RESOURCE_CLASS_NAGIOS "nagios"
#define PCMK_RESOURCE_CLASS_STONITH "stonith"
#define PCMK_RESOURCE_CLASS_ALERT "alert"
#define PCMK_RESOURCE_CLASS_DLOPEN "dlopen"

/* This is the string passed in the OCF_EXIT_REASON_PREFIX environment variable.
* The stderr output that occurs after this prefix is encountered is considered
Expand Down
3 changes: 3 additions & 0 deletions lib/common/agents.c
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@ pcmk_get_ra_caps(const char *standard)
return pcmk_ra_cap_provider | pcmk_ra_cap_params
| pcmk_ra_cap_unique | pcmk_ra_cap_promotable;

} else if (!strcasecmp(standard, PCMK_RESOURCE_CLASS_DLOPEN)) {
return pcmk_ra_cap_params;

} else if (!strcasecmp(standard, PCMK_RESOURCE_CLASS_STONITH)) {
/* @COMPAT Stonith resources can't really be unique clones, but we've
* allowed it in the past and have it in some scheduler regression tests
Expand Down
3 changes: 2 additions & 1 deletion lib/pacemaker/pcmk_injections.c
Original file line number Diff line number Diff line change
Expand Up @@ -377,7 +377,8 @@ pcmk__inject_resource_history(pcmk__output_t *out, xmlNode *cib_node,
PCMK_RESOURCE_CLASS_SERVICE,
PCMK_RESOURCE_CLASS_UPSTART,
PCMK_RESOURCE_CLASS_SYSTEMD,
PCMK_RESOURCE_CLASS_LSB, NULL)) {
PCMK_RESOURCE_CLASS_LSB,
PCMK_RESOURCE_CLASS_DLOPEN, NULL)) {
out->err(out, "Invalid class for %s: %s", resource, rclass);
return NULL;

Expand Down
2 changes: 2 additions & 0 deletions lib/services/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ lib_LTLIBRARIES = libcrmservice.la
noinst_HEADERS = pcmk-dbus.h upstart.h systemd.h \
services_lsb.h services_nagios.h \
services_ocf.h \
services_dlopen.h \
services_private.h

libcrmservice_la_LDFLAGS = -version-info 31:0:3
Expand All @@ -29,6 +30,7 @@ libcrmservice_la_SOURCES = services.c
libcrmservice_la_SOURCES += services_linux.c
libcrmservice_la_SOURCES += services_lsb.c
libcrmservice_la_SOURCES += services_ocf.c
libcrmservice_la_SOURCES += services_dlopen.c
if BUILD_DBUS
libcrmservice_la_SOURCES += dbus.c
endif
Expand Down
19 changes: 19 additions & 0 deletions lib/services/services.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
#include "services_private.h"
#include "services_ocf.h"
#include "services_lsb.h"
#include "services_dlopen.h"

#if SUPPORT_UPSTART
# include <upstart.h>
Expand Down Expand Up @@ -306,6 +307,9 @@ services__create_resource_action(const char *name, const char *standard,
} else if (strcasecmp(op->standard, PCMK_RESOURCE_CLASS_LSB) == 0) {
rc = services__lsb_prepare(op);

} else if (strcasecmp(op->standard, PCMK_RESOURCE_CLASS_DLOPEN) == 0) {
rc = services__dlopen_prepare(op);

#if SUPPORT_SYSTEMD
} else if (strcasecmp(op->standard, PCMK_RESOURCE_CLASS_SYSTEMD) == 0) {
rc = services__systemd_prepare(op);
Expand Down Expand Up @@ -574,6 +578,10 @@ services_result2ocf(const char *standard, const char *action, int exit_status)
pcmk__str_casei)) {
return services__lsb2ocf(action, exit_status);

} else if (pcmk__str_eq(standard, PCMK_RESOURCE_CLASS_DLOPEN,
pcmk__str_casei)) {
return services__dlopen2ocf(exit_status);

} else {
crm_warn("Treating result from unknown standard '%s' as OCF",
((standard == NULL)? "unspecified" : standard));
Expand Down Expand Up @@ -814,6 +822,11 @@ handle_duplicate_recurring(svc_action_t * op)
static int
execute_action(svc_action_t *op)
{
if (pcmk__str_eq(op->standard, PCMK_RESOURCE_CLASS_DLOPEN,
pcmk__str_casei)) {
return services__execute_dlopen(op);
}

#if SUPPORT_UPSTART
if (pcmk__str_eq(op->standard, PCMK_RESOURCE_CLASS_UPSTART,
pcmk__str_casei)) {
Expand Down Expand Up @@ -1063,6 +1076,7 @@ resources_list_standards(void)
GList *standards = NULL;

standards = g_list_append(standards, strdup(PCMK_RESOURCE_CLASS_OCF));
standards = g_list_append(standards, strdup(PCMK_RESOURCE_CLASS_DLOPEN));
standards = g_list_append(standards, strdup(PCMK_RESOURCE_CLASS_LSB));
standards = g_list_append(standards, strdup(PCMK_RESOURCE_CLASS_SERVICE));

Expand Down Expand Up @@ -1154,6 +1168,8 @@ resources_list_agents(const char *standard, const char *provider)
return resources_os_list_ocf_agents(provider);
} else if (strcasecmp(standard, PCMK_RESOURCE_CLASS_LSB) == 0) {
return services__list_lsb_agents();
} else if (strcasecmp(standard, PCMK_RESOURCE_CLASS_DLOPEN) == 0) {
return services__list_dlopen_agents();
#if SUPPORT_SYSTEMD
} else if (strcasecmp(standard, PCMK_RESOURCE_CLASS_SYSTEMD) == 0) {
return systemd_unit_listall();
Expand Down Expand Up @@ -1233,6 +1249,9 @@ resources_agent_exists(const char *standard, const char *provider, const char *a
} else if (pcmk__str_eq(standard, PCMK_RESOURCE_CLASS_LSB, pcmk__str_casei)) {
rc = services__lsb_agent_exists(agent);

} else if (pcmk__str_eq(standard, PCMK_RESOURCE_CLASS_DLOPEN, pcmk__str_casei)) {
rc = services__dlopen_agent_exists(agent);

#if SUPPORT_SYSTEMD
} else if (pcmk__str_eq(standard, PCMK_RESOURCE_CLASS_SYSTEMD, pcmk__str_casei)) {
rc = systemd_unit_exists(agent);
Expand Down
145 changes: 145 additions & 0 deletions lib/services/services_dlopen.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
#include <crm_internal.h>

#ifndef _GNU_SOURCE
# define _GNU_SOURCE
#endif

#include <stdio.h>
#include <errno.h>
#include <sys/stat.h>
#include <dlfcn.h>
#include <crm/crm.h>
#include <crm/services.h>
#include <sys/mman.h>
#include <fcntl.h>
#include "services_private.h"
#include "services_dlopen.h"

// #define DLOPEN_ROOT_DIR "/usr/lib/dlopen" // or "/usr/lib/dlopen/"

GList *
services__list_dlopen_agents(void)
{
return services_os_get_directory_list(DLOPEN_ROOT_DIR, TRUE, FALSE);
}

bool
services__dlopen_agent_exists(const char *agent)
{
bool rc = FALSE;
struct stat st;
char *path = pcmk__full_path(agent, DLOPEN_ROOT_DIR);

rc = (stat(path, &st) == 0);
free(path);
return rc;
}

int
services__dlopen_prepare(svc_action_t *op)
{
op->opaque->exec = pcmk__full_path(op->agent, DLOPEN_ROOT_DIR);
op->opaque->args[0] = strdup(op->opaque->exec);
op->opaque->args[1] = strdup(op->action);
if ((op->opaque->args[0] == NULL) || (op->opaque->args[1] == NULL)) {
return ENOMEM;
}
return pcmk_rc_ok;
}

// TODO:
enum ocf_exitcode
services__dlopen2ocf(int exit_status)
{
return (enum ocf_exitcode) exit_status;
}

int
services__execute_dlopen(svc_action_t *op) {
if (strcasecmp(op->action, "meta-data") == 0) {
return services__execute_dlopen_metadata(op);
}

return services__execute_dlopen_action(op);
}

int
services__execute_dlopen_metadata(svc_action_t *op) {
void *lib;
char *lib_error;
const char *metadata;
char *dst = pcmk__full_path(op->agent, DLOPEN_ROOT_DIR);
lib = dlopen(dst, RTLD_NOW | RTLD_LOCAL | RTLD_NODELETE);

if (!lib) {
return pcmk_rc_error;
}

metadata = dlsym(lib, "metadata");

if ((lib_error = dlerror()) != NULL){
free(lib_error);

return pcmk_rc_error;
}

op->rc = PCMK_OCF_OK;
op->status = PCMK_EXEC_DONE;
op->pid = 0;
op->stdout_data = strdup(metadata);

if (op->opaque->callback) {
op->opaque->callback(op);
}

dlclose(lib);
return pcmk_rc_ok;
}

int
services__execute_dlopen_action(svc_action_t *op) {
void *lib;
char *lib_error;
char *error;
int (*exec)(GHashTable *, char **);
char *dst = pcmk__full_path(op->agent, DLOPEN_ROOT_DIR);
g_hash_table_replace(op->params, strdup("DLOPEN_RESOURCE_INSTANCE"), strdup(op->rsc));
lib = dlopen(dst, RTLD_NOW | RTLD_LOCAL | RTLD_NODELETE);

if (!lib) {
return pcmk_rc_error;
}

exec = dlsym(lib, op->action);

if ((lib_error = dlerror()) != NULL){
free(lib_error);

return pcmk_rc_error;
}

op->rc = exec(op->params, &error);
op->status = PCMK_EXEC_DONE;
op->pid = 0;

if (op->interval_ms != 0) {
// Recurring operations must be either cancelled or rescheduled
if (op->cancel) {
services__set_cancelled(op);
cancel_recurring_action(op);
} else {
op->opaque->repeat_timer = g_timeout_add(op->interval_ms,
recurring_action_timer,
(void *) op);
}
}

if (op->opaque->callback) {
op->opaque->callback(op);
}

crm_info("Exit code: %d, error: %s", op->rc, error);

dlclose(lib);
return pcmk_rc_ok;
}
23 changes: 23 additions & 0 deletions lib/services/services_dlopen.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#ifndef SERVICES_DLOPEN__H
# define SERVICES_DLOPEN__H

#include <glib.h>

// G_GNUC_INTERNAL int services__get_dlopen_metadata(const char *type, char **output);
G_GNUC_INTERNAL GList *services__list_dlopen_agents(void);
G_GNUC_INTERNAL bool services__dlopen_agent_exists(const char *agent);
G_GNUC_INTERNAL int services__dlopen_prepare(svc_action_t *op);

G_GNUC_INTERNAL
enum ocf_exitcode services__dlopen2ocf(int exit_status);

G_GNUC_INTERNAL
int services__execute_dlopen(svc_action_t *op);

G_GNUC_INTERNAL
int services__execute_dlopen_metadata(svc_action_t *op);

G_GNUC_INTERNAL
int services__execute_dlopen_action(svc_action_t *op);

#endif
1 change: 1 addition & 0 deletions xml/resources-3.7.rng
Original file line number Diff line number Diff line change
Expand Up @@ -421,6 +421,7 @@
<value>service</value>
<value>systemd</value>
<value>nagios</value>
<value>dlopen</value>
</choice>
</attribute>
</choice>
Expand Down