... for release candidate: Pacemaker-2.0.0-rc2, for full details, see included ChangeLog file or https://github.com/ClusterLabs/pacemaker/releases/tag/Pacemaker-2.0.0-rc2 Adapt spec file more akin to upstream version including: . out-of-tree change from 1.1.18-2 build got subsumed (508ad52e7) . %%{_sysconfdir}/pacemaker path got properly owned (-cli package; f6e3ab98d) . -libs package started to properly declare Requires(pre): shadow-utils (293fcc1e8 + b3d49d210) . some build conditionals and dependencies dropped for no longer (snmp, esmtp; f24bdc6f2 and 1f7374884, respectively) or never being relevant (~bison, byacc, flex; 61aef8af4) . some dependencies were constrained with new or higher lower bounds: corosync needs to be of version 2+ unconditionally (ccd58fe29), ditto some others components (~GLib, 1ac2e7cbb), plus both 2 and 3 versions of Python are now (comprehensively for the auxiliary functionality where used) supported upstream with the latter being a better fit (453355f8f) . package descriptions got to reflect the drop of legacy low-level cluster infrastructures (55ab749bf) Adapt spec file akin to current packaging guidelines including: . drop some redundant/futile expressions (defattr, "-n %%{name}-libs" instead of plain "libs", "timezone hack"), add some notes for future . make -cts and -doc packages noarch (former enabled with 088a5e7d4) . simplify "systemd_requires" macro invocation, and relax it to "systemd_ordering" for -remote package where possible so as not to drag systemd into a lightweight system setup (e.g. container) needlessly . adjust, in a compatible way, common ldconfig invocation with post{,un} scriptlets (https://fedoraproject.org/wiki/Changes/Removing_ldconfig_scriptlets) . drop some more unuseful conditionals (upstart_job) Apply some regression fixes on top as patches (PR #1457, #1459) Signed-off-by: Jan Pokorný <jpokorny@redhat.com>
512 lines
15 KiB
Diff
512 lines
15 KiB
Diff
From c7abf9bc0b3596b41981ee10af60c24a68287e78 Mon Sep 17 00:00:00 2001
|
|
From: Ken Gaillot <kgaillot@redhat.com>
|
|
Date: Mon, 9 Apr 2018 14:15:23 -0500
|
|
Subject: [PATCH 06/17] Refactor: libcrmcommon: move PID functions to own file
|
|
|
|
Line counts before:
|
|
1515 lib/common/utils.c
|
|
|
|
and after:
|
|
1353 lib/common/utils.c
|
|
183 lib/common/pid.c
|
|
---
|
|
include/crm/common/internal.h | 26 ++---
|
|
include/crm_internal.h | 23 +----
|
|
lib/common/Makefile.am | 19 +---
|
|
lib/common/pid.c | 183 ++++++++++++++++++++++++++++++++++
|
|
lib/common/utils.c | 162 ------------------------------
|
|
5 files changed, 201 insertions(+), 212 deletions(-)
|
|
create mode 100644 lib/common/pid.c
|
|
|
|
diff --git a/include/crm/common/internal.h b/include/crm/common/internal.h
|
|
index 076b9f60b..064e983b6 100644
|
|
--- a/include/crm/common/internal.h
|
|
+++ b/include/crm/common/internal.h
|
|
@@ -1,20 +1,8 @@
|
|
/*
|
|
- * Copyright (C) 2015
|
|
- * Andrew Beekhof <andrew@beekhof.net>
|
|
+ * Copyright 2015-2018 Andrew Beekhof <andrew@beekhof.net>
|
|
*
|
|
- * This program is free software; you can redistribute it and/or modify
|
|
- * it under the terms of the GNU Lesser General Public License as published by
|
|
- * the Free Software Foundation; either version 2 of the License, or
|
|
- * (at your option) any later version.
|
|
- *
|
|
- * This program 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 Lesser General Public License for more details.
|
|
- *
|
|
- * You should have received a copy of the GNU Lesser General Public
|
|
- * License along with this library; if not, write to the Free Software
|
|
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
+ * This source code is licensed under the GNU Lesser General Public License
|
|
+ * version 2.1 or later (LGPLv2.1+) WITHOUT ANY WARRANTY.
|
|
*/
|
|
|
|
#ifndef CRM_COMMON_INTERNAL__H
|
|
@@ -59,6 +47,14 @@ void crm_schema_init(void);
|
|
void crm_schema_cleanup(void);
|
|
|
|
|
|
+/* internal functions related to process IDs (from pid.c) */
|
|
+
|
|
+int crm_pid_active(long pid, const char *daemon);
|
|
+long crm_pidfile_inuse(const char *filename, long mypid, const char *daemon);
|
|
+long crm_read_pidfile(const char *filename);
|
|
+int crm_lock_pidfile(const char *filename, const char *name);
|
|
+
|
|
+
|
|
/* internal generic string functions (from strings.c) */
|
|
|
|
long long crm_int_helper(const char *text, char **end_text);
|
|
diff --git a/include/crm_internal.h b/include/crm_internal.h
|
|
index 4c6fb0d4a..78d947905 100644
|
|
--- a/include/crm_internal.h
|
|
+++ b/include/crm_internal.h
|
|
@@ -1,22 +1,8 @@
|
|
-/* crm_internal.h */
|
|
-
|
|
/*
|
|
- * Copyright (C) 2006 - 2008
|
|
- * Andrew Beekhof <andrew@beekhof.net>
|
|
- *
|
|
- * This program is free software; you can redistribute it and/or modify
|
|
- * it under the terms of the GNU Lesser General Public License as published by
|
|
- * the Free Software Foundation; either version 2 of the License, or
|
|
- * (at your option) any later version.
|
|
- *
|
|
- * This program 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 Lesser General Public License for more details.
|
|
+ * Copyright 2006-2018 Andrew Beekhof <andrew@beekhof.net>
|
|
*
|
|
- * You should have received a copy of the GNU Lesser General Public
|
|
- * License along with this library; if not, write to the Free Software
|
|
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
+ * This source code is licensed under the GNU Lesser General Public License
|
|
+ * version 2.1 or later (LGPLv2.1+) WITHOUT ANY WARRANTY.
|
|
*/
|
|
|
|
#ifndef CRM_INTERNAL__H
|
|
@@ -141,7 +127,6 @@ extern int node_score_green;
|
|
extern int node_score_yellow;
|
|
|
|
/* Assorted convenience functions */
|
|
-int crm_pid_active(long pid, const char *daemon);
|
|
void crm_make_daemon(const char *name, gboolean daemonize, const char *pidfile);
|
|
|
|
/* from operations.c */
|
|
@@ -251,8 +236,6 @@ void strip_text_nodes(xmlNode * xml);
|
|
void pcmk_panic(const char *origin);
|
|
void sysrq_init(void);
|
|
pid_t pcmk_locate_sbd(void);
|
|
-long crm_pidfile_inuse(const char *filename, long mypid, const char *daemon);
|
|
-long crm_read_pidfile(const char *filename);
|
|
|
|
# define crm_config_err(fmt...) { crm_config_error = TRUE; crm_err(fmt); }
|
|
# define crm_config_warn(fmt...) { crm_config_warning = TRUE; crm_warn(fmt); }
|
|
diff --git a/lib/common/Makefile.am b/lib/common/Makefile.am
|
|
index 1fce0b927..7546fe9fc 100644
|
|
--- a/lib/common/Makefile.am
|
|
+++ b/lib/common/Makefile.am
|
|
@@ -1,19 +1,8 @@
|
|
#
|
|
-# Copyright (C) 2004 Andrew Beekhof
|
|
+# Copyright 2004-2018 Andrew Beekhof <andrew@beekhof.net>
|
|
#
|
|
-# 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
|
|
-# of the License, or (at your option) any later version.
|
|
-#
|
|
-# This program 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 program; if not, write to the Free Software
|
|
-# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
+# This source code is licensed under the GNU General Public License version 2
|
|
+# or later (GPLv2+) WITHOUT ANY WARRANTY.
|
|
#
|
|
include $(top_srcdir)/Makefile.common
|
|
|
|
@@ -40,7 +29,7 @@ libcrmcommon_la_LIBADD = @LIBADD_DL@ $(GNUTLSLIBS)
|
|
libcrmcommon_la_SOURCES = compat.c digest.c ipc.c io.c procfs.c utils.c xml.c \
|
|
iso8601.c remote.c mainloop.c logging.c watchdog.c \
|
|
schemas.c strings.c xpath.c attrd_client.c alerts.c \
|
|
- operations.c results.c
|
|
+ operations.c pid.c results.c
|
|
if BUILD_CIBSECRETS
|
|
libcrmcommon_la_SOURCES += cib_secrets.c
|
|
endif
|
|
diff --git a/lib/common/pid.c b/lib/common/pid.c
|
|
new file mode 100644
|
|
index 000000000..803799e64
|
|
--- /dev/null
|
|
+++ b/lib/common/pid.c
|
|
@@ -0,0 +1,183 @@
|
|
+/*
|
|
+ * Copyright 2004-2018 Andrew Beekhof <andrew@beekhof.net>
|
|
+ *
|
|
+ * This source code is licensed under the GNU Lesser General Public License
|
|
+ * version 2.1 or later (LGPLv2.1+) WITHOUT ANY WARRANTY.
|
|
+ */
|
|
+
|
|
+#include <crm_internal.h>
|
|
+
|
|
+#ifndef _GNU_SOURCE
|
|
+# define _GNU_SOURCE
|
|
+#endif
|
|
+
|
|
+#include <stdio.h>
|
|
+#include <string.h>
|
|
+#include <sys/stat.h>
|
|
+
|
|
+#include <crm/crm.h>
|
|
+
|
|
+int
|
|
+crm_pid_active(long pid, const char *daemon)
|
|
+{
|
|
+ static int have_proc_pid = 0;
|
|
+
|
|
+ if (have_proc_pid == 0) {
|
|
+ char proc_path[PATH_MAX], exe_path[PATH_MAX];
|
|
+
|
|
+ // Make sure pid hasn't been reused by another process
|
|
+ snprintf(proc_path, sizeof(proc_path), "/proc/%lu/exe",
|
|
+ (long unsigned int)getpid());
|
|
+
|
|
+ have_proc_pid = 1;
|
|
+ if (readlink(proc_path, exe_path, PATH_MAX - 1) < 0) {
|
|
+ have_proc_pid = -1;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ if (pid <= 0) {
|
|
+ return -1;
|
|
+
|
|
+ } else if ((kill(pid, 0) < 0) && (errno == ESRCH)) {
|
|
+ return 0;
|
|
+
|
|
+ } else if ((daemon == NULL) || (have_proc_pid == -1)) {
|
|
+ return 1;
|
|
+
|
|
+ } else {
|
|
+ int rc = 0;
|
|
+ char proc_path[PATH_MAX], exe_path[PATH_MAX], myexe_path[PATH_MAX];
|
|
+
|
|
+ // Make sure pid hasn't been reused by another process
|
|
+ snprintf(proc_path, sizeof(proc_path), "/proc/%ld/exe", pid);
|
|
+
|
|
+ rc = readlink(proc_path, exe_path, PATH_MAX - 1);
|
|
+ if ((rc < 0) && (errno == EACCES)) {
|
|
+ crm_perror(LOG_INFO, "Could not read from %s", proc_path);
|
|
+ return 1;
|
|
+ } else if (rc < 0) {
|
|
+ crm_perror(LOG_ERR, "Could not read from %s", proc_path);
|
|
+ return 0;
|
|
+ }
|
|
+
|
|
+ exe_path[rc] = 0;
|
|
+
|
|
+ if (daemon[0] != '/') {
|
|
+ rc = snprintf(myexe_path, sizeof(proc_path), CRM_DAEMON_DIR"/%s",
|
|
+ daemon);
|
|
+ myexe_path[rc] = 0;
|
|
+ } else {
|
|
+ rc = snprintf(myexe_path, sizeof(proc_path), "%s", daemon);
|
|
+ myexe_path[rc] = 0;
|
|
+ }
|
|
+
|
|
+ if (strcmp(exe_path, myexe_path) == 0) {
|
|
+ return 1;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+#define LOCKSTRLEN 11
|
|
+
|
|
+long
|
|
+crm_read_pidfile(const char *filename)
|
|
+{
|
|
+ int fd;
|
|
+ struct stat sbuf;
|
|
+ long pid = -ENOENT;
|
|
+ char buf[LOCKSTRLEN + 1];
|
|
+
|
|
+ fd = open(filename, O_RDONLY);
|
|
+ if (fd < 0) {
|
|
+ goto bail;
|
|
+ }
|
|
+
|
|
+ if ((fstat(fd, &sbuf) >= 0) && (sbuf.st_size < LOCKSTRLEN)) {
|
|
+ sleep(2); /* if someone was about to create one,
|
|
+ * give'm a sec to do so
|
|
+ */
|
|
+ }
|
|
+
|
|
+ if (read(fd, buf, sizeof(buf)) < 1) {
|
|
+ goto bail;
|
|
+ }
|
|
+
|
|
+ if (sscanf(buf, "%ld", &pid) > 0) {
|
|
+ if (pid <= 0) {
|
|
+ pid = -ESRCH;
|
|
+ } else {
|
|
+ crm_trace("Got pid %lu from %s\n", pid, filename);
|
|
+ }
|
|
+ }
|
|
+
|
|
+ bail:
|
|
+ if (fd >= 0) {
|
|
+ close(fd);
|
|
+ }
|
|
+ return pid;
|
|
+}
|
|
+
|
|
+long
|
|
+crm_pidfile_inuse(const char *filename, long mypid, const char *daemon)
|
|
+{
|
|
+ long pid = crm_read_pidfile(filename);
|
|
+
|
|
+ if (pid < 2) {
|
|
+ // Invalid pid
|
|
+ pid = -ENOENT;
|
|
+ unlink(filename);
|
|
+
|
|
+ } else if (mypid && (pid == mypid)) {
|
|
+ // In use by us
|
|
+ pid = pcmk_ok;
|
|
+
|
|
+ } else if (crm_pid_active(pid, daemon) == FALSE) {
|
|
+ // Contains a stale value
|
|
+ unlink(filename);
|
|
+ pid = -ENOENT;
|
|
+
|
|
+ } else if (mypid && (pid != mypid)) {
|
|
+ // Locked by existing process
|
|
+ pid = -EEXIST;
|
|
+ }
|
|
+
|
|
+ return pid;
|
|
+}
|
|
+
|
|
+int
|
|
+crm_lock_pidfile(const char *filename, const char *name)
|
|
+{
|
|
+ long mypid = 0;
|
|
+ int fd = 0;
|
|
+ int rc = 0;
|
|
+ char buf[LOCKSTRLEN + 2];
|
|
+
|
|
+ mypid = (unsigned long) getpid();
|
|
+
|
|
+ rc = crm_pidfile_inuse(filename, 0, name);
|
|
+ if (rc == -ENOENT) {
|
|
+ // Exists, but the process is not active
|
|
+
|
|
+ } else if (rc != pcmk_ok) {
|
|
+ // Locked by existing process
|
|
+ return rc;
|
|
+ }
|
|
+
|
|
+ fd = open(filename, O_CREAT | O_WRONLY | O_EXCL, 0644);
|
|
+ if (fd < 0) {
|
|
+ return -errno;
|
|
+ }
|
|
+
|
|
+ snprintf(buf, sizeof(buf), "%*ld\n", LOCKSTRLEN - 1, mypid);
|
|
+ rc = write(fd, buf, LOCKSTRLEN);
|
|
+ close(fd);
|
|
+
|
|
+ if (rc != LOCKSTRLEN) {
|
|
+ crm_perror(LOG_ERR, "Incomplete write to %s", filename);
|
|
+ return -errno;
|
|
+ }
|
|
+
|
|
+ return crm_pidfile_inuse(filename, mypid, name);
|
|
+}
|
|
diff --git a/lib/common/utils.c b/lib/common/utils.c
|
|
index 582838e46..07ba1b7d1 100644
|
|
--- a/lib/common/utils.c
|
|
+++ b/lib/common/utils.c
|
|
@@ -681,168 +681,6 @@ crm_abort(const char *file, const char *function, int line,
|
|
crm_perror(LOG_ERR, "Cannot wait on forked child %d", pid);
|
|
}
|
|
|
|
-int
|
|
-crm_pid_active(long pid, const char *daemon)
|
|
-{
|
|
- static int have_proc_pid = 0;
|
|
-
|
|
- if(have_proc_pid == 0) {
|
|
- char proc_path[PATH_MAX], exe_path[PATH_MAX];
|
|
-
|
|
- /* check to make sure pid hasn't been reused by another process */
|
|
- snprintf(proc_path, sizeof(proc_path), "/proc/%lu/exe", (long unsigned int)getpid());
|
|
-
|
|
- have_proc_pid = 1;
|
|
- if(readlink(proc_path, exe_path, PATH_MAX - 1) < 0) {
|
|
- have_proc_pid = -1;
|
|
- }
|
|
- }
|
|
-
|
|
- if (pid <= 0) {
|
|
- return -1;
|
|
-
|
|
- } else if (kill(pid, 0) < 0 && errno == ESRCH) {
|
|
- return 0;
|
|
-
|
|
- } else if(daemon == NULL || have_proc_pid == -1) {
|
|
- return 1;
|
|
-
|
|
- } else {
|
|
- int rc = 0;
|
|
- char proc_path[PATH_MAX], exe_path[PATH_MAX], myexe_path[PATH_MAX];
|
|
-
|
|
- /* check to make sure pid hasn't been reused by another process */
|
|
- snprintf(proc_path, sizeof(proc_path), "/proc/%ld/exe", pid);
|
|
-
|
|
- rc = readlink(proc_path, exe_path, PATH_MAX - 1);
|
|
- if (rc < 0 && errno == EACCES) {
|
|
- crm_perror(LOG_INFO, "Could not read from %s", proc_path);
|
|
- return 1;
|
|
- } else if (rc < 0) {
|
|
- crm_perror(LOG_ERR, "Could not read from %s", proc_path);
|
|
- return 0;
|
|
- }
|
|
-
|
|
-
|
|
- exe_path[rc] = 0;
|
|
-
|
|
- if(daemon[0] != '/') {
|
|
- rc = snprintf(myexe_path, sizeof(proc_path), CRM_DAEMON_DIR"/%s", daemon);
|
|
- myexe_path[rc] = 0;
|
|
- } else {
|
|
- rc = snprintf(myexe_path, sizeof(proc_path), "%s", daemon);
|
|
- myexe_path[rc] = 0;
|
|
- }
|
|
-
|
|
- if (strcmp(exe_path, myexe_path) == 0) {
|
|
- return 1;
|
|
- }
|
|
- }
|
|
-
|
|
- return 0;
|
|
-}
|
|
-
|
|
-#define LOCKSTRLEN 11
|
|
-
|
|
-long
|
|
-crm_read_pidfile(const char *filename)
|
|
-{
|
|
- int fd;
|
|
- struct stat sbuf;
|
|
- long pid = -ENOENT;
|
|
- char buf[LOCKSTRLEN + 1];
|
|
-
|
|
- if ((fd = open(filename, O_RDONLY)) < 0) {
|
|
- goto bail;
|
|
- }
|
|
-
|
|
- if (fstat(fd, &sbuf) >= 0 && sbuf.st_size < LOCKSTRLEN) {
|
|
- sleep(2); /* if someone was about to create one,
|
|
- * give'm a sec to do so
|
|
- */
|
|
- }
|
|
-
|
|
- if (read(fd, buf, sizeof(buf)) < 1) {
|
|
- goto bail;
|
|
- }
|
|
-
|
|
- if (sscanf(buf, "%ld", &pid) > 0) {
|
|
- if (pid <= 0) {
|
|
- pid = -ESRCH;
|
|
- } else {
|
|
- crm_trace("Got pid %lu from %s\n", pid, filename);
|
|
- }
|
|
- }
|
|
-
|
|
- bail:
|
|
- if (fd >= 0) {
|
|
- close(fd);
|
|
- }
|
|
- return pid;
|
|
-}
|
|
-
|
|
-long
|
|
-crm_pidfile_inuse(const char *filename, long mypid, const char *daemon)
|
|
-{
|
|
- long pid = crm_read_pidfile(filename);
|
|
-
|
|
- if (pid < 2) {
|
|
- /* Invalid pid */
|
|
- pid = -ENOENT;
|
|
- unlink(filename);
|
|
-
|
|
- } else if (mypid && pid == mypid) {
|
|
- /* In use by us */
|
|
- pid = pcmk_ok;
|
|
-
|
|
- } else if (crm_pid_active(pid, daemon) == FALSE) {
|
|
- /* Contains a stale value */
|
|
- unlink(filename);
|
|
- pid = -ENOENT;
|
|
-
|
|
- } else if (mypid && pid != mypid) {
|
|
- /* locked by existing process - give up */
|
|
- pid = -EEXIST;
|
|
- }
|
|
-
|
|
- return pid;
|
|
-}
|
|
-
|
|
-static int
|
|
-crm_lock_pidfile(const char *filename, const char *name)
|
|
-{
|
|
- long mypid = 0;
|
|
- int fd = 0, rc = 0;
|
|
- char buf[LOCKSTRLEN + 2];
|
|
-
|
|
- mypid = (unsigned long)getpid();
|
|
-
|
|
- rc = crm_pidfile_inuse(filename, 0, name);
|
|
- if (rc == -ENOENT) {
|
|
- /* exists but the process is not active */
|
|
-
|
|
- } else if (rc != pcmk_ok) {
|
|
- /* locked by existing process - give up */
|
|
- return rc;
|
|
- }
|
|
-
|
|
- if ((fd = open(filename, O_CREAT | O_WRONLY | O_EXCL, 0644)) < 0) {
|
|
- /* Hmmh, why did we fail? Anyway, nothing we can do about it */
|
|
- return -errno;
|
|
- }
|
|
-
|
|
- snprintf(buf, sizeof(buf), "%*ld\n", LOCKSTRLEN - 1, mypid);
|
|
- rc = write(fd, buf, LOCKSTRLEN);
|
|
- close(fd);
|
|
-
|
|
- if (rc != LOCKSTRLEN) {
|
|
- crm_perror(LOG_ERR, "Incomplete write to %s", filename);
|
|
- return -errno;
|
|
- }
|
|
-
|
|
- return crm_pidfile_inuse(filename, mypid, name);
|
|
-}
|
|
-
|
|
void
|
|
crm_make_daemon(const char *name, gboolean daemonize, const char *pidfile)
|
|
{
|
|
--
|
|
2.17.0
|
|
|