15 #include <sys/types.h>
18 #include <sys/utsname.h>
30 #include <qb/qbdefs.h>
41 #include <libxml2/libxml/relaxng.h>
52 # define PW_BUFFER_LEN 500
65 static struct crm_option *crm_long_options = NULL;
66 static const char *crm_app_description = NULL;
67 static char *crm_short_options = NULL;
68 static const char *crm_app_usage = NULL;
156 if(stat(value, &st) != 0) {
157 crm_err(
"Script %s does not exist", value);
161 if(S_ISREG(st.st_mode) == 0) {
162 crm_err(
"Script %s is not a regular file", value);
166 if( (st.st_mode & (S_IXUSR | S_IXGRP )) == 0) {
167 crm_err(
"Script %s is not executable", value);
178 long number = strtol(value, &end, 10);
180 if(end && end[0] !=
'%') {
182 }
else if(number < 0) {
192 free(crm_short_options);
193 crm_short_options = NULL;
257 return crm_itoa(score);
262 const char *name,
const char *old_name,
const char *def_value)
264 const char *value = NULL;
265 char *new_value = NULL;
270 value = g_hash_table_lookup(options, name);
272 if ((value == NULL) && old_name) {
273 value = g_hash_table_lookup(options, old_name);
276 " is deprecated and will be removed in a future release",
280 new_value = strdup(value);
281 g_hash_table_insert(options, strdup(name), new_value);
286 if (value && validate && (validate(value) == FALSE)) {
287 crm_config_err(
"Resetting cluster option '%s' to default: value '%s' is invalid",
301 crm_trace(
"No value or default provided for cluster option '%s'",
308 crm_err(
"Bug: default value for cluster option '%s' is invalid", name);
312 crm_trace(
"Using default value '%s' for cluster option '%s'",
315 new_value = strdup(value);
316 g_hash_table_insert(options, strdup(name), new_value);
325 const char *value = NULL;
327 for (
int lpc = 0; lpc < len; lpc++) {
330 option_list[lpc].is_valid,
331 option_list[lpc].name,
332 option_list[lpc].alt_name,
333 option_list[lpc].default_value);
347 fprintf(stdout,
"<?xml version=\"1.0\"?>"
348 "<!DOCTYPE resource-agent SYSTEM \"ra-api-1.dtd\">\n"
349 "<resource-agent name=\"%s\">\n"
350 " <version>%s</version>\n"
351 " <longdesc lang=\"en\">%s</longdesc>\n"
352 " <shortdesc lang=\"en\">%s</shortdesc>\n"
353 " <parameters>\n", name,
version, desc_long, desc_short);
355 for (lpc = 0; lpc < len; lpc++) {
356 if (option_list[lpc].description_long == NULL && option_list[lpc].description_short == NULL) {
359 fprintf(stdout,
" <parameter name=\"%s\" unique=\"0\">\n"
360 " <shortdesc lang=\"en\">%s</shortdesc>\n"
361 " <content type=\"%s\" default=\"%s\"/>\n"
362 " <longdesc lang=\"en\">%s%s%s</longdesc>\n"
364 option_list[lpc].name,
365 option_list[lpc].description_short,
366 option_list[lpc].
type,
367 option_list[lpc].default_value,
368 option_list[lpc].description_long ? option_list[lpc].
369 description_long : option_list[lpc].description_short,
370 option_list[lpc].values ?
" Allowed values: " :
"",
371 option_list[lpc].values ? option_list[lpc].values :
"");
373 fprintf(stdout,
" </parameters>\n</resource-agent>\n");
381 for (lpc = 0; lpc < len; lpc++) {
383 option_list[lpc].is_valid,
384 option_list[lpc].name,
385 option_list[lpc].alt_name, option_list[lpc].default_value);
392 char *hash_key = crm_concat(sys ? sys :
"none", crm_msg_reference,
'_');
394 crm_trace(
"created hash key: (%s)", hash_key);
405 struct passwd *pwentry = NULL;
408 rc = getpwnam_r(name, &pwd, buffer,
PW_BUFFER_LEN, &pwentry);
411 *uid = pwentry->pw_uid;
414 *gid = pwentry->pw_gid;
416 crm_trace(
"User %s has uid=%d gid=%d", name, pwentry->pw_uid, pwentry->pw_gid);
419 rc = rc? -rc : -EINVAL;
428 crm_version_helper(
const char *text,
char **end_text)
430 int atoi_result = -1;
436 if (text != NULL && text[0] != 0) {
437 atoi_result = (int)strtol(text, end_text, 10);
439 if (errno == EINVAL) {
440 crm_err(
"Conversion of '%s' %c failed", text, text[0]);
457 char *ver1_copy = NULL, *ver2_copy = NULL;
458 char *rest1 = NULL, *rest2 = NULL;
460 if (version1 == NULL && version2 == NULL) {
462 }
else if (version1 == NULL) {
464 }
else if (version2 == NULL) {
468 ver1_copy = strdup(version1);
469 ver2_copy = strdup(version2);
479 if (rest1 == rest2) {
484 digit1 = crm_version_helper(rest1, &rest1);
488 digit2 = crm_version_helper(rest2, &rest2);
491 if (digit1 < digit2) {
495 }
else if (digit1 > digit2) {
500 if (rest1 != NULL && rest1[0] ==
'.') {
503 if (rest1 != NULL && rest1[0] == 0) {
507 if (rest2 != NULL && rest2[0] ==
'.') {
510 if (rest2 != NULL && rest2[0] == 0) {
519 crm_trace(
"%s == %s (%d)", version1, version2, lpc);
521 crm_trace(
"%s < %s (%d)", version1, version2, lpc);
523 crm_trace(
"%s > %s (%d)", version1, version2, lpc);
532 # define NUMCHARS "0123456789."
536 # define WHITESPACE " \t\n\r\f"
547 }
else if (input[0] !=
'P') {
561 return (msec <= 0)? 0 : ((msec >= G_MAXUINT)? G_MAXUINT : (guint) msec);
567 const char *cp = input;
569 long long multiplier = 1000;
570 long long divisor = 1;
572 char *end_text = NULL;
584 if (strchr(
NUMCHARS, *cp) == NULL) {
588 if (strncasecmp(units,
"ms", 2) == 0 || strncasecmp(units,
"msec", 4) == 0) {
591 }
else if (strncasecmp(units,
"us", 2) == 0 || strncasecmp(units,
"usec", 4) == 0) {
594 }
else if (strncasecmp(units,
"s", 1) == 0 || strncasecmp(units,
"sec", 3) == 0) {
597 }
else if (strncasecmp(units,
"m", 1) == 0 || strncasecmp(units,
"min", 3) == 0) {
598 multiplier = 60 * 1000;
600 }
else if (strncasecmp(units,
"h", 1) == 0 || strncasecmp(units,
"hr", 2) == 0) {
601 multiplier = 60 * 60 * 1000;
603 }
else if (*units !=
EOS && *units !=
'\n' && *units !=
'\r') {
608 if (msec > LLONG_MAX/multiplier) {
623 crm_abort(
const char *file,
const char *
function,
int line,
624 const char *assert_condition, gboolean do_core, gboolean do_fork)
641 if (do_core == FALSE) {
642 crm_err(
"%s: Triggered assert at %s:%d : %s",
function, file, line, assert_condition);
645 }
else if (do_fork) {
649 crm_err(
"%s: Triggered fatal assert at %s:%d : %s",
function, file, line, assert_condition);
653 crm_crit(
"%s: Cannot create core for non-fatal assert at %s:%d : %s",
654 function, file, line, assert_condition);
657 }
else if(
pid == 0) {
664 crm_err(
"%s: Forked child %d to record non-fatal assert at %s:%d : %s",
665 function,
pid, file, line, assert_condition);
669 rc = waitpid(
pid, &status, 0);
674 }
while(errno == EINTR);
676 if (errno == ECHILD) {
678 crm_trace(
"Cannot wait on forked child %d - SIGCHLD is probably set to SIG_IGN",
pid);
689 const char *devnull =
"/dev/null";
691 if (daemonize == FALSE) {
697 if(rc <
pcmk_ok && rc != -ENOENT) {
699 crm_err(
"%s: already running [pid %ld in %s]", name,
pid, pidfile);
700 printf(
"%s: already running [pid %ld in %s]\n", name,
pid, pidfile);
706 fprintf(stderr,
"%s: could not start daemon\n", name);
710 }
else if (
pid > 0) {
717 printf(
"Could not lock '%s' for %s: %s (%d)\n", pidfile, name,
pcmk_strerror(rc), rc);
721 umask(S_IWGRP | S_IWOTH | S_IROTH);
724 (void)open(devnull, O_RDONLY);
725 close(STDOUT_FILENO);
726 (void)open(devnull, O_WRONLY);
727 close(STDERR_FILENO);
728 (void)open(devnull, O_WRONLY);
736 char *crm_name = NULL;
739 crm_name = crm_concat(
CRM_META, field,
'_');
742 max = strlen(crm_name);
743 for (; lpc < max; lpc++) {
744 switch (crm_name[lpc]) {
757 const char *value = NULL;
761 value = g_hash_table_lookup(hash, key);
768 static struct option *
769 crm_create_long_opts(
struct crm_option *long_options)
771 struct option *long_opts = NULL;
774 int index = 0, lpc = 0;
783 long_opts = realloc_safe(long_opts, (index + 1) *
sizeof(
struct option));
784 long_opts[index].name =
"__dummmy__";
785 long_opts[index].has_arg = 0;
786 long_opts[index].flag = 0;
787 long_opts[index].val =
'_';
790 for (lpc = 0; long_options[lpc].
name != NULL; lpc++) {
791 if (long_options[lpc].name[0] ==
'-') {
795 long_opts = realloc_safe(long_opts, (index + 1) *
sizeof(
struct option));
798 long_opts[index].name = long_options[lpc].
name;
799 long_opts[index].has_arg = long_options[lpc].
has_arg;
800 long_opts[index].flag = long_options[lpc].
flag;
801 long_opts[index].val = long_options[lpc].
val;
806 long_opts = realloc_safe(long_opts, (index + 1) *
sizeof(
struct option));
807 long_opts[index].name = NULL;
808 long_opts[index].has_arg = 0;
809 long_opts[index].flag = 0;
810 long_opts[index].val = 0;
818 const char *app_desc)
821 crm_short_options = strdup(short_options);
823 }
else if (long_options) {
825 int opt_string_len = 0;
826 char *local_short_options = NULL;
828 for (lpc = 0; long_options[lpc].
name != NULL; lpc++) {
829 if (long_options[lpc].val && long_options[lpc].val !=
'-' && long_options[lpc].val < UCHAR_MAX) {
830 local_short_options = realloc_safe(local_short_options, opt_string_len + 4);
831 local_short_options[opt_string_len++] = long_options[lpc].
val;
833 if (long_options[lpc].has_arg == optional_argument) {
834 local_short_options[opt_string_len++] =
':';
837 local_short_options[opt_string_len++] =
':';
839 local_short_options[opt_string_len] = 0;
842 crm_short_options = local_short_options;
843 crm_trace(
"Generated short option string: '%s'", local_short_options);
847 crm_long_options = long_options;
850 crm_app_description = app_desc;
853 crm_app_usage = app_usage;
867 static struct option *long_opts = NULL;
869 if (long_opts == NULL && crm_long_options) {
870 long_opts = crm_create_long_opts(crm_long_options);
875 int flag = getopt_long(argc, argv, crm_short_options, long_opts, index);
879 if (long_opts[*index].val) {
880 return long_opts[*index].val;
881 }
else if (longname) {
882 *longname = long_opts[*index].name;
884 crm_notice(
"Unhandled option --%s", long_opts[*index].name);
901 if (crm_short_options) {
902 return getopt(argc, argv, crm_short_options);
912 FILE *stream = (exit_code ? stderr : stdout);
914 if (cmd ==
'v' || cmd ==
'$') {
916 fprintf(stream,
"Written by Andrew Beekhof\n");
931 if (crm_long_options) {
932 fprintf(stream,
"Options:\n");
933 for (i = 0; crm_long_options[i].
name != NULL; i++) {
937 fprintf(stream,
"%s\n\n", crm_long_options[i].desc);
940 fprintf(stream,
"\t#%s\n\n", crm_long_options[i].desc);
942 }
else if (crm_long_options[i].val ==
'-' && crm_long_options[i].desc) {
943 fprintf(stream,
"%s\n", crm_long_options[i].desc);
947 if (crm_long_options[i].val && crm_long_options[i].val <= UCHAR_MAX) {
948 fprintf(stream,
" -%c,", crm_long_options[i].val);
952 fprintf(stream,
" --%s%s\t%s\n", crm_long_options[i].name,
953 crm_long_options[i].has_arg == optional_argument ?
"[=value]" :
955 crm_long_options[i].desc ? crm_long_options[i].desc :
"");
959 }
else if (crm_short_options) {
960 fprintf(stream,
"Usage: %s - %s\n",
crm_system_name, crm_app_description);
961 for (i = 0; crm_short_options[i] != 0; i++) {
964 if (crm_short_options[i + 1] ==
':') {
965 if (crm_short_options[i + 2] ==
':')
966 has_arg = optional_argument ;
971 fprintf(stream,
" -%c %s\n", crm_short_options[i],
972 has_arg == optional_argument ?
"[value]" :
985 qb_ipcs_service_t **ipcs_rw,
986 qb_ipcs_service_t **ipcs_shm,
987 struct qb_ipcs_service_handlers *ro_cb,
988 struct qb_ipcs_service_handlers *rw_cb)
994 if (*ipcs_ro == NULL || *ipcs_rw == NULL || *ipcs_shm == NULL) {
995 crm_err(
"Failed to create the CIB manager: exiting and inhibiting respawn");
996 crm_warn(
"Verify pacemaker and pacemaker_remote are not both enabled");
1002 qb_ipcs_service_t *ipcs_rw,
1003 qb_ipcs_service_t *ipcs_shm)
1005 qb_ipcs_destroy(ipcs_ro);
1006 qb_ipcs_destroy(ipcs_rw);
1007 qb_ipcs_destroy(ipcs_shm);
1021 if (*ipcs == NULL) {
1022 crm_err(
"Failed to create pacemaker-attrd server: exiting and inhibiting respawn");
1023 crm_warn(
"Verify pacemaker and pacemaker_remote are not both enabled.");
1033 if (*ipcs == NULL) {
1034 crm_err(
"Failed to create fencer: exiting and inhibiting respawn.");
1035 crm_warn(
"Verify pacemaker and pacemaker_remote are not both enabled.");
1046 if (*handle == NULL) {
1047 *handle = dlopen(lib, RTLD_LAZY);
1051 crm_err(
"%sCould not open %s: %s", fatal ?
"Fatal: " :
"", lib, dlerror());
1058 a_function = dlsym(*handle, fn);
1059 if (a_function == NULL) {
1061 crm_err(
"%sCould not find %s in %s: %s", fatal ?
"Fatal: " :
"", fn, lib, error);
1070 #ifdef HAVE_UUID_UUID_H
1071 # include <uuid/uuid.h>
1077 unsigned char uuid[16];
1078 char *buffer = malloc(37);
1080 uuid_generate(uuid);
1081 uuid_unparse(uuid, buffer);
1102 }
else if (!strcmp(name,
"pacemaker-attrd")) {
1105 }
else if (!strcmp(name,
"pacemaker-based")) {
1108 }
else if (!strcmp(name,
"pacemaker-controld")) {
1111 }
else if (!strcmp(name,
"pacemaker-execd")) {
1114 }
else if (!strcmp(name,
"pacemaker-fenced")) {
1115 return "stonith-ng";
1117 }
else if (!strcmp(name,
"pacemaker-schedulerd")) {
1138 || !strcmp(name,
"stonith-ng")
1139 || !strcmp(name,
"attrd")
1152 int lpc = 0, len = 0;
1153 char *digest = NULL;
1156 if (buffer == NULL) {
1159 len = strlen(buffer);
1161 crm_trace(
"Beginning digest of %d bytes", len);
1166 sprintf(digest + (2 * lpc),
"%02x", raw_digest[lpc]);
1172 crm_err(
"Could not create digest");
1177 #ifdef HAVE_GNUTLS_GNUTLS_H
1179 crm_gnutls_global_init(
void)
1181 signal(SIGPIPE, SIG_IGN);
1182 gnutls_global_init();
1194 struct utsname hostinfo;
1196 return (
uname(&hostinfo) < 0)? NULL : strdup(hostinfo.nodename);