Whamcloud - gitweb
LU-12349 llite: console message for disabled flock call 86/34986/13
authorLi Xi <lixi@ddn.com>
Thu, 13 Jun 2019 03:27:50 +0000 (11:27 +0800)
committerOleg Drokin <green@whamcloud.com>
Fri, 28 Jun 2019 00:01:39 +0000 (00:01 +0000)
When flock option is disabled on a Lustre client, any call to
flock() or lockf() would cause a return value with failure.
For applications that don't print proper error message, it is
hard to know the root cause is the missing flock option on Lustre
file system. Thus this patch prints following error message to
the tty that calls flock()/lockf():

"Lustre: flock disabled, mount with '-o [local]flock' to enable"

Such message will print to each file descriptor no more than
once to avoid message flood.

In order to do so, this patch adds support for CDEBUG_LIMIT(D_TTY).
It prints the message to tty. When using this macro, please
note that "\r\n" needs to be the end of the line. Otherwise,
message like "format at $FILE:$LINO:$FUNC doesn't end in '\r\n'"
will be printed to the system message for warning.

Change-Id: I4eeb3ea219848ebbbca9d14e3d2b8a23237105b5
Signed-off-by: Li Xi <lixi@ddn.com>
Reviewed-on: https://review.whamcloud.com/34986
Tested-by: Jenkins
Reviewed-by: Andreas Dilger <adilger@whamcloud.com>
Tested-by: Maloo <maloo@whamcloud.com>
Reviewed-by: Yingjin Qian <qian@ddn.com>
Reviewed-by: Oleg Drokin <green@whamcloud.com>
libcfs/libcfs/debug.c
libcfs/libcfs/linux/linux-tracefile.c
libcfs/libcfs/tracefile.c
lnet/include/uapi/linux/lnet/libcfs_debug.h
lustre/include/uapi/linux/lustre/lustre_user.h
lustre/llite/file.c
lustre/osd-ldiskfs/osd_io.c
lustre/utils/llanalyze

index 3a0c289..b059791 100644 (file)
@@ -49,8 +49,8 @@ module_param(libcfs_subsystem_debug, int, 0644);
 MODULE_PARM_DESC(libcfs_subsystem_debug, "Lustre kernel debug subsystem mask");
 EXPORT_SYMBOL(libcfs_subsystem_debug);
 
-unsigned int libcfs_debug = (D_CANTMASK |
-                            D_NETERROR | D_HA | D_CONFIG | D_IOCTL | D_LFSCK);
+unsigned int libcfs_debug = (D_CANTMASK | D_NETERROR | D_HA | D_CONFIG |
+                            D_IOCTL | D_LFSCK | D_TTY);
 module_param(libcfs_debug, int, 0644);
 MODULE_PARM_DESC(libcfs_debug, "Lustre kernel debug mask");
 EXPORT_SYMBOL(libcfs_debug);
index 54f1121..bb776a7 100644 (file)
@@ -34,6 +34,8 @@
 #define LUSTRE_TRACEFILE_PRIVATE
 
 #include <linux/slab.h>
+#include <linux/tty.h>
+#include <linux/poll.h>
 #include <libcfs/libcfs.h>
 #include "tracefile.h"
 
@@ -235,6 +237,39 @@ dbghdr_to_info_string(struct ptldebug_header *hdr)
         }
 }
 
+/**
+ * tty_write_msg - write a message to a certain tty, not just the console.
+ * @tty: the destination tty_struct
+ * @msg: the message to write
+ *
+ * tty_write_message is not exported, so write a same function for it
+ *
+ */
+static void tty_write_msg(struct tty_struct *tty, const char *msg)
+{
+       mutex_lock(&tty->atomic_write_lock);
+       tty_lock(tty);
+       if (tty->ops->write && tty->count > 0)
+               tty->ops->write(tty, msg, strlen(msg));
+       tty_unlock(tty);
+       mutex_unlock(&tty->atomic_write_lock);
+       wake_up_interruptible_poll(&tty->write_wait, POLLOUT);
+}
+
+static void cfs_tty_write_message(const char *prefix, const char *msg)
+{
+       struct tty_struct *tty;
+
+       tty = get_current_tty();
+       if (!tty)
+               return;
+
+       tty_write_msg(tty, prefix);
+       tty_write_msg(tty, ": ");
+       tty_write_msg(tty, msg);
+       tty_kref_put(tty);
+}
+
 void cfs_print_to_console(struct ptldebug_header *hdr, int mask,
                           const char *buf, int len, const char *file,
                           const char *fn)
@@ -255,6 +290,9 @@ void cfs_print_to_console(struct ptldebug_header *hdr, int mask,
                ptype = KERN_INFO;
        }
 
