Skip to content

Commit f16ea2e

Browse files
committed
Low: libcrmservice: Fix overrides for systemd resources
Previously, the override directory paths were valid only for systemd resources whose type attribute has no extension and thus defaults to ".service". For example, 'class="systemd" type="httpd"' works, but 'class="systemd" type="httpd.service"' results in an override directory /run/systemd/system/httpd.service.service.d. The same issue affected resources for non-service units. For example, for a resource managing unit "custom.timer", we would create an override directory /run/systemd/system/custom.timer.service.d. In these cases, the overrides would not be applied. This commit fixes that. We also ensure that the [Service] section is added only for service units. Signed-off-by: Reid Wahl <[email protected]>
1 parent 7b289c4 commit f16ea2e

File tree

1 file changed

+37
-15
lines changed

1 file changed

+37
-15
lines changed

lib/services/systemd.c

Lines changed: 37 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -807,10 +807,12 @@ unit_method_complete(DBusPendingCall *pending, void *user_data)
807807
*
808808
* @TODO Add start timeout
809809
*/
810-
#define SYSTEMD_OVERRIDE_TEMPLATE \
810+
#define SYSTEMD_UNIT_OVERRIDE_TEMPLATE \
811811
"[Unit]\n" \
812812
"Description=Cluster Controlled %s\n" \
813-
"Before=pacemaker.service pacemaker_remote.service\n" \
813+
"Before=pacemaker.service pacemaker_remote.service\n"
814+
815+
#define SYSTEMD_SERVICE_OVERRIDE \
814816
"\n" \
815817
"[Service]\n" \
816818
"Restart=no\n"
@@ -819,16 +821,16 @@ unit_method_complete(DBusPendingCall *pending, void *user_data)
819821
* \internal
820822
* \brief Get runtime drop-in directory path for a systemd unit
821823
*
822-
* \param[in] agent Systemd resource agent
824+
* \param[in] unit_name Systemd unit (with extension)
823825
*
824826
* \return Drop-in directory path
825827
*/
826828
static GString *
827-
get_override_dir(const char *agent)
829+
get_override_dir(const char *unit_name)
828830
{
829831
GString *buf = g_string_sized_new(128);
830832

831-
pcmk__g_strcat(buf, "/run/systemd/system/", agent, ".service.d", NULL);
833+
pcmk__g_strcat(buf, "/run/systemd/system/", unit_name, ".d", NULL);
832834
return buf;
833835
}
834836

@@ -861,13 +863,18 @@ append_override_basename(GString *buf)
861863
static int
862864
systemd_create_override(const char *agent, int timeout)
863865
{
866+
char *unit_name = NULL;
864867
GString *filename = NULL;
868+
GString *override = NULL;
865869
FILE *fp = NULL;
866870
int fd = 0;
867-
char *override = NULL;
868871
int rc = pcmk_rc_ok;
869872

870-
filename = get_override_dir(agent);
873+
unit_name = systemd_unit_name(agent, false);
874+
CRM_CHECK(!pcmk__str_empty(unit_name),
875+
rc = EINVAL; goto done);
876+
877+
filename = get_override_dir(unit_name);
871878
rc = pcmk__build_path(filename->str, 0755);
872879
if (rc != pcmk_rc_ok) {
873880
crm_err("Could not create systemd override directory %s: %s",
@@ -884,9 +891,7 @@ systemd_create_override(const char *agent, int timeout)
884891
goto done;
885892
}
886893

887-
/* Ensure the override file is world-readable. This is not strictly
888-
* necessary, but it avoids a systemd warning in the logs.
889-
*/
894+
// Ensure the override file is world-readable (avoid systemd warning in log)
890895
fd = fileno(fp);
891896
if ((fd < 0) || (fchmod(fd, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH) < 0)) {
892897
rc = errno;
@@ -895,8 +900,13 @@ systemd_create_override(const char *agent, int timeout)
895900
goto done;
896901
}
897902

898-
override = crm_strdup_printf(SYSTEMD_OVERRIDE_TEMPLATE, agent);
899-
if (fputs(override, fp) == EOF) {
903+
override = g_string_sized_new(2 * sizeof(SYSTEMD_UNIT_OVERRIDE_TEMPLATE));
904+
g_string_printf(override, SYSTEMD_UNIT_OVERRIDE_TEMPLATE, unit_name);
905+
if (pcmk__ends_with_ext(unit_name, ".service")) {
906+
g_string_append(override, SYSTEMD_SERVICE_OVERRIDE);
907+
}
908+
909+
if (fputs(override->str, fp) == EOF) {
900910
rc = EIO;
901911
crm_err("Cannot write to systemd override file %s", filename->str);
902912
}
@@ -915,19 +925,27 @@ systemd_create_override(const char *agent, int timeout)
915925
unlink(filename->str);
916926
}
917927

928+
free(unit_name);
918929
if (filename != NULL) {
919930
g_string_free(filename, TRUE);
920931
}
921-
free(override);
932+
if (override != NULL) {
933+
g_string_free(override, TRUE);
934+
}
922935
return rc;
923936
}
924937

925938
static void
926939
systemd_remove_override(const char *agent, int timeout)
927940
{
928-
GString *filename = get_override_dir(agent);
941+
char *unit_name = systemd_unit_name(agent, false);
942+
GString *filename = NULL;
929943

944+
CRM_CHECK(!pcmk__str_empty(unit_name), goto done);
945+
946+
filename = get_override_dir(unit_name);
930947
append_override_basename(filename);
948+
931949
if (unlink(filename->str) < 0) {
932950
int rc = errno;
933951

@@ -941,7 +959,11 @@ systemd_remove_override(const char *agent, int timeout)
941959
systemd_daemon_reload(timeout);
942960
}
943961

944-
g_string_free(filename, TRUE);
962+
done:
963+
free(unit_name);
964+
if (filename != NULL) {
965+
g_string_free(filename, TRUE);
966+
}
945967
}
946968

947969
/*!

0 commit comments

Comments
 (0)