mpt_evt.c revision 215046
157416Smarkm/*- 257416Smarkm * Copyright (c) 2008 Yahoo!, Inc. 357416Smarkm * All rights reserved. 457416Smarkm * Written by: John Baldwin <jhb@FreeBSD.org> 557416Smarkm * 657416Smarkm * Redistribution and use in source and binary forms, with or without 757416Smarkm * modification, are permitted provided that the following conditions 857416Smarkm * are met: 957416Smarkm * 1. Redistributions of source code must retain the above copyright 1057416Smarkm * notice, this list of conditions and the following disclaimer. 1157416Smarkm * 2. Redistributions in binary form must reproduce the above copyright 1257416Smarkm * notice, this list of conditions and the following disclaimer in the 1357416Smarkm * documentation and/or other materials provided with the distribution. 1457416Smarkm * 3. Neither the name of the author nor the names of any co-contributors 1557416Smarkm * may be used to endorse or promote products derived from this software 1657416Smarkm * without specific prior written permission. 1757416Smarkm * 1857416Smarkm * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 1957416Smarkm * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2057416Smarkm * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2157416Smarkm * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 2257416Smarkm * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2357416Smarkm * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2457416Smarkm * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2557416Smarkm * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2657416Smarkm * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2757416Smarkm * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2857416Smarkm * SUCH DAMAGE. 2957416Smarkm */ 3057416Smarkm 3157416Smarkm#include <sys/cdefs.h> 3257416Smarkm__RCSID("$FreeBSD: head/usr.sbin/mptutil/mpt_evt.c 215046 2010-11-09 19:28:06Z jhb $"); 3357416Smarkm 3457416Smarkm#include <sys/param.h> 3557416Smarkm#include <sys/errno.h> 3657416Smarkm#include <ctype.h> 3757416Smarkm#include <err.h> 3857416Smarkm#include <stdio.h> 3990926Snectar#include <stdlib.h> 4057416Smarkm#include <unistd.h> 4157416Smarkm#include "mptutil.h" 4257416Smarkm 4357416Smarkmstatic CONFIG_PAGE_LOG_0 * 4457416Smarkmmpt_get_events(int fd, U16 *IOCStatus) 4557416Smarkm{ 4657416Smarkm 4757416Smarkm return (mpt_read_extended_config_page(fd, MPI_CONFIG_EXTPAGETYPE_LOG, 4857416Smarkm 0, 0, 0, IOCStatus)); 4957416Smarkm} 5057416Smarkm 5157416Smarkm/* 5257416Smarkm * 1 2 3 4 5 6 7 5357416Smarkm * 1234567890123456789012345678901234567890123456789012345678901234567890 5457416Smarkm * < ID> < time > <ty> <X XX XX XX XX XX XX XX XX XX XX XX XX XX |..............| 5557416Smarkm * ID Time Type Log Data 5657416Smarkm */ 5757416Smarkmstatic void 5857416Smarkmmpt_print_event(MPI_LOG_0_ENTRY *entry, int verbose) 5957416Smarkm{ 6057416Smarkm int i; 6157416Smarkm 6257416Smarkm printf("%5d %7ds %4x ", entry->LogSequence, entry->TimeStamp, 6357416Smarkm entry->LogEntryQualifier); 6457416Smarkm for (i = 0; i < 14; i++) 6557416Smarkm printf("%02x ", entry->LogData[i]); 6657416Smarkm printf("|"); 6757416Smarkm for (i = 0; i < 14; i++) 6857416Smarkm printf("%c", isprint(entry->LogData[i]) ? entry->LogData[i] : 6957416Smarkm '.'); 7057416Smarkm printf("|\n"); 7157416Smarkm printf(" "); 7257416Smarkm for (i = 0; i < 14; i++) 7390926Snectar printf("%02x ", entry->LogData[i + 14]); 7457416Smarkm printf("|"); 7557416Smarkm for (i = 0; i < 14; i++) 7657416Smarkm printf("%c", isprint(entry->LogData[i + 14]) ? 7757416Smarkm entry->LogData[i + 14] : '.'); 7857416Smarkm printf("|\n"); 7957416Smarkm} 8057416Smarkm 8157416Smarkmstatic int 8257416Smarkmevent_compare(const void *first, const void *second) 8357416Smarkm{ 8457416Smarkm MPI_LOG_0_ENTRY * const *one; 8557416Smarkm MPI_LOG_0_ENTRY * const *two; 8657416Smarkm 8757416Smarkm one = first; 8890926Snectar two = second; 8990926Snectar return ((*one)->LogSequence - ((*two)->LogSequence)); 9057416Smarkm} 9157416Smarkm 9257416Smarkmstatic int 9357416Smarkmshow_events(int ac, char **av) 9457416Smarkm{ 9557416Smarkm CONFIG_PAGE_LOG_0 *log; 9657416Smarkm MPI_LOG_0_ENTRY **entries; 9757416Smarkm int ch, error, fd, i, num_events, verbose; 9857416Smarkm 9957416Smarkm fd = mpt_open(mpt_unit); 10057416Smarkm if (fd < 0) { 10157416Smarkm error = errno; 10257416Smarkm warn("mpt_open"); 10357416Smarkm return (error); 10457416Smarkm } 10557416Smarkm 10657416Smarkm log = mpt_get_events(fd, NULL); 10757416Smarkm if (log == NULL) { 10857416Smarkm error = errno; 10957416Smarkm warn("Failed to get event log info"); 11057416Smarkm return (error); 11157416Smarkm } 11257416Smarkm 11357416Smarkm /* Default settings. */ 11457416Smarkm verbose = 0; 11557416Smarkm 11657416Smarkm /* Parse any options. */ 11757416Smarkm optind = 1; 11857416Smarkm while ((ch = getopt(ac, av, "v")) != -1) { 11957416Smarkm switch (ch) { 12057416Smarkm case 'v': 12157416Smarkm verbose = 1; 12257416Smarkm break; 12357416Smarkm case '?': 12457416Smarkm default: 12557416Smarkm return (EINVAL); 12657416Smarkm } 12757416Smarkm } 12857416Smarkm ac -= optind; 12957416Smarkm av += optind; 13057416Smarkm 13157416Smarkm /* Build a list of valid entries and sort them by sequence. */ 13257416Smarkm entries = malloc(sizeof(MPI_LOG_0_ENTRY *) * log->NumLogEntries); 13357416Smarkm if (entries == NULL) 13457416Smarkm return (ENOMEM); 13557416Smarkm num_events = 0; 13657416Smarkm for (i = 0; i < log->NumLogEntries; i++) { 13757416Smarkm if (log->LogEntry[i].LogEntryQualifier == 13857416Smarkm MPI_LOG_0_ENTRY_QUAL_ENTRY_UNUSED) 13957416Smarkm continue; 14057416Smarkm entries[num_events] = &log->LogEntry[i]; 14157416Smarkm num_events++; 14257416Smarkm } 14357416Smarkm 14457416Smarkm qsort(entries, num_events, sizeof(MPI_LOG_0_ENTRY *), event_compare); 14557416Smarkm 14657416Smarkm if (num_events == 0) 14757416Smarkm printf("Event log is empty\n"); 14857416Smarkm else { 14957416Smarkm printf(" ID Time Type Log Data\n"); 15057416Smarkm for (i = 0; i < num_events; i++) 15157416Smarkm mpt_print_event(entries[i], verbose); 15257416Smarkm } 15357416Smarkm 15457416Smarkm free(entries); 15557416Smarkm close(fd); 15657416Smarkm 15757416Smarkm return (0); 15857416Smarkm} 15957416SmarkmMPT_COMMAND(show, events, show_events); 16057416Smarkm