Search This Blog

Saturday, August 21, 2010

recover an accidentally overwritten partition table

shorter version:

Q. I accidentally overwrote the partition table on my computer. Now it does not boot. Is there any way to restore it back?
A. use the testdisk program. Debian users can install it by doing

# apt-get install testdisk

To run it, use the command

# testdisk

This tool is very powerful, easy to use and interactive. It can be run from a live CD. I used it to recover the ext3, Linux swap partition information.

Long story:

My favorite tool for partitioning is qtparted. I got hooked to it couple of years back when I was trying out a knoppix live CD.

The hard drive of my laptop is /dev/sda. I recently bought a 500 GB external USB hard drive. When I connected the USB hard drive, it was recognized as /dev/sdb. I used the qtparted program to partition the /dev/sdb.

The partitioning process went smoothly. But when I click on the /dev/sdb link in the left tab of qtparted window, there were error messages on my konsole

$sudo qtparted
No Implementation: Support for opening ntfs file systems is not implemented yet.
Error: File system has an incompatible feature enabled. Compatible features are has_journal, dir_index, filetype, sparse_super and large_file. Use tune2fs or debugfs to remove features.
Error: File system has an incompatible feature enabled. Compatible features are has_journal, dir_index, filetype, sparse_super and large_file. Use tune2fs or debugfs to remove features.

Not sure of what it means, I resorted to cfdisk (a Curses based tool for partitioning).

My intention was to delete all the partitions on /dev/sdb and start afresh. However, I ended up deleting all the ext3, swap partitions on /dev/sda by accident. Notice how cfdisk only lists /dev/sda and nothing about /dev/sdb?

When the changes are committed, it gave an error. It asked me to reboot the machine in order to fix the error.

When the laptop is rebooted, Grub does not load. IIRC, the error code was 17. My computer is now officially in a half baked state with the wrong partition table (all because of my stupidity).

Kumar Appiah suggested me to try testdisk. He used it before to recover some FAT32, NTFS partitions.

So, I popped in an old Ubuntu (hoary) live CD to see if it has testdisk. It does not. The Hoary was released a while back. The official repositories were removed. So a simple

# sudo apt-get update

did not work. I modifed the /etc/apt/sources.list to point to dapper instead of hoary. Then did an apt-get update, apt-get install testdisk.

In order to install testdisk from dapper onto hoary, apt-get wanted to install a new kernal and remove the current kernel. I let the upgrade process run and gave it a 'no' when it wanted to remove the current kernel during the post configure stage. This exited the apt-get process abruptly.

Then, I did a "sudo apt-get -f install" to fix the inconsistent state. I then had to do another "sudo apt-get install testdisk". This time it proceeded without any difficulty.

Once testdisk is installed in the RAM, running it was easy. Just execute

# testdisk

The instructions in testdisk screens are very clear. At the end, I was able to recover my original partition table. Kudos to the authors, Debian maintainers of testdisk and to Kumar for suggesting it.

Useful links:
. websites of testdisk , qtparted
. links to debian packages testdisk, qtparted, e2fsprogs

Tuesday, June 15, 2010

options in function variables octave

The following octave code shows how to make functions take different paths depending on a user specified choice. It is a little template that comes in handy once in a while.
$cat options_in_function_variables_01.m
# Author : Kamaraju S. Kusumanchi
# Email : kamaraju at gmail dot com
# Last modified : Tue Jun 15 06:45:15 EDT 2010
function [X] = options_in_function_variables_01(X, choice)

if (strcmp(choice, "square"))
X = X*X;
elseif (strcmp(choice, "unity"))
X = X*1;
elseif (strcmp(choice, "cube"))
X = X*X*X;
printf("choice = %s is not a valid option.\n", choice);
error("please provide a correct choice");

To test it

$octave -qf
octave:1> options_in_function_variables_01(2.2, 'unity')
ans = 2.2000
octave:2> options_in_function_variables_01(2.2, 'square')
ans = 4.8400
octave:3> options_in_function_variables_01(2.2, 'cube')
ans = 10.648
octave:4> 10.648/4.84
ans = 2.2000
octave:5> 4.84/2.2
ans = 2.2000

Monday, May 17, 2010

passing functions as arguments in octave

It is possible to pass functions as arguments to another function in Octave. Consider the following sample code

cube.m dynamic.m script.m square.m

$cat square.m
function [sq] = square(x)
sq = x**2;

$cat cube.m
function [cu] = cube(x)
cu = x**3;

$cat dynamic.m
function [ ret ] = dynamic (fh, x)
# fh is a function name passed as a string
# ex:- b = dynamic("cube", a);
# fh can also be a handle
# handle = @square;
# b = dynamic(handle, a);
ret = feval(fh, x);

$cat script.m

# bh = b obtained by using handle as arguments
bh = dynamic( handle, a)

# bs = b obtained by using strings as arguments
bs = dynamic("square", a)

# ch = c obtained by using handle as arguments
ch = dynamic( handle, a)

# cs = c obtained by using strings as arguments
cs = dynamic("cube", a)

Run the script.m in octave

$octave3.2 -qf script.m

a = 5
bh = 25
bs = 25
ch = 125
cs = 125

Tested using Debian Lenny (stable), Octave 3.2.4

Further Reading:
1) The section on "Function handles, Inline Functions, and Anonymous Functions" in the octave manual

2) explains how to do this kind of "calling functions from functions" in various programming languages

Sunday, April 25, 2010

load data file with header lines in octave

When a data file contains some header lines before the actual data matrix, octave's dlmread function can be used to read the matrix of data and ignore the headers.

For example,

$cat input_data.m
col1 col2 col3
1, 2, 3
4, 5, 6
7, 8, 9
10, 11, 12

This file contains one header line and a 4x3 data matrix. To read it into octave, create a script called

$cat read_data.m
A = dlmread("input_data.m", SEP=',', R0=1, C0=0);

$octave3.2 -qf
octave3.2:1> read_data
A =

1 2 3
4 5 6
7 8 9
10 11 12

For more information on dlmread function, use 'help dlmread' inside octave.

Tested using octave 3.2.4-3 on Debian stable (Lenny).