1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
|
#include <linux/debugfs.h>
#include <linux/module.h>
#include <driver/swap_debugfs.h>
#include <us_manager/sspt/sspt_proc.h>
#include "debugfs_us_manager.h"
#define MAX_APPS_COUNT 8 /* According to daemon defenitions */
#define PID_STRING 21 /* Maximum pid string = 20 (max digits count in
* unsigned int on 64-bit arch) + 1 (for \n) */
/* ============================================================================
* = FOPS_TASKS =
* ============================================================================
*/
struct read_buf {
char *begin;
char *ptr;
char *end;
};
static void on_each_proc_callback(struct sspt_proc *proc, void *data)
{
struct read_buf *rbuf = (struct read_buf *)data;
char pid_str[PID_STRING];
int len;
sprintf(pid_str, "%d", proc->tgid);
len = strlen(pid_str);
if (rbuf->end - rbuf->ptr < len + 2)
return;
memcpy(rbuf->ptr, pid_str, len);
rbuf->ptr += len;
*rbuf->ptr = ' ';
++rbuf->ptr;
}
static ssize_t read_tasks(struct file *file, char __user *user_buf,
size_t count, loff_t *ppos)
{
char buf[PID_STRING * MAX_APPS_COUNT];
struct read_buf rbuf = {
.begin = buf,
.ptr = buf,
.end = buf + sizeof(buf)
};
on_each_proc_no_lock(on_each_proc_callback, (void *)&rbuf);
if (rbuf.ptr != rbuf.begin)
rbuf.ptr--;
*rbuf.ptr = '\n';
return simple_read_from_buffer(user_buf, count, ppos, rbuf.begin,
rbuf.ptr - rbuf.begin);
}
static const struct file_operations fops_tasks = {
.owner = THIS_MODULE,
.read = read_tasks,
.llseek = default_llseek
};
/* ============================================================================
* = INIT/EXIT =
* ============================================================================
*/
static struct dentry *us_manager_dir = NULL;
/**
* @brief Destroy debugfs for us_manager
*
* @return Void
*/
void exit_debugfs_us_manager(void)
{
if (us_manager_dir)
debugfs_remove_recursive(us_manager_dir);
us_manager_dir = NULL;
}
/**
* @brief Create debugfs for us_manager
*
* @return Error code
*/
int init_debugfs_us_manager(void)
{
struct dentry *swap_dir, *dentry;
swap_dir = get_swap_debugfs_dir();
if (swap_dir == NULL)
return -ENOENT;
us_manager_dir = debugfs_create_dir(US_MANAGER_DFS_DIR, swap_dir);
if (us_manager_dir == NULL)
return -ENOMEM;
dentry = debugfs_create_file(US_MANAGER_TASKS, 0600, us_manager_dir, NULL,
&fops_tasks);
if (dentry == NULL)
goto fail;
return 0;
fail:
exit_debugfs_us_manager();
return -ENOMEM;
}
|