티스토리 툴바



2012/04/26 11:54

Shell Script by exam

안쓰니까 자꾸 까먹는다...


from : http://www.indiangnu.org/ko/2009/bash-%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-%EC%98%88%EC%A0%9C%EB%A1%9C-%EB%B0%B0%EC%9A%B0%EB%8A%94/

Introduction ~

—————————————–
Program (1) ~ array.sh
—————————————–

#!/bin/bash
echo “==============”
declare -a myarr[0]=”Arun”
declare -a myarr1
myarr1=(arun bagul bangalore mumbai raju santhosh)
myarr[1]=”Bagul”

echo “my name is ${myarr[0]} ${myarr[1]}”
echo “————————–”
echo “${myarr1[*]}”
echo ${myarr1[2]}
echo ${myarr1[@]}
echo “————————–”
echo “Total no of elements in array – ${#myarr1[*]}”
echo “Total no of elements in array – ${#myarr1[@]}”
echo “Size of word ‘${myarr1[2]}’ is – ${#myarr1[2]}”
echo ${#myarr1[1]}
echo ${#myarr1[0]}

echo “————————–”

#how to delete element in array
unset myarr[1]
echo “myarr is – ${myarr[*]}”

#how to assign element in array
myarr[1]=”- System Engineer!”
echo “myarr is – ${myarr[*]}”

echo ${myarr}

————————————————————————
Program (2) ~ command_line_arguments.sh
————————————————————————

#!/bin/bash

echo “Script/command name => $0″
echo “arg1 => $1″
echo “arg2 => $2″
echo “arg3 => $3″
echo “Total No of argument = $#”

echo “Script PID is => $$”
echo “Status of previous command – $?”

name=$myname
echo “Name – $name”

read n

————————————————-
Program (3) ~ default_value.sh
————————————————-

#!/bin/bash

#start=’123′
#start=${1:-$start}

start=${1:-’123′}

echo “Value of ‘start’ variable is ==> $start”

—————————————————
Program (4) ~ echo_example.sh
—————————————————

#!/bin/bash

name=”Arun”

echo -e “My Name is $name_arun and \n”
echo -e “My Name is ${name}_arun and \n”

echo -e ‘My Name is $name and \n’

—————————————–
Program (5) ~ elif.sh
—————————————–

#! /bin/bash

if [ $1 -eq $2 ];then
echo “good”
elif [ $2 -eq $3 ];then
echo “Fine”
elif [ $1 -eq $3 ];then
echo “OK”
else
echo “NO”
fi

————————————————————
Program (6) ~ for_loop_example-1.sh
————————————————————

#!/bin/bash

i=1
while [ $i -le 512 ]
do
temp=$i
echo “What is => $i | $temp”
i=$(expr $i + 32)
for (( j=$temp; $j<=$i; j++ ))
do
echo -n ” $j”
done
done

———————————————————–
Program (7) ~ for_loop_example-2.sh
———————————————————–

#!/bin/bash
#for val in $(ls -1 /tmp)
sum=0
#for val in {1..5}
#for val in {$1..$2}
for((val=$1;$val<=$2;val++))
do
#echo “$val”
sum=$(expr $sum + $val )
#sum=`expr $sum + $val`
done

echo “$0 # Sum of $1 to $2 => $sum”

————————————————————
Program (8) ~ for_loop_example-3.sh
————————————————————

#!/bin/bash

for i in {1..9}
do
echo $i
done

—————————————–
Program (9) ~ function.sh
—————————————–

#!/bin/bash

function my_function()
{
name=”Arun Bagul”
echo “‘my_function’ body ~ $name”
return 1;
}
##########

myfunc()
{
echo “Another way of defining the function”
}

##########################

echo “Starting function program”
echo “——————————”

#calling function here
my_function
##
myfunc

echo -e “\n end of program”

—————————————————————————————
Program (10) ~ how_to_pass_argument_to_function.sh
—————————————————————————————

#!/bin/bash

function my_function()
{
echo “Total number of argument ~ $#”
echo “Arg1 => $1″
echo “Arg2 => $2″
echo “Arg3 => $3″
return 0;
}
##########

echo “Starting function program”
echo “——————————”

#calling function here
my_function arun bagul 1234

————————————————————————-
Program (11) ~ how_to_take_hidden_input.sh
————————————————————————-

#!/bin/bash

echo -n “Enter User Name :”
read username
echo -n “Enter Password :”
read -s mypwd

echo -e “\nI am $username and my password is – $mypwd”

——————————————————————————
Program (12) ~ how_to_take_input_from_user.sh
—————————————————————————–

#!/bin/bash

echo -ne “Enter the Name:- ”
read name
echo -n -e “Enter the Number:- ”
read num

echo “——————————”

add=$(expr $num + 10)

echo “Name is ~ $name”
echo “Number is ~ $add”

—————————————–
Program (13) ~ ifthen.sh
—————————————–

#!/bin/bash

if [ "arun" == "arun" ];then
echo “true!”
else
echo “false”
fi

echo “———————————-”

if [ 2 == 2 ];then
echo “true!”
else
echo “false”
fi

echo “———————————-”

if [ "arun" = "arun" ];then
echo “true!”
else
echo “false”
fi

echo “———————————-”

if [ 2 -eq 2 ];then
echo “true!”
else
echo “false”
fi

——————————————————
Program (14) ~ non-interactive.sh
——————————————————

#!/usr/bin/expect -f
spawn ssh arun@192.168.0.1
expect “password:”
sleep 1
send “pwd\r”
interact

—————————————————————-
Program (15) ~ read_file_line_by_line.sh
—————————————————————-

#!/bin/bash

file_name=”/etc/hosts”

while read myvar
do
echo “Line => $myvar”
done < $file_name

echo “#################################################”

for myvar1 in $(cat $file_name)
do
echo “Line => $myvar1″
done

——————————————————
Program (16) ~ reverse-number.sh
——————————————————

#!/bin/bash

declare -a date_array
num=$1
i=$(expr $(echo $num | wc -c) – 1 )

while [ $num -gt 10 ]
do
temp=$( expr $num % 10 )
num=$( expr $num / 10);
echo “Digit($i) => $temp”
date_array[$i]=”${temp}”
i=$(expr $i – 1)
done
echo “Digit($i) => $num”
date_array[$i]=”${num}”

echo ${date_array[*]}

——————————————————–
Program (17) ~ string-operation.sh
——————————————————–

#! /bin/bash

echo “Arun Bagul:-”
string=”/root/arun/bagul/image.gif”
echo “string=> $string”
echo “String=> ${string##/*/}”
echo “String=> ${string#/*/}”

echo “String=> ${string%.*}”
echo “String=> ${string%%.*}”
#str=”/home/y/conf/arunbagul/daily_market_0.conf”
str=”${str##/*conf/}”
echo “String=> ${str%/*}”

#done

mystr=”keyword_summary_exact_arunsb”
echo $mystr
echo ${mystr%_*}

echo “$*”

—————————————–
Program (18) ~ switch.sh
—————————————–

#!/bin/bash

echo ” Switch program | arg1 => $1″
echo ” ——————————-”
case $1 in

123)
echo “Case is 123″
;;

arun)
echo “Case is ‘arun’”
;;

pri*)

echo “Case is ‘pri*’”
;;

*)
echo ” * Usage: $0 ”
echo ” Default case (nothing is matched)”
exit 0;
;;
esac

—————————————————————–
Program (19) ~ while_loop_example-1.sh
——————————————————————

#!/bin/bash

mywait=wait

while [ "${mywait}" = "wait" ]
do
echo “arun”
done

——————————————————————-
Program (20) ~ while_loop_example-2.sh
——————————————————————–

#! /bin/bash

## on command line -> i=0 && while [ $i -le 10 ] ; do echo $i; i=$(expr $i + 1); done

i=0
while [ $i -le 10 ]
do
echo $i
i=$(expr $i + 1)
done

——————————————————————–

* Please download PDF file http://www.slideshare.net/arunbagul/bash-learning-by-examples/

Regards,

Trackback 0 Comment 0
2011/07/23 18:34

[IRIX] tardist 설치

freeware.sgi.com에서 받은 패키지를 설치하는 경우.

inst -f *.tardist

 
Trackback 0 Comment 1
2011/07/23 17:52

[IRIX] 6.5 이상에서 라우터 설정과 데몬 설정

라우터(기본 게이트웨이) 설정
    /etc/config/static-route.options 파일에 다음과 같이 추가
 $ROUTE $QUIET add -net default 130.60.XX.1

데몬 시작/끔
# chkconfig routed off
# chkconfig routed on
Trackback 0 Comment 0
2011/07/06 22:29

SGI O2 Jumpstart Jumper

원문 : http://www.nekochan.net/wiki/index.php/O2_Diagnostics:_The_Jumpstart_Procedure

Locating the PWR-UP jumper

If you remove the PCI riser and lay the carrier down with the logic board facing up (with the memory slots to the left and the i/o panel facing you), the Dallas chip is right behind the serial ports but before the Adaptec chip. The jumper is immediately to the left of the Dallas chip. On the logic boards I have, the words "PWR-UP" are silkscreened on the logic board next to the jumper.

PWR-UP jumper.jpg


How to Jumpstart the O2

  1. Disconnect the power cord - Then remove the logic board carrier.
  2. Place the jumper across both pins of "PWR-UP" (right next to the DALLAS chip).
  3. Re-install the logic baord carrier assembly into the O2.
  4. Plug in the power cord - the system should power up as soon as power is connected.
  5. Stop in the PROM command monitor - type off <enter> -the system should power down.
  6. Disconnect the power cord - Then remove the logic board carrier.
  7. Remove the jumper and place it on only one of the two header pins.
  8. Re-install the logic board carrier assembly into the O2.
  9. Reconnect the power cord and test for normal start up.


The jumpstart procedure should power up the O2 as soon as you plug it to mains. If it won't power up then (99.99%) the PSU is dead and you have to find a replacement.

Trackback 0 Comment 0
2011/04/10 02:52

리눅스 20주년!

오우! 4월 8일이 리눅스의 20주년 이었군요....
감회가 새롭습니다. 

95년에 리눅스를 486에 설치하던날이 생각납니다. 3.5인치 디스켓으로 한장 한장...ㅡ,.ㅡ

토발즈를 만나던 날도...
공동체 세미나에서 만났던 사람들도..
동호회를 통해 만나게 됐었던 사람들도..
리눅스때문에 전유성아저씨네 갔었던 날들도...
보고싶네요...모두..

그냥 주마등처럼 지나갑니다.
나를 행복하게 만들어준 OS라고나 할까...

 
Trackback 0 Comment 0
2011/04/08 00:52

Yocto 1.0 integrates OpenEmbedded and Linaro code


Linaro 관련해서 본지가 1년이 넘은것 같은데 뭔가 되가고 있나보다.
아울러 Yocto라니.... bitbake기반 개발환경이면 괜찮을듯...

-----------------------------------------------------
The Linux Foundation announced the availability of the Yocto Project Release 1.0, which includes a version of OpenEmbedded's bitbake build system, major improvements to its developer interface, and Linaro technology for improved ARM support. The Linux Foundation also announced new Yocto Steering Group members Dell and Mentor Graphics to help oversee the embedded Linux standardization project.

Launched in October with a 0.9 release, the Yocto Project aims to provide open source tools to help companies make custom, Linux-based embedded systems for ARM, MIPS, PowerPC, and x86 architectures. Hosted by the Linux Foundation (LF), the project was announced at today's Linux Foundation Collaboration Summit.

The Yocto Project Release 1.0 is based on Linux kernel 2.6.37 and consists of the following new features, says the project:

  • new process for gathering, compiling and building from upstream source code
  • system toolchain bootstrapping and machine specific sysroot
  • faster builds and better performance with speed improvements to bitbake
  • updated GCC toolchain (v4.5.1)
  • new Application Development Toolkit (ADT) installer and Application Development Guide
  • updates to the X Windows System, improving security for target devices
  • open source Linux 2.6.37 commands, libraries and middleware
  • board support packages (BSPs) for the Atheros RouterStationPro, Freescale's MPC8315E, Intel's Atom, and Texas Instruments' OMAP, among others
  • new layer that includes the latest release of the Linaro kernel and toolchain for ARM processors, resulting in increased hardware compatibility
The bitbake build system noted above is borrowed from the OpenEmbedded project. In early March, the Yocto Project announced it was aligning its technology with OpenEmbedded, which offers a popular build framework for embedded Linux. At the time, the LF said the Yocto Project would be "merging technology" with the OpenEmbedded community and "extending governance to include OpenEmbedded representatives."

In addition, the projects will share a common OpenEmbedded Core (OE-Core) metadata foundation comprised of software build recipes and core Linux components. This will be key to "preventing fragmentation and reinforcing the OpenEmbedded methodology as an open standard for embedded Linux build systems," said the LF at the time.

Despite the shift to the OpenEmbedded bitbake build system, Yocto still borrows heavily from its initial Poky Linux foundation, although Poky is now an integration layer on top of OE-Core.

 

Yocto 1.0 metadata architecture (preliminary)

http://www.linuxfordevices.com/c/a/News/Yocto-1-released/?kc=rss
http://www.yoctoproject.org/blogs/davest/2011/yocto-project-turns-1.0


 
Trackback 0 Comment 0
2010/01/18 13:43

Looking forward to 2010 - from LWN

By Jonathan Corbet
January 5, 2010
Your editor, not generally known for his good sense, has long made a tradition of putting together a set of Linux-related predictions at the beginning of each year and posting them for the world to see. There is no particular source of inside knowledge behind these predictions, and no real reason to give them more credence than is merited by much of the material found in one's spam folder. Still, it's a fun exercise in pondering how things could go and trying to guess what the important themes will be.

On that note, here's your editor's thoughts for 2010. Any relation to reality is purely coincidental.

Open hardware platforms will be seen as increasingly important by the general public. Anybody who saw Verizon's heavy advertising campaign for its Android-based "Droid" offering will have understood that openness is now seen as a selling point in the mobile phone market - something which was not true even a year or two ago. Apple has done us a favor by showing how painful a restricted platform can be - even if it is a relatively open one. Future offerings, including the much-hyped "tablet" machines, will be judged by many criteria, one of which will be "who decides which applications I can run on it?" Locked-down systems will suffer as a result of their closed nature.

We'll see a number of Linux-based tablet computers offered to the market this year. What may take a bit longer to see is just what all of these machines will really be good for.

Software patents will strike close to home again. Nokia's suit against Apple is an especially ominous development. We are seeing the opening of a whole new computing market where none of the traditionally dominating companies have a commanding share. So it's a bit of a gold rush, and some companies will undoubtedly rush to gain their gold by way of the courts.

Copyright assignment policies will be debated by numerous projects over the course of the year. In the past year, the (attempted, in-progress) acquisition of MySQL (by way of Sun) by Oracle has clearly shown how assignment of copyrights to a corporation can go wrong, and Canonical's imposition of an assignment policy has created a backlash of its own. Even Eben Moglen, who has argued for copyright assignments in the past, has stated publicly that MySQL would be better off with a more diverse ownership structure. Developers in the future will think harder about signing assignment agreements, and projects will wonder whether their interests are truly best served by imposing assignment agreements. Copyright assignment agreements will not go away, but, like heavy-handed trademark policies, they will come to be seen an an impediment to freedom which is often counterproductive.

Speaking of MySQL, Oracle's acquisition of Sun will proceed without the imposition of major changes by the European Union. Regardless of its long-term plans, Oracle will treat MySQL with a light hand in the coming year. There will almost certainly be attempts to fork the project, though, regardless of how Oracle behaves.

The browser war will heat up again, but the main contestants will be free software. Firefox holds a commanding position, but its heavy weight and long startup time are enough to push some users to the competition - which, increasingly, looks to be Google's Chrome. If Google continues to develop the browser, and continues to avoid fatal errors like disallowing ad blocking extensions, Chrome may hold a significant part of the market by the end of the year.

Solid-state storage devices will come into wider use this year, with some interesting results. For example, the above-mentioned long startup time for Firefox tends to just vanish when the browser is SSD-based. Wider use of SSDs will tend to hide lazy or inefficient application development, but it will also put more pressure on the kernel's block subsystem, which will struggle to keep up with rapidly-increasing operation rates.

Adventurous distributors will be offering Btrfs by the end of the year. The filesystem will be feature-complete and stabilizing, but it will still be very much for adventurous (and well backed up) users at that point. Ext4, instead, will be moving beyond community distributions and into "enterprise" production use.

The big kernel lock will be gone from the mainline kernel. Actually, it will probably remain in a number of places, but things will have reached a point where a lock_kernel() call is an indication of old, unmaintained, and unused code. On any reasonably current hardware, a leading-edge kernel will be able to run with no BKL use at all. This work will be part of the larger job of getting the realtime preemption patch set into the mainline, but your editor dares not attempt another prediction on when that task will be complete.

Production use of LLVM will be on the rise as this compiler matures and stabilizes. Some of the most interesting uses are likely to be in nontraditional projects like Unladen Swallow.

There will be a scary security incident involving mobile Linux devices. Our security is pretty good, but it's far from perfect; just think, for example, about the number of bugs likely to be found in wireless network drivers, which are quite complex and reviewed by relatively few people.

Speaking of security, 2010 will be the year of the sandbox. Technologies like SELinux, AppArmor, and TOMOYO will not be going away, but increasing numbers of people will decide that many security objectives are more easily obtained by just placing at-risk processes into their own box.

There will be lots of talk of clouds, with companies stumbling over each other to become the host for some portion of our lives. Your editor can only hope that, at some point, this rush toward highly centralized services will be countered by a push for personal control of data. Perhaps members of our community will make it easy for nontechnical users to set up "cloudlets" for individual or small-group use, with a focus on individual control and portability.

GNOME 3 will be released. Learning from the KDE 4 experience, the GNOME developers will promote their work less and focus more on not breaking things for users. The result will be a launch which draws relatively little attention, of either the good or the bad variety, but which lays the base for the platform's future development.

Developers will start using Python 3 as that language becomes more widely available in community distributions. By the end of the year, a small number of Python 3 programs will be in reasonably wide use. Meanwhile, we'll still be waiting for Perl 6.

Community distributions will grow in commercial importance over the course of the year. Distributions like Debian and Gentoo already show up in surprising places, with prominent organizations choosing them for their combination of stability, broad software selection, and great support. More companies will begin to realize that the "enterprise distribution" model is not perfect for all situations and will go looking for solutions which bring them closer to the communities which create all of that software in the first place.

Linux and free software will be stronger than ever at the end of the year. Yes, your editor makes this prediction every year, but it has proved rather more reliable than most of the others. It makes sense to go with a known winner, and, in any case, this prediction is easy to justify. The software keeps getting better, the community gets larger, and the value of free software is becoming more widely understood. There doesn't seem to be any reason for any of that to change anytime soon.

- 항목 하나하나 기대되지 않는것들이 없군요.

출처 -> http://lwn.net/Articles/368120/


Trackback 0 Comment 0
2010/01/14 11:17

Debugging the kernel using Ftrace - part 2


December 22, 2009

This article was contributed by Steven Rostedt

http://lwn.net/Articles/366796/

The Ftrace tracing utility has many different features that will assist in tracking down Linux kernel problems. The previous article discussed setting up Ftrace, using the function and function graph tracers, using trace_printk(), and a simple way to stop the recording of a trace from user space. This installment will touch on how user space can interact with Ftrace, faster ways of stopping the trace, debugging a crash, and finding what kernel functions are the biggest stack hogs.

Trace Markers

Seeing what happens inside the kernel gives the user a better understanding of how their system works. But sometimes there needs to be coordination between what is happening in user space and what is happening inside the kernel. The timestamps that are shown in the traces are all relative to what is happening within the trace, but they do not correspond well with wall time.

To help synchronize between the actions in user space and kernel space, the trace_marker file was created. It provides a way to write into the Ftrace ring buffer from user space. This marker will then appear in the trace to give a location in the trace of where a specific event occurred.

    [tracing]# echo hello world > trace_marker
    [tracing]# cat trace
    # tracer: nop
    #
    #           TASK-PID    CPU#    TIMESTAMP  FUNCTION
    #              | |       |          |         |
               <...>-3718  [001]  5546.183420: 0: hello world

The <...> indicates that the name of the task that wrote the marker was not recorded. Future releases may fix this.

Starting, Stopping and Recording in a Program

The tracing_on and trace_marker files work very well to trace the activities of an application if the source of the application is available. If there is a problem within the application and you need to find out what is happening inside the kernel at a particular location of the application, these two files come in handy.

At the start of the application, you can open these files to have the file descriptors ready:

    int trace_fd = -1;
    int marker_fd = -1;

    int main(int argc, char *argv)
    {
	    char *debugfs;
	    char path[256];
	    [...]

	    debugfs = find_debugfs();
	    if (debugfs) {
		    strcpy(path, debugfs);
		    strcat(path,"/tracing/tracing_on");
		    trace_fd = open(path, O_WRONLY);
		    if (trace_fd >= 0)
			    write(trace_fd, "1", 1);

		    strcpy(path, debugfs);
		    strcat(path,"/tracing/trace_marker");
		    marker_fd = open(path, O_WRONLY);

Then, at some critical location in the code, markers can be placed to show where the application currently is:

    if (marker_fd >= 0)
	    write(marker_fd, "In critical area\n", 17);

    if (critical_function() < 0) {
	    /* we failed! */
	    if (trace_fd >= 0)
		    write(trace_fd, "0", 1);
    }

In looking at the example, first you see a function called "find_debugfs()". The proper location to mount the debug file system is at /sys/kernel/debug but a robust tool should not depend on the debug file system being mounted there. An example of find_debugfs() is located here. The file descriptors are initialized to -1 to allow this code to work both with and without a tracing enabled kernel.

When the problem is detected, writing the ASCII character "0" into the trace_fd file descriptor stops tracing. As discussed in part 1, this only disables the recording into the Ftrace ring buffer, but the tracers are still incurring overhead.

When using the initialization code above, tracing will be enabled at the beginning of the application because the tracer runs in overwrite mode. That is, when the trace buffer fills up, it will remove the old data and replace it with the new. Since only the most recent trace information is relevant when the problem occurs there is no need to stop and start the tracing during the normal running of the application. The tracer only needs to be disabled when the problem is detected so the trace will have the history of what led up to the error. If interval tracing is needed within the application, it can write an ASCII "1" into the trace_fd to enable the tracing.

Here is an example of a simple program called simple_trace.c that uses the initialization process described above:

    req.tv_sec = 0;
    req.tv_nsec = 1000;
    write(marker_fd, "before nano\n", 12);
    nanosleep(&req, NULL);
    write(marker_fd, "after nano\n", 11);
    write(trace_fd, "0", 1);

(No error checking was added due to this being a simple program for example purposes only.)

Here is the process to trace this simple program:

    [tracing]# echo 0 > tracing_on
    [tracing]# echo function_graph > current_tracer
    [tracing]# ~/simple_trace
    [tracing]# cat trace

The first line disables tracing because the program will enable it at start up. Next the function graph tracer is selected. The program is executed, which results in the following trace. Note that the output can be a little verbose so much of it has been cut and replaced with [...]:

    [...]
     0)               |      __kmalloc() {
     0)   0.528 us    |        get_slab();
     0)   2.271 us    |      }
     0)               |      /* before nano */
     0)               |      kfree() {
     0)   0.475 us    |        __phys_addr();
     0)   2.062 us    |      }
     0)   0.608 us    |      inotify_inode_queue_event();
     0)   0.485 us    |      __fsnotify_parent();
    [...]
     1)   0.523 us    |          _spin_unlock();
     0)   0.495 us    |    current_kernel_time();
     1)               |          it_real_fn() {
     0)   1.602 us    |  }
     1)   0.728 us    |            __rcu_read_lock();
     0)               |  sys_nanosleep() {
     0)               |    hrtimer_nanosleep() {
     0)   0.526 us    |      hrtimer_init();
     1)   0.418 us    |            __rcu_read_lock();
     0)               |      do_nanosleep() {
     1)   1.114 us    |            _spin_lock_irqsave();
    [...]
     0)               |      __kmalloc() {
     1)   2.760 us    |  }
     0)   0.556 us    |        get_slab();
     1)               |  mwait_idle() {
     0)   1.851 us    |      }
     0)               |      /* after nano */
     0)               |      kfree() {
     0)   0.486 us    |        __phys_addr();

