Пример #1
0
void main_loop() {
    int retval;
    int node=0,n;
    while (node<n1) {
        check_stop_daemons();
	retval = count_unsent_results(n, 0);
        if (retval) {
            log_messages.printf(MSG_CRITICAL,
                "count_unsent_jobs() failed: %s\n", boincerror(retval)
            );
            exit(retval);
        }
        if (n > CUSHION) {
            daemon_sleep(5);
        } else {

          //  int njobs =  (CUSHION-n)/REPLICATION_FACTOR;
            log_messages.printf(MSG_DEBUG,
                "Making job for %d\n", node
            );
      //      for (int i=0; i<njobs; i++) {
      	      for (int i=0; i<n1; i+=CLIENT_LIMIT)
      	      {
                retval = make_job(node,i);
                if (retval) {
                    log_messages.printf(MSG_CRITICAL,
                        "can't make job: %s\n", boincerror(retval)
                    );
                    exit(retval);
                }
      	      }
   //         }
            // Now sleep for a few seconds to let the transitioner
            // create instances for the jobs we just created.
            // Otherwise we could end up creating an excess of jobs.
            double now = dtime();
            while (1) {
                daemon_sleep(5);
                double x;
                retval = min_transition_time(x);
                if (retval) {
                    log_messages.printf(MSG_CRITICAL,
                        "min_transition_time failed: %s\n", boincerror(retval)
                    );
                    exit(retval);
                }
                if (x > now) break;
            }
        }
        node++;
    }
}
Пример #2
0
void main_loop() {
    int retval;

    while (1) {
        check_stop_daemons();
        long n;
        retval = count_unsent_results(n, app.id);
        if (retval) {
            log_messages.printf(MSG_CRITICAL,
                "count_unsent_jobs() failed: %s\n", boincerror(retval)
            );
            exit(retval);
        }
        if (n > CUSHION) {
            daemon_sleep(10);
        } else {
            int njobs = (CUSHION-n)/REPLICATION_FACTOR;
            log_messages.printf(MSG_DEBUG,
                "Making %d jobs\n", njobs
            );
            for (int i=0; i<njobs; i++) {
                retval = make_job();
                if (retval) {
                    log_messages.printf(MSG_CRITICAL,
                        "can't make job: %s\n", boincerror(retval)
                    );
                    exit(retval);
                }
            }
            // Wait for the transitioner to create instances
            // of the jobs we just created.
            // Otherwise we'll create too many jobs.
            //
            double now = dtime();
            while (1) {
                daemon_sleep(5);
                double x;
                retval = min_transition_time(x);
                if (retval) {
                    log_messages.printf(MSG_CRITICAL,
                        "min_transition_time failed: %s\n", boincerror(retval)
                    );
                    exit(retval);
                }
                if (x > now) break;
            }
        }
    }
}
Пример #3
0
int main_loop(bool one_pass) {
    int retval;
    bool did_something;
    // char buf[256];

    retval = boinc_db.open(config.db_name, config.db_host, config.db_user, config.db_passwd);
    if (retval) {
        log_messages.printf(MSG_CRITICAL,
            "boinc_db.open failed: %s\n", boincerror(retval)
        );
        exit(1);
    }
/*
    sprintf(buf, "where name='%s'", app_name);
    retval = app.lookup(buf);
    if (retval) {
        log_messages.printf(MSG_CRITICAL,
            "can't find app %s\n", app_name
        );
        exit(1);
    }
*/
    // coverity[loop_top] - infinite loop is intended
    while (1) {
        check_stop_daemons();
        did_something = do_message_scan();
        if (one_pass) break;
        if (!did_something) {
            daemon_sleep(5);
        }
    }
    return 0;
}
Пример #4
0
void main_loop() {
    int retval;

    retval = boinc_db.open(config.db_name, config.db_host, config.db_user, config.db_passwd);
    if (retval) {
        log_messages.printf(MSG_CRITICAL,
            "boinc_db.open: %s\n", boincerror(retval)
        );
        exit(1);
    }

    while (1) {
        log_messages.printf(MSG_DEBUG, "doing a pass\n");
        if (1) {
            bool did_something = do_pass();
            if (one_pass) break;
            if (did_something) continue;
#ifdef GCL_SIMULATOR
            continue_simulation("transitioner");
            signal(SIGUSR2, simulator_signal_handler);
            pause();
#else
            log_messages.printf(MSG_DEBUG, "sleeping %d\n", sleep_interval);
            daemon_sleep(sleep_interval);
#endif
        }
    }
}
Пример #5
0
int main_loop(bool one_pass) {
    while (1) {
        check_stop_daemons();
        bool did_something = do_trickle_scan();
        if (one_pass) break;
        if (!did_something) {
            daemon_sleep(5);
        }
    }
    return 0;
}
Пример #6
0
int main_loop() {
    int retval;
    bool did_something;
    char buf[256];

    sprintf(buf, "where name='%s'", app_name);

    while (1) {
        check_stop_daemons();

        // look up app within the loop,
        // in case its min_avg_pfc has been changed by the feeder
        //
        retval = app.lookup(buf);
        if (retval) {
            log_messages.printf(MSG_CRITICAL, "can't find app %s\n", app_name);
            exit(1);
        }
        did_something = do_validate_scan();
        if (!did_something) {
            write_modified_app_versions(app_versions);
            if (one_pass) break;
#ifdef GCL_SIMULATOR
            char nameforsim[64];
            sprintf(nameforsim, "validator%i", app.id);
            continue_simulation(nameforsim);
            signal(SIGUSR2, simulator_signal_handler);
            pause();
#else
            daemon_sleep(sleep_interval);
#endif
        }
        if (one_pass) break;
    }
    return 0;
}
Пример #7
0
int main(int argc, char** argv) {
    int retval;
    bool one_pass = false;
    int i;
    DB_APP app;

    check_stop_daemons();

    *app.name='\0';
    for (i=1; i<argc; i++) {
        if (is_arg(argv[i], "one_pass")) {
            one_pass = true;
        } else if (is_arg(argv[i], "dont_retry_errors")) {
            dont_retry_errors = true;
        } else if (is_arg(argv[i], "preserve_wu_files")) {
            preserve_wu_files = true;
        } else if (is_arg(argv[i], "preserve_result_files")) {
            preserve_result_files = true;
        } else if (is_arg(argv[i], "app")) {
            safe_strcpy(app.name, argv[++i]);
        } else if (is_arg(argv[i], "appid")) {
            if (!argv[++i]) {
                log_messages.printf(MSG_CRITICAL, "%s requires an argument\n\n", argv[--i]);
                usage(argv[0]);
                exit(1);
            }
            appid = atol(argv[i]);
        } else if (is_arg(argv[i], "d") || is_arg(argv[i], "debug_level")) {
            if (!argv[++i]) {
                log_messages.printf(MSG_CRITICAL, "%s requires an argument\n\n", argv[--i]);
                usage(argv[0]);
                exit(1);
            }
            int dl = atoi(argv[i]);
            log_messages.set_debug_level(dl);
            if (dl == 4) g_print_queries = true;
        } else if (is_arg(argv[i], "mod")) {
            if (!argv[i+1] || !argv[i+2]) {
                log_messages.printf(MSG_CRITICAL, "%s requires two arguments\n\n", argv[i]);
                usage(argv[0]);
                exit(1);
            }
            id_modulus   = atoi(argv[++i]);
            id_remainder = atoi(argv[++i]);
        } else if (is_arg(argv[i], "download_dir")) {
            if (!argv[++i]) {
                log_messages.printf(MSG_CRITICAL, "%s requires an argument\n\n", argv[--i]);
                usage(argv[0]);
                exit(1);
            }
            download_dir = argv[i];
        } else if (is_arg(argv[i], "xml_doc_like")) {
            if (!argv[++i]) {
                log_messages.printf(MSG_CRITICAL, "%s requires an argument\n\n", argv[--i]);
                usage(argv[0]);
                exit(1);
            }
            xml_doc_like = argv[i];
        } else if (is_arg(argv[i], "dont_delete_antiques")) {
            log_messages.printf(MSG_CRITICAL, "'%s' has no effect, this file deleter does no antique files deletion\n", argv[i]);
        } else if (is_arg(argv[i], "antiques_deletion_dry_run")) {
            log_messages.printf(MSG_CRITICAL, "'%s' has no effect, this file deleter does no antique files deletion\n", argv[i]);
        } else if (is_arg(argv[i], "delete_antiques_interval")) {
            log_messages.printf(MSG_CRITICAL, "'%s' has no effect, this file deleter does no antique files deletion\n", argv[i]);
        } else if (is_arg(argv[i], "delete_antiques_usleep")) {
            log_messages.printf(MSG_CRITICAL, "'%s' has no effect, this file deleter does no antique files deletion\n", argv[i]);
        } else if (is_arg(argv[i], "delete_antiques_limit")) {
            log_messages.printf(MSG_CRITICAL, "'%s' has no effect, this file deleter does no antique files deletion\n", argv[i]);
        } else if (is_arg(argv[i], "dont_delete_batches")) {
            dont_delete_batches = true;
        } else if (is_arg(argv[i], "dry_run")) {
            dry_run = true;
        } else if (is_arg(argv[i], "delete_antiques_now")) {
            log_messages.printf(MSG_CRITICAL, "'%s' has no effect, this file deleter does no antique files deletion\n", argv[i]);
        } else if (is_arg(argv[i], "input_files_only")) {
            do_output_files = false;
        } else if (is_arg(argv[i], "output_files_only")) {
            do_input_files = false;
        } else if (is_arg(argv[i], "sleep_interval")) {
            if (!argv[++i]) {
                log_messages.printf(MSG_CRITICAL, "%s requires an argument\n\n", argv[--i]);
                usage(argv[0]);
                exit(1);
            }
            sleep_interval = atoi(argv[i]);
        } else if (is_arg(argv[i], "h") || is_arg(argv[i], "help")) {
            usage(argv[0]);
            exit(0);
        } else if (is_arg(argv[i], "v") || is_arg(argv[i], "version")) {
            printf("%s\n", SVN_VERSION);
            exit(0);
        } else {
            log_messages.printf(MSG_CRITICAL, "unknown command line argument: %s\n\n", argv[i]);
            usage(argv[0]);
            exit(1);
        }
    }

    if (id_modulus) {
        log_messages.printf(MSG_DEBUG,
            "Using mod'ed WU/result enumeration.  mod = %d  rem = %d\n",
            id_modulus, id_remainder
        );
    }

    retval = config.parse_file();
    if (retval) {
        log_messages.printf(MSG_CRITICAL,
            "Can't parse config.xml: %s\n", boincerror(retval)
        );
        exit(1);
    }

    if (download_dir) {
        log_messages.printf(MSG_NORMAL,
            "Overriding download_dir '%s' from project config with command-line '%s'\n",
            config.download_dir, download_dir
        );
    } else {
        download_dir = config.download_dir;
    }

    log_messages.printf(MSG_NORMAL, "Starting\n");

    retval = boinc_db.open(config.db_name, config.db_host, config.db_user, config.db_passwd);
    if (retval) {
        log_messages.printf(MSG_CRITICAL, "can't open DB\n");
        exit(1);
    }
    retval = boinc_db.set_isolation_level(READ_UNCOMMITTED);
    if (retval) {
        log_messages.printf(MSG_CRITICAL,
            "boinc_db.set_isolation_level: %s; %s\n",
            boincerror(retval), boinc_db.error_string()
        );
    }

    if (*app.name && !appid) {
      char buf[256];
      sprintf(buf, "where name='%s'", app.name);
      retval = app.lookup(buf);
      if (retval) {
        log_messages.printf(MSG_CRITICAL, "Can't find app\n");
        exit(1);
      }
      appid = app.id;
      log_messages.printf(MSG_DEBUG, "Deleting files of appid %lu\n",appid);
    }

    install_stop_signal_handler();

    bool retry_errors_now = !dont_retry_errors;
    double next_error_time=0;
    // coverity[loop_top] - infinite loop is intended
    while (1) {
        bool got_any = do_pass(false);
        if (retry_errors_now) {
            bool got_any_errors = do_pass(true);
            if (got_any_errors) {
                got_any = true;
            } else {
                retry_errors_now = false;
                next_error_time = dtime() + ERROR_INTERVAL;
                log_messages.printf(MSG_DEBUG,
                    "ending retry of previous errors\n"
                );
            }
        }
        if (one_pass) break;
        if (!got_any) {
            daemon_sleep(sleep_interval);
        }
        if (!dont_retry_errors && !retry_errors_now && (dtime() > next_error_time)) {
            retry_errors_now = true;
            log_messages.printf(MSG_DEBUG,
                "starting retry of previous errors\n"
            );
        }
    }
}
Пример #8
0
int main(int argc, char** argv) {
    int retval;
    char buf[256];

    for (int i=1; i<argc; i++) {
        if (!strcmp(argv[i], "--app_name")) {
            app_name = argv[++i];
        } else if (!strcmp(argv[i], "--lo")) {
            lo = atoi(argv[++i]);
        } else if (!strcmp(argv[i], "--hi")) {
            hi = atoi(argv[++i]);
        } else if (!strcmp(argv[i], "-d")) {
            log_messages.set_debug_level(atoi(argv[++i]));
        } else if (!strcmp(argv[i], "--debug_leveld")) {
            log_messages.set_debug_level(atoi(argv[++i]));
        } else if (!strcmp(argv[i], "--sleep_time")) {
            sleep_time = atoi(argv[++i]);
        } else if (!strcmp(argv[i], "--random_order")) {
            order_clause = " order by random ";
        } else if (!strcmp(argv[i], "--priority_asc")) {
            order_clause = " order by priority asc ";
        } else if (!strcmp(argv[i], "--priority_order")) {
            order_clause = " order by priority desc ";
        } else if (!strcmp(argv[i], "--priority_order_create_time")) {
            order_clause = " order by priority desc, workunitid ";
        } else {
            usage();
        }
    }
    if (!app_name || !lo || !hi || !sleep_time) {
        usage();
    }

    log_messages.printf(MSG_NORMAL, "Starting\n");

    retval = config.parse_file();
    if (retval) {
        log_messages.printf(MSG_CRITICAL,
            "Can't parse config.xml: %s\n", boincerror(retval)
        );
        exit(1);
    }

    retval = boinc_db.open(
        config.db_name, config.db_host, config.db_user, config.db_passwd
    );
    if (retval) {
        log_messages.printf(MSG_CRITICAL,
            "boinc_db.open: %d; %s\n", retval, boinc_db.error_string()
        );
        exit(1);
    }

    sprintf(buf, "where name='%s'", app_name);
    if (app.lookup(buf)) {
        log_messages.printf(MSG_CRITICAL, "no such app: %s\n", app_name);
        exit(1);
    }
    if (app.n_size_classes < 2) {
        log_messages.printf(MSG_CRITICAL, "app '%s' is not multi-size\n", app_name);
        exit(1);
    }
    while (1) {
        bool action;
        retval = do_pass(action);
        if (retval) {
            log_messages.printf(MSG_CRITICAL,
                "do_pass(): %s", boincerror(retval)
            );
            exit(1);
        }
        if (!action) {
            log_messages.printf(MSG_NORMAL, "sleeping\n");
            daemon_sleep(sleep_time);
        }
    }
}
Пример #9
0
int test_main(int argc, char **argv)
{
	int i;
	int debug = 0;
	char * cmd = 0;

	printf("PID=%ld\n", GetCurrentProcessId());
	for (i = 0; i < argc; i++) {
		printf("%d: \"%s\"\n", i, argv[i]);
		if (!strcmp(argv[i],"-d"))
			debug = 1;
	}
	if (argc > 1 && argv[argc-1][0] != '-')
		cmd = argv[argc-1];

	daemon_signal(SIGINT, sig_handler);
	daemon_signal(SIGBREAK, sig_handler);
	daemon_signal(SIGTERM, sig_handler);
	daemon_signal(SIGHUP, sig_handler);
	daemon_signal(SIGUSR1, sig_handler);
	daemon_signal(SIGUSR2, sig_handler);

	atexit(test_exit);

	if (!debug) {
		printf("Preparing to detach...\n");
		Sleep(2000);
		daemon_detach("test");
		printf("Detached!\n");
	}

	for (;;) {
		daemon_sleep(1);
		printf("."); fflush(stdout);
		if (caughtsig) {
			if (caughtsig == SIGUSR2) {
				debug ^= 1;
				if (debug)
					daemon_enable_console("Daemon[Debug]");
				else
					daemon_disable_console();
			}
			else if (caughtsig == SIGUSR1 && cmd) {
				char inpbuf[200], outbuf[1000]; int rc;
				strcpy(inpbuf, "Hello\nWorld!\n");
				rc = daemon_spawn(cmd, inpbuf, strlen(inpbuf), outbuf, sizeof(outbuf));
				if (!debug)
					daemon_enable_console("Command output");
				printf("\"%s\" returns %d\n", cmd, rc);
				if (rc >= 0)
					printf("output:\n%s.\n", outbuf);
				fflush(stdout);
				if (!debug) {
					Sleep(10000); daemon_disable_console();
				}
			}
			printf("[PID=%ld: Signal=%d]", GetCurrentProcessId(), caughtsig); fflush(stdout);
			if (caughtsig == SIGTERM || caughtsig == SIGBREAK)
				break;
			caughtsig = 0;
		}
	}
	printf("\nExiting on signal %d\n", caughtsig);
	return 0;
}
Пример #10
0
int main(int argc, char** argv) {
    int retval;
    bool one_pass = false;
    int i;
    int sleep_sec = 600;
    check_stop_daemons();

    for (i=1; i<argc; i++) {
        if (is_arg(argv[i], "one_pass")) {
            one_pass = true;
        } else if (is_arg(argv[i], "dont_delete")) {
            dont_delete = true;
        } else if (is_arg(argv[i], "d") || is_arg(argv[i], "debug_level")) {
            if (!argv[++i]) {
                log_messages.printf(MSG_CRITICAL, "%s requires an argument\n\n", argv[--i]);
                usage(argv[0]);
                exit(1);
            }
            int dl = atoi(argv[i]);
            log_messages.set_debug_level(dl);
            if (dl == 4) g_print_queries = true;
        } else if (is_arg(argv[i], "min_age_days")) {
            if (!argv[++i]) {
                log_messages.printf(MSG_CRITICAL, "%s requires an argument\n\n", argv[--i]);
                usage(argv[0]);
                exit(1);
            }
            min_age_days = atof(argv[i]);
        } else if (is_arg(argv[i], "max")) {
            if (!argv[++i]) {
                log_messages.printf(MSG_CRITICAL, "%s requires an argument\n\n", argv[--i]);
                usage(argv[0]);
                exit(1);
            }
            max_number_workunits_to_purge= atoi(argv[i]);
        } else if (is_arg(argv[i], "daily_dir")) {
            daily_dir=true;
        } else if (is_arg(argv[i], "zip")) {
            compression_type=COMPRESSION_ZIP;
        } else if (is_arg(argv[i], "gzip")) {
            compression_type=COMPRESSION_GZIP;
        } else if (is_arg(argv[i], "max_wu_per_file")) {
            if(!argv[++i]) {
                log_messages.printf(MSG_CRITICAL, "%s requires an argument\n\n", argv[--i]);
                usage(argv[0]);
                exit(1);
            }
            max_wu_per_file = atoi(argv[i]);
        } else if (is_arg(argv[i], "no_archive")) {
            no_archive = true;
        } else if (is_arg(argv[i], "-sleep")) {
            if(!argv[++i]) {
                log_messages.printf(MSG_CRITICAL, "%s requires an argument\n\n", argv[--i]);
                usage(argv[0]);
                exit(1);
            }
            sleep_sec = atoi(argv[i]);
            if (sleep_sec < 1 || sleep_sec > 86400) {
                log_messages.printf(MSG_CRITICAL,
                    "Unreasonable value of sleep interval: %d seconds\n",
                    sleep_sec
                );
                usage(argv[0]);
                exit(1);
            }
        } else if (is_arg(argv[i], "--help") || is_arg(argv[i], "-help") || is_arg(argv[i], "-h")) {
            usage(argv[0]);
            return 0;
        } else if (is_arg(argv[i], "--version") || is_arg(argv[i], "-version")) {
            printf("%s\n", SVN_VERSION);
            exit(0);
        } else if (is_arg(argv[i], "mod")) {
            if (!argv[i+1] || !argv[i+2]) {
                log_messages.printf(MSG_CRITICAL,
                    "%s requires two arguments\n\n", argv[i]
                );
                usage(argv[0]);
                exit(1);
            }
            id_modulus   = atoi(argv[++i]);
            id_remainder = atoi(argv[++i]);
        } else {
            log_messages.printf(MSG_CRITICAL,
                "unknown command line argument: %s\n\n", argv[i]
            );
            usage(argv[0]);
            exit(1);
        }
    }

    if (id_modulus && !no_archive) {
        log_messages.printf(MSG_CRITICAL,
            "If you use modulus, you must set no_archive\n\n"
        );
        usage(argv[0]);
        exit(1);
    }

    retval = config.parse_file();
    if (retval) {
        log_messages.printf(MSG_CRITICAL,
            "Can't parse config.xml: %s\n", boincerror(retval)
        );
        exit(1);
    }

    log_messages.printf(MSG_NORMAL, "Starting\n");

    retval = boinc_db.open(
        config.db_name, config.db_host, config.db_user, config.db_passwd
    );
    if (retval) {
        log_messages.printf(MSG_CRITICAL, "Can't open DB\n");
        exit(2);
    }
    install_stop_signal_handler();
    boinc_mkdir(config.project_path("archives"));

    // on exit, either via the check_stop_daemons signal handler, or
    // through a regular call to exit, these functions will be called
    // in the opposite order of registration.
    //
    atexit(close_db_exit_handler);
    atexit(close_all_archives);

    while (1) {
        if (time_to_quit()) {
            break;
        }
        if (!do_pass() && !one_pass) {
            log_messages.printf(MSG_NORMAL, "Sleeping....\n");
            daemon_sleep(sleep_sec);
        }
        if (one_pass) {
            break;
        }
    }

    // files and database are closed by exit handler
    exit(0);
}
Пример #11
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);
}
Пример #12
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;
    }
}
Пример #13
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;
}