Wednesday, October 12, 2011

Perl script to find Broken Symbolic links

Creating Symbolic links across filesystem are very handy but at the same time, they can be a real pain when they got broken. At my work I often seen Developers wasting their time in fixing application issues, which was fundamentally caused by broken symbolic links. So I came out with this script.

Upon execution of this script, it will prompt you to enter the filesystem paths as parameters. Once done, it will report all the broken symbolic links with count number.

I used the Perl module File::Find (comes default with any Perl package) for traversing through all the filenames in the specified directories and report the broken links. For each file it finds, it calls the &wanted subroutine, which in turn uses the Stat function to match the symbolic link files which are broken. To be honest, I grabbed this logic from an online book on Perl programming.

Supported platforms: Any Unix platform with Perl version 5.x installed.

EXAMPLE
[root@hostxyz opt]# perl check_broken_link.pl

Enter the filesystem path (like /etc /opt /var) : /var /etc /usr /home
Disconnected Link => /var/lib/jbossas/server/production/lib/jboss-remoting.jar -> /usr/share/java/jboss-remoting.jar
Disconnected Link => /var/lib/jbossas/server/default/lib/jboss-remoting.jar -> /usr/share/java/jboss-remoting.jar
Disconnected Link => /etc/alternatives/jaxws_api -> /usr/share/java/glassfish-jaxws.jar
Disconnected Link => /etc/alternatives/jaxws_2_1_api -> /usr/share/java/glassfish-jaxws.jar
Disconnected Link => /etc/alternatives/jaxb_2_1_api -> /usr/share/java/glassfish-jaxb.jar
Disconnected Link => /etc/alternatives/jaxb_api -> /usr/share/java/glassfish-jaxb.jar
Disconnected Link => /usr/share/java/jaxws_api.jar -> /etc/alternatives/jaxws_api
Disconnected Link => /usr/share/java/jaxb_api.jar -> /etc/alternatives/jaxb_api
Disconnected Link => /usr/share/java/jaxws_2_1_api.jar -> /etc/alternatives/jaxws_2_1_api
Disconnected Link => /usr/share/jbossas/client/jboss-remoting.jar -> /usr/share/java/jboss-remoting.jar

Total number of Disconnected links: 10
[root@hostxyz opt]# 

SCRIPT