+       if ((mask & D_TTY) != 0)
+               cfs_tty_write_message(prefix, buf);
+
        if ((mask & D_CONSOLE) != 0) {
                printk("%s%s: %.*s", ptype, prefix, len, buf);
        } else {
index f9d96d1..81e9fb2 100644 (file)
@@ -358,9 +358,16 @@ int libcfs_debug_vmsg2(struct libcfs_debug_msg_data *msgdata,
                         break;
         }
 
-       if (*(string_buf+needed-1) != '\n')
+       if (*(string_buf + needed - 1) != '\n') {
                printk(KERN_INFO "format at %s:%d:%s doesn't end in "
                       "newline\n", file, msgdata->msg_line, msgdata->msg_fn);
+       } else if (mask & D_TTY) {
+               /* TTY needs '\r\n' to move carriage to leftmost position */
+               if (needed < 2 || *(string_buf + needed - 2) != '\r')
+                       printk(KERN_INFO "format at %s:%d:%s doesn't end in "
+                              "'\\r\\n'\n", file, msgdata->msg_line,
+                              msgdata->msg_fn);
+       }
 
         header.ph_len = known_size + needed;
        debug_buf = (char *)page_address(tage->page) + tage->used;
@@ -461,8 +468,9 @@ console:
                                   cdls->cdls_count,
                                   (cdls->cdls_count > 1) ? "s" : "");
 
-                cfs_print_to_console(&header, mask,
-                                     string_buf, needed, file, msgdata->msg_fn);
+               /* Do not allow print this to TTY */
+               cfs_print_to_console(&header, mask & ~D_TTY, string_buf,
+                                    needed, file, msgdata->msg_fn);
 
                put_cpu();
                 cdls->cdls_count = 0;
index 2672fe7..03a008f 100644 (file)
@@ -106,7 +106,7 @@ struct ptldebug_header {
 #define D_TRACE         0x00000001 /* ENTRY/EXIT markers */
 #define D_INODE         0x00000002
 #define D_SUPER         0x00000004
-#define D_EXT2          0x00000008 /* anything from ext2_debug */
+#define D_TTY           0x00000008 /* notification printed to TTY */
 #define D_MALLOC        0x00000010 /* print malloc, free information */
 #define D_CACHE         0x00000020 /* cache-related items */
 #define D_INFO          0x00000040 /* general information */
@@ -137,7 +137,7 @@ struct ptldebug_header {
 #define D_LAYOUT        0x80000000
 
 #define LIBCFS_DEBUG_MASKS_NAMES {                                     \
-       "trace", "inode", "super", "ext2", "malloc", "cache", "info",   \
+       "trace", "inode", "super", "tty", "malloc", "cache", "info",    \
        "ioctl", "neterror", "net", "warning", "buffs", "other",        \
        "dentry", "nettrace", "page", "dlmtrace", "error", "emerg",     \
        "ha", "rpctrace", "vfstrace", "reada", "mmap", "config",        \
index 7d321f8..66c8fd1 100644 (file)
@@ -538,6 +538,7 @@ struct fsxattr {
 #define LL_FILE_READAHEA        0x00000004
 #define LL_FILE_LOCKED_DIRECTIO 0x00000008 /* client-side locks with dio */
 #define LL_FILE_LOCKLESS_IO     0x00000010 /* server-side locks with cio */
+#define LL_FILE_FLOCK_WARNING   0x00000020 /* warned about disabled flock */
 
 #define LOV_USER_MAGIC_V1      0x0BD10BD0
 #define LOV_USER_MAGIC         LOV_USER_MAGIC_V1
index d9627af..6bbe995 100644 (file)
@@ -4503,9 +4503,20 @@ out_iput:
 static int
 ll_file_noflock(struct file *file, int cmd, struct file_lock *file_lock)
 {
-        ENTRY;
+       struct ll_file_data *fd = LUSTRE_FPRIVATE(file);
+       ENTRY;
 
-        RETURN(-ENOSYS);
+       /*
+        * In order to avoid flood of warning messages, only print one message
+        * for one file. And the entire message rate on the client is limited
+        * by CDEBUG_LIMIT too.
+        */
+       if (!(fd->fd_flags & LL_FILE_FLOCK_WARNING)) {
+               fd->fd_flags |= LL_FILE_FLOCK_WARNING;
+               CDEBUG_LIMIT(D_TTY | D_CONSOLE,
+                            "flock disabled, mount with '-o [local]flock' to enable\r\n");
+       }
+       RETURN(-ENOSYS);
 }
 
 /**
index 0212e1c..72cb3d0 100644 (file)
@@ -1732,7 +1732,8 @@ int osd_ldiskfs_read(struct inode *inode, void *buf, int size, loff_t *offs)
                loff_t diff = i_size_read(inode) - *offs;
                spin_unlock(&inode->i_lock);
                if (diff < 0) {
-                       CDEBUG(D_EXT2, "size %llu is too short to read @%llu\n",
+                       CDEBUG(D_OTHER,
+                              "size %llu is too short to read @%llu\n",
                               i_size_read(inode), *offs);
                        return -EBADR;
                } else if (diff == 0) {
index 0b5eb88..bb78a6b 100644 (file)
@@ -53,7 +53,7 @@ $subsys->{FLD} = 1 << 31;  #/* b_new_cmd */
 $masks->{TRACE} = 1 << 0; # /* ENTRY/EXIT markers */
 $masks->{INODE} = 1 << 1; #
 $masks->{SUPER} = 1 << 2; #
-$masks->{EXT2} = 1 << 3; # /* anything from ext2_debug */
+$masks->{TTY} = 1 << 3; # /* notification printed to TTY */
 $masks->{MALLOC} = 1 << 4; # /* print malloc, free information */
 $masks->{CACHE} = 1 << 5; # /* cache-related items */
 $masks->{INFO} = 1 << 6; # /* general information */