Blame va_server_v1.c

Packit Service 501009
/* va_server_v1.c - kernel crash dump file translation library
Packit Service 501009
 *
Packit Service 501009
 * Copyright (C) 1999, 2000, 2001, 2002 Mission Critical Linux, Inc.
Packit Service 501009
 * Copyright (C) 2002, 2003, 2004, 2005 David Anderson
Packit Service 501009
 * Copyright (C) 2002, 2003, 2004, 2005 Red Hat, Inc. All rights reserved.
Packit Service 501009
 *
Packit Service 501009
 * This program is free software; you can redistribute it and/or modify
Packit Service 501009
 * it under the terms of the GNU General Public License as published by
Packit Service 501009
 * the Free Software Foundation; either version 2 of the License, or
Packit Service 501009
 * (at your option) any later version.
Packit Service 501009
 *
Packit Service 501009
 * This program is distributed in the hope that it will be useful,
Packit Service 501009
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit Service 501009
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Packit Service 501009
 * GNU General Public License for more details.
Packit Service 501009
 *
Packit Service 501009
 * 11/12/99, Dave Winchell, Preserve V1 interface.
Packit Service 501009
 */
Packit Service 501009
#include <zlib.h>
Packit Service 501009
#include <sys/types.h>
Packit Service 501009
#include <sys/stat.h>
Packit Service 501009
#include <fcntl.h>
Packit Service 501009
#include <unistd.h>
Packit Service 501009
#include <stdio.h>
Packit Service 501009
#include <stdlib.h>
Packit Service 501009
#include <string.h>
Packit Service 501009
#include "va_server.h"
Packit Service 501009
#include <errno.h>
Packit Service 501009
#include <sys/mman.h>
Packit Service 501009
#include <signal.h>
Packit Service 501009
Packit Service 501009
struct map_hdr_v1 *vas_map_base_v1 = (struct map_hdr_v1 *)0;     /* base of tree */
Packit Service 501009
Packit Service 501009
Packit Service 501009
#ifdef NOT_DEF
Packit Service 501009
#define trunc_page(x)   ((void *)(((unsigned long)(x)) & ~((unsigned long)(page_size - 1))))
Packit Service 501009
#define round_page(x)   trunc_page(((unsigned long)(x)) + ((unsigned long)(page_size - 1)))
Packit Service 501009
#endif
Packit Service 501009
Packit Service 501009
extern u_long vas_base_va;
Packit Service 501009
extern u_long vas_start_va;
Packit Service 501009
u_long vas_end_va;
Packit Service 501009
Packit Service 501009
void find_data_v1(u_long va, u_long *buf, u_long *len, u_long *offset);
Packit Service 501009
void load_data_v1(struct map_hdr_v1 *hdr, u_long index, u_long *buf, u_long *len);
Packit Service 501009
struct map_hdr_v1 *find_header_v1(u_long va);
Packit Service 501009
u_long vas_find_start_v1(void);
Packit Service 501009
u_long vas_find_end_v1(void);
Packit Service 501009
int read_maps_v1(char *crash_file);
Packit Service 501009
int read_map_v1(int blk_pos);
Packit Service 501009
Packit Service 501009
extern int Page_Size;
Packit Service 501009
Packit Service 501009
extern FILE *vas_file_p;
Packit Service 501009
Packit Service 501009
extern void *malloc(size_t);
Packit Service 501009
Packit Service 501009
Packit Service 501009
int va_server_init_v1(char *crash_file, u_long *start, u_long *end, u_long *stride)
Packit Service 501009
{
Packit Service 501009
	if(read_maps_v1(crash_file))
Packit Service 501009
		return -1;
Packit Service 501009
Packit Service 501009
	vas_base_va = vas_start_va = vas_find_start_v1();
Packit Service 501009
	vas_end_va = vas_find_end_v1();
Packit Service 501009
Packit Service 501009
	if(start)
Packit Service 501009
		*start = vas_start_va;
Packit Service 501009
	if(end)
Packit Service 501009
		*end = vas_end_va;
Packit Service 501009
	if(stride)
Packit Service 501009
		*stride = vas_map_base_v1->va_per_entry;
Packit Service 501009
	return 0;
Packit Service 501009
}
Packit Service 501009
Packit Service 501009
int vas_lseek_v1(u_long position, int whence)
Packit Service 501009
{
Packit Service 501009
	if(whence != SEEK_SET)
Packit Service 501009
		return -1;
Packit Service 501009
	if(position > (vas_end_va - vas_start_va)) {
Packit Service 501009
		printf("position 0x%lx beyond dump range of 0x%lx\n",
Packit Service 501009
		       position, (vas_end_va - vas_start_va));
Packit Service 501009
		return -1;
Packit Service 501009
	}
Packit Service 501009
	vas_base_va = vas_start_va + position;
Packit Service 501009
	return 0;
Packit Service 501009
}
Packit Service 501009
size_t vas_read_v1(void *buf_in, size_t count)
Packit Service 501009
{
Packit Service 501009
	u_long len, offset, buf, va;
Packit Service 501009
	u_long num, output, remaining;
Packit Service 501009
Packit Service 501009
Packit Service 501009
	if(count > (vas_end_va - vas_base_va)) {
Packit Service 501009
		printf("count 0x%lx greater than remaining dump of 0x%lx\n",
Packit Service 501009
		       (ulong)count, (vas_end_va - vas_base_va));
Packit Service 501009
		return -1;
Packit Service 501009
	}
Packit Service 501009
	va = vas_base_va;
Packit Service 501009
	remaining = count;
Packit Service 501009
	output = (u_long)buf_in;
Packit Service 501009
Packit Service 501009
	while(remaining) {
Packit Service 501009
		find_data_v1(va, &buf, &len, &offset);
Packit Service 501009
		num = (remaining > (len - offset)) ? (len - offset) : remaining;
Packit Service 501009
		bcopy((const void *)(buf+offset), (void *)output, num);
Packit Service 501009
		remaining -= num;
Packit Service 501009
		va += num;
Packit Service 501009
		output += num;
Packit Service 501009
	}
Packit Service 501009
	vas_base_va += count;
Packit Service 501009
	return count;
Packit Service 501009
}
Packit Service 501009
size_t vas_write_v1(void *buf_in, size_t count)
Packit Service 501009
{
Packit Service 501009
	u_long len, offset, buf, va;
Packit Service 501009
Packit Service 501009
	if(count != sizeof(u_long)) {
Packit Service 501009
		printf("count %d not %d\n", (int)count, (int)sizeof(u_long));
Packit Service 501009
		return -1;
Packit Service 501009
	}
Packit Service 501009
	va = vas_base_va;
Packit Service 501009
	find_data_v1(va, &buf, &len, &offset);
Packit Service 501009
	*(u_long *)(buf+offset) = *(u_long *)buf_in;
Packit Service 501009
Packit Service 501009
	vas_base_va += count;
Packit Service 501009
	return count;
Packit Service 501009
}
Packit Service 501009
Packit Service 501009
Packit Service 501009
void find_data_v1(u_long va, u_long *buf, u_long *len, u_long *offset)
Packit Service 501009
{
Packit Service 501009
	struct map_hdr_v1 *hdr;
Packit Service 501009
	u_long index, off;
Packit Service 501009
Packit Service 501009
	hdr = find_header_v1(va);
Packit Service 501009
	index = (va - hdr->start_va) / hdr->va_per_entry;
Packit Service 501009
	off = (va - hdr->start_va) % hdr->va_per_entry;
Packit Service 501009
	load_data_v1(hdr, index, buf, len);
Packit Service 501009
	if(offset)
Packit Service 501009
		*offset = off;
Packit Service 501009
}
Packit Service 501009
void vas_free_data_v1(u_long va)
Packit Service 501009
{
Packit Service 501009
	struct map_hdr_v1 *hdr;
Packit Service 501009
	u_long index;
Packit Service 501009
Packit Service 501009
	hdr = find_header_v1(va);
Packit Service 501009
	index = (va - hdr->start_va) / hdr->va_per_entry;
Packit Service 501009
Packit Service 501009
	if(hdr->map[index].exp_data) {
Packit Service 501009
		free((void *)hdr->map[index].exp_data);
Packit Service 501009
		hdr->map[index].exp_data = 0;
Packit Service 501009
	}
Packit Service 501009
}
Packit Service 501009
void load_data_v1(struct map_hdr_v1 *hdr, u_long index, u_long *buf, u_long *len)
Packit Service 501009
{
Packit Service 501009
	char *compr_buf;
Packit Service 501009
	char *exp_buf;
Packit Service 501009
	int ret, items;
Packit Service 501009
	uLongf destLen;
Packit Service 501009
Packit Service 501009
	if(hdr->map[index].exp_data)
Packit Service 501009
		goto out;
Packit Service 501009
	ret = fseek(vas_file_p, (long)((hdr->blk_offset + hdr->map[index].start_blk) * hdr->blk_size),
Packit Service 501009
		    SEEK_SET);
Packit Service 501009
Packit Service 501009
	if(ret == -1) {
Packit Service 501009
		printf("load_data: unable to fseek, errno = %d\n", ferror(vas_file_p));
Packit Service 501009
		clean_exit(1);
Packit Service 501009
	}
Packit Service 501009
	compr_buf =  (char *)malloc(2*hdr->va_per_entry);
Packit Service 501009
	if(!compr_buf) {
Packit Service 501009
		printf("load_data: bad ret from malloc, errno = %d\n", ferror(vas_file_p));
Packit Service 501009
		clean_exit(1);
Packit Service 501009
	}
Packit Service 501009
	items = fread((void *)compr_buf, sizeof(char), hdr->map[index].num_blks * hdr->blk_size, vas_file_p);
Packit Service 501009
	if(items != hdr->map[index].num_blks * hdr->blk_size) {
Packit Service 501009
		printf("unable to read blocks from errno = %d\n", ferror(vas_file_p));
Packit Service 501009
		clean_exit(1);
Packit Service 501009
	}
Packit Service 501009
	hdr->map[index].exp_data = exp_buf =  (char *)malloc(hdr->va_per_entry);
Packit Service 501009
	if(!exp_buf) {
Packit Service 501009
		printf("load_data: bad ret from malloc, errno = %d\n", ferror(vas_file_p));
Packit Service 501009
		clean_exit(1);
Packit Service 501009
	}
Packit Service 501009
	destLen = (uLongf)(2*hdr->va_per_entry);
Packit Service 501009
	ret = uncompress((Bytef *)exp_buf, &destLen, (const Bytef *)compr_buf, (uLong)items);
Packit Service 501009
	/*	if(destLen != hdr->va_per_entry) {
Packit Service 501009
		 printf("uncompress error\n");
Packit Service 501009
		 exit(1);
Packit Service 501009
	}
Packit Service 501009
	*/
Packit Service 501009
	if(ret) {
Packit Service 501009
		if(ret == Z_MEM_ERROR)
Packit Service 501009
			printf("load_data, bad ret Z_MEM_ERROR from uncompress\n");
Packit Service 501009
		else if(ret == Z_BUF_ERROR)
Packit Service 501009
			printf("load_data, bad ret Z_BUF_ERROR from uncompress\n");
Packit Service 501009
		else if(ret == Z_DATA_ERROR)
Packit Service 501009
			printf("load_data, bad ret Z_DATA_ERROR from uncompress\n");
Packit Service 501009
		else
Packit Service 501009
			printf("load_data, bad ret %d from uncompress\n", ret);
Packit Service 501009
		
Packit Service 501009
		clean_exit(1);
Packit Service 501009
	}
Packit Service 501009
	free((void *)compr_buf);
Packit Service 501009
  out:
Packit Service 501009
	if(buf)
Packit Service 501009
		*buf = (u_long)hdr->map[index].exp_data;
Packit Service 501009
	if(len)
Packit Service 501009
		*len = hdr->va_per_entry;
Packit Service 501009
	return;
Packit Service 501009
}
Packit Service 501009
Packit Service 501009
struct map_hdr_v1 *find_header_v1(u_long va)
Packit Service 501009
{
Packit Service 501009
	struct map_hdr_v1 *hdr;
Packit Service 501009
	int found = 0;
Packit Service 501009
Packit Service 501009
	for(hdr = vas_map_base_v1; hdr; hdr = hdr->next)
Packit Service 501009
		if((va >= hdr->start_va) && (va < hdr->end_va)) {
Packit Service 501009
			found = 1;
Packit Service 501009
			break;
Packit Service 501009
		}
Packit Service 501009
	if(found)
Packit Service 501009
		return  hdr;
Packit Service 501009
	else
Packit Service 501009
		return (struct map_hdr_v1 *)0;
Packit Service 501009
}
Packit Service 501009
u_long vas_find_start_v1(void)
Packit Service 501009
{
Packit Service 501009
	struct map_hdr_v1 *hdr;
Packit Service 501009
	u_long start;
Packit Service 501009
Packit Service 501009
	start = vas_map_base_v1->start_va;
Packit Service 501009
	for(hdr = vas_map_base_v1; hdr; hdr = hdr->next)
Packit Service 501009
		if(hdr->start_va < start)
Packit Service 501009
			start = hdr->start_va;
Packit Service 501009
Packit Service 501009
	return start;
Packit Service 501009
}
Packit Service 501009
u_long vas_find_end_v1(void)
Packit Service 501009
{
Packit Service 501009
	struct map_hdr_v1 *hdr;
Packit Service 501009
	u_long end;
Packit Service 501009
Packit Service 501009
	end = vas_map_base_v1->end_va;
Packit Service 501009
	for(hdr = vas_map_base_v1; hdr; hdr = hdr->next)
Packit Service 501009
		if(hdr->end_va > end)
Packit Service 501009
			end = hdr->end_va;
Packit Service 501009
Packit Service 501009
	return end;
Packit Service 501009
}
Packit Service 501009
int read_maps_v1(char *crash_file)
Packit Service 501009
{
Packit Service 501009
	int *cur_entry_p, *cp;
Packit Service 501009
	int ret, items, blk_pos;
Packit Service 501009
Packit Service 501009
	cur_entry_p = (int *)malloc(Page_Size);
Packit Service 501009
	if(!cur_entry_p) {
Packit Service 501009
		printf("read_maps: bad ret from malloc, errno = %d\n", ferror(vas_file_p));
Packit Service 501009
		clean_exit(1);
Packit Service 501009
	}
Packit Service 501009
	bzero((void *)cur_entry_p, Page_Size);
Packit Service 501009
Packit Service 501009
	vas_file_p = fopen(crash_file, "r");
Packit Service 501009
	if(vas_file_p == (FILE *)0) {
Packit Service 501009
		printf("read_maps: bad ret from fopen for %s: %s\n", crash_file, strerror(errno));
Packit Service 501009
		free(cur_entry_p);
Packit Service 501009
		return -1;
Packit Service 501009
	}
Packit Service 501009
	ret = fseek(vas_file_p, (long)0, SEEK_SET);
Packit Service 501009
	if(ret == -1) {
Packit Service 501009
		printf("read_maps: unable to fseek in  %s, errno = %d\n", crash_file, ferror(vas_file_p));
Packit Service 501009
		free(cur_entry_p);
Packit Service 501009
		return -1;
Packit Service 501009
	}	
Packit Service 501009
	items = fread((void *)cur_entry_p, 1, Page_Size, vas_file_p);
Packit Service 501009
	if(items != Page_Size) {
Packit Service 501009
		printf("read_maps: unable to read header from %s, errno = %d\n", crash_file, ferror(vas_file_p));
Packit Service 501009
		free(cur_entry_p);
Packit Service 501009
		return -1;
Packit Service 501009
	}
Packit Service 501009
	ret = -1;
Packit Service 501009
	cp = cur_entry_p;
Packit Service 501009
	while ((blk_pos = *cp++)) {
Packit Service 501009
		if (read_map_v1(blk_pos)) {
Packit Service 501009
			free(cur_entry_p);
Packit Service 501009
			return -1;
Packit Service 501009
		}
Packit Service 501009
		ret = 0;
Packit Service 501009
	}
Packit Service 501009
Packit Service 501009
	free(cur_entry_p);
Packit Service 501009
	return ret;
Packit Service 501009
}
Packit Service 501009
Packit Service 501009
Packit Service 501009
Packit Service 501009
Packit Service 501009
int read_map_v1(int blk_pos)
Packit Service 501009
{
Packit Service 501009
	struct crash_map_hdr_v1 *disk_hdr;
Packit Service 501009
	int ret, items;
Packit Service 501009
	struct map_hdr_v1 *hdr, *hdr1;
Packit Service 501009
	extern int console(char *, ...);
Packit Service 501009
Packit Service 501009
	hdr = (struct map_hdr_v1 *)malloc(sizeof(struct map_hdr_v1));
Packit Service 501009
	if(!hdr) {
Packit Service 501009
		printf("read_map: unable to malloc mem\n");
Packit Service 501009
		return -1;
Packit Service 501009
	}
Packit Service 501009
	bzero((void *)hdr, sizeof(struct map_hdr_v1));
Packit Service 501009
	disk_hdr = (struct crash_map_hdr_v1 *)malloc(Page_Size);
Packit Service 501009
	ret = fseek(vas_file_p, (long)(blk_pos*Page_Size), SEEK_SET);
Packit Service 501009
	if(ret == -1) {
Packit Service 501009
		console("va_server: unable to fseek, err = %d\n", ferror(vas_file_p));
Packit Service 501009
		free(hdr);
Packit Service 501009
		free(disk_hdr);
Packit Service 501009
		return -1;
Packit Service 501009
	}
Packit Service 501009
	items = fread((void *)disk_hdr, 1, Page_Size, vas_file_p);
Packit Service 501009
	if(items != Page_Size) {
Packit Service 501009
		free(hdr);
Packit Service 501009
		free(disk_hdr);
Packit Service 501009
		return -1;
Packit Service 501009
	}
Packit Service 501009
	if(disk_hdr->magic[0] != CRASH_MAGIC) {
Packit Service 501009
		console("va_server: bad magic 0x%lx\n", disk_hdr->magic[0]);
Packit Service 501009
		free(hdr);
Packit Service 501009
		free(disk_hdr);
Packit Service 501009
		return -1;
Packit Service 501009
	}
Packit Service 501009
	ret = fseek(vas_file_p, (long)((blk_pos + disk_hdr->map_block) * disk_hdr->blk_size), SEEK_SET);
Packit Service 501009
Packit Service 501009
	if(ret == -1) {
Packit Service 501009
		printf("va_server: unable to fseek, err = %d\n", ferror(vas_file_p));
Packit Service 501009
		free(hdr);
Packit Service 501009
		free(disk_hdr);
Packit Service 501009
		return -1;
Packit Service 501009
	}
Packit Service 501009
Packit Service 501009
	hdr->map_entries = disk_hdr->map_entries;
Packit Service 501009
	hdr->va_per_entry = disk_hdr->va_per_entry;
Packit Service 501009
	hdr->blk_offset = blk_pos - CRASH_OFFSET_BLKS;
Packit Service 501009
	hdr->blk_size = disk_hdr->blk_size;
Packit Service 501009
	Page_Size = disk_hdr->blk_size;    /* over-ride PAGE_SIZE */
Packit Service 501009
Packit Service 501009
	hdr->map = (struct crash_map_entry_v1 *)malloc(hdr->map_entries *
Packit Service 501009
							 sizeof(struct crash_map_entry_v1));
Packit Service 501009
	items = fread((void *)hdr->map, sizeof(struct crash_map_entry_v1), hdr->map_entries,
Packit Service 501009
		      vas_file_p);
Packit Service 501009
	if(items != hdr->map_entries) {
Packit Service 501009
		printf("unable to read map entries, err = %d\n", errno);
Packit Service 501009
		free(hdr);
Packit Service 501009
		free(disk_hdr);
Packit Service 501009
		return -1;
Packit Service 501009
	}
Packit Service 501009
Packit Service 501009
	hdr->start_va = hdr->map[0].start_va;
Packit Service 501009
	hdr->end_va = hdr->start_va + hdr->map_entries * hdr->va_per_entry;
Packit Service 501009
Packit Service 501009
	if(!vas_map_base_v1) {
Packit Service 501009
		vas_map_base_v1 = hdr;
Packit Service 501009
		hdr->next = (struct map_hdr_v1 *)0;
Packit Service 501009
	}
Packit Service 501009
	else {
Packit Service 501009
		hdr1 = vas_map_base_v1;
Packit Service 501009
		while(hdr1->next)
Packit Service 501009
			hdr1 = hdr1->next;
Packit Service 501009
		hdr1->next = hdr;
Packit Service 501009
		hdr->next = (struct map_hdr_v1 *)0;
Packit Service 501009
	}
Packit Service 501009
Packit Service 501009
	free((void *)disk_hdr);
Packit Service 501009
	return 0;
Packit Service 501009
Packit Service 501009
}
Packit Service 501009
Packit Service 501009
Packit Service 501009
Packit Service 501009