pacemaker/0006-Refactor-libcrmcommon-move-PID-functions-to-own-file.patch
Jan Pokorný 436eae4e1e
2.0.0-0.1.rc2 - Update for new upstream tarball
... 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>
2018-04-13 18:27:39 +02:00

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