Notice that the writes to trace_marker show up as comments in the function graph tracer.

The first column here represents the CPU. When we have the CPU traces interleaved like this, it may become hard to read the trace. The tool grep can easily filter this, or the per_cpu trace files may be used. The per_cpu trace files are located in the debugfs tracing directory under per_cpu.

    [tracing]# ls per_cpu
    cpu0  cpu1  cpu2  cpu3  cpu4  cpu5  cpu6  cpu7

There exists a trace file in each one of these CPU directories that only show the trace for that CPU.

To get a nice view of the function graph tracer without the interference of other CPUs just look at per_cpu/cpu0/trace.

    [tracing]# cat per_cpu/cpu0/trace
     0)               |      __kmalloc() {
     0)   0.528 us    |        get_slab();
     0)   2.271 us    |      }
     0)               |      /* before nano */
     0)               |      kfree() {
     0)   0.475 us    |        __phys_addr();
     0)   2.062 us    |      }
     0)   0.608 us    |      inotify_inode_queue_event();
     0)   0.485 us    |      __fsnotify_parent();
     0)   0.488 us    |      inotify_dentry_parent_queue_event();
     0)   1.106 us    |      fsnotify();
    [...]
     0)   0.721 us    |    _spin_unlock_irqrestore();
     0)   3.380 us    |  }
     0)               |  audit_syscall_entry() {
     0)   0.495 us    |    current_kernel_time();
     0)   1.602 us    |  }
     0)               |  sys_nanosleep() {
     0)               |    hrtimer_nanosleep() {
     0)   0.526 us    |      hrtimer_init();
     0)               |      do_nanosleep() {
     0)               |        hrtimer_start_range_ns() {
     0)               |          __hrtimer_start_range_ns() {
     0)               |            lock_hrtimer_base() {
     0)   0.866 us    |              _spin_lock_irqsave();
    [...]
     0)               |      __kmalloc() {
     0)               |        get_slab() {
     0)   1.851 us    |      }
     0)               |      /* after nano */
     0)               |      kfree() {
     0)   0.486 us    |        __phys_addr();

