16 #include <sys/types.h> 19 #include <sys/utsname.h> 32 #include <qb/qbdefs.h> 42 #include <libxml2/libxml/relaxng.h> 58 if (user == NULL || group == NULL) {
63 while ((grent = getgrent()) != NULL) {
64 if (grent->gr_mem == NULL) {
68 if(strcmp(group, grent->gr_name) != 0) {
72 gr_mem = grent->gr_mem;
73 while (*gr_mem != NULL) {
74 if (!strcmp(user, *gr_mem++)) {
90 struct passwd *pwentry = NULL;
100 *uid = pwentry->pw_uid;
103 *gid = pwentry->pw_gid;
105 crm_trace(
"User %s has uid=%d gid=%d",
name, pwentry->pw_uid, pwentry->pw_gid);
108 rc = rc? -rc : -EINVAL;
127 static uid_t daemon_uid;
128 static gid_t daemon_gid;
129 static bool found =
false;
157 version_helper(
const char *text,
const char **end_text)
159 int atoi_result = -1;
165 if (text != NULL && text[0] != 0) {
172 atoi_result = (int) strtol(text, (
char **) end_text, 10);
174 if (errno == EINVAL) {
175 crm_err(
"Conversion of '%s' %c failed", text, text[0]);
192 const char *ver1_iter, *ver2_iter;
194 if (version1 == NULL && version2 == NULL) {
196 }
else if (version1 == NULL) {
198 }
else if (version2 == NULL) {
202 ver1_iter = version1;
203 ver2_iter = version2;
211 if (ver1_iter == ver2_iter) {
215 if (ver1_iter != NULL) {
216 digit1 = version_helper(ver1_iter, &ver1_iter);
219 if (ver2_iter != NULL) {
220 digit2 = version_helper(ver2_iter, &ver2_iter);
223 if (digit1 < digit2) {
227 }
else if (digit1 > digit2) {
232 if (ver1_iter != NULL && *ver1_iter ==
'.') {
235 if (ver1_iter != NULL && *ver1_iter ==
'\0') {
239 if (ver2_iter != NULL && *ver2_iter ==
'.') {
242 if (ver2_iter != NULL && *ver2_iter == 0) {
248 crm_trace(
"%s == %s (%d)", version1, version2, lpc);
250 crm_trace(
"%s < %s (%d)", version1, version2, lpc);
252 crm_trace(
"%s > %s (%d)", version1, version2, lpc);
268 log_assertion_as(
const char *file,
const char *
function,
int line,
269 const char *assert_condition)
274 crm_err(
"%s: Triggered fatal assertion at %s:%d : %s",
275 function, file, line, assert_condition);
291 abort_as(
const char *file,
const char *
function,
int line,
292 const char *assert_condition)
294 log_assertion_as(file,
function, line, assert_condition);
312 fail_assert_as(
const char *file,
const char *
function,
int line,
313 const char *assert_condition)
319 abort_as(file,
function, line, assert_condition);
325 crm_warn(
"%s: Cannot dump core for non-fatal assertion at %s:%d " 326 ": %s",
function, file, line, assert_condition);
334 crm_err(
"%s: Forked child [%d] to record non-fatal assertion at " 335 "%s:%d : %s",
function,
pid, file, line, assert_condition);
338 if (waitpid(
pid, &status, 0) ==
pid) {
341 }
while (errno == EINTR);
342 if (errno == ECHILD) {
344 crm_trace(
"Cannot wait on forked child [%d] " 345 "(SIGCHLD is probably ignored)",
pid);
347 crm_err(
"Cannot wait on forked child [%d]: %s",
356 crm_abort(
const char *file,
const char *
function,
int line,
357 const char *assert_condition, gboolean do_core, gboolean do_fork)
360 abort_as(file,
function, line, assert_condition);
361 }
else if (do_core) {
362 fail_assert_as(file,
function, line, assert_condition);
364 log_assertion_as(file,
function, line, assert_condition);
388 crm_err(
"%s: already running [pid %lld in %s]",
389 name, (
long long)
pid, pidfile);
390 printf(
"%s: already running [pid %lld in %s]\n",
391 name, (
long long)
pid, pidfile);
397 fprintf(stderr,
"%s: could not start daemon\n",
name);
401 }
else if (
pid > 0) {
409 printf(
"Could not lock '%s' for %s: %s (%d)\n",
414 umask(S_IWGRP | S_IWOTH | S_IROTH);
417 pcmk__open_devnull(O_RDONLY);
419 close(STDOUT_FILENO);
420 pcmk__open_devnull(O_WRONLY);
422 close(STDERR_FILENO);
423 pcmk__open_devnull(O_WRONLY);
426 #ifdef HAVE_UUID_UUID_H 427 # include <uuid/uuid.h> 433 unsigned char uuid[16];
434 char *buffer = malloc(37);
438 uuid_unparse(uuid, buffer);
442 #ifdef HAVE_GNUTLS_GNUTLS_H 444 crm_gnutls_global_init(
void)
446 signal(SIGPIPE, SIG_IGN);
447 gnutls_global_init();
486 #if defined(HAVE_NANOSLEEP) 489 struct timespec req = { .tv_sec = 0, .tv_nsec = (long) (ms * 1000000) };
491 nanosleep(&req, NULL);
493 #elif defined(HAVE_USLEEP) 495 usleep((useconds_t) ms);
499 struct timeval tv = { .tv_sec = 0, .tv_usec = (suseconds_t) ms };
501 select(0, NULL, NULL, NULL, &tv);
520 }
else if (
input[0] ==
'P') {
537 return (msec >= G_MAXUINT)? G_MAXUINT : (guint) msec;
543 struct utsname hostinfo;
545 return (
uname(&hostinfo) < 0)? NULL : strdup(hostinfo.nodename);
int crm_user_lookup(const char *name, uid_t *uid, gid_t *gid)
const char * pcmk_strerror(int rc)
void crm_enable_stderr(int enable)
_Noreturn crm_exit_t crm_exit(crm_exit_t rc)
#define PCMK_VALUE_MINUS_INFINITY
#define PCMK_VALUE_INFINITY
bool pcmk_str_is_minus_infinity(const char *s)
struct crm_time_s crm_time_t
long long crm_get_msec(const char *input)
Parse a time+units string and return milliseconds equivalent.
gboolean crm_config_warning
bool pcmk_str_is_infinity(const char *s)
crm_time_t * crm_time_parse_duration(const char *duration_str)
Parse a time duration from an ISO 8601 duration specification.
#define PCMK_VALUE_PLUS_INFINITY
void pcmk__daemonize(const char *name, const char *pidfile)
const char * pcmk_rc_str(int rc)
Get a user-friendly description of a return code.
Wrappers for and extensions to glib mainloop.
#define crm_warn(fmt, args...)
guint crm_parse_interval_spec(const char *input)
void pcmk__sleep_ms(unsigned int ms)
External (OS/environmental) problem.
#define crm_trace(fmt, args...)
Wrappers for and extensions to libxml2.
char * crm_generate_uuid(void)
bool pcmk__str_any_of(const char *s,...) G_GNUC_NULL_TERMINATED
long long crm_time_get_seconds(const crm_time_t *dt)
CRM_TRACE_INIT_DATA(common)
char * pcmk_hostname(void)
void crm_write_blackbox(int nsig, const struct qb_log_callsite *callsite)
int compare_version(const char *version1, const char *version2)
void crm_abort(const char *file, const char *function, int line, const char *assert_condition, gboolean do_core, gboolean do_fork)
int pcmk__lock_pidfile(const char *filename, const char *name)
#define crm_perror(level, fmt, args...)
Send a system error message to both the log and stderr.
#define crm_err(fmt, args...)
Deprecated Pacemaker utilities.
#define pcmk__mem_assert(ptr)
int pcmk__pidfile_matches(const char *filename, pid_t expected_pid, const char *expected_name, pid_t *pid)
#define PCMK__PW_BUFFER_LEN
IPC interface to Pacemaker daemons.
gboolean crm_config_error
bool pcmk__is_user_in_group(const char *user, const char *group)
int pcmk_daemon_user(uid_t *uid, gid_t *gid)
Get user and group IDs of pacemaker daemon user.
#define crm_info(fmt, args...)
void crm_time_free(crm_time_t *dt)