static int get_uak_expiry_date(void) { int rc; char date[UAK_EXPIRY_DATE_DATA_LENGTH] = {0}; char error_buf[ERR_BUF_SIZE]; rc = rtas_get_sysparm(SYS_PARAM_UAK_EXPIRY_DATE, ARRAY_SIZE(date), date); if (rc == 0) { /* +2 since first 2 bytes in date buffer filled by the RTAS call * are used for storing length of the buffer excluding the first * two bytes and including ending '\0' */ printf("Update Access Key expiry date (yyyymmdd) is: %s\n", date + 2); } else { switch (rc) { case -1: warnx("Hardware Error"); break; case -2: warnx("Busy, Try again later"); break; case -3: warnx("System parameter not supported"); break; case -9002: warnx("Not authorized"); break; case -9999: warnx("Parameter Error"); break; case 9900 ... 9905: warnx("Delay of %ld milliseconds is expected " "before calling ibm,get-system-parameter with " "the same parameter index", (long) pow(10, rc-9900)); break; default: if (is_librtas_error(rc)) { librtas_error(rc, error_buf, ERR_BUF_SIZE); warnx("%s", error_buf); } else { warnx("Unknown error"); } } rc = UAK_ERROR; } return rc; }
static int apply_uak_key(const char *keyfile) { int rc = 0; char keyvalue[UAK_KEY_DATA_LENGTH + 1] = {0}; /* +1 for validation */ char error_buf[ERR_BUF_SIZE]; if (!is_keyfile_valid(keyfile, keyvalue)) return UAK_ERROR; rc = rtas_set_sysparm(SYS_PARAM_UAK_KEY, keyvalue); if (rc == 0) { printf("Update Access Key set successfully\n"); } else { switch (rc) { case -1: warnx("Hardware Error"); break; case -2: warnx("Busy, Try again later"); break; case -3: warnx("System parameter not supported"); break; case -9002: warnx("Setting not allowed/authorized"); break; case -9999: warnx("Parameter Error"); break; case 9900 ... 9905: warnx("Delay of %ld milliseconds is expected " "before calling ibm,set-system-parameter " "with the same parameter index", (long) pow(10, rc-9900)); break; default: if (is_librtas_error(rc)) { librtas_error(rc, error_buf, ERR_BUF_SIZE); warnx("%s", error_buf); } } rc = UAK_ERROR; } return rc; }
/** * set_rtas_indicator - Set rtas indicator * * Call the rtas_set_indicator or rtas_set_dynamic_indicator librtas calls, * depending on whether the index indicates that the indicator is dynamic. * * @indicator identification or attention indicator * @loc location code of rtas indicator * @new_value value to update indicator to * * Returns : * rtas call return code */ static int set_rtas_indicator(int indicator, struct loc_code *loc, int new_value) { int rc; int rtas_token; char err_buf[RTAS_ERROR_BUF_SIZE]; rtas_token = get_rtas_token(indicator); if (rtas_token == -1) return -3; /* No such sensor implemented */ if (loc->index == DYNAMIC_INDICATOR) rc = rtas_set_dynamic_indicator(rtas_token, new_value, (void *)loc); else rc = rtas_set_indicator(rtas_token, loc->index, new_value); switch (rc) { case 0: /*success */ break; case -1: log_msg("Hardware error while setting the indicator at %s", loc->code); break; case -2: log_msg("Busy while setting the indicator at %s. " "Try again later", loc->code); break; case -3: log_msg("The indicator at %s is not implemented", loc->code); break; default: librtas_error(rc, err_buf, RTAS_ERROR_BUF_SIZE); log_msg("Could not set %ssensor %s indicators,\n%s", (loc->index == DYNAMIC_INDICATOR) ? "dynamic " : "", get_indicator_desc(indicator), err_buf); break; } return rc; }
int main(int argc, char **argv) { char *loc_code = ""; char err_buf[ERR_BUF_SIZE]; int lflag = 0, rc, c; unsigned int seq = 1, next_seq; struct buf_element *list, *current; if (get_platform() != PLATFORM_PSERIES_LPAR) { fprintf(stderr, "%s: is not supported on the %s platform\n", argv[0], platform_name); exit(1); } if (!check_rtas_call()) { fprintf(stderr, "The ibm,get-vpd RTAS call is not available " "on this system.\n"); return 4; } /* Parse command line options */ opterr = 0; while ((c = getopt (argc, argv, "l:h")) != -1) { switch (c) { case 'l': loc_code = optarg; lflag = 1; break; case 'h': print_help(argv[0]); return 0; case '?': if (isprint (optopt)) fprintf(stderr, "Unrecognized option: -%c.\n", optopt); else fprintf(stderr, "Unrecognized option character " "\\x%x.\n", optopt); print_usage(argv[0]); return 1; default: abort(); } } list = (struct buf_element *)malloc(sizeof(struct buf_element)); if (!list) { fprintf(stderr, "Out of memory\n"); return 5; } list->size = 0; list->next = NULL; current = list; do { rc = rtas_get_vpd(loc_code, current->buf, BUF_SIZE, seq, &next_seq, &(current->size)); switch (rc) { case CONTINUE: seq = next_seq; current->next = (struct buf_element *) malloc(sizeof(struct buf_element)); if (!current->next) { fprintf(stderr, "Out of memory\n"); delete_list(list); return 5; } current = current->next; current->size = 0; current->next = NULL; /* fall through */ case SUCCESS: break; case VPD_CHANGED: seq = 1; delete_list(list); list = (struct buf_element *) malloc(sizeof(struct buf_element)); if (!list) { fprintf(stderr, "Out of memory\n"); return 5; } list->size = 0; list->next = NULL; current = list; break; case PARAMETER_ERROR: delete_list(list); return 1; case HARDWARE_ERROR: delete_list(list); return 2; default: delete_list(list); if (is_librtas_error(rc)) { librtas_error(rc, err_buf, ERR_BUF_SIZE); fprintf(stderr, "Could not gather vpd\n%s\n", err_buf); } else { fprintf(stderr, "Could not gather vpd\n"); } return 3; } } while(rc != SUCCESS); current = list; do { size_t count; if (current->size <= 0) continue; count = fwrite(current->buf, 1, current->size, stdout); if (count < current->size) break; } while ((current = (current->next)) != NULL); delete_list(list); return 0; }
/** * Calls into librtas, available only on Power64 systems, and generates * a string of all available vpd data * @param yl * The location code of the device to pass to RTAS, if this is an empty * string, all of the system VPD will be stored in data. * @param data * char** where we will put the vpd (*data should be NULL) */ int RtasCollector::rtasGetVPD(const string& yl = "", char ** data = NULL) { int size = 0; struct rtas_buf_element *current, *list; unsigned int seq = 1, nextSeq; int rc; int vpd_changed = 0; char *locCode, *buf; list = new rtas_buf_element; if (!list) return -ENOMEM; memset(list->buf, '\0', RTAS_BUF_SIZE); list->size = 0; list->next = NULL; current = list; locCode = strdup(yl.c_str( )); if(locCode == NULL) return -ENOMEM; #ifdef DEBUGRTAS printf("Collecting RTAS info: [%d] %s\n", __LINE__, __FILE__); #endif do { rc = rtas_get_vpd(locCode, current->buf, RTAS_BUF_SIZE, seq, &nextSeq, &(current->size)); switch (rc) { case CONTINUE: vpd_changed = 0; seq = nextSeq; current->next = new rtas_buf_element; if (!current->next) { deleteList(list); return -ENOMEM; } current = current->next; current->size = 0; current->next = NULL; /* fall through */ case SUCCESS: break; case VPD_CHANGED: deleteList(list); vpd_changed ++; /* * If we keep getting the VPD_CHANGED rc * for more than a threshold, we quit, than * looping forever. */ if (vpd_changed > VPD_CHANGED_THRESHOLD) return -RTAS_ERROR; seq = 1; list = new rtas_buf_element; if (!list) return -ENOMEM; list->size = 0; list->next = NULL; current = list; break; case PARAMETER_ERROR: deleteList(list); return -RTAS_PARAMETER_ERROR; case HARDWARE_ERROR: deleteList(list); return -RTAS_HARDWARD_ERROR; default: deleteList(list); librtas_error(rc); return -RTAS_ERROR; } } while(rc != SUCCESS); #ifdef DEBUGRTAS printf("Done. [%d] %s\n", __LINE__, __FILE__); #endif free(locCode); current = list; do { size += current->size; } while ((current = (current->next)) != NULL); current = list; *data = new char[ size ]; if( *data == NULL ) return -ENOMEM; memset( *data, '\0', size ); buf = *data; do { memcpy(buf, current->buf, current->size); buf += current->size; } while ((current = (current->next)) != NULL); deleteList(list); return size; }
/** * get_rtas_list - Gets rtas indicator list * * @indicator identification or attention indicator * @loc pointer to loc_code structure * * Returns : * rtas call return value */ static int get_rtas_indices(int indicator, struct loc_code **loc) { int rc; int index = 1; int next_index; int rtas_token; char workarea[BUF_SIZE]; char err_buf[RTAS_ERROR_BUF_SIZE]; struct loc_code *list = NULL; rtas_token = get_rtas_token(indicator); if (rtas_token == -1) return -3; /* Indicator type not supported */ do { rc = rtas_get_indices(0, rtas_token, workarea, BUF_SIZE, index, &next_index); switch (rc) { case 1: /* more data available */ index = next_index; /* fall through */ case 0: /* success */ list = parse_rtas_workarea(list, workarea); if (!list) return -99; /* Out of heap memory */ break; case -1: /* hardware error */ log_msg("Hardware error retrieving indicator indices"); free_indicator_list(list); break; case RTAS_UNKNOWN_OP: /* Yes, this is a librtas return code but it should * be treated the same as a -3 return code, both * indicate that functionality is not supported */ librtas_error(rc, err_buf, RTAS_ERROR_BUF_SIZE); /* fall through */ case -3: /* indicator type not supported. */ log_msg("The %s indicators are not supported on this " "system", get_indicator_desc(indicator)); if (rc == RTAS_UNKNOWN_OP) log_msg(",\n%s", err_buf); free_indicator_list(list); break; case -4: /* list changed; start over */ free_indicator_list(list); list = NULL; index = 1; break; default: librtas_error(rc, err_buf, RTAS_ERROR_BUF_SIZE); log_msg("Could not retrieve data for %s " "indicators,\n%s", get_indicator_desc(indicator), err_buf); free_indicator_list(list); break; } } while ((rc == 1) || (rc == -4)); *loc = list; return rc; }