Disabling the Tracer Within the Kernel

During the development of a kernel driver there may exist strange errors that occur during testing. Perhaps the driver gets stuck in a sleep state and never wakes up. Trying to disable the tracer from user space when a kernel event occurs is difficult and usually results in a buffer overflow and loss of the relevant information before the user can stop the trace.

There are two functions that work well inside the kernel: tracing_on() and tracing_off(). These two act just like echoing "1" or "0" respectively into the tracing_on file. If there is some condition that can be checked for inside the kernel, then the tracer may be stopped by adding something like the following:

    if (test_for_error())
	    tracing_off();

Next, add several trace_printk()s (see part 1), recompile, and boot the kernel. You can then enable the function or function graph tracer and just wait for the error condition to happen. Examining the tracing_on file will let you know when the error condition occurred. It will switch from "1" to "0" when the kernel calls tracing_off().

After examining the trace, or saving it off in another file with:

cat trace > ~/trace.sav
you can continue the trace to examine another hit. To do so, just echo "1" into tracing_on, and the trace will continue. This is also useful if the condition that triggers the tracing_off()call can be triggered legitimately. If the condition was triggered by normal operation, just restart the trace by echoing a "1" back into tracing_on and hopefully the next time the condition is hit will be because of the abnormality.

ftrace_dump_on_oops

