‏הצגת רשומות עם תוויות bash. הצג את כל הרשומות
‏הצגת רשומות עם תוויות bash. הצג את כל הרשומות

יום שני, 17 ביוני 2013

device with simple ioctl

The char driver code

  1: #include <linux/kernel.h>  /* We're doing kernel work */
  2: #include <linux/module.h>  /* Specifically, a module */
  3: #include <linux/fs.h>
  4: #include <asm/uaccess.h>  /* for get_user and put_user */
  5: #include  <linux/slab.h>
  6: 
  7: #include "chardev.h"
  8: #define SUCCESS 0
  9: #define DEVICE_NAME "char_dev"
 10: #define BUF_LEN 80
 11: #define DEBUG  
 12: /* 
 13:  * Is the device open right now? Used to prevent
 14:  * concurent access into the same device 
 15:  */
 16:  int Device_Open = 0;
 17: 
 18: static int device_open(struct inode *inode, struct file *file)
 19: {
 20:   printk(KERN_INFO "device_open(%p)\n", file);
 21: 
 22:   /* 
 23:    * currenlty void more then on client at a time 
 24:    */
 25:   if (Device_Open)
 26:   {
 27:     return -EBUSY;
 28:    }
 29:   Device_Open++;
 30:   /*
 31:    * Initialize the message 
 32:    */
 33:   
 34:   try_module_get(THIS_MODULE);
 35:   return SUCCESS;
 36: }
 37: 
 38: static int device_release(struct inode *inode, struct file *file)
 39: {
 40: #ifdef DEBUG
 41:   printk(KERN_INFO "device_release(%p,%p)\n", inode, file);
 42: #endif
 43: 
 44:   /* 
 45:    * We're now ready for our next caller 
 46:    */
 47:   Device_Open--;
 48: 
 49:   module_put(THIS_MODULE);
 50:   
 51:   return SUCCESS;
 52: }
 53: 
 54: static void HandleCountFor (void * userData )
 55: {
 56:   int mFrom ;
 57:   
 58:   int mTo;
 59:   
 60:   int mStep;
 61:   
 62:   int * theKernelSpaceData ;
 63:   
 64:   printk(KERN_ALERT "Enter HandleCountFor 1\n");
 65:   
 66:   theKernelSpaceData = kmalloc(sizeof(int) * 3, GFP_KERNEL);
 67:   
 68:   copy_from_user(theKernelSpaceData, (void *)userData, sizeof(int) * 3);
 69: 
 70:     mFrom = theKernelSpaceData[0];
 71:   
 72:   mTo = theKernelSpaceData[1];
 73:   
 74:   mStep = theKernelSpaceData[2];
 75:     
 76:   printk(KERN_ALERT "Countr From %d mTo %d mStep %d \n" , mFrom, mTo, mStep);
 77: 
 78:   kfree(theKernelSpaceData);
 79:  
 80: } 
 81: 
 82: 
 83: int device_ioctl(
 84:      struct file *file,  /* ditto */
 85:      unsigned int ioctl_num,  /* number and param for ioctl */
 86:      unsigned long ioctl_param)
 87: {
 88:   /* 
 89:    * Switch according to the ioctl called 
 90:    */
 91:   switch (ioctl_num) {
 92:   case IOCTL_SET_COUNTFOR_VARIABLES:
 93:     
 94:     HandleCountFor (ioctl_param);
 95: 
 96:     break;
 97:   
 98:   }
 99: 
100:   return SUCCESS;
101: }
102: 
103: /* Module Declarations */
104: 
105: /* 
106:  * This structure will hold the functions to be called
107:  * when a process does something to the device we
108:  * created. Since a pointer to this structure is kept in
109:  * the devices table, it can't be local to
110:  * init_module. NULL is for unimplemented functions. 
111:  */
112: struct file_operations Fops = {  
113:   .unlocked_ioctl = device_ioctl,
114:   .open = device_open,
115:   .release = device_release,  /* a.k.a. close */
116: };
117: 
118: /* 
119:  * Initialize the module - Register the character device 
120:  */
121: int init_module()
122: {
123:   int ret_val;
124:   /* 
125:    * Register the character device (atleast try) 
126:    */
127:   ret_val = register_chrdev(MAJOR_NUM, DEVICE_NAME, &Fops);
128: 
129:   /* 
130:    * Negative values signify an error 
131:    */
132:   if (ret_val < 0) {
133:     printk(KERN_ALERT "%s failed with %d\n",
134:            "Sorry, registering the character device ", ret_val);
135:     return ret_val;
136:   }
137: 
138:   printk(KERN_INFO "%s The major device number is %d.\n",
139:          "Registeration is a success", MAJOR_NUM);
140:   printk(KERN_INFO "If you want to talk to the device driver,\n");
141:   printk(KERN_INFO "you'll have to create a device file. \n");
142:   printk(KERN_INFO "We suggest you use:\n");
143:   printk(KERN_INFO "mknod %s c %d 0\n", DEVICE_FILE_NAME, MAJOR_NUM);
144:   printk(KERN_INFO "The device file name is important, because\n");
145:   printk(KERN_INFO "the ioctl program assumes that's the\n");
146:   printk(KERN_INFO "file you'll use.\n");
147: 
148:   return 0;
149: }
150: 
151: /* 
152:  * Cleanup - unregister the appropriate file from /proc 
153:  */
154: void cleanup_module()
155: { 
156:   unregister_chrdev(MAJOR_NUM, DEVICE_NAME);
157: }

