Latest Entries »

Recently my friend had a problem with his server (runs on Ubuntu), where his RAID array suffered a failed hard disk replacement (“Un des disques sur le serveur vient de subir un changement de disque” as he said in French over telephone) and wanted me to help him out.

In a Linux RAID array (Software RAID), when a failed hard disk replacement occurs or you need to remove a failed hard disk and want to add a new hard disk to the RAID array without losing data (for our case, we presume that you already removed and replaced it with a new disk), your RAID array is left with one functioning disk in Software RAID and one empty disk with no Partition Table.

In such case, you need to copy the intact Partition Table of the functioning disk to the new empty disk and then rebuild the software RAID array with the help of “mdadm” command.

In my friend’s case, the /dev/sdb has been replaced and /dev/sda is functioning well.

Warning: Please remember the correct drive/partition and don’t mess with it, else you will end up with smoking both drives and suffer serious loss of data.

Warning: Playing with “mdadm” is risky as we don’t know very well of it’s functioning and sometimes it may not work for you depending upon the parameters of your system specific only to you. So be extra careful.

Step 1:

Login to your server via SSH. When my friend asked for help, I was on Mac OS X. Not wanting to restart my system and logging into my Windows 8 (and again I needed to install “PuTTY”) or Fedora 21, I just used the Mac OS X terminal and “ssh” command.

$ ssh root@yourserver.provider.domain

or with IP address

$ ssh root@xxx.xxx.xxx.xxx

Or, launch a “Terminal” → from menu “Shell” → select “New Remote Connection…” or press key combinations “Shift+Command+K” → new window “New Remote Connection” opens. From that window, under “Service” select “Secure Shell (ssh)” → under “Server” click “+” button and add either your “server name” or “IP address” → in “User” textbox type a user or “root” → “SSH (Automatic)” will be selected by default once you selected “Service” → in below dropdown box the command that is going to be issued will be displayed automatically → Click “Connect” → a new Shell window opens and ask for password. Provide password and once into the Server’s shell proceed from there.

In the above method, the configuration is saved under a file “know_hosts” under a newly created folder “.ssh” under your “User Home Directory”. So that, in future, you can directly select your choice of server from the “New Remote Connection” window. To access the file, you can issue a command like “vi .ssh/known_hosts” from user’s home directory.

Step 2:

First thing first! Do the necessary backup of disks. Backup with your usual method or Google how to do it or ask your friends. Since you’re maintaining a Server, I assume that you are adept at backing up regularly.

Step 3:

If you don’t have “mdadm”, install it:

$ yum install mdadm (or)

$ apt-get install mdadm (or)

$ aptitude install mdadm (or)

$ rpm -Uvh --nodeps ftp://ftp.ovh.net/made-in-ovh/sources/mdadm-2.5.5p1-1.i386.rpm
(find the right and latest “mdadm” through Google search)

Or, use whatever the command you’re comfortable with installing packages under your Linux distro.

Step 4:

Now, check the status of the RAID array using the command “cat /proc/mdstat”. This returns the output of multi-disk status.

Below is an example of two functioning healthy RAID arrays.

mdstat Output 01

In the above example, it shows two healthy RAID 1 arrays. As each array has a status of [2/2] and [UU], this means that out of 2 devices in the array, both the 2 devices are functional and both are Up.

In case of failing or replaced disks, there are several possibilities.

Possibility 1:

Below is an example, where the failed drive (/dev/sdb) has been replaced with a new blank drive and therefore the status reads [2/1] and [U_] as out of 2 devices in the array, only 1 is functional and only 1 is up. This is because the /dev/sda drive is still functioning, whereas the /dev/sdb drive has been replaced and is needed to be added back into the array and rebuilt. The output shows that the /dev/sdb drive has failed by the trailing (F) behind sdb3[2] and sdb1[2]

mdstat Output 02

Possibility 2:

Below is an example, where instead of one of the devices in each array being marked as failed (as in the above example), one of the devices in each array is not listed at all. In such case, the next step can be skipped.

mdstat Output 03

Possibility 3:

In my friend’s case, earlier, I had a different output like that of below. Notice that, in md1, it’s not sdb1, sdb2 or sdb3, but just plain sdb. And it shows, both sdb[1] and sda1[0] are up [UU] and 2 out of 2 devices are functioning [2/2].

mdstat Output 04

But later, it has changed to above example (Possibility 2) after few hours. So, I proceeded with the case of “Possibility 2”.

Note:[faulty]” in the “Personalities” line is not an indication of problem with the array. Instead, it’s diagnostic personality. The “Personalities” line tells you what RAID level the kernel currently supports. Last two examples show all possible “Personalities”.

Step 5:

In case of “Possibility 1” and “Possibility 3”, you need to remove failed devices from both the arrays.

$ mdadm --manage /dev/md1 --remove /dev/sdb1
$ mdadm --manage /dev/md3 --remove /dev/sdb3

or

$ mdadm --manage /dev/md1 --remove /dev/sdb

mdadm Output 04

In case of “Possibility 2”, these devices are not listed in both md1 and md2, so you don’t need to remove them and you can skip this step altogether.

Step 6:

Now, issue “fdisk -l” command to list all the partitions of both disks.

Important:

If “fdisk -l” returns the below message:

WARNING: GPT (GUID Partition Table) detected on '/dev/sda'! The util fdisk doesn't support GPT. Use GNU Parted.

Your disk’s Partition Table in not MBR. Instead, it’s GPT (GUID Partition Table). In that case, you use “parted” command.

If “fdisk -l” displays “Disk /dev/sdb doesn’t contain a valid partition table”, as in below example, for the failed disk /dev/sdb, it’s fine. You can skip this step.

fdisk Output 01

Instead, if “fdisk -l” lists partitions for failed disk /dev/sdb, as in below example, you need to get into fdisk “fdisk /dev/sdb” and delete these partitions (Google and consult a good manual to how to do it, both for “fdisk” and “parted”).

fdisk Output 02

Once it’s done, reboot the server to delete the partitions and re-read the partition tables. Issue either “reboot” or “shutdown -r now”.

Step 7:

Now replicate the partition by copying the Partition Table of the healthy disk (/dev/sda) to the empty disk (/dev/sdb). Please be extra careful by providing the right disk names, otherwise it will wipe out the data in functioning healthy drive.

For MBR disks, issue:

$ sfdisk -d /dev/sda | sfdisk /dev/sdb

Two different examples of above command’s output.

Example 1:

sfdisk Output 01

Example 2:

sfdisk Output 02

Sometimes you may encounter, error like:

sfdisk: ERROR: sector 0 does not have an msdos signature

In that case, issue the command with “–force” option,

$ sfdisk -d /dev/sda | sfdisk --force /dev/sdb

For GPT disks, issue:

sgdisk -R=/dev/sdb /dev/sda

Now the partition structure of the replaced/empty disk matches the partition structure of the functioning healthy disk, that contains data.

Step 8:

Now, we are going to use “mdadm” command. Issue:

$ mdadm --help (and/or)
$ mdadm --misc --help

to get help and familiarize yourself with the “mdadm” command.

To get detailed information on the status of the RAID arrays, issue:

$ mdadm --misc --detail /dev/md1
$ mdadm --misc --detail /dev/md2

The output may look like below:

mdadm Output 01

Notice that, “State :” could be anything like “active, degraded” or “clean, degraded” for failed disks and “active” or “clean” for functioning disks. Also, take notice of the last three lines.

Step 9:

To find out which partition should be added to which array, issue “cat /etc/mdadm.conf” or “cat /etc/mdadm/mdadm.conf”.

mdadm.conf Output 01

Sometimes you may not get the needed information like the example below. In such case, don’t worry, you can easily guess out the right disks and right arrays with the output of previous commands we executed so far.

mdadm.conf Output 02

Step 10:

As the /dev/sdb has been replaced, you need to add the /dev/sdb partitions to the correct arrays. The output from the last step states that /dev/sdb1 should be added to the /dev/md1 array. Issue the command:

$ mdadm /dev/md1 --manage --add /dev/sdb1

Now, check the RAID array status by issuing “cat /proc/mdstat” command again. Since the correct partition has been added back to the correct array, the data should begin copying over to the new drive and recovery and thus rebuilding of /dev/sdb1 will occur.

mdadm Output 02

Once the rebuilding process is done the output of “mdadm –misc –detail /dev/md1” should look like below example.

mdadm Output 03

Do the same for the /dev/sdb2 by issuing:

$ mdadm /dev/md2 --manage --add /dev/sdb2

Step 11:

Now that both the partitions /dev/sdb1 and /dev/sdb2 are recovered and added to correct arrays and the arrays are rebuilt, we need to enable the swap partition. To verify the swap partitions, issue the command:

$ cat /proc/swaps

To enable the swap partition for /dev/sdb, issue the commands:

$ mkswap /dev/sdb3
$ swapon -p 1 /dev/sdb3 (or)
$ swapon -a

Step 12:

Issue a final “fdisk -l” to verify the condition of all partitions of both the disks.

fdisk Output 03

Note: It’s normal that “fdisk” display both /dev/md1 and /dev/md2 don’t contain valid partition tables. It’s because “fdisk” is written for handling only single disks and their partitions. MD devices are Multiple Disks and are manipulated using “mdadm” command.

Thanks for the read and please leave comments🙂

After Fedora 17, I stopped clean installing any of following Fedora releases. For Fedora 18 and 19, I did only “fedup” (FEDora UPgrader tool). In both cases, the upgradation process went well with no known glitches whatsoever at all.

The only problem was that, my machine was using GRUB and not GRUB2, latter which Fedora 18 and 19 adopted for bootloading process. “fedup” process didn’t update GRUB automatically to GRUB2. I tried the manual upgradation and didn’t work on Mac machines (and it was not much supported at that time).

But, GRUB was working flawlessly with Mac’s own Boot Manager, rEFIt, rEFInd, etc., despite GRUB legacy was no longer used on EFI systems starting from Fedora 18. So, I was happy letting the Linux bootloader be GRUB, until the following error message showed up during boot process immediately after updating the kernel to 3.10.3-300 (the numbers really don’t matter).

fb: conflicting fb hw usage nouveaufb vs EFI VGA – removing generic driver

I tried my best to rectify the problem with all the varying kernel boot parameters like nomodset, single, acpi=off, acpi=ht, removing rhgb, quiet, etc. Nothing worked. I had no way to enter into Fedora 19, for quite some weeks.

Fortunately, I backed up the entire ESP partition immediately after having tried grub2-efi installation and creating grub configuration file, before reverting to GRUB, which led me to have a copy of “grub.cfg” with old Fedora 18 kernel parameters.

So, I mounted Fedora 19 ISO image file in Mac OS X, copied the EFI, mach_kernel, System structure from mounted ANACONDA partition to Linux ESP (or you can test run on a USB stick formatted with “Mac OS extended” partition) and replaced the “grub.cfg” with backed up “grub.cfg”. Booted with this Linux ESP (or USB partition) and replaced the old kernel number with new kernel number in editing mode. And, voilà, it booted after some painful weeks of silence. So, I figured it out it’s the absence of GRUB2 that has caused this video related problem.

This write-up is for updating GRUB to GRUB2 uniquely on Mac machines with 64 bit EFI and for 64 bit Fedoras. This also servers the purpose of rectifying corrupted GRUB2 in your Fedora on Mac machine.

This write-up is based on these following posts:

The directory structure of Linux ESP, a Mac OS extended (not journaled) partition, on Mac machines, consists of a file called “mach_kernel” and two directories “EFI” and “System”.

It is the files inside System → Library → CoreServices and “mach_kernel”, that take care of Mac machines Boot Manager, Mac OS X (or BootCamp Microsoft Windows) System Preferences → Startup Disk, EFI bootloading, etc.

EFI directory has BOOT, fedora and redhat subdirectories. GRUB seems to be using redhat and GRUB2 is using fedora. BOOT has files for fallback during booting.

Install GRUB2 for EFI. This creates the necessary /boot/efi/EFI/fedora directory files and updates /boot/efi/EFI/BOOT files.

$ sudo yum install grub2-efi shim

Create the GRUB configuration “grub.cfg” file.

$ sudo grub2-mkconfig -o /boot/efi/EFI/fedora/grub.cfg

Now, create a link to this file in System → Library → CoreServices.

$ sudo ln -s /boot/efi/EFI/fedora/grub.cfg /boot/efi/System/Library/CoreServices/grub.cfg

That is it. Make sure inside System → Library → CoreServices directory, you have a grubx64.efi file, a grub.cfg link, SystemVersion.plist file and an optional boot.efi file (I’m not sure whether it’s required or not, test it on your own).

Remember, inside this ESP partition, simple copy/paste (cp command) seems to work always. If you’re an advanced user and have trouble with EFI-GRUB booting, hesitate not to play around with files created by grub2-efi command and from aforementioned ANACONDA partition.

If you’re still having problems, try this detailed step-by-step process for updating GRUB on EFI systems.

Thanks for the read and please leave comments🙂

You can install rEFInd either on Mac machine’s EFI partition (the very first partition) or anywhere on Mac OS X’s partition. You can also install it on USB Stick/Hard Drive’s EFI or other partitions. Below method explains installing rEFInd on a USB Stick which is formatted using “GUID Partition Table” as partition scheme. Same works for installing rEFInd on Mac machine or USB Hard Drive.

We are going to install rEFInd on the first partition “EFI” (ie: diskxs1, x being your USB flash drive’s number) of the USB flash drive.

diskutil list

diskutil list

First mount the “EFI” partition. Issue:

$ mkdir /Volumes/EFI
$ sudo mount -t msdos /dev/disk1s1 /Volumes/EFI

