TimeLinux1

Sunday, March 17, 2013

Tainted Kernel - What to do?

Tainted Kernel:

In the Linux world, where Opensource drivers and modules rule the roost, you may happen to receive a message in your system alerts saying that your kernel is 'Tainted'. Before we go further its useful to understand what it means.

Because of the Opensource model, Linux kernel modules and drivers are designed, developed and maintained by the Linux Opensource community. Some Linux flavors like GNU Hurd are strict about their principles about Free Open Source software fundamentals and therefore would not include any non-Free drivers and modules in their distribution. On the other hand Linux distributions like Ubuntu and LinuxMint are not so strict. They emphasise functionality and ease of use over Principles of FSF. Their driver and module inclusion policy in their distributions is more relaxed. What that means is that often in these distributions would include proprietary drivers and modules to make something work. This is especially true in case of Graphical, Audio or Wireless drivers. For instance the Graphic Drivers from AMD (Radeon) could be included in a certain Linux distribution.
Now, whenever proprietary drivers are included, they come only as binary code--no source code.
Which means if there is any problem or bug detected in that (proprietary) softwar, the Linux community cannot  access the source code and therefore cannot fix it. This fix can only come from the vendor who provided that proprietary driver or module. This is lack of visibility in the source code of a proprietary driver or module that is having problems working with Linux kernel is said to have 'Tainted the Linux kernel'.

Great, now we know what it means, how do we confirm it? How do we fix diagnose and fix it?
Well, it varies, but in almost all cases, you would know that your kernel is Tainted if you receive a popup/warning or alert from the system. On Fedora, the distribution that I use all the time, the 'Tainted kernel' alert is easily visible from the system alerts on the bottom right corner of the GUI screen. From the command line, its visible under the kernel message utility dmesg, as follows:


[root@ms-vaio ~]# dmesg | grep -i taint
[83346.433966] Pid: 31775, comm: kworker/u:0 Tainted: G        W    3.7.6-102.fc17.x86_64 #1

This can also be confirmed by looking into the file /proc/sys/kernel/tainted:


[root@ms-vaio ~]# cat /proc/sys/kernel/tainted 
512

Typically (for an un-tainted kernel), this file is empty. But as you can see, in my case its not. And in this case the process id 31775 is causing the kernel to be tainted. To dig into what that process is you can look into the process listing as follows:

[root@ms-vaio ~]# ps -efly | grep 31775
S root      4330  1539  0  80   0   872 27350 pipe_w 17:52 pts/0    00:00:00 grep --color=auto 31775
[root@ms-vaio ~]# 

As you can see, the process with pid=31775 does not exist in my case, which means the process was shortlived, it caused a kernel warning and then it was termintated.


For a detailed discussion on the meaning of each Taint Flag like 512, G, W etc, go here and search for 'tainted'.

Now what to do to fix it?

Typically there is, Nothing to fix.

All it means is that your kernel has a device driver that is not open source. It may be wireless, or video driver (either are common) or you have some slightly unusual hardware that doesn't have a kernel supported driver.

The only time it causes a problem is if a kernel failure/panic occurs. The kernel developers cannot debug such a failure because they are not able to trace the entire problem. It may have been caused by a bug in the proprietary driver either directly (it happens to be in the traceback) or indirectly by modifying some kernel data that other drivers depended on.

So a reboot usually clears the warning and resets the /proc/sys/kernel/tainted file to zero bytes.


Friday, March 8, 2013

Allow users to connect to remote MySQL database

When you are working with MySQL, chances are that your client and server are on two different hosts.
In such a case, its natural to want to connect to a remote MySQL database.
Lets say your local host (or client) is 10.10.80.103 and your remote host (or server) is 10.10.80.102.
So when you try connecting from client to server, default behavior of MySQL is to deny access:


[root@10.10.80.103 /root]# mysql -u myuser -p -h10.10.80.102
Enter password: *****
ERROR 1045 (28000): Access denied for user 'myuser'@'redhat3.maprtech.com' (using password: YES)

In such a situation, to allow access from remote hosts, go to the server (in this case 10.10.80.102), and do this as the admin user (root):


[root@10.10.80.102 /root]# mysql -u root -p
Enter password:*****

Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 7982
Server version: 5.1.52 Source distribution
Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
This software comes with ABSOLUTELY NO WARRANTY. This is free software,
and you are welcome to modify and redistribute it under the GPL v2 license
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.



mysql> use mysql;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed

mysql> grant all on *.* to myuser@'10.10.80.103' identified by 'mypass';
Query OK, 0 rows affected (0.00 sec)


