Hello community,
here is the log from the commit of package makedumpfile
checked in at Mon Feb 5 15:40:29 CET 2007.
--------
--- makedumpfile/makedumpfile.changes 2007-01-18 15:35:52.000000000 +0100
+++ /mounts/work_src_done/STABLE/makedumpfile/makedumpfile.changes 2007-02-05 13:37:51.000000000 +0100
@@ -1,0 +2,6 @@
+Mon Feb 5 13:37:36 CET 2007 - tiwai@suse.de
+
+- updated to version 1.1.0:
+ * support SSH transfer
+
+-------------------------------------------------------------------
Old:
----
makedumpfile-1.0.9.tar.bz2
New:
----
makedumpfile-1.1.0.tar.bz2
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ makedumpfile.spec ++++++
--- /var/tmp/diff_new_pack.c23215/_old 2007-02-05 15:40:20.000000000 +0100
+++ /var/tmp/diff_new_pack.c23215/_new 2007-02-05 15:40:20.000000000 +0100
@@ -1,5 +1,5 @@
#
-# spec file for package makedumpfile (Version 1.0.9)
+# spec file for package makedumpfile (Version 1.1.0)
#
# Copyright (c) 2007 SUSE LINUX Products GmbH, Nuernberg, Germany.
# This file and all modifications and additions to the pristine
@@ -13,8 +13,8 @@
Name: makedumpfile
BuildRequires: gcc-c++
%define elfutils_version 0.124
-License: Commercial (all types), GNU General Public License (GPL)
-Version: 1.0.9
+License: GNU General Public License (GPL)
+Version: 1.1.0
Release: 1
Summary: Partial kernel dump
Group: System/Kernel
@@ -72,6 +72,7 @@
%install
mkdir -p $RPM_BUILD_ROOT/bin
install -c -m 0755 makedumpfile $RPM_BUILD_ROOT/bin
+install -c -m 0755 makedumpfile-R.pl $RPM_BUILD_ROOT/bin
%clean
[ "$RPM_BUILD_ROOT" != "/" ] && rm -rf $RPM_BUILD_ROOT
@@ -80,9 +81,12 @@
%defattr(-,root,root)
%doc README
%doc elfutils-*/COPYING
-/bin/makedumpfile
+/bin/*
%changelog -n makedumpfile
+* Mon Feb 05 2007 - tiwai@suse.de
+- updated to version 1.1.0:
+ * support SSH transfer
* Thu Jan 18 2007 - tiwai@suse.de
- updated to version 1.0.9:
* fix the calculation of page size.
++++++ makedumpfile-1.0.9.tar.bz2 -> makedumpfile-1.1.0.tar.bz2 ++++++
diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/makedumpfile/diskdump_mod.h new/makedumpfile/diskdump_mod.h
--- old/makedumpfile/diskdump_mod.h 2007-01-18 21:26:57.000000000 +0100
+++ new/makedumpfile/diskdump_mod.h 2007-02-02 10:20:09.000000000 +0100
@@ -18,6 +18,7 @@
#define divideup(x, y) (((x) + ((y) - 1)) / (y))
#define round(x, y) (((x) / (y)) * (y))
+#define roundup(x, y) ((((x) + ((y) - 1)) / (y)) * (y))
#define DUMP_PARTITION_SIGNATURE "diskdump"
#define DISK_DUMP_SIGNATURE "DISKDUMP"
diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/makedumpfile/makedumpfile.c new/makedumpfile/makedumpfile.c
--- old/makedumpfile/makedumpfile.c 2007-01-18 21:27:17.000000000 +0100
+++ new/makedumpfile/makedumpfile.c 2007-02-02 10:20:09.000000000 +0100
@@ -307,6 +307,29 @@
MSG(" the system under operation(Capture kernel) as the one of dump_mem\n");
MSG(" (First-kernel).\n");
MSG("\n");
+ MSG(" [-F]:\n");
+ MSG(" Output dump data of flattened format to a standard output for\n");
+ MSG(" transporting dump data by ssh. Both kdump-compressed dumpfile\n");
+ MSG(" (-c/none) and ELF dumpfile(-E) can be transported in flattened format.\n");
+ MSG(" Ex:\n");
+ MSG(" makedumpfile -F -d8 -x vmlinux /proc/vmcore | ssh user@host \"cat > dumpfile.tmp\"\n");
+ MSG("\n");
+ MSG(" Analysis tools(ex. crash) cannot read flattened format directly.\n");
+ MSG(" For analysis, dump data of flattened format should be re-arranged to\n");
+ MSG(" a normal dumpfile(readable by analysis tools) by -R option.\n");
+ MSG("\n");
+ MSG(" [-R]:\n");
+ MSG(" Re-arrange dump data of flattened format to a normal dumpfile (readable by\n");
+ MSG(" analysis tools) from a standard input.\n");
+ MSG(" Ex:\n");
+ MSG(" makedumpfile -R dumpfile < dumpfile.tmp\n");
+ MSG(" makedumpfile -F -d8 -x vmlinux /proc/vmcore | ssh user@host \"makedumpfile -R dumpfile\"\n");
+ MSG("\n");
+ MSG(" Instead of using -R option, a perl script \"makedumpfile-R.pl\" re-arranges\n");
+ MSG(" dump data of flattened format to a normal dumpfile too.\n");
+ MSG(" Ex:\n");
+ MSG(" makedumpfile -F -d8 -x vmlinux /proc/vmcore | ssh user@host \"makedumpfile-R.pl dumpfile\"\n");
+ MSG("\n");
MSG(" [-v]:\n");
MSG(" Show the version of makedumpfile\n");
MSG("\n");
@@ -372,7 +395,17 @@
{
int fd;
- if ((fd = open(info->name_dumpfile, O_RDWR|O_CREAT|O_EXCL,
+ if (info->flag_flatten) {
+ if ((info->name_dumpfile
+ = (char *)malloc(sizeof(FILENAME_STDOUT))) == NULL) {
+ ERRMSG("Can't allocate memory for the filename. %s\n",
+ strerror(errno));
+ return FALSE;
+ }
+ fd = STDOUT_FILENO;
+ strcpy(info->name_dumpfile, FILENAME_STDOUT);
+
+ } else if ((fd = open(info->name_dumpfile, O_RDWR|O_CREAT|O_EXCL,
S_IRUSR|S_IWUSR)) < 0) {
ERRMSG("Can't open the dump file(%s). %s\n",
info->name_dumpfile, strerror(errno));
@@ -446,6 +479,19 @@
}
/*
+ * Open the following file when it re-arranges the dump data.
+ * - dump file
+ */
+int
+open_files_for_rearranging_dumpdata(struct DumpInfo *info)
+{
+ if (!open_dump_file(info))
+ return FALSE;
+
+ return TRUE;
+}
+
+/*
* Open the following files when it creates the dump file.
* - dump mem
* - dump file
@@ -2038,26 +2084,68 @@
}
int
-write_cache(struct cache_data *cd, void *buf, size_t size)
+is_bigendian()
+{
+ int i = 0x12345678;
+
+ if (*(char *)&i == 0x12)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+int
+write_buffer(int fd, off_t offset, void *buf, size_t buf_size,
+ char *file_name)
{
+ struct makedumpfile_data_header fdh;
const off_t failed = (off_t)-1;
+ if (fd == STDOUT_FILENO) {
+ /*
+ * Output a header of flattened format instead of
+ * lseek(). For sending dump data to a different
+ * architecture, change the values to big endian.
+ */
+ if (is_bigendian()){
+ fdh.offset = offset;
+ fdh.buf_size = buf_size;
+ } else {
+ fdh.offset = bswap_64(offset);
+ fdh.buf_size = bswap_64(buf_size);
+ }
+ if (write(fd, &fdh, sizeof(fdh)) != sizeof(fdh)) {
+ ERRMSG("Can't write the dump file(%s). %s\n",
+ file_name, strerror(errno));
+ return FALSE;
+ }
+ } else {
+ if (lseek(fd, offset, SEEK_SET) == failed) {
+ ERRMSG("Can't seek the dump file(%s). %s\n",
+ file_name, strerror(errno));
+ return FALSE;
+ }
+ }
+ if (write(fd, buf, buf_size) != buf_size) {
+ ERRMSG("Can't write the dump file(%s). %s\n",
+ file_name, strerror(errno));
+ return FALSE;
+ }
+ return TRUE;
+}
+
+int
+write_cache(struct cache_data *cd, void *buf, size_t size)
+{
memcpy(cd->buf + cd->buf_size, buf, size);
cd->buf_size += size;
if (cd->buf_size < cd->cache_size)
return TRUE;
- if (lseek(cd->fd, cd->offset, SEEK_SET) == failed) {
- ERRMSG("Can't seek the dump file(%s). %s\n",
- cd->file_name, strerror(errno));
- return FALSE;
- }
- if (write(cd->fd, cd->buf, cd->cache_size) != cd->cache_size) {
- ERRMSG("Can't write the dump file(%s). %s\n",
- cd->file_name, strerror(errno));
+ if (!write_buffer(cd->fd, cd->offset, cd->buf, cd->cache_size,
+ cd->file_name))
return FALSE;
- }
cd->buf_size -= cd->cache_size;
memcpy(cd->buf, cd->buf + cd->cache_size, cd->buf_size);
@@ -2068,26 +2156,192 @@
int
write_cache_bufsz(struct cache_data *cd)
{
- const off_t failed = (off_t)-1;
-
if (!cd->buf_size)
return TRUE;
- if (lseek(cd->fd, cd->offset, SEEK_SET) == failed) {
- ERRMSG("Can't seek the dump file(%s). %s\n",
- cd->file_name, strerror(errno));
+ if (!write_buffer(cd->fd, cd->offset, cd->buf, cd->buf_size,
+ cd->file_name))
return FALSE;
+
+ cd->offset += cd->buf_size;
+ cd->buf_size = 0;
+ return TRUE;
+}
+
+int
+read_buf_from_stdin(void *buf, int buf_size)
+{
+ int read_size = 0, tmp_read_size = 0;
+ time_t last_time, tm;
+
+ last_time = time(NULL);
+
+ while (read_size != buf_size) {
+
+ tmp_read_size = read(STDIN_FILENO, buf + read_size,
+ buf_size - read_size);
+
+ if (tmp_read_size < 0) {
+ ERRMSG("Can't read STDIN. %s\n", strerror(errno));
+ return FALSE;
+
+ } else if (0 == tmp_read_size) {
+ /*
+ * If it cannot get any data from a standard input
+ * while long time, break this loop.
+ */
+ tm = time(NULL);
+ if (TIMEOUT_STDIN < (tm - last_time)) {
+ ERRMSG("Can't get any data from STDIN.\n");
+ return FALSE;
+ }
+ } else {
+ read_size += tmp_read_size;
+ last_time = time(NULL);
+ }
}
- if (write(cd->fd, cd->buf, cd->buf_size) != cd->buf_size) {
- ERRMSG("Can't write the dump file(%s). %s\n",
- cd->file_name, strerror(errno));
+ return TRUE;
+}
+
+int
+read_start_flat_header(struct DumpInfo *info)
+{
+ char *buf = NULL;
+ struct makedumpfile_header fh;
+
+ int ret = FALSE;
+
+ if ((buf = malloc(MAX_SIZE_MDF_HEADER)) == NULL) {
+ ERRMSG("Can't allocate memory for buffer of flat header. %s\n",
+ strerror(errno));
return FALSE;
}
- cd->offset += cd->buf_size;
- cd->buf_size = 0;
+
+ /*
+ * Get flat header.
+ */
+ if (!read_buf_from_stdin(buf, MAX_SIZE_MDF_HEADER)) {
+ ERRMSG("Can't get header of flattened format.\n");
+ goto out;
+ }
+ memcpy(&fh, buf, sizeof(fh));
+
+ if (!is_bigendian()){
+ fh.type = bswap_64(fh.type);
+ fh.version = bswap_64(fh.version);
+ }
+
+ /*
+ * Check flat header.
+ */
+ if (strcmp(fh.signature, MAKEDUMPFILE_SIGNATURE)) {
+ ERRMSG("Can't get signature of flattened format.\n");
+ goto out;
+ }
+ if (fh.type != TYPE_FLAT_HEADER) {
+ ERRMSG("Can't get type of flattened format.\n");
+ goto out;
+ }
+
+ ret = TRUE;
+out:
+ if (buf != NULL)
+ free(buf);
+
+ return ret;
+}
+
+int
+read_flat_data_header(struct makedumpfile_data_header *fdh)
+{
+ if (!read_buf_from_stdin(fdh,
+ sizeof(struct makedumpfile_data_header))) {
+ ERRMSG("Can't get header of flattened format.\n");
+ return FALSE;
+ }
+ if (!is_bigendian()){
+ fdh->offset = bswap_64(fdh->offset);
+ fdh->buf_size = bswap_64(fdh->buf_size);
+ }
return TRUE;
}
+int
+rearrange_dumpdata(struct DumpInfo *info)
+{
+ int buf_size, read_size, tmp_read_size;
+ char *buf = NULL;
+ struct makedumpfile_data_header fdh;
+
+ int ret = FALSE;
+
+ buf_size = SIZE_BUF_STDIN;
+
+ /*
+ * Get flat header.
+ */
+ if (!read_start_flat_header(info)) {
+ ERRMSG("Can't get header of flattened format.\n");
+ goto out;
+ }
+
+ if ((buf = malloc(buf_size)) == NULL) {
+ ERRMSG("Can't allocate memory for buffer of flattend format. %s\n",
+ strerror(errno));
+ return FALSE;
+ }
+
+ /*
+ * Read the first data header.
+ */
+ if (!read_flat_data_header(&fdh)) {
+ ERRMSG("Can't get header of flattened format.\n");
+ goto out;
+ }
+
+ do {
+ read_size = 0;
+ while (read_size < fdh.buf_size) {
+ if (buf_size < (fdh.buf_size - read_size))
+ tmp_read_size = buf_size;
+ else
+ tmp_read_size = fdh.buf_size - read_size;
+
+ if (!read_buf_from_stdin(buf, tmp_read_size)) {
+ ERRMSG("Can't get data of flattened format.\n");
+ goto out;
+ }
+ if (!write_buffer(info->fd_dumpfile,
+ fdh.offset + read_size, buf, tmp_read_size,
+ info->name_dumpfile))
+ goto out;
+
+ read_size += tmp_read_size;
+ }
+ /*
+ * Read the next header.
+ */
+ if (!read_flat_data_header(&fdh)) {
+ ERRMSG("Can't get data header of flattened format.\n");
+ goto out;
+ }
+
+ } while ((0 <= fdh.offset) && (0 < fdh.buf_size));
+
+ if ((fdh.offset != END_FLAG_FLAT_HEADER)
+ || (fdh.buf_size != END_FLAG_FLAT_HEADER)) {
+ ERRMSG("Can't get valid end header of flattened format.\n");
+ goto out;
+ }
+
+ ret = TRUE;
+out:
+ if (buf != NULL)
+ free(buf);
+
+ return ret;
+}
+
/*
* Get the number of online nodes.
*/
@@ -2818,6 +3072,70 @@
}
int
+write_start_flat_header(struct DumpInfo *info)
+{
+ char *buf = NULL;
+ struct makedumpfile_header fh;
+
+ int ret = FALSE;
+
+ if (!info->flag_flatten)
+ return FALSE;
+
+ strcpy(fh.signature, MAKEDUMPFILE_SIGNATURE);
+
+ /*
+ * For sending dump data to a different architecture, change the values
+ * to big endian.
+ */
+ if (is_bigendian()){
+ fh.type = TYPE_FLAT_HEADER;
+ fh.version = VERSION_FLAT_HEADER;
+ } else {
+ fh.type = bswap_64(TYPE_FLAT_HEADER);
+ fh.version = bswap_64(VERSION_FLAT_HEADER);
+ }
+
+ if ((buf = calloc(1, MAX_SIZE_MDF_HEADER)) == NULL) {
+ ERRMSG("Can't allocate memory for header of flattened format. %s\n",
+ strerror(errno));
+ return FALSE;
+ }
+ memcpy(buf, &fh, sizeof(fh));
+ if (write(info->fd_dumpfile, buf, MAX_SIZE_MDF_HEADER)
+ != MAX_SIZE_MDF_HEADER) {
+ ERRMSG("Can't write the dump file(%s). %s\n",
+ info->name_dumpfile, strerror(errno));
+ goto out;
+ }
+ ret = TRUE;
+out:
+ if (buf != NULL)
+ free(buf);
+
+ return ret;
+}
+
+int
+write_end_flat_header(struct DumpInfo *info)
+{
+ struct makedumpfile_data_header fdh;
+
+ if (!info->flag_flatten)
+ return FALSE;
+
+ fdh.offset = END_FLAG_FLAT_HEADER;
+ fdh.buf_size = END_FLAG_FLAT_HEADER;
+
+ if (write(info->fd_dumpfile, &fdh, sizeof(fdh)) != sizeof(fdh)) {
+ ERRMSG("Can't write the dump file(%s). %s\n",
+ info->name_dumpfile, strerror(errno));
+ return FALSE;
+ }
+ return TRUE;
+}
+
+int
write_elf_header(struct DumpInfo *info)
{
int i, num_loads_dumpfile;
@@ -2867,25 +3185,15 @@
/*
* Write a ELF header.
*/
- if (lseek(info->fd_dumpfile, 0, SEEK_SET) == failed) {
- ERRMSG("Can't seek the dump file(%s). %s\n",
- info->name_dumpfile, strerror(errno));
- goto out;
- }
if (info->flag_elf64) { /* ELF64 */
- if (write(info->fd_dumpfile, &ehdr64, sizeof(ehdr64))
- != sizeof(ehdr64)) {
- ERRMSG("Can't write the dump file(%s). %s\n",
- info->name_dumpfile, strerror(errno));
+ if (!write_buffer(info->fd_dumpfile, 0, &ehdr64, sizeof(ehdr64),
+ info->name_dumpfile))
goto out;
- }
+
} else { /* ELF32 */
- if (write(info->fd_dumpfile, &ehdr32, sizeof(ehdr32))
- != sizeof(ehdr32)) {
- ERRMSG("Can't write the dump file(%s). %s\n",
- info->name_dumpfile, strerror(errno));
+ if (!write_buffer(info->fd_dumpfile, 0, &ehdr32, sizeof(ehdr32),
+ info->name_dumpfile))
goto out;
- }
}
/*
@@ -2911,12 +3219,10 @@
note64.p_offset = offset_note_dumpfile;
size_note = note64.p_filesz;
- if (write(info->fd_dumpfile, ¬e64, sizeof(note64))
- != sizeof(note64)) {
- ERRMSG("Can't write the dump file(%s). %s\n",
- info->name_dumpfile, strerror(errno));
+ if (!write_buffer(info->fd_dumpfile, sizeof(ehdr64), ¬e64,
+ sizeof(note64), info->name_dumpfile))
goto out;
- }
+
} else { /* ELF32 */
for (i = 0; i < ehdr32.e_phnum; i++) {
if (!get_elf32_phdr(info, i, ¬e32)) {
@@ -2937,12 +3243,9 @@
note32.p_offset = offset_note_dumpfile;
size_note = note32.p_filesz;
- if (write(info->fd_dumpfile, ¬e32, sizeof(note32))
- != sizeof(note32)) {
- ERRMSG("Can't write the dump file(%s). %s\n",
- info->name_dumpfile, strerror(errno));
+ if (!write_buffer(info->fd_dumpfile, sizeof(ehdr32), ¬e32,
+ sizeof(note32), info->name_dumpfile))
goto out;
- }
}
/*
@@ -2964,15 +3267,9 @@
info->name_memory, strerror(errno));
goto out;
}
- if (lseek(info->fd_dumpfile, offset_note_dumpfile, SEEK_SET) == failed){
- ERRMSG("Can't seek the dump file(%s). %s\n",
- info->name_dumpfile, strerror(errno));
- }
- if (write(info->fd_dumpfile, buf, size_note) != size_note) {
- ERRMSG("Can't write the dump file(%s). %s\n",
- info->name_dumpfile, strerror(errno));
+ if (!write_buffer(info->fd_dumpfile, offset_note_dumpfile, buf,
+ size_note, info->name_dumpfile))
goto out;
- }
/*
* Set a offset of PT_LOAD segment.
@@ -2993,7 +3290,6 @@
size_t size;
struct disk_dump_header *dh = info->dump_header;
struct kdump_sub_header sub_dump_header;
- const off_t failed = (off_t)-1;
if (info->flag_elf_dumpfile)
return FALSE;
@@ -3009,33 +3305,18 @@
dh->bitmap_blocks
= divideup(info->len_bitmap, dh->block_size);
- if (lseek(info->fd_dumpfile, 0, SEEK_SET) == failed) {
- ERRMSG("Can't seek the dump file(%s). %s\n",
- info->name_dumpfile, strerror(errno));
- return FALSE;
- }
size = sizeof(struct disk_dump_header);
- if (write(info->fd_dumpfile, dh, size) != size) {
- ERRMSG("Can't write the dump file(%s). %s\n",
- info->name_dumpfile, strerror(errno));
+ if (!write_buffer(info->fd_dumpfile, 0, dh, size, info->name_dumpfile))
return FALSE;
- }
/*
* Write sub header
*/
sub_dump_header.phys_base = info->phys_base;
- if (lseek(info->fd_dumpfile, dh->block_size, SEEK_SET) == failed) {
- ERRMSG("Can't seek the dump file(%s). %s\n",
- info->name_dumpfile, strerror(errno));
- return FALSE;
- }
size = sizeof(struct kdump_sub_header);
- if (write(info->fd_dumpfile, &sub_dump_header, size) != size) {
- ERRMSG("Can't write the dump file(%s). %s\n",
- info->name_dumpfile, strerror(errno));
+ if (!write_buffer(info->fd_dumpfile, dh->block_size, &sub_dump_header,
+ size, info->name_dumpfile))
return FALSE;
- }
info->offset_bitmap1
= (1 + dh->sub_hdr_size) * dh->block_size;
@@ -3073,13 +3354,14 @@
unsigned long long num_dumpable = 0, num_dumped = 0, per;
unsigned long long memsz, filesz;
unsigned long frac_head, frac_tail;
- off_t off_hdr_load, off_seg_load, off_memory;
+ off_t off_seg_load, off_memory;
Elf64_Ehdr ehdr64;
Elf64_Phdr load64;
Elf32_Ehdr ehdr32;
Elf32_Phdr load32;
char *buf = NULL;
struct dump_bitmap bitmap2;
+ struct cache_data cd_hdr, cd_seg;
const off_t failed = (off_t)-1;
int ret = FALSE;
@@ -3092,6 +3374,18 @@
bitmap2.buf = NULL;
bitmap2.offset = info->len_bitmap/2;
+ cd_hdr.fd = info->fd_dumpfile;
+ cd_hdr.file_name = info->name_dumpfile;
+ cd_hdr.cache_size = info->page_size<<info->block_order;
+ cd_hdr.buf_size = 0;
+ cd_hdr.buf = NULL;
+
+ cd_seg.fd = info->fd_dumpfile;
+ cd_seg.file_name = info->name_dumpfile;
+ cd_seg.cache_size = info->page_size<<info->block_order;
+ cd_seg.buf_size = 0;
+ cd_seg.buf = NULL;
+
if ((buf = malloc(info->page_size)) == NULL) {
ERRMSG("Can't allocate memory for buffer. %s\n",
strerror(errno));
@@ -3102,6 +3396,19 @@
strerror(errno));
goto out;
}
+ if ((cd_hdr.buf = malloc(cd_hdr.cache_size + info->page_size))
+ == NULL) {
+ ERRMSG("Can't allocate memory for the page data buffer. %s\n",
+ strerror(errno));
+ goto out;
+ }
+ if ((cd_seg.buf = malloc(cd_seg.cache_size + info->page_size))
+ == NULL) {
+ ERRMSG("Can't allocate memory for the page data buffer. %s\n",
+ strerror(errno));
+ goto out;
+ }
+
/*
* Count the number of dumpable pages.
*/
@@ -3111,18 +3418,19 @@
}
per = num_dumpable / 100;
- off_seg_load = info->offset_load_dumpfile;
+ off_seg_load = info->offset_load_dumpfile;
+ cd_seg.offset = info->offset_load_dumpfile;
off_memory = 0;
if (info->flag_elf64) { /* ELF64 */
- off_hdr_load = sizeof(Elf64_Ehdr) + sizeof(Elf64_Phdr);
+ cd_hdr.offset = sizeof(Elf64_Ehdr) + sizeof(Elf64_Phdr);
if (!get_elf64_ehdr(info, &ehdr64)) {
ERRMSG("Can't get ehdr64.\n");
goto out;
}
phnum = ehdr64.e_phnum;
} else { /* ELF32 */
- off_hdr_load = sizeof(Elf32_Ehdr) + sizeof(Elf32_Phdr);
+ cd_hdr.offset = sizeof(Elf32_Ehdr) + sizeof(Elf32_Phdr);
if (!get_elf32_ehdr(info, &ehdr32)) {
ERRMSG("Can't get ehdr32.\n");
goto out;
@@ -3227,26 +3535,13 @@
/*
* Write a PT_LOAD header.
*/
- if (lseek(info->fd_dumpfile, off_hdr_load, SEEK_SET)
- == failed) {
- ERRMSG("Can't seek the dump file(%s). %s\n",
- info->name_dumpfile, strerror(errno));
- goto out;
- }
if (info->flag_elf64) { /* ELF64 */
- if (write(info->fd_dumpfile, &load64,
- sizeof(load64)) != sizeof(load64)) {
- ERRMSG("Can't write the dump file(%s). %s\n",
- info->name_dumpfile, strerror(errno));
+ if (!write_cache(&cd_hdr, &load64, sizeof(load64)))
goto out;
- }
+
} else { /* ELF32 */
- if (write(info->fd_dumpfile, &load32,
- sizeof(load32)) != sizeof(load32)) {
- ERRMSG("Can't write the dump file(%s). %s\n",
- info->name_dumpfile, strerror(errno));
+ if (!write_cache(&cd_hdr, &load32, sizeof(load32)))
goto out;
- }
}
/*
* Write a PT_LOAD segment.
@@ -3263,13 +3558,6 @@
info->name_memory, strerror(errno));
goto out;
}
- if (lseek(info->fd_dumpfile, off_seg_load, SEEK_SET)
- == failed) {
- ERRMSG("Can't seek the dump file(%s). %s\n",
- info->name_dumpfile, strerror(errno));
- goto out;
- }
-
if (info->flag_elf64) /* ELF64 */
bufsz_remain = load64.p_filesz;
else /* ELF32 */
@@ -3290,15 +3578,13 @@
info->name_memory, strerror(errno));
goto out;
}
- if (write(info->fd_dumpfile, buf, bufsz_write)
- != bufsz_write) {
- ERRMSG("Can't write the dump file(%s). %s\n",
- info->name_dumpfile, strerror(errno));
+ if (!write_cache(&cd_seg, buf, bufsz_write))
goto out;
- }
+
bufsz_remain -= page_size;
num_dumped++;
}
+
if (info->flag_elf64) { /* ELF64 */
load64.p_paddr += load64.p_memsz;
#ifdef __x86__
@@ -3308,7 +3594,6 @@
load64.p_vaddr += load64.p_memsz;
#endif /* x86 */
paddr = load64.p_paddr;
- off_hdr_load += sizeof(load64);
off_seg_load += load64.p_filesz;
} else { /* ELF32 */
load32.p_paddr += load32.p_memsz;
@@ -3319,7 +3604,6 @@
load32.p_vaddr += load32.p_memsz;
#endif /* x86 */
paddr = load32.p_paddr;
- off_hdr_load += sizeof(load32);
off_seg_load += load32.p_filesz;
}
num_excluded = 0;
@@ -3342,26 +3626,13 @@
/*
* Write a PT_LOAD header.
*/
- if (lseek(info->fd_dumpfile, off_hdr_load, SEEK_SET)
- == failed) {
- ERRMSG("Can't seek the dump file(%s). %s\n",
- info->name_dumpfile, strerror(errno));
- goto out;
- }
if (info->flag_elf64) { /* ELF64 */
- if (write(info->fd_dumpfile, &load64, sizeof(load64))
- != sizeof(load64)) {
- ERRMSG("Can't write the dump file(%s). %s\n",
- info->name_dumpfile, strerror(errno));
+ if (!write_cache(&cd_hdr, &load64, sizeof(load64)))
goto out;
- }
+
} else { /* ELF32 */
- if (write(info->fd_dumpfile, &load32, sizeof(load32))
- != sizeof(load32)) {
- ERRMSG("Can't write the dump file(%s). %s\n",
- info->name_dumpfile, strerror(errno));
+ if (!write_cache(&cd_hdr, &load32, sizeof(load32)))
goto out;
- }
}
/*
@@ -3379,12 +3650,6 @@
info->name_memory, strerror(errno));
goto out;
}
- if (lseek(info->fd_dumpfile, off_seg_load, SEEK_SET)
- == failed) {
- ERRMSG("Can't seek the dump file(%s). %s\n",
- info->name_dumpfile, strerror(errno));
- goto out;
- }
if (info->flag_elf64) /* ELF64 */
bufsz_remain = load64.p_filesz;
else /* ELF32 */
@@ -3405,23 +3670,22 @@
info->name_memory, strerror(errno));
goto out;
}
- if (write(info->fd_dumpfile, buf, bufsz_write)
- != bufsz_write) {
- ERRMSG("Can't write the dump file(%s). %s\n",
- info->name_dumpfile, strerror(errno));
+ if (!write_cache(&cd_seg, buf, bufsz_write))
goto out;
- }
+
bufsz_remain -= page_size;
num_dumped++;
}
- if (info->flag_elf64) { /* ELF64 */
- off_hdr_load += sizeof(load64);
+ if (info->flag_elf64) /* ELF64 */
off_seg_load += load64.p_filesz;
- } else { /* ELF32 */
- off_hdr_load += sizeof(load32);
+ else /* ELF32 */
off_seg_load += load32.p_filesz;
- }
}
+ if (!write_cache_bufsz(&cd_hdr))
+ goto out;
+ if (!write_cache_bufsz(&cd_seg))
+ goto out;
+
print_progress(num_dumpable, num_dumpable);
ret = TRUE;
out:
@@ -3429,6 +3693,10 @@
free(buf);
if (bitmap2.buf != NULL)
free(bitmap2.buf);
+ if (cd_hdr.buf != NULL)
+ free(cd_hdr.buf);
+ if (cd_seg.buf != NULL)
+ free(cd_seg.buf);
return ret;
}
@@ -3680,7 +3948,7 @@
{
struct cache_data bm;
long buf_size;
- const off_t failed = (off_t)-1;
+ off_t offset;
int ret = FALSE;
@@ -3697,12 +3965,7 @@
strerror(errno));
goto out;
}
- if (lseek(info->fd_dumpfile, info->offset_bitmap1, SEEK_SET)
- == failed) {
- ERRMSG("Can't seek the dump file(%s). %s\n",
- info->name_dumpfile, strerror(errno));
- goto out;
- }
+ offset = info->offset_bitmap1;
buf_size = info->len_bitmap;
while (buf_size > 0) {
@@ -3714,12 +3977,11 @@
if(!read_cache(&bm))
goto out;
- if (write(info->fd_dumpfile, bm.buf, bm.cache_size)
- != bm.cache_size) {
- ERRMSG("Can't write the dump file(%s). %s\n",
- info->name_dumpfile, strerror(errno));
+ if (!write_buffer(info->fd_dumpfile, offset,
+ bm.buf, bm.cache_size, info->name_dumpfile))
goto out;
- }
+
+ offset += bm.cache_size;
buf_size -= BUFSIZE_BITMAP;
}
ret = TRUE;
@@ -3749,6 +4011,9 @@
void
close_dump_file(struct DumpInfo *info)
{
+ if (info->flag_flatten)
+ return;
+
if ((info->fd_dumpfile = close(info->fd_dumpfile)) < 0)
ERRMSG("Can't close the dump file(%s). %s\n",
info->name_dumpfile, strerror(errno));
@@ -3796,6 +4061,18 @@
}
/*
+ * Close the following file when it re-arranges the dump data.
+ * - dump file
+ */
+int
+close_files_for_rearranging_dumpdata(struct DumpInfo *info)
+{
+ close_dump_file(info);
+
+ return TRUE;
+}
+
+/*
* Close the following files when it creates the dump file.
* - dump mem
* - dump file
@@ -3844,7 +4121,8 @@
}
vt = &info->vm_table;
- while ((opt = getopt(argc, argv, "b:cDd:Eg:i:vx:")) != -1) {
+ info->block_order = DEFAULT_ORDER;
+ while ((opt = getopt(argc, argv, "b:cDd:EFg:i:Rvx:")) != -1) {
switch (opt) {
case 'b':
info->block_order = atoi(optarg);
@@ -3863,6 +4141,9 @@
case 'E':
info->flag_elf_dumpfile = 1;
break;
+ case 'F':
+ info->flag_flatten = 1;
+ break;
case 'g':
info->flag_generate_config = 1;
info->name_configfile = optarg;
@@ -3871,6 +4152,9 @@
info->flag_read_config = 1;
info->name_configfile = optarg;
break;
+ case 'R':
+ info->flag_rearrange = 1;
+ break;
case 'v':
info->flag_show_version = 1;
break;
@@ -3890,7 +4174,7 @@
}
if (info->flag_generate_config) {
/*
- * generate the configuration file
+ * Check parameters to generate the configuration file.
*/
if (argc != optind) {
ERRMSG("Commandline parameter is invalid.\n");
@@ -3899,14 +4183,15 @@
}
if (info->flag_compress || info->dump_level
|| info->flag_elf_dumpfile || info->flag_read_config
- || !info->flag_vmlinux) {
+ || !info->flag_vmlinux || info->flag_flatten
+ || info->flag_rearrange) {
ERRMSG("Commandline parameter is invalid.\n");
print_usage();
goto out;
}
- } else if (info->flag_read_config) {
+ } else {
/*
- * check parameters to read the configuration file
+ * Check parameters to create the dump file.
*/
if ((info->dump_level < MIN_DUMP_LEVEL)
|| (MAX_DUMP_LEVEL < info->dump_level)) {
@@ -3914,30 +4199,44 @@
print_usage();
goto out;
}
- if ((argc != optind + 2)
- || (info->flag_compress && info->flag_elf_dumpfile)
- || info->flag_vmlinux) {
+ if ((info->flag_compress && info->flag_elf_dumpfile)
+ || (info->flag_vmlinux && info->flag_read_config)) {
ERRMSG("Commandline parameter is invalid.\n");
print_usage();
goto out;
}
- info->name_memory = argv[optind];
- info->name_dumpfile = argv[optind+1];
- } else {
- if ((info->dump_level < MIN_DUMP_LEVEL)
- || (MAX_DUMP_LEVEL < info->dump_level)) {
- ERRMSG("Dump_level is invalid.\n");
- print_usage();
- goto out;
- }
- if ((argc != optind + 2)
- || (info->flag_compress && info->flag_elf_dumpfile)) {
+ if ((argc == optind + 2)
+ && !info->flag_flatten && !info->flag_rearrange) {
+ /*
+ * Parameters for creating the dumpfile from vmcore.
+ */
+ info->name_memory = argv[optind];
+ info->name_dumpfile = argv[optind+1];
+
+ } else if ((argc == optind + 1)
+ && info->flag_flatten && !info->flag_rearrange) {
+ /*
+ * Parameters for outputting the dump data of the
+ * flattened format to STDOUT.
+ */
+ info->name_memory = argv[optind];
+
+ } else if ((argc == optind + 1)
+ && !info->flag_flatten && info->flag_rearrange
+ && !info->dump_level && !info->flag_compress
+ && !info->flag_vmlinux && !info->flag_read_config
+ && !info->flag_elf_dumpfile) {
+ /*
+ * Parameters for creating dumpfile from the dump data
+ * of flattened format by re-arranging the dump data.
+ */
+ info->name_dumpfile = argv[optind];
+
+ } else {
ERRMSG("Commandline parameter is invalid.\n");
print_usage();
goto out;
}
- info->name_memory = argv[optind];
- info->name_dumpfile = argv[optind+1];
}
if (elf_version(EV_CURRENT) == EV_NONE ) {
@@ -3959,6 +4258,19 @@
MSG("\n");
MSG("The configfile is saved to %s.\n", info->name_configfile);
+
+ } else if (info->flag_rearrange) {
+ if (!open_files_for_rearranging_dumpdata(info))
+ goto out;
+
+ if (!rearrange_dumpdata(info))
+ goto out;
+
+ if (!close_files_for_rearranging_dumpdata(info))
+ goto out;
+
+ MSG("\n");
+ MSG("The dumpfile is saved to %s.\n", info->name_dumpfile);
} else {
if (!open_files_for_creating_dumpfile(info))
goto out;
@@ -3969,6 +4281,10 @@
if (!create_dump_bitmap(info))
goto out;
+ if (info->flag_flatten) {
+ if (!write_start_flat_header(info))
+ goto out;
+ }
if (info->flag_elf_dumpfile) {
if (!write_elf_header(info))
goto out;
@@ -3982,6 +4298,11 @@
if (!write_kdump_bitmap(info))
goto out;
}
+ if (info->flag_flatten) {
+ if (!write_end_flat_header(info))
+ goto out;
+ }
+
if (!close_files_for_creating_dumpfile(info))
goto out;
diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/makedumpfile/makedumpfile.h new/makedumpfile/makedumpfile.h
--- old/makedumpfile/makedumpfile.h 2007-01-18 21:26:57.000000000 +0100
+++ new/makedumpfile/makedumpfile.h 2007-02-02 10:20:09.000000000 +0100
@@ -28,6 +28,7 @@
#include