[FEATURE] MSG_PROCESS_STATUS_INFO implement 22/39422/3
authorVyacheslav Cherkashin <v.cherkashin@samsung.com>
Thu, 14 May 2015 18:47:24 +0000 (21:47 +0300)
committerDmitry Kovalenko <d.kovalenko@samsung.com>
Fri, 15 May 2015 11:12:24 +0000 (04:12 -0700)
Change-Id: I3c2d5b585dba5b9e7204d54e43d86d6cf7609b6c
Signed-off-by: Vyacheslav Cherkashin <v.cherkashin@samsung.com>
us_manager/pf/pf_group.c
us_manager/us_manager.c
us_manager/usm_msg.c
us_manager/usm_msg.h
writer/swap_msg.h

index c19242c..86d44cc 100644 (file)
@@ -191,6 +191,7 @@ static void first_install(struct task_struct *task, struct sspt_proc *proc,
 
        down_write(&task->mm->mmap_sem);
        usm_msg_info(task, dentry);
+       usm_msg_status_info(task);
        sspt_proc_install(proc);
        up_write(&task->mm->mmap_sem);
 }
index 57f3c26..b19cbc6 100644 (file)
@@ -28,6 +28,7 @@
 #include "sspt/sspt_proc.h"
 #include "helper.h"
 #include "us_manager.h"
+#include "usm_msg.h"
 #include "debugfs_us_manager.h"
 #include <writer/event_filter.h>
 #include <master/swap_initializer.h>
@@ -205,6 +206,17 @@ static void exit_us_filter(void)
 
 
 
+static int usm_once(void)
+{
+       int ret;
+
+       ret = once_helper();
+       if (ret)
+               return ret;
+
+       return usm_msg_once();
+}
+
 static int init_us_manager(void)
 {
        int ret;
@@ -222,7 +234,7 @@ static void exit_us_manager(void)
        exit_us_filter();
 }
 
