2 * What: /sys/kernel/debug/orangefs/debug-help
4 * Contact: Mike Marshall <hubcap@omnibond.com>
6 * List of client and kernel debug keywords.
9 * What: /sys/kernel/debug/orangefs/client-debug
11 * Contact: Mike Marshall <hubcap@omnibond.com>
13 * Debug setting for "the client", the userspace
14 * helper for the kernel module.
17 * What: /sys/kernel/debug/orangefs/kernel-debug
19 * Contact: Mike Marshall <hubcap@omnibond.com>
21 * Debug setting for the orangefs kernel module.
23 * Any of the keywords, or comma-separated lists
24 * of keywords, from debug-help can be catted to
25 * client-debug or kernel-debug.
27 * "none", "all" and "verbose" are special keywords
28 * for client-debug. Setting client-debug to "all"
29 * is kind of like trying to drink water from a
30 * fire hose, "verbose" triggers most of the same
31 * output except for the constant flow of output
32 * from the main wait loop.
34 * "none" and "all" are similar settings for kernel-debug
35 * no need for a "verbose".
37 #include <linux/debugfs.h>
38 #include <linux/slab.h>
40 #include <linux/uaccess.h>
42 #include "orangefs-debugfs.h"
44 #include "orangefs-kernel.h"
46 static int orangefs_debug_disabled
= 1;
48 static int orangefs_debug_help_open(struct inode
*, struct file
*);
50 const struct file_operations debug_help_fops
= {
51 .open
= orangefs_debug_help_open
,
53 .release
= seq_release
,
57 static void *help_start(struct seq_file
*, loff_t
*);
58 static void *help_next(struct seq_file
*, void *, loff_t
*);
59 static void help_stop(struct seq_file
*, void *);
60 static int help_show(struct seq_file
*, void *);
62 static const struct seq_operations help_debug_ops
= {
70 * Used to protect data in ORANGEFS_KMOD_DEBUG_FILE and
71 * ORANGEFS_KMOD_DEBUG_FILE.
73 static DEFINE_MUTEX(orangefs_debug_lock
);
75 int orangefs_debug_open(struct inode
*, struct file
*);
77 static ssize_t
orangefs_debug_read(struct file
*,
82 static ssize_t
orangefs_debug_write(struct file
*,
87 static const struct file_operations kernel_debug_fops
= {
88 .open
= orangefs_debug_open
,
89 .read
= orangefs_debug_read
,
90 .write
= orangefs_debug_write
,
91 .llseek
= generic_file_llseek
,
95 * initialize kmod debug operations, create orangefs debugfs dir and
96 * ORANGEFS_KMOD_DEBUG_HELP_FILE.
98 int orangefs_debugfs_init(void)
103 debug_dir
= debugfs_create_dir("orangefs", NULL
);
105 pr_info("%s: debugfs_create_dir failed.\n", __func__
);
109 help_file_dentry
= debugfs_create_file(ORANGEFS_KMOD_DEBUG_HELP_FILE
,
114 if (!help_file_dentry
) {
115 pr_info("%s: debugfs_create_file failed.\n", __func__
);
119 orangefs_debug_disabled
= 0;
127 void orangefs_debugfs_cleanup(void)
129 debugfs_remove_recursive(debug_dir
);
132 /* open ORANGEFS_KMOD_DEBUG_HELP_FILE */
133 static int orangefs_debug_help_open(struct inode
*inode
, struct file
*file
)
138 gossip_debug(GOSSIP_DEBUGFS_DEBUG
,
139 "orangefs_debug_help_open: start\n");
141 if (orangefs_debug_disabled
)
144 ret
= seq_open(file
, &help_debug_ops
);
148 ((struct seq_file
*)(file
->private_data
))->private = inode
->i_private
;
153 gossip_debug(GOSSIP_DEBUGFS_DEBUG
,
154 "orangefs_debug_help_open: rc:%d:\n",
160 * I think start always gets called again after stop. Start
161 * needs to return NULL when it is done. The whole "payload"
162 * in this case is a single (long) string, so by the second
163 * time we get to start (pos = 1), we're done.
165 static void *help_start(struct seq_file
*m
, loff_t
*pos
)
167 void *payload
= NULL
;
169 gossip_debug(GOSSIP_DEBUGFS_DEBUG
, "help_start: start\n");
172 payload
= m
->private;
177 static void *help_next(struct seq_file
*m
, void *v
, loff_t
*pos
)
179 gossip_debug(GOSSIP_DEBUGFS_DEBUG
, "help_next: start\n");
184 static void help_stop(struct seq_file
*m
, void *p
)
186 gossip_debug(GOSSIP_DEBUGFS_DEBUG
, "help_stop: start\n");
189 static int help_show(struct seq_file
*m
, void *v
)
191 gossip_debug(GOSSIP_DEBUGFS_DEBUG
, "help_show: start\n");
199 * initialize the kernel-debug file.
201 int orangefs_kernel_debug_init(void)
205 char *k_buffer
= NULL
;
207 gossip_debug(GOSSIP_DEBUGFS_DEBUG
, "%s: start\n", __func__
);
209 k_buffer
= kzalloc(ORANGEFS_MAX_DEBUG_STRING_LEN
, GFP_KERNEL
);
213 if (strlen(kernel_debug_string
) + 1 < ORANGEFS_MAX_DEBUG_STRING_LEN
) {
214 strcpy(k_buffer
, kernel_debug_string
);
215 strcat(k_buffer
, "\n");
217 strcpy(k_buffer
, "none\n");
218 pr_info("%s: overflow 1!\n", __func__
);
221 ret
= debugfs_create_file(ORANGEFS_KMOD_DEBUG_FILE
,
227 pr_info("%s: failed to create %s.\n",
229 ORANGEFS_KMOD_DEBUG_FILE
);
237 gossip_debug(GOSSIP_DEBUGFS_DEBUG
, "%s: rc:%d:\n", __func__
, rc
);
242 * initialize the client-debug file.
244 int orangefs_client_debug_init(void)
248 char *c_buffer
= NULL
;
250 gossip_debug(GOSSIP_DEBUGFS_DEBUG
, "%s: start\n", __func__
);
252 c_buffer
= kzalloc(ORANGEFS_MAX_DEBUG_STRING_LEN
, GFP_KERNEL
);
256 if (strlen(client_debug_string
) + 1 < ORANGEFS_MAX_DEBUG_STRING_LEN
) {
257 strcpy(c_buffer
, client_debug_string
);
258 strcat(c_buffer
, "\n");
260 strcpy(c_buffer
, "none\n");
261 pr_info("%s: overflow! 2\n", __func__
);
264 client_debug_dentry
= debugfs_create_file(ORANGEFS_CLIENT_DEBUG_FILE
,
269 if (!client_debug_dentry
) {
270 pr_info("%s: failed to create updated %s.\n",
272 ORANGEFS_CLIENT_DEBUG_FILE
);
280 gossip_debug(GOSSIP_DEBUGFS_DEBUG
, "%s: rc:%d:\n", __func__
, rc
);
284 /* open ORANGEFS_KMOD_DEBUG_FILE or ORANGEFS_CLIENT_DEBUG_FILE.*/
285 int orangefs_debug_open(struct inode
*inode
, struct file
*file
)
289 gossip_debug(GOSSIP_DEBUGFS_DEBUG
,
290 "%s: orangefs_debug_disabled: %d\n",
292 orangefs_debug_disabled
);
294 if (orangefs_debug_disabled
)
298 mutex_lock(&orangefs_debug_lock
);
299 file
->private_data
= inode
->i_private
;
300 mutex_unlock(&orangefs_debug_lock
);
303 gossip_debug(GOSSIP_DEBUGFS_DEBUG
,
304 "orangefs_debug_open: rc: %d\n",
309 static ssize_t
orangefs_debug_read(struct file
*file
,
316 ssize_t read_ret
= -ENOMEM
;
318 gossip_debug(GOSSIP_DEBUGFS_DEBUG
, "orangefs_debug_read: start\n");
320 buf
= kmalloc(ORANGEFS_MAX_DEBUG_STRING_LEN
, GFP_KERNEL
);
324 mutex_lock(&orangefs_debug_lock
);
325 sprintf_ret
= sprintf(buf
, "%s", (char *)file
->private_data
);
326 mutex_unlock(&orangefs_debug_lock
);
328 read_ret
= simple_read_from_buffer(ubuf
, count
, ppos
, buf
, sprintf_ret
);
333 gossip_debug(GOSSIP_DEBUGFS_DEBUG
,
334 "orangefs_debug_read: ret: %zu\n",
340 static ssize_t
orangefs_debug_write(struct file
*file
,
341 const char __user
*ubuf
,
349 struct orangefs_kernel_op_s
*new_op
= NULL
;
350 struct client_debug_mask c_mask
= { NULL
, 0, 0 };
352 gossip_debug(GOSSIP_DEBUGFS_DEBUG
,
353 "orangefs_debug_write: %s\n",
354 file
->f_path
.dentry
->d_name
.name
);
357 * Thwart users who try to jamb a ridiculous number
358 * of bytes into the debug file...
360 if (count
> ORANGEFS_MAX_DEBUG_STRING_LEN
+ 1) {
362 count
= ORANGEFS_MAX_DEBUG_STRING_LEN
+ 1;
365 buf
= kzalloc(ORANGEFS_MAX_DEBUG_STRING_LEN
, GFP_KERNEL
);
369 if (copy_from_user(buf
, ubuf
, count
- 1)) {
370 gossip_debug(GOSSIP_DEBUGFS_DEBUG
,
371 "%s: copy_from_user failed!\n",
377 * Map the keyword string from userspace into a valid debug mask.
378 * The mapping process involves mapping the human-inputted string
379 * into a valid mask, and then rebuilding the string from the
380 * verified valid mask.
382 * A service operation is required to set a new client-side
385 if (!strcmp(file
->f_path
.dentry
->d_name
.name
,
386 ORANGEFS_KMOD_DEBUG_FILE
)) {
387 debug_string_to_mask(buf
, &gossip_debug_mask
, 0);
388 debug_mask_to_string(&gossip_debug_mask
, 0);
389 debug_string
= kernel_debug_string
;
390 gossip_debug(GOSSIP_DEBUGFS_DEBUG
,
391 "New kernel debug string is %s\n",
392 kernel_debug_string
);
394 /* Can't reset client debug mask if client is not running. */
395 if (is_daemon_in_service()) {
396 pr_info("%s: Client not running :%d:\n",
398 is_daemon_in_service());
402 debug_string_to_mask(buf
, &c_mask
, 1);
403 debug_mask_to_string(&c_mask
, 1);
404 debug_string
= client_debug_string
;
406 new_op
= op_alloc(ORANGEFS_VFS_OP_PARAM
);
408 pr_info("%s: op_alloc failed!\n", __func__
);
412 new_op
->upcall
.req
.param
.op
=
413 ORANGEFS_PARAM_REQUEST_OP_TWO_MASK_VALUES
;
414 new_op
->upcall
.req
.param
.type
= ORANGEFS_PARAM_REQUEST_SET
;
415 memset(new_op
->upcall
.req
.param
.s_value
,
417 ORANGEFS_MAX_DEBUG_STRING_LEN
);
418 sprintf(new_op
->upcall
.req
.param
.s_value
,
423 /* service_operation returns 0 on success... */
424 rc
= service_operation(new_op
,
426 ORANGEFS_OP_INTERRUPTIBLE
);
429 gossip_debug(GOSSIP_DEBUGFS_DEBUG
,
430 "%s: service_operation failed! rc:%d:\n",
437 mutex_lock(&orangefs_debug_lock
);
438 memset(file
->f_inode
->i_private
, 0, ORANGEFS_MAX_DEBUG_STRING_LEN
);
439 sprintf((char *)file
->f_inode
->i_private
, "%s\n", debug_string
);
440 mutex_unlock(&orangefs_debug_lock
);
449 gossip_debug(GOSSIP_DEBUGFS_DEBUG
,
450 "orangefs_debug_write: rc: %d\n",