struct timeval timeout;
unsigned int current;
- struct ctdb_scripts *scripts;
+ struct ctdb_scripts_wire *scripts;
};
-struct ctdb_script {
- const char *name;
- struct timeval start;
- struct timeval finished;
- int32_t status;
- char *output;
-};
-
-struct ctdb_scripts {
- uint32_t num_scripts;
- struct ctdb_script scripts[1];
-};
-
-static struct ctdb_script *get_current_script(struct ctdb_event_script_state *state)
+static struct ctdb_script_wire *get_current_script(struct ctdb_event_script_state *state)
{
return &state->scripts->scripts[state->current];
}
{
struct ctdb_event_script_state *state
= talloc_get_type(p, struct ctdb_event_script_state);
- struct ctdb_script *current = get_current_script(state);
-
- current->output = talloc_asprintf_append(current->output, "%*.*s", len, len, str);
-}
-
-static struct ctdb_scripts_wire *marshall_monitoring_scripts(TALLOC_CTX *mem_ctx, const struct ctdb_scripts *scripts, unsigned int num_scripts)
-{
- struct ctdb_scripts_wire *wire;
- unsigned int i;
-
- /* Overallocates by 1, but that's OK. */
- wire = talloc_zero_size(mem_ctx, sizeof(*wire) +
- sizeof(wire->scripts)*num_scripts);
- if (wire == NULL) {
- return NULL;
- }
+ struct ctdb_script_wire *current = get_current_script(state);
+ unsigned int slen, min;
- wire->num_scripts = num_scripts;
- for (i = 0; i < wire->num_scripts; i++) {
- strncpy(wire->scripts[i].name,
- scripts->scripts[i].name, MAX_SCRIPT_NAME);
- wire->scripts[i].start = scripts->scripts[i].start;
- wire->scripts[i].finished = scripts->scripts[i].finished;
- wire->scripts[i].status = scripts->scripts[i].status;
- if (scripts->scripts[i].output != NULL) {
- strncpy(wire->scripts[i].output,
- scripts->scripts[i].output, MAX_SCRIPT_OUTPUT);
- }
- }
+ /* Append, but don't overfill buffer. It starts zero-filled. */
+ slen = strlen(current->output);
+ min = MIN(len, sizeof(current->output) - slen - 1);
- return wire;
+ memcpy(current->output + slen, str, min);
}
/* called when all event script child processes are done */
}
talloc_free(ctdb->last_status);
- ctdb->last_status
- = marshall_monitoring_scripts(ctdb,
- ctdb->current_monitor->scripts,
- ctdb->current_monitor->current+1);
- if (ctdb->last_status == NULL) {
- DEBUG(DEBUG_ERR,(__location__ " failed to talloc last_status\n"));
- return -1;
+ ctdb->last_status = talloc_steal(ctdb, ctdb->current_monitor->scripts);
+ /* if we didn't finish all the scripts, trim status array. */
+ if (ctdb->current_monitor->current < ctdb->last_status->num_scripts) {
+ ctdb->last_status->num_scripts
+ = ctdb->current_monitor->current+1;
}
-
- talloc_free(ctdb->current_monitor->scripts);
ctdb->current_monitor->scripts = NULL;
return 0;
return true;
}
-static struct ctdb_scripts *ctdb_get_script_list(struct ctdb_context *ctdb, TALLOC_CTX *mem_ctx)
+static struct ctdb_scripts_wire *ctdb_get_script_list(struct ctdb_context *ctdb, TALLOC_CTX *mem_ctx)
{
DIR *dir;
struct dirent *de;
struct stat st;
trbt_tree_t *tree;
- struct ctdb_scripts *scripts;
+ struct ctdb_scripts_wire *scripts;
TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
struct ctdb_script_tree_item *tree_item;
int count;
continue;
}
+ if (strlen(de->d_name) > MAX_SCRIPT_NAME) {
+ DEBUG(DEBUG_ERR,("Script name %s too long! %u chars max",
+ de->d_name, MAX_SCRIPT_NAME));
+ continue;
+ }
+
tree_item = talloc(tree, struct ctdb_script_tree_item);
if (tree_item == NULL) {
DEBUG(DEBUG_ERR, (__location__ " Failed to allocate new tree item\n"));
closedir(dir);
/* Overallocates by one, but that's OK */
- scripts = talloc_size(tmp_ctx,
- sizeof(*scripts)
- + sizeof(scripts->scripts[0]) * count);
+ scripts = talloc_zero_size(tmp_ctx,
+ sizeof(*scripts)
+ + sizeof(scripts->scripts[0]) * count);
if (scripts == NULL) {
DEBUG(DEBUG_ERR, (__location__ " Failed to allocate scripts\n"));
talloc_free(tmp_ctx);
for (count = 0; count < scripts->num_scripts; count++) {
tree_item = trbt_findfirstarray32(tree, 1);
- scripts->scripts[count].name
- = talloc_steal(scripts, tree_item->name);
+ strcpy(scripts->scripts[count].name, tree_item->name);
scripts->scripts[count].status = -tree_item->error;
- scripts->scripts[count].output = talloc_strdup(scripts, "");
- if (scripts->scripts[count].output == NULL) {
- DEBUG(DEBUG_ERR, (__location__ " Failed to allocate new script output\n"));
- talloc_free(tmp_ctx);
- return NULL;
- }
+
/* remove this script from the tree */
talloc_free(tree_item);
}
bool from_user,
enum ctdb_eventscript_call call,
const char *options,
- struct ctdb_script *current)
+ struct ctdb_script_wire *current)
{
char *cmdstr;
int ret;
struct ctdb_event_script_state *state)
{
int r;
- struct ctdb_script *current = get_current_script(state);
+ struct ctdb_script_wire *current = get_current_script(state);
current->start = timeval_current();
return -errno;
}
- if (!ctdb_fork_with_logging(current->output, ctdb,
- log_event_script_output,
+ if (!ctdb_fork_with_logging(state, ctdb, log_event_script_output,
state, &state->child)) {
r = -errno;
close(state->fd[0]);
{
struct ctdb_event_script_state *state =
talloc_get_type(p, struct ctdb_event_script_state);
- struct ctdb_script *current = get_current_script(state);
+ struct ctdb_script_wire *current = get_current_script(state);
struct ctdb_context *ctdb = state->ctdb;
int r;