There are times that the kernel will crash and examining the memory and state of the crash is more of a CSI science than a program debugging science. Using kdump/kexec with the crashutility is a valuable way to examine the state of the system at the point of the crash, but it does not let you see what has happened prior to the event that caused the crash.

Having Ftrace configured and enabling ftrace_dump_on_oops in the kernel boot parameters, or by echoing a "1" into /proc/sys/kernel/ftrace_dump_on_oops, will enable Ftrace to dump to the console the entire trace buffer in ASCII format on oops or panic. Having the console output to a serial log makes debugging crashes much easier. You can now trace back the events that led up to the crash.

Dumping to the console may take a long time since the default Ftrace ring buffer is over a megabyte per CPU. To shrink the size of the ring buffer, write the number of kilobytes you want the ring buffer to be to buffer_size_kb. Note that the value is per CPU, not the total size of the ring buffer.

    [tracing]# echo 50 > buffer_size_kb
The above will shrink the Ftrace ring buffer down to 50 kilobytes per CPU.

You can also trigger a dump of the Ftrace buffer to the console with sysrq-z.

To choose a particular location for the kernel dump, the kernel may call ftrace_dump() directly. Note, this may permanently disable Ftrace and a reboot may be necessary to enable it again. This is because ftrace_dump() reads the buffer. The buffer is made to be written to in all contexts (interrupt, NMI, scheduling) but the reading of the buffer requires locking. To be able to perform ftrace_dump() the locking is disabled and the buffer may end up being corrupted after the output.

    /*
     * The following code will lock up the box, so we dump out the
     * trace before we hit that location.
     */
    ftrace_dump();

    /* code that locks up */

