[PATCH] makedumpfile: make --work-dir easier to use
Atsushi Kumagai
ats-kumagai at wm.jp.nec.com
Thu Sep 10 00:44:02 PDT 2015
>Hello Kumagai,
>
>On Wed, Sep 09, 2015 at 07:51:50AM +0000, Atsushi Kumagai wrote:
>> 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
>
>I have been looking at how this could be done.
>As each distro may mount the root filesystem differently, it would seem to me that
>the name must be passed to makedumpfile somehow. I don't see kexec having a role but
>the scripts that make the kdump initrd could.
>Am I missing your point in concluding that?
Let's say about RHEL, if *path* parameter in kdump.conf is /var/crash,
mkdumprd can pass it to --work-dir. Since that path can store vmcore,
it must store also bitmaps and makedumpfilepfns.
>One could add another option to makedumpfile (maybe --root=<path>). And then the distro's
>scripts could add that option to the makedumpfile command line. But that turns out to be
>difficult to do in SLES, as it has its own binary named 'kdumptool' that invokes
>makedumpfile and it does not have a way to pass an option to makedumpfile
>that is derived at mkdumprd time. It only passes along options that have been stored
>in /etc/sysconfig/kdump.
>
>Deriving the root path from the dump name is not very reliable if it depends on a
>convention that could change.
>What is configured in the kdump or kdump.conf file is the "/var/crash" or similar dump
>file directory.
>I propose to add a --dump-dir option to makedumpfile. The distro script can easily
>add --dump-dir=/var/crash to the command line, and then the path to root can be
>accurately derived. If --dump-dir is not specified then --work-dir would have to
>be pre-adjusted, as it is currently.
Why don't you think --work-dir=/var/crash, it's simple.
Thanks,
Atsushi Kumagai
>-Cliff
>>
>> >---
>> > 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");
>
>--
>Cliff Wickman
>SGI
>cpw at sgi.com
>(651)683-7524 vnet 207524
>(651)482-9347 home
>
>_______________________________________________
>kexec mailing list
>kexec at lists.infradead.org
>http://lists.infradead.org/mailman/listinfo/kexec
More information about the kexec
mailing list