-SWAP_LIGHT_INIT_MODULE(once_helper, init_us_manager, exit_us_manager,
+SWAP_LIGHT_INIT_MODULE(usm_once, init_us_manager, exit_us_manager,
                       init_debugfs_us_manager, exit_debugfs_us_manager);
 
 MODULE_LICENSE("GPL");
index a81c0ec..eef244b 100644 (file)
 
 
 #include <linux/fs.h>
+#include <linux/stat.h>
 #include <linux/sched.h>
 #include <linux/dcache.h>
-
+#include <linux/fdtable.h>
 #include <writer/swap_msg.h>
 #include <us_manager/sspt/sspt.h>      /* ... check_vma() */
 
 #define USM_PREFIX      KERN_INFO "[USM] "
 
 
+static struct files_struct *(*swap_get_files_struct)(struct task_struct *);
+static void (*swap_put_files_struct)(struct files_struct *fs);
+
+int usm_msg_once(void)
+{
+       const char *sym;
+
+       sym = "get_files_struct";
+       swap_get_files_struct = (void *)swap_ksyms(sym);
+       if (swap_get_files_struct == NULL)
+               goto not_found;
+
+       sym = "put_files_struct";
+       swap_put_files_struct = (void *)swap_ksyms(sym);
+       if (swap_put_files_struct == NULL)
+               goto not_found;
+
+       return 0;
+
+not_found:
+       printk("ERROR: symbol '%s' not found\n", sym);
+       return -ESRCH;
+}
+
+
+
+
+
 struct kmem_info {
        const char *name;
        unsigned long start;
@@ -461,3 +490,122 @@ void usm_msg_comm(struct task_struct *task)
        swap_msg_flush(m, sizeof(*c) + strlen(c->comm) + 1);
        swap_msg_put(m);
 }
+
+
+
+
+
+/* ============================================================================
+ * =                          MSG_PROCESS_STATUS_INFO                         =
+ * ============================================================================
+ */
+struct ofile {
+       u32 fd;
+       u64 size;
+       char path[0];
+} __packed;
+
+static int pack_ofile(void *data, size_t size, int fd, struct file *file,
+                     loff_t fsize)
+{
+       int ret;
+       struct ofile *ofile;
+
+       if (size < sizeof(*ofile))
+               return -ENOMEM;
+
+       ofile = (struct ofile *)data;
+       ofile->fd = (u32)fd;
+       ofile->size = (u64)fsize;
+
+       ret = pack_path(ofile->path, size - sizeof(*ofile), file);
+       if (ret < 0)
+               return ret;
+
+       return sizeof(*ofile) + ret;
+}
+
+static int pack_status_info(void *data, size_t size, struct task_struct *task)
+{
+       int ret, fd;
+       u32 *file_cnt;
+       struct files_struct *files;
+       const size_t old_size = size;
+
+       files = swap_get_files_struct(task);
+       if (files == NULL) {
+               ret = -EIO;
+               goto put_fstruct;
+       }
+
+       /* pack pid */
+       *((u32 *)data) = (u32)task->tgid;
+       data += 4;
+       size -= 4;
+
+       /* pack file count */
+       file_cnt = (u32 *)data;
+       *file_cnt = 0;
+       data += 4;
+       size -= 4;
+
+       /* pack file list */
+       rcu_read_lock();
+       for (fd = 0; fd < files_fdtable(files)->max_fds; ++fd) {
+               struct file *file;
+               struct inode *inode;
+               loff_t fsize;
+
+               file = fcheck_files(files, fd);
+               if (file == NULL)
+                        continue;
+
+               inode = file->f_path.dentry->d_inode;
+               /* check inode and if it is a regular file */
+               if (inode == NULL || !S_ISREG(inode->i_mode))
+                       continue;
+
+               fsize = inode->i_size;
+               rcu_read_unlock();
+
+               ret = pack_ofile(data, size, fd, file, fsize);
+               if (ret < 0)
+                       goto put_fstruct;
+
+               data += ret;
+               size -= ret;
+               ++(*file_cnt);
+
+               rcu_read_lock();
+       }
+       rcu_read_unlock();
+       ret = old_size - size;
+
+put_fstruct:
+       swap_put_files_struct(files);
+       return ret;
+}
+
+void usm_msg_status_info(struct task_struct *task)
+{
+       int ret;
+       void *data;
+       size_t size;
+       struct swap_msg *m;
+
+       m = swap_msg_get(MSG_PROCESS_STATUS_INFO);
+
+       data = swap_msg_payload(m);
+       size = swap_msg_size(m);
+       ret = pack_status_info(data, size, task);
+       if (ret < 0) {
+               printk(USM_PREFIX "ERROR: MSG_PROCESS_STATUS_INFO "
+                      "packing, ret=%d\n", ret);
+               goto put_msg;
+       }
+
+       swap_msg_flush(m, ret);
+
+put_msg:
+       swap_msg_put(m);
+}
index c144817..b151be5 100644 (file)
@@ -28,12 +28,14 @@ struct dentry;
 struct task_struct;
 struct vm_area_struct;
 
+int usm_msg_once(void);
 
 void usm_msg_info(struct task_struct *task, struct dentry *dentry);
 void usm_msg_term(struct task_struct *task);
 void usm_msg_map(struct vm_area_struct *vma);
 void usm_msg_unmap(unsigned long start, unsigned long end);
 void usm_msg_comm(struct task_struct *task);
+void usm_msg_status_info(struct task_struct *task);
 
 
 #endif /* _USM_MSG_H */
index 288caec..1748a59 100644 (file)
@@ -39,6 +39,7 @@ enum swap_msg_id {
        MSG_SYSCALL_EXIT                = 0x000b,
        MSG_FILE_FUNCTION_ENTRY         = 0x000c,
        MSG_FILE_FUNCTION_EXIT          = 0x000d,
+       MSG_PROCESS_STATUS_INFO         = 0x000e,
        MSG_CONTEXT_SWITCH_ENTRY        = 0x0010,
        MSG_CONTEXT_SWITCH_EXIT         = 0x0011,
        MSG_PROC_MAP                    = 0x0012,