/*************************************************************************//**
*****************************************************************************
* @file disklog.c
* @brief
* @author Forrest Y. Yu
* @date Thu Nov 20 16:22:45 2008
*****************************************************************************
*****************************************************************************/
#include "type.h"
#include "config.h"
#include "stdio.h"
#include "const.h"
#include "protect.h"
#include "string.h"
#include "fs.h"
#include "proc.h"
#include "tty.h"
#include "console.h"
#include "global.h"
#include "keyboard.h"
#include "proto.h"
#include "hd.h"
#include "fs.h"
#define DISKLOG_RD_SECT(dev,sect_nr) rw_sector(DEV_READ, \
dev, \
(sect_nr) * SECTOR_SIZE, \
SECTOR_SIZE, /* read one sector */ \
getpid(), \
logdiskbuf);
#define DISKLOG_WR_SECT(dev,sect_nr) rw_sector(DEV_WRITE, \
dev, \
(sect_nr) * SECTOR_SIZE, \
SECTOR_SIZE, /* write one sector */ \
getpid(), \
logdiskbuf);
/* /\***************************************************************************** */
/* * do_disklog */
/* *****************************************************************************\/ */
/* /\** */
/* * Perform syslog() system call . */
/* * */
/* * @return */
/* *****************************************************************************\/ */
/* PUBLIC int do_disklog() */
/* { */
/* char buf[STR_DEFAULT_LEN]; */
/* /\* get parameters from the message *\/ */
/* int str_len = fs_msg.CNT; /\* length of filename *\/ */
/* int src = fs_msg.source; /\* caller proc nr. *\/ */
/* assert(str_len < STR_DEFAULT_LEN); */
/* phys_copy((void*)va2la(TASK_FS, buf), /\* to *\/ */
/* (void*)va2la(src, fs_msg.BUF), /\* from *\/ */
/* str_len); */
/* buf[str_len] = 0; /\* terminate the string *\/ */
/* return disklog(buf); */
/* } */
/*****************************************************************************
* disklog
*****************************************************************************/
/**
* <Ring 1> Write log string directly into disk.
*
* @param p Ptr to the MESSAGE.
*****************************************************************************/
PUBLIC int disklog(char * logstr)
{
int device = root_inode->i_dev;
struct super_block * sb = get_super_block(device);
int nr_log_blk0_nr = sb->nr_sects - NR_SECTS_FOR_LOG; /* 0x9D41-0x800=0x9541 */
static int pos = 0;
if (!pos) { /* first time invoking this routine */
#ifdef SET_LOG_SECT_SMAP_AT_STARTUP
/*
* set sector-map so that other files cannot use the log sectors
*/
int bits_per_sect = SECTOR_SIZE * 8; /* 4096 */
int smap_blk0_nr = 1 + 1 + sb->nr_imap_sects; /* 3 */
int sect_nr = smap_blk0_nr + nr_log_blk0_nr / bits_per_sect; /* 3+9=12 */
int byte_off = (nr_log_blk0_nr % bits_per_sect) / 8; /* 168 */
int bit_off = (nr_log_blk0_nr % bits_per_sect) % 8; /* 1 */
int sect_cnt = NR_SECTS_FOR_LOG / bits_per_sect + 2; /* 1 */
int bits_left= NR_SECTS_FOR_LOG; /* 2048 */
int i;
for (i = 0; i < sect_cnt; i++) {
DISKLOG_RD_SECT(device, sect_nr + i); /* DISKLOG_RD_SECT(?, 12) */
for (; byte_off < SECTOR_SIZE && bits_left > 0; byte_off++) {
for (; bit_off < 8; bit_off++) { /* repeat till enough bits are set */
assert(((logdiskbuf[byte_off] >> bit_off) & 1) == 0);
logdiskbuf[byte_off] |= (1 << bit_off);
if (--bits_left == 0)
break;
}
bit_off = 0;
}
byte_off = 0;
bit_off = 0;
DISKLOG_WR_SECT(device, sect_nr + i);
if (bits_left == 0)
break;
}
assert(bits_left == 0);
#endif /* SET_LOG_SECT_SMAP_AT_STARTUP */
pos = 0x40;
#ifdef MEMSET_LOG_SECTS
/* write padding stuff to log sectors */
int chunk = min(MAX_IO_BYTES, LOGDISKBUF_SIZE >> SECTOR_SIZE_SHIFT);
assert(chunk == 256);
int sects_left = NR_SECTS_FOR_LOG;
for (i = nr_log_blk0_nr;
i < nr_log_blk0_nr + NR_SECTS_FOR_LOG;
i += chunk) {
memset(logdiskbuf, 0x20, chunk*SECTOR_SIZE);
rw_sector(DEV_WRITE,
device,
i * SECTOR_SIZE,
chunk * SECTOR_SIZE,
getpid(),
logdiskbuf);
sects_left -= chunk;
}
if (sects_left != 0)
panic("sects_left should be 0, current: %d.", sects_left);
#endif /* MEMSET_LOG_SECTS */
}
char * p = logstr;
int bytes_left = strlen(logstr);
int sect_nr = nr_log_blk0_nr + (pos >> SECTOR_SIZE_SHIFT);
while (bytes_left) {
DISKLOG_RD_SECT(device, sect_nr);
int off = pos % SECTOR_SIZE;
int bytes = min(bytes_left, SECTOR_SIZE - off);
memcpy(&logdiskbuf[off], p, bytes);
off += bytes;
bytes_left -= bytes;
DISKLOG_WR_SECT(device, sect_nr);
sect_nr++;
pos += bytes;
p += bytes;
}
struct time t;
MESSAGE msg;
msg.type = GET_RTC_TIME;
msg.BUF= &t;
send_recv(BOTH, TASK_SYS, &msg);
/* write `pos' and time into the log file header */
DISKLOG_RD_SECT(device, nr_log_blk0_nr);
sprintf((char*)logdiskbuf, "%8d\n", pos);
memset(logdiskbuf+9, ' ', 22);
logdiskbuf[31] = '\n';
sprintf((char*)logdiskbuf+32, "<%d-%02d-%02d %02d:%02d:%02d>\n",
t.year,
t.month,
t.day,
t.hour,
t.minute,
t.second);
memset(logdiskbuf+32+22, ' ', 9);
logdiskbuf[63] = '\n';
DISKLOG_WR_SECT(device, nr_log_blk0_nr);
memset(logdiskbuf+64, logdiskbuf[32+19], 512-64);
DISKLOG_WR_SECT(device, nr_log_blk0_nr + NR_SECTS_FOR_LOG - 1);
return pos;
}
/* /\***************************************************************************** */
/* * inode2filename */
/* *****************************************************************************\/ */
/* /\** */
/* * Get filename via i-node */
/* * */
/* * @param inode */
/* * @param filename */
/* * */
/* * @return */
/* *****************************************************************************\/ */
/* PRIVATE char * inode2filename(int inode, char * filename) */
/* { */
/* int i, j; */
/* struct inode * dir_inode = root_inode; */
/* /\** */
/* * Search the dir for the file. */
/* *\/ */
/* int dir_blk0_nr = dir_inode->i_start_sect; */
/* int nr_dir_blks = (dir_inode->i_size + SECTOR_SIZE - 1) / SECTOR_SIZE; */
/* int nr_dir_entries = */
/* dir_inode->i_size / DIR_ENTRY_SIZE; /\** */
/* * including unused slots */
/* * (the file has been deleted */
/* * but the slot is still there) */
/* *\/ */
/* int m = 0; */
/* struct dir_entry * pde; */
/* for (i = 0; i < nr_dir_blks; i++) { */
/* DISKLOG_RD_SECT(dir_inode->i_dev, dir_blk0_nr + i); */
/* pde = (struct dir_entry *)logdiskbuf; */
/* for (j = 0; j < SECTOR_SIZE / DIR_ENTRY_SIZE; j++,pde++) { */
/* if (pde->inode_nr == inode) { */
/* memcpy(filename, pde->name, MAX_FILENAME_LEN); */
/* filename[MAX_FILENAME_LEN] = 0; */
/* if (filename[0] == '.') */
/* filename[0] = '/'; */
/* return filename; */
/* } */
/* if (++m > nr_dir_entries) */
/* break; */
/* } */
/* if (m > nr_dir_entries) /\* all entries have been iterated *\/ */
/* break; */
/* } */
/* /\* file not found *\/ */
/* return 0; */
/* } */
#define LOG_PROCS 1 /* YES */
#define LOG_FD_TABLE 1
#define LOG_INODE_TABLE 1
#define LOG_SMAP 1
#define LOG_IMAP 1
#define LOG_INODE_ARRAY 1
#define LOG_ROOT_DIR 1
#define LOG_MSG_SRC2DST 1 /* YES */
#define LOG_ARROW_PARENT_CHILD 1 /* YES */
#define LOG_ARROW_PROC_FD 1
#define LOG_ARROW_FD_INODE 1
#define LOG_ARROW_INODE_INODEARRAY 1
#if (LOG_SMAP == 1 || LOG_IMAP == 1 || LOG_INODE_ARRAY || LOG_ROOT_DIR == 1)
static char _buf[SECTOR_SIZE];
#endif
/*****************************************************************************
* dump_fd_graph
*****************************************************************************/
/**
* Output a dot graph file.
*
*****
评论9
最新资源