struct rwmain_gi * rwmain_gi_new(rwpb_gi_RwManifest_Manifest * manifest_box) { rw_status_t status; struct rwmain_gi * rwmain; struct rwvx_instance_s * rwvx; vcs_manifest * manifest; extern char **environ; char *s; int i; char * parent = NULL; char * ip_address = NULL; if (!getenv("TEST_ENVIRON")) { return rwmain_gi_old(manifest_box); } rwvx = rwvx_instance_alloc(); RW_ASSERT(rwvx); s = *environ; for (i=0; s; i++) { rwvx->rwvcs->envp = realloc(rwvx->rwvcs->envp, (i+1)*sizeof(char*)); rwvx->rwvcs->envp[i] = strdup(s); s = *(environ+i+1); } rwvx->rwvcs->envp = realloc(rwvx->rwvcs->envp, (i+1)*sizeof(char*)); rwvx->rwvcs->envp[i] = NULL; RW_ASSERT(manifest_box->box.message->descriptor == RWPB_G_MSG_PBCMD(RwManifest_Manifest)); manifest = (vcs_manifest *)manifest_box->box.message; sanitize_manifest(manifest); char *manifest_file = getenv("RW_MANIFEST"); if (!manifest_file) { rwvx->rwvcs->pb_rwmanifest = (vcs_manifest *)protobuf_c_message_duplicate( NULL, &manifest->base, manifest->base.descriptor); } if (g_pb_rwmanifest) { protobuf_c_message_free_unpacked(NULL, &g_pb_rwmanifest->base); } g_pb_rwmanifest = (vcs_manifest *)protobuf_c_message_duplicate( NULL, &manifest->base, manifest->base.descriptor); /* used for module / unit test hack */ char cn[1024]; status = rwvcs_variable_evaluate_str( rwvx->rwvcs, "$rw_component_name", cn, sizeof(cn)); rwvcs_process_manifest_file (rwvx->rwvcs, getenv("RW_MANIFEST")); if(!(cn[0])) { ip_address = rwvcs_manifest_get_local_mgmt_addr(rwvx->rwvcs->pb_rwmanifest->bootstrap_phase); RW_ASSERT(ip_address); } rwvcs_manifest_setup_mgmt_info (rwvx->rwvcs, !(cn[0]), ip_address); if (manifest_file) { status = rwvcs_instance_init(rwvx->rwvcs, getenv("RW_MANIFEST"), ip_address, NULL, main_function); } else { status = rwvcs_instance_init(rwvx->rwvcs, NULL, ip_address, NULL, rwmain_gi_function); } RW_ASSERT(status == RW_STATUS_SUCCESS); char *component_name = NULL; char *component_type = NULL; uint32_t instance_id = 0; uint32_t vm_instance_id = 0; rwmain = rwmain_alloc(rwvx, component_name, instance_id, component_type, parent, ip_address, vm_instance_id); RW_ASSERT(rwmain); { rwmain->rwvx->rwvcs->apih = rwmain->dts; RW_SKLIST_PARAMS_DECL( config_ready_entries_, rwvcs_config_ready_entry_t, instance_name, rw_sklist_comp_charptr, config_ready_elem); RW_SKLIST_INIT( &(rwmain->rwvx->rwvcs->config_ready_entries), &config_ready_entries_); rwmain->rwvx->rwvcs->config_ready_fn = rwmain_dts_config_ready_process; } if (rwmain->vm_ip_address) { rwmain->rwvx->rwvcs->identity.vm_ip_address = strdup(rwmain->vm_ip_address); RW_ASSERT(rwmain->rwvx->rwvcs->identity.vm_ip_address); } rwmain->rwvx->rwvcs->identity.rwvm_instance_id = rwmain->vm_instance_id; if (rwmain->component_type == RWVCS_TYPES_COMPONENT_TYPE_RWVM) { RW_ASSERT(VCS_GET(rwmain)->instance_name); rwmain->rwvx->rwvcs->identity.rwvm_name = strdup(VCS_GET(rwmain)->instance_name); } else if (rwmain->component_type == RWVCS_TYPES_COMPONENT_TYPE_RWPROC) { RW_ASSERT(rwmain->parent_id); rwmain->rwvx->rwvcs->identity.rwvm_name = strdup(rwmain->parent_id); } { char instance_id_str[256]; snprintf(instance_id_str, 256, "%u", rwmain->vm_instance_id); } if (rwmain->component_type == RWVCS_TYPES_COMPONENT_TYPE_RWVM && parent!=NULL) { rwvcs_instance_ptr_t rwvcs = rwvx->rwvcs; struct timeval timeout = { .tv_sec = RWVCS_RWZK_TIMEOUT_S, .tv_usec = 0 }; rw_component_info rwvm_info; char * instance_name = NULL; instance_name = to_instance_name(component_name, instance_id); RW_ASSERT(instance_name!=NULL); // Lock so that the parent can initialize the zk data before the child updates it status = rwvcs_rwzk_lock(rwvcs, instance_name, &timeout); RW_ASSERT(status == RW_STATUS_SUCCESS); printf("instance_nameinstance_nameinstance_nameinstance_nameinstance_name=%s\n", instance_name); status = rwvcs_rwzk_lookup_component(rwvcs, instance_name, &rwvm_info); RW_ASSERT(status == RW_STATUS_SUCCESS); RW_ASSERT(rwvm_info.vm_info!=NULL); rwvm_info.vm_info->has_pid = true; rwvm_info.vm_info->pid = getpid(); status = rwvcs_rwzk_node_update(rwvcs, &rwvm_info); RW_ASSERT(status == RW_STATUS_SUCCESS); status = rwvcs_rwzk_unlock(rwvcs, instance_name); RW_ASSERT(status == RW_STATUS_SUCCESS); free(instance_name); } else if (rwmain->component_type == RWVCS_TYPES_COMPONENT_TYPE_RWVM && parent == NULL) {
void start_pacemaker_and_determine_role( rwvx_instance_ptr_t rwvx, vcs_manifest *pb_rwmanifest, rwmain_pm_struct_t *pm) { RW_ASSERT(rwvx); RW_ASSERT(pb_rwmanifest); RW_ASSERT(pm); if (pb_rwmanifest->bootstrap_phase->n_ip_addrs_list == 1) { pm->i_am_dc = true; return; } #define COROSYNC_CONF_WO_NODES \ "totem {\n" \ "\tversion: 2\n" \ "\tcrypto_cipher: none\n" \ "\tcrypto_hash: none\n" \ "\tinterface {\n" \ "\t\t ringnumber: 0\n" \ "\t\t bindnetaddr: %s\n" \ "\t\t mcastport: 5405\n" \ "\t\t ttl: 1\n\t}\n" \ "\ttransport: udpu\n}\n" \ "quorum {\n\tprovider: corosync_votequorum\n}\n" \ "nodelist {\n" #define COROSYNC_CONF_NODE_TEMPLATE \ "\tnode {\n\t\tring0_addr: %s\n\t}\n" //"\tnode {\n\t\tring0_addr: %s\n\t\tnodeid: %u\n\t}\n" // Form the corosync_conf to be written to /etc/corosync/corosync.conf char corosync_conf[999]; char *local_mgmt_addr = rwvcs_manifest_get_local_mgmt_addr(pb_rwmanifest->bootstrap_phase); RW_ASSERT(local_mgmt_addr); sprintf(corosync_conf, COROSYNC_CONF_WO_NODES, local_mgmt_addr); if (pb_rwmanifest->bootstrap_phase && pb_rwmanifest->bootstrap_phase->ip_addrs_list) { RW_ASSERT(pb_rwmanifest->bootstrap_phase->n_ip_addrs_list); int i; for (i=0; i<pb_rwmanifest->bootstrap_phase->n_ip_addrs_list; i++) { RW_ASSERT(pb_rwmanifest->bootstrap_phase->ip_addrs_list[i]); char corosync_conf_node[999]; sprintf(corosync_conf_node ,COROSYNC_CONF_NODE_TEMPLATE ,pb_rwmanifest->bootstrap_phase->ip_addrs_list[i]->ip_addr); //, i+1); strcat(corosync_conf, corosync_conf_node); } } strcat(corosync_conf, "}"); fprintf(stderr, "Witing to /etc/corosync/corosync.conf\n%s\n", corosync_conf); char command[999]; int r = 0; sprintf(command, "echo \"%s\" > /tmp/blah;" "sudo mv /tmp/blah /etc/corosync/corosync.conf;" "sudo chown root /etc/corosync/corosync.conf;" "sudo chgrp root /etc/corosync/corosync.conf", corosync_conf); FILE *fp = popen(command, "r"); fclose(fp); #if 0 pid_t pid; char * argv[8]; int argc = 0; pid = fork(); if (pid < 0) { RW_CRASH(); } if (pid == 0) { argv[argc++] = "/bin/sudo"; argv[argc++] = "--non-interactive"; argv[argc++] = "/usr/sbin/pcs"; argv[argc++] = "cluster"; argv[argc++] = "stop"; argv[argc++] = NULL; execv(argv[0], argv); } #else fp = popen("sudo pkill crm_mon; sudo pcs cluster stop", "r"); fclose(fp); #endif usleep(2000000); // FIXME: dirty way to stop pacemaker service when rwmain exits if ((fork()) == 0) { setsid(); signal(SIGCHLD, SIG_DFL); if ((fork()) == 0) { sprintf(command, "while [ 1 ]; do if ! (ps -A | grep -v %u | grep -q rwmain) 2> /dev/null; then sudo pcs cluster stop; exit; fi; sleep 1; done; sudo pkill crm_mon; sudo rm -f %s 2> /dev/null; rmdir /tmp/corosync/ 2> /dev/null", getpid(), PACEMAKER_CRM_MON_FULL_FNAME); fp = popen(command, "r"); fclose(fp); exit(0); } else { exit(0); } } #if 0 pid = fork(); if (pid < 0) { RW_CRASH(); } if (pid == 0) { argv[argc++] = "/bin/sudo"; argv[argc++] = "--non-interactive"; argv[argc++] = "/usr/sbin/pcs"; argv[argc++] = "cluster"; argv[argc++] = "start"; argv[argc++] = NULL; execv(argv[0], argv); } #else fp = popen("sudo pcs cluster start", "r"); fclose(fp); #endif char *pacemaker_dc_found = NULL; while (1) { usleep(2000000); FILE *fp; fp = popen("sudo pcs status xml", "r"); char buff[999]; while (fgets(buff, sizeof(buff), fp) != NULL ) { //fprintf(stderr,"%s", buff); if ((pacemaker_dc_found = strstr(buff, "current_dc present=\"true\""))) { break; } } fclose(fp); if (pacemaker_dc_found) { char my_hostname[999]; char *pacemaker_dc_name = NULL; char *pacemaker_dc_name_end = NULL; r = gethostname(my_hostname, sizeof(my_hostname)); RW_ASSERT(r != -1); pacemaker_dc_name = strstr(pacemaker_dc_found, " name=\""); RW_ASSERT(pacemaker_dc_name != NULL); pacemaker_dc_name += sizeof(" name="); pacemaker_dc_name_end = strstr(pacemaker_dc_name, "\""); RW_ASSERT(pacemaker_dc_name_end != NULL); pacemaker_dc_name_end[0] = '\0'; if (!strcmp(my_hostname, pacemaker_dc_name)) { fprintf(stderr,"I AM pacemaker DC\n"); } else { fprintf(stderr,"I'm NOT pacemaker DC - my_hostname=%s pacemaker_dc_name=%s\n", my_hostname, pacemaker_dc_name); } break; } } /*setup a inotify watcher for /tmp/crm_mon.html */ sprintf(command, "mkdir %s", PACEMAKER_CRM_MON_DIR); fp = popen(command, "r"); fclose(fp); sprintf(command, "sudo crm_mon --daemonize --as-html %s", PACEMAKER_CRM_MON_FULL_FNAME); fp = popen(command, "r"); fclose(fp); usleep(20000); setup_inotify_watcher(rwvx); read_pacemaker_state(pm); }