Showing posts with label linux. Show all posts
Showing posts with label linux. Show all posts

02 February 2013

330. Installing Arch linux: installing from existing linux onto an external USB HDD

Update: You might want to look at this post instead: http://verahill.blogspot.com.au/2013/02/331-full-linux-install-on-usb-stick.html -- it covers setting up Arch with LXDE (very, very basic set-up -- more openbox than lxde) and wicd

I'll update this post once I've got a good solution to setting up network on headless boxes (i.e. a way of bringing up multiple interfaces without knowing their mac addresses)

Original post:

Note: what follows is what I've 'discovered' while learning. If you have suggestions, feel free to post comments. If you have questions, be aware that I'm only a beginning at Arch myself and will probably not have much advice to offer.

The problem: I have a headless server running 32 bit debian. I don't actually use it much, and so I figured I might as well use it to explore Gentoo or Arch. Given that it's a single core atom I didn't want to risk spending hours compiling things just to get things up and running (Feb/March are busy days at Australian Unis) and I figured that Arch, with it's version of ports, ABS, is a better choice for now.

I'm also curious about systemd, which arch uses by default. (that curiosity has currently turned to frustration)

Why Arch?
I do like my debian, but you need to challenge yourself every now and again. I can also see how a more 'sparse' distro might be a good candidate for my cluster nodes -- less overhead is a good thing. But before doing that I need a test case.

Also, even though I've been using debian I occasionally pay a visit to the Arch wiki and forum when I run into trouble with software that I've compiled myself -- Arch is a lot more bleeding edge than debian (which emphasizes stability), and the information there is often quite good.

Well then...
The easiest way (needing little preparation) by far to install arch would be to use ArchBang which is fast, pretty and functional. I don't need the graphical environment, and I want the learning experience. Otherwise I'd definitely give that a look as well: http://archbang.org/

We'll follow this guide: https://wiki.archlinux.org/index.php/Install_from_Existing_Linux

We'll use method "2: Chroot into LiveCD image".

I've ripped out the harddrive from the headless box and have attached it via USB to my main desktop, which runs Debian Testing.

I've rewritten this guide a couple of time -- not everything worked smoothly from the beginning -- so if it's unreadable and confusing, let me know. Also, due to the lack of versioning in blogspot I have had to try to recover/rewrite from memory, which annoys me.

