Tuesday, 8 May 2012

Zombie and Orphan processes in Unix.

For more info visit

Zombie Process

A zombie process is the process which is actually dead, but is actually haunting the process structure table. We know that whenever a process runs in Unix, its entry is made in the process structure table which keeps track of a lot of things, for example number of files that the process is using, etc. Whenever a child process dies, its parent process recieves the signal SIGCHLD. Suppose a parent spawned the child process and forgot to handle the SIGCHLD signal or ignored the signal (which is the default scenario when signal is not handled), then the child process becomes the Zombie process. Whenever a parent waits for its child process and reads its exit status, the child process is removed from the process structure table before the parent. Zombie processes are denoted by Z in the status column when we run the command ps -le. Note: Suppose the child  has become a zombie, it remains zombie only for the time interval for which its parent is alive. Once the parent of a zombie process is dead, it is adopted by the init process of the unix which then acts as the father of the process. Init continously runs wait system call to remove zombies from the system. Zombie processes are a big problem when their parent processes run for a long time. In this case Zombies will persist in the process structure table for a lot of time. Let's see an example which creates a Zombie process. We will write a program in C language to understand the zombie process. #include<stdio.h> int main() { int pid; pid=fork(); if(pid>0) { sleep(30); printf("parent process id %d",getpid()); printf("in parent process"); } else if(pid==0) { printf("child process id %d",getpid()); printf("in child process"); } return 1; } Now we will understand, what the above code is doing. With the use of fork() system call we are creating a new child process. Fork() actually returns twice, i.e. from now onwards two process are created, so it returns 0 to the child process and pid of child process to the parent process. Compile this program and run it in the background because we want the shell to be interactive to check the creation of zombie process. While this program runs, it will run the parent process and put it to sleep for 30 sec, which was necessary for our analysis. At the same time pid of child process will be printed and child process will die after completion. Immediately run the command to see the dead child zombie. ps -le|grep 'Z' This command will search for Z in the list of processes running. As  we already know that zombie process remains in the process structure table unless its parent is dead. So, we will be able to find its details through ps command till 30 seconds. If everything worked right, you will notice the process detail with status as Z and pid as the pid of the child process.  

Orphan Process

Orphan process is the process for which parent is dead. Suppose a program forks a new child process and while the child is performing some work, its parent dies. This child process then becomes orphan. Orphan process doesn't remain orphan for a long time because after its parent death , the child process is adopted by the init process which we already know is the parent of all the processes. When the child process is adopted by the init process then its ppid value becomes 1, which is the pid for init process. #include<stdio.h> int main() { int pid; pid=fork(); if(pid>0) { printf("parent process id %d",getpid()); printf("in parent process"); } else if(pid==0) { printf("child process id %d",getpid()); sleep(30); printf("in child process"); } return 1; } Note the pid of the child process which is printed by the program. Run ps -el command and search for pid as pid of the child process. See the ppid(parent process id) of this process and you will notice that ppid of this process is 1. This is because the orphan child process has now been adopted by the init process

Friday, 4 May 2012

File descriptor manipulation in Unix

