Whamcloud - gitweb
LU-9067 utils: ensure debugfs is mounted 82/25182/8
authorJames Simmons <uja.ornl@yahoo.com>
Fri, 17 Feb 2017 17:17:19 +0000 (12:17 -0500)
committerOleg Drokin <oleg.drokin@intel.com>
Wed, 1 Mar 2017 05:11:54 +0000 (05:11 +0000)
With the move of lustre to sysfs and tracepoint it
will become critical to have debugfs mounted. On
older platforms like RHEL6 its not mounted by default.
Also it is possible that debugfs could become umounted
by accident thus disabling needed functionality
to control lustre. Add to libcfs.a a function that
is always called to ensure debugfs is mounted.
If debugfs is not mounted then mount it if the caller
is root.

Change-Id: I21f85ba252b67bfbc22b23920e2ccaffc196074b
Signed-off-by: James Simmons <uja.ornl@yahoo.com>
Reviewed-on: https://review.whamcloud.com/25182
Reviewed-by: Bob Glossman <bob.glossman@intel.com>
Tested-by: Jenkins
Tested-by: Maloo <hpdd-maloo@intel.com>
Reviewed-by: Andreas Dilger <andreas.dilger@intel.com>
libcfs/libcfs/util/param.c
lustre/tests/conf-sanity.sh

index 15c7dbe..74a3726 100644 (file)
 #include <errno.h>
 #include <fcntl.h>
 #include <glob.h>
 #include <errno.h>
 #include <fcntl.h>
 #include <glob.h>
+#include <mntent.h>
+#include <paths.h>
 #include <stdarg.h>
 #include <stdarg.h>
+#include <stdbool.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <sys/mount.h>
+#include <sys/stat.h>
+#include <sys/types.h>
 #include <unistd.h>
 #include <linux/limits.h>
 #include <libcfs/util/string.h>
 #include <unistd.h>
 #include <linux/limits.h>
 #include <libcfs/util/string.h>
@@ -58,11 +64,52 @@ cfs_get_param_paths(glob_t *paths, const char *pattern, ...)
 {
        char path[PATH_MAX] = "{/sys/{fs,kernel/debug}/{lnet,lustre}/,"
                               "/proc/{fs,sys}/{lnet,lustre}/}";
 {
        char path[PATH_MAX] = "{/sys/{fs,kernel/debug}/{lnet,lustre}/,"
                               "/proc/{fs,sys}/{lnet,lustre}/}";
+       static bool test_mounted = false;
        size_t len = strlen(path);
        char buf[PATH_MAX];
        va_list args;
        int rc;
 
        size_t len = strlen(path);
        char buf[PATH_MAX];
        va_list args;
        int rc;
 
+       if (test_mounted)
+               goto skip_mounting;
+       test_mounted = true;
+
+       if (mount("none", "/sys/kernel/debug", "debugfs", 0, "") == -1) {
+               /* Already mounted or don't have permission to mount is okay */
+               if (errno != EPERM && errno != EBUSY)
+                       fprintf(stderr, "Warning: failed to mount debug: %s\n",
+                               strerror(errno));
+       } else {
+               struct stat mtab;
+
+               /* This is all for RHEL6 which is old school. Can be removed
+                * later when RHEL6 client support is dropped. */
+               rc = lstat(_PATH_MOUNTED, &mtab);
+               if (!rc && !S_ISLNK(mtab.st_mode)) {
+                       FILE *fp = setmntent(_PATH_MOUNTED, "r+");
+
+                       if (fp != NULL) {
+                               const struct mntent fs = {
+                                       .mnt_fsname     = "debugfs",
+                                       .mnt_dir        = "/sys/kernel/debug",
+                                       .mnt_type       = "debugfs",
+                                       .mnt_opts       = "rw,relatime",
+                               };
+
+                               rc = addmntent(fp, &fs);
+                               if (rc) {
+                                       fprintf(stderr,
+                                               "failed to add debugfs to %s: %s\n",
+                                               _PATH_MOUNTED, strerror(errno));
+                               }
+                               endmntent(fp);
+                       } else {
+                               fprintf(stderr, "could not open %s: %s\n",
+                                       _PATH_MOUNTED, strerror(errno));
+                       }
+               }
+       }
+skip_mounting:
        va_start(args, pattern);
        rc = vsnprintf(buf, sizeof(buf), pattern, args);
        va_end(args);
        va_start(args, pattern);
        rc = vsnprintf(buf, sizeof(buf), pattern, args);
        va_end(args);
index 037a782..7a031a2 100755 (executable)
@@ -522,6 +522,17 @@ test_5f() {
 }
 run_test 5f "mds down, cleanup after failed mount (bug 2712)"
 
 }
 run_test 5f "mds down, cleanup after failed mount (bug 2712)"
 
+test_5g() {
+       modprobe lustre
+       [ $(lustre_version_code client) -lt $(version_code 2.9.53) ] &&
+               { skip "automount of debugfs missing before 2.9.53" && return 0; }
+       umount /sys/kernel/debug
+       $LCTL get_param -n devices | egrep -v "error" && \
+               error "lctl can't access debugfs data"
+       grep " debugfs " /etc/mtab || error "debugfs failed to remount"
+}
+run_test 5g "handle missing debugfs"
+
 test_6() {
        setup
        manual_umount_client
 test_6() {
        setup
        manual_umount_client