Saturday, February 23, 2013

Puppet tip

I have a custom puppet type called iptables. Not surprisingly it is used to build iptables rules.

Recently I was setting up a router which required MASQUERADING a few virtual network interfaces. I found that the module was lacking the ability to negate a match. For example I wanted a rule:
-A FORWARD ! -s 192.168.1.0/24 -i vnet -j DROP

It seemed like a simple task to add in the ability to insert the !. After all it is mostly just string manipulation.

My puppet setup already has pluginsync enabled and working so I though deploying my changes would be easy too.

I managed to make my changes (even though ruby is quite a foreign language to me). When I ran puppet I could see the changes being pulled down to the client but alas, it did not work correctly.

I checked with several web pages which try to explain how easy it is to add new properties and everything I was doing was correct.

After wasting hours tinkering in the ruby code I had the idea to restart the puppet master and bang, it started working.

Seems so obvious in hindsight.

Monday, February 4, 2013

udev tip

From time to time I have to write some udev rules but I always struggle to work out which magic strings are required.

It does not help that every version of udev seems to change everything.

I have found a command for modern versions which helps work out what is required:

udevadm info -e

From there you can find out everything there is available to identify your devices.

The udev 'rule' is then a series of commands separated by a comma (,). You can test for equality with == and set properties with either = or :=. When you use := your value can not be overridden by another rule. For example:

SUBSYSTEM=="video4linux", MODE:="0666"

Will match all video devices and set the permissions to be world read write.

If you save that into a file called /etc/udev/rules.d/99-v4l2.rules
you can then apply it with the command:
udevadm trigger


There is much more which can be done but that is enough to get started. The names of the keys which can be set is actually listed in the man page man 7 udev but it be quite confusing to follow without examples.