For more info visitTo understand File Descriptor manipulation we will have to know, what are file descriptors? Whenever we run a process, Unix automatically associates some indicators with the process for accessing input and output devices. The default indicators which unix associates with any process are 0 - Input from user or standard input. 1- Output to user or standard output. 2- Error output which shares the same stream as standard output i.e , standard output and error output share the terminal. When we login into the terminal , unix kernel creates a shell for us which is a process. 0,1,2 are also associated with the shell.We can also redirect these file descriptors to some other source for example echo John > myfile It actually means cat John 1> myfile This simply means, redirect the output, which was actually meant for standard output, to the file "myfile". Now the output will go to the file "myfile", instead of coming on screen. We all know that in unix, everything is treated as a file. Standard input/output terminal is not an exception to this, /dev/tty is the file associated with every terminal which is connected to Unix system. Remember, there can be one or more terminal connected to a Unix system with different user working on each system. So whenever anyone tries to use /dev/tty, it corresponds to their own terminal. I already told you that error stream also shares the same output device as output stream, i.e terminal .We can also redirect error stream to some file, instead of showing it on terminal. cat zombie 2>myfile I don't have any file "zombie" in my system, but instead of showing error on terminal , I am redirecting error to the file "myfile". We can also manipulate file descriptors using exec command. For example, if we run the following command on the shell. exec 1>myfile Now, whenever we try to print something on terminal, it will go to the file. This is because we have redirected output stream of the process "shell" to myfile. We won't be able to see the contents of myfile, since it is being used by the process "shell" to store its output. We can see the contents of "myfile"  once we redirect the shell's output stream back to "/dev/tty", using exec 1>/dev/tty. We can also create our own file descriptors and associate them with some file. Those file descriptors can have numbers like  3,4,5..... .Whenever we create our own file descriptor the shell opens file, either in reading or writing mode depending on the file descriptor made. This happens in the background, and user never gets to know about this. So, creation of every file descriptor leads to opening of a file, or more precisely opening of any file by a process leads to creation of a file descriptor.  Generally, kernel maintains these file descriptors to keep track of access patterns for a file. For example. exec 3>myfile Output file desciptor 3 is associated with "myfile".  We can write commands like the following to send output to "myfile". echo hello >&3 Above command will put output "hello" in "myfile" instead of displaying it on screen. We can also create an input file descriptor for a file. exec 4<myfile After this, the process can take input from this file. cat <&4 We can also create a file descriptor based on some other file descriptor. For example, 4 is the input file descriptor for "myfile".We can associate some other input file descriptor, using file descriptor 4, with  "myfile". exec 5<&4 Now,  we can read input from myfile using any file descriptor(4 or 5). In the same way we can do it for output file descriptor. Note: i) Whenever we create a file desciptor using another descriptor then both should be either output file descriptor or input file descriptor. ii) Whenever we close one file descriptor for a file, then it doesn't close other file descriptor which was made using the previous file descriptor. In the example if we close file descriptor 5, it won't close file descriptor 4. iii) A file descriptor made with the help of other file descriptor shares the same pointer to the file in the file table.

 Closing of File Descriptor

We can close the file descriptor using following command. exec 4>&- Note: We always close the file descriptor using ">", irrespective of the fact that it's an input file descriptor or an output file descriptor.

Sunday, 29 April 2012

Why cannot I change the ownership of my file ?...

For more info visit
A lot of time it would have come to our mind. Why am I not allowed to change the owner of my file in Unix/Linux? Why do I have to be a ROOT user or sudo as a ROOT user when I want to change the ownership of my file? I mean, it's my file. I should have been given the full right to change the owner of my file. Is it necessary for the ROOT to meddle in between !.... I am not trespassing someone else's property. It's not fair enough and blah blah blah...... The answer to all these questions is very simple. Whenever I am changing the owner of my file, it's not something in which only my account is involved. Infact if I had the permission,  it would be like forcing other user to become the owner of my file. So it's kind of dealing with others account also? Now, you may very well ask that why the other user might have problem with this? At the first place, most of the people don't allow anyone to even read their files and look at me, I am giving the ownership of my file to other user. Isn't it fair amount of GENEROSITY. Well, the answer to this question depends on your intentions. Now I will explain it with the help of a simple example that what catastrophe it would have been if you had the permissions to change the owner of your file. Basically everyone knows that they are not allowed to see the contents of /etc/shadow file, which contains password in encrypted format. Though the password for every user is stored in encrypted format, even then you are not allowed to see it. I mean, the ROOT is just taking caution, supposing that some of you could be good hackers. Now I will write a very simple script.   cat>myfile cat /etc/shadow Give all the permissions to everyone for this file.   chmod a+rwx myfile Now we can see, all the users have all the permissions on the file. If you change the ownership of the file from here, supposing that your intentions are to read the contents of shadow file, then let me remind you it would not be very helpful. Even though you can run the file after changing ownership, you will not be allowed to cat /etc/shadow because the script is running with effective UID as your id, who doesn't have the permission to read/write/execute shadow file.  Now you can be smart here, before transferring the ownership to ROOT set SUID for your file.   chmod u+s myfile Then transfer the ownership of your file to ROOT   chown root myfile   Now when the ownership has been transferred and you try to run the file, it would be run with ROOT id as effective UID. So, you would very well be able to see the contents of /etc/shadow file. And then depending on how much you understand encryption/decryption, you could have played a havoc with the system. This is one of the example which justifies that no user should be able to transfer the ownership of their file without ROOT's permission, supposing, in most of the cases ROOT users are trustworthy.

Saturday, 28 April 2012

Global Temporary Tables in Oracle

For more info visit
Global Temporary tables are used for temporary storage of data which has to be cleaned up at the end of some task. Generally, batch programs use temporary tables to store data at some temporary location and then the data is automatically deleted/cleaned at the end of the session or at commit. Data in temporary tables is stored in temp segments in tablespace. Data in the temporary table is session specific, i.e a user saved data in a session cannot be accessed by him/her in other session. A user session is associated with the Global Temporary tables when the data is inserted in a session. Now let's see how the Global Temporary table is created Create Global Temporary table my_tab( name varchar(20), Contact number(10) )On Commit [Delete Rows|Preserve Rows];