mysql> flush privileges;
Query OK, 0 rows affected (0.00 sec)


Then go back to the client side (here 10.10.80.103) and make a connection attempt to the server (here 10.10.80.102):


[root@10.10.80.103 /root]# mysql -h 10.10.80.102 -u myuser-p 
Enter password:
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 8340
Server version: 5.1.52 Source distribution

Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
This software comes with ABSOLUTELY NO WARRANTY. This is free software,
and you are welcome to modify and redistribute it under the GPL v2 license

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql>                          [[[ connection succeeds and you are in.]]]


Note: Ensure that the firewall settings are permissive on the server side or simply turn off firewall if you want (using 'service iptables stop' command).





Thursday, March 7, 2013

How to install MySQL on Linux

MySQL is a FOSS database that is available in a free community edition and a paid commercial edition from Oracle corp. Oracle acquired MySQL from Sun Microsystemes acquisition. MySQL is an integral part of LAMP Stack and is used for a majority of web applications. Infact, MySQL is a choice DB platform for many Internet Applications like Facebook, Twitter, Yahoo etc.

Its very simple to install and run MySQL on Linux using yum, as shown below.

1- Check status of MySQL prior to install:


[root@redhat2 bin]# service mysqld status
mysqld: unrecognized service
[root@redhat2 bin]#

As you see mysql doesnt exist. You can also verify using rpm.

[root@redhat2 bin]# rpm -qa | grep mysql
[root@redhat2 bin]#

2-To install:

[root@redhat2 lib]# yum install -y mysql-server
Loaded plugins: product-id, security, subscription-manager
Updating certificate-based repositories.
Setting up Install Process
Resolving Dependencies
--> Running transaction check
---> Package mysql-server.x86_64 0:5.1.52-1.el6_0.1 will be installed
--> Processing Dependency: perl-DBD-MySQL for package: mysql-server-5.1.52-1.el6_0.1.x86_64
--> Running transaction check
---> Package perl-DBD-MySQL.x86_64 0:4.013-3.el6 will be installed
--> Finished Dependency Resolution

Dependencies Resolved

===================================================================================================================================
 Package                           Arch                      Version                              Repository                  Size
===================================================================================================================================
Installing:
 mysql-server                      x86_64                    5.1.52-1.el6_0.1                     mynew                    8.1 M
Installing for dependencies:
 perl-DBD-MySQL                    x86_64                    4.013-3.el6                          mynew                    134 k

Transaction Summary
===================================================================================================================================
Install       2 Package(s)

Total download size: 8.2 M
Installed size: 24 M
Downloading Packages:
(1/2): mysql-server-5.1.52-1.el6_0.1.x86_64.rpm                                                             | 8.1 MB     00:00  
(2/2): perl-DBD-MySQL-4.013-3.el6.x86_64.rpm                                                                | 134 kB     00:00  
-----------------------------------------------------------------------------------------------------------------------------------
Total                                                                                               48 MB/s | 8.2 MB     00:00  
Running rpm_check_debug
Running Transaction Test
Transaction Test Succeeded
Running Transaction
  Installing : perl-DBD-MySQL-4.013-3.el6.x86_64                                                                               1/2
  Installing : mysql-server-5.1.52-1.el6_0.1.x86_64                                                                            2/2
Installed products updated.

Installed:
  mysql-server.x86_64 0:5.1.52-1.el6_0.1                                                                                        

Dependency Installed:
  perl-DBD-MySQL.x86_64 0:4.013-3.el6                                                                                            

Complete!

3- Verify installation:

[root@redhat2 lib]# rpm -qa | grep mysql
mysql-libs-5.1.52-1.el6_0.1.x86_64
soci-mysql-3.1.0-1.el6.x86_64
mysql-5.1.52-1.el6_0.1.x86_64
mysql-server-5.1.52-1.el6_0.1.x86_64

[root@redhat2 lib]# ls /etc/init.d/mysqld 
/etc/init.d/mysqld
[root@redhat2 lib]# 

4- Post install config:

root@redhat2 lib]# /usr/bin/mysql_install_db --user=mysql
Installing MySQL system tables...
OK
Filling help tables...
OK

To start mysqld at boot time you have to copy
support-files/mysql.server to the right place for your system

PLEASE REMEMBER TO SET A PASSWORD FOR THE MySQL root USER !
To do so, start the server, then issue the following commands:

/usr/bin/mysqladmin -u root password 'new-password'
/usr/bin/mysqladmin -u root -h redhat2 password 'new-password'