Next time I have to work on flashcache I will try and blog about the new GOTO style rules :-(

Friday, February 1, 2013

Telstra error message

Recently I phoned my parents and I got an unusual error. It was a recorded voice message saying 'S3MA 1 4'.

Now that seemed a bit cryptic to me so I though I would write it down and look up what it means. It played a few times while I was writing it down and then to my surprise, Dad answered the phone.

Clearly something weird going on in the bowels of the phone exchange. Google did not have much to say on the topic so I put the word out to a contact who work at Telstra.

Apparently it is uncommon so it was hard to find but they concluded that it means 'Not connected to network'. Exactly what is not connected I don't know but I guess it became connected and then the call went through.

Some further research shows that S3MA is the name of Signalling Point ISPC Code 5-012-1 which is operated by PowerTel. That does not tell me much either.http://www.google.com/search?q=ispc+s3ma
but I guess the connection between the two telcos was offline for a short period. Once they were reconnected, the call was placed. This probably happens all the time and no one notices.

Sunday, January 13, 2013

The Raspberry Pi needs a home

While out shopping for a book case I saw a classic old tape deck. I have not got any cassettes so it was of no value for playing tapes but the retro appeal had me thinking. Easily large enough for a Raspberry Pi and some relay boards. This is the case mod that I need to house my project.

Pioneer CT-F500 Stereo Cassette Tape Deck.
After pulling the case off I was impressed with the internals. I can re-use the power socket and switch. The transformer is easily removed and provides a small earthed shelf where I can mount my new power supplies from DX.

Next to make some more room in there. I wanted to keep as many wires as possible to make it easier to use the existing plugs, switches & outputs. Needless to say, this puppy won't be playing any more tapes!

After pulling out some boards labelled 'Dolby' I though, 'I wonder how much they are worth?' And then I though, 'I wonder how much a working unit is worth?' A quick google showed that in the right condition and for the right buyer it might be worth a few hundred dollars. Well we will never know if this unit worked (although I assume that it did). It seems to be in extremely good condition (a bit of finger grime and a price tag on the front should clean off easily). When I am finished with it, I think it will be priceless.

First I hooked up the 5v power to make sure that it works. Yes it does!
Raspberry Pi getting to know it's new home.


Next I set about wiring in the 5v and 12v power trying to keep it neat and safe. The two power supplies fit side by side like it was designed that way. Then I wrestled in some 240v wires and presto, working power. I think it needs some tape though to keep things safe.

5v and 12v power installed and working.
Next I think the cassette motor needs to come out to make some more room.

Thursday, January 10, 2013

I2C 16bit IO extender

The PCA9555 is a 16 bit IO chip which interfaces with I2C. Each of the 16 bits can be individually configured as a digital input or digital output.

PCA9555 demo board. GPIO pins are on the top.


I will be using this to control a bank of relays from my Raspberry Pi. If you are not familiar with I2C on the RPI you might want to look at my posts about the PCA8591.

This time I bought the chip mounted to a board from ebay. I had to solder the header pins to the board so I could connect all the inputs & outputs.

jnewbigin@raspberrypi:~$ i2cdetect 1
WARNING! This program can confuse your I2C bus, cause data loss and worse!
I will probe file /dev/i2c-1.
I will probe address range 0x03-0x77.
Continue? [Y/n]
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: 20 -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --          

As expected, the chip shows up at address 0x20. The PCA9555 is programmed by a set of registers. The registers are split up into ports or banks which operate on 8 bits at a time. The registers are:

  • 0x00 Select Input values for bank 0
  • 0x01 Select Input values for bank 1
  • 0x02 Select Output values for bank 0
  • 0x03 Select Output values for bank 1
  • 0x04 Select Polarity Inversion for bank 0
  • 0x05 Select Polarity Inversion for bank 1
  • 0x06 Select IO Configuration for bank 0
    (set/1 = input (default), clear/0 = output)
  • 0x07 Select IO Configuration for bank 1
    (set/1 = input (default), clear/0 = output)

To read the first 8 inputs
i2cset -y 1 0x20 0x00
i2cget -y 1 0x20


To read the next 8 inputs
i2cset -y 1 0x20 0x01
i2cget -y 1 0x20

To set the first 8 bits to be outputs
i2cset -y 1 0x20 0x06 0x00
And to turn all the outputs on
i2cset -y 1 0x20 0x02 0xff

My next job is to hook up the relay boards but that requires setting up a more permanent power supply which can run the Raspberry Pi, drive the relays and power the relay devices. Hopefully photos to come soon.

Sunday, December 23, 2012

SMART errors and software RAID

For a while now I have been having an intermittent problem with some of my drives. They seem to be working but stop responding to SMART. If I reboot they don't show up any more but if I power off and back on they work fine.

I have two 640Gig WD Green drives in a software RAID1 and another WD Blue drive. After a suspend/resume, sometimes one of the drives is MIA. The kernel thinks it is still there but my SMART tools can't talk to it and start to complain.

The Blue drive has a bad (unreadable) sector but touch wood, that has not caused a problem yet. SMART knows about this and tells me about it frequently. This however does not appear to be the problem. There is a telling message is in dmesg:

sd 0:0:0:0: [sda] START_STOP FAILED
sd 0:0:0:0: [sda] Result: hostbyte=DID_BAD_TARGET driverbyte=DRIVER_OK
PM: Device 0:0:0:0 failed to resume: error 262144

So for some reason, the disk is not responding when the computer resumes. I guess it is a timeout (and I wonder if I can extend it?) Anyway, now I have the situation where my disk is not working even though I know there is nothing actually wrong with it.

Luckily I am using software RAID and the other disk is working so I can continue about my business without crashing or loosing data. After poking and prodding a few different things I have worked out a solution:


  • Hot-remove the device (from the kernel)
echo 1 > /sys/block/sda/device/delete
  • Rescan for the device to hot-add it to the kernel
echo "- - -" > /sys/class/scsi_host/host0/scan
  • Add the 'failed' drive back into the RAID set
mdadm /dev/md127 --re-add /dev/sda2

You must remove the existing (sda) device first or the disk will be re-detected and added with a new name (sde in my case).

Because I have a write-intent bitmap, the RAID set knows what has changed since the drive was failed and only the changes must be re-synced which is quite fast.

There seems to be a 'vibe' that green drives are not good for RAID. I don't really think this is a problem because the drive is green, I think it is a problem because the driver is not trying hard enough to restart the disk.

So in the end this was not a SMART problem after all. Not there there are no bugs to fix there. Particularly in udisks-helper-ata-smart-collect which keeps running and locking up sending the load average into the hundreds. For a tool designed to detect error conditions it probably needs a bit more work.

My next job is to select a replacement drive for the faulty WD Blue...

Wednesday, December 19, 2012

I2C Analog to Digital Converter

The first device I hooked to my Raspberry Pi is based on the PCF8591 Analog to Digital Converter (ADC). This chip has 4 analog inputs (ADC) and one analog output or Digital to Analog Converter (DAC).

I am using a pre-assembled board from Deal Extreme which comes with the chip, a temperature sensor, light sensor, variable resistor and LED. This provides a simple showcase for the chip and more importantly, it has a light sensor which is important to my project. The board was only a few dollars http://dx.com/p/pcf8591-8-bit-a-d-d-a-converter-module-150190 there are also other similar boards on there.

PCF8591 demo board. GPIO pins are visible on the right.


The first step is to physically hook up the board. Mine came with the required cables (often called dupont cables) which is also a handy way to start. The cables must be connected to the Raspberry Pi GPIO pins nominated for I2C. These have the required 'pull up resistors' already installed. (These are what make the wires operate like a bus). The pins are
  • P1-01 +3.3v (VCC)
  • P1-03 Data (SDA)
  • P1-05 Clock (SCL)
  • P1-09 Ground (GND)
Raspberry Pi showing GPIO cables connected.


My demo board has a red power indicator LED which came on once I powered up.

The next big test is to see if the i2c driver can talk to your chip. The Raspberry Pi actually comes configured with two I2C buses and for reasons unknown, on my system the bus labelled I2C0 is allocated the Linux device i2c-1.

Scanning both buses won't hurt.

jnewbigin@raspberrypi:~$ i2cdetect 1
WARNING! This program can confuse your I2C bus, cause data loss and worse!
I will probe file /dev/i2c-1.
I will probe address range 0x03-0x77.
Continue? [Y/n] y
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- 48 -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --                         


You can see here that a device has been detected at address 0x48. This is the expected address for my chip so that means we are in business.

Reading and writing to the chip is quite straight forward but the chip does have a few nuances.  The first read after power on will return 0x80. The analog to digital conversion is performed when you make a read request but the read will return the previous sample so it is always one sample behind. This is not too confusing unless you are switching to read a different input.

I will show how to read the data using the command line tools i2cget and i2cset. In another blog post I will show how you can interface with the chip from c code.

All these commands take a parameter 1 to specify which i2c bus and I pass -y which skips the safety warning. (We know what we are doing so this is OK. On other hardware such as your PC, things can and do go wrong by using these commands).

The most basic read is the default channel (input 0).
jnewbigin@raspberrypi:~$ i2cget -y 1 0x48
0x80
That is the power on status code. Now we read again

jnewbigin@raspberrypi:~$ i2cget -y 1 0x48
0xd2
That is the value that was sampled when we made our first read (the one that returned 0x80).
Now cover up the light sensor and read again

jnewbigin@raspberrypi:~$ i2cget -y 1 0x48
0xd2
Yep, no change. The new value has been sampled so now we read it
jnewbigin@raspberrypi:~$ i2cget -y 1 0x48
0xeb
Now we get the new value.

Now, switch to read another input, input number 1
jnewbigin@raspberrypi:~$ i2cset -y 1 0x48 0x01
jnewbigin@raspberrypi:~$ i2cget -y 1 0x48
0xeb
First we get an old value.
jnewbigin@raspberrypi:~$ i2cget -y 1 0x48
0xcf
Then the new value

We can repeat to select channel 2 and 3.

We can enable the analog output by adding bit 0x40 to the set command and then specify a value for the DAC
jnewbigin@raspberrypi:~$ i2cset -y 1 0x48 0x41 0xff

And the indicator LED turns on

jnewbigin@raspberrypi:~$ i2cset -y 1 0x48 0x41 0x00
And the indicator LED turns off. You can of course set it to any value between 0x00 and 0xff and see the LED dim and turn off. (You can also see why LEDs don't make good analog indicators).