Stack Tracing

The final topic to discuss is the ability to examine the size of the kernel stack and how much stack space each function is using. Enabling the stack tracer (CONFIG_STACK_TRACER) will show where the biggest use of the stack takes place.

The stack tracer is built from the function tracer infrastructure. It does not use the Ftrace ring buffer, but it does use the function tracer to hook into every function call. Because it uses the function tracer infrastructure, it does not add overhead when not enabled. To enable the stack tracer, echo 1 into /proc/sys/kernel/stack_tracer_enabled. To see the max stack size during boot up, add "stacktrace" to the kernel boot parameters.

The stack tracer checks the size of the stack at every function call. If it is greater than the last recorded maximum, it records the stack trace and updates the maximum with the new size. To see the current maximum, look at the stack_max_size file.

    [tracing]# echo 1 > /proc/sys/kernel/stack_tracer_enabled
    [tracing]# cat stack_max_size
    2928
    [tracing]# cat stack_trace
            Depth    Size   Location    (34 entries)
            -----    ----   --------
      0)     2952      16   mempool_alloc_slab+0x15/0x17
      1)     2936     144   mempool_alloc+0x52/0x104
      2)     2792      16   scsi_sg_alloc+0x4a/0x4c [scsi_mod]
      3)     2776     112   __sg_alloc_table+0x62/0x103
    [...]
     13)     2072      48   __elv_add_request+0x98/0x9f
     14)     2024     112   __make_request+0x43e/0x4bb
     15)     1912     224   generic_make_request+0x424/0x471
     16)     1688      80   submit_bio+0x108/0x115
     17)     1608      48   submit_bh+0xfc/0x11e
     18)     1560     112   __block_write_full_page+0x1ee/0x2e8
     19)     1448      80   block_write_full_page_endio+0xff/0x10e
     20)     1368      16   block_write_full_page+0x15/0x17
     21)     1352      16   blkdev_writepage+0x18/0x1a
     22)     1336      32   __writepage+0x1a/0x40
     23)     1304     304   write_cache_pages+0x241/0x3c1
     24)     1000      16   generic_writepages+0x27/0x29
    [...]
     30)      424      64   bdi_writeback_task+0x3f/0xb0
     31)      360      48   bdi_start_fn+0x76/0xd7
     32)      312     128   kthread+0x7f/0x87
     33)      184     184   child_rip+0xa/0x20

