Tuesday, January 5, 2010

rrdtool - every data is a rate!

This article is about understanding the rate calculating in the rrdtool.

I'm doing a SA project recently. We get the RTTs(round-trip time) by the ping command and write the RTT to a rrd file, print out the graph, ...

More information about the rrdtool can be found on their website.
http://oss.oetiker.ch/rrdtool/

I first created a rrd file:
rrdtool create F.rrd \
--step 10 \
DS:rtt1:GAUGE:20:0:U \
RRA:MAX:0.5:1:35712

Then, I updated some values to the F.rrd file. A interesting fact is that when I update the value at exact the time step (say 10, 20, 30, etc.), I'll have a accurate value.

# rrdtool update F 1262733290:3
# rrdtool update F 1262733300:4
# rrdtool update F 1262733310:5
# rrdtool update F 1262733320:6

1262733300: 4.0000000000e+00
1262733310: 5.0000000000e+00
1262733320: 6.0000000000e+00

OK, there is a thing called "heartbeat" in the rddtool, it helps the updates that occur at a not-accurate timestamps. For example, if we update a value at time 1262733331, the rrdtool will put the value to 1262733330. It's a nice feature, since there is always some delays in the networking world.

Let's take a look

# rrdtool update F 1262733331:7
# rrdtool update F 1262733340:8

1262733330: 7.0000000000e+00
1262733340: 7.9000000000e+00

As you can see, the value 7 is updated at 1262733331 but is shifted to 126273330 in the rrd file. But what happened with the next update at 1262733340? We update 8 but the rrd file recorded 7.9. Strange, right?

Here is how 7.9 comes out: since rrdtool treats every data as a rate, if there are more than one samples before a time step, rrdtool tries to calculate the average rate of all the samples before the time step (after the previous time step, of course).

previous time step: 1262733330
when we update 7 at 1262733331; 8 at 1262733340.
the calculation is
(7 * (1262733331 - 1262733330) +
8 * (1262733340 - 1262733331) ) / 10 = 7.9

Here is a figure to help understanding:


OK, Let's do the math with another example:

# rrdtool update F 1262733341:54
# rrdtool update F 1262733342:3
# rrdtool update F 1262733347:31
# rrdtool update F 1262733350:3

To find out the average value at 1262733350:
previous time step: 1262733340
(54 * (1262733341 - 1262733340) +
3 * (1262733342 - 1262733341) +
31 * (1262733347 - 1262733342) +
3 * (1262733350 - 1262733347)) / 10 = 22.1

Read the rrd file to verify our answer:
1262733350: 2.2100000000e+01

It's a perfect match. :-)

I hope this article can help someone who has the same question as I did.

Wednesday, December 30, 2009

Config language - sqldeveloper

sqldeveloper\sqldeveloper\bin\sqldeveloper.config

AddVMOption -Duser.language=en
AddVMOption -Duser.region=US

Sunday, December 13, 2009

double fork to avoid zombie process

It is a common mistake to fork a child process without calling waitpid() to wait for the termination of the child process. Without a wait() call, the child process will become a zombie process after its termination because its parent process does not cleanup its process information in the system. A zombie process occupies a pid in the system, decrease the available pids in the system. Zombies are mark as "defunct" if you check the process by the "ps" command.

However, sometimes we do not want the parent process to wait for its child process for a long time. There is a way to achieve both "not create zombie process" and "not wait for the child process to its termination", and the way is to do a double fork.

The idea is simple, when a parent process (say A) want to fork a child process to do "something". Process A does not fork a process to do "something" directly. Process A first forks a child process (say B), and process then forks its child process (say C) to do "something" and process B terminates as soon as process C is created. In this way, process A only has to wait for process B for a short time. In the same time, since it has no parent process (process B is dead), the system will "rechild" process C to the init process. The init process calls wait() for its child process, solving the zombie process problem.

The program looks like


void func()
{
pit_t pid1;
pit_t pid2;
int status;

if (pid1 = fork()) {
/* parent process A */
waitpid(pid1, &status, NULL);
} else if (!pit1) {
/* child process B */
if (pid2 = fork()) {
exit(0);
} else if (!pid2) {
/* child process C */
execvp("something");
} else {
/* error */
}
} else {
/* error */
}
}

Monday, December 7, 2009

kill all child process

killtree () {
for child in $(ps -o pid= --ppid $1)
do
killtree $child
done
echo "kill -9 $1"
kill -9 $1 2>/dev/null
}
killtree {some pid}

read line in bash script

It is very easy to read "words" in a bash script. But what if you want to read a line in a text file? I have this problem today, After some googling, I found a interesting way to do this.

while read l
do
echo $l
done < xxx.txt

It use the xxx.txt as input, and the read command in bash will read the input line by line.

linux 802.1q support

In the previous article "vlan tag under vmware/virtualbox", I found that the e1000 network driver cannot insert vlan tag to frames. In this article I want to tell you that I WAS WRONG.

After some experiments, I found that the e1000 driver does insert the vlan tag into the frames. The problem is that the e1000 driver automatically remove vlan tags when receiving incoming frames before I was trying to read the incoming frames by tcpdump.

So, we can now use liunx + 802.1q module to communicate with vlan members.

Sunday, November 15, 2009

vlan tag under vmware/virtualbox

When I was trying to add a vlan tag on my network traffic, I found that the tcpdump can read the correct vlan id information when I was using VMware or Virtualbox, but it failed to read that on my host machine.

After a lot of googling and test, I found that the Intel Pro/1000 driver has a bug that it automically filter the vlan tag. The reason that VMware and Virtualbox worded fine is that they do not have a Intel Pro/1000 NIC (network interface card).

I will keep my work on the virtual machines. To test the vlan feature:

promote> vconfig add eth0 101
add a vlan interface named eth0.101
promote> ifconfig eth0.101 10.0.0.7/24 up
give eth0.101 a ip and active it
promote> ping -I eth0.101 xxx.xxx.xxx.xxx
ping a ip through eth0.101

we can dump the packet via tcpdump
promote> tcpdump -ne -i eth0 -xx

you can see output message like:

12:54:08.887252 00:0c:29:6f:2e:e2 > Broadcast, ethertype 802.1Q (0x8100), length 46: vlan 101, p 0, ethertype ARP, arp who-has 23.24.4.43 tell 10.0.0.7
0x0000: ffff ffff ffff 000c 296f 2ee2 8100 0065
0x0010: 0806 0001 0800 0604 0001 000c 296f 2ee2
0x0020: 0a00 0007 0000 0000 0000 1718 042b

where the rea-marked bits are the valn id.

Thursday, November 12, 2009

Virtualbox share folder with linux

mount -t vboxsf [-o OPTIONS] sharename mountpoint

Monday, November 9, 2009

wvdial - using SE w980

[Dialer Defaults]
Phone = *99#
APN = internet
Stupid Mode = yes
Dial Command = ATDT
Modem = /dev/ttyACM0
Baud = 460800
;Init1 = AT+CPIN=0000
Init2 = ATZ
Init3 = ATQ0 V1 E1 S0=0 &C1 &D2 +FCLASS=0
Init4 = AT+cgdcont=1,"IP","internet"
Password = internet
Username = internet
New PPPD = yes
ISDN = 0
Modem Type = USB Modem

Wednesday, November 4, 2009

adobe plash plug-in for firefox

1)download the plash player (.tar.gz) from adobe's website.
2)decompress the file.
3)cp the libflashplayer.so to ./mozille/plugins
4)enable the plug-in in the add-on menu.