Exemplo n.º 1
0
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) {
Exemplo n.º 2
0
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);
}