Alternatively you can run:
/usr/bin/mysql_secure_installation

which will also give you the option of removing the test
databases and anonymous user created by default.  This is
strongly recommended for production servers.

See the manual for more instructions.

You can start the MySQL daemon with:
cd /usr ; /usr/bin/mysqld_safe &

You can test the MySQL daemon with mysql-test-run.pl
cd /usr/mysql-test ; perl mysql-test-run.pl

Please report any problems with the /usr/bin/mysqlbug script!


[root@redhat2 ~]# /usr/bin/mysql_secure_installation

NOTE: RUNNING ALL PARTS OF THIS SCRIPT IS RECOMMENDED FOR ALL MySQL
      SERVERS IN PRODUCTION USE!  PLEASE READ EACH STEP CAREFULLY!

In order to log into MySQL to secure it, we'll need the current
password for the root user.  If you've just installed MySQL, and
you haven't set the root password yet, the password will be blank,
so you should just press enter here.

Enter current password for root (enter for none): *****
OK, successfully used password, moving on...

Setting the root password ensures that nobody can log into the MySQL
root user without the proper authorisation.

Set root password? [Y/n] Y    
New password:
Re-enter new password:
Password updated successfully!
Reloading privilege tables..
 ... Success!


By default, a MySQL installation has an anonymous user, allowing anyone
to log into MySQL without having to have a user account created for
them.  This is intended only for testing, and to make the installation
go a bit smoother.  You should remove them before moving into a
production environment.

Remove anonymous users? [Y/n] Y
 ... Success!

Normally, root should only be allowed to connect from 'localhost'.  This
ensures that someone cannot guess at the root password from the network.

Disallow root login remotely? [Y/n] n
 ... skipping.

By default, MySQL comes with a database named 'test' that anyone can
access.  This is also intended only for testing, and should be removed
before moving into a production environment.

Remove test database and access to it? [Y/n] n
 ... skipping.

Reloading the privilege tables will ensure that all changes made so far
will take effect immediately.

Reload privilege tables now? [Y/n] y
 ... Success!

Cleaning up...

All done!  If you've completed all of the above steps, your MySQL
installation should now be secure.

Thanks for using MySQL!

[root@redhat2 ~]#

5- Start using MySQL:

[root@redhat2 lib]# service mysqld status
mysqld (pid  10324) is running...

[root@redhat2 lib]# mysql -u root -p
Enter password: xyzxyz

Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 2
Server version: 5.1.52 Source distribution

Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
This software comes with ABSOLUTELY NO WARRANTY. This is free software,
and you are welcome to modify and redistribute it under the GPL v2 license

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| test               |
+--------------------+
3 rows in set (0.00 sec)

mysql> use mysql;

Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
mysql> show tables;
+---------------------------+
| Tables_in_mysql           |
+---------------------------+
| columns_priv              |
| db                        |
| event                     |
| func                      |
| general_log               |
| help_category             |
| help_keyword              |
| help_relation             |
| help_topic                |
| host                      |
| ndb_binlog_index          |
| plugin                    |
| proc                      |
| procs_priv                |
| servers                   |
| slow_log                  |
| tables_priv               |
| time_zone                 |
| time_zone_leap_second     |
| time_zone_name            |
| time_zone_transition      |
| time_zone_transition_type |
| user                      |
+---------------------------+
23 rows in set (0.00 sec)

mysql> exit
Bye

Enjoy!


Wednesday, March 6, 2013

Heredoc to automate shell scripts

Ever wondered if there was a way to automate passing multiple bash commands to run non interactively?
For instance, if you wanted to create a shell script to start vi editor, get into insert mode and populate some commands based on some condition and then escape, save and exit out of the editor all while being in the shell script--how would you do it?

The answer is what is called heredoc. The concept of heredoc comes from C programming language and which was later borrowed into Unix/Linux tradition. Basically what a heredoc does is to accept commands from a stream starting with a start-signature and ending with the same signature. So all the commands or interactions with the shell between those start-end signatures are non-interactive.
For a more detailed discussion visit heredoc pages here and here.

An Example:

#-------------


[root@redhat2 mrinal]# cat myscript
#!/bin/bash

tfile=$1

