static void do_event_scan(void) { int error; do { memset(logdata, 0, rtas_error_log_max); error = rtas_call(event_scan, 4, 1, NULL, RTAS_EVENT_SCAN_ALL_EVENTS, 0, __pa(logdata), rtas_error_log_max); if (error == -1) { printk(KERN_ERR "event-scan failed\n"); break; } if (error == 0) { pSeries_log_error(logdata, ERR_TYPE_RTAS_LOG, 0); handle_rtas_event((struct rtas_error_log *)logdata); } } while(error == 0); }
/** * update_rtas_msgs * @brief Update RTAS messages in the platfrom log * * Update the file /var/log/platform with any RTAS events * found in syslog that have not been handled by rtas_errd. */ void update_rtas_msgs(void) { struct stat log_sbuf, msgs_sbuf; char *log_mmap = NULL, *log_mmap_end; char *msgs_mmap = NULL, *msgs_mmap_end; char *rtas_msgs_end, *rtas_msgs_start, *msgs_p; char *log_p; char *last_p; int last_rtas_log_no, last_rtas_msgs_no, cur_rtas_no; messages_log = "/var/log/messages"; if (access(messages_log, R_OK)) { /* try /var/log/syslog */ if (!access("/var/log/syslog", R_OK)) { messages_log = "/var/log/syslog"; } } if ((msgs_log_fd = open(messages_log, O_RDONLY)) < 0) { log_msg(NULL, "Could not open %s to update RTAS events, %s", messages_log, strerror(errno)); goto cleanup; } if ((fstat(msgs_log_fd, &msgs_sbuf)) < 0) { log_msg(NULL, "Cannot get status of %s to update RTAS events, " "%s", messages_log, strerror(errno)); goto cleanup; } /* abort if file size is zero */ if (msgs_sbuf.st_size == 0) { goto cleanup; } if ((msgs_mmap = mmap(0, msgs_sbuf.st_size, PROT_READ, MAP_PRIVATE, msgs_log_fd, 0)) == (char *)-1) { log_msg(NULL, "Cannot map %s to update RTAS events", messages_log); msgs_mmap = NULL; goto cleanup; } msgs_p = msgs_mmap; msgs_mmap_end = msgs_mmap + msgs_sbuf.st_size; if ((fstat(platform_log_fd, &log_sbuf)) < 0) { log_msg(NULL, "Cannot get status of %s to update RTAS events", platform_log); goto cleanup; } /* nothing to do if file size is zero */ if (log_sbuf.st_size == 0) goto cleanup; if ((log_mmap = mmap(0, log_sbuf.st_size, PROT_READ, MAP_PRIVATE, platform_log_fd, 0)) == (char *)-1) { log_msg(NULL, "Cannot map %s to update RTAS events, %s", platform_log, strerror(errno)); log_mmap = NULL; goto cleanup; } log_p = log_mmap; log_mmap_end = log_mmap + log_sbuf.st_size; /* find the last RTAS event in /var/log/platform */ last_p = NULL; log_p = find_rtas_start(log_p, log_mmap_end); while (log_p != NULL) { last_p = log_p; log_p = find_rtas_start(log_p + sizeof(RTAS_START), log_mmap_end); } if (last_p == NULL) last_rtas_log_no = 0; else last_rtas_log_no = get_rtas_no(last_p); /* We're finished with /var/log/platform; unamp it */ munmap(log_mmap, log_sbuf.st_size); log_mmap = NULL; /* find the last RTAS event in syslog */ last_p = NULL; msgs_p = find_rtas_start(msgs_p, msgs_mmap_end); while (msgs_p != NULL) { last_p = msgs_p; msgs_p = find_rtas_start(msgs_p + strlen(RTAS_START), msgs_mmap_end); } if (last_p == NULL) { dbg("%s does not conatin any RTAS events", messages_log); goto cleanup; } last_rtas_msgs_no = get_rtas_no(last_p); if (last_rtas_log_no >= last_rtas_msgs_no) goto cleanup; /* * If we get here we know there are some events that have not * been processed by rtas_errd, process them now. NOTE: There * are scenarios in which we will process events that have * already been processed. There is not much we can do about * this, just accept it and move along. */ /* Move to the first event that has not been handled so we * can process them in order. */ cur_rtas_no = 0; rtas_msgs_start = msgs_mmap; while (cur_rtas_no <= last_rtas_log_no) { rtas_msgs_start = find_rtas_start(rtas_msgs_start + strlen(RTAS_START), msgs_mmap_end); cur_rtas_no = get_rtas_no(rtas_msgs_start); } rtas_msgs_end = find_rtas_end(rtas_msgs_start, msgs_mmap_end); /* Retrieve RTAS events from syslog */ while (rtas_msgs_start != NULL) { struct event event; unsigned long *out_buf; char *tmp = rtas_msgs_start; memset(&event, 0, sizeof(event)); out_buf = (unsigned long *)event.event_buf; /* put event number in first */ cur_rtas_no = get_rtas_no(rtas_msgs_start); /* skip past the "RTAS event begin" message */ tmp += strlen(RTAS_START); while (tmp < rtas_msgs_end) { int i; /* find the word "RTAS" */ for ( ; *tmp != 'R'; tmp++); if (strncmp(tmp++, "RTAS", 4) != 0) continue; /* we found "RTAS", go to the colon */ for( ; *tmp != ':'; tmp++); /* add two to get to the first value */ tmp += 2; /* parse the values */ for (i = 0; i < 4; i++) { *out_buf = strtoul(tmp, NULL, 16); out_buf++; tmp += 9; /* char hex value + space */ } } /* Initializethe fields of the rtas event */ event.seq_num = cur_rtas_no; event.rtas_event = parse_rtas_event(event.event_buf, RTAS_ERROR_LOG_MAX); if (event.rtas_event == NULL) { log_msg(NULL, "Could not update RTAS Event %d to %s", cur_rtas_no, platform_log); } else { log_msg(NULL, "Updating RTAS event %d to %s", cur_rtas_no, platform_log); event.rtas_hdr = rtas_get_event_hdr_scn(event.rtas_event); event.length = event.rtas_hdr->ext_log_length + 8; handle_rtas_event(&event); } rtas_msgs_start = find_rtas_start(rtas_msgs_end, msgs_mmap_end); rtas_msgs_end = find_rtas_end(rtas_msgs_start, msgs_mmap_end); } cleanup: if (msgs_mmap) munmap(msgs_mmap, msgs_sbuf.st_size); if (msgs_log_fd != -1) close(msgs_log_fd); return; }