diff --git a/GNUmakefile b/GNUmakefile
index f28dea8..7a4c929 100644
--- a/GNUmakefile
+++ b/GNUmakefile
@@ -325,7 +325,7 @@ clang:
test -e $(CLANG_analyzer)
scan-build $(CLANG_checkers:%=-enable-checker %) make
-# V3 = scandir unsetenv alphasort
+# V3 = scandir unsetenv alphasort xalloc
# V2 = setenv strerror strchrnul strndup
# http://www.gnu.org/software/gnulib/manual/html_node/Initial-import.html#Initial-import
GNU_MODS = crypto/md5
diff --git a/crmd/lrm.c b/crmd/lrm.c
index b68f657..8315f6f 100644
--- a/crmd/lrm.c
+++ b/crmd/lrm.c
@@ -630,7 +630,7 @@ append_restart_list(lrmd_rsc_info_t * rsc, lrmd_event_data_t * op, xmlNode * upd
crm_xml_add(restart, param, value);
}
len += strlen(param) + 2;
- list = realloc(list, len + 1);
+ list = realloc_safe(list, len + 1);
sprintf(list + start, " %s ", param);
}
diff --git a/cts/CIB.py b/cts/CIB.py
index d26efdb..7922d8b 100644
--- a/cts/CIB.py
+++ b/cts/CIB.py
@@ -298,7 +298,28 @@ class CIB11(ConfigBase):
# Group Resource
g = Group(self.Factory, "group-1")
g.add_child(self.NewIP())
- g.add_child(self.NewIP())
+
+ if self.CM.Env["have_systemd"]:
+ dummy_service_file = """
+[Unit]
+Description=Dummy resource that takes a while to start
+
+[Service]
+Type=notify
+ExecStart=/usr/bin/python -c 'import time; import systemd.daemon;time.sleep(10); systemd.daemon.notify("READY=1"); time.sleep(3600)'
+ExecStop=sleep 10
+ExecStop=/bin/kill -KILL $MAINPID
+"""
+
+ os.system("cat <<-END >/tmp/DummySD.service\n%s\nEND" % (dummy_service_file))
+
+ self.CM.install_helper("DummySD.service", destdir="/usr/lib/systemd/system/", sourcedir="/tmp")
+ sysd = Resource(self.Factory, "petulant", "DummySD", "service")
+ sysd.add_op("monitor", "P10S")
+ g.add_child(sysd)
+ else:
+ g.add_child(self.NewIP())
+
g.add_child(self.NewIP())
# Group with the master
diff --git a/cts/environment.py b/cts/environment.py
index d741452..2b2a343 100644
--- a/cts/environment.py
+++ b/cts/environment.py
@@ -283,9 +283,9 @@ class Environment:
break;
self["cts-master"] = master
- if self.has_key("have_systemd"):
- self["have_systemd"] = not rsh(discover, "systemctl list-units")
-
+ if not self.has_key("have_systemd"):
+ self["have_systemd"] = not self.rsh(self.target, "systemctl list-units")
+
self.detect_syslog()
self.detect_at_boot()
self.detect_ip_offset()
diff --git a/fencing/standalone_config.c b/fencing/standalone_config.c
index 01c22b6..4319c4a 100644
--- a/fencing/standalone_config.c
+++ b/fencing/standalone_config.c
@@ -170,7 +170,7 @@ standalone_cfg_add_node(const char *node, const char *device, const char *ports)
if (tmp) {
offset = strlen(tmp);
- tmp = realloc(tmp, len + offset + 1);
+ tmp = realloc_safe(tmp, len + offset + 1);
} else {
tmp = malloc(len);
}
diff --git a/include/crm_internal.h b/include/crm_internal.h
index 3eb88de..169d6d3 100644
--- a/include/crm_internal.h
+++ b/include/crm_internal.h
@@ -341,4 +341,16 @@ void cib_ipc_servers_destroy(qb_ipcs_service_t *ipcs_ro,
qb_ipcs_service_t *ipcs_rw,
qb_ipcs_service_t *ipcs_shm);
+static inline void *realloc_safe(void *ptr, size_t size)
+{
+ void *ret = realloc(ptr, size);
+
+ if(ret == NULL) {
+ abort();
+ }
+
+ return ret;
+}
+
+
#endif /* CRM_INTERNAL__H */
diff --git a/lib/ais/plugin.c b/lib/ais/plugin.c
index 3d4f369..ab534fa 100644
--- a/lib/ais/plugin.c
+++ b/lib/ais/plugin.c
@@ -1214,7 +1214,7 @@ pcmk_generate_membership_data(void)
g_hash_table_foreach(membership_list, member_loop_fn, &data);
size = strlen(data.string);
- data.string = realloc(data.string, size + 9); /* 9 = </nodes> + nul */
+ data.string = realloc_safe(data.string, size + 9); /* 9 = </nodes> + nul */
sprintf(data.string + size, "</nodes>");
return data.string;
}
diff --git a/lib/ais/utils.c b/lib/ais/utils.c
index e56fb6d..94a2505 100644
--- a/lib/ais/utils.c
+++ b/lib/ais/utils.c
@@ -409,7 +409,7 @@ append_member(char *data, crm_node_t * node)
if (node->version) {
size += (9 + strlen(node->version));
}
- data = realloc(data, size);
+ data = realloc_safe(data, size);
offset += snprintf(data + offset, size - offset, "<node id=\"%u\" ", node->id);
if (node->uname) {
diff --git a/lib/cluster/cpg.c b/lib/cluster/cpg.c
index 6c86e83..cda6326 100644
--- a/lib/cluster/cpg.c
+++ b/lib/cluster/cpg.c
@@ -584,7 +584,7 @@ send_cluster_text(int class, const char *data,
msg->header.size = sizeof(AIS_Message) + msg->size;
if (msg->size < CRM_BZ2_THRESHOLD) {
- msg = realloc(msg, msg->header.size);
+ msg = realloc_safe(msg, msg->header.size);
memcpy(msg->data, data, msg->size);
} else {
@@ -595,14 +595,14 @@ send_cluster_text(int class, const char *data,
if (crm_compress_string(uncompressed, msg->size, 0, &compressed, &new_size)) {
msg->header.size = sizeof(AIS_Message) + new_size;
- msg = realloc(msg, msg->header.size);
+ msg = realloc_safe(msg, msg->header.size);
memcpy(msg->data, compressed, new_size);
msg->is_compressed = TRUE;
msg->compressed_size = new_size;
} else {
- msg = realloc(msg, msg->header.size);
+ msg = realloc_safe(msg, msg->header.size);
memcpy(msg->data, data, msg->size);
}
diff --git a/lib/cluster/heartbeat.c b/lib/cluster/heartbeat.c
index a801c8e..6f6a388 100644
--- a/lib/cluster/heartbeat.c
+++ b/lib/cluster/heartbeat.c
@@ -106,7 +106,7 @@ convert_ha_field(xmlNode * parent, void *msg_v, int lpc)
crm_trace("Trying to decompress %d bytes", (int)orig_len);
retry:
- uncompressed = realloc(uncompressed, size);
+ uncompressed = realloc_safe(uncompressed, size);
memset(uncompressed, 0, size);
used = size - 1; /* always leave room for a trailing '\0'
* BZ2_bzBuffToBuffDecompress wont say anything if
diff --git a/lib/common/logging.c b/lib/common/logging.c
index d64b77a..f211d80 100644
--- a/lib/common/logging.c
+++ b/lib/common/logging.c
@@ -956,7 +956,7 @@ crm_log_args(int argc, char **argv)
}
len = 2 + strlen(argv[lpc]); /* +1 space, +1 EOS */
- arg_string = realloc(arg_string, len + existing_len);
+ arg_string = realloc_safe(arg_string, len + existing_len);
existing_len += sprintf(arg_string + existing_len, "%s ", argv[lpc]);
}
diff --git a/lib/common/remote.c b/lib/common/remote.c
index f11ebcd..2a5b449 100644
--- a/lib/common/remote.c
+++ b/lib/common/remote.c
@@ -520,7 +520,7 @@ crm_remote_recv_once(crm_remote_t * remote)
remote->buffer_size = 2 * read_len;
crm_trace("Expanding buffer to %u bytes", remote->buffer_size);
- remote->buffer = realloc(remote->buffer, remote->buffer_size + 1);
+ remote->buffer = realloc_safe(remote->buffer, remote->buffer_size + 1);
CRM_ASSERT(remote->buffer != NULL);
}
diff --git a/lib/common/utils.c b/lib/common/utils.c
index eacd8e9..d70778d 100644
--- a/lib/common/utils.c
+++ b/lib/common/utils.c
@@ -1712,7 +1712,7 @@ crm_create_long_opts(struct crm_option *long_options)
* This dummy entry allows us to differentiate between the two in crm_get_option()
* and exit with the correct error code
*/
- long_opts = realloc(long_opts, (index + 1) * sizeof(struct option));
+ long_opts = realloc_safe(long_opts, (index + 1) * sizeof(struct option));
long_opts[index].name = "__dummmy__";
long_opts[index].has_arg = 0;
long_opts[index].flag = 0;
@@ -1724,7 +1724,7 @@ crm_create_long_opts(struct crm_option *long_options)
continue;
}
- long_opts = realloc(long_opts, (index + 1) * sizeof(struct option));
+ long_opts = realloc_safe(long_opts, (index + 1) * sizeof(struct option));
/*fprintf(stderr, "Creating %d %s = %c\n", index,
* long_options[lpc].name, long_options[lpc].val); */
long_opts[index].name = long_options[lpc].name;
@@ -1735,7 +1735,7 @@ crm_create_long_opts(struct crm_option *long_options)
}
/* Now create the list terminator */
- long_opts = realloc(long_opts, (index + 1) * sizeof(struct option));
+ long_opts = realloc_safe(long_opts, (index + 1) * sizeof(struct option));
long_opts[index].name = NULL;
long_opts[index].has_arg = 0;
long_opts[index].flag = 0;
@@ -1759,7 +1759,7 @@ crm_set_options(const char *short_options, const char *app_usage, struct crm_opt
for (lpc = 0; long_options[lpc].name != NULL; lpc++) {
if (long_options[lpc].val && long_options[lpc].val != '-' && long_options[lpc].val < UCHAR_MAX) {
- local_short_options = realloc(local_short_options, opt_string_len + 4);
+ local_short_options = realloc_safe(local_short_options, opt_string_len + 4);
local_short_options[opt_string_len++] = long_options[lpc].val;
/* getopt(3) says: Two colons mean an option takes an optional arg; */
if (long_options[lpc].has_arg == optional_argument) {
@@ -2517,7 +2517,7 @@ add_list_element(char *list, const char *value)
}
len = last + 2; /* +1 space, +1 EOS */
len += strlen(value);
- list = realloc(list, len);
+ list = realloc_safe(list, len);
sprintf(list + last, " %s", value);
return list;
}
diff --git a/lib/common/xml.c b/lib/common/xml.c
index e63a582..0effd47 100644
--- a/lib/common/xml.c
+++ b/lib/common/xml.c
@@ -206,7 +206,7 @@ static inline bool TRACKING_CHANGES(xmlNode *xml)
} else if(rc >= ((max) - (offset))) { \
char *tmp = NULL; \
(max) = QB_MAX(CHUNK_SIZE, (max) * 2); \
- tmp = realloc((buffer), (max) + 1); \
+ tmp = realloc_safe((buffer), (max) + 1); \
CRM_ASSERT(tmp); \
(buffer) = tmp; \
} else { \
@@ -223,7 +223,7 @@ insert_prefix(int options, char **buffer, int *offset, int *max, int depth)
if ((*buffer) == NULL || spaces >= ((*max) - (*offset))) {
(*max) = QB_MAX(CHUNK_SIZE, (*max) * 2);
- (*buffer) = realloc((*buffer), (*max) + 1);
+ (*buffer) = realloc_safe((*buffer), (*max) + 1);
}
memset((*buffer) + (*offset), ' ', spaces);
(*offset) += spaces;
@@ -305,7 +305,7 @@ static void __xml_schema_add(
int last = xml_schema_max;
xml_schema_max++;
- known_schemas = realloc(known_schemas, xml_schema_max*sizeof(struct schema_s));
+ known_schemas = realloc_safe(known_schemas, xml_schema_max*sizeof(struct schema_s));
CRM_ASSERT(known_schemas != NULL);
memset(known_schemas+last, 0, sizeof(struct schema_s));
known_schemas[last].type = type;
@@ -2759,6 +2759,7 @@ create_xml_node(xmlNode * parent, const char *name)
xmlNode *node = NULL;
if (name == NULL || name[0] == 0) {
+ CRM_CHECK(name != NULL || name[0] == 0, return NULL);
return NULL;
}
@@ -2905,7 +2906,7 @@ crm_xml_err(void *ctx, const char *msg, ...)
buf = NULL;
} else {
- buffer = realloc(buffer, 1 + buffer_len + len);
+ buffer = realloc_safe(buffer, 1 + buffer_len + len);
memcpy(buffer + buffer_len, buf, len);
buffer_len += len;
buffer[buffer_len] = 0;
@@ -2997,7 +2998,7 @@ stdin2xml(void)
break;
}
- xml_buffer = realloc(xml_buffer, next);
+ xml_buffer = realloc_safe(xml_buffer, next);
read_chars = fread(xml_buffer + data_length, 1, XML_BUFFER_SIZE, stdin);
data_length += read_chars;
} while (read_chars > 0);
@@ -3043,7 +3044,7 @@ decompress_file(const char *filename)
rc = BZ_OK;
while (rc == BZ_OK) {
- buffer = realloc(buffer, XML_BUFFER_SIZE + length + 1);
+ buffer = realloc_safe(buffer, XML_BUFFER_SIZE + length + 1);
read_len = BZ2_bzRead(&rc, bz_file, buffer + length, XML_BUFFER_SIZE);
crm_trace("Read %ld bytes from file: %d", (long)read_len, rc);
@@ -3301,7 +3302,7 @@ crm_xml_escape_shuffle(char *text, int start, int *length, const char *replace)
int offset = strlen(replace) - 1; /* We have space for 1 char already */
*length += offset;
- text = realloc(text, *length);
+ text = realloc_safe(text, *length);
for (lpc = (*length) - 1; lpc > (start + offset); lpc--) {
text[lpc] = text[lpc - offset];
@@ -5369,7 +5370,7 @@ crm_xml_init(void)
if(init) {
init = FALSE;
/* The default allocator XML_BUFFER_ALLOC_EXACT does far too many
- * realloc()s and it can take upwards of 18 seconds (yes, seconds)
+ * realloc_safe()s and it can take upwards of 18 seconds (yes, seconds)
* to dump a 28kb tree which XML_BUFFER_ALLOC_DOUBLEIT can do in
* less than 1 second.
*/
@@ -5987,7 +5988,7 @@ get_xpath_object_relative(const char *xpath, xmlNode * xml_obj, int error_level)
len += strlen(xpath);
xpath_full = strdup(xpath_prefix);
- xpath_full = realloc(xpath_full, len + 1);
+ xpath_full = realloc_safe(xpath_full, len + 1);
strncat(xpath_full, xpath, len);
result = get_xpath_object(xpath_full, xml_obj, error_level);
diff --git a/lib/fencing/st_client.c b/lib/fencing/st_client.c
index 06b9492..e51d673 100644
--- a/lib/fencing/st_client.c
+++ b/lib/fencing/st_client.c
@@ -308,7 +308,7 @@ append_arg(gpointer key, gpointer value, gpointer user_data)
last = strlen(*args);
}
- *args = realloc(*args, last + len);
+ *args = realloc_safe(*args, last + len);
crm_trace("Appending: %s=%s", (char *)key, (char *)value);
sprintf((*args) + last, "%s=%s\n", (char *)key, (char *)value);
}
@@ -627,7 +627,7 @@ read_output(int fd)
* 'more' is always less than our buffer size
*/
crm_trace("Got %d more bytes: %.200s...", more, buffer);
- output = realloc(output, len + more + 1);
+ output = realloc_safe(output, len + more + 1);
snprintf(output + len, more + 1, "%s", buffer);
len += more;
}
diff --git a/lib/services/services_linux.c b/lib/services/services_linux.c
index 8d6f450..de29706 100644
--- a/lib/services/services_linux.c
+++ b/lib/services/services_linux.c
@@ -94,7 +94,7 @@ svc_read_output(int fd, svc_action_t * op, bool is_stderr)
if (rc > 0) {
crm_trace("Got %d characters starting with %.20s", rc, buf);
buf[rc] = 0;
- data = realloc(data, len + rc + 1);
+ data = realloc_safe(data, len + rc + 1);
len += sprintf(data + len, "%s", buf);
} else if (errno != EINTR) {
diff --git a/lib/services/systemd.c b/lib/services/systemd.c
index a8bf1b4..c0a1721 100644
--- a/lib/services/systemd.c
+++ b/lib/services/systemd.c
@@ -462,10 +462,11 @@ systemd_async_dispatch(DBusPendingCall *pending, void *user_data)
if(op) {
crm_trace("Got result: %p for %p for %s, %s", reply, pending, op->rsc, op->action);
op->opaque->pending = NULL;
+ systemd_exec_result(reply, op);
+
} else {
crm_trace("Got result: %p for %p", reply, pending);
}
- systemd_exec_result(reply, op);
if(pending) {
dbus_pending_call_unref(pending);
@@ -491,6 +492,8 @@ systemd_unit_check(const char *name, const char *state, void *userdata)
op->rc = PCMK_OCF_OK;
} else if (g_strcmp0(state, "activating") == 0) {
op->rc = PCMK_OCF_PENDING;
+ } else if (g_strcmp0(state, "deactivating") == 0) {
+ op->rc = PCMK_OCF_PENDING;
} else {
op->rc = PCMK_OCF_NOT_RUNNING;
}
diff --git a/lrmd/lrmd.c b/lrmd/lrmd.c
index d3ede18..0f5f529 100644
--- a/lrmd/lrmd.c
+++ b/lrmd/lrmd.c
@@ -790,10 +790,30 @@ action_complete(svc_action_t * action)
cmd->real_action = cmd->action;
cmd->action = strdup("monitor");
+ } else if(cmd->exec_rc == PCMK_OCF_OK && safe_str_eq(cmd->action, "stop")) {
+ goagain = true;
+ cmd->real_action = cmd->action;
+ cmd->action = strdup("monitor");
+
} else if(cmd->real_action) {
/* Ok, so this is the follow up monitor action to check if start actually completed */
if(cmd->lrmd_op_status == PCMK_LRM_OP_DONE && cmd->exec_rc == PCMK_OCF_PENDING) {
goagain = true;
+
+ } else {
+ int time_sum = 0;
+ int timeout_left = 0;
+ struct timeb now = { 0, };
+
+ ftime(&now);
+ time_sum = time_diff_ms(&now, &cmd->t_first_run);
+ timeout_left = cmd->timeout_orig - time_sum;
+ crm_debug("%s %s is now complete (elapsed=%dms, remaining=%dms): %s (%d)",
+ cmd->rsc_id, cmd->real_action, time_sum, timeout_left, services_ocf_exitcode_str(cmd->exec_rc), cmd->exec_rc);
+
+ if(cmd->lrmd_op_status == PCMK_LRM_OP_DONE && cmd->exec_rc == PCMK_OCF_NOT_RUNNING && safe_str_eq(cmd->real_action, "stop")) {
+ cmd->exec_rc = PCMK_OCF_OK;
+ }
}
}
}
@@ -827,13 +847,22 @@ action_complete(svc_action_t * action)
delay = timeout_left/2;
}
+ delay = QB_MIN(2000, delay);
if (delay < timeout_left) {
cmd->start_delay = delay;
cmd->timeout = timeout_left;
- if(cmd->exec_rc != PCMK_OCF_OK) {
- crm_info("%s %s failed (rc=%d): re-scheduling (elapsed=%dms, remaining=%dms, start_delay=%dms)",
- cmd->rsc_id, cmd->action, cmd->exec_rc, time_sum, timeout_left, delay);
+ if(cmd->exec_rc == PCMK_OCF_OK) {
+ crm_debug("%s %s may still be in progress: re-scheduling (elapsed=%dms, remaining=%dms, start_delay=%dms)",
+ cmd->rsc_id, cmd->real_action, time_sum, timeout_left, delay);
+
+ } else if(cmd->exec_rc == PCMK_OCF_PENDING) {
+ crm_info("%s %s is still in progress: re-scheduling (elapsed=%dms, remaining=%dms, start_delay=%dms)",
+ cmd->rsc_id, cmd->action, time_sum, timeout_left, delay);
+
+ } else {
+ crm_notice("%s %s failed '%s' (%d): re-scheduling (elapsed=%dms, remaining=%dms, start_delay=%dms)",
+ cmd->rsc_id, cmd->action, services_ocf_exitcode_str(cmd->exec_rc), cmd->exec_rc, time_sum, timeout_left, delay);
}
cmd_reset(cmd);
diff --git a/pengine/allocate.c b/pengine/allocate.c
index 45e2212..748ca54 100644
--- a/pengine/allocate.c
+++ b/pengine/allocate.c
@@ -1913,7 +1913,7 @@ expand_list(GListPtr list, char **rsc_list, char **node_list)
}
crm_trace("Adding %s (%dc) at offset %d", rsc_id, len - 2, existing_len);
- *rsc_list = realloc(*rsc_list, len + existing_len);
+ *rsc_list = realloc_safe(*rsc_list, len + existing_len);
sprintf(*rsc_list + existing_len, "%s ", rsc_id);
}
@@ -1930,7 +1930,7 @@ expand_list(GListPtr list, char **rsc_list, char **node_list)
}
crm_trace("Adding %s (%dc) at offset %d", uname, len - 2, existing_len);
- *node_list = realloc(*node_list, len + existing_len);
+ *node_list = realloc_safe(*node_list, len + existing_len);
sprintf(*node_list + existing_len, "%s ", uname);
}
}
diff --git a/replace/scandir.c b/replace/scandir.c
index 7a8efea..0011630 100644
--- a/replace/scandir.c
+++ b/replace/scandir.c
@@ -202,7 +202,7 @@ scandir(const char *directory_name,
if (counter + 1 == allocated) {
allocated <<= 1;
array = (struct dirent **)
- realloc((char *)array, allocated * sizeof(struct dirent *));
+ realloc_safe((char *)array, allocated * sizeof(struct dirent *));
if (array == NULL) {
closedir(directory);
free(array);
diff --git a/tools/crm_resource.c b/tools/crm_resource.c
index 6e510e1..236d43c 100644
--- a/tools/crm_resource.c
+++ b/tools/crm_resource.c
@@ -1399,16 +1399,20 @@ static void display_list(GList *items, const char *tag)
static int
update_dataset(cib_t *cib, pe_working_set_t * data_set, bool simulate)
{
+ char *pid = NULL;
+ char *shadow_file = NULL;
+ cib_t *shadow_cib = NULL;
xmlNode *cib_xml_copy = NULL;
int rc = cib->cmds->query(cib, NULL, &cib_xml_copy, cib_scope_local | cib_sync_call);
if(rc != pcmk_ok) {
fprintf(stdout, "Could not obtain the current CIB: %s (%d)\n", pcmk_strerror(rc), rc);
- return crm_exit(rc);
+ goto cleanup;
} else if (cli_config_update(&cib_xml_copy, NULL, FALSE) == FALSE) {
fprintf(stderr, "Could not upgrade the current CIB\n");
- return -ENOKEY;
+ rc = -ENOKEY;
+ goto cleanup;
}
set_working_set_defaults(data_set);
@@ -1416,70 +1420,103 @@ update_dataset(cib_t *cib, pe_working_set_t * data_set, bool simulate)
data_set->now = crm_time_new(NULL);
if(simulate) {
- char *pid = crm_itoa(getpid());
- cib_t *shadow_cib = cib_shadow_new(pid);
- char *shadow_file = get_shadow_file(pid);
+ pid = crm_itoa(getpid());
+ shadow_cib = cib_shadow_new(pid);
+ shadow_file = get_shadow_file(pid);
if (shadow_cib == NULL) {
fprintf(stderr, "Could not create shadow cib: '%s'\n", pid);
- crm_exit(-ENXIO);
+ rc = -ENXIO;
+ goto cleanup;
}
+ free(pid);
rc = write_xml_file(cib_xml_copy, shadow_file, FALSE);
if (rc < 0) {
fprintf(stderr, "Could not populate shadow cib: %s (%d)\n", pcmk_strerror(rc), rc);
- free_xml(cib_xml_copy);
- return rc;
+ goto cleanup;
}
rc = shadow_cib->cmds->signon(shadow_cib, crm_system_name, cib_command);
if(rc != pcmk_ok) {
fprintf(stderr, "Could not connect to shadow cib: %s (%d)\n", pcmk_strerror(rc), rc);
- free_xml(cib_xml_copy);
- return rc;
+ goto cleanup;
}
do_calculations(data_set, cib_xml_copy, NULL);
run_simulation(data_set, shadow_cib, NULL, TRUE);
rc = update_dataset(shadow_cib, data_set, FALSE);
- cib_delete(shadow_cib);
- /* unlink(shadow_file); */
- free(shadow_file);
-
} else {
cluster_status(data_set);
}
+ cleanup:
+ cib_delete(shadow_cib);
+ free_xml(cib_xml_copy);
+ free(pid);
+
+ if(shadow_file) {
+ unlink(shadow_file);
+ free(shadow_file);
+ }
+
return rc;
}
static int
-max_delay_in(pe_working_set_t * data_set, GList *resources)
+max_delay_for_resource(pe_working_set_t * data_set, resource_t *rsc)
{
+ int delay = 0;
int max_delay = 0;
- GList *item = NULL;
- for (item = resources; item != NULL; item = item->next) {
- resource_t *rsc = pe_find_resource(data_set->resources, (const char *)item->data);
+ if(rsc && rsc->children) {
+ GList *iter = NULL;
- if(rsc) {
- char *key = g_strdup_printf("%s_%s_0", rsc->id, RSC_STOP);
- action_t *stop = custom_action(rsc, key, RSC_STOP, NULL, TRUE, FALSE, data_set);
- const char *value = g_hash_table_lookup(stop->meta, XML_ATTR_TIMEOUT);
- int delay = crm_int_helper(value, NULL);
+ for(iter = rsc->children; iter; iter = iter->next) {
+ resource_t *child = (resource_t *)iter->data;
+ delay = max_delay_for_resource(data_set, child);
if(delay > max_delay) {
- crm_trace("Calculated new delay of %s ms due to %s", value, rsc->id);
+ double seconds = delay / 1000;
+ crm_trace("Calculated new delay of %.1fs due to %s", seconds, child->id);
max_delay = delay;
}
-
- pe_free_action(stop);
}
+
+ } else if(rsc) {
+ char *key = g_strdup_printf("%s_%s_0", rsc->id, RSC_STOP);
+ action_t *stop = custom_action(rsc, key, RSC_STOP, NULL, TRUE, FALSE, data_set);
+ const char *value = g_hash_table_lookup(stop->meta, XML_ATTR_TIMEOUT);
+
+ max_delay = crm_int_helper(value, NULL);
+ pe_free_action(stop);
}
+ return max_delay;
+}
+
+static int
+max_delay_in(pe_working_set_t * data_set, GList *resources)
+{
+ int max_delay = 0;
+ GList *item = NULL;
+
+ for (item = resources; item != NULL; item = item->next) {
+ int delay = 0;
+ resource_t *rsc = pe_find_resource(data_set->resources, (const char *)item->data);
+
+ delay = max_delay_for_resource(data_set, rsc);
+
+ if(delay > max_delay) {
+ double seconds = delay / 1000;
+ crm_trace("Calculated new delay of %.1fs due to %s", seconds, rsc->id);
+ max_delay = delay;
+ }
+ }
+
return 5 + (max_delay / 1000);
}
@@ -1507,7 +1544,7 @@ resource_restart(resource_t * rsc, const char *host, int timeout_ms, cib_t * cib
return -ENXIO;
}
-
+ attr_set_type = XML_TAG_META_SETS;
rsc_id = strdup(rsc->id);
if(rsc->variant > pe_group) {
is_clone = TRUE;
@@ -1536,6 +1573,7 @@ resource_restart(resource_t * rsc, const char *host, int timeout_ms, cib_t * cib
rc = update_dataset(cib, &data_set, FALSE);
if(rc != pcmk_ok) {
fprintf(stdout, "Could not get new resource list: %s (%d)\n", pcmk_strerror(rc), rc);
+ free(rsc_id);
return rc;
}
@@ -1553,6 +1591,7 @@ resource_restart(resource_t * rsc, const char *host, int timeout_ms, cib_t * cib
}
if(rc != pcmk_ok) {
fprintf(stderr, "Could not set target-role for %s: %s (%d)\n", rsc_id, pcmk_strerror(rc), rc);
+ free(rsc_id);
return crm_exit(rc);
}
@@ -1615,6 +1654,7 @@ resource_restart(resource_t * rsc, const char *host, int timeout_ms, cib_t * cib
if(rc != pcmk_ok) {
fprintf(stderr, "Could not unset target-role for %s: %s (%d)\n", rsc_id, pcmk_strerror(rc), rc);
+ free(rsc_id);
return crm_exit(rc);
}
@@ -1659,6 +1699,7 @@ resource_restart(resource_t * rsc, const char *host, int timeout_ms, cib_t * cib
} while(g_list_length(list_delta) > 0);
+ free(rsc_id);
return pcmk_ok;
failure:
@@ -1668,6 +1709,7 @@ resource_restart(resource_t * rsc, const char *host, int timeout_ms, cib_t * cib
} else {
delete_resource_attr(rsc_id, NULL, NULL, XML_RSC_ATTR_TARGET_ROLE, cib, &data_set);
}
+ free(rsc_id);
return rc;
}