網頁

2009年6月25日 星期四

Shell script tricks

1. The array of shell script 
names=( Jennifer Tonya Anna Sadie )
for name in ${names[@]}
do
   echo $name
done
names=( Jennifer Tonya Anna Sadie )
for (( i = 0 ; i < ${#names[@]} ; i++ ))
do
    echo ${names[$i]}
done
2. Variable substitution for shell script 
$DEVICE0=eth0
$echo "Configure interface " ${!DEVICE${i}}
$n=1
$ eval echo \${$n}
$ n="date"
$ echo $($n)
Output :Wed May 21 20:39:00 EEST 2008
3. Increment i in the while loop 
i=$(($i+1))
i=`expr i + $i`

2009年6月15日 星期一

Re-entrant vs Thread safe

Both concepts of reentrancy and thread safety relate to the way functions handle resources. However, they are not the same. While the concept of reentrancy can affect the external interface of a function, thread safety only concerns the implementation of the function and not its external interface.
  • In most cases, to make a non-reentrant function reentrant, its external interface must be modified such that all data is provided by the caller of the function.
  • To make a thread-unsafe function thread-safe, only the implementation needs to be changed, usually by addingsynchronization blocks to protect shared resources from concurrent accesses by different threads.
Therefore, reentrancy is a more fundamental property than thread-safety and by definition, leads to thread-safety: Every reentrant function is thread-safe; however, not every thread-safe function is reentrant.
Reference from http://en.wikipedia.org/wiki/Reentrant_(subroutine)

2009年6月9日 星期二

How to show the page table entry


excerpt from arch/arm/mm/fault.c
void show_pte(struct mm_struct *mm, unsigned long addr)
{
pgd_t *pgd;

if (!mm)
mm = &init_mm;

printk(KERN_ALERT "pgd = %p\n", mm->pgd);
pgd = pgd_offset(mm, addr);
printk(KERN_ALERT "[%08lx] *pgd=%08lx", addr, pgd_val(*pgd));

do {
pmd_t *pmd;
pte_t *pte;

if (pgd_none(*pgd))
break;

if (pgd_bad(*pgd)) {
printk("(bad)");
break;
}

pmd = pmd_offset(pgd, addr);
#if PTRS_PER_PMD != 1
printk(", *pmd=%08lx", pmd_val(*pmd));
#endif

if (pmd_none(*pmd))
break;

if (pmd_bad(*pmd)) {
printk("(bad)");
break;
}

#ifndef CONFIG_HIGHMEM
/* We must not map this if we have highmem enabled */
pte = pte_offset_map(pmd, addr);
printk(", *pte=%08lx", pte_val(*pte));
printk(", *ppte=%08lx", pte_val(pte[-PTRS_PER_PTE]));
pte_unmap(pte);
#endif
} while(0);

printk("\n");
}

crontab

Crontab command
#export to the file
crontab -l > filename
# import from the file
crontab filename 
# import from the file for the specific user
crontab -u user filename 
# edit
crontab -e 
# delete all
crontab -r 

Crontab special usage 


EntryDescriptionEquivalent To
@rebootRun once, at startup.None
@yearlyRun once a year0 0 1 1 *
@annually(same as @yearly)0 0 1 1 *
@monthlyRun once a month0 0 1 * *
@weeklyRun once a week0 0 * * 0
@dailyRun once a day0 0 * * *
@midnight(same as @daily)0 0 * * *
@hourlyRun once an hour0 * * * *


Crontab Example

# .---------------- minute (0 - 59) 
# | .------------- hour (0 - 23)
# | | .---------- day of month (1 - 31)
# | | | .------- month (1 - 12) OR jan,feb,mar,apr ...
# | | | | .---- day of week (0 - 6) (Sunday=0 or 7) OR sun,mon,tue,wed,thu,fri,sat
# | | | | |
# * * * * * command to be executed

minhourday/monthmonthday/week Execution time
30011,6,12*-- 00:30 Hrs  on 1st of Jan, June & Dec.

:

020*101-5--8.00 PM every weekday (Mon-Fri) only in Oct.

:

001,10,15**-- midnight on 1st ,10th & 15th of month

:

5,10010*1-- At 12.05,12.10 every Monday & on 10th of every month
:

 
*/8 * * * * root init 6  After 8 minutes , execute "reboot" command
ps: "*/8" in the minute time field is equivalent to "0,8,16,24,32,48,56"

2009年6月8日 星期一

Linux 2.6 Driver Template


#include <linux/module.h>
#include <linux/config.h>
#include <linux/sched.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/ioport.h>
#include <asm/io.h>

#include <linux/fs.h>
#include <linux/cdev.h>
#include <asm/uaccess.h>

typedef struct
{
void **data;
struct cdev *cdev ;

}DBG_Dev_Tag;

#define DBG_MAJOR 111
#define DBG_MINOR 1
#define MAXDEVICENUM 1

#define DEBUG_IOC_MAGIC 'D'
#define DEBUG_IOCSHOWDEB _IOR(DEBUG_IOC_MAGIC, 1, int)

DBG_Dev_Tag *DBG_devices;


int dbg_major = DBG_MAJOR;
int dbg_minor;

static struct file_operations DBG_fops =
{
.ioctl = DBG_ioctl,
.read = DBG_read,
.write = DBG_write,
.open = DBG_open,
.release = DBG_release,
};

int DBG_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg)
{
struct net_device *dev = &_wpcm450_netdevice;

switch (cmd)
{
case DEBUG_IOCSHOWDEB:
//show something

break;
default:
break;
}

return 0;
}

ssize_t DBG_read (struct file *filp, char *buf, size_t count, loff_t *offset)
{
return 0;
}

ssize_t DBG_write (struct file *file, const char *buf, size_t count, loff_t *offset)
{
return 0;
}

static int DBG_open(struct inode *inode, struct file *filp)
{
DBG_Dev_Tag *dev;

dev = container_of (inode->i_cdev,DBG_Dev_Tag,cdev);

filp-> private_data = dev;

return 0;
}

static int DBG_release(struct inode *inode, struct file *filp)
{


return 0;
}



static void dbg_setup_cdev(DBG_Dev_Tag *dev,int index)
{
int err;
int dev_id = MKDEV(dbg_major,dbg_minor + index );

cdev_init(dev->cdev,&DBG_fops);

dev->cdev->owner = THIS_MODULE;

dev->cdev->ops = &DBG_fops;

err = cdev_add(dev->cdev,dev_id,1);

if (err)
printk ("error %x adding dbg%x\n",err,index);

}


static int __init DBG_init(void)
{
int result;
dev_t dev_id;


DBG_devices = kmalloc (sizeof (DBG_Dev_Tag) * MAXDEVICENUM ,GFP_KERNEL);

if (DBG_devices == NULL)
{
result = -ENOMEM;
return result;
}

memset(DBG_devices, 0, MAXDEVICENUM * sizeof(DBG_Dev_Tag));

if (dbg_major)
{
dev_id = MKDEV(dbg_major,dbg_minor);

result = register_chrdev_region(dev_id, 1, "debug");
}
else
{
result = alloc_chrdev_region(&dev_id,DBG_MINOR,1,"dbg");
dbg_major = MAJOR(dev_id);
}

if (result < 0 )
{
printk ("can't get major %d\n",dbg_major);
return result;
}

DBG_devices->cdev = cdev_alloc();

dbg_setup_cdev(DBG_devices,1);

return 0;
}

static void __exit DBG_exit(void)
{
dev_t dev_id;

kfree(DBG_devices);

cdev_del(DBG_devices ->cdev);

dev_id = MKDEV(dbg_major,dbg_minor);
unregister_chrdev_region(dev_id,1);
return;
}

MODULE_AUTHOR("XXXXXXXXXX");
MODULE_DESCRIPTION("Debug driver");
MODULE_LICENSE("GPL");

module_init(DBG_init);
module_exit(DBG_exit);

//**************************Makefile *******************************
KERNELDIR =   obj-m := test_drv.o
#combine two drivers into the one. 
#test_drv-objs := testA_drv.o testB_drv.o  
ifneq ($(KERNELRELEASE),)  
CFLAGS +=  -D__KERNEL__ -DMODULE  -Wall -DEXPORT_SYMTAB -O2  
else  
all:  
 $(MAKE) -C $(KERNELDIR) M=$(shell pwd) modules endif 

2009年6月5日 星期五

TCP keepalive under linux

TCP keepalive During TCP connection idle
Main goal:
  • Checking for dead peers
  • Preventing disconnection due to network inactivity- TCP connections through NATs or proxy but they keep limited memory resources (mantain a few TCP connections, discard old connections)
How to use TCP keepalive under Linux
  • tcp_keepalive_time - the interval between the last data packet sent (simple ACKs are not considered data) and the first keepalive probe; after the connection is marked to need keepalive
  • tcp_keepalive_intvl - the interval between subsequential keepalive probes, regardless of what the connection has exchanged in the meantime
  • tcp_keepalive_probes - the number of unacknowledged probes to send before considering the connection dead and notifying the application layer
procfs interface

echo 20 > /proc/sys/net/ipv4/tcp_keepalive_probes

echo 600 > /proc/sys/net/ipv4/tcp_keepalive_time

echo 60 > /proc/sys/net/ipv4/tcp_keepalive_intvl
sysctl interface


sysctl -w \

> net.ipv4.tcp_keepalive_time=600 \

> net.ipv4.tcp_keepalive_intvl=60 \

> net.ipv4.tcp_keepalive_probes=20

How to program network applications with TCP keepalive
  • System call :setsockopt(s, SOL_SOCKET, SO_KEEPALIVE, &optval, optlen)
  • Other three socket options for the current socket overide system-wide variables as the follwoing
TCP_KEEPCNT: overrides tcp_keepalive_probes
TCP_KEEPIDLE: overrides tcp_keepalive_time
TCP_KEEPINTVL: overrides tcp_keepalive_intvl
reference from http://tldp.org/HOWTO/html_single/TCP-Keepalive-HOWTO/#whatis