Not only does this give you the size of the maximum stack found, it also shows the breakdown of the stack sizes used by each function. Notice that write_cache_pages had the biggest stack with 304 bytes being used, followed by generic_make_request with 224 bytes of stack.

To reset the maximum, echo "0" into the stack_max_size file.

    [tracing]# echo 0 > stack_max_size

Keeping this running for a while will show where the kernel is using a bit too much stack. But remember that the stack tracer only has no overhead when it is not enabled. When it is running you may notice a bit of a performance degradation.

Note that the stack tracer will not trace the max stack size when the kernel is using a separate stack. Because interrupts have their own stack, it will not trace the stack usage there. The reason is that currently there is no easy way to quickly see what the top of the stack is when the stack is something other than the current task's stack. When using split stacks, a process stack may be two pages but the interrupt stack may only be one. This may be fixed in the future, but keep this in mind when using the stack tracer.

Conclusion

Ftrace is a very powerful tool and easy to configure. No extra tools are necessary. Everything that was shown it this tutorial can be used on embedded devices that only have Busybox installed. Taking advantage of the Ftrace infrastructure should cut the time needed to debug that hard-to-find race condition. I seldom use printk() any more because using the function and function graph tracers along with trace_printk() and tracing_off() have become my main tools for debugging the Linux kernel.

Trackback 0 Comment 0
2010/01/14 11:15

Debugging the kernel using Ftrace - part 1

December 9, 2009

This article was contributed by Steven Rostedt


from LWN:http://lwn.net/Articles/365835/

Ftrace is a tracing utility built directly into the Linux kernel. Many distributions already have various configurations of Ftrace enabled in their most recent releases. One of the benefits that Ftrace brings to Linux is the ability to see what is happening inside the kernel. As such, this makes finding problem areas or simply tracking down that strange bug more manageable.

Ftrace's ability to show the events that lead up to a crash gives a better chance of finding exactly what caused it and can help the developer in creating the correct solution. This article is a two part series that will cover various methods of using Ftrace for debugging the Linux kernel. This first part will talk briefly about setting up Ftrace, using the function tracer, writing to the Ftrace buffer from within the kernel, and various ways to stop the tracer when a problem is detected.

Ftrace was derived from two tools. One was the "latency tracer" by Ingo Molnar used in the -rt tree. The other was my own "logdev" utility that had its primary use on debugging the Linux kernel. This article will mostly describe features that came out of logdev, but will also look at the function tracer that originated in the latency tracer.

Setting up Ftrace

Currently the API to interface with Ftrace is located in the Debugfs file system. Typically, that is mounted at /sys/kernel/debug. For easier accessibility, I usually create a /debugdirectory and mount it there. Feel free to choose your own location for Debugfs.

When Ftrace is configured, it will create its own directory called tracing within the Debugfs file system. This article will reference those files in that directory as though the user first changed directory to the Debugfs tracing directory to avoid any confusion as to where the Debugfs file system has been mounted.

    [~]# cd /sys/kernel/debug/tracing
    [tracing]#