#!/usr/bin/perl
use File::Find ();
use vars qw/*name *dir *prune/;
my ($cnt,$i,$cnt_sub) = (0,0,0);
print "\n";
*name = *File::Find::name;
*dir = *File::Find::dir;
*prune = *File::Find::prune;
print "Enter the filesystem path (like /etc /opt /var) : ";
my $arr = <>;
chomp($arr);
print "\n";
my @inpts = split(/ /, $arr);


foreach(@inpts)
{

File::Find::find({wanted => \&wanted}, $inpts[$i] ); # Calling wanted subroutine which use stat function to match broken links
$cnt = $cnt_sub + $cnt;
$i++;
$cnt_sub = 0;
}
print "Total number of Disconnected links: $cnt \n\n";


sub wanted {
if (-l $_) {
@stat = stat($_);
if ($#stat == -1)
{
$flname = `ls -l $name`;
($flperm, $numlnk, $flown1, $flown2, $dt, $mnth, $tm1, $tm2, $cfnm, $ar, $dsfl) = split /\s+/, $flname;
print "Disconnected Link => $cfnm $ar $dsfl\n\n";
$cnt_sub++;
  }
 }
}

Listing all Linux servers which are up in a network


Situation:
Suppose you want to find all the servers which are Up in Network or in a range of IPs.  We may need this information for trouble-shooting purpose like fixing IP conflicts or to get an idea about how many servers are online at a given point of time.


Solution:
# nmap -v -sP  
The network info can be given as a whole network (say 10.10.22.0/24) or as a range (say 10.10.22.1-40).


Example:
[root@gtxash01 ~]# nmap -v -sP 10.10.22.1-40      ß  Scans servers in the IP range of 10.10.22.1 to 10.10.22.40
Starting Nmap 4.11 ( http://www.insecure.org/nmap/ ) at 2010-10-14 06:09 CDT
DNS resolution of 25 IPs took 5.50s.
Host 10.10.22.1 appears to be up.
Host 10.10.22.2 appears to be up.
Host 10.10.22.3 appears to be down.
Host 10.10.22.4 appears to be down.
Host 10.10.22.5 appears to be down.
Host 10.10.22.6 appears to be down.
Host 10.10.22.7 appears to be down.
Host 10.10.22.8 appears to be down.
Host 10.10.22.9 appears to be down.
Host 10.10.22.10 appears to be down.
Host 10.10.22.11 appears to be down.
Host rwbcat01.tcprod.local (10.10.22.12) appears to be up.
Host 10.10.22.13 appears to be down.
Host rsarash01.tcprod.local (10.10.22.14) appears to be up.
Host rdbash01.tcprod.local (10.10.22.15) appears to be up.
Host 10.10.22.16 appears to be down.
Host 10.10.22.17 appears to be down.
Host 10.10.22.18 appears to be down.
Host 10.10.22.19 appears to be down.
Host xenlashb1.tcprod.net (10.10.22.20) appears to be up.
Host webash04.tcprod.net (10.10.22.21) appears to be up.
Host webash23.tcprod.net (10.10.22.22) appears to be up.
Host xenc1bx-ih.tcprod.net (10.10.22.23) appears to be up.
.
< Output truncated >
.
Host gdsash02.tcprod.local (10.10.22.39) appears to be up.
Host 10.10.22.40 appears to be down.
Nmap finished: 40 IP addresses (25 hosts up) scanned in 6.178 seconds
               Raw packets sent: 110 (3740B) | Rcvd: 50 (2300B)


[root@gtxash01 ~]# nmap -v -sP 10.10.22.0/24  | grep up   # Scans servers in entire 10.10.22.0 network

Starting Nmap 4.11 ( http://www.insecure.org/nmap/ ) at 2010-10-14 06:10 CDT
DNS resolution of 53 IPs took 5.50s.
Host 10.10.22.0 seems to be a subnet broadcast address (returned 1 extra pings).
Host 10.10.22.1 appears to be up.
Host 10.10.22.2 appears to be up.
.
< Output truncated >
.
Host 10.10.22.243 appears to be up.
Host 10.10.22.244 appears to be up.
Host l2ash.tcprod.local (10.10.22.250) appears to be up.
Host l22ash.tcprod.local (10.10.22.251) appears to be up.
Host 10.10.22.255 seems to be a subnet broadcast address (returned 1 extra pings).
Nmap finished: 256 IP addresses (53 hosts up) scanned in 7.755 seconds
               Raw packets sent: 914 (31.076KB) | Rcvd: 108 (4968B)
[root@gtxash01 ~]#

Capturing everything that scrolls on your Linux terminal


In many circumstances, we might want to capture all the messages that scrolls on your terminal. This we may require to review details about installations or deployments or to analyze some problem on the server. And this can be used to submit as a proof to Management. 

Here is an example.

“script” is the command used for this purpose and the syntax goes like this:

# script    or just  script

Whatever the filename specified after script command will gets created and that will capture everything. If you just execute the command “script”, then all the messages will be captured by the default file “typescript” as shown below:

[adevaraju@sys01 ~]$ script
Script started, file is typescript
[adevaraju@sys01 ~]$


[root@sys01 rmanbackp]# script capture_my_work        ß All the messages that appears on the screen will be captured by the file “capture_my_work”
Script started, file is capture_my_work
[root@sys01 rmanbackp]#
.
.
.
.
[root@sys01 ~]# set | grep SHLVL                                     
SHLVL=2                                                                   ß Please observe executing ‘script’ command will take one shell level up.
[root@sys01 ~]#
[root@sys01 rmanbackp]# exit
exit
Script done, file is capture_my_work
[root@sys01 rmanbackp]#
[root@sysllm01 ~]# set | grep SHLVL
SHLVL=1                                                                ß Shell level become 1 now (the base level)
[root@sys01 ~]#


Type “exit” when you want to stop capturing. By typing “exit” once, you will not thrown out of shell prompt since you will be in Shell level 2.

Copying only missing files on destination folder


Let’s say you have a requirement to copy the contents of folder to another but only the files which AREN’T present in the destination folder. Use the cp command with ‘-aru’ option. You got to notice certain things while doing this; it is explained with the below example here which is self-explanatory.

In this example, you got to just notice the time-stamp of each files created under the folder /dir1 & /dir2.

[root@host01 ~]# mkdir /dir1 /dir2
[root@host01 ~]# cd /dir1
[root@host01 dir1]#
[root@host01 dir1]# touch a b c d e f; mkdir d1 d2        
[root@host01 dir1]# touch d1/file1 d1/file2
[root@host01 dir1]# touch d2/take1 d2/take2
[root@host01 dir1]# ls -lR /dir1                                     ß Using -lR option to list the sub-folder contents of /dir1
/dir1:
total 8
-rw-r--r-- 1 root root    0 Dec  9 12:18 a
-rw-r--r-- 1 root root    0 Dec  9 12:18 b
-rw-r--r-- 1 root root    0 Dec  9 12:18 c
-rw-r--r-- 1 root root    0 Dec  9 12:18 d
drwxr-xr-x 2 root root 4096 Dec  9 12:18 d1
drwxr-xr-x 2 root root 4096 Dec  9 12:19 d2
-rw-r--r-- 1 root root    0 Dec  9 12:18 e
-rw-r--r-- 1 root root    0 Dec  9 12:18 f

/dir1/d1:
total 0
-rw-r--r-- 1 root root 0 Dec  9 12:18 file1
-rw-r--r-- 1 root root 0 Dec  9 12:18 file2

/dir1/d2:
total 0
-rw-r--r-- 1 root root 0 Dec  9 12:19 take1
-rw-r--r-- 1 root root 0 Dec  9 12:19 take2

[root@host01 dir1]#
[root@host01 dir1]# cd /dir2
[root@host01 dir2]# touch b d f Z; mkdir d1
[root@host01 dir2]# touch d1/key1 d1/key2
[root@host01 dir2]# ls -lR /dir2
/dir2:
total 4
-rw-r--r-- 1 root root    0 Dec  9 12:20 b
-rw-r--r-- 1 root root    0 Dec  9 12:20 d
drwxr-xr-x 2 root root 4096 Dec  9 12:20 d1
-rw-r--r-- 1 root root    0 Dec  9 12:20 f
-rw-r--r-- 1 root root    0 Dec  9 12:20 Z

/dir2/d1:
total 0
-rw-r--r-- 1 root root 0 Dec  9 12:20 key1
-rw-r--r-- 1 root root 0 Dec  9 12:20 key2
[root@host01 dir2]# cp -aru /dir1/* /dir2
[root@host01 dir2]# ls -lR /dir2
/dir2:
total 8
-rw-r--r-- 1 root root    0 Dec  9 12:18 a
-rw-r--r-- 1 root root    0 Dec  9 12:20 b
-rw-r--r-- 1 root root    0 Dec  9 12:18 c
-rw-r--r-- 1 root root    0 Dec  9 12:20 d
drwxr-xr-x 2 root root 4096 Dec  9 12:18 d1
drwxr-xr-x 2 root root 4096 Dec  9 12:19 d2
-rw-r--r-- 1 root root    0 Dec  9 12:18 e
-rw-r--r-- 1 root root    0 Dec  9 12:20 f
-rw-r--r-- 1 root root    0 Dec  9 12:20 Z


/dir2/d1:
total 0
-rw-r--r-- 1 root root 0 Dec  9 12:18 file1
-rw-r--r-- 1 root root 0 Dec  9 12:18 file2
-rw-r--r-- 1 root root 0 Dec  9 12:20 key1
-rw-r--r-- 1 root root 0 Dec  9 12:20 key2

/dir2/d2:
total 0
-rw-r--r-- 1 root root 0 Dec  9 12:19 take1
-rw-r--r-- 1 root root 0 Dec  9 12:19 take2
[root@host01 dir2]#

Conclusion on executing cp command with -aru option:
1. Files with same names (b, d & f ) were left un-touched. You can confirm it by timestamps of those files (12.20).
2. It copied all the missing files (a , c & e ) and missing folder (d2) on to the destination folder /dir2.
3. The file ‘Z’ which present only on /dir2 remains same. It haven’t got deleted
4. Contents of folder “d1” which is present both in source and destination folder is retained, however it copied the files (key1 & key2) which are present in /dir1 folder. So it didn’t replace the d1 folder on destination.

Usage: Use this option when incase the copy which you initiated before got interrupted for some reason. Using this you need not to copy it over again by typing “yes” for over-writing the existing files which are copied before.

Port numbers in Linux


Ports in computer networking is an application-specific or process-specific software construct serving as a communications endpoint. It is used by Transport Layer protocols of the Internet Protocol Suite, such as Transmission Control Protocol (TCP) and User Datagram Protocol (UDP). A specific port is identified by its number, commonly known as the port number, the IP address with which it is associated, and the protocol used for communication.
The Internet Assigned Numbers Authority (IANA) is responsible for maintaining the official assignments of port numbers for specific uses. However, many unofficial uses of both well-known and registered port numbers occur in practice.

The port numbers are divided into three ranges:

Well-Known/Standard Ports   (Range: 0 to 1023 )
Used by system processes that provide widely-used types of network services such as SSH, Telnet, SMTP, FTP etc

Registered Ports, and    (Range:  1024 to 49151 )
Used by specific service upon applications such as Oracle database listener (1521), MySql (3306), Microsoft Terminal server (3389) etc.

Dynamic and/or Private Ports. (Range: 49152 to 65535 )
These ports can’t be registered by IANA.  This is used for custom or temporary purposes and for automatic allocation of short-lived (or ephemeral ) ports which is used internally by application/processes. You can see these ports by running ‘netstat’ command under “Local address” column.


In Linux, the port details can be viewed by checking the /etc/services file  and the non-standard (un-registered) ports used by the server can be find using /proc/sys/net/ipv4/ip_local_port_range file.

[suresh@host01 ~]$ cat /proc/sys/net/ipv4/ip_local_port_range
32768   61000
[suresh@host01 ~]$

Resolving Too many files open error in Linux


Situation:
Users couldn't execute *ANY* commands. It gives "Too many open files" error as shown below:

orabi@miaash02-t1$ top
ksh: top: /usr/bin/top: cannot execute [Too many open files in system]
dwilliams@miaash02-t1$ ls -l
ksh: ls: /bin/ls: cannot execute [Too many open files in system]


Reason:
Everything in Linux are files; Linux forks most things including devices, sockets and pipes as files.  There is a kernel parameter called “file-max” which controls the maximum number of files that can be opened in a system. The default value is 65K (approx), can be find using the following command:
“sysctl -a | grep file-max”.
To check the count of number of files open, we can use the following command: “lsof | wc –l”. However this will not give you the exact number, because it is possible for a single file to be opened multiple times for readind and each additional concurrent open will increase the count for file-max value.  And in addition even connections to network ports can eat up the ‘file-max’ value.

Resolution:
As a temporary solution, we can increase the ‘file-max’ value by issuing the following command:
# echo “value” > /proc/sys/fs/file-max and then we need to identify the problem by analyzing either the System logs or by using lsof command itself with appropriate options. 

12 Most Useful Google Chrome Browser chrome:// Commands


To get to the Menu on Google Chrome browser, click on the “Wrench” icon on the top right-hand corner. From here you can access certain browser features.
However, there are several features that are not available from the Menu, which you can access only using the chrome:// commands. Some of the features are available under both Menu and chrome:// commands.
Following are the 12 most helpful chrome:// commands that you should know.

1. chrome://flags

From here you can enable some of the experimental features that are hidden in the google Chrome browser. Please note that as mentioned on this page, since these are experimental, these might not work as expected and might cause issues. Enable these features and use it at your own risk.

2. chrome://dns

This displays the list of hostnames for which the browser will prefetch the DNS records.

3. chrome://downloads

This is also available from the Menu -> Downloads. Short cut key is Ctrl+J

4. chrome://extensions

This is also available from the Menu -> Tools -> Extensions

5. chrome://bookmarks

This is also available from the Menu -> Bookmarks -> Bookmark Manager. Short cut key is Ctrl+Shift+O

6. chrome://history

This is also availble from the Menu -> History. Short cut key is Ctrl+H

7. chrome://memory

This will redirect to “chrome://memory-redirect/”. This will display the memory used by Google chrome browser, and all other browsers running on the system (including firefox).
This also display all the process related to browser with their PID, process name, and the memory it takes.

8. chrome://net-internals

This displays all networking related information. Use this to capture network events generated by the browser. You can also export this data. You can view DNS host resolver cache.
One of the important feature in this feature is “Test”. If a URL failed to load, you can go to “chrome://net-internals” -> click on “Tests” tab -> type that URL which failed, and click on “Start Test”, which will do some test and report you why that URL failed.
chrome://plugins/

9. chrome://quota-internals

This gives information about the disk space quote used by the browser, including the break down of how much space the individual websites took under temporary files.

10. chrome://sessions

This displays the number of sessions and magic list that are currently running.

11. chrome://settings

This is also available from the Menu -> Options (on Windows), and Menu -> Preferences (on Linux). From here you can control various browser related settings.

12. chrome://sync-internals

This gives information about the chrome sync feature, including the Sync URL used by google, and sync statistics.
Finally, to view all the available chrome:// commands, type chrome://about/ in your chrome browser URL as shown below.
Also, please note that all of the commands mentioned above can also be called using google chrome about command, which redirects to chrome://.
For example, both of the following are exactly the same.
about:dns
chrome://dns

What is Orphan Process?

It’s a pretty much common question asked in most of the interviews related to Linux, and most of the time people got it confused with Zombie Process. But these two are totally different from each other. An Orphan Process is nearly the same thing which we see in real world. Orphan means someone whose parents are dead. The same way Orphan process is a process, whose parents are dead, that means parents are either terminated, killed or exited but the child process is still alive.
In Linux/Unix like operating systems, as soon as parents of any process are dead, re-parenting occurs, automatically. Re-parenting means processes whose parents are dead, means Orphaned processes, are immediately adopted by special process “init”. Thing to notice here is that even after re-parenting, the process still remains Orphan as the parent which created the process is dead,
Reasons for Orphan Processes:
A process can be orphaned either intentionally or unintentionally. Sometime a parent process exits/terminates or crashes leaving the child process still running, and then they become orphan processes.
Also, a process can be intentionally orphaned just to keep it running. For example when you need to run a job in the background which don’t need any manual intervention and going to take long time, then you detach it from user session and leave it there. Same way, when you need to run a process in the background for infinite time, you need to do the same thing. Processes running in the background like this are known as daemon process.
At the same time, when a client connects to a remote server and initiated a process, and due to some reason the client crashes unexpectedly, the process on the server becomes Orphan.
Finding a Orphan Process:
It’s very easy to spot a Orphan process. Orphan process is a user process, which is having init (process id – 1) as parent. You can use this command in linux to find the Orphan processes.
# ps -elf | head -1; ps -elf | awk '{if ($5 == 1 && $3 != "root") {print $0}}' | head
This will show you all the orphan processes running in your system. The output from this command confirms that they are Orphan processes but doesn’t mean that they are all useless, so confirm from some other source also before killing them.
Killing a Orphan Process:
As orphaned processes waste server resources, so it’s not advised to have lots of orphan processes running into the system. To kill a orphan process is same as killing a normal process.
# kill -15 
If that don’t work then simply use
# kill -9 

FAQs:

Q. Is Orphan process different from an Zombie process ?
A. Yes, Orphan process are totally different from Zombie processes. Zombie processes are the ones which are not alive but still have entry in parent table. For more details, please refer to —Zombie Processes.
Q. Are Orphan processes harmful for system ?
A. Yes. Orphan processes take resources while they are in the system, and can potentially leave a server starved for resources. Having too many Orphan processes will overload the init process and can hang-up a Linux system. We can say that a normal user who has access to your Linux server is capable to easily kill your Linux server in a  minute.

What is a Zombie Process ?

It’s a pretty much common question asked in most of the interviews related to Linux, and most of the time people got it confused with Orphan Process. But these two are totally different from each other. A Zombie Process is nearly the same thing which we see in lot of horror movies. Like the dead people which don’t have any life force left, Zombie processes are the dead processes sitting in the process table and doing nothing.
To explain this in much better way, “Zombie process or defunct process is a process that have completed the execution, have released all the resources (CPU, memory) but still had an entry in the process table.”

Reasons of Zombie Process:

Most of the time, the reason for existence of Zombie process is bad coding. Normally, when a child (subprocess) finishes it’s task and exits, then it’s parent is suppose to use the “wait” system call and get the status of the process. So, until the parent process don’t check for the child’s exit status, the process is a Zombie process, but it usually is very small duration. But if due to any reason (bad programming or a bug), the parent process didn’t check the status of the child and don’t call “wait”, the child process stays in the state of Zombie waiting for parent to check it’s status.

Finding Zombie processes:

To check whether you have any Zombie processes in your system, simply run linux command line utility “top”. It shows the number of zombie processes at the upper-right side of its output.
At the same time, you can use one more command to check that
# ps aux
All the processes which are having “z” in their Stat column are Zombie processes.

Killing a Zombie Process:

Well, before taking any decision of killing the Zombie process, you should wait, as it is possible that the parent process is intentionally leaving the process in a zombie state to ensure that future children that it may create will not receive the same pid. Or perhaps the parent is occupied, and will reap the child process momentarily.
If that didn’t happen then you can send a SIGCHLD signal to the parent process of zombie which will instruct parents to reap their zombie children.
# kill -s SIGCHLD 
Even if this don’t work, then the last option you will have is to kill the parent process. You can easily find out the parent’s process ID with this command:
# ps aux -eo ppid | grep 
# kill -9 
So when a Zombie process loses it’s parent process, it becomes orphan and adopted by “init”. Init periodically executes the wait system call to reap any zombies with init as parent.

FAQs:

Q. Why I can’t kill a Zombie process with “kill” command ?
A. Zombie process is already dead, so killing them with “kill -9″ won’t help at all.
Q. Is it bad to have Zombie processes on your system ?
A. Well, as Zombie processes are not taking any resources of your system, leaving a small entry in process table, it’s not at all harmful to have Zombie processes in your system, but it may hurt you sometime under heavy load. So, it’s always better not to have them.
Q. I am seeing a lots of Zombie processes around in my system, what could be the reason ?
A. If this is the case then you are using some code/software in your system which is having a lot of bugs or not properly written. Look for something like that and fix it.
Q. Is Zombie process different from an Orphan process ?
A. Yes, Zombie is something which is already dead, but Orphan processes are those whose parents are dead.