/* * Validate a device. */ int check_device(const char *path, boolean_t force, boolean_t isspare) { dm_descriptor_t desc; int err; char *dev; /* * For whole disks, libdiskmgt does not include the leading dev path. */ dev = strrchr(path, '/'); assert(dev != NULL); dev++; if ((desc = dm_get_descriptor_by_name(DM_ALIAS, dev, &err)) != NULL) { err = check_disk(path, desc, force, isspare); dm_free_descriptor(desc); return (err); } return (check_slice(path, force, B_FALSE, isspare)); }
// Fast checks (no DB access) to see if the job can be sent to the host. // Reasons why not include: // 1) the host doesn't have enough memory; // 2) the host doesn't have enough disk space; // 3) based on CPU speed, resource share and estimated delay, // the host probably won't get the result done within the delay bound // 4) app isn't in user's "approved apps" list // // If the job is feasible, return 0 and fill in wu.delay_bound // with the delay bound we've decided to use. // int wu_is_infeasible_fast( WORKUNIT& wu, int res_server_state, int res_priority, double res_report_deadline, APP& app, BEST_APP_VERSION& bav ) { int retval; // project-specific check // if (wu_is_infeasible_custom(wu, app, bav)) { return INFEASIBLE_CUSTOM; } if (config.user_filter) { if (wu.batch && wu.batch != g_reply->user.id) { return INFEASIBLE_USER_FILTER; } } // homogeneous redundancy: can't send if app uses HR and // 1) host is of unknown HR class, or // 2) WU is already committed to different HR class // if (app_hr_type(app)) { if (hr_unknown_class(g_reply->host, app_hr_type(app))) { if (config.debug_send) { log_messages.printf(MSG_NORMAL, "[send] [HOST#%d] [WU#%u %s] host is of unknown class in HR type %d\n", g_reply->host.id, wu.id, wu.name, app_hr_type(app) ); } return INFEASIBLE_HR; } if (already_sent_to_different_hr_class(wu, app)) { if (config.debug_send) { log_messages.printf(MSG_NORMAL, "[send] [HOST#%d] [WU#%u %s] failed quick HR check: WU is class %d, host is class %d\n", g_reply->host.id, wu.id, wu.name, wu.hr_class, hr_class(g_request->host, app_hr_type(app)) ); } return INFEASIBLE_HR; } } // homogeneous app version // if (app.homogeneous_app_version) { int avid = wu.app_version_id; if (avid && bav.avp->id != avid) { if (config.debug_send) { log_messages.printf(MSG_NORMAL, "[send] [HOST#%d] [WU#%u %s] failed homogeneous app version check: %d %d\n", g_reply->host.id, wu.id, wu.name, avid, bav.avp->id ); } return INFEASIBLE_HAV; } } if (config.one_result_per_user_per_wu || config.one_result_per_host_per_wu) { if (wu_already_in_reply(wu)) { return INFEASIBLE_DUP; } } retval = check_memory(wu); if (retval) return retval; retval = check_disk(wu); if (retval) return retval; retval = check_bandwidth(wu); if (retval) return retval; if (app.non_cpu_intensive) { return 0; } // do deadline check last because EDF sim uses some CPU // double opt, pess; get_delay_bound_range( wu, res_server_state, res_priority, res_report_deadline, bav, opt, pess ); wu.delay_bound = (int)opt; if (opt == 0) { // this is a resend; skip deadline check return 0; } retval = check_deadline(wu, app, bav); if (retval && (opt != pess)) { wu.delay_bound = (int)pess; retval = check_deadline(wu, app, bav); } return retval; }
int main(int argc,char *argv[]) { dasdfmt_info_t info; volume_label_t vlabel; char old_volser[7]; char dev_filename[PATH_MAX]; char str[ERR_LENGTH]; char buf[7]; char *blksize_param_str = NULL; char *reqsize_param_str = NULL; char *hashstep_str = NULL; int rc, index; /* Establish a handler for interrupt signals. */ signal (SIGTERM, program_interrupt_signal); signal (SIGINT, program_interrupt_signal); signal (SIGQUIT, program_interrupt_signal); /******************* initialization ********************/ prog_name = argv[0]; /* set default values */ init_info(&info); vtoc_volume_label_init(&vlabel); format_params.blksize = DEFAULT_BLOCKSIZE; format_params.intensity = DASD_FMT_INT_COMPAT; /*************** parse parameters **********************/ while (1) { rc=getopt_long(argc, argv, dasdfmt_getopt_string, dasdfmt_getopt_long_options, &index); switch (rc) { case 'F': info.force=1; break; case 'C': format_params.intensity |= DASD_FMT_INT_COMPAT; break; case 'd' : if (strncmp(optarg,"cdl",3)==0) { format_params.intensity |= DASD_FMT_INT_COMPAT; if (info.writenolabel) { printf("WARNING: using the cdl " \ "format without writing a " \ "label doesn't make much " \ "sense!\n"); exit(1); } } else if (strncmp(optarg,"ldl",3)==0) format_params.intensity &= ~DASD_FMT_INT_COMPAT; else { printf("%s is not a valid option!\n", optarg); exit(1); } break; case 'y': info.withoutprompt=1; break; case 'z': format_params.intensity |= DASD_FMT_INT_FMT_NOR0; break; case 't': info.testmode=1; break; case 'p': if (!(info.print_hashmarks || info.print_percentage)) info.print_progressbar = 1; break; case 'm': if (!(info.print_progressbar || info.print_percentage)) { hashstep_str=optarg; info.print_hashmarks=1; } break; case 'P': if (!(info.print_hashmarks || info.print_progressbar)) info.print_percentage = 1; break; case 'v': info.verbosity=1; break; case 'h': exit_usage(0); case 'V': print_version(); exit(0); case 'l': strncpy(buf, optarg, 6); if (check_volser(buf, 0) < 0) break; vtoc_volume_label_set_volser(&vlabel,buf); info.labelspec=1; break; case 'L': if (format_params.intensity & DASD_FMT_INT_COMPAT) { printf("WARNING: using the cdl format " \ "without writing a label doesn't " \ "make much sense!\n"); exit(1); } info.writenolabel=1; break; case 'b' : blksize_param_str=optarg; info.blksize_specified=1; break; case 'r': reqsize_param_str = optarg; info.reqsize_specified = 1; break; case 'f' : strncpy(dev_filename, optarg, PATH_MAX); info.node_specified=1; break; case 'k' : info.keep_volser=1; break; case -1: /* End of options string - start of devices list */ info.device_id = optind; break; default: ERRMSG_EXIT(EXIT_MISUSE, "Try '%s --help' for more" " information.\n",prog_name); } if (rc==-1) break; // exit loop if finished } CHECK_SPEC_MAX_ONCE(info.blksize_specified, "blocksize"); CHECK_SPEC_MAX_ONCE(info.labelspec, "label"); CHECK_SPEC_MAX_ONCE(info.writenolabel, "omit-label-writing flag"); if (info.blksize_specified) PARSE_PARAM_INTO(format_params.blksize,blksize_param_str,10, "blocksize"); if (info.reqsize_specified) { PARSE_PARAM_INTO(reqsize, reqsize_param_str, 10, "requestsize"); if (reqsize < 1 || reqsize > 255) ERRMSG_EXIT(EXIT_FAILURE, "invalid requestsize %d specified\n", reqsize); } else reqsize = DEFAULT_REQUESTSIZE; if (info.print_hashmarks) PARSE_PARAM_INTO(info.hashstep, hashstep_str,10,"hashstep"); get_device_name(&info, dev_filename, argc, argv); if (!info.blksize_specified) format_params = ask_user_for_blksize(format_params); if (info.keep_volser) { if(info.labelspec) { ERRMSG_EXIT(EXIT_MISUSE,"%s: The -k and -l options are mutually exclusive\n", prog_name); } if(!(format_params.intensity & DASD_FMT_INT_COMPAT)) { printf("WARNING: VOLSER cannot be kept " \ "when using the ldl format!\n"); exit(1); } if(dasdfmt_get_volser(info.devname, old_volser) == 0) vtoc_volume_label_set_volser(&vlabel, old_volser); else ERRMSG_EXIT(EXIT_FAILURE,"%s: VOLSER not found on device %s\n", prog_name, info.devname); } if ((filedes = open(info.devname, O_RDWR)) == -1) ERRMSG_EXIT(EXIT_FAILURE,"%s: Unable to open device %s: %s\n", prog_name, info.devname, strerror(errno)); check_disk(&info); if (check_param(str, ERR_LENGTH, &format_params) < 0) ERRMSG_EXIT(EXIT_MISUSE, "%s: %s\n", prog_name, str); do_format_dasd(&info, &format_params, &vlabel); if (close(filedes) != 0) ERRMSG("%s: error during close: %s\ncontinuing...\n", prog_name, strerror(errno)); return 0; }
/** * Our main entry, decode requests and monitor activity */ static void avr_evtd_main(void) { char buf[17]; char cmd; char pushed_power = 0; char pushed_reset = 0; char pressed_power_flag = 0; char pressed_reset_flag = 0; char current_status = 0; time_t idle = time(NULL); time_t power_press = idle; time_t fault_time; time_t last_shutdown_ping; fd_set serialfd_set; struct timeval timeout_poll; int fan_fault = 0; long time_diff; char extraTime = 0; char disk_full = 0; /* Update the shutdown timer */ fault_time = 0; last_shutdown_ping = time(NULL); /* Loop whilst port is valid */ while (serialfd) { timeout_poll.tv_usec = 0; int res = refresh_rate; /* After file change or startup, update the time within 20 secs as the * user may have pushed the refresh time out. */ if (check_state > 0) { res = 2; } else { /* Change our timer to check for a power/reset request need a * faster poll rate here to see the double press event * properly. */ if (pushed_power || pushed_reset || first_time_flag > 1) { timeout_poll.tv_usec = 250; res = 0; check_state = -2; /* Hold off any configuration file updates */ } } if (check_state != -2) { /* Ensure we shutdown on the nail if the timer is enabled will * be off slightly as timer reads are different */ if (timer_flag == 1) { if (shutdown_timer < res) res = shutdown_timer; } /* If we have a fan failure report, then ping frequently */ if (fan_fault > 0) res = fan_fault == 6 ? fan_fault_seize : 2; } timeout_poll.tv_sec = res; FD_ZERO(&serialfd_set); FD_SET(serialfd, &serialfd_set); /* Wait for AVR message or time-out? */ res = select(serialfd + 1, &serialfd_set, NULL, NULL, &timeout_poll); time_t time_now = time(NULL); /* catch input? */ if (res > 0) { /* Read AVR message */ res = read(serialfd, buf, 16); /* AVR command detected so force to ping only */ check_state = -2; switch (buf[0]) { /* power button release */ case 0x20: /* ' ' */ if (pressed_power_flag == 0) { cmd = POWER_RELEASE; if ((time_now - power_press) <= HOLD_TIME && first_time_flag < 2) { cmd = USER_RESET; } else if (shutdown_timer < FIVE_MINUTES || first_time_flag > 1) { if (first_time_flag == 0) first_time_flag = 10; shutdown_timer += FIVE_MINUTES; first_time_flag--; extraTime = 1; } exec_simple_cmd(cmd); power_press = time_now; } pushed_power = pressed_power_flag = 0; break; /* power button push */ case 0x21: /* '!' */ exec_simple_cmd(POWER_PRESS); pressed_power_flag = 0; pushed_power = 1; break; /* reset button release */ case 0x22: /* '"' */ if (pressed_reset_flag == 0) { cmd = RESET_RELEASE; res = 0; /* Launch our telnet daemon */ if ((time_now - power_press) <= HOLD_TIME) { cmd = SPECIAL_RESET; res = reset_presses; reset_presses++; } exec_cmd(cmd, res); power_press = time_now; } pushed_reset = pressed_reset_flag = 0; break; /* reset button push */ case 0x23: /* '#' */ exec_simple_cmd(RESET_PRESS); pressed_reset_flag = 0; pushed_reset = 1; break; /* Fan on high speed */ case 0x24: /* '$' */ fan_fault = 6; fault_time = time_now; break; /* Fan fault */ case 0x25: /* '%' */ /* Flag the EventScript */ exec_cmd(FAN_FAULT, fan_fault); if (fan_fault_seize > 0) { fan_fault = 2; fault_time = time_now; } else fan_fault = -1; break; /* Acknowledge */ case 0x30: /* '0' */ break; /* AVR halt requested */ case 0x31: /* '1' */ close_serial(); exec_simple_cmd(AVR_HALT); break; /* AVR initialization complete */ case 0x33: /* '3' */ break; default: syslog(LOG_INFO, "unknown message %X[%d]", buf[0], res); break; } /* Get time for use later */ time(&idle); } else { /* Time-out event */ /* Check if button(s) are still held after holdcyle seconds */ if ((idle + hold_cycle) < time_now) { /* Power down selected */ if (pushed_power == 1) { /* Re-validate our time wake-up; do not perform if in extra time */ if (!extraTime) set_avr_timer(1); exec_simple_cmd(USER_POWER_DOWN); pushed_power = 0; pressed_power_flag = 1; } } /* Has user held the reset button long enough to request EM-Mode? */ if ((idle + EM_MODE_TIME) < time_now) { if (pushed_reset == 1 && in_em_mode) { /* Send EM-Mode request to script. The script handles the * flash device decoding and writes the HDD no-good flag * NGNGNG into the flash status. It then flags a reboot * which causes the box to boot from ram-disk backup to * recover the HDD. */ exec_simple_cmd(EM_MODE); pushed_reset = 0; pressed_reset_flag = 1; } } /* Skip this processing during power/reset scan */ if (!pushed_reset && !pushed_power && first_time_flag < 2) { /* shutdown timer event? */ if (timer_flag == 1) { /* Decrement our powerdown timer */ if (shutdown_timer > 0) { time_diff = (time_now - last_shutdown_ping); /* If time difference is more than a minute, * force a re-calculation of shutdown time */ if (refresh_rate + 60 > labs(time_diff)) { shutdown_timer -= time_diff; /* Within five minutes of shutdown? */ if (shutdown_timer < FIVE_MINUTES) { if (first_time_flag) { first_time_flag = 0; /* Inform the EventScript */ exec_cmd(FIVE_SHUTDOWN, shutdown_timer); /* Re-validate out time wake-up; do not * perform if in extra time */ if (!extraTime) set_avr_timer(1); } } } /* Large clock drift, either user set time * or an ntp update, handle accordingly. */ else { check_timer(2); } } else { /* Prevent re-entry and execute command */ pushed_power = pressed_reset_flag = 2; exec_simple_cmd(TIMED_SHUTDOWN); } } /* Keep track of shutdown time remaining */ last_shutdown_ping = time(NULL); /* Split loading, handle disk checks * over a number of cycles, reduce CPU hog */ switch (check_state) { /* Kick state machine */ case 0: check_state = 1; break; /* Check for timer change through configuration file */ case 1: check_timer(0); check_state = 2; break; /* Check the disk and ping AVR accordingly */ case -2: /* Check the disk to see if full and output appropriate * AVR command? */ case 2: cmd = keep_alive; if ((current_status = check_disk())) { /* Execute some user code on disk full */ if (first_warning) { first_warning = pester_message; exec_cmd(DISK_FULL, pct_used); } } /* Only update DISK LED on disk full change */ if (disk_full != current_status) { /* LED status */ cmd = 0x56; /* 'V' */ if (current_status) cmd++; else { first_warning = 0; exec_cmd(DISK_FULL, 0); } disk_full = current_status; } /* Ping AVR */ write_to_uart(cmd); check_state = 3; break; /* Wait for next refresh kick */ case 3: check_state = 0; break; } } /* Try and catch spurious fan fault messages */ switch (fan_fault) { case -1: break; case 1: fan_fault = 0; break; /* Check how long we have been operating with a fan failure */ case 2: case 3: case 4: if ((fault_time + fan_fault_seize) < time_now) { /* Run some user script on no fan restart message after * FAN_FAULT_SEIZE time */ exec_cmd(FAN_FAULT, 4); fan_fault = 5; } break; /* Fan sped up message received */ case 6: /* Attempt to slow fan down again after 5 minutes */ if ((fault_time + FIVE_MINUTES) < time_now) { write_to_uart(0x5C); /* '\\' */ fan_fault = 1; } break; } /* Check that the shutdown pause function (if activated) is still * available, no then ping the delayed time */ if ((power_press + SP_MONITOR_TIME) < time_now && first_time_flag > 1) { /* Inform the EventScript */ exec_cmd(FIVE_SHUTDOWN, shutdown_timer/60); first_time_flag = 1; power_press = 0; } } } }
int main( int argc, char ** argv) { char *line = NULL; char *qdisk = NULL; char *qamdevice = NULL; char *optstr = NULL; char *err_extra = NULL; char *s, *fp; int ch; dle_t *dle = NULL; int level; GSList *errlist; level_t *alevel; if (argc > 1 && argv && argv[1] && g_str_equal(argv[1], "--version")) { printf("selfcheck-%s\n", VERSION); return (0); } /* initialize */ /* * Configure program for internationalization: * 1) Only set the message locale for now. * 2) Set textdomain for all amanda related programs to "amanda" * We don't want to be forced to support dozens of message catalogs. */ setlocale(LC_MESSAGES, "C"); textdomain("amanda"); safe_fd(-1, 0); openbsd_fd_inform(); safe_cd(); set_pname("selfcheck"); /* Don't die when child closes pipe */ signal(SIGPIPE, SIG_IGN); add_amanda_log_handler(amanda_log_stderr); add_amanda_log_handler(amanda_log_syslog); dbopen(DBG_SUBDIR_CLIENT); startclock(); dbprintf(_("version %s\n"), VERSION); g_printf("OK version %s\n", VERSION); print_platform(); if(argc > 2 && g_str_equal(argv[1], "amandad")) { amandad_auth = g_strdup(argv[2]); } config_init(CONFIG_INIT_CLIENT, NULL); /* (check for config errors comes later) */ check_running_as(RUNNING_AS_CLIENT_LOGIN); our_features = am_init_feature_set(); our_feature_string = am_feature_to_string(our_features); /* handle all service requests */ /*@ignore@*/ for(; (line = agets(stdin)) != NULL; free(line)) { /*@end@*/ if (line[0] == '\0') continue; if(strncmp_const(line, "OPTIONS ") == 0) { if (g_options) { g_printf(_("ERROR [Multiple OPTIONS line in selfcheck input]\n")); error(_("Multiple OPTIONS line in selfcheck input\n")); /*NOTREACHED*/ } g_options = parse_g_options(line+8, 1); if(!g_options->hostname) { g_options->hostname = g_malloc(MAX_HOSTNAME_LENGTH+1); gethostname(g_options->hostname, MAX_HOSTNAME_LENGTH); g_options->hostname[MAX_HOSTNAME_LENGTH] = '\0'; } g_printf("OPTIONS "); if(am_has_feature(g_options->features, fe_rep_options_features)) { g_printf("features=%s;", our_feature_string); } if(am_has_feature(g_options->features, fe_rep_options_hostname)) { g_printf("hostname=%s;", g_options->hostname); } g_printf("\n"); fflush(stdout); if (g_options->config) { /* overlay this configuration on the existing (nameless) configuration */ config_init(CONFIG_INIT_CLIENT | CONFIG_INIT_EXPLICIT_NAME | CONFIG_INIT_OVERLAY, g_options->config); dbrename(get_config_name(), DBG_SUBDIR_CLIENT); } /* check for any config errors now */ if (config_errors(&errlist) >= CFGERR_ERRORS) { char *errstr = config_errors_to_error_string(errlist); g_printf("%s\n", errstr); amfree(errstr); amfree(line); dbclose(); return 1; } if (am_has_feature(g_options->features, fe_req_xml)) { break; } continue; } dle = alloc_dle(); s = line; ch = *s++; skip_whitespace(s, ch); /* find program name */ if (ch == '\0') { goto err; /* no program */ } dle->program = s - 1; skip_non_whitespace(s, ch); s[-1] = '\0'; /* terminate the program name */ dle->program_is_application_api = 0; if(g_str_equal(dle->program, "APPLICATION")) { dle->program_is_application_api = 1; skip_whitespace(s, ch); /* find dumper name */ if (ch == '\0') { goto err; /* no program */ } dle->program = s - 1; skip_non_whitespace(s, ch); s[-1] = '\0'; /* terminate the program name */ } if(strncmp_const(dle->program, "CALCSIZE") == 0) { skip_whitespace(s, ch); /* find program name */ if (ch == '\0') { goto err; /* no program */ } dle->program = s - 1; skip_non_whitespace(s, ch); s[-1] = '\0'; dle->estimatelist = g_slist_append(dle->estimatelist, GINT_TO_POINTER(ES_CALCSIZE)); } else { dle->estimatelist = g_slist_append(dle->estimatelist, GINT_TO_POINTER(ES_CLIENT)); } skip_whitespace(s, ch); /* find disk name */ if (ch == '\0') { goto err; /* no disk */ } qdisk = s - 1; skip_quoted_string(s, ch); s[-1] = '\0'; /* terminate the disk name */ dle->disk = unquote_string(qdisk); skip_whitespace(s, ch); /* find the device or level */ if (ch == '\0') { goto err; /* no device or level */ } if(!isdigit((int)s[-1])) { fp = s - 1; skip_quoted_string(s, ch); s[-1] = '\0'; /* terminate the device */ qamdevice = g_strdup(fp); dle->device = unquote_string(qamdevice); skip_whitespace(s, ch); /* find level number */ } else { dle->device = g_strdup(dle->disk); qamdevice = g_strdup(qdisk); } amfree(qamdevice); /* find level number */ if (ch == '\0' || sscanf(s - 1, "%d", &level) != 1) { goto err; /* bad level */ } alevel = g_new0(level_t, 1); alevel->level = level; dle->levellist = g_slist_append(dle->levellist, alevel); skip_integer(s, ch); skip_whitespace(s, ch); if (ch && strncmp_const_skip(s - 1, "OPTIONS ", s, ch) == 0) { skip_whitespace(s, ch); /* find the option string */ if(ch == '\0') { goto err; /* bad options string */ } optstr = s - 1; skip_quoted_string(s, ch); s[-1] = '\0'; /* terminate the options */ parse_options(optstr, dle, g_options->features, 1); /*@ignore@*/ check_options(dle); check_disk(dle); /*@end@*/ } else if (ch == '\0') { /* check all since no option */ need_samba=1; need_rundump=1; need_dump=1; need_restore=1; need_vdump=1; need_vrestore=1; need_xfsdump=1; need_xfsrestore=1; need_vxdump=1; need_vxrestore=1; need_runtar=1; need_gnutar=1; need_compress_path=1; need_calcsize=1; need_global_check=1; /*@ignore@*/ check_disk(dle); /*@end@*/ } else { goto err; /* bad syntax */ } free_dle(dle); dle = NULL; } if (g_options == NULL) { g_printf(_("ERROR [Missing OPTIONS line in selfcheck input]\n")); error(_("Missing OPTIONS line in selfcheck input\n")); /*NOTREACHED*/ } if (am_has_feature(g_options->features, fe_req_xml)) { char *errmsg = NULL; dle_t *dles, *dle, *dle_next; dles = amxml_parse_node_FILE(stdin, &errmsg); if (errmsg) { err_extra = errmsg; goto err; } if (merge_dles_properties(dles, 1) == 0) { goto checkoverall; } for (dle = dles; dle != NULL; dle = dle->next) { run_client_scripts(EXECUTE_ON_PRE_HOST_AMCHECK, g_options, dle, stdout); } for (dle = dles; dle != NULL; dle = dle->next) { check_options(dle); run_client_scripts(EXECUTE_ON_PRE_DLE_AMCHECK, g_options, dle, stdout); check_disk(dle); run_client_scripts(EXECUTE_ON_POST_DLE_AMCHECK, g_options, dle, stdout); } for (dle = dles; dle != NULL; dle = dle->next) { run_client_scripts(EXECUTE_ON_POST_HOST_AMCHECK, g_options, dle, stdout); } for (dle = dles; dle != NULL; dle = dle_next) { dle_next = dle->next; free_dle(dle); } } checkoverall: check_overall(); amfree(line); amfree(our_feature_string); am_release_feature_set(our_features); our_features = NULL; free_g_options(g_options); dbclose(); return 0; err: if (err_extra) { g_printf(_("ERROR [FORMAT ERROR IN REQUEST PACKET %s]\n"), err_extra); dbprintf(_("REQ packet is bogus: %s\n"), err_extra); } else { g_printf(_("ERROR [FORMAT ERROR IN REQUEST PACKET]\n")); dbprintf(_("REQ packet is bogus\n")); } amfree(err_extra); amfree(line); if (dle) free_dle(dle); dbclose(); return 1; }