[PATCH] makedumpfile: make --work-dir easier to use
Atsushi Kumagai
ats-kumagai at wm.jp.nec.com
Wed Sep 9 00:51:50 PDT 2015
Hello Cliff,
>From: Cliff Wickman <cpw at sgi.com>
>
>This patch enhances the --work-dir feature to make it easier to use.
>
>Kumagai, I plan to require the --work-dir for the -e feature, as you suggested. I did find --work-dir
>hard to implement because of the differences between the way the various distros mount the root device
>in the crashkernel. Hence this patch.
>
>Currently the --work-dir=<PATH> must be specified in a form that is valid in the crashkernel's environment.
>In other words, the boot kernel's /var, for example, must be specified as:
> RHEL6: /mnt/var/
> RHEL7: /sysroot/var/
> SLES11: /kdump/0/var/
> SLES12: (with root=kdump) /kdump/mnt0/var/
>And the administrator must remember to create that directory.
>
>If these conditions are not met makedumpfile fails, with little explanation as to why.
>
>This patch:
>
>- Allow the path to be one that is valid in the crashkernel's environment, or allow
> it to be valid in the boot kernel's environment. In the second case, adjust the path to
> how the root device is mounted in the crashkernel.
> Limitation: The adjustment is only made if a dump file is being written, and the dump is
> being written to /var/crash/. Otherwise you must (as currently) use a path that is known
> to be valid in the crashkernel's environment.
>
>- Make the directory if it does not already exist. All components of the path are
> made if necessary, similar to mkdir -p.
I think such adjusting should be done in kdump feature side (e.g. kexec-tools) since
it constructs the crash kernel's environment. Each distro's kdump feature can
take care of each own environment.
Just checking by is_dir() and creating a directory are enough in makedumpfile side.
Thanks,
Atsushi Kumagai
>---
> makedumpfile.c | 144 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> makedumpfile.h | 3 -
> print_info.c | 15 ++++-
> 3 files changed, 158 insertions(+), 4 deletions(-)
>
>Index: code/makedumpfile.c
>===================================================================
>--- code.orig/makedumpfile.c
>+++ code/makedumpfile.c
>@@ -25,6 +25,7 @@
> #include <sys/time.h>
> #include <limits.h>
> #include <assert.h>
>+#include <sys/stat.h>
>
> struct symbol_table symbol_table;
> struct size_table size_table;
>@@ -10364,6 +10365,146 @@ int show_mem_usage(void)
> return TRUE;
> }
>
>+/*
>+ * return 1 if path is a directory
>+ * else return 0
>+ */
>+int
>+isdir(char *path)
>+{
>+ struct stat buf;
>+
>+ if (path) {
>+ if (stat(path, &buf) || !S_ISDIR(buf.st_mode)) {
>+ return 0;
>+ }
>+ return 1;
>+ } else {
>+ return 0;
>+ }
>+}
>+
>+/*
>+ * Set info->root_dir to the crashkernel's path to the bootkernel's root
>+ * or set it to null if that path cannot be determined.
>+ * We must assume that the dump file is in the bootkernel's /var/crash/
>+ */
>+void
>+set_rootdir()
>+{
>+ int len;
>+ char *cp1, *cp2;
>+
>+ /* allow this function to be called multiple times */
>+ if (info->root_dir)
>+ return;
>+
>+ if (!info->name_dumpfile) {
>+ info->root_dir = NULL;
>+ return;
>+ }
>+
>+ len = (int)strlen(info->name_dumpfile);
>+ if (len == 0) {
>+ info->root_dir = NULL;
>+ return;
>+ }
>+ info->root_dir = malloc(len);
>+ cp1 = info->name_dumpfile;
>+ cp2 = cp1;
>+ while (*cp2 != '\0') {
>+ if (!strncmp(cp2, "/var/crash/", 11)) {
>+ len = cp2 - cp1;
>+ strncpy(info->root_dir, cp1, len);
>+ if (!isdir(info->root_dir)) {
>+ fprintf(stderr, "Error: root directory %s does not exist\n",
>+ info->root_dir);
>+ exit(1);
>+ }
>+ return;
>+ }
>+ cp2++;
>+ }
>+ info->root_dir = NULL;
>+ return;
>+}
>+
>+/*
>+ * The --work-dir directory should be validated and created if necessary.
>+ */
>+void
>+adjust_working_dir()
>+{
>+ int ret, finished=0;
>+ char *hold, *inter_dir = NULL, *cp1, *cp2;
>+
>+ /* if a crashkernel root environment was specified, no adjust is necessary */
>+ if (isdir(info->working_dir))
>+ return;
>+
>+ set_rootdir();
>+
>+ if (!strncmp(info->working_dir, "/", 1)) {
>+ /* an absolute path should either exist in the crashkernel's
>+ root, or should be adjusted to be relative to it */
>+ if (info->root_dir) {
>+ hold = malloc(strlen(info->working_dir)+1);
>+ strcpy(hold, info->working_dir);
>+ info->working_dir = malloc(strlen(info->root_dir) + strlen(info->working_dir));
>+ inter_dir = malloc(strlen(info->root_dir) + strlen(info->working_dir));
>+ strcpy(info->working_dir, info->root_dir);
>+ strcat(info->working_dir, hold);
>+ free (hold);
>+ fprintf(stderr, "--workdir set to %s\n", info->working_dir);
>+ } else {
>+ inter_dir = malloc(strlen(info->working_dir));
>+ }
>+ } else {
>+ /* a relative path that does not already exist should be made absolute; it is taken to
>+ be relative to the crash kernel's root */
>+ if (info->root_dir) {
>+ hold = malloc(strlen(info->working_dir)+1);
>+ strcpy(hold, info->working_dir);
>+ info->working_dir = malloc(strlen(info->root_dir) + strlen(info->working_dir) + 1);
>+ inter_dir = malloc(strlen(info->root_dir) + strlen(info->working_dir) + 1);
>+ strcpy(info->working_dir, info->root_dir);
>+ strcat(info->working_dir, "/");
>+ strcat(info->working_dir, hold);
>+ free (hold);
>+ fprintf(stderr, "--workdir set to %s\n", info->working_dir);
>+ } else {
>+ inter_dir = malloc(strlen(info->working_dir));
>+ }
>+ }
>+
>+ /* path is complete, now make sure it exists */
>+ if (!isdir(info->working_dir)) {
>+ strcpy(inter_dir, info->working_dir);
>+ if (info->root_dir)
>+ cp1 = inter_dir + strlen(info->root_dir) + 1;
>+ else
>+ cp1 = inter_dir + 1;
>+ while (finished == 0) {
>+ strcpy(inter_dir, info->working_dir);
>+ cp2 = strchr(cp1, '/');
>+ if (cp2) {
>+ *cp2 = '\0';
>+ cp1 = cp2 + 1;
>+ } else {
>+ finished = 1;
>+ }
>+ if (!isdir(inter_dir)) {
>+ ret = mkdir(inter_dir, 0755);
>+ if (ret) {
>+ fprintf(stderr, "Error: mkdir(%s, 0755) returned %d\n",
>+ inter_dir, ret);
>+ exit(1);
>+ }
>+ }
>+ }
>+ }
>+ return;
>+}
>
> static struct option longopts[] = {
> {"split", no_argument, NULL, OPT_SPLIT},
>@@ -10549,6 +10690,9 @@ main(int argc, char *argv[])
> return COMPLETED;
> }
>
>+ if (info->working_dir)
>+ adjust_working_dir();
>+
> if (elf_version(EV_CURRENT) == EV_NONE ) {
> /*
> * library out of date
>Index: code/makedumpfile.h
>===================================================================
>--- code.orig/makedumpfile.h
>+++ code/makedumpfile.h
>@@ -1258,7 +1258,8 @@ struct DumpInfo {
> /*
> * for cyclic processing
> */
>- char *working_dir; /* working directory for bitmap */
>+ char *working_dir; /* working directory for bitmap */
>+ char *root_dir; /* crashkernel path to boot kernel's root */
> mdf_pfn_t num_dumpable;
> unsigned long bufsize_cyclic;
> unsigned long pfn_cyclic;
>Index: code/print_info.c
>===================================================================
>--- code.orig/print_info.c
>+++ code/print_info.c
>@@ -221,11 +221,20 @@ print_usage(void)
> MSG(" size is at most N kilo bytes.\n");
> MSG("\n");
> MSG(" [--work-dir]:\n");
>- MSG(" Specify the working directory for the temporary bitmap file.\n");
>- MSG(" If this option isn't specified, the bitmap will be saved on memory.\n");
>+ MSG(" Specify the working directory for temporary files such as the bitmap.\n");
>+ MSG(" If this option isn't specified, the bitmap will be saved in memory.\n");
> MSG(" Filtering processing has to do 2 pass scanning to fix the memory consumption,\n");
>- MSG(" but it can be avoided by using working directory on file system.\n");
>+ MSG(" but it can be avoided by using this working directory on the file system.\n");
> MSG(" So if you specify this option, the filtering speed may be bit faster.\n");
>+ MSG(" The directory path may be absolute or relative.\n");
>+ MSG(" If relative, it is taken to be based at the root filesystem.\n");
>+ MSG(" It may be an existing directory expressed with the path to the root filesystem as\n");
>+ MSG(" it is mounted in the crashkernel.\n");
>+ MSG(" Or it may expressed with '/' as the path to the root filesystem. In that case it will\n");
>+ MSG(" be automatically adjusted to be relative to the root of the crashkernel.\n");
>+ MSG(" The root of the crashkernel is determined from the dump name, if present. An assumption\n");
>+ MSG(" is made that the dump file is to be written to /var/crash/.\n");
>+ MSG(" If the directory does not exist it will be created, including multiple components.\n");
> MSG("\n");
> MSG(" [--non-mmap]:\n");
> MSG(" Never use mmap(2) to read VMCORE even if it supports mmap(2).\n");
More information about the kexec
mailing list