diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-06-03 13:39:29 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-06-03 13:39:29 +0000 |
commit | b41961d74fe7ff2d4d4abaca92454e87c561e49f (patch) | |
tree | b34e3826a7b649dafdbd05081140c990c96d736d /lib/services | |
parent | Releasing progress-linux version 2.1.7-1~progress7.99u1. (diff) | |
download | pacemaker-b41961d74fe7ff2d4d4abaca92454e87c561e49f.tar.xz pacemaker-b41961d74fe7ff2d4d4abaca92454e87c561e49f.zip |
Merging upstream version 2.1.8~rc1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'lib/services')
-rw-r--r-- | lib/services/Makefile.am | 2 | ||||
-rw-r--r-- | lib/services/services.c | 12 | ||||
-rw-r--r-- | lib/services/services_linux.c | 50 | ||||
-rw-r--r-- | lib/services/services_lsb.c | 191 | ||||
-rw-r--r-- | lib/services/services_nagios.c | 8 | ||||
-rw-r--r-- | lib/services/systemd.c | 65 | ||||
-rw-r--r-- | lib/services/upstart.c | 55 |
7 files changed, 227 insertions, 156 deletions
diff --git a/lib/services/Makefile.am b/lib/services/Makefile.am index 5a19003..69c8a2c 100644 --- a/lib/services/Makefile.am +++ b/lib/services/Makefile.am @@ -14,7 +14,7 @@ AM_CPPFLAGS = -I$(top_srcdir)/include lib_LTLIBRARIES = libcrmservice.la noinst_HEADERS = $(wildcard *.h) -libcrmservice_la_LDFLAGS = -version-info 32:0:4 +libcrmservice_la_LDFLAGS = -version-info 32:1:4 libcrmservice_la_CFLAGS = libcrmservice_la_CFLAGS += $(CFLAGS_HARDENED_LIB) diff --git a/lib/services/services.c b/lib/services/services.c index e438443..94a8afc 100644 --- a/lib/services/services.c +++ b/lib/services/services.c @@ -1,5 +1,5 @@ /* - * Copyright 2010-2023 the Pacemaker project contributors + * Copyright 2010-2024 the Pacemaker project contributors * * The version control history for this file may have further details. * @@ -26,7 +26,7 @@ #include <crm/services.h> #include <crm/services_internal.h> #include <crm/stonith-ng.h> -#include <crm/msg_xml.h> +#include <crm/common/xml.h> #include "services_private.h" #include "services_ocf.h" #include "services_lsb.h" @@ -357,7 +357,7 @@ services_action_create_generic(const char *exec, const char *args[]) { svc_action_t *op = new_action(); - CRM_ASSERT(op != NULL); + pcmk__mem_assert(op); op->opaque->exec = strdup(exec); op->opaque->args[0] = strdup(exec); @@ -415,10 +415,8 @@ services_alert_create(const char *id, const char *exec, int timeout, { svc_action_t *action = services_action_create_generic(exec, NULL); - action->id = strdup(id); - action->standard = strdup(PCMK_RESOURCE_CLASS_ALERT); - CRM_ASSERT((action->id != NULL) && (action->standard != NULL)); - + action->id = pcmk__str_copy(id); + action->standard = pcmk__str_copy(PCMK_RESOURCE_CLASS_ALERT); action->timeout = timeout; action->params = params; action->sequence = sequence; diff --git a/lib/services/services_linux.c b/lib/services/services_linux.c index c7792f0..971d38c 100644 --- a/lib/services/services_linux.c +++ b/lib/services/services_linux.c @@ -51,6 +51,7 @@ static void close_pipe(int fildes[]); struct sigchld_data_s { sigset_t mask; // Signals to block now (including SIGCHLD) sigset_t old_mask; // Previous set of blocked signals + bool ignored; // If SIGCHLD for another child has been ignored }; // Initialize SIGCHLD data and prepare for use @@ -68,6 +69,9 @@ sigchld_setup(struct sigchld_data_s *data) CRM_XS " source=sigprocmask", pcmk_rc_str(errno)); return false; } + + data->ignored = false; + return true; } @@ -98,7 +102,7 @@ sigchld_close(int fd) // Return true if SIGCHLD was received from polled fd static bool -sigchld_received(int fd) +sigchld_received(int fd, int pid, struct sigchld_data_s *data) { struct signalfd_siginfo fdsi; ssize_t s; @@ -112,7 +116,18 @@ sigchld_received(int fd) CRM_XS " source=read", pcmk_rc_str(errno)); } else if (fdsi.ssi_signo == SIGCHLD) { - return true; + if (fdsi.ssi_pid == pid) { + return true; + + } else { + /* This SIGCHLD is for another child. We have to ignore it here but + * will still need to resend it after this synchronous action has + * completed and SIGCHLD has been restored to be handled by the + * previous SIGCHLD handler, so that it will be handled. + */ + data->ignored = true; + return false; + } } return false; } @@ -127,6 +142,12 @@ sigchld_cleanup(struct sigchld_data_s *data) crm_warn("Could not clean up after child process completion: %s", pcmk_rc_str(errno)); } + + // Resend any ignored SIGCHLD for other children so that they'll be handled. + if (data->ignored && kill(getpid(), SIGCHLD) != 0) { + crm_warn("Could not resend ignored SIGCHLD to ourselves: %s", + pcmk_rc_str(errno)); + } } #else // HAVE_SYS_SIGNALFD_H not defined @@ -137,6 +158,7 @@ struct sigchld_data_s { int pipe_fd[2]; // Pipe file descriptors struct sigaction sa; // Signal handling info (with SIGCHLD) struct sigaction old_sa; // Previous signal handling info + bool ignored; // If SIGCHLD for another child has been ignored }; // We need a global to use in the signal handler @@ -187,6 +209,8 @@ sigchld_setup(struct sigchld_data_s *data) CRM_XS " source=sigaction", pcmk_rc_str(errno)); } + data->ignored = false; + // Remember data for use in signal handler last_sigchld_data = data; return true; @@ -207,7 +231,7 @@ sigchld_close(int fd) } static bool -sigchld_received(int fd) +sigchld_received(int fd, int pid, struct sigchld_data_s *data) { char ch; @@ -230,6 +254,12 @@ sigchld_cleanup(struct sigchld_data_s *data) } close_pipe(data->pipe_fd); + + // Resend any ignored SIGCHLD for other children so that they'll be handled. + if (data->ignored && kill(getpid(), SIGCHLD) != 0) { + crm_warn("Could not resend ignored SIGCHLD to ourselves: %s", + pcmk_rc_str(errno)); + } } #endif @@ -1054,7 +1084,8 @@ wait_for_sync_result(svc_action_t *op, struct sigchld_data_s *data) svc_read_output(op->opaque->stderr_fd, op, TRUE); } - if ((fds[2].revents & POLLIN) && sigchld_received(fds[2].fd)) { + if ((fds[2].revents & POLLIN) + && sigchld_received(fds[2].fd, op->pid, data)) { wait_rc = waitpid(op->pid, &status, WNOHANG); if ((wait_rc > 0) || ((wait_rc < 0) && (errno == ECHILD))) { @@ -1067,6 +1098,17 @@ wait_for_sync_result(svc_action_t *op, struct sigchld_data_s *data) CRM_XS " source=waitpid", op->id, op->pid, wait_reason); wait_rc = 0; // Act as if process is still running + +#ifndef HAVE_SYS_SIGNALFD_H + } else { + /* The child hasn't exited, so this SIGCHLD could be for + * another child. We have to ignore it here but will still + * need to resend it after this synchronous action has + * completed and SIGCHLD has been restored to be handled by + * the previous handler, so that it will be handled. + */ + data->ignored = true; +#endif } } diff --git a/lib/services/services_lsb.c b/lib/services/services_lsb.c index 9ad7025..83587f2 100644 --- a/lib/services/services_lsb.c +++ b/lib/services/services_lsb.c @@ -1,5 +1,5 @@ /* - * Copyright 2010-2023 the Pacemaker project contributors + * Copyright 2010-2024 the Pacemaker project contributors * * The version control history for this file may have further details. * @@ -18,63 +18,67 @@ #include <sys/stat.h> #include <crm/crm.h> +#include <crm/common/xml.h> #include <crm/services.h> #include "services_private.h" #include "services_lsb.h" +// @TODO Use XML string constants and maybe a real XML object #define lsb_metadata_template \ - "<?xml version='1.0'?>\n" \ - "<!DOCTYPE resource-agent SYSTEM 'ra-api-1.dtd'>\n" \ - "<resource-agent name='%s' version='" PCMK_DEFAULT_AGENT_VERSION "'>\n" \ - " <version>1.0</version>\n" \ - " <longdesc lang='en'>\n" \ - "%s" \ - " </longdesc>\n" \ - " <shortdesc lang='en'>%s</shortdesc>\n" \ - " <parameters>\n" \ - " </parameters>\n" \ - " <actions>\n" \ - " <action name='meta-data' timeout='5' />\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='force-reload' timeout='15' />\n" \ - " <action name='monitor' timeout='15' interval='15' />\n" \ - " </actions>\n" \ - " <special tag='LSB'>\n" \ - " <Provides>%s</Provides>\n" \ - " <Required-Start>%s</Required-Start>\n" \ - " <Required-Stop>%s</Required-Stop>\n" \ - " <Should-Start>%s</Should-Start>\n" \ - " <Should-Stop>%s</Should-Stop>\n" \ - " <Default-Start>%s</Default-Start>\n" \ - " <Default-Stop>%s</Default-Stop>\n" \ - " </special>\n" \ - "</resource-agent>\n" + "<?xml " PCMK_XA_VERSION "='1.0'?>\n" \ + "<" PCMK_XE_RESOURCE_AGENT " " \ + PCMK_XA_NAME "='%s' " \ + PCMK_XA_VERSION "='" PCMK_DEFAULT_AGENT_VERSION "'>\n" \ + " <" PCMK_XE_VERSION ">1.1</" PCMK_XE_VERSION ">\n" \ + " <" PCMK_XE_LONGDESC " " PCMK_XA_LANG "='" PCMK__VALUE_EN "'>\n" \ + "%s" \ + " </" PCMK_XE_LONGDESC ">\n" \ + " <" PCMK_XE_SHORTDESC " " PCMK_XA_LANG "='" PCMK__VALUE_EN "'>" \ + "%s" \ + "</" PCMK_XE_SHORTDESC ">\n" \ + " <" PCMK_XE_PARAMETERS "/>\n" \ + " <" PCMK_XE_ACTIONS ">\n" \ + " <" PCMK_XE_ACTION " " PCMK_XA_NAME "='" PCMK_ACTION_META_DATA "'" \ + " " PCMK_META_TIMEOUT "='5s' />\n" \ + " <" PCMK_XE_ACTION " " PCMK_XA_NAME "='" PCMK_ACTION_START "'" \ + " " PCMK_META_TIMEOUT "='15s' />\n" \ + " <" PCMK_XE_ACTION " " PCMK_XA_NAME "='" PCMK_ACTION_STOP "'" \ + " " PCMK_META_TIMEOUT "='15s' />\n" \ + " <" PCMK_XE_ACTION " " PCMK_XA_NAME "='" PCMK_ACTION_STATUS "'" \ + " " PCMK_META_TIMEOUT "='15s' />\n" \ + " <" PCMK_XE_ACTION " " PCMK_XA_NAME "='restart'" \ + " " PCMK_META_TIMEOUT "='15s' />\n" \ + " <" PCMK_XE_ACTION " " PCMK_XA_NAME "='force-reload'" \ + " " PCMK_META_TIMEOUT "='15s' />\n" \ + " <" PCMK_XE_ACTION " " PCMK_XA_NAME "='" PCMK_ACTION_MONITOR "'" \ + " " PCMK_META_TIMEOUT "='15s'" \ + " " PCMK_META_INTERVAL "='15s' />\n" \ + " </" PCMK_XE_ACTIONS ">\n" \ + " <" PCMK_XE_SPECIAL " " PCMK_XA_TAG "='LSB'>\n" \ + " <Provides>%s</Provides>\n" \ + " <Required-Start>%s</Required-Start>\n" \ + " <Required-Stop>%s</Required-Stop>\n" \ + " <Should-Start>%s</Should-Start>\n" \ + " <Should-Stop>%s</Should-Stop>\n" \ + " <Default-Start>%s</Default-Start>\n" \ + " <Default-Stop>%s</Default-Stop>\n" \ + " </" PCMK_XE_SPECIAL ">\n" \ + "</" PCMK_XE_RESOURCE_AGENT ">\n" /* See "Comment Conventions for Init Scripts" in the LSB core specification at: * http://refspecs.linuxfoundation.org/lsb.shtml */ -#define LSB_INITSCRIPT_INFOBEGIN_TAG "### BEGIN INIT INFO" -#define LSB_INITSCRIPT_INFOEND_TAG "### END INIT INFO" -#define PROVIDES "# Provides:" -#define REQ_START "# Required-Start:" -#define REQ_STOP "# Required-Stop:" -#define SHLD_START "# Should-Start:" -#define SHLD_STOP "# Should-Stop:" -#define DFLT_START "# Default-Start:" -#define DFLT_STOP "# Default-Stop:" -#define SHORT_DSCR "# Short-Description:" -#define DESCRIPTION "# Description:" - -#define lsb_meta_helper_free_value(m) \ - do { \ - if ((m) != NULL) { \ - xmlFree(m); \ - (m) = NULL; \ - } \ - } while(0) +#define LSB_INITSCRIPT_INFOBEGIN_TAG "### BEGIN INIT INFO" +#define LSB_INITSCRIPT_INFOEND_TAG "### END INIT INFO" +#define PROVIDES "# Provides:" +#define REQUIRED_START "# Required-Start:" +#define REQUIRED_STOP "# Required-Stop:" +#define SHOULD_START "# Should-Start:" +#define SHOULD_STOP "# Should-Stop:" +#define DEFAULT_START "# Default-Start:" +#define DEFAULT_STOP "# Default-Stop:" +#define SHORT_DESC "# Short-Description:" +#define DESCRIPTION "# Description:" /*! * \internal @@ -87,10 +91,13 @@ * \return TRUE if value was set, FALSE otherwise */ static inline gboolean -lsb_meta_helper_get_value(const char *line, char **value, const char *prefix) +lsb_meta_helper_get_value(const char *line, gchar **value, const char *prefix) { - if (!*value && pcmk__starts_with(line, prefix)) { - *value = (char *)xmlEncodeEntitiesReentrant(NULL, BAD_CAST line+strlen(prefix)); + /* @TODO Perhaps update later to use pcmk__xml_needs_escape(). Involves many + * extra variables in the caller. + */ + if ((*value == NULL) && pcmk__starts_with(line, prefix)) { + *value = pcmk__xml_escape(line + strlen(prefix), pcmk__xml_escape_text); return TRUE; } return FALSE; @@ -102,15 +109,15 @@ services__get_lsb_metadata(const char *type, char **output) char ra_pathname[PATH_MAX] = { 0, }; FILE *fp = NULL; char buffer[1024] = { 0, }; - char *provides = NULL; - char *req_start = NULL; - char *req_stop = NULL; - char *shld_start = NULL; - char *shld_stop = NULL; - char *dflt_start = NULL; - char *dflt_stop = NULL; - char *s_dscrpt = NULL; - char *xml_l_dscrpt = NULL; + gchar *provides = NULL; + gchar *required_start = NULL; + gchar *required_stop = NULL; + gchar *should_start = NULL; + gchar *should_stop = NULL; + gchar *default_start = NULL; + gchar *default_stop = NULL; + gchar *short_desc = NULL; + gchar *long_desc = NULL; bool in_header = FALSE; if (type[0] == '/') { @@ -142,30 +149,31 @@ services__get_lsb_metadata(const char *type, char **output) if (lsb_meta_helper_get_value(buffer, &provides, PROVIDES)) { continue; } - if (lsb_meta_helper_get_value(buffer, &req_start, REQ_START)) { + if (lsb_meta_helper_get_value(buffer, &required_start, + REQUIRED_START)) { continue; } - if (lsb_meta_helper_get_value(buffer, &req_stop, REQ_STOP)) { + if (lsb_meta_helper_get_value(buffer, &required_stop, REQUIRED_STOP)) { continue; } - if (lsb_meta_helper_get_value(buffer, &shld_start, SHLD_START)) { + if (lsb_meta_helper_get_value(buffer, &should_start, SHOULD_START)) { continue; } - if (lsb_meta_helper_get_value(buffer, &shld_stop, SHLD_STOP)) { + if (lsb_meta_helper_get_value(buffer, &should_stop, SHOULD_STOP)) { continue; } - if (lsb_meta_helper_get_value(buffer, &dflt_start, DFLT_START)) { + if (lsb_meta_helper_get_value(buffer, &default_start, DEFAULT_START)) { continue; } - if (lsb_meta_helper_get_value(buffer, &dflt_stop, DFLT_STOP)) { + if (lsb_meta_helper_get_value(buffer, &default_stop, DEFAULT_STOP)) { continue; } - if (lsb_meta_helper_get_value(buffer, &s_dscrpt, SHORT_DSCR)) { + if (lsb_meta_helper_get_value(buffer, &short_desc, SHORT_DESC)) { continue; } /* Long description may cross multiple lines */ - if ((xml_l_dscrpt == NULL) // haven't already found long description + if ((long_desc == NULL) // Haven't already found long description && pcmk__starts_with(buffer, DESCRIPTION)) { bool processed_line = TRUE; GString *desc = g_string_sized_new(2048); @@ -192,9 +200,7 @@ services__get_lsb_metadata(const char *type, char **output) } // Make long description safe to use in XML - xml_l_dscrpt = - (char *) xmlEncodeEntitiesReentrant(NULL, - (pcmkXmlStr) desc->str); + long_desc = pcmk__xml_escape(desc->str, pcmk__xml_escape_text); g_string_free(desc, TRUE); if (processed_line) { @@ -214,28 +220,25 @@ services__get_lsb_metadata(const char *type, char **output) fclose(fp); *output = crm_strdup_printf(lsb_metadata_template, type, - (xml_l_dscrpt? xml_l_dscrpt : type), - (s_dscrpt? s_dscrpt : type), - (provides? provides : ""), - (req_start? req_start : ""), - (req_stop? req_stop : ""), - (shld_start? shld_start : ""), - (shld_stop? shld_stop : ""), - (dflt_start? dflt_start : ""), - (dflt_stop? dflt_stop : "")); - - lsb_meta_helper_free_value(xml_l_dscrpt); - lsb_meta_helper_free_value(s_dscrpt); - lsb_meta_helper_free_value(provides); - lsb_meta_helper_free_value(req_start); - lsb_meta_helper_free_value(req_stop); - lsb_meta_helper_free_value(shld_start); - lsb_meta_helper_free_value(shld_stop); - lsb_meta_helper_free_value(dflt_start); - lsb_meta_helper_free_value(dflt_stop); - - crm_trace("Created fake metadata: %llu", - (unsigned long long) strlen(*output)); + pcmk__s(long_desc, type), + pcmk__s(short_desc, type), + pcmk__s(provides, ""), + pcmk__s(required_start, ""), + pcmk__s(required_stop, ""), + pcmk__s(should_start, ""), + pcmk__s(should_stop, ""), + pcmk__s(default_start, ""), + pcmk__s(default_stop, "")); + + g_free(long_desc); + g_free(short_desc); + g_free(provides); + g_free(required_start); + g_free(required_stop); + g_free(should_start); + g_free(should_stop); + g_free(default_start); + g_free(default_stop); return pcmk_ok; } diff --git a/lib/services/services_nagios.c b/lib/services/services_nagios.c index 10759b5..f4b1320 100644 --- a/lib/services/services_nagios.c +++ b/lib/services/services_nagios.c @@ -1,5 +1,5 @@ /* - * Copyright 2010-2023 the Pacemaker project contributors + * Copyright 2010-2024 the Pacemaker project contributors * * The version control history for this file may have further details. * @@ -25,7 +25,7 @@ #include <sys/resource.h> #include "crm/crm.h" -#include <crm/msg_xml.h> +#include <crm/common/xml.h> #include "crm/common/mainloop.h" #include "crm/services.h" @@ -73,7 +73,7 @@ services__nagios_prepare(svc_action_t *op) return E2BIG; } - if (pcmk__str_eq(key, XML_ATTR_CRM_VERSION, pcmk__str_casei) + if (pcmk__str_eq(key, PCMK_XA_CRM_FEATURE_SET, pcmk__str_casei) || strstr(key, CRM_META "_")) { continue; } @@ -203,7 +203,7 @@ services__get_nagios_metadata(const char *type, char **output) } else { crm_trace("Reading %d bytes from file", length); - *output = calloc(1, (length + 1)); + *output = pcmk__assert_alloc(1, (length + 1)); read_len = fread(*output, 1, length, file_strm); if (read_len != length) { crm_err("Calculated and read bytes differ: %d vs. %d", diff --git a/lib/services/systemd.c b/lib/services/systemd.c index ecac86c..0563c49 100644 --- a/lib/services/systemd.c +++ b/lib/services/systemd.c @@ -1,5 +1,5 @@ /* - * Copyright 2012-2023 the Pacemaker project contributors + * Copyright 2012-2024 the Pacemaker project contributors * * The version control history for this file may have further details. * @@ -9,6 +9,7 @@ #include <crm_internal.h> #include <crm/crm.h> +#include <crm/common/xml.h> #include <crm/services.h> #include <crm/services_internal.h> #include <crm/common/mainloop.h> @@ -663,25 +664,35 @@ systemd_unit_exists(const char *name) return FALSE; } -#define METADATA_FORMAT \ - "<?xml version=\"1.0\"?>\n" \ - "<!DOCTYPE resource-agent SYSTEM \"ra-api-1.dtd\">\n" \ - "<resource-agent name=\"%s\" version=\"" PCMK_DEFAULT_AGENT_VERSION "\">\n" \ - " <version>1.1</version>\n" \ - " <longdesc lang=\"en\">\n" \ - " %s\n" \ - " </longdesc>\n" \ - " <shortdesc lang=\"en\">systemd unit file for %s</shortdesc>\n" \ - " <parameters/>\n" \ - " <actions>\n" \ - " <action name=\"start\" timeout=\"100\" />\n" \ - " <action name=\"stop\" timeout=\"100\" />\n" \ - " <action name=\"status\" timeout=\"100\" />\n" \ - " <action name=\"monitor\" timeout=\"100\" interval=\"60\"/>\n" \ - " <action name=\"meta-data\" timeout=\"5\" />\n" \ - " </actions>\n" \ - " <special tag=\"systemd\"/>\n" \ - "</resource-agent>\n" +// @TODO Use XML string constants and maybe a real XML object +#define METADATA_FORMAT \ + "<?xml " PCMK_XA_VERSION "=\"1.0\"?>\n" \ + "<" PCMK_XE_RESOURCE_AGENT " " \ + PCMK_XA_NAME "=\"%s\" " \ + PCMK_XA_VERSION "=\"" PCMK_DEFAULT_AGENT_VERSION "\">\n" \ + " <" PCMK_XE_VERSION ">1.1</" PCMK_XE_VERSION ">\n" \ + " <" PCMK_XE_LONGDESC " " PCMK_XA_LANG "=\"" PCMK__VALUE_EN "\">\n" \ + " %s\n" \ + " </" PCMK_XE_LONGDESC ">\n" \ + " <" PCMK_XE_SHORTDESC " " PCMK_XA_LANG "=\"" PCMK__VALUE_EN "\">" \ + "systemd unit file for %s" \ + "</" PCMK_XE_SHORTDESC ">\n" \ + " <" PCMK_XE_PARAMETERS "/>\n" \ + " <" PCMK_XE_ACTIONS ">\n" \ + " <" PCMK_XE_ACTION " " PCMK_XA_NAME "=\"" PCMK_ACTION_START "\"" \ + " " PCMK_META_TIMEOUT "=\"100s\" />\n" \ + " <" PCMK_XE_ACTION " " PCMK_XA_NAME "=\"" PCMK_ACTION_STOP "\"" \ + " " PCMK_META_TIMEOUT "=\"100s\" />\n" \ + " <" PCMK_XE_ACTION " " PCMK_XA_NAME "=\"" PCMK_ACTION_STATUS "\"" \ + " " PCMK_META_TIMEOUT "=\"100s\" />\n" \ + " <" PCMK_XE_ACTION " " PCMK_XA_NAME "=\"" PCMK_ACTION_MONITOR "\"" \ + " " PCMK_META_TIMEOUT "=\"100s\"" \ + " " PCMK_META_INTERVAL "=\"60s\" />\n" \ + " <" PCMK_XE_ACTION " " PCMK_XA_NAME "=\"" PCMK_ACTION_META_DATA "\"" \ + " " PCMK_META_TIMEOUT "=\"5s\" />\n" \ + " </" PCMK_XE_ACTIONS ">\n" \ + " <" PCMK_XE_SPECIAL " " PCMK_XA_TAG "=\"systemd\"/>\n" \ + "</" PCMK_XE_RESOURCE_AGENT ">\n" static char * systemd_unit_metadata(const char *name, int timeout) @@ -690,8 +701,6 @@ systemd_unit_metadata(const char *name, int timeout) char *desc = NULL; char *path = NULL; - char *escaped = NULL; - if (invoke_unit_by_name(name, NULL, &path) == pcmk_rc_ok) { /* TODO: Worth a making blocking call for? Probably not. Possibly if cached. */ desc = systemd_get_property(path, "Description", NULL, NULL, NULL, @@ -700,12 +709,18 @@ systemd_unit_metadata(const char *name, int timeout) desc = crm_strdup_printf("Systemd unit file for %s", name); } - escaped = crm_xml_escape(desc); + if (pcmk__xml_needs_escape(desc, pcmk__xml_escape_text)) { + gchar *escaped = pcmk__xml_escape(desc, pcmk__xml_escape_text); + + meta = crm_strdup_printf(METADATA_FORMAT, name, escaped, name); + g_free(escaped); + + } else { + meta = crm_strdup_printf(METADATA_FORMAT, name, desc, name); + } - meta = crm_strdup_printf(METADATA_FORMAT, name, escaped, name); free(desc); free(path); - free(escaped); return meta; } diff --git a/lib/services/upstart.c b/lib/services/upstart.c index 2306e73..b6f58f4 100644 --- a/lib/services/upstart.c +++ b/lib/services/upstart.c @@ -1,7 +1,7 @@ /* * Original copyright 2010 Senko Rasic <senko.rasic@dobarkod.hr> * and Ante Karamatic <ivoks@init.hr> - * Later changes copyright 2012-2023 the Pacemaker project contributors + * Later changes copyright 2012-2024 the Pacemaker project contributors * * The version control history for this file may have further details. * @@ -14,6 +14,7 @@ #include <stdio.h> #include <crm/crm.h> +#include <crm/common/xml.h> #include <crm/services.h> #include <crm/common/mainloop.h> @@ -370,26 +371,38 @@ parse_status_result(const char *name, const char *state, void *userdata) } } -#define METADATA_FORMAT \ - "<?xml version=\"1.0\"?>\n" \ - "<!DOCTYPE resource-agent SYSTEM \"ra-api-1.dtd\">\n" \ - "<resource-agent name=\"%s\" version=\"" PCMK_DEFAULT_AGENT_VERSION "\">\n" \ - " <version>1.1</version>\n" \ - " <longdesc lang=\"en\">\n" \ - " Upstart agent for controlling the system %s service\n" \ - " </longdesc>\n" \ - " <shortdesc lang=\"en\">Upstart job for %s</shortdesc>\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" \ - "</resource-agent>\n" +// @TODO Use XML string constants and maybe a real XML object +#define METADATA_FORMAT \ + "<?xml " PCMK_XA_VERSION "=\"1.0\"?>\n" \ + "<" PCMK_XE_RESOURCE_AGENT " " \ + PCMK_XA_NAME "=\"%s\" " \ + PCMK_XA_VERSION "=\"" PCMK_DEFAULT_AGENT_VERSION "\">\n" \ + " <" PCMK_XE_VERSION ">1.1</" PCMK_XE_VERSION ">\n" \ + " <" PCMK_XE_LONGDESC " " PCMK_XA_LANG "=\"" PCMK__VALUE_EN "\">\n" \ + " Upstart agent for controlling the system %s service\n" \ + " </" PCMK_XE_LONGDESC ">\n" \ + " <" PCMK_XE_SHORTDESC " " PCMK_XA_LANG "=\"" PCMK__VALUE_EN "\">" \ + "Upstart job for %s" \ + "</" PCMK_XE_SHORTDESC ">\n" \ + " <" PCMK_XE_PARAMETERS "/>\n" \ + " <" PCMK_XE_ACTIONS ">\n" \ + " <" PCMK_XE_ACTION " " PCMK_XA_NAME "=\"" PCMK_ACTION_START "\"" \ + " " PCMK_META_TIMEOUT "=\"15s\" />\n" \ + " <" PCMK_XE_ACTION " " PCMK_XA_NAME "=\"" PCMK_ACTION_STOP "\"" \ + " " PCMK_META_TIMEOUT "=\"15s\" />\n" \ + " <" PCMK_XE_ACTION " " PCMK_XA_NAME "=\"" PCMK_ACTION_STATUS "\"" \ + " " PCMK_META_TIMEOUT "=\"15s\" />\n" \ + " <" PCMK_XE_ACTION " " PCMK_XA_NAME "=\"restart\"" \ + " " PCMK_META_TIMEOUT "=\"15s\" />\n" \ + " <" PCMK_XE_ACTION " " PCMK_XA_NAME "=\"" PCMK_ACTION_MONITOR "\"" \ + " " PCMK_META_TIMEOUT "=\"15s\"" \ + " " PCMK_META_INTERVAL "=\"15s\"" \ + " " PCMK_META_START_DELAY "=\"15s\" />\n" \ + " <" PCMK_XE_ACTION " " PCMK_XA_NAME "=\"" PCMK_ACTION_META_DATA "\"" \ + " " PCMK_META_TIMEOUT "=\"5s\" />\n" \ + " </" PCMK_XE_ACTIONS ">\n" \ + " <" PCMK_XE_SPECIAL " " PCMK_XA_TAG "=\"upstart\"/>\n" \ + "</" PCMK_XE_RESOURCE_AGENT ">\n" static char * upstart_job_metadata(const char *name) |