Beispiel #1
0
void
tengine_stonith_callback(stonith_t * stonith, const xmlNode * msg, int call_id, int rc,
                         xmlNode * output, void *userdata)
{
    char *uuid = NULL;
    int target_rc = -1;
    int stonith_id = -1;
    int transition_id = -1;
    crm_action_t *action = NULL;

    CRM_CHECK(userdata != NULL, return);
    crm_log_xml_trace(output, "StonithOp");
    crm_notice("Stonith operation %d/%s: %s (%d)", call_id, (char *)userdata,
             stonith_error2string(rc), rc);

    if (AM_I_DC == FALSE) {
        return;
    }
    /* crm_info("call=%d, optype=%d, node_name=%s, result=%d, node_list=%s, action=%s", */
    /*       op->call_id, op->optype, op->node_name, op->op_result, */
    /*       (char *)op->node_list, op->private_data); */

    /* filter out old STONITH actions */
    CRM_CHECK(decode_transition_key(userdata, &uuid, &transition_id, &stonith_id, &target_rc),
              crm_err("Invalid event detected");
              goto bail;
        );
Beispiel #2
0
void do_local_reply(xmlNode *notify_src, const char *client_id,
		     gboolean sync_reply, gboolean from_peer)
{
    /* send callback to originating child */
    stonith_client_t *client_obj = NULL;
    enum stonith_errors local_rc = stonith_ok;

    crm_trace("Sending response");

    if(client_id != NULL) {
	client_obj = g_hash_table_lookup(client_list, client_id);
    } else {
	crm_trace("No client to sent the response to."
		    "  F_STONITH_CLIENTID not set.");
    }
	
    crm_trace("Sending callback to request originator");
    if(client_obj == NULL) {
	local_rc = -1;
		
    } else {
	const char *client_id = client_obj->callback_id;
	crm_trace("Sending %ssync response to %s %s",
		    sync_reply?"":"an a-",
		    client_obj->name,
		    from_peer?"(originator of delegated request)":"");
		
	if(sync_reply) {
	    client_id = client_obj->id;
	}
	local_rc = send_via_callback_channel(notify_src, client_id);
    } 
	
    if(local_rc != stonith_ok && client_obj != NULL) {
	crm_warn("%sSync reply to %s failed: %s",
		 sync_reply?"":"A-",
		 client_obj?client_obj->name:"<unknown>", stonith_error2string(local_rc));
    }
}
Beispiel #3
0
static void
tengine_stonith_notify(stonith_t * st, const char *event, xmlNode * msg)
{
    int rc = -99;
    const char *origin = NULL;
    const char *target = NULL;
    const char *executioner = NULL;
    xmlNode *action = get_xpath_object("//st-data", msg, LOG_ERR);

    if (action == NULL) {
        crm_log_xml(LOG_ERR, "Notify data not found", msg);
        return;
    }

    crm_log_xml(LOG_DEBUG, "stonith_notify", msg);
    crm_element_value_int(msg, F_STONITH_RC, &rc);
    origin = crm_element_value(action, F_STONITH_ORIGIN);
    target = crm_element_value(action, F_STONITH_TARGET);
    executioner = crm_element_value(action, F_STONITH_DELEGATE);

    if (rc == stonith_ok && crm_str_eq(target, fsa_our_uname, TRUE)) {
        crm_err("We were alegedly just fenced by %s for %s!", executioner, origin);
        register_fsa_error_adv(C_FSA_INTERNAL, I_ERROR, NULL, NULL, __FUNCTION__);

    } else if (rc == stonith_ok) {
        crm_info("Peer %s was terminated (%s) by %s for %s (ref=%s): %s",
                 target,
                 crm_element_value(action, F_STONITH_OPERATION),
                 executioner, origin,
                 crm_element_value(action, F_STONITH_REMOTE), stonith_error2string(rc));
    } else {
        crm_err("Peer %s could not be terminated (%s) by %s for %s (ref=%s): %s",
                target,
                crm_element_value(action, F_STONITH_OPERATION),
                executioner ? executioner : "<anyone>", origin,
                crm_element_value(action, F_STONITH_REMOTE), stonith_error2string(rc));
    }

#ifdef SUPPORT_CMAN
    if (rc == stonith_ok && is_cman_cluster()) {
        int local_rc = 0;
        int confirm = 0;
        char *target_copy = crm_strdup(target);

        /* In case fenced hasn't noticed yet */
        local_rc = fenced_external(target_copy);
        if (local_rc != 0) {
            crm_err("Could not notify CMAN that '%s' is now fenced: %d", target, local_rc);
        } else {
            crm_notice("Notified CMAN that '%s' is now fenced", target);
        }

        /* In case fenced is already trying to shoot it */
        confirm = open("/var/run/cluster/fenced_override", O_NONBLOCK|O_WRONLY);
        if (confirm) {
            int len = strlen(target_copy);

            errno = 0;
            local_rc = write(confirm, target_copy, len);
            write(confirm, "\n", 1);

            if(errno == EBADF) {
                crm_trace("CMAN not expecting %s to be fenced (yet)", target);

            } else if (local_rc < len) {
                crm_perror(LOG_ERR, "Confirmation of CMAN fencing event for '%s' failed: %d", target, local_rc);

            } else {
                fsync(confirm);
                crm_notice("Confirmed CMAN fencing event for '%s'", target);
            }
            close(confirm);
        }
    }
#endif

    if (rc == stonith_ok && safe_str_eq(target, origin)) {
        if (fsa_our_dc == NULL || safe_str_eq(fsa_our_dc, target)) {
            crm_notice("Target was our leader %s (recorded: %s)",
                       target, fsa_our_dc ? fsa_our_dc : "<unset>");
            /* Given the CIB resyncing that occurs around elections,
             * have one node update the CIB now and, if the new DC is different,
             * have them do so too after the election
             */
            if (safe_str_eq(executioner, fsa_our_uname)) {
                const char *uuid = get_uuid(target);

                send_stonith_update(NULL, target, uuid);
            } else {
                stonith_cleanup_list = g_list_append(stonith_cleanup_list, crm_strdup(target));
            }
        }
    }
}
Beispiel #4
0
int
main(int argc, char ** argv)
{
    int flag;
    int rc = 0;
    int quiet = 0;
    int verbose = 0;
    int argerr = 0;
    int timeout = 120;
    int option_index = 0;
    int fence_level = 0;

    char name[512];
    char value[512];
    const char *agent = NULL;
    const char *device = NULL;
    const char *target = NULL;
    
    char action = 0;
    stonith_t *st = NULL;
    stonith_key_value_t *params = NULL;
    stonith_key_value_t *devices = NULL;
    stonith_key_value_t *dIter = NULL;
    
    crm_log_init(NULL, LOG_INFO, TRUE, FALSE, argc, argv);
    crm_set_options(NULL, "mode [options]", long_options,
		    "Provides access to the stonith-ng API.\n"
                    "\nAllows the administrator to add/remove/list devices, check device and host status and fence hosts\n");

    while (1) {
	flag = crm_get_option(argc, argv, &option_index);
	if (flag == -1)
	    break;
		
	switch(flag) {
	    case 'V':
		verbose = 1;
		crm_bump_log_level();
		break;
	    case '$':
	    case '?':
		crm_help(flag, LSB_EXIT_OK);
		break;
	    case 'L':
	    case 'I':
		action = flag;
		break;
	    case 'q':
		quiet = 1;
		break;
	    case 'Q':
	    case 'R':
	    case 'D':
		action = flag;
		device = optarg;
		break;
	    case 'a':
		agent = optarg;
		break;
	    case 'l':
		target = optarg;
		action = 'L';
		break;
	    case 'M':
		action = flag;
		break;
            case 't':
                timeout = crm_atoi(optarg, NULL);
                break;
	    case 'B':
	    case 'F':
	    case 'U':
	    case 'C':
	    case 'H':
	    case 'r':
	    case 'd':
		target = optarg;
		action = flag;
		break;
            case 'i':
                fence_level = crm_atoi(optarg, NULL);
                break;
            case 'v':
                devices = stonith_key_value_add(devices, NULL, optarg);
                break;
	    case 'o':
		crm_info("Scanning: -o %s", optarg);
		rc = sscanf(optarg, "%[^=]=%[^=]", name, value);
		if(rc != 2) {
		    crm_err("Invalid option: -o %s", optarg);
		    ++argerr;
		} else {
		    crm_info("Got: '%s'='%s'", name, value);
		    stonith_key_value_add(params, name, value);
		}
		break;
	    case 'e':
		{
		    char *key = crm_concat("OCF_RESKEY", optarg, '_');
		    const char *env = getenv(key);
		    
		    if(env == NULL) {
			crm_err("Invalid option: -e %s", optarg);
			++argerr;
		    } else {
			crm_info("Got: '%s'='%s'", optarg, env);
                        stonith_key_value_add( params, optarg, env);
		    }
		}
		break;
	    default:
		++argerr;
		break;
	}
    }

    if (optind > argc) {
	++argerr;
    }
    
    if (argerr) {
	crm_help('?', LSB_EXIT_GENERIC);
    }

    crm_debug("Create");
    st = stonith_api_new();

    if(action != 'M' && action != 'I') {
	rc = st->cmds->connect(st, crm_system_name, NULL);
	crm_debug("Connect: %d", rc);

	if(rc < 0) {
	    goto done;
	}
    }
    
    switch(action)
    {
	case 'I':
	    rc = st->cmds->list(st, st_opt_sync_call, NULL, &devices, timeout);
	    for(dIter = devices; dIter; dIter = dIter->next ) {
		fprintf( stdout, " %s\n", dIter->value );
	    }
	    if(rc == 0) {
		fprintf(stderr, "No devices found\n");

	    } else if(rc > 0) {
		fprintf(stderr, "%d devices found\n", rc);
		rc = 0;
	    }
	    stonith_key_value_freeall(devices, 1, 1);
	    break;
	    
	case 'L':
	    rc = st->cmds->query(st, st_opts, target, &devices, timeout);
	    for(dIter = devices; dIter; dIter = dIter->next ) {
		fprintf( stdout, " %s\n", dIter->value );
	    }
	    if(rc == 0) {
		fprintf(stderr, "No devices found\n");

	    } else if(rc > 0) {
		fprintf(stderr, "%d devices found\n", rc);
		rc = 0;
	    }
	    stonith_key_value_freeall(devices, 1, 1);
	    break;
	case 'Q':
	    rc = st->cmds->call(st, st_opts, device, "monitor", NULL, timeout);
	    if(rc < 0) {
		rc = st->cmds->call(st, st_opts, device, "list", NULL, timeout);
	    }
	    break;
	case 'R':
	    rc = st->cmds->register_device(st, st_opts, device, "stonith-ng",
                agent, params);
	    break;
	case 'D':
	    rc = st->cmds->remove_device(st, st_opts, device);
	    break;
	case 'r':
	    rc = st->cmds->register_level(st, st_opts, target, fence_level, devices);
	    break;
	case 'd':
	    rc = st->cmds->remove_level(st, st_opts, target, fence_level);
	    break;
	case 'M':
	    if (agent == NULL) {
		printf("Please specify an agent to query using -a,--agent [value]\n");
		return -1;
		
	    } else {
	        char *buffer = NULL;
		st->cmds->metadata(st, st_opt_sync_call, agent, NULL, &buffer, timeout);
		printf("%s\n", buffer);
		crm_free(buffer);
	    }
	    break;
	    
	case 'C':
	    rc = st->cmds->confirm(st, st_opts, target);
	    break;
	case 'B':
	    rc = st->cmds->fence(st, st_opts, target, "reboot", timeout);
	    break;
	case 'F':
	    rc = st->cmds->fence(st, st_opts, target, "off", timeout);
	    break;
	case 'U':
	    rc = st->cmds->fence(st, st_opts, target, "on", timeout);
	    break;
	case 'H':
	    {
		stonith_history_t *history, *hp, *latest = NULL;
		rc = st->cmds->history(st, st_opts, target, &history, timeout);
		for(hp = history; hp; hp = hp->next) {
		    char *action_s = NULL;
		    time_t complete = hp->completed;

		    if(hp->state == st_done) {
			latest = hp;
		    }

		    if(quiet || !verbose) {
			continue;
		    } else if(hp->action == NULL) {
			action_s = crm_strdup("unknown");
		    } else if(hp->action[0] != 'r') {
			action_s = crm_concat("turn", hp->action, ' ');
		    } else {
			action_s = crm_strdup(hp->action);
		    }
			
		    if(hp->state == st_failed) {
			printf("%s failed to %s node %s on behalf of %s at %s\n",
			       hp->delegate?hp->delegate:"We", action_s, hp->target, hp->origin,
			       ctime(&complete));

		    } else if(hp->state == st_done && hp->delegate) {
			printf("%s was able to %s node %s on behalf of %s at %s\n",
			       hp->delegate, action_s, hp->target, hp->origin, ctime(&complete));

		    } else if(hp->state == st_done) {
			printf("We were able to %s node %s on behalf of %s at %s\n",
			       action_s, hp->target, hp->origin, ctime(&complete));
		    } else {
			printf("%s wishes to %s node %s - %d %d\n",
			       hp->origin, action_s, hp->target, hp->state, hp->completed);
		    }
		    
		    crm_free(action_s);
	        }

		if(latest) {
		    if(quiet) {
			printf("%d\n", latest->completed);
		    } else {
			char *action_s = NULL;
			time_t complete = latest->completed;
			if(latest->action == NULL) {
			    action_s = crm_strdup("unknown");
			} else if(latest->action[0] != 'r') {
			    action_s = crm_concat("turn", latest->action, ' ');
			} else {
			    action_s = crm_strdup(latest->action);
			}
			
			printf("%s was able to %s node %s on behalf of %s at %s\n",
			       latest->delegate?latest->delegate:"We", action_s, latest->target,
			       latest->origin, ctime(&complete));
			
			crm_free(action_s);
		    }
		}
	    }
	    break;
    }    

  done:
    if(rc < 0) {
	printf("Command failed: %s\n", stonith_error2string(rc));
    }
    
    stonith_key_value_freeall(params, 1, 1);
    st->cmds->disconnect(st);
    crm_debug("Disconnect: %d", rc);

    crm_debug("Destroy");
    stonith_api_delete(st);
    
    return rc;
}