Now, go to rEFInd website and download the CD-R image file. You can also use the binary zip file. But the CD-R image file contains the said binary zip file, docs as well as other goodies. Extract the .zip file and mount the resulting .iso file. Once mounted, copy the “EFI” folder, which contains “boot” subfolder, and paste it to the mounted “EFI” volume. In Mac machines, once mounted, you will already have “EFI” folder with “APPLE -> EXTENSIONS” subfolder. Don’t mess with the “APPLE” folder, which contains the firmware. You just copy the “boot” subfolder onto the already existing “EFI” folder. The “EFI” folder is not case-sensitive since it is on “msdos” partition. If yours is a 64 bit EFI, you may delete the “bootia32.efi” file and the “drivers_ia32” folder, which are present in “boot” folder. That is it.

You may also want to add extra tools like EFI shell, GPT Sync, etc. to the rEFInd Boot Manager.

rEFInd Screen

rEFInd Screen

To do so, you need tools, which are NOT provided by rEFInd. These tools can be found in rEFIt, from which rEFInd is derived. Though rEFIt is now discontinued and it was last updated on March 2010, these tools are very useful and some other aspects are recycled and used in rEFInd. Go to rEFIt website and download the .dmg file. Mount the .dmg file, go to “efi -> tools” folder and copy the tools you want to use. Now, go to “EFI” volume, “EFI” folder and create a folder called “tools” and paste the copied tools on to the “tools” folder.

rEFIt tools Folder

rEFIt tools Folder

Once it’s done, in “EFI” volume, go to “EFI -> boot” folder and edit “refind.conf” file as below.

refind.conf File

refind.conf File

It’s done. Now, your “EFI” volume has an “EFI” folder, which contains “boot” and “tools” subfolders.

In this manual installation method we install “bootx64.efi(fallback filename) file of rEFInd instead of “refind_x64.efi” file. This, in general, does not require issuing “bless” command, especially for USB Stick/Hard Drive. Also, when you press “Alt (Option)” key immediately after the startup CHIME, Mac machine’s Startup Manager brings rEFInd as an option of booting the machine.

On Mac machines, if you want to enable rEFInd permanently, issue:

1) For EFI installation:

$ sudo bless --mount /Volumes/EFI --setBoot --file /Volumes/EFI/EFI/boot/bootx64.efi

2) For other folder installation:

$ sudo bless --setBoot --folder "$TARGETDIR" --file "$TARGETDIR/bootx64.efi"

Where “$TARGETDIR” stands for the directory in which you installed rEFInd. Option “—setBoot” enables rEFInd permanently. Better “$TARGETDIR be “/efi/boot” or “/efi/refind“.

Alternatively, you can install rEFInd using the supplied shell command “install.sh“, which installs refind_x64.efi.

  • ./install.sh” installs rEFInd on Mac OS X’s root partition as “/EFI/refind“.
  • ./install.sh —esp” installs rEFInd on EFI partition.
  • For other options including installing “bootx64.efi” using “./install.sh” see extra install.sh instructions.

Note:

1) Better install rEFInd on EFI partition, since around 200 MB of unused disk space is sitting idle there. Also use “bootx64.efi” file, which makes things a lot easier for Mac machine’s Startup Manager.

2) For Windows or Linux installation, check rEFInd installation document page.

3) Copy a desired .icns file from “EFI -> boot -> icons” folder in rEFIt or rEFInd and paste it on to USB Stick’s EFI partition (root of the partition) and then rename it as “.VolumeIcon.icns”. This will display an icon for rEFInd while startup by pressing “Alt (Option)” key immediately after the startup CHIME.

Partition Icons

Partition Icons

Once everything is done, you can safely eject or unmount the volume.

$ umount /Volumes/EFI/

Thanks for the read and please leave comments🙂

For web-designers, graphic artists, animators and others who work with Adobe Photoshop, Gimp, Apple Motion, Adobe After Effects, Blender, etc. Rulers are very important to measure the screen elements. There are many free and paid Rulers out there to do this job.

But for a hyper-quick solution, without opening any Apps, to measure elements on screen, simply use the built-in Screen Capture command (Command (⌘) + Shift + 4). Simply press Command (⌘) + Shift + 4 and then use mouse to click and drag to select/measure the region or the elements of your interest. To avoid taking screenshots simply press the ESC key before releasing the button. Don’t worry if you forgot to press ESC key and released the mouse. The taken screenshots will be saved on to the Desktop, so you can delete them later.

The built-in Screen Capture command has some awesome ways to select a particular region of our interest either for taking a screenshot or in our case for measurement. Only in Leopard or later, hold down the following key or key combinations while selecting an area:

  • Space – Lock the size of the selected region and move the region wherever you want.
  • Left or Right Shift + Space – Lock the selected region and move only either horizontally or vertically.
  • Left or Right Shift – Resize the selected region only towards one side, either vertical or horizontal.
  • Option (⌥) – Resize the selected region all sides with its center as the anchor point.
  • Left or Right Shift + Option (⌥) – Resize the selected region either up and down or left and right with its center as the anchor point.

In Tiger and its predecessors above options are not available. Also only in Leopard or later the X, Y axis pixels are displayed near the crosshair.

If you find any new key combinations please share them in the comments section.

Thanks for the read and please leave comments🙂

Note:

  • I worked only on 64 bit platforms. For 32 bit platforms it could be the same or may be even much easier. So try it on your own.
  • This write-up is about how to prepare multiboot installation USB flash drive on Mac OS for the purpose of booting uniquely from Intel Mac machines. Mine is MacBook Pro 17″ (3.1, late 2007 with 64 bit EFI).
  • In all cases a simple “cp -R” command does the trick to prepare the bootable volumes.

Requirements:

  1. A USB flash drive with size, say above 8, 16, 32GB or whatever that suits your needs.
  2. The respective Operating Systems’ ISO/DMG files. And that’s it.

Prepare your USB flash drive:

Launch Disk Utility. Select the USB flash drive and click on “Partition” tab. Select the number of partitions you want to make from the “Partition Layout” drop down menu (In my case I opted for 4 partitions). Now click on “Options…” found below “Partition Layout” and select “GUID Partition Table” and click “OK”.

Note: To boot from a Mac machine it is important that the Hard drive’s or USB flash drive’s “Partition Map Scheme” must be “GUID Partition Table”.

GUID Partition Table

GUID Partition Table

Click on the partitions and edit “Name”, “Format” and “Size” according to your needs.

Partition Layout

Partition Layout

On my 32GB SanDisk I created:

  1. Name: Mountain Lion, Format: Mac OS Extended (Jounaled), Size: 5GB
  2. Name: WIN8PROWMC, Format: MS-DOS (FAT), Size: 5GB
  3. Name: FEDORA17, Format: MS-DOS (FAT), Size: 5GB
  4. Name: DataStorage, Format: ExFAT, Size: 17GB

After editing the partitions click on “Apply” to create the partitions.

Prepare MOUNTAIN LION installation boot volume:

Once you downloaded Mountain Lion for installation from “Mac App Store“, get the “InstallESD.dmg“. To do that go to “/Applications” folder. Locate “Install OS X Mountain Lion“. Right click on it and select “Show Package Contents” from the pop-up menu. Open “Contents -> SharedSupport” folder. Double click on “InstallESD.dmg” to mount it. The name of the mounted Volume would be like “Mac OS X Install ESD” and it would be sitting in the Disk Utility.

Method 1:

Click on it from Disk Utility and hit “Restore” tab. Now, the “Source” box will be populated with “Mac OS X Install ESD“. Drag and drop the Mac OS partition from the left side list under the USB flash drive (in my case “Mountain Lion“) on to the “Destination” box. Hit “Restore” to write the image on to the partition. Once it’s written the partition “Name” will change into “Mac OS X Install ESD” and “Format” will become “Mac OS Extended“. That is it. This partition is ready for booting the installation media of Mountain Lion. You can rename the partition “Mac OS X Install ESD” back to “Mountain Lion“.

Restore

Restore

Method 2:

Launch Terminal from Utilities folder. Issue:

$ cp -R “/Volumes/Mac OS X Install ESD”/* “/Volumes/Mountain Lion”/

(or)

$ ditto “/Volumes/Mac OS X Install ESD”/* “/Volumes/Mountain Lion”/

Though “cp” seems to be quite fast.

It’s that simple. Only thing is that make sure all the hidden files and directories such as mach_kernel, boot.efi, etc. are copied properly. Issue an “ls -al” command to verify it.

This volume boots off and installs Mountain Lion flawlessly on to your internal hard disk or external USB flash drive or hard disk.

Prepare FEDORA 17 installation boot volume:

First copy the entire “Fedora-17-x86_64-DVD.iso” or whatever respective ISO file directly to the desired USB flash drive’s partition (In my case FEDORA17 partition).  Then extract ONLY the “images” folder from “Fedora-17-x86_64-DVD.iso” to the same partition. No other folders or files (hidden or not) are required. Use “The Unarchiver“, which is available in Mac App Store for free, or others to extract files. If a file called “TRANS.TBL” is present in every folder, you can delete all by searching for the said file in Finder’s search box under FEDORA17 volume and once all the “TRANS.TBL” files are listed delete them all.

Once it’s done, now mount the same ISO file using “DiskImageMounter“. It mounts a ridiculously small sized volume called “ANACONDA“. Drag and drop all of its contents (EFI, System and mach_kernel) to FEDORA17 partition in Finder. The FEDORA17 partition should look like the image below.

FEDORA17 Partition's Contents

FEDORA17 Partition’s Contents

Now go to the System -> Library -> CoreServices folder. This is the folder structure where all the information needed to do an EFI boot is put. This applies to Mountain Lion, Fedora 17, Windows 8, etc..

Open the “boot.conf” file using a text editor. Modify the first entry as shown below.

title Fedora 17
root (hd0,3)
kernel /images/pxeboot/vmlinuz repo=hd:LABEL=FEDORA17:/
initrd /images/pxeboot/initrd.img

boot.conf File

boot.conf File

In (hd0,3), 0 is your USB flash drive and 3 is your FEDORA17 partition. It’s important that the “LABEL” in kernel command must be assigned the exact name of your “FEDORA17” partition label. If there is any blank spaces in partition label use “\x20” for a single blank space. It’s better you avoid any blank spaces in partition label.

As soon as the “mach_kernel” file is present in any partition, that partition will be added to “System Preferences -> Startup Disk“. These Startup Disk partitions are available in installed Mountain Lion, Mountain Lion installation environment, and in Boot Camp installed Window 8.

That’ is it. Your FEDORA17 installation boot volume is ready.

Note 1:

  • I arrived at the above mentioned solution after having tried different permutations and combinations of “root=“, “repo=” and others. So, it must be working for most of you.
  • In this method, I didn’t encounter “AttributeError: ‘NoneType’ object has no attribute ‘format’“, which was persistent in my other trials. This error came just after preparing/formating the installation media and Anaconda was trying to locate local installation repo.
  • The error “ISO image could not be mounted. Verify that the media is not LVM or RAID” also vanished.
  • I didn’t encounter any bootloader installation problem or any such.
  • I tried to install Fedora 17 from one USB flash drive to another. It went smoothly without any glitches whatsoever though it took an awful lot of time (around 8 hours for Desktop installation). It’s may be because of a direct ISO repo on a USB 2.0 to another USB 2.0. Anyway, now, the installed Fedora 17 Desktop boots off smoothly in EFI mode from the USB flash drive.

Note 2:

I installed Fedora 17 on my MacBook Pro using a USB flash drive prepared using dd command:

$ sudo dd if=Fedora-17-x86_64-DVD.iso of=/dev/disk1 bs=1m

The installation went flawlessly without any glitches.

Prepare Windows 8 installation boot volume:

Note:

  • The below method worked only once (at the very first time, which is quite bizarre since it is not supposed to work on my old Mac machine). After that, all my attempts resulted in Windows 8 getting booted and ending up displaying an error message “Status: 0x000000e Unexpected error occurred” complaining about change/problem in hardware settings.
  • The problem is that, Apple uses EFI 1.1 whereas Microsoft supports UEFI 2.1, so it is not going to work smooth anytime soon without BIOS emulation. Compared to other operating systems like Fedora, Ubuntu or other tools, Microsoft does not provide a decent support for EFI on Mac machines and others.
  • According to this forum, the real issue lies in hardware problem related to video cards. Some users had success following the guidance given by the forum members.
  • The below method may work for MacBook Air and other new Mac machines. So, try it on your own.

It is simple, just mount the ISO image and drag & drop all files to your Windows partition, in my case WIN8PROWMC. At root level there must be a folder called “efi” containing “boot” and “Microsoft” subfolders. Make sure the “boot” folder has a file called “bootx64.efi“. Once it is done:

  • Boot from Windows 8 partition by pressing and holding down “Alt (Option)” key immediately after the startup CHIME.
  • Or select “bootx64.efi” from rEFIt or rEFInd menu, if you have installed one of those Boot Managers (See below to find how to install rEFInd).

Alternatively, you can go to “EFI Shell” and issue:

Shell> fs6:
fs6:> \efi\boot\bootx64.efi

Where fs6 stands for the Windows partition of your USB flash drive, in my case WIN8PROWMC.

Prepare rEFInd Boot Manager:

We are going to install rEFInd on the first partition “EFI” (ie: diskxs1, x being your USB flash drive’s number) of the USB flash drive. But you can also install it on any other partitions of your choice, if you want.

diskutil list

diskutil list

First mount the “EFI” partition. Issue:

$ mkdir /Volumes/EFI
$ sudo mount -t msdos /dev/disk1s1 /Volumes/EFI

Now, go to rEFInd website and download the CD-R image file. You can also use the binary zip file. But the CD-R image file contains the said binary zip file, docs as well as other goodies. Extract the .zip file and mount the resulting .iso file. Once mounted, copy the “EFI” folder, which contains “boot” subfolder, and paste it to the mounted “EFI” volume. You may delete the “bootia32.efi” file and the “drivers_ia32” folder, which are present in “boot” folder. That is it.

You may also want to add extra tools like EFI shell, GPT Sync, etc. to the rEFInd Boot Manager.

rEFInd Screen

rEFInd Screen

To do so, you need tools, which are NOT provided by rEFInd. These tools can be found in rEFIt, from which rEFInd is derived. Though rEFIt is now discontinued and it was last updated on March 2010, these tools are very useful and some other aspects are recycled and used in rEFInd. Go to rEFIt website and download the .dmg file. Mount the .dmg file, go to “efi -> tools” folder and copy the tools you want to use. Now, go to “EFI” volume, “efi” folder and create a folder called “tools” and paste the copied tools on to the “tools” folder.

rEFIt tools Folder

rEFIt tools Folder

Once it’s done, in “EFI” volume, go to “efi -> boot” folder and edit “refind.conf” file as below.

refind.conf File

refind.conf File

It’s done. Now, your “EFI” volume has an “efi” folder, which contains “boot” and “tools” subfolders. You can safely eject or unmount the volume.

$ umount /Volumes/EFI/

Note:

1) Since it is GUID Partition Table (GPT), you can add as many OS boot/installation partitions or other tools as you want as long as they are EFI and GPT compatible.

2) In all cases, a simple direct extraction of files from the ISO/DMG to the respective partitions does the trick. Or mount the ISO/DMG and drag & drop or issue a simple “cp -R *” or “ditto” command from the /Volumes towards the respective partitions.

3) You access these partitions by pressing and holding “Alt (Option)” key immediately after the startup CHIME. This results in the Startup Manager bringing all bootable volumes.

4) Copy a desired .icns file from “efi -> boot -> icons” folder in rEFIt or rEFInd and paste it on to the root folder of corresponding partitions (Mountain Lion, Fedora, Windows or rEFInd, etc.) and then rename it as “.VolumeIcon.icns”. This will display the appropriate icon of the associated partition while startup after pressing “Alt (Option)” key.

Partition Icons

Partition Icons

5) I worked only with Fedora 17 and not with Fedora 18 since I didn’t like the new Anaconda Installer, where customized installation is not possible (I felt comfortable upgrading from 17 to 18 using “FedUp“). Also, Fedora 18’s unsupported GRUB 2 on EFI machine and Fedora 18’s DVD ISO image exceeding 4GB limit for a FAT32 filesystem put a check on my testing process for time being.

Thanks for the read and please leave comments🙂

Method 1:

Create and copy a table in Microsoft Word or in NeoOffice (Mac OS X) or OpenOffice/LibreOffice Writer or copy a table from any HTML page and directly paste it in the “Visual Editor”. That’s it. You can see the automatically created code complete with tags when switching to “Text Editor”.

But, somehow, tables created using Pages (Mac OS X) are not working. Bizarrely though, tables created in Pages copied and pasted to Word or Writer then copied and pasted in “Visual Editor” works perfectly well. Strange!!!

Note: Better don’t use “Paste from Word” which will be visible after enabling “Show/Hide Kitchen Sink (Alt + Shift + Z)” from “Visual Editor”.

Method 2:

If you don’t have Pages or Word or Writer handy, then use the following simple HTML code in “Text Editor” mode for the following table.

Row 1, Coulmn 1 Row 1, Coulmn 2 Row 1, Coulmn 3
Row 2, Coulmn 1 Row 2, Coulmn 2 Row 2, Coulmn 3

Code:

<table style=”margin: auto;” border=”1″>
<tbody>
<tr>
<td>Row 1, Coulmn 1</td>
<td>Row 1, Coulmn 2</td>
<td>Row 1, Coulmn 3</td>
</tr>
<tr>
<td>Row 2, Coulmn 1</td>
<td>Row 2, Coulmn 2</td>
<td>Row 2, Coulmn 3</td>
</tr>
</tbody>
</table>

A bit more sophisticated table.

Code:

<style type=”text/css”><!–
P { margin-bottom: 0.08in; }
–></style>
<table width=”583″ border=”1″ cellspacing=”0″ cellpadding=”7″><colgroup> <col width=”184″ /> <col width=”178″ /> <col width=”177″ /> </colgroup>
<tbody>
<tr valign=”TOP”>
<td bgcolor=”#b0b3b2″ width=”184″></td>
<td bgcolor=”#b0b3b2″ width=”178″>
<p align=”CENTER”><span style=”color: #000000;”><span style=”font-family: Helvetica,sans-serif;”><span style=”font-size: medium;”><b>Column 1</b></span></span></span></p>
</td>
<td bgcolor=”#b0b3b2″ width=”177″>
<p align=”CENTER”><span style=”color: #000000;”><span style=”font-family: Helvetica,sans-serif;”><span style=”font-size: medium;”><b>Column 2</b></span></span></span></p>
</td>
</tr>
<tr valign=”TOP”>
<td width=”184″><span style=”color: #000000;”><span style=”font-family: Helvetica,sans-serif;”><span style=”font-size: medium;”>Row 1</span></span></span></td>
<td width=”178″></td>
<td width=”177″></td>
</tr>
<tr valign=”TOP”>
<td width=”184″><span style=”color: #000000;”><span style=”font-family: Helvetica,sans-serif;”><span style=”font-size: medium;”>Row 2</span></span></span></td>
<td width=”178″></td>
<td width=”177″></td>
</tr>
<tr valign=”TOP”>
<td width=”184″><span style=”color: #000000;”><span style=”font-family: Helvetica,sans-serif;”><span style=”font-size: medium;”>Row 3</span></span></span></td>
<td width=”178″></td>
<td width=”177″></td>
</tr>
</tbody>
</table>

To align center:

Use style=”margin: auto;” as other methods like “align center” are deprecated. Usage example:

Code:

<table style=”margin: auto;” width=”206″ border=”0″ cellspacing=”1″ cellpadding=”1″>

Note: The methods discussed in this blog may give a different result or may not work in old and unsupported browsers. And again, the underlying “Theme” of your WordPress blog will also mess up the tables. Both the tables given in this example looked good in “Visual Editor“. But when once published, in the original post, they are completely different or messed up.

Thanks for the read and please leave comments🙂

You can easily capture, record and export live streaming audio, without destroying the quality, using Soundflower and Audacity, which are free tools. This following method can also be used to capture whatever sound that is played on your Mac machine.

  1. Download and install the latest Open-Source Audio Routing tool Soundflower.
  2. Download and install the excellent Open-Source Audio Editing tool Audacity.
  3. If required and you wish to export the captured/recorded audio stream to MP3 file format,
    • Download and install LAME MP3 Encoder as well. Or get it directly from here. Once installed, go to Audacity -> Preferences -> Libraries and verify whether it’s properly located. If not click on the «Locate» button to locate it.
    • Or go to Audacity -> Preferences -> Libraries and click on «Download» button and follow it from thereon.

Audacity Preferences Window

Start Soundflower (Soundflowerbed) and if required, complete the initial configuration. Soundflower icon will now be sitting on the Task Bar.

Soundflower Menu on Task Bar

Soundflower has two modes: 1) Soundflower (2ch) – two channel and 2) Soundflower (16ch) – 16 channel along with other configured Audio Input/Output peripherals. While Mac’s Internal Speaker has 0 Inputs/2 Outputs and Internal Mic has 2 Inputs/0 Outputs, Soundflower (2ch) has 2 Inputs/2 Outputs and Soundflower (16ch) has 16 Inputs/16 Outputs.

Now to capture/record live streaming audios:

  1. Go to System Preferences,  -> System Preferences -> Sound -> Output and select Soundflower (2ch) as Output.System Preferences Sound
  2. Under Sound Effects, disable all sound effects so that they will not interfere and spoil a clean recording process.
  3. Now launch Audacity.
    • Either go to Audacity -> Preferences -> Audio I/O, and under Recording, change the Device to Soundflower (2ch). Leave the Output Device as Built-in Output, so that you can monitor the recording process.

    • Or change the settings directly in Audacity itself.

Now, you can easily record any audio streamed through internet with great quality.

First start the Audacity Recording by clicking on Record button. Then start any internet or other live stream audio (which you have already readied for playback) so that recording goes correctly. Later, you can edit the recorded sound, add effects or make any other audio manipulation that can be done using Audacity.

Once recording is done and stopped, go to File -> Export, select your favorite format like mp3, wav, aiff, etc. and click on Save. It will open another window for Tag Editting. Fill it if required or just proceed with exporting. Voilà, now you have recorded and exported a live streaming audio with same quality as streamed using Soundflower and Audacity.

Don’t forget to change the audio settings back to normal after recording your favorite audio streaming. And please respect Copyright rules.

Edited later:

A) Soundflower works great with QuickTime 7.x as well (Mine is “Pro”. I’m not sure about “Non Pro”). But no luck with QuickTime 10.x.

B) To listen to playback while recording, do the following:

  1. Launch Soundflower. From menu, under Soundflower (2ch), select “Built-in Output” (pervious one would be “None (OFF)“).
  2. Open System Preferences. Under Sound, set Soundflower (2ch) as both Output and Input.
  3. Now open Audacity. Set Soundflower (2ch) as “Recording Device” and 2 (Stereo) as “Recording Channels”. Leave Built-in Output as “Playback device”.

C) Suggestion:

Want to try something simple, I recommend Wondershare AllMyMusic. Lightweight. User friendly. Intuitive.

Key features:

  • Easy to Use – Just One-Click Smart Recording.
  • Play and Record Automatically – Records only when Audio is played. Stops and Splits when Silence.
  • Record Audio with 100% Original Quality (1:1 Quality Ratio Lossless Audio).
  • Identify Songs and get Music Info.
  • Personalize Your Recordings – Tag Editing, Metadata Retrieval, etc.
  • Seamless Integration with OS and iTunes.
  • Drag and Drop CD Burning Tool.
  • Record Unlimited Free Music – Over 500 Radio Stations, YouTube, Pandora, Yahoo Music, etc.
  • Available for both Mac and Windows.

Technical specifications for Mac – Supported O/P format and settings:

  • Format           :  MP3 (*.mp3), M4A (*.m4a)
  • Sample Rate   :  44100Hz
  • Encoder         :  .mp3:(MP3),  .m4a:(AAC)
  • Bit Rate          :  256kbps, 320kbps

Update 1 (For El Capitan):

SoundFlower is broken in Mac OS X El Capitan. Relax, there is a solution, in fact a better one.

  • Download the newest version from here: Soundflower 2 (Signed. Beta version)
  • Double click to mount the downloaded .dmg file.
  • Run “Uninstall Soundflower.scpt
  • REBOOT. It is a must. You need to Reboot.
  • Run the installer “Soundflower.pkg“. That’s it!

Previous SoundFlower is 2ch & 16ch. This one is 2ch & 64ch. You cannot find this new version installed in “Application” folder and hence you cannot directly launch it. It is installed as “Kernel Extension“. But, you can find SoundFlower options in “System Preferences -> Sound” and “Audacity Preferences“. Enjoy!

Update 2 (For QuickTime Player):

SoundFlower works (including the newest version) great with QuickTime Player 10.x (recent one is 10.4 (854)) as well.

  • Go to “System Preferences -> Sound
  • Set both “Input” and “Output” as SoundFlower 2ch
  • Open QuickTime Player -> File -> New Audio Recording

And start recording the streaming audio (or whatever the system sound) flawlessly. Enjoy!

Thanks for the read and please leave comments🙂

This is also an example program for:

  • How to hide input for entering password (Console ECHO OFF/ON),
  • How to get input from keyboard without pressing ENTER,
  • How to restrict keyboard to get only one character as input at a time,
  • How to suspend/resume multiple threads effectively, etc..

After an exhaustive googling to find a perfect (clearly understandable) way of doing suspend/resume threads and having went through many not much satisfying sort of producer/consumer examples, I wrote this program.

There are many ways of doing thread suspend/resume:

  • Using Mutexes and Boolean Variables,
  • Using Thread Conditions,
  • Using Semaphores,
  • Using Signals,
  • Using Message Passing Interface, etc.

This program employs a combination of Boolean Variables, Mutexes and Thread Conditions.

The program is simple. The main thread (function main()) creates/initializes and launches four threads which run simultaneously. They are:

  1. watch_for_user_keypress_thread, which goes into a loop and wait for user input and suspend/resume other three threads according to user keypress. This thread also handles terminal settings (i.e. tty console settings).
  2. func_one_thread, which is a resource independent thread that counts variable count_one and prints it in STDERR stream.
  3. func_two_thread, which is also resource independent and does the same process like func_one, but on counter count_two.
  4. func_three_thread, adds count_one and count_two and prints the result along with its own counter count in STDERR stream.

Inputs to the program are:

  • 1 – is a toggle switch to suspend/resume thread_one
  • 2 – is a toggle switch to suspend/resume thread_two
  • 3 – is a toggle switch for thread_three
  • 0 – ends watch_for_user_keypress and signals all the threads to stop their execution and quit
  • Other keypress – nothing happens

The program is not complicated and is self-explanatory.

// multitask_multithread.c

#include <pthread.h>
#include <stdio.h>
#include <termios.h>
#include <time.h>

#define TRUE 	1
#define FALSE 	0

// Current tty console settings variable
static struct termios tty_state_current;

// Threads 1, 2 and 3 declared as global
pthread_t func_one_thread, func_two_thread, func_three_thread;

// Thread conditions
pthread_cond_t thread_cond_one, thread_cond_two, thread_cond_three;

// Thread mutex to go with thread conditions
pthread_mutex_t mutex_flag;

// Boolean flags
short tflag_one_on, tflag_two_on, tflag_three_on, quit_flag = FALSE;

// Counters for threads 1 and 2
int count_one, count_two = 0;

// tty console ECHO ON
int echo_on() {
  struct termios tty_state;

  if(tcgetattr(0, &tty_state) < 0)
    return -1;
  tty_state.c_lflag |= ECHO;
  return tcsetattr(0, TCSANOW, &tty_state);
}

// tty console ECHO OFF
int echo_off() {
  struct termios tty_state;

  if(tcgetattr(0, &tty_state) < 0)
    return -1;
  tty_state.c_lflag &= ~ECHO;
  return tcsetattr(0, TCSANOW, &tty_state);
}

// Restore tty console settings to its previous original state
void restore_terminal_settings(void) {
  tcsetattr(0, TCSANOW, &tty_state_current);
}

// Disable waiting for ENTER and accept only one keypress as input
void disable_waiting_for_enter(void) {
  struct termios tty_state;

  tcgetattr(0, &tty_state_current);  // Get current tty console settings
  tty_state = tty_state_current;
  tty_state.c_lflag &= ~(ICANON | ECHO);
  tcsetattr(0, TCSANOW, &tty_state);
  atexit(restore_terminal_settings); // Very handy function to restore settings
}

// Take user keypress and suspend/resume other threads accordingly
void *watch_for_user_keypress() {
  char getKeyPress;

  disable_waiting_for_enter();
  echo_off();

  do {
    getKeyPress = getchar();
    switch (getKeyPress) {
      case 49:
        if(!tflag_one_on) {
          tflag_one_on = TRUE;
          pthread_mutex_lock(&mutex_flag);
          pthread_cond_signal(&thread_cond_one);
          pthread_mutex_unlock(&mutex_flag);
        } else {
          tflag_one_on = FALSE;
        }
        break;
      case 50:
        if(!tflag_two_on) {
          tflag_two_on = TRUE;
          pthread_mutex_lock(&mutex_flag);
          pthread_cond_signal(&thread_cond_two);
          pthread_mutex_unlock(&mutex_flag);
        } else {
          tflag_two_on = FALSE;
        }
        break;
      case 51:
        if(!tflag_three_on) {
          tflag_three_on = TRUE;
          pthread_mutex_lock(&mutex_flag);
          pthread_cond_signal(&thread_cond_three);
          pthread_mutex_unlock(&mutex_flag);
        } else {
          tflag_three_on = FALSE;
        }
    }
  } while(getKeyPress != 48);

  quit_flag = TRUE;

  pthread_cond_broadcast(&thread_cond_one);
  pthread_cond_broadcast(&thread_cond_two);
  pthread_cond_broadcast(&thread_cond_three);

  //echo_on(); // No need for this since atexit() restores previous settings
  pthread_exit(NULL);
}

void *func_one() {
  pthread_mutex_lock(&mutex_flag);
  pthread_cond_wait(&thread_cond_one, &mutex_flag);
  pthread_mutex_unlock(&mutex_flag);

  if(quit_flag) pthread_exit(NULL);

  while(TRUE) {
    if(!tflag_one_on) {
      pthread_mutex_lock(&mutex_flag);
      pthread_cond_wait(&thread_cond_one, &mutex_flag);
      pthread_mutex_unlock(&mutex_flag);
    }
    if(quit_flag) break;
    fprintf(stderr, "<<--%d-->> ", ++count_one);
    sleep(1);
  }

  pthread_exit(NULL);
}

void *func_two() {
  pthread_mutex_lock(&mutex_flag);
  pthread_cond_wait(&thread_cond_two, &mutex_flag);
  pthread_mutex_unlock(&mutex_flag);

  if(quit_flag) pthread_exit(NULL);

  while(TRUE) {
    if(!tflag_two_on) {
      pthread_mutex_lock(&mutex_flag);
      pthread_cond_wait(&thread_cond_two, &mutex_flag);
      pthread_mutex_unlock(&mutex_flag);
    }
    if(quit_flag) break;
    fprintf(stderr, "<<oo%doo>> ", ++count_two);
    sleep(1);
  }

  pthread_exit(NULL);
}

void *func_three() {
  int count = 0;

  pthread_mutex_lock(&mutex_flag);
  pthread_cond_wait(&thread_cond_three, &mutex_flag);
  pthread_mutex_unlock(&mutex_flag);

  if(quit_flag) pthread_exit(NULL);

  while(TRUE) {
    if(!tflag_three_on) {
      pthread_mutex_lock(&mutex_flag);
      pthread_cond_wait(&thread_cond_three, &mutex_flag);
      pthread_mutex_unlock(&mutex_flag);
    }
    if(quit_flag) break;
    fprintf(stderr, "<<==%d::%d==>> ", ++count, count_one+count_two);
    sleep(1);
  }

  pthread_exit(NULL);
}

int main(int argc, char *argv[]) {
  pthread_t watch_for_user_keypress_thread;

  // Thread mutex initialization
  pthread_mutex_init(&mutex_flag, NULL);

  // Thread condtions initialization
  pthread_cond_init(&thread_cond_one, NULL);
  pthread_cond_init(&thread_cond_two, NULL);
  pthread_cond_init(&thread_cond_three, NULL);

  // Thread creation
  pthread_create(&watch_for_user_keypress_thread, NULL, watch_for_user_keypress, NULL);
  pthread_create(&func_one_thread, NULL, func_one, NULL);
  pthread_create(&func_two_thread, NULL, func_two, NULL);
  pthread_create(&func_three_thread, NULL, func_three, NULL);

  // main() launches these four threads and starts waiting for their completion
  pthread_join(watch_for_user_keypress_thread, NULL);
  pthread_join(func_one_thread, NULL);
  pthread_join(func_two_thread, NULL);
  pthread_join(func_three_thread, NULL);

  // All threads exited normally
  printf("\n");

  return 0;
}

Compile it.

$ gcc multitask_multithread.c -o multitask_multithread -lpthread

The output looks like:

$ ./multitask_multithread
<<–1–>> <<–2–>> <<–3–>> <<–4–>> <<–5–>> <<–6–>> <<oo1oo>> <<–7–>> <<oo2oo>> <<–8–>> <<oo3oo>> <<–9–>> <<oo4oo>> <<–10–>> <<oo5oo>> <<–11–>> <<oo6oo>> <<–12–>> <<–13–>> <<–14–>> <<–15–>> <<–16–>> <<–17–>> <<–18–>> <<==1::24==>> <<==2::24==>> <<==3::24==>> <<oo7oo>> <<==4::25==>> <<oo8oo>> <<==5::26==>> <<oo9oo>> <<==6::27==>> <<–19–>> <<oo10oo>> <<==7::29==>> <<–20–>> <<oo11oo>> <<==8::31==>> <<–21–>> <<oo12oo>> <<–22–>> <<oo13oo>> <<–23–>> <<oo14oo>> <<–24–>> <<–25–>> <<–26–>> <<–27–>> <<–28–>> <<–29–>> <<–30–>> <<oo15oo>> <<–31–>> <<oo16oo>> <<–32–>> <<oo17oo>> <<–33–>> <<==9::50==>> <<oo18oo>> <<–34–>> <<==10::52==>> <<oo19oo>> <<–35–>> <<==11::54==>> <<oo20oo>> <<–36–>> <<==12::56==>> <<oo21oo>> <<–37–>> <<==13::58==>> <<oo22oo>>

Note 1: Bad programming ethics. Any outputs of a program are not supposed to be printed onto error (STDERR) stream. Only errors should be printed using STDERR. This sort of bad ethics affects the usage of standard pipes>”, “<” and “|” and other operations.

Note 2: Instead of printing normal output onto STDERR, we can use functions like kbhit()/getch() or other workarounds that suppress “keyboard input wait” hindering background threads printing onto STDOUT stream.

Thanks for the read and please leave comments🙂

This is also a solution to:

  • mpicc” or “mpif90” command not found
  • Sample C program for Open MPI under Fedora
  • libmpi.so.1: cannot open shared object file” problem, etc.

The Open MPI is an open source “Message Passing Interface” implementation for High Performance Computing or Supercomputing, which is developed and maintained by a consortium of research, academic and industry partners.

After a successful Fedora 15 installation, I found

  • blacs-openmpi (BLACS – Basic Linear Algebra Communication Subprograms),
  • openmpi, and
  • scalapack-openmpi (SCALAPACK – Scalable LAPACK (Linear Algebra PACKage))

are already installed on my system.

openmpi” package simply provides execution tools like mpiexec, mpirun and others like ompi-clean, ompi-iof, ompi-ps, etc.

To have the compiler wrappers (for C, C++ and Fortran, i.e.: mpicc, mpic++, mpif77, mpif90, etc.) and their respective VampirTrace, you need to install “openmpi-devel” (no need of mpich/mpich2). So issue:

$ sudo yum install openmpi-devel

Fedora does not install the required compiler executables under default /usr/bin, /usr/sbin or /usr/local/bin, etc. and libraries under default /usr/lib or /usr/lib64, etc., but under /usr/lib64/openmpi/bin and /usr/lib64/openmpi/lib. And the $PATH variable is not updated to include these paths. This results in “mpicc: Command not found” error when you try to issue such commands.

Sample Master/Slave C program:

// master_slave.c

#include <stdio.h>
#include <mpi.h>
#include <unistd.h>

int main(int argc, char *argv[]) {
        int num_procs, rank, namelength;
        char processor_name[MPI_MAX_PROCESSOR_NAME];

        MPI_Init(&argc, &argv);
        MPI_Comm_size(MPI_COMM_WORLD, &num_procs);
        MPI_Comm_rank(MPI_COMM_WORLD, &rank);
        MPI_Get_processor_name(processor_name, &namelength);

        if (rank == 0) {
                printf("[%02d/%02d %s]: I am the master of all known universe\n", rank+1, num_procs, processor_name);
        // Tell the slaves to bring some wine or a Cat o' nine tails.
        }
        else {
                printf("[%02d/%02d %s]: I am a humble poor slave\n", rank+1, num_procs, processor_name);
        // Wait for some orders or 1001 lashes...
        }

        MPI_Finalize();
}

Compile it with:

$ /usr/lib64/openmpi/bin/mpicc master_slave.c
or
$ /usr/lib64/openmpi/bin/mpicc master_slave.c -o master_slave

Run the executable with:

$ /usr/lib64/openmpi/bin/mpirun a.out
or
$ /usr/lib64/openmpi/bin/mpirun master_slave

mpicc is a wrapper for gcc or other default compiler with necessary compiler/linker flags. Open MPI team “strongly” suggests not to use the underlying default compilers. Without humoring their suggestion let’s go for gcc compilation.

$ gcc -I/usr/include/openmpi-x86_64 -L/usr/lib64/openmpi/lib -pthread -m64 -lmpi -ldl -Wl,–export-dynamic -lnsl -lutil -lm -ldl master_slave.c -o master_slave

Above gcc does both compilation and linking at the same time. If you want to do compilation and linking separately:

$ gcc -I/usr/include/openmpi-x86_64 -pthread -m64 -c master_slave.c
$ gcc -L/usr/lib64/openmpi/lib -pthread -m64 -lmpi -ldl -Wl,–export-dynamic -lnsl -lutil -lm -ldl master_slave.o -o master_slave
$ /usr/lib64/openmpi/bin/mpirun master_slave

You will find the necessary compiler/linker flags by issuing:

$ /usr/lib64/openmpi/bin/mpicc –showme:compile

-I/usr/include/openmpi-x86_64 -pthread -m64
$ /usr/lib64/openmpi/bin/mpicc –showme:link

-pthread -m64 -L/usr/lib64/openmpi/lib -lmpi -ldl -Wl,–export-dynamic -lnsl -lutil -lm -ldl

Under a simulated slow network environment with four systems connected, the output would be:

[01/04 Fedora15.MacBookPro]: I am the master of all known universe
[02/04 Majnun]: I am a humble poor slave
[03/04 Devdas]: I am a humble poor slave
[04/04 Aesop]: I am a humble poor slave

Tips:

  • Add “PATH=$PATH:/usr/lib64/openmpi/bin” without quotes to your .bash_profile so that you don’t need to type the entire “/usr/lib64/openmpi/bin” path repeatedly. Or as a temporary fix issue:

$ export PATH=$PATH:/usr/lib64/openmpi/bin

  • 1) When you try to run ./a.out or ./master_slave directly it will give the following error:

./master_slave: error while loading shared libraries: libmpi.so.1: cannot open shared object file: No such file or directory

  • 2) When you try to run mpirun a.out or mpirun master_slave it will give the following error:

master_slave: error while loading shared libraries: libmpi.so.1: cannot open shared object file: No such file or directory
————————————————————————–
mpirun noticed that the job aborted, but has no info as to the process that caused that situation.
————————————————————————–

  • 1) and 2) happen so because the loader is not able to find the libmpi.so due to non availability of /usr/lib64/openmpi/lib in its PATH (LD_LIBRARY_PATH). To fix it add “LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/lib64/openmpi/lib” without quotes to your .bash_profile. Or as temporary fix issue:

$ export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/lib64/openmpi/lib

  • To make this change at system level (i.e.: effective to all users), as root, edit the /etc/ld.so.conf file, add “/usr/lib64/openmpi/lib” without quotes and run ldconfig or reboot the system.
  • Now you can issue ./a.out or ./master_slave directly or mpirun a.out or mpirun master_slave. All will give the same result, though stick to mpirun, which has more controls and options. See here the man page.

Thanks for the read and please leave comments🙂