This article is focusing on using Ftrace as a debugging tool. Some configurations for Ftrace are used for other purposes, like finding latency or analyzing the system. For the purpose of debugging, the kernel configuration parameters that should be enabled are:

    CONFIG_FUNCTION_TRACER
    CONFIG_FUNCTION_GRAPH_TRACER
    CONFIG_STACK_TRACER
    CONFIG_DYNAMIC_FTRACE

Function tracing - no modification necessary

One of the most powerful tracers of Ftrace is the function tracer. It uses the -pg option of gcc to have every function in the kernel call a special function "mcount()". That function must be implemented in assembly because the call does not follow the normal C ABI.

When CONFIG_DYNAMIC_FTRACE is configured the call is converted to a NOP at boot time to keep the system running at 100% performance. During compilation the mcount() call-sites are recorded. That list is used at boot time to convert those sites to NOPs. Since NOPs are pretty useless for tracing, the list is saved to convert the call-sites back into trace calls when the function (or function graph) tracer is enabled.

It is highly recommended to enable CONFIG_DYNAMIC_FTRACE because of this performance enhancement. In addition, CONFIG_DYNAMIC_FTRACE gives the ability to filter which function should be traced. Note, even though the NOPs do not show any impact in benchmarks, the addition of frame pointers that come with the -pg option has been known to cause a slight overhead.

To find out which tracers are available, simply cat the available_tracers file in the tracing directory:

    [tracing]# cat available_tracers 
    function_graph function sched_switch nop

To enable the function tracer, just echo "function" into the current_tracer file.

    [tracing]# echo function > current_tracer
    [tracing]# cat current_tracer
    function

    [tracing]# cat trace | head -10
    # tracer: function
    #
    #           TASK-PID    CPU#    TIMESTAMP  FUNCTION
    #              | |       |          |         |
                bash-16939 [000]  6075.461561: mutex_unlock <-tracing_set_tracer
              <idle>-0     [001]  6075.461561: _spin_unlock_irqrestore <-hrtimer_get_next_event
              <idle>-0     [001]  6075.461562: rcu_needs_cpu <-tick_nohz_stop_sched_tick
                bash-16939 [000]  6075.461563: inotify_inode_queue_event <-vfs_write
              <idle>-0     [001]  6075.461563: mwait_idle <-cpu_idle
                bash-16939 [000]  6075.461563: __fsnotify_parent <-vfs_write

The header explains the format of the output pretty well. The first two items are the traced task name and PID. The CPU that the trace was executed on is within the brackets. The timestamp is the time since boot, followed by the function name. The function in this case is the function being traced with its parent following the "<-" symbol.

This information is quite powerful and shows the flow of functions nicely. But it can be a bit hard to follow. The function graph tracer, created by Frederic Weisbecker, traces both the entry and exit of a function, which gives the tracer the ability to know the depth of functions that are called. The function graph tracer can make following the flow of execution within the kernel much easier to follow with the human eye:

    [tracing]# echo function_graph > current_tracer 
    [tracing]# cat trace | head -20
    # tracer: function_graph
    #
    # CPU  DURATION                  FUNCTION CALLS
    # |     |   |                     |   |   |   |
     1)   1.015 us    |        _spin_lock_irqsave();
     1)   0.476 us    |        internal_add_timer();
     1)   0.423 us    |        wake_up_idle_cpu();
     1)   0.461 us    |        _spin_unlock_irqrestore();
     1)   4.770 us    |      }
     1)   5.725 us    |    }
     1)   0.450 us    |    mutex_unlock();
     1) + 24.243 us   |  }
     1)   0.483 us    |  _spin_lock_irq();
     1)   0.517 us    |  _spin_unlock_irq();
     1)               |  prepare_to_wait() {
     1)   0.468 us    |    _spin_lock_irqsave();
     1)   0.502 us    |    _spin_unlock_irqrestore();
     1)   2.411 us    |  }
     1)   0.449 us    |  kthread_should_stop();
     1)               |  schedule() {

This gives the start and end of a function denoted with the C like annotation of "{" to start a function and "}" at the end. Leaf functions, which do not call other functions, simply end with a ";". The DURATION column shows the time spent in the corresponding function. The function graph tracer records the time the function was entered and exited and reports the difference as the duration. These numbers only appear with the leaf functions and the "}" symbol. Note that this time also includes the overhead of all functions within a nested function as well as the overhead of the function graph tracer itself. The function graph tracer hijacks the return address of the function in order to insert a trace callback for the function exit. This breaks the CPU's branch prediction and causes a bit more overhead than the function tracer. The closest true timings only occur for the leaf functions.

The lonely "+" that is there is an annotation marker. When the duration is greater than 10 microseconds, a "+" is shown. If the duration is greater than 100 microseconds a "!" will be displayed.

Using trace_printk()

printk() is the king of all debuggers, but it has a problem. If you are debugging a high volume area such as the timer interrupt, the scheduler, or the network, printk() can lead to bogging down the system or can even create a live lock. It is also quite common to see a bug "disappear" when adding a few printk()s. This is due to the sheer overhead thatprintk() introduces.

Ftrace introduces a new form of printk() called trace_printk(). It can be used just like printk(), and can also be used in any context (interrupt code, NMI code, and scheduler code). What is nice about trace_printk() is that it does not output to the console. Instead it writes to the Ftrace ring buffer and can be read via the trace file.

Writing into the ring buffer with trace_printk() only takes around a tenth of a microsecond or so. But using printk(), especially when writing to the serial console, may take several milliseconds per write. The performance advantage of trace_printk() lets you record the most sensitive areas of the kernel with very little impact.

For example you can add something like this to the kernel or module:

    trace_printk("read foo %d out of bar %p\n", bar->foo, bar);

Then by looking at the trace file, you can see your output.

    [tracing]# cat trace
    # tracer: nop
    #
    #           TASK-PID    CPU#    TIMESTAMP  FUNCTION
    #              | |       |          |         |
               <...>-10690 [003] 17279.332920: : read foo 10 out of bar ffff880013a5bef8

The above example was done by adding a module that actually had a foo and bar construct.

trace_printk() output will appear in any tracer, even the function and function graph tracers.

    [tracing]# echo function_graph > current_tracer
    [tracing]# insmod ~/modules/foo.ko
    [tracing]# cat trace
    # tracer: function_graph
    #
    # CPU  DURATION                  FUNCTION CALLS
    # |     |   |                     |   |   |   |
     3) + 16.283 us   |      }
     3) + 17.364 us   |    }
     3)               |    do_one_initcall() {
     3)               |      /* read foo 10 out of bar ffff88001191bef8 */
     3)   4.221 us    |    }
     3)               |    __wake_up() {
     3)   0.633 us    |      _spin_lock_irqsave();
     3)   0.538 us    |      __wake_up_common();
     3)   0.563 us    |      _spin_unlock_irqrestore();

