Esempio n. 1
0
ipmi_ctx_t
ipmi_open (const char *progname,
           const char *hostname,
           struct common_cmd_args *common_args,
	   pstdout_state_t pstate)
{
  ipmi_ctx_t ipmi_ctx = NULL;
  unsigned int workaround_flags = 0;

  assert (progname);
  assert (common_args);

  if (!(ipmi_ctx = ipmi_ctx_create ()))
    {
      PSTDOUT_FPRINTF (pstate,
		       stderr,
		       "ipmi_ctx_create: %s",
		       strerror (errno));
      goto cleanup;
    }

  if (hostname
      && strcasecmp (hostname, "localhost") != 0
      && strcmp (hostname, "127.0.0.1") != 0)
    {
      if (common_args->driver_type == IPMI_DEVICE_LAN_2_0)
        {
	  parse_get_freeipmi_outofband_2_0_flags (common_args->workaround_flags_outofband_2_0,
						  &workaround_flags);
          
          if (ipmi_ctx_open_outofband_2_0 (ipmi_ctx,
                                           hostname,
                                           common_args->username,
                                           common_args->password,
                                           (common_args->k_g_len) ? common_args->k_g : NULL,
                                           (common_args->k_g_len) ? common_args->k_g_len : 0,
                                           common_args->privilege_level,
                                           common_args->cipher_suite_id,
                                           common_args->session_timeout,
                                           common_args->retransmission_timeout,
                                           workaround_flags,
                                           (common_args->debug) ? IPMI_FLAGS_DEBUG_DUMP : IPMI_FLAGS_DEFAULT) < 0)
            {
              if (ipmi_ctx_errnum (ipmi_ctx) == IPMI_ERR_USERNAME_INVALID
                  || ipmi_ctx_errnum (ipmi_ctx) == IPMI_ERR_PASSWORD_INVALID
                  || ipmi_ctx_errnum (ipmi_ctx) == IPMI_ERR_K_G_INVALID
                  || ipmi_ctx_errnum (ipmi_ctx) == IPMI_ERR_PRIVILEGE_LEVEL_INSUFFICIENT
                  || ipmi_ctx_errnum (ipmi_ctx) == IPMI_ERR_PRIVILEGE_LEVEL_CANNOT_BE_OBTAINED
                  || ipmi_ctx_errnum (ipmi_ctx) == IPMI_ERR_AUTHENTICATION_TYPE_UNAVAILABLE
                  || ipmi_ctx_errnum (ipmi_ctx) == IPMI_ERR_CIPHER_SUITE_ID_UNAVAILABLE
                  || ipmi_ctx_errnum (ipmi_ctx) == IPMI_ERR_PASSWORD_VERIFICATION_TIMEOUT
                  || ipmi_ctx_errnum (ipmi_ctx) == IPMI_ERR_HOSTNAME_INVALID
                  || ipmi_ctx_errnum (ipmi_ctx) == IPMI_ERR_IPMI_2_0_UNAVAILABLE
                  || ipmi_ctx_errnum (ipmi_ctx) == IPMI_ERR_CONNECTION_TIMEOUT)
                PSTDOUT_FPRINTF (pstate,
				 stderr,
				 "%s: %s\n",
				 progname,
				 ipmi_ctx_errormsg (ipmi_ctx));
              else
                PSTDOUT_FPRINTF (pstate,
				 stderr,
				 "ipmi_ctx_open_outofband_2_0: %s\n",
				 ipmi_ctx_errormsg (ipmi_ctx));
              goto cleanup;
            }
        }
      else
        {
	  parse_get_freeipmi_outofband_flags (common_args->workaround_flags_outofband,
					      &workaround_flags);

          if (ipmi_ctx_open_outofband (ipmi_ctx,
                                       hostname,
                                       common_args->username,
                                       common_args->password,
                                       common_args->authentication_type,
                                       common_args->privilege_level,
                                       common_args->session_timeout,
                                       common_args->retransmission_timeout,
                                       workaround_flags,
                                       (common_args->debug) ? IPMI_FLAGS_DEBUG_DUMP : IPMI_FLAGS_DEFAULT) < 0)
            {
              if (ipmi_ctx_errnum (ipmi_ctx) == IPMI_ERR_USERNAME_INVALID
                  || ipmi_ctx_errnum (ipmi_ctx) == IPMI_ERR_PASSWORD_INVALID
                  || ipmi_ctx_errnum (ipmi_ctx) == IPMI_ERR_PRIVILEGE_LEVEL_INSUFFICIENT
                  || ipmi_ctx_errnum (ipmi_ctx) == IPMI_ERR_PRIVILEGE_LEVEL_CANNOT_BE_OBTAINED
                  || ipmi_ctx_errnum (ipmi_ctx) == IPMI_ERR_AUTHENTICATION_TYPE_UNAVAILABLE
                  || ipmi_ctx_errnum (ipmi_ctx) == IPMI_ERR_PASSWORD_VERIFICATION_TIMEOUT
                  || ipmi_ctx_errnum (ipmi_ctx) == IPMI_ERR_HOSTNAME_INVALID
                  || ipmi_ctx_errnum (ipmi_ctx) == IPMI_ERR_CONNECTION_TIMEOUT)
                PSTDOUT_FPRINTF (pstate,
				 stderr,
				 "%s: %s\n",
				 progname,
				 ipmi_ctx_errormsg (ipmi_ctx));
              else
                PSTDOUT_FPRINTF (pstate,
				 stderr,
				 "ipmi_ctx_open_outofband: %s\n",
				 ipmi_ctx_errormsg (ipmi_ctx));
              goto cleanup;
            }
        }
    }
  else
    {
      if (!ipmi_is_root ())
        {
          PSTDOUT_FPRINTF (pstate,
			   stderr,
			   "%s: %s\n",
			   progname,
			   ipmi_ctx_strerror (IPMI_ERR_PERMISSION));
          goto cleanup;
        }

      parse_get_freeipmi_inband_flags (common_args->workaround_flags_inband,
				       &workaround_flags);

      if (common_args->driver_type == IPMI_DEVICE_UNKNOWN)
        {
          int ret;

          if ((ret = ipmi_ctx_find_inband (ipmi_ctx,
                                           NULL,
                                           common_args->disable_auto_probe,
                                           common_args->driver_address,
                                           common_args->register_spacing,
                                           common_args->driver_device,
                                           workaround_flags,
                                           (common_args->debug) ? IPMI_FLAGS_DEBUG_DUMP : IPMI_FLAGS_DEFAULT)) < 0)
            {
              PSTDOUT_FPRINTF (pstate,
			       stderr,
			       "ipmi_ctx_find_inband: %s\n",
			       ipmi_ctx_errormsg (ipmi_ctx));
              goto cleanup;
            }

          if (!ret)
            {
              PSTDOUT_FPRINTF (pstate,
			       stderr,
			       "could not find inband device");
              goto cleanup;
            }
        }
      else
        {
          if (ipmi_ctx_open_inband (ipmi_ctx,
                                    common_args->driver_type,
                                    common_args->disable_auto_probe,
                                    common_args->driver_address,
                                    common_args->register_spacing,
                                    common_args->driver_device,
                                    workaround_flags,
                                    (common_args->debug) ? IPMI_FLAGS_DEBUG_DUMP : IPMI_FLAGS_DEFAULT) < 0)
            {
              if (ipmi_ctx_errnum (ipmi_ctx) == IPMI_ERR_DEVICE_NOT_FOUND)
                PSTDOUT_FPRINTF (pstate,
				 stderr,
				 "%s: %s\n",
				 progname,
				 ipmi_ctx_errormsg (ipmi_ctx));
              else
                PSTDOUT_FPRINTF (pstate,
				 stderr,
				 "ipmi_ctx_open_inband: %s\n",
				 ipmi_ctx_errormsg (ipmi_ctx));
              goto cleanup;
            }
        }
    }

  if (common_args->target_channel_number_is_set
      || common_args->target_slave_address_is_set)
    {
      if (ipmi_ctx_set_target (ipmi_ctx,
			       common_args->target_channel_number_is_set ? &common_args->target_channel_number : NULL,
			       common_args->target_slave_address_is_set ? &common_args->target_slave_address : NULL) < 0)
	{
	  PSTDOUT_FPRINTF (pstate,
			   stderr,
			   "ipmi_ctx_set_target: %s\n",
			   ipmi_ctx_errormsg (ipmi_ctx));
	  goto cleanup;
	} 
    }
  
  return (ipmi_ctx);

 cleanup: 
  ipmi_ctx_close (ipmi_ctx);
  ipmi_ctx_destroy (ipmi_ctx);
  return (NULL);
}
Esempio n. 2
0
int main(int argc, char *argv[])
{
	uint8_t threadid_main = 0;
	pthread_key_create(&threadid_key, NULL);
	pthread_setspecific(threadid_key, &threadid_main);

	mprintf("University of Wisconsin IPMI MicroTCA System Manager\n");
	if (argc > 1 && strcmp(argv[1], "--version") == 0) {
		mprintf("\nCompiled from %s@%s\n", (GIT_BRANCH[0] ? GIT_BRANCH : "git-archive"), (GIT_COMMIT[0] ? GIT_COMMIT : "27868b9b800d107fbb53b68c2fce207144f97a98"));
		if (strlen(GIT_DIRTY) > 1)
			mprintf("%s", GIT_DIRTY);
		mprintf("\n");
		return 0;
	}

	/*
	 * Parse Configuration
	 */

	cfg_opt_t opts_auth[] =
	{
		CFG_STR_LIST(const_cast<char *>("raw"), const_cast<char *>("{}"), CFGF_NONE),
		CFG_STR_LIST(const_cast<char *>("manage"), const_cast<char *>("{}"), CFGF_NONE),
		CFG_STR_LIST(const_cast<char *>("read"), const_cast<char *>("{}"), CFGF_NONE),
		CFG_END()
	};

	cfg_opt_t opts_crate[] =
	{
		CFG_STR(const_cast<char *>("host"), const_cast<char *>(""), CFGF_NONE),
		CFG_STR(const_cast<char *>("description"), const_cast<char *>(""), CFGF_NONE),
		CFG_STR(const_cast<char *>("username"), const_cast<char *>(""), CFGF_NONE),
		CFG_STR(const_cast<char *>("password"), const_cast<char *>(""), CFGF_NONE),
		CFG_INT_CB(const_cast<char *>("authtype"), 0, CFGF_NONE, cfg_parse_authtype),
		CFG_INT_CB(const_cast<char *>("mch"), 0, CFGF_NONE, cfg_parse_MCH),
		CFG_BOOL(const_cast<char *>("enabled"), cfg_true, CFGF_NONE),
		CFG_END()
	};

	cfg_opt_t opts_cardmodule[] =
	{
		CFG_STR(const_cast<char *>("module"), const_cast<char *>(""), CFGF_NONE),
		CFG_STR_LIST(const_cast<char *>("config"), const_cast<char *>("{}"), CFGF_NONE),
		CFG_END()
	};

	cfg_opt_t opts[] =
	{
		CFG_SEC(const_cast<char *>("authentication"), opts_auth, CFGF_NONE),
		CFG_SEC(const_cast<char *>("crate"), opts_crate, CFGF_MULTI),
		CFG_SEC(const_cast<char *>("cardmodule"), opts_cardmodule, CFGF_MULTI),
		CFG_INT(const_cast<char *>("socket_port"), 4681, CFGF_NONE),
		CFG_INT(const_cast<char *>("ratelimit_delay"), 0, CFGF_NONE),
		CFG_BOOL(const_cast<char *>("daemonize"), cfg_false, CFGF_NONE),
		CFG_END()
	};
	cfg_t *cfg = cfg_init(opts, CFGF_NONE);
	cfg_set_validate_func(cfg, "crate|host", &cfg_validate_hostname);
	cfg_set_validate_func(cfg, "socket_port", &cfg_validate_port);

	if (argc >= 2 && access(argv[1], R_OK) == 0) {
		if(cfg_parse(cfg, argv[1]) == CFG_PARSE_ERROR)
			exit(1);
	}
	else if (access(CONFIG_PATH "/" CONFIG_FILE, R_OK) == 0) {
		if(cfg_parse(cfg, CONFIG_PATH "/" CONFIG_FILE) == CFG_PARSE_ERROR)
			exit(1);
	}
	else {
		printf("Config file %s not found, and no argument supplied.\n", CONFIG_PATH "/" CONFIG_FILE);
		printf("Try: %s sysmgr.conf\n", argv[0]);
		exit(1);
	}

	bool crate_found = false;
	bool crate_enabled = false;

	cfg_t *cfgauth = cfg_getsec(cfg, "authentication");
	for(unsigned int i = 0; i < cfg_size(cfgauth, "raw"); i++)
		config_authdata.raw.push_back(std::string(cfg_getnstr(cfgauth, "raw", i)));
	for(unsigned int i = 0; i < cfg_size(cfgauth, "manage"); i++)
		config_authdata.manage.push_back(std::string(cfg_getnstr(cfgauth, "manage", i)));
	for(unsigned int i = 0; i < cfg_size(cfgauth, "read"); i++)
		config_authdata.read.push_back(std::string(cfg_getnstr(cfgauth, "read", i)));

	for(unsigned int i = 0; i < cfg_size(cfg, "crate"); i++) {
		cfg_t *cfgcrate = cfg_getnsec(cfg, "crate", i);
		crate_found = true;

		enum Crate::Mfgr MCH;
		switch (cfg_getint(cfgcrate, "mch")) {
			case Crate::VADATECH: MCH = Crate::VADATECH; break;
			case Crate::NAT: MCH = Crate::NAT; break;
		}

		const char *user = cfg_getstr(cfgcrate, "username");
		const char *pass = cfg_getstr(cfgcrate, "password");

		Crate *crate = new Crate(i+1, MCH, cfg_getstr(cfgcrate, "host"), (user[0] ? user : NULL), (pass[0] ? pass : NULL), cfg_getint(cfgcrate, "authtype"), cfg_getstr(cfgcrate, "description"));

		bool enabled = (cfg_getbool(cfgcrate, "enabled") == cfg_true);
		if (enabled)
			crate_enabled = true;
		threadlocal.push_back(threadlocaldata_t(crate, enabled));
	}

	for(unsigned int i = 0; i < cfg_size(cfg, "cardmodule"); i++) {
		cfg_t *cfgmodule = cfg_getnsec(cfg, "cardmodule", i);

		const char *module = cfg_getstr(cfgmodule, "module");

		std::vector<std::string> configdata;
		for(unsigned int i = 0; i < cfg_size(cfgmodule, "config"); i++)
			configdata.push_back(std::string(cfg_getnstr(cfgmodule, "config", i)));

		std::string default_module_path = DEFAULT_MODULE_PATH;
	   	if (getenv("SYSMGR_MODULE_PATH") != NULL)
			default_module_path = getenv("SYSMGR_MODULE_PATH");

		std::string modulepath = module;
		if (modulepath.find("/") == std::string::npos)
			modulepath = default_module_path +"/"+ modulepath;

		cardmodule_t cm;
		cm.dl_addr = dlopen(modulepath.c_str(), RTLD_NOW|RTLD_GLOBAL);
		if (cm.dl_addr == NULL) {
			printf("Error loading module %s:\n\t%s\n", module, dlerror());
			exit(2);
		}

		void *sym;
#define LOAD_SYM(name, type) \
		sym = dlsym(cm.dl_addr, #name); \
		if (sym == NULL) { \
			mprintf("Error loading module %s " type " " #name ":\n\t%s\n", module, dlerror()); \
			exit(2); \
		}

		LOAD_SYM(APIVER, "variable");
		cm.APIVER = *reinterpret_cast<uint32_t*>(sym);

		LOAD_SYM(MIN_APIVER, "variable");
		cm.MIN_APIVER = *reinterpret_cast<uint32_t*>(sym);

		if (cm.APIVER < 2 || cm.MIN_APIVER > 2) {
			mprintf("Error loading module %s: Incompatible API version %u\n", module, cm.APIVER);
		}

		LOAD_SYM(initialize_module, "function");
		cm.initialize_module = reinterpret_cast<bool (*)(std::vector<std::string>)>(sym);

		LOAD_SYM(instantiate_card, "function");
		cm.instantiate_card = reinterpret_cast<Card* (*)(Crate*, std::string, void*, uint8_t)>(sym);

#undef LOAD_SYM

		if (!cm.initialize_module(configdata)) {
			printf("Error loading module %s: initialize_module() returned false\n", module);
			exit(2);
		}

		card_modules.insert(card_modules.begin(), cm);
	}

	uint16_t port = cfg_getint(cfg, "socket_port");
	config_ratelimit_delay = cfg_getint(cfg, "ratelimit_delay");
	bool daemonize = (cfg_getbool(cfg, "daemonize") == cfg_true);

	cfg_free(cfg);

	if (!crate_found) {
		printf("No crate specified in the configuration file.\n");
		exit(1);
	}
	if (!crate_enabled) {
		printf("No crates are enabled in the configuration file.\n");
		printf("No crates to service.\n");
		exit(1);
	}

	if (daemonize) {
		do_fork();
		stdout_use_syslog = true;
		mprintf("University of Wisconsin IPMI MicroTCA System Manager\n");
	}

	/*
	 * Initialize library crypto routines before spawning threads.
	 * This connect will fail due to hostname too long, after running the crypt init functions.
	 *
	 * Max Hostname Limit: 64
	 */
	ipmi_ctx_t dummy_ipmi_ctx = ipmi_ctx_create();
	if (ipmi_ctx_open_outofband_2_0(dummy_ipmi_ctx,
				".................................................................",			// hostname
				NULL,					// username
				NULL,					// password
				NULL,						// k_g
				0,							// k_g_len,
				4,							// privilege_level
				0,							// cipher_suite_id
				0,							// session_timeout
				5,							// retransmission_timeout
				IPMI_WORKAROUND_FLAGS_OUTOFBAND_2_0_OPEN_SESSION_PRIVILEGE,	// workaround_flags
				IPMI_FLAGS_DEFAULT			// flags
				) == 0) {
		ipmi_ctx_close(dummy_ipmi_ctx);
	}
	ipmi_ctx_destroy(dummy_ipmi_ctx);

	/*
	 * Instantiate Worker Threads
	 */

	for (std::vector<threadlocaldata_t>::iterator it = threadlocal.begin(); it != threadlocal.end(); it++)
		if (it->enabled)
			pthread_create(&it->thread, NULL, crate_monitor, (void *)it->crate->get_number());

#ifndef DEBUG_ONESHOT
	protocol_server(port);
#endif

	for (std::vector<threadlocaldata_t>::iterator it = threadlocal.begin(); it != threadlocal.end(); it++)
		if (it->enabled)
			pthread_join(it->thread, NULL);
}