The header file


  1: #include <linux/ioctl.h>
  2: 
  3: /* 
  4:  * The major device number. We can't rely on dynamic 
  5:  * registration any more, because ioctls need to know 
  6:  * it. 
  7:  */
  8: #define MAJOR_NUM 100
  9: 
 10: #define IOCTL_SET_COUNTFOR_VARIABLES _IOWR(MAJOR_NUM, 3, int * )
 11: 
 12: /* 
 13:  * The name of the device file 
 14:  */
 15: #define DEVICE_FILE_NAME "char_dev"

The make file


  1: obj-m := chardev.o 
  2: 
  3: KDIR  := /lib/modules/$(shell uname -r)/build
  4: PWD   := $(shell pwd)
  5: 
  6: default:
  7:   $(MAKE) -C $(KDIR) M=$(PWD) modules
  8: 

The test file


  1: #include <stdio.h>
  2: #include <stdlib.h>
  3: #include <fcntl.h>    /* open */
  4: #include <unistd.h>    /* exit */
  5: #include <sys/ioctl.h>    /* ioctl */
  6: 
  7: 
  8: #include <linux/ioctl.h>
  9: 
 10: #define MAJOR_NUM 100
 11: 
 12: #define IOCTL_SET_COUNTFOR_VARIABLES _IOWR(MAJOR_NUM, 3, int * )
 13: 
 14: /*
 15:  * The name of the device file
 16:  */
 17: #define DEVICE_FILE_NAME "char_dev"
 18: 
 19: void ioctl_Send_FromToStep (int file_desc,int pFrom, int pTo, int pStep)
 20: {
 21:   int  theBuf [3];
 22: 
 23:   theBuf[0] = pFrom;
 24: 
 25:   theBuf[1] = pTo;
 26: 
 27:   theBuf[2] = pStep;
 28: 
 29:   ioctl(file_desc, IOCTL_SET_COUNTFOR_VARIABLES, theBuf);
 30: 
 31: }
 32: 
 33: void main()
 34: {
 35:   int file_desc, ret_val;
 36:   char *msg = "Message passed by ioctl\n";
 37: 
 38:   char * theDriver = "/home/zvika/myStaff/CharDrivers/chardev/char_dev3";
 39: 
 40:   printf (theDriver);
 41: 
 42:   file_desc = open(theDriver, O_RDWR);
 43:   if (file_desc < 0) {
 44:     printf("Can't open device file: %s\n", "char_dev");
 45:     exit(-1);
 46:   }
 47: 
 48:   ioctl_Send_FromToStep (file_desc ,1 , 60 , 4);
 49: 
 50:   close(file_desc);
 51: }

The helper bash file to compile and deploy the device




  1: #!/bin/bash
  2: 
  3: echo "use: sudo ./chardev.sh"
  4: 
  5: echo "Start deploying" 
  6: 
  7: # Root or die  
  8: if [ "$(id -u)" != "0" ]  
  9: then  
 10:   echo "You must be root to load or unload kernel modules"  
 11:   exit 1  
 12: fi  
 13: 
 14: make
 15: 
 16: rmmod chardev.ko
 17: 
 18: insmod chardev.ko

The Result:
Calling: dmesg


[ 6385.292794] device_open(ffff88008025b700)
[ 6385.292798] Enter HandleCountFor 1
[ 6385.292801] Countr From 1 mTo 100 mStep 2
zvika@ubuntu:~/myStaff/CharDrivers/PlayWithKernel$


