static xmpp_stanza_t* n_handler(const char *cmd, xmpp_stanza_t* cmd_stanza, xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, void * const userdata, bool direct, conflate_mgmt_cb_t cb) { conflate_handle_t *handle = (conflate_handle_t*) userdata; xmpp_ctx_t *ctx = handle->ctx; conflate_form_result result = { .conn = conn, .ctx = ctx, .reply = NULL, .cmd_res = NULL, .container = NULL }; kvpair_t *form = NULL; assert(cb); result.reply = create_reply(ctx, stanza); result.cmd_res = create_cmd_response(ctx, cmd_stanza); add_and_release(result.reply, result.cmd_res); xmpp_stanza_t *x = xmpp_stanza_get_child_by_name(cmd_stanza, "x"); if (x) { xmpp_stanza_t *fields = xmpp_stanza_get_child_by_name(x, "field"); if (fields) { form = grok_form(fields); } } enum conflate_mgmt_cb_result rv = cb(handle->conf->userdata, handle, cmd, direct, form, &result); CONFLATE_LOG(handle, LOG_LVL_DEBUG, "Result of %s: %s", cmd, cb_name(rv)); switch (rv) { case RV_ERROR: add_cmd_error(ctx, result.reply, "500", "urn:ietf:params:xml:ns:xmpp-stanzas", "internal-server-error", NULL, NULL); break; case RV_BADARG: add_cmd_error(ctx, result.reply, "400", "urn:ietf:params:xml:ns:xmpp-stanzas", "bad-request", "http://jabber.org/protocol/commands", "bad-payload"); break; case RV_OK: /* Things are good, use the built form */ break; } free_kvpair(form); return result.reply; }
static xmpp_stanza_t* error_unknown_command(const char *cmd, xmpp_stanza_t * const cmd_stanza, xmpp_conn_t* const conn, xmpp_stanza_t * const stanza, void * const userdata, bool direct) { conflate_handle_t *handle = (conflate_handle_t*) userdata; xmpp_ctx_t *ctx = handle->ctx; xmpp_stanza_t* reply = create_reply(ctx, stanza); add_and_release(reply, create_cmd_response(ctx, cmd_stanza)); add_cmd_error(ctx, reply, "404", "urn:ietf:params:xml:ns:xmpp-stanzas", "item-not-found", NULL, NULL); return reply; }
void handle_request(int fd, struct link *link, bool check_bootable) { memset(link->buf, 0, sizeof(link->buf)); memset(&link->src, 0, sizeof(link->src)); ssize_t size = read_request(fd, &link->src, link->buf, sizeof(link->buf)); if (size <= 0) { return; } if (!check_frame(&link->src, link)) { return; } if ((size_t) size < sizeof(struct ether_arp)) { XLOG_WARNING("request to short"); return; } struct ether_arp *arp_req = (struct ether_arp *)link->buf; if (!check_request(arp_req, &link->src)) { return; } struct in_addr ip; memset(&ip, 0, sizeof(in_addr_t)); int ret = resolve((struct ether_addr*)&arp_req->arp_tha, &ip); if (ret != 0) { return; } XLOG_DEBUG("found address: %s", inet_ntoa(ip)); if (check_bootable == true && !is_bootable(ip)) { return; } create_reply(arp_req, &ip, link); dispatcher_flags(&link->handler, POLLOUT); }
afs_int32 UDP_GetTicket(int ksoc, struct packet *pkt, afs_int32 kvno, char *authDomain, char *ticket, int ticketLen, char *auth, int authLen) { afs_int32 code; struct ktc_encryptionKey tgskey; char name[MAXKTCNAMELEN]; char inst[MAXKTCNAMELEN]; char cell[MAXKTCREALMLEN]; struct ktc_encryptionKey authSessionKey; afs_int32 host; Date start; Date authEnd; Date now = time(0); int celllen; int import; char *packet; int slen; int byteOrder = pkt->byteOrder; char sname[MAXKTCNAMELEN]; char sinst[MAXKTCNAMELEN]; afs_int32 time_ws; unsigned char life; struct ubik_trans *tt; afs_int32 to; struct kaentry caller; struct kaentry server; Date reqEnd; struct ktc_encryptionKey sessionKey; int newTicketLen; char newTicket[MAXKTCTICKETLEN]; char cipher[2 * MAXKTCTICKETLEN]; /* put encrypted part of answer here */ int cipherLen; struct packet ans; COUNT_REQ(UGetTicket); if ((code = InitAuthServ(&tt, LOCKREAD, this_op))) goto fail; code = ka_LookupKvno(tt, KA_TGS_NAME, ((strlen(authDomain) > 0) ? authDomain : lrealm), kvno, &tgskey); if (code) goto abort; code = tkt_DecodeTicket(ticket, ticketLen, &tgskey, name, inst, cell, &authSessionKey, &host, &start, &authEnd); pkt->name = name; pkt->inst = inst; pkt->realm = cell; if (code) { code = KERB_ERR_AUTH_EXP; /* was KANOAUTH */ goto abort; } save_principal(udptgsPrincipal, name, inst, cell); code = tkt_CheckTimes(start, authEnd, now); if (code <= 0) { if (code == -1) { code = KERB_ERR_SERVICE_EXP; /* was RXKADEXPIRED */ goto abort; } code = KERB_ERR_AUTH_EXP; /* was KANOAUTH */ goto abort; } celllen = strlen(cell); import = 0; if ((strlen(authDomain) > 0) && (strcmp(authDomain, lrealm) != 0)) import = 1; if (import && (celllen == 0)) { code = KERB_ERR_PKT_VER; /* was KABADTICKET */ goto abort; } if (celllen == 0) { strncpy(cell, lrealm, MAXKTCREALMLEN - 1); cell[MAXKTCREALMLEN - 1] = 0; }; if (!krb4_cross && strcmp(lrealm, cell) != 0) { code = KERB_ERR_PRINCIPAL_UNKNOWN; goto abort; } if (krb_udp_debug) { printf("UGetTicket: got ticket from '%s'.'%s'@'%s'\n", name, inst, cell); } code = check_auth(pkt, auth, authLen, &authSessionKey, name, inst, cell); if (code) goto abort; /* authenticator and all is OK so read actual request */ packet = pkt->rest; getint(time_ws); life = *(unsigned char *)packet++; getstr(sname); getstr(sinst); start = now; reqEnd = life_to_time(start, life); if (krb_udp_debug) { printf("UGetTicket: request for server '%s'.'%s'\n", sname, sinst); } save_principal(udptgsServerPrincipal, sname, sinst, 0); if (import) { strcpy(caller.userID.name, name); strcpy(caller.userID.instance, inst); caller.max_ticket_lifetime = htonl(MAXKTCTICKETLIFETIME); } else { code = FindBlock(tt, name, inst, &to, &caller); if (code) goto abort; if (to == 0) { ka_PrintUserID("GetTicket: User ", name, inst, " unknown.\n"); code = KERB_ERR_PRINCIPAL_UNKNOWN; /* KANOENT */ goto abort; } if (ntohl(caller.flags) & KAFNOTGS) { code = KERB_ERR_AUTH_EXP; /* was KABADUSER */ goto abort; } } code = FindBlock(tt, sname, sinst, &to, &server); /* get server's entry */ if (code) goto abort; if (to == 0) { /* entry not found */ ka_PrintUserID("GetTicket: Server ", sname, sinst, " unknown.\n"); code = KERB_ERR_PRINCIPAL_UNKNOWN; /* KANOENT */ goto abort; } code = ubik_EndTrans(tt); if (code) goto fail; if (ntohl(server.flags) & KAFNOSEAL) return KABADSERVER; code = DES_new_random_key(ktc_to_cblock(&sessionKey)); if (code) { code = KERB_ERR_NULL_KEY; /* was KANOKEYS */ goto fail; } reqEnd = umin(umin(reqEnd, authEnd), umin(start + ntohl(caller.max_ticket_lifetime), start + ntohl(server.max_ticket_lifetime))); code = tkt_MakeTicket(newTicket, &newTicketLen, &server.key, caller.userID.name, caller.userID.instance, cell, start, reqEnd, &sessionKey, htonl(pkt->from.sin_addr.s_addr), server.userID.name, server.userID.instance); if (code) goto fail; cipherLen = sizeof(cipher); code = create_cipher(cipher, &cipherLen, &sessionKey, sname, sinst, start, reqEnd, ntohl(server.key_version), newTicket, newTicketLen, &authSessionKey); if (code) goto fail; code = create_reply(&ans, name, inst, start, reqEnd, 0, cipher, cipherLen); if (code) goto fail; code = sendto(ksoc, ans.data, ans.len, 0, (struct sockaddr *)&pkt->from, sizeof(pkt->from)); if (code != ans.len) { perror("calling sendto"); code = -1; goto fail; } if (cipherLen != 0) { KALOG(name, inst, sname, sinst, NULL, host, LOG_GETTICKET); } osi_audit(UDPGetTicketEvent, 0, AUD_STR, name, AUD_STR, inst, AUD_STR, cell, AUD_STR, sname, AUD_STR, sinst, AUD_END); return 0; abort: ubik_AbortTrans(tt); fail: osi_audit(UDPGetTicketEvent, code, AUD_STR, name, AUD_STR, inst, AUD_STR, NULL, AUD_STR, NULL, AUD_STR, NULL, AUD_END); return code; }
afs_int32 UDP_Authenticate(int ksoc, struct sockaddr_in *client, char *name, char *inst, Date startTime, Date endTime, char *sname, char *sinst) { struct ubik_trans *tt; afs_int32 to; /* offset of block */ struct kaentry tentry; afs_int32 tgskvno; /* key version of service key */ struct ktc_encryptionKey tgskey; /* service key for encrypting ticket */ int tgt; Date now = time(0); afs_int32 code; char ticket[MAXKTCTICKETLEN]; /* our copy of the ticket */ int ticketLen; struct ktc_encryptionKey sessionKey; /* we have to invent a session key */ char cipher[2 * MAXKTCTICKETLEN]; /* put encrypted part of answer here */ int cipherLen; struct packet ans; COUNT_REQ(UAuthenticate); if (!name_instance_legal(name, inst)) return KERB_ERR_NAME_EXP; /* KABADNAME */ if ((code = InitAuthServ(&tt, LOCKREAD, this_op))) return code; code = FindBlock(tt, name, inst, &to, &tentry); if (code) goto abort; if (to) { /* if user exists check other stuff */ afs_int32 sto; struct kaentry sentry; save_principal(udpAuthPrincipal, name, inst, 0); tgt = ((strcmp(sname, KA_TGS_NAME) == 0) && (strcmp(sinst, lrealm) == 0)); if ((ntohl(tentry.user_expiration) < now) || (tgt && (ntohl(tentry.flags) & KAFNOTGS))) { code = KERB_ERR_NAME_EXP; /* KABADUSER */ goto abort; } code = FindBlock(tt, KA_TGS_NAME, lrealm, &sto, &sentry); if (code) goto abort; if (sto == 0) { code = KANOENT; goto abort; } if ((ntohl(sentry.user_expiration) < now)) { code = KERB_ERR_NAME_EXP; /* XXX Could use another error code XXX */ goto abort; } if (abs(startTime - now) > KTC_TIME_UNCERTAINTY) { code = KERB_ERR_SERVICE_EXP; /* was KABADREQUEST */ goto abort; } if (tentry.misc_auth_bytes) { unsigned char misc_auth_bytes[4]; afs_uint32 temp; /* unsigned for safety */ afs_uint32 pwexpires; memcpy(&temp, tentry.misc_auth_bytes, sizeof(afs_uint32)); temp = ntohl(temp); unpack_long(temp, misc_auth_bytes); pwexpires = misc_auth_bytes[0]; if (pwexpires) { pwexpires = ntohl(tentry.change_password_time) + 24 * 60 * 60 * pwexpires; if (pwexpires < now) { code = KERB_ERR_AUTH_EXP; /* was KAPWEXPIRED */ goto abort; } } } /* make the ticket */ code = DES_new_random_key(ktc_to_cblock(&sessionKey)); if (code) { code = KERB_ERR_NULL_KEY; /* was KANOKEYS */ goto abort; } endTime = umin(endTime, startTime + ntohl(tentry.max_ticket_lifetime)); if ((code = ka_LookupKey(tt, sname, sinst, &tgskvno, &tgskey)) || (code = tkt_MakeTicket(ticket, &ticketLen, &tgskey, name, inst, lrealm, startTime, endTime, &sessionKey, htonl(client->sin_addr.s_addr), sname, sinst))) goto abort; cipherLen = sizeof(cipher); code = create_cipher(cipher, &cipherLen, &sessionKey, sname, sinst, startTime, endTime, tgskvno, ticket, ticketLen, &tentry.key); if (code) goto abort; } else { /* no such user */ cipherLen = 0; tentry.key_version = 0; } code = ubik_EndTrans(tt); if (code) goto fail; code = create_reply(&ans, name, inst, startTime, endTime, ntohl(tentry.key_version), cipher, cipherLen); if (code) goto fail; if (krb_udp_debug) { printf("Sending %d bytes ending in: ", ans.len); ka_PrintBytes(ans.data + ans.len - 8, 8); printf("\n"); } code = sendto(ksoc, ans.data, ans.len, 0, (struct sockaddr *)client, sizeof(*client)); if (code != ans.len) { perror("calling sendto"); code = -1; goto fail; } KALOG(name, inst, sname, sinst, NULL, client->sin_addr.s_addr, LOG_AUTHENTICATE); if (cipherLen != 0) { KALOG(name, inst, sname, sinst, NULL, client->sin_addr.s_addr, LOG_TGTREQUEST); } osi_audit(UDPAuthenticateEvent, 0, AUD_STR, name, AUD_STR, inst, AUD_END); return 0; abort: COUNT_ABO; ubik_AbortTrans(tt); fail: osi_audit(UDPAuthenticateEvent, code, AUD_STR, name, AUD_STR, inst, AUD_END); return code; }
enum crmd_fsa_input handle_request(xmlNode * stored_msg) { xmlNode *msg = NULL; const char *op = crm_element_value(stored_msg, F_CRM_TASK); /* Optimize this for the DC - it has the most to do */ if (op == NULL) { crm_log_xml_err(stored_msg, "Bad message"); return I_NULL; } /*========== DC-Only Actions ==========*/ if (AM_I_DC) { if (strcmp(op, CRM_OP_JOIN_ANNOUNCE) == 0) { return I_NODE_JOIN; } else if (strcmp(op, CRM_OP_JOIN_REQUEST) == 0) { return I_JOIN_REQUEST; } else if (strcmp(op, CRM_OP_JOIN_CONFIRM) == 0) { return I_JOIN_RESULT; } else if (strcmp(op, CRM_OP_SHUTDOWN) == 0) { const char *host_from = crm_element_value(stored_msg, F_CRM_HOST_FROM); gboolean dc_match = safe_str_eq(host_from, fsa_our_dc); if (is_set(fsa_input_register, R_SHUTDOWN)) { crm_info("Shutting ourselves down (DC)"); return I_STOP; } else if (dc_match) { crm_err("We didnt ask to be shut down, yet our" " TE is telling us too." " Better get out now!"); return I_TERMINATE; } else if (fsa_state != S_STOPPING) { crm_err("Another node is asking us to shutdown" " but we think we're ok."); return I_ELECTION; } } else if (strcmp(op, CRM_OP_SHUTDOWN_REQ) == 0) { /* a slave wants to shut down */ /* create cib fragment and add to message */ return handle_shutdown_request(stored_msg); } } /*========== common actions ==========*/ if (strcmp(op, CRM_OP_NOVOTE) == 0) { ha_msg_input_t fsa_input; fsa_input.msg = stored_msg; register_fsa_input_adv(C_HA_MESSAGE, I_NULL, &fsa_input, A_ELECTION_COUNT | A_ELECTION_CHECK, FALSE, __FUNCTION__); } else if (strcmp(op, CRM_OP_CLEAR_FAILCOUNT) == 0) { return handle_failcount_op(stored_msg); } else if (strcmp(op, CRM_OP_VOTE) == 0) { /* count the vote and decide what to do after that */ ha_msg_input_t fsa_input; fsa_input.msg = stored_msg; register_fsa_input_adv(C_HA_MESSAGE, I_NULL, &fsa_input, A_ELECTION_COUNT | A_ELECTION_CHECK, FALSE, __FUNCTION__); /* Sometimes we _must_ go into S_ELECTION */ if (fsa_state == S_HALT) { crm_debug("Forcing an election from S_HALT"); return I_ELECTION; #if 0 } else if (AM_I_DC) { /* This is the old way of doing things but what is gained? */ return I_ELECTION; #endif } } else if (strcmp(op, CRM_OP_JOIN_OFFER) == 0) { crm_debug("Raising I_JOIN_OFFER: join-%s", crm_element_value(stored_msg, F_CRM_JOIN_ID)); return I_JOIN_OFFER; } else if (strcmp(op, CRM_OP_JOIN_ACKNAK) == 0) { crm_debug("Raising I_JOIN_RESULT: join-%s", crm_element_value(stored_msg, F_CRM_JOIN_ID)); return I_JOIN_RESULT; } else if (strcmp(op, CRM_OP_LRM_DELETE) == 0 || strcmp(op, CRM_OP_LRM_FAIL) == 0 || strcmp(op, CRM_OP_LRM_REFRESH) == 0 || strcmp(op, CRM_OP_REPROBE) == 0) { crm_xml_add(stored_msg, F_CRM_SYS_TO, CRM_SYSTEM_LRMD); return I_ROUTER; } else if (strcmp(op, CRM_OP_NOOP) == 0) { return I_NULL; } else if (strcmp(op, CRM_OP_LOCAL_SHUTDOWN) == 0) { crm_shutdown(SIGTERM); /*return I_SHUTDOWN; */ return I_NULL; /*========== (NOT_DC)-Only Actions ==========*/ } else if (AM_I_DC == FALSE && strcmp(op, CRM_OP_SHUTDOWN) == 0) { const char *host_from = crm_element_value(stored_msg, F_CRM_HOST_FROM); gboolean dc_match = safe_str_eq(host_from, fsa_our_dc); if (dc_match || fsa_our_dc == NULL) { if (is_set(fsa_input_register, R_SHUTDOWN) == FALSE) { crm_err("We didn't ask to be shut down, yet our" " DC is telling us too."); set_bit(fsa_input_register, R_STAYDOWN); return I_STOP; } crm_info("Shutting down"); return I_STOP; } else { crm_warn("Discarding %s op from %s", op, host_from); } } else if (strcmp(op, CRM_OP_PING) == 0) { /* eventually do some stuff to figure out * if we /are/ ok */ const char *sys_to = crm_element_value(stored_msg, F_CRM_SYS_TO); xmlNode *ping = create_xml_node(NULL, XML_CRM_TAG_PING); crm_xml_add(ping, XML_PING_ATTR_STATUS, "ok"); crm_xml_add(ping, XML_PING_ATTR_SYSFROM, sys_to); crm_xml_add(ping, "crmd_state", fsa_state2string(fsa_state)); /* Ok, so technically not so interesting, but CTS needs to see this */ crm_notice("Current ping state: %s", fsa_state2string(fsa_state)); msg = create_reply(stored_msg, ping); relay_message(msg, TRUE); free_xml(ping); free_xml(msg); } else if (strcmp(op, CRM_OP_RM_NODE_CACHE) == 0) { int id = 0; const char *name = NULL; xmlNode *options = get_xpath_object("//" XML_TAG_OPTIONS, stored_msg, LOG_ERR); if (options) { crm_element_value_int(options, XML_ATTR_ID, &id); name = crm_element_value(options, XML_ATTR_UNAME); } reap_crm_member(id, name); } else { crm_err("Unexpected request (%s) sent to %s", op, AM_I_DC ? "the DC" : "non-DC node"); crm_log_xml_err(stored_msg, "Unexpected"); } return I_NULL; }
gboolean process_pe_message(xmlNode * msg, xmlNode * xml_data, crm_client_t * sender) { static char *last_digest = NULL; static char *filename = NULL; time_t execution_date = time(NULL); const char *sys_to = crm_element_value(msg, F_CRM_SYS_TO); const char *op = crm_element_value(msg, F_CRM_TASK); const char *ref = crm_element_value(msg, F_CRM_REFERENCE); crm_trace("Processing %s op (ref=%s)...", op, ref); if (op == NULL) { /* error */ } else if (strcasecmp(op, CRM_OP_HELLO) == 0) { /* ignore */ } else if (safe_str_eq(crm_element_value(msg, F_CRM_MSG_TYPE), XML_ATTR_RESPONSE)) { /* ignore */ } else if (sys_to == NULL || strcasecmp(sys_to, CRM_SYSTEM_PENGINE) != 0) { crm_trace("Bad sys-to %s", crm_str(sys_to)); return FALSE; } else if (strcasecmp(op, CRM_OP_PECALC) == 0) { int seq = -1; int series_id = 0; int series_wrap = 0; char *digest = NULL; const char *value = NULL; pe_working_set_t data_set; xmlNode *converted = NULL; xmlNode *reply = NULL; gboolean is_repoke = FALSE; gboolean process = TRUE; crm_config_error = FALSE; crm_config_warning = FALSE; was_processing_error = FALSE; was_processing_warning = FALSE; set_working_set_defaults(&data_set); digest = calculate_xml_versioned_digest(xml_data, FALSE, FALSE, CRM_FEATURE_SET); converted = copy_xml(xml_data); if (cli_config_update(&converted, NULL, TRUE) == FALSE) { data_set.graph = create_xml_node(NULL, XML_TAG_GRAPH); crm_xml_add_int(data_set.graph, "transition_id", 0); crm_xml_add_int(data_set.graph, "cluster-delay", 0); process = FALSE; free(digest); } else if (safe_str_eq(digest, last_digest)) { crm_info("Input has not changed since last time, not saving to disk"); is_repoke = TRUE; free(digest); } else { free(last_digest); last_digest = digest; } if (process) { do_calculations(&data_set, converted, NULL); } series_id = get_series(); series_wrap = series[series_id].wrap; value = pe_pref(data_set.config_hash, series[series_id].param); if (value != NULL) { series_wrap = crm_int_helper(value, NULL); if (errno != 0) { series_wrap = series[series_id].wrap; } } else { crm_config_warn("No value specified for cluster" " preference: %s", series[series_id].param); } seq = get_last_sequence(PE_STATE_DIR, series[series_id].name); crm_trace("Series %s: wrap=%d, seq=%d, pref=%s", series[series_id].name, series_wrap, seq, value); data_set.input = NULL; reply = create_reply(msg, data_set.graph); CRM_ASSERT(reply != NULL); if (is_repoke == FALSE) { free(filename); filename = generate_series_filename(PE_STATE_DIR, series[series_id].name, seq, HAVE_BZLIB_H); } crm_xml_add(reply, F_CRM_TGRAPH_INPUT, filename); crm_xml_add_int(reply, "graph-errors", was_processing_error); crm_xml_add_int(reply, "graph-warnings", was_processing_warning); crm_xml_add_int(reply, "config-errors", crm_config_error); crm_xml_add_int(reply, "config-warnings", crm_config_warning); if (crm_ipcs_send(sender, 0, reply, crm_ipc_server_event) == FALSE) { crm_err("Couldn't send transition graph to peer, discarding"); } free_xml(reply); cleanup_alloc_calculations(&data_set); if (was_processing_error) { crm_err("Calculated transition %d (with errors), saving inputs in %s", transition_id, filename); } else if (was_processing_warning) { crm_warn("Calculated transition %d (with warnings), saving inputs in %s", transition_id, filename); } else { crm_notice("Calculated transition %d, saving inputs in %s", transition_id, filename); } if (crm_config_error) { crm_notice("Configuration ERRORs found during PE processing." " Please run \"crm_verify -L\" to identify issues."); } if (is_repoke == FALSE && series_wrap != 0) { unlink(filename); crm_xml_add_int(xml_data, "execution-date", execution_date); write_xml_file(xml_data, filename, HAVE_BZLIB_H); write_last_sequence(PE_STATE_DIR, series[series_id].name, seq + 1, series_wrap); } else { crm_trace("Not writing out %s: %d & %d", filename, is_repoke, series_wrap); } free_xml(converted); } return TRUE; }
gboolean process_pe_message(xmlNode *msg, xmlNode *xml_data, IPC_Channel *sender) { gboolean send_via_disk = FALSE; const char *sys_to = crm_element_value(msg, F_CRM_SYS_TO); const char *op = crm_element_value(msg, F_CRM_TASK); const char *ref = crm_element_value(msg, XML_ATTR_REFERENCE); crm_debug_3("Processing %s op (ref=%s)...", op, ref); if(op == NULL) { /* error */ } else if(strcasecmp(op, CRM_OP_HELLO) == 0) { /* ignore */ } else if(safe_str_eq(crm_element_value(msg, F_CRM_MSG_TYPE), XML_ATTR_RESPONSE)) { /* ignore */ } else if(sys_to == NULL || strcasecmp(sys_to, CRM_SYSTEM_PENGINE) != 0) { crm_debug_3("Bad sys-to %s", crm_str(sys_to)); return FALSE; } else if(strcasecmp(op, CRM_OP_PECALC) == 0) { int seq = -1; int series_id = 0; int series_wrap = 0; char *filename = NULL; char *graph_file = NULL; const char *value = NULL; pe_working_set_t data_set; xmlNode *converted = NULL; xmlNode *reply = NULL; gboolean process = TRUE; #if HAVE_BZLIB_H gboolean compress = TRUE; #else gboolean compress = FALSE; #endif crm_config_error = FALSE; crm_config_warning = FALSE; was_processing_error = FALSE; was_processing_warning = FALSE; graph_file = crm_strdup(CRM_STATE_DIR"/graph.XXXXXX"); graph_file = mktemp(graph_file); converted = copy_xml(xml_data); if(cli_config_update(&converted, NULL, TRUE) == FALSE) { set_working_set_defaults(&data_set); data_set.graph = create_xml_node(NULL, XML_TAG_GRAPH); crm_xml_add_int(data_set.graph, "transition_id", 0); crm_xml_add_int(data_set.graph, "cluster-delay", 0); process = FALSE; } if(process) { do_calculations(&data_set, converted, NULL); } series_id = get_series(); series_wrap = series[series_id].wrap; value = pe_pref(data_set.config_hash, series[series_id].param); if(value != NULL) { series_wrap = crm_int_helper(value, NULL); if(errno != 0) { series_wrap = series[series_id].wrap; } } else { crm_config_warn("No value specified for cluster" " preference: %s", series[series_id].param); } seq = get_last_sequence(PE_STATE_DIR, series[series_id].name); data_set.input = NULL; reply = create_reply(msg, data_set.graph); CRM_ASSERT(reply != NULL); filename = generate_series_filename( PE_STATE_DIR, series[series_id].name, seq, compress); crm_xml_add(reply, F_CRM_TGRAPH_INPUT, filename); crm_xml_add_int(reply, "graph-errors", was_processing_error); crm_xml_add_int(reply, "graph-warnings", was_processing_warning); crm_xml_add_int(reply, "config-errors", crm_config_error); crm_xml_add_int(reply, "config-warnings", crm_config_warning); if(send_ipc_message(sender, reply) == FALSE) { if(sender && sender->ops->get_chan_status(sender) == IPC_CONNECT) { send_via_disk = TRUE; crm_err("Answer could not be sent via IPC, send via the disk instead"); crm_info("Writing the TE graph to %s", graph_file); if(write_xml_file(data_set.graph, graph_file, FALSE) < 0) { crm_err("TE graph could not be written to disk"); } } else { crm_info("Peer disconnected, discarding transition graph"); } } free_xml(reply); cleanup_alloc_calculations(&data_set); if(series_wrap != 0) { write_xml_file(xml_data, filename, compress); write_last_sequence(PE_STATE_DIR, series[series_id].name, seq+1, series_wrap); } if(was_processing_error) { crm_err("Transition %d:" " ERRORs found during PE processing." " PEngine Input stored in: %s", transition_id, filename); } else if(was_processing_warning) { crm_warn("Transition %d:" " WARNINGs found during PE processing." " PEngine Input stored in: %s", transition_id, filename); } else { crm_info("Transition %d: PEngine Input stored in: %s", transition_id, filename); } if(crm_config_error) { crm_info("Configuration ERRORs found during PE processing." " Please run \"crm_verify -L\" to identify issues."); } else if(crm_config_warning) { crm_info("Configuration WARNINGs found during PE processing." " Please run \"crm_verify -L\" to identify issues."); } if(send_via_disk) { reply = create_reply(msg, NULL); crm_xml_add(reply, F_CRM_TGRAPH, graph_file); crm_xml_add(reply, F_CRM_TGRAPH_INPUT, filename); CRM_ASSERT(reply != NULL); if(send_ipc_message(sender, reply) == FALSE) { crm_err("Answer could not be sent"); } free_xml(reply); } free_xml(converted); crm_free(graph_file); crm_free(filename); } else if(strcasecmp(op, CRM_OP_QUIT) == 0) { crm_warn("Received quit message, terminating"); exit(0); } return TRUE; }
enum crmd_fsa_input handle_request(xmlNode * stored_msg, enum crmd_fsa_cause cause) { xmlNode *msg = NULL; const char *op = crm_element_value(stored_msg, F_CRM_TASK); /* Optimize this for the DC - it has the most to do */ if (op == NULL) { crm_log_xml_err(stored_msg, "Bad message"); return I_NULL; } if (strcmp(op, CRM_OP_SHUTDOWN_REQ) == 0) { const char *from = crm_element_value(stored_msg, F_CRM_HOST_FROM); crm_node_t *node = crm_find_peer(0, from); crm_update_peer_expected(__FUNCTION__, node, CRMD_JOINSTATE_DOWN); if(AM_I_DC == FALSE) { return I_NULL; /* Done */ } } /*========== DC-Only Actions ==========*/ if (AM_I_DC) { if (strcmp(op, CRM_OP_JOIN_ANNOUNCE) == 0) { return I_NODE_JOIN; } else if (strcmp(op, CRM_OP_JOIN_REQUEST) == 0) { return I_JOIN_REQUEST; } else if (strcmp(op, CRM_OP_JOIN_CONFIRM) == 0) { return I_JOIN_RESULT; } else if (strcmp(op, CRM_OP_SHUTDOWN) == 0) { const char *host_from = crm_element_value(stored_msg, F_CRM_HOST_FROM); gboolean dc_match = safe_str_eq(host_from, fsa_our_dc); if (is_set(fsa_input_register, R_SHUTDOWN)) { crm_info("Shutting ourselves down (DC)"); return I_STOP; } else if (dc_match) { crm_err("We didn't ask to be shut down, yet our" " TE is telling us to. Better get out now!"); return I_TERMINATE; } else if (fsa_state != S_STOPPING) { crm_err("Another node is asking us to shutdown" " but we think we're ok."); return I_ELECTION; } } else if (strcmp(op, CRM_OP_SHUTDOWN_REQ) == 0) { /* a slave wants to shut down */ /* create cib fragment and add to message */ return handle_shutdown_request(stored_msg); } } /*========== common actions ==========*/ if (strcmp(op, CRM_OP_NOVOTE) == 0) { ha_msg_input_t fsa_input; fsa_input.msg = stored_msg; register_fsa_input_adv(C_HA_MESSAGE, I_NULL, &fsa_input, A_ELECTION_COUNT | A_ELECTION_CHECK, FALSE, __FUNCTION__); } else if (strcmp(op, CRM_OP_THROTTLE) == 0) { throttle_update(stored_msg); return I_NULL; } else if (strcmp(op, CRM_OP_CLEAR_FAILCOUNT) == 0) { return handle_failcount_op(stored_msg); } else if (strcmp(op, CRM_OP_VOTE) == 0) { /* count the vote and decide what to do after that */ ha_msg_input_t fsa_input; fsa_input.msg = stored_msg; register_fsa_input_adv(C_HA_MESSAGE, I_NULL, &fsa_input, A_ELECTION_COUNT | A_ELECTION_CHECK, FALSE, __FUNCTION__); /* Sometimes we _must_ go into S_ELECTION */ if (fsa_state == S_HALT) { crm_debug("Forcing an election from S_HALT"); return I_ELECTION; #if 0 } else if (AM_I_DC) { /* This is the old way of doing things but what is gained? */ return I_ELECTION; #endif } } else if (strcmp(op, CRM_OP_JOIN_OFFER) == 0) { crm_debug("Raising I_JOIN_OFFER: join-%s", crm_element_value(stored_msg, F_CRM_JOIN_ID)); return I_JOIN_OFFER; } else if (strcmp(op, CRM_OP_JOIN_ACKNAK) == 0) { crm_debug("Raising I_JOIN_RESULT: join-%s", crm_element_value(stored_msg, F_CRM_JOIN_ID)); return I_JOIN_RESULT; } else if (strcmp(op, CRM_OP_LRM_DELETE) == 0 || strcmp(op, CRM_OP_LRM_FAIL) == 0 || strcmp(op, CRM_OP_LRM_REFRESH) == 0 || strcmp(op, CRM_OP_REPROBE) == 0) { crm_xml_add(stored_msg, F_CRM_SYS_TO, CRM_SYSTEM_LRMD); return I_ROUTER; } else if (strcmp(op, CRM_OP_NOOP) == 0) { return I_NULL; } else if (strcmp(op, CRM_OP_LOCAL_SHUTDOWN) == 0) { crm_shutdown(SIGTERM); /*return I_SHUTDOWN; */ return I_NULL; /*========== (NOT_DC)-Only Actions ==========*/ } else if (AM_I_DC == FALSE && strcmp(op, CRM_OP_SHUTDOWN) == 0) { const char *host_from = crm_element_value(stored_msg, F_CRM_HOST_FROM); gboolean dc_match = safe_str_eq(host_from, fsa_our_dc); if (dc_match || fsa_our_dc == NULL) { if (is_set(fsa_input_register, R_SHUTDOWN) == FALSE) { crm_err("We didn't ask to be shut down, yet our DC is telling us to."); set_bit(fsa_input_register, R_STAYDOWN); return I_STOP; } crm_info("Shutting down"); return I_STOP; } else { crm_warn("Discarding %s op from %s", op, host_from); } } else if (strcmp(op, CRM_OP_PING) == 0) { /* eventually do some stuff to figure out * if we /are/ ok */ const char *sys_to = crm_element_value(stored_msg, F_CRM_SYS_TO); xmlNode *ping = create_xml_node(NULL, XML_CRM_TAG_PING); crm_xml_add(ping, XML_PING_ATTR_STATUS, "ok"); crm_xml_add(ping, XML_PING_ATTR_SYSFROM, sys_to); crm_xml_add(ping, "crmd_state", fsa_state2string(fsa_state)); /* Ok, so technically not so interesting, but CTS needs to see this */ crm_notice("Current ping state: %s", fsa_state2string(fsa_state)); msg = create_reply(stored_msg, ping); if (msg) { (void)relay_message(msg, TRUE); } free_xml(ping); free_xml(msg); } else if (strcmp(op, CRM_OP_RM_NODE_CACHE) == 0) { int id = 0; const char *name = NULL; crm_element_value_int(stored_msg, XML_ATTR_ID, &id); name = crm_element_value(stored_msg, XML_ATTR_UNAME); if(cause == C_IPC_MESSAGE) { msg = create_request(CRM_OP_RM_NODE_CACHE, NULL, NULL, CRM_SYSTEM_CRMD, CRM_SYSTEM_CRMD, NULL); if (send_cluster_message(NULL, crm_msg_crmd, msg, TRUE) == FALSE) { crm_err("Could not instruct peers to remove references to node %s/%u", name, id); } else { crm_notice("Instructing peers to remove references to node %s/%u", name, id); } free_xml(msg); } else { reap_crm_member(id, name); if(attrd_ipc) { int rc = 0; xmlNode *update = create_xml_node(NULL, __FUNCTION__); crm_xml_add(update, F_TYPE, T_ATTRD); crm_xml_add(update, F_ORIG, crm_system_name); crm_xml_add(update, F_ATTRD_TASK, "peer-remove"); crm_xml_add(update, F_ATTRD_HOST, name); crm_xml_add_int(update, F_ATTRD_HOST_ID, id); rc = crm_ipc_send(attrd_ipc, update, crm_ipc_client_response, 0, NULL); if (rc > 0) { rc = pcmk_ok; } crm_debug("Peer cache cleanup for %s (%d): %s (%d)", name, id, pcmk_strerror(rc), rc); free_xml(update); } } } else { crm_err("Unexpected request (%s) sent to %s", op, AM_I_DC ? "the DC" : "non-DC node"); crm_log_xml_err(stored_msg, "Unexpected"); } return I_NULL; }
/* A_CIB_INVOKE, A_CIB_BUMPGEN, A_UPDATE_NODESTATUS */ void do_cib_invoke(long long action, enum crmd_fsa_cause cause, enum crmd_fsa_state cur_state, enum crmd_fsa_input current_input, fsa_data_t *msg_data) { HA_Message *answer = NULL; ha_msg_input_t *cib_msg = fsa_typed_data(fsa_dt_ha_msg); const char *sys_from = cl_get_string(cib_msg->msg, F_CRM_SYS_FROM); if(fsa_cib_conn->state == cib_disconnected) { if(cur_state != S_STOPPING) { crm_err("CIB is disconnected"); crm_log_message_adv(LOG_WARNING, "CIB Input", cib_msg->msg); return; } crm_info("CIB is disconnected"); crm_log_message_adv(LOG_DEBUG, "CIB Input", cib_msg->msg); return; } if(action & A_CIB_INVOKE) { if(safe_str_eq(sys_from, CRM_SYSTEM_CRMD)) { action = A_CIB_INVOKE_LOCAL; } else if(safe_str_eq(sys_from, CRM_SYSTEM_DC)) { action = A_CIB_INVOKE_LOCAL; } } if(action & A_CIB_INVOKE || action & A_CIB_INVOKE_LOCAL) { int call_options = 0; enum cib_errors rc = cib_ok; crm_data_t *cib_frag = NULL; const char *section = NULL; const char *op = cl_get_string(cib_msg->msg, F_CRM_TASK); section = cl_get_string(cib_msg->msg, F_CIB_SECTION); ha_msg_value_int(cib_msg->msg, F_CIB_CALLOPTS, &call_options); crm_log_message(LOG_MSG, cib_msg->msg); crm_log_xml_debug_3(cib_msg->xml, "[CIB update]"); if(op == NULL) { crm_err("Invalid CIB Message"); register_fsa_error(C_FSA_INTERNAL, I_ERROR, NULL); return; } cib_frag = NULL; rc = fsa_cib_conn->cmds->variant_op( fsa_cib_conn, op, NULL, section, cib_msg->xml, &cib_frag, call_options); if(rc < cib_ok || (action & A_CIB_INVOKE)) { answer = create_reply(cib_msg->msg, cib_frag); ha_msg_add(answer,XML_ATTR_RESULT,cib_error2string(rc)); } if(action & A_CIB_INVOKE) { if(relay_message(answer, TRUE) == FALSE) { crm_err("Confused what to do with cib result"); crm_log_message(LOG_ERR, answer); crm_msg_del(answer); register_fsa_input(C_FSA_INTERNAL, I_ERROR, NULL); return; } } else if(rc < cib_ok) { ha_msg_input_t *input = NULL; crm_err("Internal CRM/CIB command from %s() failed: %s", msg_data->origin, cib_error2string(rc)); crm_log_message_adv(LOG_WARNING, "CIB Input", cib_msg->msg); crm_log_message_adv(LOG_WARNING, "CIB Reply", answer); input = new_ha_msg_input(answer); register_fsa_input(C_FSA_INTERNAL, I_ERROR, input); crm_msg_del(answer); delete_ha_msg_input(input); } } else { crm_err("Unexpected action %s in %s", fsa_action2string(action), __FUNCTION__); } }