Exemple #1
0
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;
}