We can use two options with Global Temporary tables

a) On Commit Delete Rows: If this option is used, data corresponding to the user session is deleted when transaction completes/is committed. b) On Commit Preserve Rows: When this option is used, data in the Global temporary table persists unless the session is over.

Some features of Global Temporary tables

Note: From here whenever I say table just consider it to be Global Temporary table, as it's very tedious to write it again and again. i) Data in a session cannot be accessed in other session. Though different session of a user are using the same Global Temporary table, data of a session cannot be accessed in other session. In short, Data in the table is session specific. ii) If the table is already created by a session and if we try to create table again in other session, it will give an error. iii) At the end of the session or transaction only session specific data is deleted and not the structure of the table from the user's schema. iv) We can run DDL statements(ALTER TABLE, CREATE INDEX) on the table only when it is not used by any other session. v) Truncating table will only delete the session specific data. vi) The scope of the index created on the table is limited to the session which creates it. vii) Views can be created on the table, or on the table and some other permanent table. viii) We can also associate the table with some trigger but remember we cannot reference the table in the trigger. ix) We can have primary key in the table but we cannot create any referential integrity constraint in the table. At the same time, we cannot access the table  in a referential integrity constraint.  x) Abnormal closing  of the session will truncate the session specific data from the table even if the data was not commited or the session was not over.

Sunday, 22 April 2012

Anchored Declarations in PL/SQL.

We often declare variables in our PL/SQL programs, and most of the time these variables are used to fetch some values from database tables or store some values in the database tables. The variables used for this purpose should have size and structure  resembling that of table columns. Now, unless you have a very sharp memory, remembering the structure and size of database colums is really a hard task. We can solve this problem by making use of Anchored Declarations. PL/SQL offfer two types of anchoring. i) Scalar Anchoring: In this type of anchoring we use %TYPE attribute to define variable based on some table column or any other PL/SQL variable. ii) Record Anchoring: We can use %ROWTYPE attribute to define a variable based on a row in the table or on an explicit cursor. Let's see the use of Anchored Declarations with the help of an example. Suppose we have a table which has script as shown below. create table contacts(name varchar2(20), mobile number(10)); insert into contacts values('John', 4563821293); insert into contacts values('Paul', 7463292330); In the above script a table contacts has been created and some data is inserted. Now we will write an anonymous block to understand the use of Anchored declarations. set serveroutput on; Declare v_mobile contacts.mobile%type; Begin select mobile into v_mobile from contacts where name='John'; dbms_output.put_line('Mobile no. is '||v_mobile); end; In the above block we are trying to fetch the mobile no. of John. Just see how v_mobile variable is defined with the use of anchored declaration. Just by writing contacts.mobile%type, its datatype is referenced to that of column mobile in the table. This was an example of scalar declaration. In the next example we will see the use of record anchor declarations. We shall again write an anonymous block to demonstrate the use of Record anchored declaration. Declare v_rec contacts%rowtype; Begin select * into v_rec from contacts where name='John'; dbms_output.put_line('Mobile no. is '||v_rec.mobile); end; In the above block we are trying to fetch the whole row in a variable using anchored declarations. Just see, this time we have used %rowtype for fetching the row of a table. To access the individual field we use "variable.columnname", so here we are using v_rec.mobile which is the column name of the table. Not only this, we can also anchor declare a variable based on another PL/SQL variable. A simple PL/SQL block is given below to demonstrate the usage. Declare v_rec contacts%rowtype; v_rec1 v_rec%type; Begin select * into v_rec from contacts where name='John'; v_rec1:=v_rec; dbms_output.put_line('Mobile no. is '||v_rec1.mobile); end; In the above block we are using a variable v_rec1 which is anchored declared based on v_rec.

Advantages of using anchored declarations

