Beispiel #1
0
static void
_daemon_cmd_err (const char *str, int exit_on_fatal)
{
  assert (str);

  if (!cmd_args.verbose_logging)
    {
      if (repeat_ipmi_ctx_errnum == last_ipmi_ctx_errnum
	  && repeat_cmd == last_cmd
	  && repeat_netfn == last_netfn
	  && repeat_comp_code == last_comp_code)
	{
	  log_repeat_count++;
	  if (log_repeat_count < BMC_WATCHDOG_LOG_REPEAT_LIMIT)
	    return;
	}
    }

  if (ipmi_ctx_errnum (ipmi_ctx) == IPMI_ERR_BAD_COMPLETION_CODE)
    err_output ("%s: %s", str, comp_code_errbuf);
  else if (ipmi_ctx_errnum (ipmi_ctx) != IPMI_ERR_DRIVER_BUSY
	   && ipmi_ctx_errnum (ipmi_ctx) != IPMI_ERR_BMC_BUSY
	   && ipmi_ctx_errnum (ipmi_ctx) != IPMI_ERR_IPMI_ERROR)
    {
      err_output ("%s: %s", str, ipmi_ctx_errormsg (ipmi_ctx));
      if (exit_on_fatal)
	exit (EXIT_FAILURE);
    }

  repeat_ipmi_ctx_errnum = last_ipmi_ctx_errnum;
  repeat_cmd = last_cmd;
  repeat_netfn = last_netfn;
  repeat_comp_code = last_comp_code;
  log_repeat_count = 0;
}
Beispiel #2
0
static void log_no_err(const char *fmt,...)
{
#ifdef AP_LOG_EXEC
    va_list ap;

    va_start(ap, fmt);
    err_output(0, fmt, ap); /* 0 == !is_error */
    va_end(ap);
#endif /* AP_LOG_EXEC */
    return;
}
Beispiel #3
0
static void log_err(const char *fmt,...)
{
#ifdef LOG_EXEC
    va_list ap;

    va_start(ap, fmt);
    err_output(fmt, ap);
    va_end(ap);
#endif /* LOG_EXEC */
    return;
}
Beispiel #4
0
static void log_err(const char *fmt,...)
{
#ifdef SUEXEC_LOGFILE
    va_list ap;

    va_start(ap, fmt);
    err_output(1, fmt, ap); /* 1 == is_error */
    va_end(ap);
#endif /* SUEXEC_LOGFILE */
    return;
}
Beispiel #5
0
void
ipmiseld_err_output (ipmiseld_host_data_t *host_data,
		     const char *message,
		     ...)
{
  char buf[IPMISELD_ERR_BUFLEN + 1];
  va_list ap;

  assert (host_data);
  assert (message);
  memset (buf, '\0', IPMISELD_ERR_BUFLEN + 1);

  va_start (ap, message);
  vsnprintf(buf, IPMISELD_ERR_BUFLEN, message, ap);

  if (!host_data->hostname)
    err_output ("%s", buf);
  else
    err_output ("%s: %s", host_data->hostname, buf);
  va_end (ap);
}
static void
_config_file_parse (void)
{
  int ipmiping_period_flag,
    ipmidetectd_server_port_flag,
    host_flag;

  struct conffile_option options[] =
    {
      {
	"ipmiping_period",
	CONFFILE_OPTION_INT,
	-1,
	conffile_int,
	1,
	0,
	&(ipmiping_period_flag),
	&(conf.ipmiping_period),
	0
      },
      {
	"ipmidetectd_server_port",
	CONFFILE_OPTION_INT,
	-1,
	conffile_int,
	1,
	0,
	&(ipmidetectd_server_port_flag),
	&(conf.ipmidetectd_server_port),
	0,
      },
      {
	"host",
	CONFFILE_OPTION_STRING,
	-1,
	_cb_host,
	INT_MAX,
	0,
	&host_flag,
	NULL,
	0
      },
    };
  conffile_t cf = NULL;
  int legacy_file_loaded = 0;
  int num;
  
  if (!(cf = conffile_handle_create ()))
    {
      err_output ("conffile_handle_create");
      goto cleanup;
    }

  num = sizeof (options)/sizeof (struct conffile_option);

  /* Try legacy file first */
  if (!cmd_args.config_file)
    {
      if (!conffile_parse (cf,
                           IPMIDETECTD_CONFIG_FILE_LEGACY,
                           options,
                           num,
                           NULL,
                           0,
                           0))
        legacy_file_loaded++;
    }

  if (!legacy_file_loaded)
    {
      if (conffile_parse (cf,
                          cmd_args.config_file ? cmd_args.config_file : IPMIDETECTD_CONFIG_FILE_DEFAULT,
                          options,
                          num,
                          NULL,
                          0,
                          0) < 0)
        {
          char buf[CONFFILE_MAX_ERRMSGLEN];
          
          /* Its not an error if the default configuration file doesn't exist */
          if ((!cmd_args.config_file
	       || !strcmp (cmd_args.config_file, IPMIDETECTD_CONFIG_FILE_DEFAULT))
              && conffile_errnum (cf) == CONFFILE_ERR_EXIST)
            goto cleanup;
          
          if (conffile_errmsg (cf, buf, CONFFILE_MAX_ERRMSGLEN) < 0)
            err_exit ("conffile_parse: %d", conffile_errnum (cf));
          else
            err_exit ("conffile_parse: %s", buf);
        }
    }

 cleanup:
  conffile_handle_destroy (cf);
}
Beispiel #7
0
static int
_cmd (const char *str,
      uint8_t netfn,
      uint8_t cmd,
      fiid_obj_t obj_cmd_rq,
      fiid_obj_t obj_cmd_rs)
{
  int retry_count = 0;
  int ret = 0;

  assert (str
          && (netfn == IPMI_NET_FN_APP_RQ || netfn == IPMI_NET_FN_TRANSPORT_RQ)
          && obj_cmd_rq
          && obj_cmd_rs);

  last_ipmi_ctx_errnum = -1;
  last_cmd = cmd;
  last_netfn = netfn;
  last_comp_code = 0;

  while (1)
    {
      if ((ret = ipmi_cmd (ipmi_ctx,
			   IPMI_BMC_IPMB_LUN_BMC,
			   netfn,
			   obj_cmd_rq,
			   obj_cmd_rs)) < 0)
	{
	  last_ipmi_ctx_errnum = ipmi_ctx_errnum (ipmi_ctx);

	  if (ipmi_ctx_errnum (ipmi_ctx) != IPMI_ERR_DRIVER_BUSY
	      && ipmi_ctx_errnum (ipmi_ctx) != IPMI_ERR_BMC_BUSY
	      && ipmi_ctx_errnum (ipmi_ctx) != IPMI_ERR_IPMI_ERROR)
	    {
	      if (cmd_args.verbose_logging)
		err_output ("%s: ipmi_cmd: %s", str, ipmi_ctx_errormsg (ipmi_ctx));


	      if (ipmi_ctx_errnum (ipmi_ctx) == IPMI_ERR_BAD_COMPLETION_CODE)
		{
		  if (ipmi_completion_code_strerror_cmd_r (obj_cmd_rs,
							   netfn,
							   comp_code_errbuf,
							   BMC_WATCHDOG_ERR_BUFLEN) < 0)
		    {
		      uint64_t val;
		      
		      _fiid_obj_get (obj_cmd_rs, "comp_code", &val);
		      last_comp_code = val;
		      
		      snprintf (comp_code_errbuf,
				BMC_WATCHDOG_ERR_BUFLEN,
				"Comp Code 0x%X",
				last_comp_code);
		    }
		}

	      return (-1);
	    }
        }

      if (ret < 0)
        {
          if (retry_count >= retry_attempts)
	    {
	      err_output ("%s: BMC Timeout: %s", str, ipmi_ctx_errormsg (ipmi_ctx));
              return (-1);
            }
	  
          daemon_sleep (retry_wait_time);
          retry_count++;
        }
      else
        break;
    }

  return (0);
}
Beispiel #8
0
static void
_daemon_cmd (const char *progname)
{
  uint32_t reset_period = BMC_WATCHDOG_RESET_PERIOD_DEFAULT;
  uint8_t timer_use, timer_state, log, timeout_action, pre_timeout_interrupt,
    pre_timeout_interval;
  uint16_t initial_countdown_seconds;
  uint16_t previous_present_countdown_seconds = 0;
  uint16_t present_countdown_seconds;

  assert (progname);

  /* Run in foreground if debugging */
  if (!cmd_args.common_args.debug)
    daemonize_common (BMC_WATCHDOG_PIDFILE);

  daemon_signal_handler_setup (_signal_handler_callback);

  /* move error outs to syslog from stderr */

  if (!cmd_args.no_logging)
    err_set_flags (ERROR_SYSLOG);
  else
    err_set_flags (0);

  openlog (progname, LOG_ODELAY | LOG_PID, LOG_DAEMON);

  _init_bmc_watchdog ();

  _daemon_setup ();

  if (cmd_args.reset_period)
    reset_period = cmd_args.reset_period_arg;

  retry_wait_time = BMC_WATCHDOG_RETRY_WAIT_TIME_DEFAULT;
  retry_attempts = BMC_WATCHDOG_RETRY_ATTEMPTS_DEFAULT;

  if ((retry_wait_time * retry_attempts) > reset_period)
    {
      retry_wait_time = 0;
      retry_attempts = 0;
    }
  else if (reset_period > retry_wait_time
           && reset_period < (retry_wait_time * retry_attempts))
    retry_attempts = reset_period/retry_wait_time;

  /* IPMI Workaround
   *
   * Discovered on Sun x4100M2 and x4200M2
   *
   * If implementing the IGNORE_STATE_FLAG workaround flag below, we
   * need to sleep a little bit to make sure the BMC timer has really
   * started.
   *
   * From 27.7 "Internal delays in the BMC may require software to
   * delay up to 100 ms before seeing the countdown value change and
   * be reflected in the Get Watchdog Timer command".
   */
  if (cmd_args.common_args.section_specific_workaround_flags & IPMI_PARSE_SECTION_SPECIFIC_WORKAROUND_FLAGS_IGNORE_STATE_FLAG)
    daemon_sleep (1);

  while (shutdown_flag)
    {
      struct timeval start_tv, end_tv;
      uint32_t adjusted_period;

      if (gettimeofday (&start_tv, NULL) < 0)
	err_exit ("gettimeofday: %s", strerror (errno));

      if (_get_watchdog_timer_cmd (NULL,
				   &timer_state,
				   NULL,
				   NULL,
				   NULL,
				   NULL,
				   NULL,
				   NULL,
				   NULL,
				   NULL,
				   NULL,
				   NULL,
				   &present_countdown_seconds) < 0)
        {
          _daemon_cmd_err_no_exit ("Get Watchdog Timer");
          goto sleep_now;
        }

      /* IPMI Workaround
       *
       * Discovered on Sun x4100M2 and x4200M2
       *
       * On some BMCs, the timer state flag is not functional.  Therefore,
       * to have an operational BMC watchdog, it must function without it.
       * We instead look to see if the timer is changing.
       */
      if (cmd_args.common_args.section_specific_workaround_flags & IPMI_PARSE_SECTION_SPECIFIC_WORKAROUND_FLAGS_IGNORE_STATE_FLAG)
        {
          if (previous_present_countdown_seconds == present_countdown_seconds)
            {
	      err_output ("timer stopped by another process");
	      return;
            }
          previous_present_countdown_seconds = present_countdown_seconds;
        }
      else
        {
          if (timer_state == IPMI_BMC_WATCHDOG_TIMER_TIMER_STATE_STOPPED)
            {
              err_output ("timer stopped by another process");
	      return;
            }
        }

      if (_reset_watchdog_timer_cmd () < 0)
        {
          _daemon_cmd_err_no_exit ("Reset Watchdog Timer");
          goto sleep_now;
        }

      /* IPMI Workaround
       *
       * Discovered on Sun x4100M2 and x4200M2
       *
       * If implementing the IGNORE_STATE_FLAG workaround flag above,
       * we need to reset the previous_present_countdown_seconds to
       * what it is after the timer reset.
       */
      if (cmd_args.common_args.section_specific_workaround_flags & IPMI_PARSE_SECTION_SPECIFIC_WORKAROUND_FLAGS_IGNORE_STATE_FLAG)
        {
          /* From 27.7 "Internal delays in the BMC may require software to
           * delay up to 100 ms before seeing the countdown value change and
           * be reflected in the Get Watchdog Timer command".
           */
          daemon_sleep (1);

          if (_get_watchdog_timer_cmd (NULL,
				       NULL,
				       NULL,
				       NULL,
				       NULL,
				       NULL,
				       NULL,
				       NULL,
				       NULL,
				       NULL,
				       NULL,
				       NULL,
				       &present_countdown_seconds) < 0)
            {
	      _daemon_cmd_err_no_exit ("Get Watchdog Timer");
              goto sleep_now;
            }
          
          previous_present_countdown_seconds = present_countdown_seconds;
        }

    sleep_now:
      if (gettimeofday (&end_tv, NULL) < 0)
	err_exit ("gettimeofday: %s", strerror (errno));

      adjusted_period = reset_period;

      /* Ignore micro secs, just seconds is good enough */
      if ((end_tv.tv_sec - start_tv.tv_sec) < adjusted_period)
	adjusted_period -= (end_tv.tv_sec - start_tv.tv_sec);

      daemon_sleep (adjusted_period);
    }

  /* Need to stop the timer, don't want it to keep on going.  Don't
   * give up until its shut off.
   */

  /* set back to defaults, no reset-period adjustment anymore */
  retry_wait_time = BMC_WATCHDOG_RETRY_WAIT_TIME_DEFAULT;
  retry_attempts = BMC_WATCHDOG_RETRY_ATTEMPTS_DEFAULT;

  while (1)
    {
      if (_get_watchdog_timer_cmd (&timer_use,
				   NULL,
				   &log,
				   &timeout_action,
				   &pre_timeout_interrupt,
				   &pre_timeout_interval,
				   NULL,
				   NULL,
				   NULL,
				   NULL,
				   NULL,
				   &initial_countdown_seconds,
				   NULL) < 0)
        {
          _daemon_cmd_err_no_exit ("Get Watchdog Timer");
	  daemon_sleep (BMC_WATCHDOG_RETRY_WAIT_TIME_DEFAULT);
          continue;
        }
      break;
    }

  while (1)
    {
      if (_set_watchdog_timer_cmd (timer_use,
				   IPMI_BMC_WATCHDOG_TIMER_STOP_TIMER_ENABLE,
				   log,
				   timeout_action,
				   pre_timeout_interrupt,
				   pre_timeout_interval,
				   0,
				   0,
				   0,
				   0,
				   0,
				   initial_countdown_seconds) < 0)
        {
          _daemon_cmd_err_no_exit ("Set Watchdog Timer");
	  daemon_sleep (BMC_WATCHDOG_RETRY_WAIT_TIME_DEFAULT);
          continue;
        }
      break;
    }
}
Beispiel #9
0
static void
_daemon_setup (void)
{
  uint8_t timer_use, timer_state, log, timeout_action, pre_timeout_interrupt,
    pre_timeout_interval;
  uint32_t reset_period = BMC_WATCHDOG_RESET_PERIOD_DEFAULT;
  uint16_t initial_countdown_seconds;

  while (1)
    {
      if (_get_watchdog_timer_cmd (&timer_use,
				   &timer_state,
				   &log,
				   &timeout_action,
				   &pre_timeout_interrupt,
				   &pre_timeout_interval,
				   NULL,
				   NULL,
				   NULL,
				   NULL,
				   NULL,
				   &initial_countdown_seconds,
				   NULL) < 0)
        {
          _daemon_cmd_err_maybe_exit ("Get Watchdog Timer");
	  daemon_sleep (BMC_WATCHDOG_RETRY_WAIT_TIME_DEFAULT);
          continue;
        }
      break;
    }

  if (timer_state == IPMI_BMC_WATCHDOG_TIMER_TIMER_STATE_RUNNING)
    err_exit ("Error: watchdog timer must be stopped before running daemon");

  timer_use = (cmd_args.timer_use) ? cmd_args.timer_use_arg : timer_use;

  log = (cmd_args.log) ? cmd_args.log_arg : log;

  timeout_action = (cmd_args.timeout_action) ?
    cmd_args.timeout_action_arg : timeout_action;

  pre_timeout_interrupt = (cmd_args.pre_timeout_interrupt) ?
    cmd_args.pre_timeout_interrupt_arg : pre_timeout_interrupt;

  pre_timeout_interval = (cmd_args.pre_timeout_interval) ?
    cmd_args.pre_timeout_interval_arg : pre_timeout_interval;

  initial_countdown_seconds = (cmd_args.initial_countdown_seconds) ?
    cmd_args.initial_countdown_seconds_arg : initial_countdown_seconds;

  if ((pre_timeout_interrupt != IPMI_BMC_WATCHDOG_TIMER_PRE_TIMEOUT_INTERRUPT_NONE)
      && (pre_timeout_interval > initial_countdown_seconds))
    err_exit ("Error: pre-timeout interval greater than initial countdown seconds");

  if (cmd_args.reset_period)
    reset_period = cmd_args.reset_period_arg;

  if (reset_period > initial_countdown_seconds)
    err_exit ("Error: reset-period interval greater than initial countdown seconds");

  while (1)
    {
      if (_set_watchdog_timer_cmd (timer_use,
				   IPMI_BMC_WATCHDOG_TIMER_STOP_TIMER_ENABLE,
				   log,
				   timeout_action,
				   pre_timeout_interrupt,
				   pre_timeout_interval,
				   (cmd_args.clear_bios_frb2) ? 1 : 0,
				   (cmd_args.clear_bios_post) ? 1 : 0,
				   (cmd_args.clear_os_load) ? 1 : 0,
				   (cmd_args.clear_sms_os) ? 1 : 0,
				   (cmd_args.clear_oem) ? 1 : 0,
				   initial_countdown_seconds) < 0)
        {
          _daemon_cmd_err_maybe_exit ("Set Watchdog Timer");
	  daemon_sleep (BMC_WATCHDOG_RETRY_WAIT_TIME_DEFAULT);
          continue;
        }
      break;
    }

  /* Must start watchdog timer before entering loop */
  while (1)
    {
      if (_reset_watchdog_timer_cmd () < 0)
        {
          _daemon_cmd_err_maybe_exit ("Reset Watchdog Timer");
	  daemon_sleep (BMC_WATCHDOG_RETRY_WAIT_TIME_DEFAULT);
          continue;
        }
      break;
    }

  if (cmd_args.gratuitous_arp || cmd_args.arp_response)
    {
      uint8_t gratuitous_arp, arp_response;

      if (cmd_args.gratuitous_arp)
        gratuitous_arp = cmd_args.gratuitous_arp_arg;
      else
        gratuitous_arp = IPMI_BMC_GENERATED_GRATUITOUS_ARP_DO_NOT_SUSPEND;

      if (cmd_args.arp_response)
        arp_response = cmd_args.gratuitous_arp_arg;
      else
        arp_response = IPMI_BMC_GENERATED_ARP_RESPONSE_DO_NOT_SUSPEND;

      while (1)
        {
	  int ret;

          if ((ret = _suspend_bmc_arps_cmd (gratuitous_arp,
                                            arp_response)) < 0)
            {
              _daemon_cmd_err_maybe_exit ("Suspend BMC ARPs");
	      daemon_sleep (BMC_WATCHDOG_RETRY_WAIT_TIME_DEFAULT);
              continue;
            }

	  if (!ret)
	    err_output ("cannot suspend BMC ARPs"); 

          break;
        }
    }

  return;
}