patch-2.4.19 linux-2.4.19/arch/ppc64/kernel/flight_recorder.c
Next file: linux-2.4.19/arch/ppc64/kernel/head.S
Previous file: linux-2.4.19/arch/ppc64/kernel/entry.S
Back to the patch index
Back to the overall index
- Lines: 183
- Date:
Fri Aug 2 17:39:43 2002
- Orig file:
linux-2.4.18/arch/ppc64/kernel/flight_recorder.c
- Orig date:
Wed Dec 31 16:00:00 1969
diff -urN linux-2.4.18/arch/ppc64/kernel/flight_recorder.c linux-2.4.19/arch/ppc64/kernel/flight_recorder.c
@@ -0,0 +1,182 @@
+/************************************************************************
+ * flight_recorder.c
+ ************************************************************************
+ * This code supports the a generic flight recorder. *
+ * Copyright (C) 20yy <Allan H Trautman> <IBM Corp> *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the: *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place, Suite 330, *
+ * Boston, MA 02111-1307 USA *
+ ************************************************************************
+ * This is a simple text based flight recorder. Useful for logging
+ * information the you may want to retreive at a latter time. Errors or
+ * debug inforamtion are good examples. A good method to dump the
+ * information is via the proc file system.
+ *
+ * To use.
+ * 1. Create the flight recorder object. Passing a NULL pointer will
+ * kmalloc the space for you. If it is too early for kmalloc, create
+ * space for the object. Beware, don't lie about the size, you will
+ * pay for that later.
+ * FlightRecorder* TestFr = alloc_Flight_Recorder(NULL,"TestFr",4096);
+ *
+ * 2. Log any notable events, initialzation, error conditions, etc.
+ * LOGFR(TestFr,"5. Stack Variable(10) %d",StackVariable);
+ *
+ * 3. Dump the information to a buffer.
+ * fr_Dump(TestFr, proc_file_buffer, proc_file_buffer_size);
+ *
+ ************************************************************************/
+#include <stdarg.h>
+#include <linux/kernel.h>
+#include <linux/rtc.h>
+#include <linux/slab.h>
+#include <asm/string.h>
+#include <asm/time.h>
+#include <asm/flight_recorder.h>
+
+static char LogText[512];
+static int LogTextIndex;
+static int LogCount = 0;
+static spinlock_t Fr_Lock;
+
+/************************************************************************
+ * Build the log time prefix based on Flags.
+ * 00 = No time prefix
+ * 01 = Date(mmddyy) Time(hhmmss) prefix
+ * 02 = Day(dd) Time(hhmmss) prefix
+ * 03 = Time(hhmmss) prefix
+ ************************************************************************/
+static void fr_Log_Time(FlightRecorder* Fr)
+{
+ struct timeval TimeClock;
+ struct rtc_time LogTime;
+
+ do_gettimeofday(&TimeClock);
+ to_tm(TimeClock.tv_sec, &LogTime);
+
+ if (Fr->Flags == 1) {
+ LogTextIndex = sprintf(LogText,"%02d%02d%02d %02d%02d%02d ",
+ LogTime.tm_mon, LogTime.tm_mday, LogTime.tm_year-2000,
+ LogTime.tm_hour,LogTime.tm_min, LogTime.tm_sec);
+ }
+ else if (Fr->Flags == 2) {
+ LogTextIndex = sprintf(LogText,"%02d %02d%02d%02d ",
+ LogTime.tm_mday,
+ LogTime.tm_hour,LogTime.tm_min, LogTime.tm_sec);
+ }
+
+ else if (Fr->Flags == 3) {
+ LogTextIndex = sprintf(LogText,"%02d%02d%02d ",
+ LogTime.tm_hour,LogTime.tm_min, LogTime.tm_sec);
+ }
+ else {
+ ++LogCount;
+ LogTextIndex = sprintf(LogText,"%04d. ",LogCount);
+ }
+}
+
+/************************************************************************/
+/* Log entry into buffer, */
+/* ->If entry is going to wrap, log "WRAP" and start at the top. */
+/************************************************************************/
+static void fr_Log_Data(FlightRecorder* Fr)
+{
+ int TextLen = strlen(LogText);
+ int Residual = ( Fr->EndPointer - Fr->NextPointer)-15;
+ if (TextLen > Residual) {
+ strcpy(Fr->NextPointer,"WRAP");
+ Fr->WrapPointer = Fr->NextPointer + 5;
+ Fr->NextPointer = Fr->StartPointer;
+ }
+ strcpy(Fr->NextPointer,LogText);
+ Fr->NextPointer += TextLen+1;
+ strcpy(Fr->NextPointer,"<=");
+}
+/************************************************************************
+ * Build the log text, support variable args.
+ ************************************************************************/
+void fr_Log_Entry(struct flightRecorder* LogFr, const char *fmt, ...)
+{
+ va_list arg_ptr;
+ spin_lock(&Fr_Lock);
+
+ fr_Log_Time(LogFr);
+ va_start(arg_ptr, fmt);
+ vsprintf(LogText+LogTextIndex, fmt, arg_ptr);
+ va_end(arg_ptr);
+ fr_Log_Data(LogFr);
+
+ spin_unlock(&Fr_Lock);
+
+}
+/************************************************************************
+ * Dump Flight Recorder into buffer.
+ * -> Handles the buffer wrapping.
+ ************************************************************************/
+int fr_Dump(FlightRecorder* Fr, char *Buffer, int BufferLen)
+{
+ int LineLen = 0;
+ char* StartEntry;
+ char* EndEntry;
+ spin_lock(&Fr_Lock);
+ /****************************************************************
+ * If Buffer has wrapped, find last usable entry to start with.
+ ****************************************************************/
+ if (Fr->WrapPointer != NULL) {
+ StartEntry = Fr->NextPointer+3;
+ StartEntry += strlen(StartEntry)+1;
+ EndEntry = Fr->WrapPointer;
+
+ while (EndEntry > StartEntry && LineLen < BufferLen) {
+ LineLen += sprintf(Buffer+LineLen,"%s\n",StartEntry);
+ StartEntry += strlen(StartEntry) + 1;
+ }
+ }
+
+ /****************************************************************
+ * Dump from the beginning to the last logged entry
+ ****************************************************************/
+ StartEntry = Fr->StartPointer;
+ EndEntry = Fr->NextPointer;
+ while (EndEntry > StartEntry && LineLen < BufferLen) {
+ LineLen += sprintf(Buffer+LineLen,"%s\n",StartEntry);
+ StartEntry += strlen(StartEntry) + 1;
+ }
+ spin_unlock(&Fr_Lock);
+ return LineLen;
+}
+
+/************************************************************************
+ * Allocate and Initialized the Flight Recorder
+ * -> If no FlightRecorder pointer is passed, the space is kmalloc.
+ ************************************************************************/
+FlightRecorder* alloc_Flight_Recorder(FlightRecorder* FrPtr, char* Signature, int SizeOfFr)
+{
+ FlightRecorder* Fr = FrPtr; /* Pointer to Object */
+ int FrSize = (SizeOfFr/16)*16; /* Could be static */
+ if (Fr == NULL)
+ Fr = (FlightRecorder*)kmalloc(SizeOfFr, GFP_KERNEL);
+ memset(Fr,0,SizeOfFr);
+ strcpy(Fr->Signature,Signature);
+ Fr->Size = FrSize;
+ Fr->Flags = 0;
+ Fr->StartPointer = (char*)&Fr->Buffer;
+ Fr->EndPointer = (char*)Fr + Fr->Size;
+ Fr->NextPointer = Fr->StartPointer;
+
+ fr_Log_Entry(Fr,"Initialized.");
+ return Fr;
+}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)