Yes, the trace_printk() output looks like a comment in the function graph tracer.

Starting and stopping the trace

Obviously there are times where you only want to trace a particular code path. Perhaps you only want to trace what is happening when you run a specific test. The file tracing_on is used to disable the ring buffer from recording data:

    [tracing]# echo 0 > tracing_on

This will disable the Ftrace ring buffer from recording. Everything else still happens with the tracers and they will still incur most of their overhead. They do notice that the ring buffer is not recording and will not attempt to write any data, but the calls that the tracers make are still performed.

To re-enable the ring buffer, simply write a '1' into that file:

    [tracing]# echo 1 > tracing_on

Note, it is very important that you have a space between the number and the greater than sign ">". Otherwise you may be writing standard input or output into that file.

    [tracing]# echo 0> tracing_on   /* this will not work! */

A common run might be:

    [tracing]# echo 0 > tracing_on
    [tracing]# echo function_graph > current_tracer
    [tracing]# echo 1 > tracing_on; run_test; echo 0 > tracing_on

The first line disables the ring buffer from recording any data. The next enables the function graph tracer. The overhead of the function graph tracer is still present but nothing will be recorded into the trace buffer. The last line enables the ring buffer, runs the test program, then disables the ring buffer. This narrows the data stored by the function graph tracer to include mostly just the data accumulated by the run_test program.

What's next?

The next article will continue the discussion on debugging the kernel with Ftrace. The method above to disable the tracing may not be fast enough. The latency between the end of the program run_test and echoing the 0 into the tracing_on file may cause the ring buffer to overflow and lose the relevant data. I will discuss other methods to stop tracing a bit more efficiently, how to debug a crash, and looking at what functions in the kernel are stack hogs. The best way to find out more is to enable Ftrace and just play with it. You can learn a lot about how the kernel works by just following the function graph tracer.



Trackback 0 Comment 0
2009/11/18 11:21

안드로이드 커널 버전

Linux 2 6 27

Linux 2.6.27 kernel released 9 October 2008.

Summary: 2.6.27 add a new filesystem (UBIFS) optimized for "pure" flash-based storage devices, the page-cache is now lockless, much improved Direct I/O scalability and performance, delayed allocation for ext4, multiqueue networking, an alternative hibernation implementation based on kexec/kdump, data integrity support in the block layer for devices that support it, a simple tracer called ftrace, a mmio tracer, sysprof support, extraction of all the in-kernel's firmware to /lib/firmware, XEN support for saving/restorig VMs, improved video camera support, support for the Intel wireless 5000 series and RTL8187B network cards, a new ath9k driver for the Atheros AR5008 and AR9001 family of chipsets, more new drivers, improved support for others and many other improvements and fixes.


Linux 2 6 28

Linux 2.6.28 kernel released on 25 December, 2008.

Summary: Linux 2.6.28 adds the first version of Ext4 as a stable filesystem, the much-expected GPU memory manager which will be the foundation of a renewed graphic stack, support for Ultra Wide Band (Wireless USB, UWB-IP), memory management scalability and performance improvements, a boot tracer, disk shock protection, the phonet network protocol, support of SSD discard requests, transparent proxy support, several new network drivers, controlable IO CPU affinity, high-resolution poll()/select(), support of a minimal "dummy" policy in SELinux, tracing improvements, x86 x2APIC support, a fb driver for VIA UniChrome devices, Mitac Mio A701 ARM-based smartphone support, some new drivers, improved device support, and many other small improvements and fixes.


Linux 2 6 29

Linux 2.6.29 kernel released on 23 March, 2009.

Summary: Linux 2.6.29 adds kernel based graphic mode setting, WiMAX support, Access Point support in the wifi stack, the inclusion of the btrfs and squashfs filesystems, ecryptfs filename encryption, ext4 no journaling mode, ocfs2 metadata checksums, a more scalable RCU implementation, filesystem freeze support, swap management in the memory controller, many new drivers and many other improvements.


 2.6.29 based Android Kernel (sep, 2009)

------------------------------------ 

Belows is kernel feature for 2.6.29 based android kernel. 

01). GoldFish : Qemutrace , FB Driver/RTC/Power/Nand/MMC/Events/tty/
audio for godlfish
02). pmem : Android pmem allocator
03). yaffs : mtdif2
04). kernel debugger
05). android USB : USB Gadget driver for android.
06). HAL : TI Wifi Control Functions , Bluetooth (RFCOMM-L2CAP Socket)
07). Android Shared Memory (ASHMEM)
08). Paranoid  Network
09). Binder: mmap fix , more offset validation
10). Power : User Wake Lock , Wake Lock , Early Suspend , FB
Eearlysuspend
11). Logger Subsystem
12). Low Memory Killer: /sys/module/lowmemorykiller/parameters/adj and
minfree
11). Etc : Timed GPIO / Timed Output 


Trackback 0 Comment 0