int join(commandline_t *comline, char *main_envp[]) { int i, err; int envptr = 0; int argvptr = 0; char scratch[1024]; char config_modules[1024]; cman_handle_t h = NULL; int status; hdb_handle_t object_handle; confdb_handle_t confdb_handle; int res; pid_t corosync_pid; int p[2]; confdb_callbacks_t callbacks = { .confdb_key_change_notify_fn = NULL, .confdb_object_create_change_notify_fn = NULL, .confdb_object_delete_change_notify_fn = NULL }; /* * If we can talk to cman then we're already joined (or joining); */ h = cman_admin_init(NULL); if (h) die("Node is already active"); /* Set up environment variables for override */ if (comline->multicast_addr) { snprintf(scratch, sizeof(scratch), "CMAN_MCAST_ADDR=%s", comline->multicast_addr); envp[envptr++] = strdup(scratch); } if (comline->votes_opt) { snprintf(scratch, sizeof(scratch), "CMAN_VOTES=%d", comline->votes); envp[envptr++] = strdup(scratch); } if (comline->expected_votes_opt) { snprintf(scratch, sizeof(scratch), "CMAN_EXPECTEDVOTES=%d", comline->expected_votes); envp[envptr++] = strdup(scratch); } if (comline->port) { snprintf(scratch, sizeof(scratch), "CMAN_IP_PORT=%d", comline->port); envp[envptr++] = strdup(scratch); } if (comline->nodeid) { snprintf(scratch, sizeof(scratch), "CMAN_NODEID=%d", comline->nodeid); envp[envptr++] = strdup(scratch); } if (comline->clustername_opt) { snprintf(scratch, sizeof(scratch), "CMAN_CLUSTER_NAME=%s", comline->clustername); envp[envptr++] = strdup(scratch); } if (comline->nodenames[0]) { snprintf(scratch, sizeof(scratch), "CMAN_NODENAME=%s", comline->nodenames[0]); envp[envptr++] = strdup(scratch); } if (comline->key_filename) { snprintf(scratch, sizeof(scratch), "CMAN_KEYFILE=%s", comline->key_filename); envp[envptr++] = strdup(scratch); } if (comline->two_node) { snprintf(scratch, sizeof(scratch), "CMAN_2NODE=true"); envp[envptr++] = strdup(scratch); } if (comline->verbose ^ DEBUG_STARTUP_ONLY) { snprintf(scratch, sizeof(scratch), "CMAN_DEBUG=%d", comline->verbose); envp[envptr++] = strdup(scratch); } if (comline->nostderr_debug) { snprintf(scratch, sizeof(scratch), "CMAN_NOSTDERR_DEBUG=true"); envp[envptr++] = strdup(scratch); } if (comline->noconfig_opt) { envp[envptr++] = strdup("CMAN_NOCONFIG=true"); snprintf(config_modules, sizeof(config_modules), "cmanpreconfig"); } else { snprintf(config_modules, sizeof(config_modules), "%s:cmanpreconfig", comline->config_lcrso); } if (comline->noopenais_opt) { envp[envptr++] = strdup("CMAN_NOOPENAIS=true"); } snprintf(scratch, sizeof(scratch), "COROSYNC_DEFAULT_CONFIG_IFACE=%s", config_modules); envp[envptr++] = strdup(scratch); /* Copy any COROSYNC_* env variables to the new daemon */ i=0; while (i < MAX_ARGS && main_envp[i]) { if (strncmp(main_envp[i], "COROSYNC_", 9) == 0) envp[envptr++] = main_envp[i]; i++; } /* Create a pipe to monitor cman startup progress */ if (pipe(p) < 0) die("unable to create pipe: %s", strerror(errno)); fcntl(p[1], F_SETFD, 0); /* Don't close on exec */ snprintf(scratch, sizeof(scratch), "CMAN_PIPE=%d", p[1]); envp[envptr++] = strdup(scratch); envp[envptr++] = NULL; /* Always run corosync -f because we have already forked twice anyway, and we want to return any exit code that might happen */ /* also strdup strings because it's otherwise virtually impossible to fix * build warnings due to the way argv C implementation is done */ argv[0] = strdup("corosync"); argv[++argvptr] = strdup("-f"); if (comline->nosetpri_opt) argv[++argvptr] = strdup("-p"); argv[++argvptr] = NULL; /* Fork/exec cman */ switch ( (corosync_pid = fork()) ) { case -1: die("fork of corosync daemon failed: %s", strerror(errno)); case 0: /* child */ close(p[0]); if (comline->verbose & DEBUG_STARTUP_ONLY) { fprintf(stderr, "Starting %s", COROSYNCBIN); for (i=0; i< argvptr; i++) { fprintf(stderr, " %s", argv[i]); } fprintf(stderr, "\n"); for (i=0; i<envptr-1; i++) { fprintf(stderr, "%s\n", envp[i]); } } be_daemon(); sprintf(scratch, "FORKED: %d\n", getpid()); err = write(p[1], scratch, strlen(scratch)); execve(COROSYNCBIN, argv, envp); /* exec failed - tell the parent process */ sprintf(scratch, "execve of " COROSYNCBIN " failed: %s", strerror(errno)); err = write(p[1], scratch, strlen(scratch)); exit(1); break; default: /* parent */ break; } /* Give the daemon a chance to start up, and monitor the pipe FD for messages */ i = 0; close(p[1]); /* Wait for the process to start or die */ sleep(1); do { fd_set fds; struct timeval tv={1, 0}; char message[1024]; char *messageptr = message; FD_ZERO(&fds); FD_SET(p[0], &fds); status = select(p[0]+1, &fds, NULL, NULL, &tv); /* Did we get a cman-reported error? */ if (status == 1) { int len; if ((len = read(p[0], message, sizeof(message)) > 0)) { /* Forked OK - get the real corosync pid */ if (sscanf(messageptr, "FORKED: %d", &corosync_pid) == 1) { if (comline->verbose & DEBUG_STARTUP_ONLY) fprintf(stderr, "forked process ID is %d\n", corosync_pid); status = 0; /* There might be a SUCCESS or error message in the pipe too. */ messageptr = strchr(messageptr, '\n'); if (messageptr && strlen(messageptr) > 1) messageptr++; else continue; } /* Success! get the new PID of double-forked corosync */ if (sscanf(messageptr, "SUCCESS: %d", &corosync_pid) == 1) { if (comline->verbose & DEBUG_STARTUP_ONLY) fprintf(stderr, "corosync running, process ID is %d\n", corosync_pid); status = 0; break; } else if (messageptr) { fprintf(stderr, "%s\n", messageptr); status = 1; break; } } else if (len < 0 && errno == EINTR) { continue; } else { /* Error or EOF - check the child status */ status = check_corosync_status(corosync_pid); if (status == 0) break; } } } while (status == 0); close(p[0]); /* If corosync has started, try to connect to cman ... if it's still there */ if (status == 0) { do { if (status == 0) { if (kill(corosync_pid, 0) < 0) { status = check_corosync_status(corosync_pid); die("corosync died during startup\n"); } h = cman_admin_init(NULL); if (!h && comline->verbose & DEBUG_STARTUP_ONLY) { fprintf(stderr, "waiting for cman to start\n"); status = check_corosync_status(corosync_pid); } } sleep (1); } while (!h && ++i < 100); } if (!h) die("corosync daemon didn't start"); if ((comline->verbose & DEBUG_STARTUP_ONLY) && !cman_is_active(h)) fprintf(stderr, "corosync started, but not joined the cluster yet.\n"); cman_finish(h); /* Copy all COROSYNC_* environment variables into objdb so they can be used to validate new configurations later */ res = confdb_initialize (&confdb_handle, &callbacks); if (res != CS_OK) goto join_exit; res = confdb_object_create(confdb_handle, OBJECT_PARENT_HANDLE, "cman_private", strlen("cman_private"), &object_handle); if (res == CS_OK) { int envnum = 0; const char *envvar = main_envp[envnum]; const char *equal; char envname[PATH_MAX]; while (envvar) { if (strncmp("COROSYNC_", envvar, 9) == 0) { equal = strchr(envvar, '='); if (equal) { strncpy(envname, envvar, PATH_MAX); if (equal-envvar < PATH_MAX) { envname[equal-envvar] = '\0'; res = confdb_key_create_typed(confdb_handle, object_handle, envname, equal+1, strlen(equal+1),CONFDB_VALUETYPE_STRING); } } } envvar = main_envp[++envnum]; } } res = confdb_key_create_typed(confdb_handle, object_handle, "COROSYNC_DEFAULT_CONFIG_IFACE", config_modules, strlen(config_modules), CONFDB_VALUETYPE_STRING); confdb_finalize (confdb_handle); join_exit: return 0; }
int main(int argc, char** argv) { int c; char *ubus_socket = UBUS_UNIX_SOCKET; #ifdef LOG_LEVEL_DEFAULT LOG_INIT(APP_NAME, LOG_LEVEL_DEFAULT, STDOUT); #else LOG_INIT(APP_NAME, LR_LOG_INFO, STDOUT); #endif while((c = getopt(argc, argv, "dl:")) != -1) { switch (c) { case 'd': become_daemon = 0; break; case 'l': { char *end; long l; l = strtoul(optarg, &end, 0); if(*optarg == 0 || *end != 0 || l > 10) { ERROR(DEFAULT_GROUP,"Invalid loglevel %s", optarg); exit(1); } SET_LOG_LEVEL(l); break; } default: return -1; } } if(become_daemon){ LOG_MODE(SYSLOG); openlog(APP_NAME, LOG_CONS | LOG_PID, LOG_LOCAL1); be_daemon(); } lpd_setup_signals(); pthread_create(&lpd_thread_id, NULL, (void *)loop_detect_run, NULL); if (loop_detect_ubus_init(ubus_socket) < 0) { ERROR(DEFAULT_GROUP, "failed to connect to ubus\n"); return -1; } loop_detect_ubus_run(); pthread_cancel(lpd_thread_id); pthread_join(lpd_thread_id, NULL); return 0; }
int main(int argc, char *argv[]) { int c; char *ubus_socket = UBUS_UNIX_SOCKET; #if 0 /* Sanity check */ { bridge_identifier_t BridgeIdentifier; mst_configuration_identifier_t MST_ConfigurationIdentifier; TST(sizeof(BridgeIdentifier) == 8, -1); TST(sizeof(BridgeIdentifier.u) == 8, -1); TST(sizeof(BridgeIdentifier.s) == 8, -1); TST(sizeof(BridgeIdentifier.s.priority) == 2, -1); TST(sizeof(BridgeIdentifier.s.mac_address) == 6, -1); TST(sizeof(MST_ConfigurationIdentifier) == 51, -1); TST(sizeof(MST_ConfigurationIdentifier.a) == 51, -1); TST(sizeof(MST_ConfigurationIdentifier.s) == 51, -1); #ifdef HMAC_MDS_TEST_FUNCTIONS TST(MD5TestSuite(), -1); #endif /* HMAC_MDS_TEST_FUNCTIONS */ INFO(GLOBAL_OUT_GROUP,"Sanity checks succeeded"); } #endif #ifdef LOG_LEVEL_DEFAULT LOG_INIT("mstpd", LOG_LEVEL_DEFAULT, STDOUT); #else LOG_INIT("mstpd", LR_LOG_INFO, STDOUT); #endif while((c = getopt(argc, argv, "dl:")) != -1) { switch (c) { case 'd': become_daemon = 0; break; case 'l': { char *end; long l; l = strtoul(optarg, &end, 0); if(*optarg == 0 || *end != 0 || l > 10) { ERROR(GLOBAL_OUT_GROUP,"Invalid loglevel %s", optarg); exit(1); } SET_LOG_LEVEL(l); break; } default: return -1; } } if(become_daemon){ LOG_MODE(SYSLOG); openlog(SERVICE_NAME, LOG_CONS | LOG_PID, LOG_LOCAL1); be_daemon(); } mstpd_setup_signals(); int ret,stacksize = 204800; pthread_attr_t attr; ret = pthread_attr_init(&attr); /*初始化线程属性*/ if (ret != 0){ return -1; } ret = pthread_attr_setstacksize(&attr, stacksize); if(ret != 0){ pthread_attr_destroy(&attr); return -1; } ret = pthread_attr_setschedpolicy(&attr, SCHED_FIFO); if(ret != 0){ pthread_attr_destroy(&attr); return -1; } #if 1 struct sched_param param; param.sched_priority = 90; ret = pthread_attr_setschedparam(&attr, ¶m); if(ret != 0){ pthread_attr_destroy(&attr); return -1; } #endif int err = pthread_create(&mstp_thread_id, &attr, (void *)mstpd_run, NULL); if (err != 0){ ERROR(GLOBAL_OUT_GROUP, "can't create thread: %s\n", strerror(err)); return -1; } if (mstpd_ubus_init(ubus_socket) < 0) { ERROR(GLOBAL_OUT_GROUP, "failed to connect to ubus\n"); pthread_cancel(mstp_thread_id); pthread_join(mstp_thread_id, NULL); pthread_attr_destroy(&attr); return -1; } mstpd_ubus_run(); pthread_cancel(mstp_thread_id); pthread_join(mstp_thread_id, NULL); pthread_attr_destroy(&attr); return 0; }