A word of warning: at one point when working in a chroot I accidentally did grub-install /dev/sda instead of /dev/sdc. I then did update-grub in the main system and rebooted. I should've done grub-install /dev/sda again but from the host system. Anyway, you might screw things up, so a first precaution will be to burn a live CD of some linux distro that you can use to rescue your system with if you mess things up too badly. I'm a debian guy, but I found that the Ubuntu Rescue Remix (http://ubuntu-rescue-remix.org/) was a pretty good thing to have lying around.

Overview:
1. Nuke the existing file system (not necessary, but easier)
2. Get the iso and unsquash it
3. Mount the unsquashed image using chroot, and mount your hdd under it. Get packages
4. Chroot inside the chroot and install the bootloader
5. Set up network


Get started


Format/Prepare your harddrive:
In this case I'm using a 40 Gb hard drive. Since it's so small I'll just partition it to hold one / partition and one /swap partition. We'll make the swap partition 1 Gb which should be plenty, given that the box has 512 Mb RAM. Make sure that you leave enough space before you partition -- 1 Mb is overkill, but is something you can afford. In my original attempt I used palimpsest to format my drive and ended up having to shrink the partition using gparted. Better to use fdisk which may be slightly more challenging, but will give you full control.

Remove the harddrive from your target box, and attach it to your running linux desktop e.g. via USB (or by opening the case and hooking it up via sata/pata). If it automounted, do df -h so see what device it is (here /dev/sdc), otherwise just do ls /dev/sd* before and after it's attached.

df -h
Filesystem Size Used Avail Use% Mounted on /dev/sdc1 36G 15G 20G 43% /media/steelhead
Unmount it:
sudo umount /media/steelhead

We now know that our disk is /dev/sdc, so let's get cracking with fdisk
fdisk -u -l /dev/sdc
Disk /dev/sdc: 40 GB, 40007761920 bytes 255 heads, 63 sectors/track, 4864 cylinders, total 78140160 sectors Units = sectors of 1 * 512 = 512 bytes Device Boot Start End Blocks Id System /dev/sdc1 * 63 78140159 39070048 83 Linux
We want our swap to be 1 Gb. (40007761920 bytes /4864 cylinders)/(1024*1024*1024)=.00766038894653320312 Gb per cylinder or ca 130.5 cylinders per Gb. Our first partition will start at cylinder 2 and run until cylinder (4864-131=)4733.

sudo fdisk /dev/sdc
Command (m for help): d
Partition number (1-1): 1
Command (m for help): n
Partition type e extended p primary partition (1-4)
p First cylinder (default 0cyl): 2 Last cylinder or +size or +sizeMB or +sizeKB (default 4863cyl): 4733 Command (m for help): n
Partition type e extended p primary partition (1-4)
p First cylinder (default 0cyl): 4735 Last cylinder or +size or +sizeMB or +sizeKB (default 4863cyl): Command (m for help): w sudo fdisk /dev/sdc Command (m for help): p
Disk /dev/sdc: 40 GB, 40007761920 bytes 255 heads, 63 sectors/track, 4864 cylinders Units = cylinders of 16065 * 512 = 8225280 bytes Device Boot Start End Blocks Id System /dev/sdc1 2 4734 38025792 83 Linux Warning: Partition 1 does not end on cylinder boundary. /dev/sdc2 4735 4864 1036192 83 Linux
Command (m for help): a Partition number (1-2): 1 Command (m for help): t Partition number (1-2): 2 Hex code (type L to list codes): 82 Changed type of partition 2 to 82 (Linux swap) Command (m for help): w

The cylinder boundary warning is why we started the next partition on cylinder 4735, so as to avoid overlap. 'a' makes the first partition bootable. 't' creates the swap fs.

Create the file system for partition 1:
sudo mkfs.ext4 /dev/sdc1
sudo mkswap /dev/sdc2


Get the iso:
sudo apt-get install bittorrent
cd ~/Downloads
btdownloadcurses https://www.archlinux.org/iso/2013.01.04/archlinux-2013.01.04-dual.iso.torrent

If you're company/isp/whatever has a blanket ban on P2P (e.g. bittorrent) download the file using regular http, e.g.
cd ~/Downloads
wget http://mirror.aarnet.edu.au/pub/archlinux/iso/2013.01.04/archlinux-2013.01.04-dual.iso

However you downloaded it, do:
sudo apt-get install squashfs-tools
sudo mount -o loop archlinux-2013.01.04-dual.iso /mnt
unsquashfs -d /tmp/squashfs-root /mnt/arch/i686/root-image.fs.sfs

This is for a 32 bit install. Most likely you'll want the 64 bit, so change i686 to x86_64 for that. Also note that the unsquashed image is 1.4 Gb so make sure you put it somewhere with sufficient space.

Continue:

sudo umount /mnt
sudo mount -o loop /tmp/squashfs-root/root-image.fs /mnt
sudo mount -t proc none /mnt/proc
sudo mount -t sysfs none /mnt/sys
sudo mount -o bind /dev /mnt/dev
sudo mount -o bind /dev/pts /mnt/dev/pts
sudo cp /etc/resolv.conf /mnt/etc/resolv.conf
sudo chroot /mnt
[root@beryllium /]#

You're now in the chroot.

In the chroot:
mount /dev/sdc1 /mnt
mkdir /run/shm

Since I am installing 32 bit Arch from a 64 bit host, I had to edit /etc/pacman.conf using nano and change
23 Architecture = auto
to
23 Architecture = i686

If you are installing 64 bit Arch from a 64 bit host you don't need to edit anything. Also, the only editor installed by default is nano, not vi, for some reason.

Finally, edit /etc/pacman.d/mirrors and copy/paste (ctrl+k, ctrl+u) the nearest/most logical mirror to the beginning of the file.

pacman-key --init
pacman-key --populate archlinux
pacstrap /mnt base base-devel vim grub-bios openssh
==> Creating install root at /mnt ==> Installing packages to /mnt warning: database file for 'core' does not exist warning: database file for 'extra' does not exist warning: database file for 'community' does not exist :: Synchronizing package databases... core 105.1 KiB 15.8K/s 00:07 [##################] 100% [..] Total Download Size: 163.59 MiB Total Installed Size: 603.01 MiB [..]
I got a couple of errors above re file systems (during grub init) that arch had no business looking at. I don't think it matters since the next chroot is what's important.
pacman -Syy
genfstab -p /mnt >> /mnt/etc/fstab
cat /mnt/etc/fstab
# # /etc/fstab: static file system information # #

# UUID=ae73518f-5675-486e-8cdd-6579c528ab72 LABEL=steelhead /dev/sdc1 / ext4 rw,relatime,data=ordered 0 1 # UUID=f25a484c-e8e2-4ead-808b-96dd5e915020 /dev/sda5 none swap defaults 0 0
Two problems here:
* Since this will be the only hdd on the new system the root partition is probably /dev/sda1. Change the sdc1 to sda1 above OR use UUID
* Likewise, the swap will be the current sdc2 but the future sda2. Alternatively, get the UUID via blkid.

Here's my new two-line version of fstab with uuid:
UUID=ae73518f-5675-486e-8cdd-6579c528ab72 / ext4 rw,relatime,data=ordered 0 1 UUID=a12b484c-f2d2-4edd-8d8b-76ee6f725020 none swap defaults 0 0
Continue:

arch-chroot /mnt

which gives
sh-4.2#

You're now in a chroot inside a chroot.

A chroot within a chroot:


pacman -Syy
pacman-key --init
pacman-key --populate archlinux
ln -s /usr/share/zoneinfo/Australia/Melbourne /etc/localtime
echo "kookaburra" > /etc/hostname

Kookaburra is the hostname of the new Arch box.

Edit /etc/pacman.conf and change Architecture from auto to i686 if you need to.

Edit /etc/locale.gen and uncomment the locales you want. For me
en_AU.UTF-8 UTF-8 en_GB.UTF-8 UTF-8 en_US.UTF-8 UTF-8

Continue working on boot:
locale-gen
echo 'LANG="en_AU.UTF-8"'>/etc/locale
echo 'KEYMAP=us'> /etc/vconsole.conf
mkinitcpio -p linux
==> Building image from preset: 'default' -> -k /boot/vmlinuz-linux -c /etc/mkinitcpio.conf -g /boot/initramfs-linux.img ==> Starting build: 3.7.4-1-ARCH -> Running build hook: [base] [..] ==> Creating gzip initcpio image: /boot/initramfs-linux-fallback.img ==> Image generation successful
grub-mkconfig -o /boot/grub/grub.cfg
Generating grub.cfg ... Found linux image: /boot/vmlinuz-linux Found initrd image: /boot/initramfs-linux.img done

Check /boot/grub/grub.cfg to see that it exists and that it doesn't look like it's about to blow up. Double-check the uuid vs fstab. Check the 'root'. Mine was wrong. I changed it in /boot/grub/grub.cfg by hand, which isn't recommended but we'll deal with that later. In /boot/grub/grub.cfg change hdX to whatever the correct setting is (counting starts at 0) e.g.
  
        set root='hd0,msdos1'

since /dev/sdc in the future will be the only hdd. Changing this file by hand is untenable in the long run, but our goal is to boot and then regenerate the grub.cfg at a later stage.

grub-install /dev/sdc
Installation finished. No error reported.
Then continue -- in this case we're working with a headless box so we want openssh-server and all that:

passwd
Enter new UNIX password: Retype new UNIX password: passwd: password updated successfully
pacman -S net-tools ifplugd dialog sudo wireless_tools wpa_supplicant wpa_actiond systemctl enable sshd.service systemctl enable net-auto-wired.service systemctl enable net-auto-wireless.service cp /etc/network.d/examples/ethernet-dhcp /etc/network.d/ethli

Edit the /etc/network.d/ethli file as shown in the next section.(the ethli name holds no significance)

adduser verahill -m

Edit /etc/sudoers and add:
verahill ALL=(ALL) ALL
pacman -S pkgtools mlocate htop screen elinks

Time to exit:

sh-4.2# exit
exit
[root@beryllium /]# umount /mnt
[root@beryllium /]# exit

You're now back in your normal host filesystem, and unmount the rest:
sudo umount /mnt/proc
sudo umount /mnt/sys
sudo umount /mnt/dev/pts
sudo umount /mnt/dev
sudo umount /mnt

At this point you have a bootable system. I attached the hdd to my laptop using USB, and chose to boot from it. Went fine. However, it turns out that networking in arch and/or using systemd is very different from debian and initd.

Networking:
Networking should be one of the easiest things in the world to set up, since if you have network access everything else will eventually sort itself out. No network means no remote access via ssh if the screen/keyboard/mouse get screwed up. No network means that you can't install anything. No network means that you can't go online and look up solutions.

initd was easy -- you checked your udev rules, then edited /etc/network/interfaces and added an auto eth0 line followed by e.g. iface eth0 inet dhcp or a more extensive static definition. It was easy.
So I'm a bit frustrated that systemd seems to make the whole process of managing network interfaces so much more difficult. At least for a newcomer.

With systemd your interfaces may not have simple names like eth0 right off the bat, but may have names like enpS08 instead -- it does make things a bit more difficult and unpredictable -- remember that my goal is to get a headless box up and running and that I have no way of getting any error messages -- openssh will simply have to work from the start. I mean, there's a certain logic to systemd, but there are plenty of frustrating issues with it too if you're used to chucking start-up commands in rc.local and setting up your own network devices.

Some of this stuff you could do by hand on a running system, but that's not very helpful when you are working with a headless box where your only option is to connect via ssh (technically I could do rs-232 but I can't find a cable).

Anyway.

Create /etc/udev/10-persisten-net.rules
SUBSYSTEM=="net", ATTR{address}=="00:2e:9e:2e:bb:20", KERNEL=="eth*", NAME="ethli"
SUBSYSTEM=="net", ATTR{address}=="00:e2:bb:be:d4:c8", KERNEL=="wlan*", NAME="wlan0"
and put the mac addresses of you interfaces in it.

Edit /etc/conf.d/netcfg to use the correct WIRED_INTERFACE,
NETWORKS=(ethli ethkb5 ethkb3 wpa-wireless)
WIRED_INTERFACE="ethli"
WIRELESS_INTERFACE="wlan0"
ethkb5, ethb3 and wpa-wireless are other files that I've set up in /etc/network.d/, although at this point they are pretty darned useless -- I can define plenty of profiles, but I can only define a single WIRED_INTERFACE from what I can tell. So only one interface will be started by netcfg.

Copy /etc/network.d/example/ethernet-dhcp to /etc/network.d/ethli, and edit the interface name.
CONNECTION='ethernet'
DESCRIPTION='A basic dhcp ethernet connection using iproute'
INTERFACE='ethli'
IP='dhcp'
Do the same for any other profiles.
For wireless, all you need to do is copy  /etc/network.d/examples/wpa-wireless to /etc/network.d/ and add the password in clear text (i.e. no need to use wpa_password). Change the permissions so that it's 'safe'.

Here's my wpa-wireless
CONNECTION='wireless'
DESCRIPTION='A simple WPA encrypted wireless connection'
INTERFACE='wlan0'
SECURITY='wpa'
ESSID='verahillunwired'
KEY='sadfUsfdjdsfH87j'
IP='dhcp'

The wired network should now start on boot. To launch it manually, just do
sudo netcfg ethli

This is where I'm currently at:
* arch works fine when I boot it by attaching the hdd via usb to a laptop or desktop and booting off of it. I have working internet and the sky's the limit to what can be done

* I can't get it to boot my headless box (or at least not to get a working network connection), and because it's completely headless (it's a server with only eth ports and an RS 232 port) I have no idea why. The logging in systemd leaves a lot to be desired it seems. I'm waiting for an rs-232 cable to arrive via ebay, so we'll see.
The two possibilities that I'm entertaining right now is that either there's an issue with the network devices or...well, I don't know. I'm also getting tired of netcfg and will probably switch to wicd -- it's not quite what I want, but at least I know that it works.
But more about that some other time...

Error 1:
# pacstrap /mnt
==> Creating install root at /mnt
mount: mount point /mnt/dev/shm is a symbolic link to nowhere
==> ERROR: failed to setup API filesystems in new root

Solution:
mkdir /run/shm

On debian /dev/shm points to /run/shm via a symlink, so your chroot has a dead link.

Error 2:
error: key "E62F853100F0D0F0" could not be looked up remotely
error: psmisc: key "FCF2CB179205AC90" is unknown
error: key "FCF2CB179205AC90" could not be looked up remotely
error: reiserfsprogs: key "7F2D434B9741E8AC" is unknown
error: key "7F2D434B9741E8AC" could not be looked up remotely

Solution:
pacman-key --init
pacman-key --populate archlinux

You need to get all the gpg keys so you can check the package signatures.

Error 3:
warning: database file for 'core' does not exist
warning: database file for 'extra' does not exist
warning: database file for 'community' does not exist

Solution:
pacman -Syy

Not sure, but probably due to me interrupting pacman rather rudely with ^C at some point.

Error 4:
# arch-chroot /mnt pacman -S grub-bios
error: failed to prepare transaction (package architecture is not valid) :: package grub-bios-2.00-1-i686 does not have a valid architecture
Solution:
pacstrap /mnt grub-bios

And then skip the arch-root command

Error:
grub-install /dev/sdc
/usr/sbin/grub-bios-setup: warning: your embedding area is unusually small.  core.img won't fit in it..
/usr/sbin/grub-bios-setup: warning: Embedding is not possible.  GRUB can only be installed in this setup by using blocklists.  However, blocklists are UNRELIABLE and their use is discouraged..
/usr/sbin/grub-bios-setup: error: will not proceed with blocklists.

Solution: You partitioned your system without leaving enough space before the first partition. In my case I had 32 sectors*512 bytes.
sudo apt-get install gparted
gparted
Start gparted and shrink the partition. I put 2 Mb (probably overkill) of free space in front, and aligned to cylinder.

28 January 2013

328. Liberate your router: dd-wrt on Netgear WGT624 v4

UPDATE 1 Feb 2013: I haven't had any explicit problems with my router since flashing it. Everything is apparently working well and my network connection is reliable and fine (if only subjectively a bit slower than before --  running a speed test shows that it's as fast as ever so not sure what's happening). HOWEVER, I've suddenly started having issues with ECCE and submitting jobs via a frontendMachine -- I kept getting "cannot 'cd' to run directory" errors, but the ECCE log contains no errors messages at all. This wouldn't happen for very small NWChem input files, and it would happen ca 80% of the time. Normally I wouldn't suspect this was a router issue, but changing back to my (unflashed) AR430W resolved the issues immediately. Somehow I suspect this is a router version of this http://verahill.blogspot.com.au/2012/09/briefly-packet-corrupt-during-ssh.html, but then I should see error messages in the ECCE log...

Other than that I'm really happy with dd-wrt (no sarcasm intended -- I've had no other issues and I love the power dd-wrt gives me over my hardware).

Finally, there's the old adage about correlation vs causuality. We'll see if the errors start popping up again while using my AR430W.

Original post:

I've been using Tomato with my WRT54G for a couple of years now, and I'm incredibly happy with it. Since I have a couple of old routers (airlink 1010 ar430w and netgear wgt624 v4) with stock firmware lying around I figured it was time to turn them into something useful. So here's how to flash the netgear router. If it stands up to sustained use I'll be writing an AR430W guide later.


dd-wrt


Lengthy preamble
The stock firmware basically does nothing for me -- it's clunky, slow, and there's no terminal access. In particular, I want busybox/ssh, Tomato does all that for me, but it doesn't support a particularly wide range of routers (I reckon that Tomato is the reason why Linksys WRT54GL still costs $90 in Australia, in spite of being old as sin -- those who doubt the value of opening up their hardware may want to consider the RoI on that one)

In addition to Tomato, there's also DD-WRT (supported devices) and OpenWRT (supported devices). DD-WRT support a huge number of routers, but it appears to be a whole lot more complicated to install than Tomato. Maybe this varies according to the router as well.

For instructions you're referred via the database to the dd-wrt forum thread about your router. The problem with this is that you'll be facing 30-odd pages with instructions, problems, dead-ends etc. Some threads end with a step-by-step summary on how to install dd-wrt, but not all do.

Anyway, here's my best attempt at writing a simple and complete step-by-step guide to replacing the stock firmware on Netgear WGT24 v4 with DD-WRT on Debian Testing/Wheezy. I'm basically just following this blog post: http://lauriaus.no-ip.org/blog/?p=90 , but hopefully I've added enough detail to make it possible for just about anyone to follow this guide.

Please consult http://www.dd-wrt.com/site/support/router-database to see what files you need. NOTE: the files below only apply to v4 of Netgear WGT624. Installing them on any other router may brick it.



On your linux computer:

Get the files:
sudo apt-get install atftpd tftp putty
cd /tmp
mkdir ftpdboot
cd ftpdboot/
wget http://www.dd-wrt.com/dd-wrtv2/downloads/others/redboot_collection/images_default/redboot_ap61_16M_4M_admtek.rom
wget http://www.dd-wrt.com/routerdb/de/download/Netgear/WGT624/v4/linux.bin/3614 -O linux.bin
wget http://www.dd-wrt.com/routerdb/de/download/Netgear/WGT624/v4/wgt624v4-firmware.bin/3613 -O wgt624v4-firmware.bin

Edit /etc/default/atftpd:
USE_INETD=false #true OPTIONS="--tftpd-timeout 300 --retry-timeout 5 --mcast-port 1758 --mcast-addr 239.239.239.0-255 --mcast-ttl 1 --maxthread 100 --verbose=5 /tmp/ftpdboot"

Edit /etc/inetd.conf
32 tftp dgram udp4 wait nobody /usr/sbin/tcpd /usr/sbin/in.tftpd --tftpd-timeout 300 --retry-timeout 5 --mcast-port 1758 --mcast-addr 239.239.239.0-255 --mcast-ttl 1 --maxthread 100 --verbose=5 /tmp/ftpdboot
and do
sudo /etc/init.d/openbsd-inetd reload

for good luck. If you don't have openbsd-inetd you may have xinetd or inetutils-inetd installed instead (I think openbsd-inetd is default on debian). Edit the command as necessary.

Edit your /etc/network/interfaces file:
auto eth0 iface eth0 inet static address 192.168.1.155 gateway 192.168.1.1 netmask 255.255.255.0

and run
sudo service networking restart

Make sure that your card came up ok (do e.g. ip addr)
2: eth0: broadcast mtu 1500 qdisc pfifo_fast state UP qlen 1000 link/ether 00:26:9e:27:9b:20 brd ff:ff:ff:ff:ff:ff inet 192.168.1.155/24 brd 192.168.1.255 scope global eth0
Continue.

Prepare two terminals, side by side (or start a screen session with two tabs open). In one, type
echo "^C"> end.txt
putty telnet 192.168.1.1:9000 -m end.txt

But don't hit enter after the second command.

In the other terminal, type
ping 192.168.1.1

but don't hit enter.

Connect the ethernet port on your computer to one of the ethernet LAN ports (not WAN/Internet) on your router.

You are next going to unplug the power from the router, and hit enter after the ping command. Immediately when you get ping replies:
64 bytes from 192.168.1.1: icmp_req=4 ttl=64 time=0.371 ms
you hit enter after the putty command in the other window. If nothing good happens, then redo (i.e. unplug the router, hit enter after the ping command etc. Don't start the ping until you're re-plugged the router).

Ready? GO!
ping 192.168.1.1
64 bytes from 192.168.1.1: icmp_req=1 ttl=64 time=0.371 ms
putty telnet 192.168.1.1:9000 -m end.txt

And you should get

Before you continue make sure that you've opened up your firewall e.g. if you're not connected to the internet you can go crazy like this:
sudo iptables -P INPUT ACCEPT
sudo iptables -P OUTPUT ACCEPT
sudo iptables -P FORWARD ACCEPT

And don't forget to restore your firewall once you're done.
Time to get dangerous.

RedBoot> fis init
About to initialize [format] FLASH image system - continue (y/n)? Y *** Initialize FLASH Image System ... Erase from 0xbffe0000-0xbfff0000: . ... Program from 0x80ff0000-0x81000000 at 0xbffe0000: . RedBoot> ip_address -h 192.168.1.155 IP: 192.168.1.1/255.255.255.0, Gateway: 192.168.1.254 Default server: 192.168.1.155
RedBoot> load -r -b %{FREEMEMLO} redboot_ap61_16M_4M_admtek.rom
Using default protocol (TFTP) TFTP timed out 1/15 Can't load 'redboot_ap61_16M_4M_admtek.rom': operation timed out
Try again:
RedBoot> load -r -b %{FREEMEMLO} redboot_ap61_16M_4M_admtek.rom
Using default protocol (TFTP) Raw file loaded 0x80040c00-0x8005007f, assumed entry at 0x80040c00
RedBoot> fis create -l 0x30000 -e 0xbfc00000 RedBoot fis create -l 0x30000 -e 0xbfc00000 RedBoot An image named 'RedBoot' exists - continue (y/n)? y ... Erase from 0xbfc00000-0xbfc30000: ... ... Program from 0x80040c00-0x80050080 at 0xbfc00000: . ... Erase from 0xbffe0000-0xbfff0000: . ... Program from 0x80ff0000-0x81000000 at 0xbffe0000: .
RedBoot> reset

You'll see a couple of flashing lights on the router as the only indication that something just happened. Kill your current putty connection and start a new one.
=~=~=~=~=~=~=~=~=~=~=~= PuTTY log 2013.01.28 20:29:38 =~=~=~=~=~=~=~ ^C
RedBoot> fis init
About to initialize [format] FLASH image system - continue (y/n)? y *** Initialize FLASH Image System ... Erase from 0xbffe0000-0xbfff0000: . ... Program from 0x80ff0000-0x81000000 at 0xbffe0000: .
RedBoot> ip_address -h 192.168.1.155
IP: 192.168.1.1, Default server: 192.168.1.155
RedBoot> load -r -b 0x80041000 linux.bin
Using default protocol (TFTP) Raw file loaded 0x80041000-0x803ecfff, assumed entry at 0x80041000
RedBoot> fis create linux

Be patient -- this step takes a long time: 19 minutes in my case (some routers take an hour). Write down the time when it starts and WAIT at least 20 minutes.
... Erase from 0xbfc10000-0xbffbc000: ........................................................... ... Program from 0x80041000-0x803ed000 at 0xbfc10000: ........................................................... ... Erase from 0xbffe0000-0xbfff0000: . ... Program from 0x80ff0000-0x81000000 at 0xbffe0000: .
RedBoot> fconfig
Run script at boot: true Boot script: .. fis load -l kernel .. go Enter script, terminate with empty line
>> fis load -l linux >> exec >> Boot script timeout (1000ms resolution): 12 Use BOOTP for network configuration: false bootp_my_gateway_ip: 192.168.1.254 Local IP address: 192.168.1.1 bootp_my_ip_mask: 255.255.255.0 Default server IP address: 192.168.1.55 Console baud rate: 9600 GDB connection port: 9000 Force console for special debug messages: false net_debug: false Update RedBoot non-volatile configuration - continue (y/n)? y ... Erase from 0xbffe0000-0xbfff0000: . ... Program from 0x80ff0000-0x81000000 at 0xbffe0000: . RedBoot> reset

Done!

You can now navigate to 192.168.1.1 in your router, but unplug, replug the router for good luck.
Success!


I created a user called admin and set a password i.e. there's no pw or username you need to know a priori.
click on services


check sshd

Don't trust important infrastructure with passwords. Use keys.




And finally
ssh root@192.168.1.1

and hopefully you're in.

First impressions:
The busybox ('linux') version is a bit too sparse for my liking -- no netstat command...but it's still obviously a major step up from the stock firmware. dd-wrt is different from tomato -- if you're used to one you're not necessarily going to feel comfortable with the other. Luckily, dd-wrt is widely used and there are plenty of resource online. In addition, there's a demo ( http://www.dd-wrt.com/demo/ ) so you can try it out before installing it.

How to set up 'static' dhcp (i.e. make sure that some computers always have the same IP address while still running a dhcp server) wasn't completely obvious either, but this post helped: http://www.dd-wrt.com/wiki/index.php/Static_DHCP


16 January 2013

320. Wsearch32 in Wine

Wsearch32 is a windows program that does what it's supposed to -- open mass spectrometer data files. Because our students use it quite a lot and to save me time in training them, here's how to install wsearch32 and how to get started with it. It runs almost perfectly in Wine.

One notable thing about Wsearch is that it opens HP Agilent Chemstation .D files without any problems. It's notable because different versions of HP Agilent Chemstation can't even open files written by other versions (yup, it's true...) of the same damned program.

Another obvious advantage of Wsearch is that it makes it very easy to export data, although it only exports one spectrum at a time (i.e. you can't get the full time-dependent data set).

WSearch was written by Frank Antolasic at the RMIT in Melbourne, Australia.


What doesn't work under Wine: It will freeze if you try to open several files at the same time. This does not happen on native Windows.




Installation
Download it from here: http://www.wsearch.com.au/
wget http://www.wsearch.com.au/wsearch32/wsearch32.zip
unzip wsearch32.zip
and follow the instructions:
There's nothing odd about the installation process

It works as well as under windows


Screenshots
This is the default view

Click on the import icon (the red one in the left corner), and select your file. There are plenty of supported formats.

This is the TIC view. Click anywhere on the TIC to get the corresponding spectrum

TIC and spectrum view.

Click on the M/I icon on the right to get a list of all the data in the spectrum plot..
You can then save the spectrum in a range of ascii based formats.


You can get the acquisition headers under Chromatogram/List header info. You can also make ion plots  in the same menu.
Wsearch also comes with a simple isotopic pattern calculator.

The Help works fine under linux/wine


This is the free version of wsearch -- there is some functionality missing.







12 January 2013

317. Compiling samba 4.0.0 on Debian Testing/Wheezy

Not much to say about this one -- samba/SMB is only one among several linux solutions for sharing files, and probably the easiest one for sharing directories with windows computers. Samba has also been around for about as long as linux, so it has a long and interesting history.

New major versions are always exciting though. Information about Samba 4 can be found here: http://wiki.samba.org/index.php/Samba4

I won't cover configuration here -- partly because I don't know much about it -- so see the link above. To get started you might want to look at this post though: http://verahill.blogspot.com.au/2012/12/300-briefly-sharing-folder-using-samba.html

I also wrote this a long time ago, but haven't checked it for accuracy:
http://verahill.blogspot.com.au/2012/03/building-and-installing-samba-from.html

These instructions will build Samba 4.0.0 with LDAP and Cluster support.
Compilation:
sudo apt-get install build-essential libacl1-dev libattr1-dev libaio-dev libpam0g-dev kfreebsd-headers-9.0-2 libtalloc-dev python-talloc-dev libtevent-dev valgrind libsasl2-dev python2.7-dev libgnutls-dev xsltproc libctdb-dev libldap2-dev libcups2-dev python-ldb-dev ldb-tools libldb-dev checkinstall
mkdir ~/tmp 
cd ~/tmp
wget http://www.samba.org/samba/ftp/stable/samba-4.0.0.tar.gz
tar xvf samba-4.0.0.tar.gz
cd samba-4.0.0/
./configure --prefix=$HOME/.smb4
time make
sudo checkinstall
dpkg -i samba_4.0.0-1_amd64.deb

And you're done. 

Takes about 14 minutes to compile. When you run checkinstall and you're asked
Some of the files created by the installation are inside the home directory: /home You probably don't want them to be included in the package. Do you want me to list them? [n]: n Should I exclude them from the package? (Saying yes is a good idea) [n]: n

Answer no, you DO want to include them. You're getting this warning because we set a --prefix and the files aren't going to the / structure like normal programs.

The samba daemon, smbd, is in ~/.smb4/sbin/ and the configuration files are in /etc/samba/.


Here's the structure of ~/.smb4:
~/.smb4/
|-- bin
|   |-- cifsdd
|   |-- dbwrap_tool
|   |-- eventlogadm
|   |-- gentest
|   |-- ldbadd
|   |-- ldbdel
|   |-- ldbedit
|   |-- ldbmodify
|   |-- ldbrename
|   |-- ldbsearch
|   |-- locktest
|   |-- masktest
|   |-- ndrdump
|   |-- net
|   |-- nmblookup
|   |-- nmblookup4
|   |-- ntlm_auth
|   |-- oLschema2ldif
|   |-- pdbedit
|   |-- pidl
|   |-- profiles
|   |-- regdiff
|   |-- regpatch
|   |-- regshell
|   |-- regtree
|   |-- rpcclient
|   |-- samba-tool
|   |-- sharesec
|   |-- smbcacls
|   |-- smbclient
|   |-- smbclient4
|   |-- smbcontrol
|   |-- smbcquotas
|   |-- smbget
|   |-- smbpasswd
|   |-- smbspool
|   |-- smbstatus
|   |-- smbta-util
|   |-- smbtorture
|   |-- smbtree
|   |-- testparm
|   `-- wbinfo
|-- etc
|-- include
|   |-- charset.h
|   |-- core
|   |-- credentials.h
|   |-- dcerpc.h
|   |-- dcerpc_server.h
|   |-- dlinklist.h
|   |-- domain_credentials.h
|   |-- gen_ndr
|   |-- gensec.h
|   |-- ldap-util.h
|   |-- ldap_errors.h
|   |-- ldap_message.h
|   |-- ldap_ndr.h
|   |-- ldb_wrap.h
|   |-- libsmbclient.h
|   |-- lookup_sid.h
|   |-- machine_sid.h
|   |-- ndr
|   |-- ndr.h
|   |-- netapi.h
|   |-- param.h
|   |-- passdb.h
|   |-- policy.h
|   |-- read_smb.h
|   |-- registry.h
|   |-- roles.h
|   |-- rpc_common.h
|   |-- samba
|   |-- samba_util.h
|   |-- share.h
|   |-- smb2.h
|   |-- smb2_constants.h
|   |-- smb2_create_blob.h
|   |-- smb2_signing.h
|   |-- smb_cli.h
|   |-- smb_cliraw.h
|   |-- smb_common.h
|   |-- smb_composite.h
|   |-- smb_constants.h
|   |-- smb_ldap.h
|   |-- smb_raw.h
|   |-- smb_raw_interfaces.h
|   |-- smb_raw_signing.h
|   |-- smb_raw_trans2.h
|   |-- smb_request.h
|   |-- smb_seal.h
|   |-- smb_share_modes.h
|   |-- smb_signing.h
|   |-- smb_unix_ext.h
|   |-- smb_util.h
|   |-- smbconf.h
|   |-- smbldap.h
|   |-- tdr.h
|   |-- torture.h
|   |-- tsocket.h
|   |-- tsocket_internal.h
|   |-- util
|   |-- util_ldb.h
|   `-- wbclient.h
|-- lib
|   |-- auth
|   |-- bind9
|   |-- gensec
|   |-- idmap
|   |-- ldb
|   |-- libdcerpc-atsvc.so -> libdcerpc-atsvc.so.0.0.1
|   |-- libdcerpc-atsvc.so.0 -> libdcerpc-atsvc.so.0.0.1
|   |-- libdcerpc-atsvc.so.0.0.1
|   |-- libdcerpc-binding.so -> libdcerpc-binding.so.0.0.1
|   |-- libdcerpc-binding.so.0 -> libdcerpc-binding.so.0.0.1
|   |-- libdcerpc-binding.so.0.0.1
|   |-- libdcerpc-samr.so -> libdcerpc-samr.so.0.0.1
|   |-- libdcerpc-samr.so.0 -> libdcerpc-samr.so.0.0.1
|   |-- libdcerpc-samr.so.0.0.1
|   |-- libdcerpc-server.so -> libdcerpc-server.so.0.0.1
|   |-- libdcerpc-server.so.0 -> libdcerpc-server.so.0.0.1
|   |-- libdcerpc-server.so.0.0.1
|   |-- libdcerpc.so -> libdcerpc.so.0.0.1
|   |-- libdcerpc.so.0 -> libdcerpc.so.0.0.1
|   |-- libdcerpc.so.0.0.1
|   |-- libgensec.so -> libgensec.so.0.0.1
|   |-- libgensec.so.0 -> libgensec.so.0.0.1
|   |-- libgensec.so.0.0.1
|   |-- libndr-krb5pac.so -> libndr-krb5pac.so.0.0.1
|   |-- libndr-krb5pac.so.0 -> libndr-krb5pac.so.0.0.1
|   |-- libndr-krb5pac.so.0.0.1
|   |-- libndr-nbt.so -> libndr-nbt.so.0.0.1
|   |-- libndr-nbt.so.0 -> libndr-nbt.so.0.0.1
|   |-- libndr-nbt.so.0.0.1
|   |-- libndr-standard.so -> libndr-standard.so.0.0.1
|   |-- libndr-standard.so.0 -> libndr-standard.so.0.0.1
|   |-- libndr-standard.so.0.0.1
|   |-- libndr.so -> libndr.so.0.0.1
|   |-- libndr.so.0 -> libndr.so.0.0.1
|   |-- libndr.so.0.0.1
|   |-- libnetapi.so -> libnetapi.so.0
|   |-- libnetapi.so.0
|   |-- libnss_winbind.so -> libnss_winbind.so.2
|   |-- libnss_winbind.so.2
|   |-- libnss_wins.so -> libnss_wins.so.2
|   |-- libnss_wins.so.2
|   |-- libpdb.so -> libpdb.so.0
|   |-- libpdb.so.0
|   |-- libregistry.so -> libregistry.so.0.0.1
|   |-- libregistry.so.0 -> libregistry.so.0.0.1
|   |-- libregistry.so.0.0.1
|   |-- libsamba-credentials.so -> libsamba-credentials.so.0.0.1
|   |-- libsamba-credentials.so.0 -> libsamba-credentials.so.0.0.1
|   |-- libsamba-credentials.so.0.0.1
|   |-- libsamba-hostconfig.so -> libsamba-hostconfig.so.0.0.1
|   |-- libsamba-hostconfig.so.0 -> libsamba-hostconfig.so.0.0.1
|   |-- libsamba-hostconfig.so.0.0.1
|   |-- libsamba-policy.so -> libsamba-policy.so.0.0.1
|   |-- libsamba-policy.so.0 -> libsamba-policy.so.0.0.1
|   |-- libsamba-policy.so.0.0.1
|   |-- libsamba-util.so -> libsamba-util.so.0.0.1
|   |-- libsamba-util.so.0 -> libsamba-util.so.0.0.1
|   |-- libsamba-util.so.0.0.1
|   |-- libsamdb.so -> libsamdb.so.0.0.1
|   |-- libsamdb.so.0 -> libsamdb.so.0.0.1
|   |-- libsamdb.so.0.0.1
|   |-- libsmbclient-raw.so -> libsmbclient-raw.so.0.0.1
|   |-- libsmbclient-raw.so.0 -> libsmbclient-raw.so.0.0.1
|   |-- libsmbclient-raw.so.0.0.1
|   |-- libsmbclient.so -> libsmbclient.so.0.2.0
|   |-- libsmbclient.so.0 -> libsmbclient.so.0.2.0
|   |-- libsmbclient.so.0.2.0
|   |-- libsmbconf.so -> libsmbconf.so.0
|   |-- libsmbconf.so.0
|   |-- libsmbldap.so -> libsmbldap.so.0
|   |-- libsmbldap.so.0
|   |-- libsmbsharemodes.so -> libsmbsharemodes.so.0
|   |-- libsmbsharemodes.so.0
|   |-- libtevent-util.so -> libtevent-util.so.0.0.1
|   |-- libtevent-util.so.0 -> libtevent-util.so.0.0.1
|   |-- libtevent-util.so.0.0.1
|   |-- libtorture.so -> libtorture.so.0.0.1
|   |-- libtorture.so.0 -> libtorture.so.0.0.1
|   |-- libtorture.so.0.0.1
|   |-- libwbclient.so -> libwbclient.so.0.11
|   |-- libwbclient.so.0 -> libwbclient.so.0.11
|   |-- libwbclient.so.0.11
|   |-- mit_samba.so
|   |-- nss_info
|   |-- pkgconfig
|   |-- private
|   |-- process_model
|   |-- python2.7
|   |-- security
|   |-- service
|   |-- vfs
|   `-- winbind_krb5_locator.so
|-- private
|-- sbin
|   |-- nmbd
|   |-- samba
|   |-- samba_dnsupdate
|   |-- samba_kcc
|   |-- samba_spnupdate
|   |-- samba_upgradedns
|   |-- samba_upgradeprovision
|   |-- smbd
|   |-- swat
|   `-- winbindd
|-- share
|   |-- codepages
|   |-- man
|   |-- perl5
|   |-- setup
|   `-- swat
`-- var
    |-- cache
    |-- lib
    |-- lock
    |-- locks
    `-- run


09 January 2013

310. Remote mounting using sshfs

I've run out of USB ports on my work desktop, so I occasionally cheat and attach USB drives to one of my compute nodes and transfer the files across the network to my desktop. Since I've got a gigabit switch set up, the speeds are quite acceptable.

NFS isn't really a solution here. Instead, sshfs is the tool to use.

The local and remote computer will be referring to Desktop and Node, respectively. The specific example I'm using here is that of a USB drive manually mounted on the Node, which contains pictures that I want to transfer to my Desktop.

On the Node
The plugged in USB device is found as /dev/sdb, and holds only one partition, /dev/sdb1.

sudo mkdir /media/usbdrive
sudo mount /dev/sdb1 /media/usbdrive


On the Desktop

sudo apt-get install sshfs
sudo mkdir /media/remote
sudo sshfs $USER@Node:/media/usbdrive /media/remote -o allow_other

That's about it. To unmount do
sudo umount /media/remote

and
sudo umount /media/usbdrive

respectively.

05 January 2013

303. Compiling Simon on Debian Testing (Simon 0.4)

Here's how to get Simon 0.4.0 compiled. Simon does speech recognition which allows you do voice-control your computer. It does NOT do transcription, e.g. like Dragon Naturally Speaking.

See e.g. here, here and here for more information about Simon.

Simon uses cmake. I hate cmake since it makes life a lot more difficult than it needs to be.

Also, note that Simon relies heavily on KDE, so you need a number of KDE related files -- if not the whole desktop -- installed. Obviously, it runs fine under GNOME, which is where I'm using it.

This post is limited to describing how to compile it, not how to use it -- that may come later.



First get the deendencies. The list of deps is taken from http://userbase.kde.org/Simon/Development_Environment#Requirements, and expanded (e.g. libboost).

sudo apt-get install qt4-qtconfig kdelibs5-dev libxtst-dev libsamplerate-dev kdepimlibs5-dev libboost-dev
sudo apt-get install build-essential cmake gettext kdeartwork libqwt-dev libqt4-sql-sqlite libphonon-dev libattica0 libattica-dev zlib1g-dev libasound2-dev 


Next sort out Julius
I think it used to be in the repos, but it's not there anymore from what I can see).

mkdir ~/tmp/simon -p
cd ~/tmp/simon
wget http://jaist.dl.sourceforge.jp/julius/56549/julius-4.2.2.tar.gz
tar xvf julius-4.2.2.tar.gz
cd julius-4.2.2/
./configure --prefix=~/.simon/julius
**************************************************************** Julius/Julian libsent library rev.4.2.2: - Audio I/O primary mic device API : alsa (Advanced Linux Sound Architecture) available mic device API : alsa oss supported audio format : RAW and WAV only NetAudio support : no - Language Modeling class N-gram support : yes - Libraries file decompression by : zlib library - Process management fork on adinnet input : no Note: compilation time flags are now stored in "libsent-config". If you link this library, please add output of "libsent-config --cflags" to CFLAGS and "libsent-config --libs" to LIBS. ****************************************************************
make make install cd ../


HTK
You'll need HTK to use adaptive models with the Voxforge base. It's not necessary otherwise.
To get HTK, register here: http://htk.eng.cam.ac.uk/register.shtml

You should receive a password immediately afterwards. Then go to http://htk.eng.cam.ac.uk/download.shtml and download the Linux sources.Put the HTK-3.4.1.tar.gz file in ~/tmp/simon.
cd ~/tmp/simon
tar xvf HTK-3.4.1.tar.gz
cd htk/
./configure --prefix=$HOME/.simon/htk --disable-hslab
make all
mkdir ~/.simon/htk
make install

For some reason it's built as 32 bit, not 64. Also, it wants the parent install directory to exist before running make install.

Next, sphinx:

wget http://sourceforge.net/projects/cmusphinx/files/sphinxbase/0.8/sphinxbase-0.8.tar.gz
tar xvf sphinxbase-0.8.tar.gz 
cd sphinxbase-0.8/
./configure --prefix=$HOME/.simon/sphinxbase
make
make install
cd ../


wget http://sourceforge.net/projects/cmusphinx/files/pocketsphinx/0.8/pocketsphinx-0.8.tar.gz
tar xvf pocketsphinx-0.8.tar.gz
cd pocketsphinx-0.8/
./configure --prefix=$HOME/.simon/pocketsphinx SphinxBase_CFLAGS=-I$HOME/.simon/sphinxbase/include/sphinxbase SphinxBase_LIBS=-L$HOME/.simon/sphinxbase/lib
make
make install
cd ../

wget http://sourceforge.net/projects/cmusphinx/files/sphinxtrain/1.0.8/sphinxtrain-1.0.8.tar.gz
tar xvf sphinxtrain-1.0.8.tar.gz
cd sphinxtrain-1.0.8/
./configure --prefix=$HOME/.simon/sphinxtrain SphinxBase_CFLAGS=-I$HOME/.simon/sphinxbase/include/sphinxbase SphinxBase_LIBS=-L$HOME/.simon/sphinxbase/lib
make
make install


I couldn't sort out OpenCV, so this Simon won't be watching you.


Finally, Simon.
wget http://mirrors.mit.edu/kde/stable/simon/0.4.0/src/simon-0.4.0.tar.bz2
tar xvf simon-0.4.0.tar.bz2
mkdir build/
cd build/
cmake -DCMAKE_INSTALL_PREFIX=~/.simon -DPOCKETSPHINX_LIBRARIES=$HOME/.simon/pocketsphinx/lib/libpocketsphinx.so -DPOCKETSPHINX_INCLUDE_DIR=$HOME/.simon/pocketsphinx/include/ -DSphinxBase_INCLUDE_DIR=$HOME/.simon/sphinxbase/include/ -DSphinxBase_LIBRARY=$HOME/.simon/sphinxbase/lib/libsphinxbase.so -DPJULIUS=$HOME/.simon/julius -DPSPHINX=$HOME/.simon/sphinxbase ../simon-0.4.0/

at which points you should see:
----------------------------------------------------------------------------- -- The following external packages were located on your system. -- This installation will have the extra features provided by these packages. ----------------------------------------------------------------------------- * LibSampleRate - Resampling library * KDE PIM Libs - KDE Libraries for PIM * Sphinxbase - Open source toolkit for speech recognition * PocketSphinx - PocketSphinx is a small-footprint continuous speech recognition system ----------------------------------------------------------------------------- -- The following OPTIONAL packages could NOT be located on your system. -- Consider installing them to enable more features from this software. ----------------------------------------------------------------------------- * qaccessibilityclient KDE client-side accessibility library Required to enable ATSPI plugin. * OpenCV OpenCV (Open Source Computer Vision) is a library of programming functions for real time computer vision Required for Simon Vision -----------------------------------------------------------------------------


And now a bit of a hackjob -- we give the sphinx include dirs above, and while it works fine for most include files (they use e.g. sphinxbase/includeme.h), a number of files (prim_type, sphnx_config.h etc.) point towards the wrong directory (e.g. #include ). Two solutions -- either edit the files or put symmlinks where the files are looking. Symmlinks work well for me.


ln -s ~/.simon/sphinxbase/include/sphinxbase/sphinx_config.h ~/.simon/sphinxbase/include/sphinx_config.h
ln -s ~/.simon/pocketsphinx/include/pocketsphinx/pocketsphinx_export.h ~/.simon/pocketsphinx/include/pocketsphinx_export.h
ln -s ~/.simon/pocketsphinx/include/pocketsphinx/cmdln_macro.h ~/.simon/pocketsphinx/include/cmdln_macro.h
ln -s ~/.simon/pocketsphinx/include/pocketsphinx/ps_lattice.h ~/.simon/pocketsphinx/include/ps_lattice.h
ln -s ~/.simon/pocketsphinx/include/pocketsphinx/ps_mllr.h ~/.simon/pocketsphinx/include/ps_mllr.h
ln -s ~/.simon/pocketsphinx/include/pocketsphinx/fsg_set.h ~/.simon/pocketsphinx/include/fsg_set.h

make
make install
cd ~/.simon/bin
export PATH=$PATH:/$HOME/.simon/julius/bin:$HOME/.simon/sphinxtrain/bin:$HOME/.simon/htk/bin:$HOME/.simon/bin
simond &
simon

I haven't really explored it yet, but here are the first few dialogues:




There's an official video which you may want to watch before you get started:



Issues:
Stuff that doesn't work: Configure Audio from within simon, Configure Acoustic Model from within Simon
Stuff that does work: speech recognition.

Note:
If you set it up 'wrong' the first time around (or it crashed coding samples as above)) and want the wizard to run again, delete all the configuration files:
rm ~/.kde/share/apps/simon* -rf
rm ~/.kde/share/config/simon*

Links to this post:
http://www.forum-raspberrypi.de/Thread-speech-to-text?pid=13465

28 October 2012

267. ECCE client connecting to remote site via reverse port/local port forwarding

The situation I'm about describe is quite specific, yet I don't think it's that unusual.

A. I've got a computer at work which is behind a firewall so that I can't connect directly to it from the outside. This will be referred to as Work.

B. I've got a laptop at home which is connected to a wireless  router. This will be referred to as Home.

C. The router is a Linksys/tomato router, which is accessible from the outside (myrouter.com). This will be referred to as Router.

I'd like to connect from home to my ecce server at work so that I can monitor and submit jobs.

At Work:
ssh -R 19997:localhost:8096 root@myrouter.com

At Home:
ssh -L 5555:localhost:19997 root@myrouter.com

We're basically tying together port 5555 at Home with port 8096 at Work, via an intermediary server.

At Home, edit your ecce/apps/siteconfig/Dataservers and change the relevant lines to

<eccedata>
  <ecceserver>
    <url>http://localhost:5555/Ecce</url>
    <desc>ECCE Data Server--remote</desc>
  </ecceserver>

  <basisset>http://localhost:5555/Ecce/system/GaussianBasisSetLibrary</basisset>
</eccedata>

Note that submission actually happens from your ecce client, not your server (i.e. from Home, not Work), so to get your submission scripts in order you may have to do a bit of fiddling. E.g. if you ecce server is also the queue master for an SGE batch system:

Work:
ssh -R 19999:localhost:22 root@myrouter.com

Home:
ssh -L 5454:localhost:19999 root@myrouter.com

Home:
Edit /apps/siteconfig/remote_shells.site and add
ssh_p5454: ssh -XC -p 5454|scp -P 5454|xterm

But you can read more about that here: http://verahill.blogspot.com.au/2012/05/port-redirection-with-eccenwchem.html

24 October 2012

265. shmmax revisited -- and shmall, shmmni

I've upgraded two of my nodes -- my old 4 core node with 8 GB ram now has 4x4=16 GB RAM, while my old 8 core, 16 GB ram now has 4*8=32 GB ram.

When using nwchem you eventually will run into an shmmax problem:


******************* ARMCI INFO ************************
The application attempted to allocate a shared memory segment of 44498944 bytes in size. This might be in addition to segments that were allocated succesfully previously. The current system configuration does not allow enough shared memory to be allocated to the application.

This is most often caused by:
1) system parameter SHMMAX (largest shared memory segment) being too small or
2) insufficient swap space.
Please ask your system administrator to verify if SHMMAX matches the amount of memory needed by your application and the system has sufficient amount of swap space. Most UNIX systems can be easily reconfigured to allow larger shared memory segments,
see http://www.emsl.pnl.gov/docs/global/support.html
In some cases, the problem might be caused by insufficient swap space.
*******************************************************
0:allocate: failed to create shared region : -1
(rank:0 hostname:boron pid:17222):ARMCI DASSERT fail. shmem.c:armci_allocate():1082 cond:0

I haven't gotten that in a while since I increased shmmax to 6572498432, but running a frequency calculation on a large molecule with unrestricted DFT triggered it again on my 32 GB node. So I hit google. These posts were informative:
http://www.pythian.com/news/245/the-mysterious-world-of-shmmax-and-shmall/
http://padmavyuha.blogspot.com.au/2010/12/configuring-shmmax-and-shmall-for.html
http://yuji.wordpress.com/2011/11/03/what-is-shmmax-shmall-shmmni-shared-memory-max/


me@neon:~$  cat /proc/sys/kernel/shmall
2097152
me@neon:~$ cat /proc/sys/kernel/shmni
4096
me@neon:~$ cat /proc/sys/kernel/shmmax
6572498432

That works out to (4096 bytes/page*2097152)*(1/(1024*1024*1024) bytes per gigabyte) pages=8.192 GB. And they are the same on all my nodes in spite of the memory available varying.

Another way of looking at it:
ipcs -lm

------ Shared Memory Limits --------
max number of segments = 4096
max seg size (kbytes) = 6418455
max total shared memory (kbytes) = 8388608
min seg size (bytes) = 1


Your shmmall is the number of pages total, the shmmni is the page size and the shmmax is the largest contigouos chunk of RAM available.

 So if I get things right, and parroting what's said on the pages above, your shmmall should approach but not exceed your total physical memory, you shmni is better left alone, and your shmmax can be anywhere up to your total RAM.

The links above cite Oracle recommendations which state that (for 32 bit system) it should be 4 GB - 1 byte OR half your RAM, whichever is smaller. I'll show that case here, but will be testing using 80% of my RAM for my calcs.

 So for my boxes:

32 GB RAM => shmmax=16GB, shmmall=(32-2 GB)/4095, shmni=4096
sudo sysctl -w kernel.shmmax=17179869184
sudo sysctl -w kernel.shmall=7340032
ipcs -lm

------ Shared Memory Limits -------- max number of segments = 4096 max seg size (kbytes) = 16777216 max total shared memory (kbytes) = 29360128 min seg size (bytes) = 1
16 GB RAM => shmmax=8GB, shmmall=(16-2 GB)/4096, shmni=4096
sudo sysctl -w kernel.shmmax=8589934592
sudo sysctl -w kernel.shmall=3670016


If you're happy with those values, make them permanent by editing your sysctl.conf and adding the relevant lines:
kernel.shmmax=17179869184
kernel.shmall=7340032


So here are the formulae (assuming that you set shmmax to half your ram and leave 2 gb out of shmall):
shmmax=RAM (bytes)/2
shmni=4096
shmmall=(RAM(bytes)-2147483648)/shmni

22 October 2012

263. Cyanogen mod on Nexus One

Note that you need an unlocked and rooted Nexus One for this. I did this in the past and can barely remember how I did it. So don't ask me. Also, I'm using linux for this, so asking me about OS X or Windows would be doubly unwelcome.

Besides, I'm just following orders: http://wiki.cyanogenmod.com/wiki/Nexus_One:_Full_Update_Guide

0. Back up everything. Root and unlock your Nexus One.
I used Titanium Backup and SMS Backup and Restore to back things up, just in case. Then I connected my phone to my computer and copied everything. I unlocked the boot loader and rooted my phone quite a while ago and so can't remember how it's best done.

Looking at the traces in my system I used bexboot.v2.GRK39F_OTA and I don't remember that it was difficult. Just be aware that everything on your phone WILL BE WIPED. So back stuff up.

cd ~/tmp
wget http://bexboot.googlecode.com/files/bexboot.v2.GRK39F_OTA.zip
unzip bexboot.v2.GRK39F_OTA.zip
cd bexboot.v2.GRK39F_OTA/
chmod +x fastboot-linux

1. Download stuff

1a. Download the cyanogen mod image:
wget http://download.cyanogenmod.com/get/jenkins/2857/cm-7.2.0-passion.zip
md5sum cm-7.2.0-passion.zip 
0d37cc25fd42b0ad00f87c9e009b7a9c cm-7.2.0-passion.zip
1b. Get the Amon Ra recovery image:
wget http://cmw.22aaf3.com/passion/recovery/recovery-RA-passion-v2.2.1-CM.img 
md5sum recovery-RA-passion-v2.2.1-CM.img 
e8262ae23943ce50fd346001812fae79 recovery-RA-passion-v2.2.1-CM.img
1c. Then get the google apps:
wget http://cmw.22aaf3.com/gapps/gapps-gb-20110828-signed.zip
md5sum gapps-gb-20110828-signed.zip
1647897d8ac3efb04723d2ad2c361a3f gapps-gb-20110828-signed.zip

This is a good time to move the gapps-gb-20110828-signed.zip and cm-7.2.0-passion.zip files to the root of your SD card.

2. Edit your /etc/udev/rules.d/51-android.rules
 I changed mine from

SUBSYSTEM=="usb", ATTR{idVendor}=="18d1", MODE="0666", GROUP="plugdev"
to

SUBSYSTEM=="usb", ATTR{idVendor}=="0bb4", MODE="0666", GROUP="plugdev"

since

Bus 001 Device 020: ID 0bb4:0fff HTC (High Tech Computer Corp.) Android Fastboot Bootloader

and did

sudo chmod a+rx /etc/udev/rules.d/51-android.rules
sudo service udev restart

3. Flash
Get Turn off your phone and plug in the usb cable. Hold down the scroll ball and, while holding it down, turn on your phone. Don't select anything. Instead, on your computer:
./fastboot-linux devices
HT015P801117 fastboot
So far so good!

./fastboot-linux flash recovery recovery-RA-passion-v2.2.1-CM.img 
sending 'recovery' (3380 KB)... OKAY
writing 'recovery'... OKAY
On your phone, select "bootloader" then "recovery", which starts the Android System Recovery  -- look at the bottom of the screen though, where it'll say "Build: RA-passion-v2.2.1"

Scroll (painfully -- it's really unresponsive so don't freak out) using the scroll ball on your phone to "Wipe", then push down the track ball to select it. Then select "Wipe ALL data/factory reset".

You'll then get asked:
Wipe ALL userdata
Press Trackball to confirm.
any other key to abort.
Confirm. You'll get the following messages:
Formatting DATA:...
Formatting SDCARD:.android_secure...
Formatting CACHE:...
Skipping format of /sd-ext.
Userdata wipe complete!
Now press Vol-Down to return to the previous menu, where you select "Flash zip from sdcard". You're now asked whether to choose zip from sdcard or to toggle signature verification. Choose "zip", and select "cm-7.2.0-passion.zip", which will launch the installation.

Once that's done, select "choose zip from sdcard" again and this time pick your gapps-gb-20110828-signed.zip. Once that's installed, hit Vol-Down to go up one level in the menu and select Reboot. You're now done.

In case of trouble:
My system complained here that the gapps file was 'bad', so I went up one menu level and rebooted. Without google apps life is less fun, but I didn't have an SD card reader at hand. Once my (flashy new) system was up I mounted the SD card via USB, and checked the md5sum, which was bad. I put a new copy of the file on the sd card, checked the md5sum (now good), and powered off the phone.
I then powered it on by holding down the trackball while pushing the power button, running "./fastboot-linux flash recovery recovery-RA-passion-v2.2.1-CM.img" on my computer, selecting bootload/recovery, then "flash zip from sdcard", "choose zip from sdcard", selecting "gapps-gb-20110828-signed.zip", and THIS TIME it went fine! Then just hit Vol-Down, select "Reboot system now" and you're done!

All in all, it took a while to prepare everything, but it wasn't as difficult or scary as one would be lead to believe.

The verdict:
I actually don't use my phone much these days, so I can't really tell how 'different' the cyanogen mod really is from my previous android install. But it looks a little bit different, and I seem to have a lot more control over the details, which is nice.

16 October 2012

258. Briefly: Throttle CPU between certain hours on linux

Because university administrators apparently don't consider academics trustworthy enough, at my university each office has an AC unit which cannot be adjusted. Sure, we can set the temperature -- but the unit cannot be turned on or off. Instead it shuts itself off at 5 pm and goes back on at 8 am. Same goes for weekends -- the unit shuts itself off on Friday at 5 pm and turns itself back on on Monday morning.

Obviously all the windows are sealed shut.

Which is fair enough in terms of saving energy -- no administrator would be in their office over the weekend. But most academics are constantly fighting to keep themselves afloat in terms of work, and most of us are in on weekends too.

But this is Australia -- the winters get cold enough that it's unpleasant to sit in an unheated office (no insulation) and the summers hot enough that computers get unhappy.

And I'm running a cluster in my office, so on a warmish weekend (above 20 degrees) my tiny office gets really hot. Last night one of my nodes overheated and shut itself down.

So, in want of a better solution, I figure I will throttle the CPUs overnight to give the fans a fighting chance to keep the cpus cool when the aircon is off. In particular weekends, with no air-conditioning from 5 pm on Friday until 8 am on Monday, are a challenge.


Enough talking! 

Put the following files in /etc/cron.d

throttle.sh
#!/bin/bash
## minimise heating overnight
/usr/bin/cpufreq-set -c 0 -g powersave
/usr/bin/cpufreq-set -c 1 -g powersave
/usr/bin/cpufreq-set -c 2 -g powersave
/usr/bin/cpufreq-set -c 3 -g powersave
/usr/bin/cpufreq-set -c 4 -g powersave
/usr/bin/cpufreq-set -c 5 -g powersave

slowdown.sh
#!/bin/bash
## minimise heating overnight
/usr/bin/cpufreq-set -c 0 -g userspace
/usr/bin/cpufreq-set -c 1 -g userspace
/usr/bin/cpufreq-set -c 2 -g userspace
/usr/bin/cpufreq-set -c 3 -g userspace
/usr/bin/cpufreq-set -c 4 -g userspace
/usr/bin/cpufreq-set -c 5 -g userspace
/usr/bin/cpufreq-set -c 0 -f 2.2G
/usr/bin/cpufreq-set -c 1 -f 2.2G
/usr/bin/cpufreq-set -c 2 -f 2.2G
/usr/bin/cpufreq-set -c 3 -f 2.2G
/usr/bin/cpufreq-set -c 4 -f 2.2G
/usr/bin/cpufreq-set -c 5 -f 2.2G

unthrottle.sh
#!/bin/bash
## maximise performance during the day
/usr/bin/cpufreq-set -c 0 -g ondemand
/usr/bin/cpufreq-set -c 1 -g ondemand
/usr/bin/cpufreq-set -c 2 -g ondemand
/usr/bin/cpufreq-set -c 3 -g ondemand
/usr/bin/cpufreq-set -c 4 -g ondemand
/usr/bin/cpufreq-set -c 5 -g ondemand

Now edit /etc/crontab
00 08   * * 1-5 root    sh /etc/cron.d/unthrottle.sh
00 17   * * 1-4 root    sh /etc/cron.d/slowdown.sh
00 17 * * 5 root sh /etc/cron.d/throttle.sh


And you're good to go.

08 October 2012

252. Molecular weight calculator in python

Here's the molecular weight part of the isotopic pattern calculator in a previous post.

Most people won't need a full molecular weight calculator with plotting of isotopic composition, so I'm publishing the molecular weight part as a separate program.

The actual algorithm is fairly simple and is more or less contained in the formulaExpander function below. It looks messy because of the definition of the PeriodicTable dictionary at the beginning, but it's simple.

Copy the code, past it into a file (call it e.g. molcalc), put it in e.g. /usr/local/bin and chmod +x it.

Usage:
molcalc 'Mg2(PO4)3'
returns
The mass of Mg2P3O12 is 333.524247 and the calculated charge is -5.
The charge is based on my default oxidation states -- depending on what kind of chemistry you do the oxidation states you encounter are likely to differ.

#!/usr/bin/python2.7
#########################################################################
# Principal author of current version: Me
# Isotopic abundances and masses were copied from Wsearch32.
#
#
# Dependencies:
# To be honest I'm not quite certain. At a minimum you will need python2.7,
# python-numpy
#
#########################################################################

import re #for regular expressions
import sys
from numpy import matrix,transpose # for molw calc
try:
 molecules=sys.argv[1]
except:
 quit()

#slowly changed to IUPAC 1997 isotopic compositions and IUPAC 2007 masses
# see http://pac.iupac.org/publications/pac/pdf/1998/pdf/7001x0217.pdf for
# natural variations in isotopic composition
PeriodicTable ={
   'H':[1,1,[1.0078250321,2.0141017780],[0.999885,0.0001157]], # iupac '97 in water
   'He':[2,0,[3.0160293097,4.0026032497],[0.00000137,0.99999863]], # iupac iso '97
   'Li':[3,1,[6.0151233,7.0160040],[0.0759,0.9241]], # iupac '97
   'Be':[4,2,[9.0121821],[1.0]], # iupac '97
   'B':[5,3,[10.0129370,11.0093055],[0.199,0.801]], # iupac' 97
                        'C':[6,4,[12.0,13.0033548378],[0.9893,0.0107]], # iupac '97
                        'N':[7,5,[14.0030740052,15.0001088984],[0.99632,0.00368]], # iupac '97
                        'O':[8,-2,[15.9949146221,16.99913150,17.9991604],[0.99757,0.00038,0.00205]], # iupac '97
                        'F':[9,-1,[18.99840320],[1.0]], # iupac '97
                        'Ne':[10,0,[19.9924401759,20.99384674,21.99138551],[0.9048,0.0027,0.0925]], # iupac '97 in air
                        'Na':[11,1,[22.98976967],[1.0]], #iupac '97
                        'Mg':[12,2,[23.98504190,24.98583702,25.98259304],[0.7899,0.10,0.1101]], #iupac '97
                        'Al':[13,3,[26.98153844],[1.0]], #iupac '97
                        'Si':[14,4,[27.9769265327,28.97649472,29.97377022],[0.92297,0.046832,0.030872]],#iupac '97
                        'P':[15,5,[30.97376151],[1.0]], #iupac '97
                        'S':[16,-2,[31.97207069,32.97145850,33.96786683,35.96708088],[0.9493,0.0076,0.0429,0.0002]], #iupac '97
                        'Cl':[17,-1,[34.96885271,36.96590260],[0.7578,0.2422]], #iupac '97
                        'Ar':[18,0,[35.96754628,37.9627322,39.962383123],[0.003365,0.000632,0.996003]],#iupac '97 in air
                        'K':[19,1,[38.9637069,39.96399867,40.96182597],[0.932581,0.000117,0.067302]], #iupac '97
                        'Ca':[20,2,[39.9625912,41.9586183,42.9587668,43.9554811,45.9536928,47.952534],[0.96941,0.00647,0.00135,0.02086,0.00004,0.00187]], #iupac '97
                        'Sc':[21,3,[44.9559102],[1.0]], #iupac '97
                        'Ti':[22,4,[45.9526295,46.9517638,47.9479471,48.9478708,49.9447921],[0.0825,0.0744,0.7372,0.0541,0.0518]], #iupac '97
                        'V':[23,5,[49.9471628,50.9439637],[0.00250,0.99750]], #iupac '97
                        'Cr':[24,2,[49.9460496,51.9405119,52.9406538,53.9388849],[0.04345,0.83789,0.09501,0.02365]], #iupac '97
                        'Mn':[25,2,[54.9380496],[1.0]], #iupac '97
                        'Fe':[26,3,[53.9396148,55.9349421,56.9353987,57.9332805],[0.05845,0.91754,0.02119,0.00282]], #iupac '97
                        'Ni':[27,3,[57.9353479,59.9307906,60.9310604,61.9283488,63.9279696],[0.680769,0.262231,0.011399,0.036345,0.009256]], #iupac '97
                        'Co':[28,2,[58.933195],[1.0]], #iupac '97
                        'Cu':[29,2,[62.9296011,64.9277937],[0.6917,0.3083]], #iupac '97
                        'Zn':[30,2,[63.9291466,65.9260368,66.9271309,67.9248476,69.925325],[0.4863,0.2790,0.0410,0.1875,0.0062]], #iupac '97
                        'Ga':[31,3,[68.925581,70.9247050],[0.60108,0.39892]], #iupac '97
                        'Ge':[32,2,[69.9242504,71.9220762,72.9234594,73.9211782,75.9214027],[0.2084,0.2754,0.0773,0.3628,0.0761]], #iupac '97
                        'As':[33,3,[74.9215964],[1.0]], #iupac '97
                        'Se':[34,4,[73.9224766,75.9192141,76.9199146,77.9173095,79.9165218,81.9167000],[0.0089,0.0937,0.0763,0.2377,0.4961,0.0873]], #iupac '97
                        'Br':[35,-1,[78.9183376,80.916291],[0.5069,0.4931]],#iupac '97
                        'Kr':[36,0,[77.920386,79.916378,81.9134846,82.914136,83.911507,85.9106103],[0.0035,0.0228,0.1158,0.1149,0.5700,0.1730]], #iupac '97 in air
                        'Rb':[37,1,[84.9117893,86.9091835],[0.7217,0.2783]], #iupac '97
                        'Sr':[38,2,[83.913425,85.9092624,86.9088793,87.9056143],[0.0056,0.0986,0.0700,0.8258]], #iupac '97
                        'Y': [39,3,[88.9058479],[1.0]], #iupac '97
                        'Zr': [40,4,[89.9047037,90.9056450,91.9050401,93.9063158,95.908276],[0.5145,0.1122,0.1715,0.1738,0.0280]],#iupac '97
                        'Nb':[41,5,[92.9063775],[1.0]], #iupac '97
                        'Mo':[42,6,[91.906810,93.9050876,94.9058415,95.9046789,96.9060210,97.9054078,99.907477],[0.1484,0.0925,0.1592,0.1668,0.0955,0.2413,0.0963]], #checked, iupac '97
                        'Tc': [43,2,[96.906365,97.907216,98.9062546],[1.0]], #no natural abundance
                        'Ru': [44,3,[95.907598,97.905287,98.9059393,99.9042197,100.9055822,101.9043495,103.905430],[0.0554,0.0187,0.1276,0.1260,0.1706,0.3155,0.1862]], #iupac '97
                        'Rh':[45,2,[102.905504],[1.0]], #iupac '97
                        'Pd':[46,2,[101.905608,103.904035,104.905084,105.903483,107.903894,109.905152],[0.0102,0.1114,0.2233,0.2733,0.2646,0.1172]], #iupac '97
                        'Ag':[47,1,[106.905093,108.904756],[0.51839,0.48161]], #iupac '97
                        'Cd':[48,2,[105.906458,107.904183,109.903006,110.904182,111.9027572,112.9044009,113.9033581,115.904755],[0.0125,0.0089,0.1249,0.1280,0.2413,0.1222,0.2873,0.0749]],#iupac '97
                        'In':[49,3,[112.904061,114.903878],[0.0429,0.9571]], #iupac '97
                        'Sn':[50,4,[111.904821,113.902782,114.903346,115.901744,116.902954,117.901606,118.903309,119.9021966,121.9034401,123.9052746],[0.0097,0.0066,0.0034,0.1454,0.0768,0.2422,0.0859,0.3258,0.0463,0.0579]], #iupac '97
                        'Sb':[51,3,[120.9038180,122.9042157],[0.5721,0.4279]], #iupac '97
                        'Te':[52,4,[119.904020,121.9030471,122.9042730,123.9028195,124.9044247,125.9033055,127.9044614,129.9062228],[0.0009,0.0255,0.0089,0.0474,0.0707,0.1884,0.3174,0.3408]],#iupac '97
                        'I':[53,-1,[126.904468],[1.0]], #iupac '97
                        'Xe':[54,0,[123.9058958,125.904269,127.9035304,128.9047795,129.9035079,130.9050819,131.9041545,133.9053945,135.907220],[0.0009,0.0009,0.0192,0.2644,0.0408,0.2118,0.2689,0.1044,0.0887]], #iupac '97
                        'Cs':[55,1,[132.905447],[1.0]], #iupac '97
   'Ba':[56,2,[129.906310,131.905056,133.904503,134.905683,135.904570,136.905821,137.905241],[0.00106,0.00101,0.02417,0.06592,0.07854,0.11232,0.71698]], #iupac '97
   'La':[57,3,[137.907107,138.906348],[0.00090,0.99910]],#iupac '97
   'Ce':[58,3,[135.907140,137.905986,139.905434,141.909240],[0.00185,0.00251,0.88450,0.11114]],#iupac '97
                        'Pr':[59,3,[140.907648],[1.0]], #iupac '97
   'Nd':[60,3,[141.907719,142.909810,143.910083,144.912569,145.913112,147.916889,149.920887],[0.272,0.122,0.238,0.083,0.172,0.057,0.056]],#iupac '97
   'Pm':[61,3,[144.91270],[1.0]], #no natural occurence
   'Sm':[62,3,[143.911995,146.914893,147.914818,148.917180,149.917271,151.919728,153.922205],[0.0307,0.1499,0.1124,0.1382,0.0738,0.2675,0.2275]], #iupac '97
   'Eu':[63,3,[150.919846,152.921226],[0.4781,0.5219]], #iupac '97
   'Gd':[64,3,[151.919788,153.920862,154.922619,155.922120,156.923957,157.924101,159.927051],[0.0020,0.0218,0.1480,0.2047,0.1565,0.2484,0.2186]],#iupac '97
                        'Tb':[65,4,[158.925343],[1.0]], #iupac '97
   'Dy':[66,3,[155.924278,157.924405,159.925194,160.926930,161.926795,162.928728,163.929171],[0.0006,0.0010,0.0234,0.1891,0.2551,0.2490,0.2818]], #iupac '97
   'Ho':[67,3,[164.930319],[1.0]], #iupac '97
   'Er':[68,3,[161.928775,163.929197,165.930290,166.932045,167.932368,169.935460],[0.0014,0.0161,0.3361,0.2293,0.2678,0.1493]], #iupac '97
   'Tm':[69,3,[168.934211],[1.0]], #iupac '97
                        'Yb':[70,3,[167.933894,169.934759,170.936322,171.9363777,172.9382068,173.9388581,175.942568],[0.0013,0.0304,0.1428,0.2183,0.1613,0.3183,0.1276]], #iupac '97
   'Lu':[71,3,[174.9407679,175.9426824],[0.9741,0.0259]],#iupac '97
   'Hf':[72,4,[173.940040,175.9414018,176.9432200,177.9436977,178.9458151,179.9465488],[0.0016,0.0526,0.1860,0.2728,0.1362,0.3508]], #iupac '97
   'Ta':[73,5,[179.947466,180.947996],[0.00012,0.99988]], #iupac '97
   'W':[74,6,[179.946704,181.9482042,182.9502230,183.9509312,185.9543641],[0.0012,0.2650,0.1431,0.3064,0.2843]], #iupac  '97
                        'Re':[75,2,[184.9529557,186.9557508],[0.3740,0.6260]],#iupac '97
   'Os':[76,4,[183.952491,185.953838,186.9557479,187.9558360,188.9581449,189.958445,191.961479],[0.0002,0.0159,0.0196,0.1324,0.1615,0.2626,0.4078]],#iupac '97
   'Ir':[77,4,[190.960591,192.962924],[0.373,0.627]], #iupac '97
   'Pt':[78,4,[189.959930,191.961035,193.962664,194.964774,195.964935,197.967876],[0.00014,0.00782,0.32967,0.33832,0.25242,0.07163]],#iupac '97
   'Au':[79,3,[196.966552],[1.0]], #iupac '97
                        'Hg':[80,2,[195.965815,197.966752,198.968262,199.968309,200.970285,201.970626,203.973476],[0.0015,0.0997,0.1687,0.2310,0.1318,0.2986,0.0687]], #iupac '97
   'Tl':[81,1,[202.972329,204.974412],[0.29524,0.70476]], #iupac '97
   'Pb':[82,2,[203.973029,205.974449,206.975881,207.976636],[0.014,0.241,0.221,0.524]],#
   'Bi':[83,3,[208.980383],[1.0]], #iupac '97
   'Po':[84,4,[209.0],[1.0]],
   'At':[85,7,[210.0],[1.0]],
                        'Rn':[86,0,[220.0],[1.0]],
   'Fr':[87,1,[223.0],[1.0]],
   'Ra':[88,2,[226.0],[1.0]],
   'Ac':[89,3,[227.0],[1.0]],
   'Th':[90,4,[232.0380504],[1.0]], #iupac '97
   'Pa':[91,4,[231.03588],[1.0]],
                        'U':[92,6,[234.0409456,235.0439231,236.0455619,238.0507826],[0.000055,0.007200,0.0,0.992745]], #iupac '97
   'Np':[93,5,[237.0],[1.0]],
   'Pu':[94,3,[244.0],[1.0]],
   'Am':[95,2,[243.0],[1.0]],
   'Cm':[96,3,[247.0],[1.0]],
   'Bk':[97,3,[247.0],[1.0]],
   'Cf':[98,0,[251.0],[1.0]],
                        'Es':[99,0,[252,.0],[1.0]],
   'Fm':[100,0,[257.0],[1.0]],
   'Md':[101,0,[258.0],[1.0]],
   'No':[102,0,[259.0],[1.0]],
   'Lr':[103, 0,[262.0],[1.0]],
   'Rf':[104, 0,[261.0],[1.0]],
   'Db':[105, 0,[262.0],[1.0]],
   'Sg':[106, 0,[266.0],[1.0]]
}

#######################################
# Collect properties
#######################################
def getMass(x):
 atom=re.findall('[A-Z][a-z]*',x)
 number=re.findall('[0-9]+', x)
 if len(number) == 0:
  multiplier = 1
 else:
  multiplier = float(number[0])
 atomic_mass=float(matrix(PeriodicTable[atom[0]][2])*transpose(matrix(PeriodicTable[atom[0]][3])))
# That's right -- the molecular weight is based on the isotopes and ratios
 return (atomic_mass*multiplier)

def getCharge(x):
 atom=re.findall('[A-Z][a-z]*',x)
 number=re.findall('[0-9]+', x)
 if len(number) == 0:
  multiplier = 1
 else:
  multiplier = float(number[0])
 atomic_charge=float(PeriodicTable[atom[0]][1])
 return (atomic_charge*multiplier)


#####################################################
# Iterate over expanded formula to collect property
#####################################################
def molmass(formula):
 mass=0
 while (len(formula)>0):
  segments = re.findall('[A-Z][a-z]*[0-9]*',formula)
  for i in range(0, len(segments)):
   mass+=getMass(segments[i])
  formula=re.sub(formula, '', formula)
 return mass

def molcharge(formula):
 charge=0
 while (len(formula)>0):
  segments = re.findall('[A-Z][a-z]*[0-9]*',formula)
  for i in range(0, len(segments)):
   charge+=getCharge(segments[i])  
  formula=re.sub(formula, '', formula)
 return charge


################################################################################
#expands ((((M)N)O)P)Q to M*N*O*P*Q
################################################################################

def formulaExpander(formula):
 while len(re.findall('\(\w*\)',formula))>0:
  parenthetical=re.findall('\(\w*\)[0-9]+',formula)
  for i in parenthetical:
   p=re.findall('[0-9]+',str(re.findall('\)[0-9]+',i)))
   j=re.findall('[A-Z][a-z]*[0-9]*',i)
   oldj=j
   for n in range(0,len(j)):
    numero=re.findall('[0-9]+',j[n])
    if len(numero)!=0:
     for k in numero:
      nu=re.sub(k,str(int(int(k)*int(p[0]))),j[n])
    else:
     nu=re.sub(j[n],j[n]+p[0],j[n])
    j[n]=nu
   newphrase=""
   for m in j:
    newphrase+=str(m)
   formula=formula.replace(i,newphrase)
  if (len((re.findall('\(\w*\)[0-9]+',formula)))==0) and (len(re.findall('\(\w*\)',formula))!=0):
   formula=formula.replace('(','')
   formula=formula.replace(')','')
 return formula


#######
# main #
########
if __name__ == '__main__':
 molecules=molecules.split(',')
 for element in molecules:
  element=formulaExpander(element)
  print ('The mass of %(substance)s is %(Mass)f and the calculated charge is %(Charge)i.' % {'substance': \
   element, 'Mass': molmass(element), 'Charge': molcharge(element)})