vi $tfile << bye                      /* start vi with a file argument $tfile by user & start signature = bye*/
i                                              /* invoke 'insert' mode of vi */
echo `date`                              /* run a command */
`uname -a`                              /* run another command */
`ls -l`
^[                                            /* escape to command mode of vi, passed by Ctrl+v on keyboard */
wq                                          /* save file */
bye                                      /* end non interactive mode when sees the signature = bye */

#------------

The above shell script will open vi non-interactively and run a bunch of commands between the start-end signature, here in our case the word 'bye'. It could be anything you choose, as long the start and end signatures are the same. 

How to add swap in Linux

Swap space is a special filesystem in Linux that acts as virtual memory.
Virtual memory is not real or physical memory like the DIMM/SIMM modules you would install on your computers motherboard. Rather its a dedicated  piece of your computer's hard disk that looks and feels like a physical memory. Virtual memory is used by the system whenever there is a shortage of Real memory to accomodate all running programs in a multiuser, multiprogramming system like Linux. Think of a user running several programs simultaneously (a browser, a word processor, an email client, a vim editor, a video player etc). This situation would demand that all the running programs (ie processes) exist in (physical) memory. If the physical memory is not sufficient to hold all the programs then the less used programs would be 'swapped' to the swap space to make room for the more demanding processes. This ensures the system keeps running all the programs and servicing the user instead of crashing suddenly.

Now that we know a bit about swap space and why its needed, lets look at how we can add more swap space to a system.
Essentially, there are two ways to add swap space:
      1- add a new physical hard disk or partition and assign that as additional swap
      2- add a new file on your file-system and assign that as additional swap.

First to check the swap before adding new swap, we run swapon command as follows:



[root@redhat4 ~]# swapon -s
Filename Type Size Used Priority
/dev/dm-1                               partition 6160376 228 -1

This shows the system has about 6 GB of swap to begin with. Now we try each one of the two methods listed above

1- To add a new physical hard disk or partition and assign that as additional swap:

Lets say we have a new device /dev/sdc as a free hard disk / partition, then to make it as swap:

[root@redhat4 ~]# mkswap /dev/sdc1

Then enable the swap partition for usage using swapon command as shown below.

[root@redhat4 ~]#swapon /dev/sdc1

Then verify that the new swap partition is now available for use (assuming /dev/sdc1 was 1GB in size)

[root@redhat4 ~]# swapon -s
Filename Type Size     Used  Priority
/dev/dm-1                         partition   6160376 228  -1
/dev/sdc1                          partition    1048568         0     -2

To make the new swap partition available after reboot add the following line to /etc/fstab

[root@redhat4 ~]# cat /etc/fstab
/dev/sdc1               swap                    swap    defaults        0 0

Thats it for adding a new disk or partition as swap. Now to the 2nd method of adding a file as swap.

2- To add a new file on your file-system and assign that as additional swap:

First lets examine the initial swap:


[root@redhat4 ~]# swapon -s
Filename Type Size Used Priority
/dev/dm-1                               partition 6160376 228 -1

Lets add a 10 GB file created using dd utility (disk dump utility) as follows:
(obviously, you would want to make sure you have 10GB free on your filesystem before doing so)


[root@redhat4 ~]# dd if=/dev/zero of=/root/myswapfile bs=1M count=10000
10000+0 records in
10000+0 records out
10485760000 bytes (10 GB) copied, 824.221 s, 12.7 MB/s

Then check the new file and change its permissions to 600 so only root can use it.


[root@redhat4 ~]# ls -l /root/myswapfile
-rw-r--r--. 1 root root 10485760000 Mar  6 09:48 /root/myswapfile
[root@redhat4 ~]# chmod 600 /root/myswapfile

[root@redhat4 ~]# ls -l /root/myswapfile
-rw-------. 1 root root 10485760000 Mar  6 09:50 /root/myswapfile

Then make this new file as swap:


[root@redhat4 ~]# mkswap /root/myswapfile
mkswap: /root/myswapfile: warning: don't erase bootbits sectors
        on whole disk. Use -f to force.
Setting up swapspace version 1, size = 10239996 KiB
no label, UUID=c83a0679-aa64-4a42-85ee-851f4d7bab60

Then enable this new file as swap:

[root@redhat4 ~]# swapon /root/myswapfile

Then verify that all looks good.

[root@redhat4 ~]# swapon -s
Filename Type Size Used Priority
/dev/dm-1                               partition 6160376 228 -1
/root/myswapfile                        file 10239992 0 -2

[root@redhat4 ~]# free -m
             total       used       free     shared    buffers     cached
Mem:          9893       9702        190          0         33        648
-/+ buffers/cache:       9019        873
Swap:        16015          0      16015

To make this new file available as swap across reboots, add the following line in /etc/fstab:

UUID=c83a0679-aa64-4a42-85ee-851f4d7bab60  swap swap    defaults        0 0


And thats it. You now have a new swap space in your system!