[REFACTOR] Buffer: move getting next queue element into separate function
[kernel/swap-modules.git] / parser / us_inst.c
1 /*
2  *  SWAP Parser
3  *  modules/parser/us_inst.c
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18  *
19  * Copyright (C) Samsung Electronics, 2013
20  *
21  * 2013  Vyacheslav Cherkashin: SWAP Parser implement
22  *
23  */
24
25
26 #include <linux/module.h>
27 #include <linux/version.h>
28 #include <linux/errno.h>
29 #include <linux/namei.h>
30 #include <us_manager/pf/pf_group.h>
31 #include "msg_parser.h"
32 #include "us_inst.h"
33
34 /* FIXME: create get_dentry() and put_dentry() */
35 static struct dentry *dentry_by_path(const char *path)
36 {
37         struct dentry *dentry;
38 #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 38)
39         struct path st_path;
40         if (kern_path(path, LOOKUP_FOLLOW, &st_path) != 0) {
41 #else /* LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 38) */
42         struct nameidata nd;
43         if (path_lookup(path, LOOKUP_FOLLOW, &nd) != 0) {
44 #endif /* LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 38) */
45                 printk("failed to lookup dentry for path %s!\n", path);
46                 return NULL;
47         }
48
49 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 25)
50         dentry = nd.dentry;
51         path_release(&nd);
52 #elif LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 38)
53         dentry = nd.path.dentry;
54         path_put(&nd.path);
55 #else /* LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 38) */
56         dentry = st_path.dentry;
57         path_put(&st_path);
58 #endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 25) */
59         return dentry;
60 }
61
62
63 static int mod_func_inst(struct func_inst_data *func, struct pf_group *pfg,
64                          struct dentry *dentry, enum MOD_TYPE mt)
65 {
66         int ret;
67
68         switch (mt) {
69         case MT_ADD:
70                 ret = pf_register_probe(pfg, dentry, func->addr, func->args,
71                                         func->ret_type);
72                 break;
73         case MT_DEL:
74                 ret = pf_unregister_probe(pfg, dentry, func->addr);
75                 break;
76         default:
77                 printk("ERROR: mod_type=0x%x\n", mt);
78                 ret = -EINVAL;
79         }
80
81         return ret;
82 }
83
84 static int mod_lib_inst(struct lib_inst_data *lib, struct pf_group *pfg,
85                         enum MOD_TYPE mt)
86 {
87         int ret = 0, i;
88         struct dentry *dentry;
89
90         dentry = dentry_by_path(lib->path);
91         if (dentry == NULL) {
92                 printk("Cannot get dentry by path %s\n", lib->path);
93                 return -EINVAL;
94         }
95
96         for (i = 0; i < lib->cnt_func; ++i) {
97                 ret = mod_func_inst(lib->func[i], pfg, dentry, mt);
98                 if (ret) {
99                         printk("Cannot mod func inst, ret = %d\n", ret);
100                         return ret;
101                 }
102         }
103
104         return ret;
105 }
106
107 static int get_pfg_by_app_info(struct app_info_data *app_info, struct pf_group **pfg)
108 {
109         struct dentry *dentry;
110
111         dentry = dentry_by_path(app_info->exec_path);
112         if (dentry == NULL)
113                 return -EINVAL;
114
115         switch (app_info->app_type) {
116         case AT_PID:
117                 *pfg = get_pf_group_by_tgid(app_info->tgid, dentry);
118                 break;
119         case AT_TIZEN_NATIVE_APP:
120         case AT_COMMON_EXEC:
121                 *pfg = get_pf_group_by_dentry(dentry, dentry);
122                 break;
123         default:
124                 printk("ERROR: app_type=0x%x\n", app_info->app_type);
125                 return -EINVAL;
126         }
127
128         return 0;
129 }
130
131 static int mod_us_app_inst(struct app_inst_data *app_inst, enum MOD_TYPE mt)
132 {
133         int ret, i;
134         struct pf_group *pfg;
135         struct dentry *dentry;
136
137         ret = get_pfg_by_app_info(app_inst->app_info, &pfg);
138         if (ret) {
139                 printk("Cannot get pfg by app info, ret = %d\n", ret);
140                 return ret;
141         }
142
143         for (i = 0; i < app_inst->cnt_func; ++i) {
144                 /* TODO: */
145                 dentry = dentry_by_path(app_inst->app_info->exec_path);
146                 if (dentry == NULL) {
147                         printk("Cannot find dentry by path %s\n",
148                                app_inst->app_info->exec_path);
149                         return -EINVAL;
150                 }
151
152                 ret = mod_func_inst(app_inst->func[i], pfg, dentry, mt);
153                 if (ret) {
154                         printk("Cannot mod func inst, ret = %d\n", ret);
155                         return ret;
156                 }
157         }
158
159         for (i = 0; i < app_inst->cnt_lib; ++i) {
160                 ret = mod_lib_inst(app_inst->lib[i], pfg, mt);
161                 if (ret) {
162                         printk("Cannot mod lib inst, ret = %d\n", ret);
163                         return ret;
164                 }
165         }
166
167         return 0;
168 }
169
170 int mod_us_inst(struct us_inst_data *us_inst, enum MOD_TYPE mt)
171 {
172         u32 i;
173         int ret;
174
175         for (i = 0; i < us_inst->cnt; ++i) {
176                 ret = mod_us_app_inst(us_inst->app_inst[i], mt);
177                 if (ret) {
178                         printk("Cannot mod us app inst, ret = %d\n", ret);
179                         return ret;
180                 }
181         }
182
183         return 0;
184 }