Synchronization with Database table columns: Whenever we declare an anchored variable based on row or a column of a table, then the datatype and size of the variable is automatically defined to that of the table column. So, we need not worry about datatype of a variable after anchored declaration. Normalization: Suppose we have declared a number variable as v_num number(5). Now we have the need to declare the same type of variable in a lot of procedures, functions and packages. Now let's say, one day the need arises to change the datatype of this variable from number(5) to number(8). In this scenario it would be a tedious task to search for this variable in all the functions and procedure, and change its datatype. To solve this problem we can make use of anchor declaration based on a PL/SQL variable as follows. create or replace package mypack is v_num number(5); end; declare v_num1 mypack.v_num%type; begin null; end; In the above code we have defined a variable v_num in the package mypack, and later in our procedures and functions we can anchor declare any variable based on this package variable. This solves the problem discussed above. Note: i) Whenever we change the structure of any column in our tables, it is our duty to recompile the functions and procedures, otherwise the functions and packages, using anchor declaration based on table columns, will not work. ii) Keep in mind, in the case of anchored declarations based on a PL/SQL variable, NOT NULL constraint is automatically transferred to the anchor declared variable. In case of anchored declaration based on table columns, this does not happen.

Thursday, 19 April 2012

Programmer Defined Subtypes in Oracle.

A programmer can define his/her own subtypes instead of using default subtypes in oracle. Infact these subtypes are defined with the help of default data types only.

User defined subtypes are really easy to use. Suppose we have to declare a varchar of size 3000.
We can declare a varchar of size 3000 as follows.

v_var varchar2(3000);

Now suppose we have to use a varchar of size 3000 in a lot of procedures. Writing this big line again and again in many procedures shall be a pain for us. Also if there is a data flow between different procedures then it is expected that size of the data types in all the procedures should be same. By mistake, a programmer may define different sizes of data types  in different procedures.

In order to solve these problems, we make use of Subtypes.

We can declare the structure of all the variable types,which will be used in our procedures and functions, in a package. Don't worry if you don't know packages. It's just a simple example using package. For the time being , you just take package in oracle as a container.
create or replace package mydatatypes as
subtype mychar is varchar2(20);
subtype mynumber is number(20);
end;


Now we can use mychar,mynumber user defined subtypes in our procedures and functions.These will act in the same way as using varchar2(20),number(20) respectively.

To use these user defined subtype we will write an anonymous block as follows.

 

DECLARE
v_var mydatatypes.mychar;
BEGIN
v_var:='John Smith';
dbms_output.put_line(v_var);
end;


And the output is John Smith.

If you see the block, mydatatypes.mychar is used as a user defined subtype. This is because the mychar subtype is defined inside the package mydatatypes,  and to access it we would have to use mydatatypes.mychar.

We could also have defined subtypes in declaration section of our anonymous block. But that would have defeated the purpose of using subtypes, which are generally used to maintain consistency among data types in different procedures or functions.

For more information visit

Sunday, 15 April 2012

Soft links(Symbolic links) in Unix.

Soft Links:-

We have seen hard links in our previous post. Hard links are nothing but more than one names for a file. Hard links have some shortcomings.

i) We cannot hard link two files in different file systems, i.e. a file in /usr directory cannot be hardlinked in /home directory.

ii) Hard links cannot link directories even in the same file systems. It can link only files.

Soft links remove limitations of Hard links.

Now let's see what are Soft links.

We make a file "file1" as shown below

[code]cat>file1
date
[/code]Assign execute permission to this file
[code]chmod u+x file1 [/code]
Now we create a symbolic link "file2" to this file as shown below
[code]ln -s file1 file2[/code]
Note: We are using -s attribute to create a symbolic link. If -s is not used then it would create a hard link.

Now, our symbolic link is created. You can verify the creation of symbolic link using

[code]ls -l file2[/code]
Output is:

lrwxr--r-- 1 user1 user1 2012-04-15 16:14 file2 -> file1

Note: l in the starting and "file2 -> file1" denote the creation of symbolic link. Also, number in the second column is 1. This means, a new file is created, as contrary to Hard links in which no new file is created.

Now we have two files. We know the content of file1 but What does file2 contains?

file2 contains the pathname of file1. When we execute cat command on file2, it actually redirects to file1 and opens its content.
So, cat file1 and cat file2, both show the same content. We can also execute the content using any of the file.

The output of ./file1 and ./file2 are same, i.e.

Sun Apr 15 16:18:28 EDT 2012

 One  advantage of soft link over hard link is that it can link directories also. Suppose we have to link a large number of files from one directory to another. If we use Hard link, then the only way is to link each file individually. But, when we use soft link, we can link an entire directory to another directory.

Caution: Hard link provides safety against accidental deletions, i.e. if one alias is deleted then we can access the file through other aliases.

But, in the case of symbolic link, we created above,  if file2 is deleted then there is nothing to worry about. But, if  by mistake file1 is deleted then all our content is lost.  Also symbolic link file2 would become a dangling symbolic link.This is because symbolic link is a seperate file, and  not a pointer to the original file.

 

For more information visit