Making a device file so a user mode program could access it
zvika@ubuntu:~/myStaff/CharDrivers/PlayWithKernel$ sudo mknod char_dev c 100 0Remove the device file
zvika@ubuntu:~/myStaff/CharDrivers/PlayWithKernel$ unlink char_dev
Deploy the module 
zvika@ubuntu:~/myStaff/CharDrivers/PlayWithKernel$ sudo insmod chardev.ko
Remove the deployed module
zvika@ubuntu:~/myStaff/CharDrivers/PlayWithKernel$ sudo rmmod chardev.ko


Resources:
http://www.techrepublic.com/article/loading-and-unloading-modules-in-linux/5031591
http://stackoverflow.com/questions/10713956/failed-to-open-device

http://elinux.org/Debugging_by_printing
http://appusajeev.wordpress.com/2011/06/18/writing-a-linux-character-device-driver/

יום שני, 10 ביוני 2013

Array manipulation in bash

The following is a simple array manipulation in bash: 

  1: #Create a new array 
  2: 
  3: declare -a Animales =('Dog' 'Cat' 'Hourse' 'Monkey' );
  4: 
  5: Animales[4] = 'Pig'
  6: 
  7: #print the Hourse
  8: echo  ${Animales[2]}
  9: 
 10: #The total no of animales in the array 
 11: 
 12: echo ${#Animales[@]} 
 13: 
 14: #get the 2th and the 3rt elements 
 15: 
 16: echo ${Animales[@]:2:2}
 17: 
 18: #Replacing Cat with Lion
 19: 
 20: echo ${Animales[@]/Cat/Lion}
 21: 
 22: #Firing the Dog 
 23: 
 24: unset Animales[0]

We can  although loop over the array

  1: #loop over the array 
  2: for i in "${Animales[@]}"
  3: do
  4:   echo $i
  5: done
  6: #loop over the array last 3 elements 
  7: for i in "${Animales[@]:2:3}"
  8: do
  9:   echo $i
 10: done


Resources:
http://www.thegeekstuff.com/2010/06/bash-array-tutorial/
http://www.cyberciti.biz/faq/bash-for-loop-array/

יום חמישי, 30 במאי 2013

Starting stopping and restarting a java service app in bash

I found the following bash script used to allow stopping restarting and starting of an java application service:

  1: #!/bin/sh
  2: case "$1" in
  3: 
  4: 	start)
  5: 		echo "Start myService"
  6: 		cd /home/ubuntu/myService
  7: 		nohup java -cp .:Service-bin:lib/* com.myCompany.Services.myService > OutputData.log &
  8: 		sleep 3
  9: 		tail -n 10 OutputData.log
 10: 	;;
 11: 
 12: 	stop)
 13: 		echo "Stop service"
 14: 		kill $(ps aux | grep myService|awk '{print $2}') > /dev/null
 15: 	;;
 16: 
 17: 	restart)
 18: 		echo "Restart myService"
 19: 		$0 stop
 20: 		sleep 1
 21: 		$0 start
 22: 	;;
 23: esac
 24: 
 25: exit 0

Things I want to emphasize:
1.The restart case is reenter into the script using the $0
2.Running the service using the nohup bash command .The nohup bash command allows to run command./process or shell script that can continue running in the background after you log out from a shell.
3.The java –cp option allows to provide the classpath i.e. path(s) to additional classes or libraries that your program may require when being compiled or run.
4.Tail –n  10:prints only the final 10 lines of the log
5.The killing of the service line (line 14) list all the current process with the following columns:
USER = user owning the process
PID = process ID of the process
%CPU = It is the CPU time used divided by the time the process has been running.
%MEM = ratio of the process’s resident set size to the physical memory on the machine
VSZ = virtual memory usage of entire process
RSS = resident set size, the non-swapped physical memory that a task has used
TTY = controlling tty (terminal)
STAT = multi-character process state
START = starting time or date of the process
TIME = cumulative CPU time
COMMAND = command with all its arguments
 
we try to find the lines with the smyervice phrase and then use awk to get the 2nd word (the Pid that is going to be killed ).
We discard any output to directing the output to the null device .

יום חמישי, 16 במאי 2013

Simple bash and awk program

A simple bash program:

echo "Start "
#Iterate over all the files in the Logs directory
for nextLogFile in Logs/*
do
    #pring the file
    echo $nextLogFile
 
  /*
        for every file  cat stream its content into the awk
        the awk print the 2nd space delemeted word in each line
        in the end of the iteration over the lines print "done"   
    */
    cat $nextLogFile|awk '{print $2}{print "done"}'
   
 
   /*
        for every file cat stream its content into the awk
        the awk test using regex if the 2nd space delemeted word in each line
        start with G or S if yes then its print the word    
    */
    cat $nextLogFile|awk '{
        theName = $2   
        if ( theName ~ /[GS]/)
            print theName;
        }'
done
echo "End"