learning proc read write

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi ,
   That is my first post here. I'm studying kernel and more especific /proc. I'm trying to receive a pid on write using /proc ,find uid and print all tasks with the same uid.Like this :
    # ps aux
root      4713   0.0  0.0  1592  500 tty1     Ss+  Jan09   0:00
/sbin/getty 38400 tty1
root      4714  0.0  0.0  1592  504 tty2     Ss+  Jan09   0:00
/sbin/getty 38400 tty2
root      4715   0.0  0.0  1596  508 tty3     Ss+  Jan09   0:00
/sbin/getty 38400 tty3
root      4716  0.0  0.0  1596  504 tty4     Ss+  Jan09   0:00
/sbin/getty 38400 tty4
root      4717  0.0  0.0  1592  504 tty5     Ss+  Jan09   0:00
/sbin/getty 38400 tty5
root      4718  0.0  0.0  1592  504 tty6     Ss+  Jan09   0:00
/sbin/getty 38400 tty6
foo      29661  0.0  0.0  3696 2064 pts/0    Ss   Jan10   0:00 bash
foo       1794  0.0  0.0  3672 2036 pts/3    Ss   Jan10   0:00 bash
foo      26631  0.0  0.1  3660 2328 pts/1    S+   16:09   0:00 vim foo.txt
root       718  0.0  0.0   592  500 ?        Ss+  Jan09   0:00 /sbin/cron
    # echo "1794" > /proc/entrada
    # cat /proc/entrada
<29661, bash>
<1794, bash>
<26631, vim>


I wrote some changes and created a patch (end of file),the new kernel is crashing.

root@darkstar:~# cat /proc/entrada
< 1 , init  >
< 2 , migration/0  >
< 3 , ksoftirqd/0  >
< 4 , watchdog/0  >
< 5 , events/0  >
< 6 , khelper  >
< 7 , kthread  >
< 8 , kblockd/0  >
< 22 , pdflush  >
< 23 , pdflush  >
< 25 , aio/0  >
< 24 , kswapd0  >
< 673 , syslogd  >
< 676 , klogd  >
< 712 , inetd  >
< 721 , crond  >
< 724 , bash  >
< 741 , agetty  >
< 742 , agetty  >
< 743 , agetty  >
< 757 , cat  >
root@darkstar:~# su - foo
[42949478.160000] Kernel panic - not syncing: Kernel mode fault at addr 0x61202d68, ip 0x400ab0b8
[42949478.160000]  [42949478.160000]


My first patch :)


Index: linux-2.6.15.7/fs/proc/proc_misc.c
===================================================================
--- linux-2.6.15.7.orig/fs/proc/proc_misc.c    2006-08-11 10:08:20.000000000 -0400
+++ linux-2.6.15.7/fs/proc/proc_misc.c    2006-08-11 10:08:38.000000000 -0400
@@ -13,6 +13,8 @@
  * Changes:
  * Fulton Green      :  Encapsulated position metric calculations.
  *            <kernel@xxxxxxxxxxxxxxx>
+ *     Changes Francisco Keppler Silva Alecrim ( alecrim@xxxxxxxxx)
+ *     Create "entrada" on /proc to read a pid number and return all processes of its owner.
  */
 
 #include <linux/types.h>
@@ -67,7 +69,8 @@
 extern int get_exec_domain_list(char *);
 extern int get_dma_list(char *);
 extern int get_locks_status (char *, char **, off_t, int);
-
+static struct proc_dir_entry *proc_entry_file;
+int process_number=0;                
 static int proc_calc_metrics(char *page, char **start, off_t off,
                  int count, int *eof, int len)
 {
@@ -563,6 +566,55 @@
         entry->proc_fops = f;
 }
 
+
+/*function called when someone try to read /proc/entrada
+ * It returns all processes of a owner*/
+static int proc_entry_file_read(char *page, char **start, off_t off,
+                 int count, int *eof, void *data)
+{
+    int len; //length - used to store the page length
+    char *out,*item; // out - store all info
+    struct task_struct *p,*c=find_task_by_pid(process_number);//p - pointer process - used to check all processes // c - pointer for current process
+    if(!c)//if not not found
+    {
+        len=sprintf(page,"Current pid=%d does not exist! :p\n",process_number);//store on page : not found
+        return len;         //returning length of page used
+    }
+    out=kmalloc(200,GFP_KERNEL);
+    item=kmalloc(20,GFP_KERNEL);
+    strcpy(out,"");
+    for_each_process(p)//pointer p will run for all process
+    {
+         if(c->uid == p->uid)//some uid = user identifier
+         {
+            sprintf(item,"< %d , %s  >\n",p->pid,p->comm);//store on task identifier and name on item
+            strcat(out,item); //acumulate item to out
+         }
+    }   
+    len=sprintf(page,"%s",out);//store on page : all task of a user
+    return len;
+}
+/*function called when someone try to write /proc/entrada
+ * It stores a process number giving by someone on process_number*/
+static int proc_entry_file_write (struct file *file, const char *buffer,unsigned long count, void *data)
+{
+    char *input = kmalloc (count,GFP_KERNEL) ;// pointer to store buffer number
+          if (!input)
+     {
+         return -ENOMEM ;  // Out of memory
+     }
+    if(copy_from_user(input,buffer,count))//copy value stored on buffer to input
+     {
+         kfree(input);
+        return -EFAULT;  //Bad address
+     }
+    process_number=simple_strtoul(input,NULL,10); // convert string to unsigned integer and store on process_number
+    printk(KERN_INFO "proc_entry_file - received process number %d \n",process_number);
+    kfree(input);
+    return count ;   
+}
+
+
 void __init proc_misc_init(void)
 {
     struct proc_dir_entry *entry;
@@ -629,4 +681,7 @@
     if (entry)
         entry->proc_fops = &proc_sysrq_trigger_operations;
 #endif
+    proc_entry_file=create_proc_entry("entrada",S_IRUGO | S_IWUSR,NULL); // creating a proc entry
+        proc_entry_file->read_proc= proc_entry_file_read; //defining that when file read , execute proc_entry_file_read
+    proc_entry_file->write_proc=proc_entry_file_write; // when write proc_entry_file_read
 }


What is wrong ?
Go ahead , give it hell. I'm open for comments and sugestions.

Thanks

--
--
Francisco Keppler Silva Alecrim
Instituto Nokia de Tecnologia (INdT) - OSMRC

[Index of Archives]     [Newbies FAQ]     [Linux Kernel Mentors]     [Linux Kernel Development]     [IETF Annouce]     [Git]     [Networking]     [Security]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux SCSI]     [Linux ACPI]
  Powered by Linux