Dobrica Pavlinušić's random unstructured stuff
Dobrica Pavlinušić's random unstructured stuff: Revision 4

This is the home page for Dobrica Pavlinušić's random unstructured stuff.

  • Power cycle network switch using Arduino and relay

    Our top-of-switch rack decides to die randomly from time to time. It was somewhat inconvenient since it also killed most of our infrastructure including primary and secondary DNS so I needed a solution quickly. Since different rack is still on the network, I should be able to hack something and finally connect my Arduino knowledge and sysadmin realm, right? Think of it as power cycle watchdog based on network state.

    First thing was to figure out what was happening with the switch. It seemed like it was still working (LEDs did blink), but only thing that helped was power cycle. So as a first strep, I connected serial console (using RS-232 extension cable) to on-board serial port (since it doesn't seem to work using cheap CH340 based USB serial dongles) and I didn't expect this:

    0x37491a0 (bcmCNTR.0): memPartAlloc: block too big 6184 bytes (0x10 aligned) in partition 0x30f6d88
    0x3cd6bd0 (bcmCNTR.1): memPartAlloc: block too big 6184 bytes (0x10 aligned) in partition 0x30f6d88
    0x6024c00 (simPts_task): memPartAlloc: block too big 1576 bytes (0x10 aligned) in partition 0x30f6d88
    0x6024c00 (simPts_task): memPartAlloc: block too big 1576 bytes (0x10 aligned) in partition 0x30f6d88
    
    When I google messages like this I get two types of answers:
    1. beginner questions about VxWorks which summ up to: you have memory leak
    2. errors from switches with boardcomm chipset from various vendors
    There is basically no solution. We are running latest firmware, and internet doesn't have any idea what to do.
    Serial console did emit a lot of messages, but didn't respond to input at all. I would at last expect that watchdog timer in the switch will reset it once it manages to fragment it's own memory so much that it has stopped forwarding packets, oh well.... What else can I do?

    IEC power cable with relay

    I wanted something what I can plug in between the existing switch with IEC power connector with USB on the other end that can be plugged into any USB port for control.

    IMG_20181219_172912.jpg

    Since this is 220V project (and my first important one), I tried to do it as safe as possible.

    • I started with a power cable, that I cut in half and put ferrules on all wires to be sure that connectors will grip those wires well.
    • Then I replaced the power plug with IEC connector so it's can be inserted in any power cable. In this case, we soldered wires ends, since ferrules where too big to fit into connector housing. We did wrap a wire around a screw in a connector correctly, so tightening the screw will not displace the wire.
    • Finally I connected cheap 10A 250VAC relay which should be enough for fully loaded 48 port gigabit network switch that draws round 80W.
    • To make sure that rest of the system can't just power cycle device connected at any time, I connected live wire through normally closed pins on a relay. This means that this cable should work as-is (without powering it at all) and when powered, since board has pull-up resistor on the relay to VCC, the relay will be in the same sate, passing power to device.
    • Finally I checked all three power cable wires with multi-meter and got around 0.2 ohms which mans that whole thing works for now.
    At this point we should note that this relay board has only three pins (IN, GND and VCC) and has no optical isolation to 220V side. Since isolation would require us to provide additional power supply for 220V side, it was acceptable a risk.

    Putting it into a box

    I really wanted to somehow fix wires and protect the bottom of the relay board (which has 220V on it) from shorting to something, so I used an old box from a dairy product and created a housing for electronics.

    IMG_20181220_095707.jpg

    If you look carefully, you will notice that I had to cut the case all the way through to pass through the power cable (that has a zip-tie on inside to prevent it from pulling out). The Case will be fixed using hot glue and a lid, so this won't be a problem.
    Warning and label on the lid is also nice touch, and shouldn't be skipped when creating a thing which you won't be only user of.

    Arduino software

    You will also notice that relay is connected to A7, which didn't work out. Let me explain:
    The idea is to use Arduino default pin state (INPUT) as a state in which the pin will stay most of the time. This makes pin floating, and we can inspect pull-up on relay board and report if we see it. When we want to activate the relay, we'll flip pin to output, pull it down, and activate the relay.
    Code is available at https://github.com/dpavlin/Arduino-projects/blob/nuc/power_cycle/power_cycle.ino and it can't be much simpler:

    /*
     * power cycle switch
     * 
     * relay is connected across 5V relay through normally closed pins so that failure of arduino doesn't kill power to switch.
     * to activate relay on this board, signal pin has to be pulled to ground.and coil draw is 76 mA when active
     * board has pull up on input pin to it's vcc
    */
    
    #define RELAY_PIN 2
    
    void setup() {
      Serial.begin(115200);
    
      pinMode(LED_BUILTIN, OUTPUT);
    
      pinMode(RELAY_PIN, INPUT); // don't modify pin state
      Serial.print("Relay pin on reset: ");
      Serial.println(digitalRead(RELAY_PIN));
    }
    
    void loop() {
      if ( Serial.available() ) {
        char c = Serial.read();
        if ( c == '0' ) {
          Serial.print("L");
          pinMode(RELAY_PIN, OUTPUT);
          digitalWrite(RELAY_PIN, LOW); // activate relay
    
          digitalWrite(LED_BUILTIN, HIGH); // led on
        } else if ( c == '1' ) {
          Serial.print("H");
          pinMode(RELAY_PIN, INPUT);
    
          digitalWrite(LED_BUILTIN, LOW); // led off
        } else {
          Serial.print(c);
        }
      }
    }
    
    Simple is good: I toyed with idea of automatically releasing the relay from Arduino code, and when I started to implement timeout configuration on Arduino side, I remembered what this will be plugged into random server USB port, without avrdude and any handy way to update firmware on it, so I decided to just leave simplest possible commands:
    • 1 - ON (outputs H) - power on, default
    • 0 - OFF (outputs L) - power off, relay active

    Hot glue galore

    Then, I applied liberal amount of hot-glue to fix power cables and board in place. It worked out pretty well. You will also notice that the relay pin has moved to D2.

    IMG_20181220_111345.jpg

    Installation

    IMG_20181220_132632.jpg

    And here it is, installed between existing switch power cable and switch, connected to only USB port still available in rack which is still on network.

    cron and serial port

    Idea is simple: we'll use cron to ping primary and secondary DNS IP addresses and if any of these fail, we'll send 0 to turn power off, wait 3 seconds, and send 1 to turn power back on.
    Implementation, however, is full of quirks, mostly because we don't want to depend on additional utilities installed, and we need to wait for Arduino to reset after connecting to serial port (and to give it time to display value of relay pin) before we start turning power off.

    #!/bin/sh -e
    
    ping -q -c 5 193.198.212.8 > /dev/shm/ping && ping -q -c 5 193.198.213.8 >> /dev/shm/ping || (
    
    test -e /dev/shm/reset && exit 0 # reset just once
    cp /dev/shm/ping /dev/shm/reset  # store failed ping
    
    date +%Y-%m-%dT%H:%M:%S
    cat /dev/shm/ping
    
    dev=/dev/ttyUSB0
    
    trap "exit" INT TERM
    trap "kill 0" EXIT
    
    stty -F $dev speed 115200 raw
    cat < $dev &
    (
            echo
            sleep 3 # wait for reset and startup message
            echo 0  # off
            sleep 3
            echo 1  # on
            sleep 1
    ) | cat > $dev
    
    kill $!
    
    ) # ping subshell
    
    It's started from crontab with user which has dialout group membership so he can open /dev/ttyUSB0:
    dpavlin@ceph04:~$ ls -al /dev/ttyUSB0 
    crw-rw---- 1 root dialout 188, 0 Dec 28 01:44 /dev/ttyUSB0
    dpavlin@ceph04:~$ id
    uid=1001(dpavlin) gid=1001(dpavlin) groups=1001(dpavlin),20(dialout),27(sudo)
    dpavlin@ceph04:~$ crontab -l | tail -1
    */1 *  *   *   *     /home/dpavlin/sw-lib-srv-power-cycle.sh
    
    This will execute script every minute. This allows us to detect error within minute. However, switch boot takes 50s, so we can't just run this script every minute, because it will result in constant switch power cycles. But since we are resetting switch just once this is not a problem.

    With this in place, your network switch will not force you to walk to it so you can power cycle it any more. :-)
    And it's interesting combination of sysadmin skills and electronics which might be helpful to someone.

    remote access

    If we want to access our servers while switch doesn't work, it's always useful to create few shell scripts on remote nodes which will capture IP addresses and commands which you will need to execute to recover your network.

    dpavlin@data:~/ffzg$ cat ceph04-switch-relay.sh 
    #!/bin/sh -xe
    
    ssh 193.198.212.46 microcom -p /dev/ttyUSB0 -s 115200
    
    dpavlin@data:~/ffzg$ cat r1u32-sw-rack3.sh 
    
    #!/bin/sh
    
    ssh 193.198.212.43 microcom -p /dev/ttyS1 -s 9600
    

  • LSI MegaRAID slow compared to md

    This week I learned valuable lesson: if you are using MIPS from 2008 in your RAID controller, you can't really expect it to be faster than more modern Intel CPU when doing RAID 10 on disks.

    It all started with failure of SSD in our bcache setup which sits on top of MegaRAID RAID10 array. Since this required me take one of ganeti nodes down, it was also a good opportunity to add one more disk (we where running 6 disks and one SSD) and switch to software md RAID10 so we can use all 7 disks in RAID10. In this process, I did some benchmarking and was shocked with results.

    First, let's see original MegaRAID configuration:

    # lsblk --scsi -m
    NAME HCTL       TYPE VENDOR   MODEL             REV TRAN NAME   SIZE OWNER GROUP MODE
    sda  0:0:6:0    disk ATA      WDC WD1002FBYS-1 0C12      sda  931.5G root  disk  brw-rw----
    sdb  0:0:7:0    disk ATA      INTEL SSDSC2BW24 DC32      sdb  223.6G root  disk  brw-rw----
    sdc  0:2:0:0    disk DELL     PERC H310        2.12      sdc    2.7T root  disk  brw-rw----
    # hdparm -tT /dev/sdc
    
    /dev/sdc:
     Timing cached reads:   13920 MB in  1.99 seconds = 6981.76 MB/sec
     Timing buffered disk reads: 1356 MB in  3.00 seconds = 451.81 MB/sec
    
    and let's compare that with JBOD disks on controller and creating md array:
    # hdparm -Tt /dev/md0
    /dev/md0:
     Timing cached reads:   13826 MB in  1.99 seconds = 6935.19 MB/sec
     Timing buffered disk reads: 1888 MB in  3.01 seconds = 628.05 MB/sec
    
    So, TL;DR is that you are throwing away disk performance if you are using hardware RAID. You didn't expect that? I didn't. In retrospect it's logical that newish Intel CPU can process data much faster than slowish MIPS on RAID controller, but on the other hand only difference is RAID overhead because same controller is still handling disks with software raid.

    I also wrote document with a lot of console output and commands to type if you want to do the same: https://github.com/ffzg/gnt-info/blob/master/doc/megaraid-to-md.txt

  • Edit any textarea in vi with syntax highlight

    Today I was explaining xclip utility and found this useful snippet which I wrote back in 2011 that allows you to edit browser textarea in terminal using vi with syntax highlighting.

    #!/bin/sh
    
    # workflow:
    # 1. focus textarea in browser you want to edit
    # 2. press ctrl+a then ctrl+c
    # 3. switch to terminal and start this script with optional extensioni for highlight: xclip-vi html
    # 4. edit file in vi, and save it
    # 5. switch back to browser, and press ctrl+v in already selected textarea
    
    ext=$1
    test -z "$ext" && ext=txt
    
    xclip -out > /tmp/$$.$ext && vi /tmp/$$.$ext && xclip -in -selection clipboard < /tmp/$$.$ext
    

    xclip-vi.sh github gist

  • Running legacy binary junk after upgrade in chroot

    These days, my work seems more like archeology than implementing newest and coolest web technologies, but someone has to keep an eye on old web servers which are useful to people.

    In this case, it's two major Debian releases upgrade which of course did result in some amount of breakage as you would expect. Most of breakage was easy to fix, but we had one site which had only pyc files, and python2.6 with correct modules wasn't supported on current distribution.

    First idea was to use python de-compiler to generate source python files, and this only got me to different python errors which I didn't know how to fix. so, this was dead end.

    I did have a backup of machine before upgrade on zfs pool, so next logical idea was to run minimal amount of old binaries to keep the site up. And I decided to do it in chroot so I can easily share mysql socket from current installation into pre-upgrade squeeze. Let's see what was involved in making this happen.

    1. make writable copy of filesystem

    Our backups are on zfs pool, so we cloned all three disks into same layout as they are mounted on filesystem:

    2018-06-08.10:07:53 zfs clone lib15/backup/pauk.ffzg.hr/0@2018-05-01 lib15/export/pauk.ffzg.hr
    2018-06-08.10:08:19 zfs clone lib15/backup/pauk.ffzg.hr/1@2018-05-01 lib15/export/pauk.ffzg.hr/home
    2018-06-08.10:08:38 zfs clone lib15/backup/pauk.ffzg.hr/2@2018-05-01 lib15/export/pauk.ffzg.hr/srv
    

    2. nfs export it to upgraded server

    Take a note of crossmnt parameter, this will allow us to mount all descending filesystems automatically.

    root@lib15:~# grep pauk /etc/exports 
    /lib15/export/pauk.ffzg.hr 10.21.0.2(rw,fsid=2,no_subtree_check,no_root_squash,crossmnt)
    root@lib15:~# exportfs -va
    exporting 10.21.0.2:/lib15/export/pauk.ffzg.hr
    

    3. mount nfs export

    root@pauk:~# grep squeeze /etc/fstab
    10.21.0.215:/lib15/export/pauk.ffzg.hr  /mnt/squeeze    nfs     defaults,rw     0 0
    

    4. start chroot with old version of service

    To make this work, I first edited apache configuration in chroot to start it on different port, and configured front-end server to redirect site to new port.

    root@pauk:/home/dpavlin# cat chroot-squeeze.sh 
    
    to=/mnt/squeeze
    
    mount --bind /dev $to/dev
    mount --bind /sys $to/sys
    mount --bind /proc $to/proc
    
    mount --bind /var/run/mysqld/ /mnt/squeeze/var/run/mysqld/
    
    /usr/sbin/chroot $to /etc/init.d/apache2 start
    

    5. redirect apache traffic to server in chroot

    You will have to insert something like this in current apache configuration for vhost:

    <Proxy http://127.0.0.1:18080/*>
        Order allow,deny
        Allow from all
    </Proxy>
    <Location /german2/>
        RequestHeader set Host "www.ffzg.unizg.hr"
        ProxyPreserveHost On
        ProxyPass        http://127.0.0.1:18080/german/
        ProxyPassReverse http://127.0.0.1:18080/german/
    </Location>
    

    You might scream at me that in days of containers, systemd and other better solutions chroot is obsolete. In my opinion, it's just a right tool for a job from time to time, if you have backup :-)

  • DORS/CLUC 2018: linux+sensor+device-tree+shell=IoT ?

    This year on DORS/CLUC 2018 I decided to talk about device tree in Linux kernel, so here are blurb, presentation and video of that lecture.

    You have one of those fruity *Pi arm boards and cheep sensor from China? Some buttons and LEDs? Do I really need to learn whole new scripting language and few web technologies to read my temperature, blink a led or toggle a relay?
    No, because your Linux kernel already has drivers for them and all you need is device tree and cat.

    Below is transcript of talk:
    0:00:00.000,0:00:09.540
    Hello. How are you?
    This is the participation part, come on
    
    0:00:09.540,0:00:19.619
    you're not the first I time here!
    OK, my name is Dobrica Pavlinušić and I will try to
    
    0:00:19.619,0:00:25.019
    persuade you today that you can do with
    your Linux something which you might not
    
    0:00:25.019,0:00:32.969
    have thought of by yourself I hope in a
    sense in last year and a half I noticed
    
    0:00:32.969,0:00:38.610
    that I am using microcontrollers for
    less and less and that I'm using my
    
    0:00:38.610,0:00:44.760
    Linux more and more for more or less the
    same tasks and in that progress process
    
    0:00:44.760,0:00:51.239
    I actually learned something which I
    want to share with you today in a sense
    
    0:00:51.239,0:00:57.059
    my idea is to tell you how to do
    something with your arm single board
    
    0:00:57.059,0:01:05.729
    computer in this lecture we will talk
    mostly about Allwinner boards but if
    
    0:01:05.729,0:01:12.119
    you want a hint if you want to buy
    some arm computer please buy the board
    
    0:01:12.119,0:01:17.070
    which is supported by armbian. armbian  is the project which actually
    
    0:01:17.070,0:01:21.360
    maintains the distribution for our
    boards and is currently the best
    
    0:01:21.360,0:01:27.689
    distribution for arms aside from me
    raspbian for Raspberry Pi but raspbian
    
    0:01:27.689,0:01:32.909
    supports only Raspberry Pi but if you have
    any other board please take a look if
    
    0:01:32.909,0:01:37.860
    there is an armbian port. if there isn't
    try to contribute one and if you are
    
    0:01:37.860,0:01:41.850
    just deciding which board to buy my
    suggestion is buy the one which is
    
    0:01:41.850,0:01:47.070
    already supported on the other hand if
    you already did something similar you
    
    0:01:47.070,0:01:52.079
    might have found some references on the
    internet about device three and it
    
    0:01:52.079,0:01:55.619
    looked like magic
    so we'll try to dispel some of that
    
    0:01:55.619,0:02:03.180
    magic today unfortunately when you start
    playing with it one of the first things
    
    0:02:03.180,0:02:10.459
    you will want to do is recompile the
    kernel on your board so be prepared to
    
    0:02:10.459,0:02:15.810
    compile additional drivers if they are
    not already included. armbian again
    
    0:02:15.810,0:02:21.890
    wins because it comes with a lot of
    a lot of drivers already included and
    
    0:02:21.890,0:02:28.950
    this year I will not say anything which
    requires soldering which might be good
    
    0:02:28.950,0:02:35.190
    for you if you are afraid of the heat
    but it will be a little bit more than
    
    0:02:35.190,0:02:41.519
    just connecting few wires not much more
    for a start let's start with the warning
    
    0:02:41.519,0:02:46.980
    for example you have a arms in arms
    small arm board and you want to have a
    
    0:02:46.980,0:02:52.019
    real clock in it you know the one which
    keeps the time when the board is powered
    
    0:02:52.019,0:02:57.239
    off has the battery and so on if you buy
    the cheapest one from China which is
    
    0:02:57.239,0:03:02.879
    basically for Arduino you will buy the
    device which is 5 volt device which your
    
    0:03:02.879,0:03:10.170
    arm single board computer isn't. you can
    modify the board removing two resistors
    
    0:03:10.170,0:03:16.409
    if you want to but don't tell anyone I2C, and will mostly talk about i2c
    
    0:03:16.409,0:03:23.819
    sensors here, should be 5 volt tolerant
    so if you by mistake just connected and
    
    0:03:23.819,0:03:30.569
    your data signals are really 5 volt you
    won't burn your board but if you are
    
    0:03:30.569,0:03:35.129
    supplying your sensor with 5 volts
    please double-check that your that is
    
    0:03:35.129,0:03:39.060
    sure to connect it to your board and
    nothing bad will happen this is the only
    
    0:03:39.060,0:03:44.970
    warning I have for the whole lecture in
    this example I showed you a really
    
    0:03:44.970,0:03:49.829
    simple way in which you can take the
    sensors run i2cdetect, detect its
    
    0:03:49.829,0:03:59.370
    address in this case it's 68 - and then
    - load 1 kernel module and all of the
    
    0:03:59.370,0:04:03.889
    sudden your Raspberry Pi will have battery backed clock, just like your laptop does
    
    0:04:03.889,0:04:12.569
    but how did this journey all started for
    me? about two years ago I was very
    
    0:04:12.569,0:04:18.060
    unsatisfied with the choice of pinouts
    which you can download from the internet
    
    0:04:18.060,0:04:23.820
    I was thinking something along the lines
    wouldn't be it wouldn't it be nice if I
    
    0:04:23.820,0:04:27.060
    could
    print the pinout for any board I have
    
    0:04:27.060,0:04:36.360
    with perfect 2.54 millimeters pin
    spacing which I can put beside my pins
    
    0:04:36.360,0:04:43.440
    and never make a mistake of plugging the
    wire in the wrong pin and we all know
    
    0:04:43.440,0:04:48.000
    that plugging the wire in the wrong pin
    is always the first problem you have on
    
    0:04:48.000,0:04:54.120
    the other hand you say oh this is the
    great idea and you are looking at your
    
    0:04:54.120,0:04:58.320
    pin out which is from the top of the
    board and you are plugging the wires
    
    0:04:58.320,0:05:02.160
    from the bottom of the board and all of
    the sudden your pin out has to be
    
    0:05:02.160,0:05:06.660
    flipped but once you write a script
    which actually displays the pin out it's
    
    0:05:06.660,0:05:12.950
    trivially easy to get to add options to
    flip it horizontally or vertically and
    
    0:05:12.950,0:05:18.870
    create either black and white pin out if
    you are printing it a laser or color pin
    
    0:05:18.870,0:05:26.639
    out if you are printing it on some kind
    of inkjet so once you have that SVG
    
    0:05:26.639,0:05:31.680
    which you can print and cut with the
    scissors and so on it's just a script on
    
    0:05:31.680,0:05:38.370
    your machine so you could also have the
    common line output and then it went all
    
    0:05:38.370,0:05:44.070
    south I started adding additional data
    which you can see on this slide in
    
    0:05:44.070,0:05:50.250
    square brackets with the intention of
    having additional data for each pin for
    
    0:05:50.250,0:05:56.250
    example if I started SPI I want to see
    that this pin is already used so I will
    
    0:05:56.250,0:06:01.830
    not by mistake plug something into the
    SPI pins if I already have the SPI pin
    
    0:06:01.830,0:06:08.150
    started if I have the serial port on
    different boards your serial might be
    
    0:06:08.150,0:06:14.880
    UART4 on this particular CPU but it's
    the only serial in your Linux system so
    
    0:06:14.880,0:06:21.270
    it will be /dev/ttyS0 for
    example so I wanted to see all the data
    
    0:06:21.270,0:06:27.180
    and in the process I actually saw a lot
    of things which kernel know and I didn't
    
    0:06:27.180,0:06:33.690
    so today talking to you about it of
    course in comment line because you might
    
    0:06:33.690,0:06:36.990
    rotate your board well plug in the wires
    you can also do
    
    0:06:36.990,0:06:45.540
    all the flips and things you you already
    saw in the in the graphic part so let's
    
    0:06:45.540,0:06:50.190
    start with the sensor okay I said cheap
    sensor for eBay we'll get the cheap
    
    0:06:50.190,0:06:54.840
    sensors from eBay but this sensor is from
    some old PowerPC Macintosh. It was
    
    0:06:54.840,0:06:59.580
    attached to the disk drive and the
    Macintosh used it to measure the
    
    0:06:59.580,0:07:04.890
    temperature of the disk drive. you know
    that was in the times before the smart
    
    0:07:04.890,0:07:12.060
    had a temperature and I said hmm this
    is the old sensor, kernel surely
    
    0:07:12.060,0:07:16.800
    doesn't have support for it, but, oh look,
    just grep through the kernel
    
    0:07:16.800,0:07:21.900
    source and indeed there is a driver and
    this was a start I said hmm
    
    0:07:21.900,0:07:29.580
    driver in kernel, I don't have to use
    Arduino for it - now that I know that
    
    0:07:29.580,0:07:35.070
    driver is there and I have kernel module compiled, we said that prerequisite
    
    0:07:35.070,0:07:40.950
    is that we can compile the kernel, what
    do we actually have to program or do to
    
    0:07:40.950,0:07:46.260
    make this sensor alive? not more than
    this a echo in the middle of the slide
    
    0:07:46.260,0:07:52.200
    you just echo the name of the module and
    the i2c address the i2c addresses we saw
    
    0:07:52.200,0:07:56.070
    it before we can get it with i2cdetect by just connecting the sensor and
    
    0:07:56.070,0:08:02.280
    the new device will magically appear it
    will be shown in the sensors if you have
    
    0:08:02.280,0:08:06.840
    lm-sensors package installed but if
    you don't you can always find the same
    
    0:08:06.840,0:08:14.160
    data in /sys/ file system which is full
    of wonders and as we'll see in non
    
    0:08:14.160,0:08:19.350
    formatted way so the first two digits
    actually the last three digits digits
    
    0:08:19.350,0:08:26.640
    are the decimal numbers and the all the
    other are the the integer celsius in
    
    0:08:26.640,0:08:34.470
    this case. but you might say - I
    don't want to put that echo in my startup
    
    0:08:34.470,0:08:40.380
    script! or I would like to have that as
    soon as possible I don't want to depend
    
    0:08:40.380,0:08:43.980
    on the userland
    to actually start my sensor and believe
    
    0:08:43.980,0:08:48.710
    it or not because your smart phones have
    various sensors in
    
    0:08:48.710,0:08:52.790
    them, there is a solution in the Linux kernel
    for that and it's called the device tree
    
    0:08:52.790,0:08:58.700
    so this is probably the simplest form of
    the device tree which still doesn't look
    
    0:08:58.700,0:09:06.020
    scary, but it i will, stay with me, and it
    again defines our module the address
    
    0:09:06.020,0:09:12.020
    which is 49 in this case and i2c 1
    interface just like we did in that echo
    
    0:09:12.020,0:09:16.700
    but in this case this module will be
    activated as soon as kernel starts up
    
    0:09:16.700,0:09:24.590
    as opposed to the end of your boot up
    process. one additional thing that kernel
    
    0:09:24.590,0:09:31.000
    has and many people do not use is
    ability to load those device trees
    
    0:09:31.000,0:09:35.750
    dynamically the reason why those most
    people don't use it is because they are
    
    0:09:35.750,0:09:41.270
    on to old kernels I think you have to
    have something along the lines of 4.8
    
    0:09:41.270,0:09:47.510
    4.8 or newer to actually have the
    ability to load the device trees live
    
    0:09:47.510,0:09:54.470
    basically you are you are using /sys/kernel/config directory and this script
    
    0:09:54.470,0:10:00.620
    just finds where you have it mounted and
    loads your device tree live word of
    
    0:10:00.620,0:10:09.200
    warning currently although it seems like
    you can do that on Raspberry Pi the API
    
    0:10:09.200,0:10:14.270
    is there the model is compiled,
    everything is nice and Diddley, kernel
    
    0:10:14.270,0:10:18.350
    even says that device tree overlay is
    applied, it doesn't work on the raspberry
    
    0:10:18.350,0:10:24.950
    pi because raspberry pi is different but
    if you gave a any other platform live
    
    0:10:24.950,0:10:31.670
    loading is actually quite nice and
    diddley. so now we have some sensor and it
    
    0:10:31.670,0:10:37.310
    works or it doesn't
    and we somewhat suspect that kernel
    
    0:10:37.310,0:10:43.040
    developers didn't write a good driver
    which is never ever the case if you
    
    0:10:43.040,0:10:48.260
    really want to implement some driver
    please look first at the kernel source
    
    0:10:48.260,0:10:52.220
    tree there probably is the
    implementation better than the one you
    
    0:10:52.220,0:10:56.930
    will write and you can use because the
    kernel is GPL you can use that
    
    0:10:56.930,0:11:00.970
    implementation as a reference because in
    my
    
    0:11:00.970,0:11:05.890
    small experience with those drivers in
    kernel they are really really nice but
    
    0:11:05.890,0:11:10.960
    what do you do well to debug it?
    I said no soldering and I didn't say but
    
    0:11:10.960,0:11:15.010
    it would be nice if I could do that
    without additional hardware. Oh, look
    
    0:11:15.010,0:11:20.890
    kernel has ability to debug my i2c
    devices and it's actually using tracing.
    
    0:11:20.890,0:11:26.140
    the same thing I'm using on my servers
    to get performance counters. isn't that
    
    0:11:26.140,0:11:30.340
    nice. I don't have to have a logic
    analyzer. I can just start tracing and
    
    0:11:30.340,0:11:40.120
    have do all the dumps in kernel. nice,
    unexpected, but nice! so let's get to the
    
    0:11:40.120,0:11:45.790
    first cheap board from China so you
    bought your arm single base computer
    
    0:11:45.790,0:11:52.030
    single board computer and you want to
    add few analog digital converters to it
    
    0:11:52.030,0:11:57.070
    because you are used to Arduino and you
    have some analog sensor or something and
    
    0:11:57.070,0:12:05.620
    you found the cheapest one on eBay and
    bought few four five six because they
    
    0:12:05.620,0:12:10.990
    are just the $ each, so what do you do
    the same thing we saw earlier you just
    
    0:12:10.990,0:12:17.800
    compile the models say the address of
    the interface and it will appear and
    
    0:12:17.800,0:12:23.770
    just like it did in the last example so
    everything is nice but but but you read
    
    0:12:23.770,0:12:30.790
    the datasheet of that sensor and the
    sensor other than 4 analog inputs also
    
    0:12:30.790,0:12:38.860
    has 1 analog output which is the top
    pin on the left denoted by AOUT, so you
    
    0:12:38.860,0:12:42.850
    want to use it
    oh this kernel model doesn't is not very
    
    0:12:42.850,0:12:46.900
    good it doesn't have ability to control
    that of course it does but how do you
    
    0:12:46.900,0:12:50.680
    find it?
    my suggestion is actually to search
    
    0:12:50.680,0:12:57.190
    through the /sys/ for either address of
    your i2c sensor, which is this
    
    0:12:57.190,0:13:05.790
    case is 48, or for the word output or
    input and you will actually get all
    
    0:13:05.790,0:13:12.400
    files, because in linux everything is a
    file, which are defined in driver of this
    
    0:13:12.400,0:13:16.620
    module, and if you
    look at it, there is actually out0_output
    
    0:13:16.620,0:13:24.630
    out0_output file in which you can
    turn output on or off so we are all
    
    0:13:24.630,0:13:29.910
    golden. kernel developers didn't forget
    to implement part of the driver for this
    
    0:13:29.910,0:13:38.910
    sensor all golden my original idea was
    to measure current consumptions of arm
    
    0:13:38.910,0:13:44.490
    boards because I'm annoyed by the random
    problems you can have just because your
    
    0:13:44.490,0:13:49.470
    power supply is not powerful enough so
    it's nice actually to monitor your power
    
    0:13:49.470,0:13:55.740
    usage so you will see what changes, for
    example, you surely... we'll get that, remind
    
    0:13:55.740,0:14:01.250
    me to tell you how much power does the
     the additional button take
    
    0:14:01.250,0:14:05.130
    that's actually interesting thing which
    you wouldn't know if you don't measure
    
    0:14:05.130,0:14:10.950
    current so you buy the cheapest possible
    eBay sensor for current, the right one
    
    0:14:10.950,0:14:16.560
    is the ina219 which is
    bi-directional current sensing so you
    
    0:14:16.560,0:14:21.690
    can put it between your battery and solar panel and you will see
    
    0:14:21.690,0:14:26.160
    whether the battery is charging or
    discharging, or if you need more channels
    
    0:14:26.160,0:14:34.020
    I like an ina3221 which has 3 channels,
    the same voltage
    
    0:14:34.020,0:14:40.500
    but 3 different channels, so you can
    power 3 arm single computers from one
    
    0:14:40.500,0:14:47.670
    sensor if you want to. and of course once
    you have that again the current is in
    
    0:14:47.670,0:14:53.260
    some file and it will be someting...
    
    0:14:53.260,0:14:56.490
    But, I promised you IOT? right? nothing
    
    0:14:56.490,0:14:59.070
    I said so far is IOT! where is the
    Internet?
    
    0:14:59.070,0:15:05.100
    where are the things? buzzwords are missing! OK, challenge
    
    0:15:05.100,0:15:08.550
    accepted! Let's make a button! you know it's like a
    
    0:15:08.550,0:15:15.029
    blink LED. So buttons, because I was
    not allowed to use soldering iron in
    
    0:15:15.029,0:15:21.990
    this talk, I'm using old buttons from old
    scanner. nothing special 3 buttons, in
    
    0:15:21.990,0:15:25.350
    this case with hardware debounce, but we
    don't care.
    
    0:15:25.350,0:15:29.270
    4 wires 3 buttons.
    how hard can it be?
    
    0:15:29.270,0:15:36.240
    well basically it can be really really
    simple  this is the smallest
    
    0:15:36.240,0:15:42.638
    font so if you see how to read this I
    congratulate you! in this case I am
    
    0:15:44.580,0:15:51.360
    specifying that I want software pull up, in this first fragment on the top.
    
    0:15:51.360,0:15:57.840
    I could have put some
    resistors, but you said no soldering
    
    0:15:57.840,0:16:03.540
    so here I am telling to my
    processor. please do pull up on
    
    0:16:03.540,0:16:09.540
    those pins. and then I'm defining three
    keys. as you can see email. connect and
    
    0:16:09.540,0:16:15.660
    print. which generate real Linux
    keyboard events. so if you are in X and
    
    0:16:15.660,0:16:20.730
    press that key, it will generate that key,
    I thought it would it would be better to
    
    0:16:20.730,0:16:26.400
    generate you know the magic multimedia
    key bindings as opposed to A, B and C
    
    0:16:26.400,0:16:31.940
    because if I generated a ABC and was its
    console I would actually generate
    
    0:16:31.940,0:16:39.140
    letters on a login prompt which I didn't
    want so actually did it and it's quite
    
    0:16:39.140,0:16:47.310
    quite easy. In this case I'm using gpio-keys-polled which means that my CPU
    
    0:16:47.310,0:16:52.500
    is actually pulling every 100
    milliseconds those keys to see whether
    
    0:16:52.500,0:16:57.150
    they their status changed and since the
    board is actually connected through the
    
    0:16:57.150,0:17:01.890
    current sensing - sensor I mentioned earlier I'm
    
    0:17:01.890,0:17:11.209
    getting additional: how many mA?
    every 100 milliseconds, pulling 3 keys?
    
    0:17:13.010,0:17:19.350
    60! I wouldn't expect my power
    consumption to rise by 60 milliamps
    
    0:17:19.350,0:17:24.480
    because I am pulling 3 keys every 100
    milliseconds! but it did and because I
    
    0:17:24.480,0:17:32.430
    could add sensors to the linux without
    programming drivers, I know that! why am I
    
    0:17:32.430,0:17:40.450
    using polling because on allwinner
    all pins are not interrupt capable so in
    
    0:17:40.450,0:17:44.520
    the sense all pins cannot generate
    interrupts on allwinner
    
    0:17:44.520,0:17:48.940
    raspberry pi in this case is different
    on raspberry pi every pin can be
    
    0:17:48.940,0:17:54.279
    interrupt pin on Allwinner that is not
    the case. so the next logical question is
    
    0:17:54.279,0:17:58.510
    how do I know when I'm sitting in front
    of my board whether the pin can get the
    
    0:17:58.510,0:18:05.440
    interrupt or not? my suggestion is ask
    the kernel. just grap through the debug
    
    0:18:05.440,0:18:10.720
    interface of the kernel through pinctrl
    which is basically the the thing
    
    0:18:10.720,0:18:19.570
    which configures the pins on your arm
    CPU and try to find the irq
    
    0:18:19.570,0:18:25.840
    will surely get the list of the pins
    which are which are irq capable take in
    
    0:18:25.840,0:18:30.370
    mind that this will be different on
    different arm architectures so
    
    0:18:30.370,0:18:34.419
    unfortunately on allwinner
    it will always look the same because it
    
    0:18:34.419,0:18:41.020
    is allwinner architecture. actually
    sunxi ! but on the Raspberry Pi for
    
    0:18:41.020,0:18:45.880
    example this will be somewhat different
    but the kernel knows, and the grep is
    
    0:18:45.880,0:18:51.490
    your friend. so you wrote the device
    three you load it either live or some
    
    0:18:51.490,0:18:57.279
    something on some other way you connect
    your buttons and now let's try does it really
    
    0:18:57.279,0:19:03.580
    work? of course it does! we will start
    evtest which will show us all the
    
    0:19:03.580,0:19:08.350
    input devices we have the new one is the
    gpio-3-buttons, which is the same name
    
    0:19:08.350,0:19:14.559
    as our device three overlay and we can see
     the same things we saw in
    
    0:19:14.559,0:19:20.230
    device three we defined three keys with
    this event but we free-of-charge
    
    0:19:20.230,0:19:25.990
    got for example keyboard repeat because
    this is actually meant to be used for
    
    0:19:25.990,0:19:31.630
    keyboards our kernel is automatically
    implementing repeat key we can turn it
    
    0:19:31.630,0:19:35.919
    off but this is example of one of the
    features which you probably wouldn't
    
    0:19:35.919,0:19:43.330
    implement yourself if you are connecting
    those three keys to your Arduino but but
    
    0:19:43.330,0:19:46.120
    but this is still not the
    internet-of-things
    
    0:19:46.120,0:19:49.789
    if this is the Internet it should have
    some kind of
    
    0:19:49.789,0:19:56.299
    Internet in it some buzzwords for
    example mqtt and it really can just
    
    0:19:56.299,0:20:01.759
    install trigger-happy demon which is
    nice deamon which listens to
    
    0:20:01.759,0:20:06.830
    input events and write a free file
    configuration which will send the each
    
    0:20:06.830,0:20:15.139
    key pressed order MQTT and job done i
    did the internet button without a line
    
    0:20:15.139,0:20:23.419
    of code the configuration one side note
    here if you are designing some some
    
    0:20:23.419,0:20:30.919
    Internet of Things thingy which even if
    you are only one who will use it it's a
    
    0:20:30.919,0:20:33.889
    good idea but if you are doing it for
    somebody else
    
    0:20:33.889,0:20:41.119
    please don't depend on the cloud because
    I wouldn't like for my door to be locked
    
    0:20:41.119,0:20:45.590
    permanently with me outside just because
    my internet connection isn't working
    
    0:20:45.590,0:20:52.999
    think about it of course you can use any
    buttons in this case this was the first
    
    0:20:52.999,0:20:57.070
    try actually like the three buttons
    better than this one that's why this
    
    0:20:57.070,0:21:02.419
    these buttons are coming second and this
    board with the buttons has one
    
    0:21:02.419,0:21:08.840
    additional nice thing and that is the
    LED we said that will cover buttons and
    
    0:21:08.840,0:21:15.379
    LEDs right unfortunately this LED is 5
    volts so it won't light up on 3.3 volts
    
    0:21:15.379,0:21:24.139
    but when you mentioned LEDs something
    came to mind how can I use those LEDs
    
    0:21:24.139,0:21:29.029
    for something more useful than just
    blinking them on or off we'll see you
    
    0:21:29.029,0:21:34.039
    later then turning them on or off it is
    also useful you probably didn't know
    
    0:21:34.039,0:21:40.580
    that you can use Linux triggers to
    actually display status of your MMC card
    
    0:21:40.580,0:21:47.720
    CPU load network traffic or something
    else on the LEDs itself either the LEDs
    
    0:21:47.720,0:21:51.859
    which you already have on the board but
    if your manufacturer didn't provide
    
    0:21:51.859,0:21:56.679
    enough of them you can always just add
    random LEDs, write device tree and
    
    0:21:56.679,0:22:01.559
    define the trigger for them, and this is
    an example of that
    
    0:22:01.559,0:22:08.219
    and this example is actually for this
    board which is from the ThinkPad
    
    0:22:08.219,0:22:14.019
    ThinkPad dock to be exact, which
    unfortunately isn't at all visible
    
    0:22:14.019,0:22:20.169
    on this picture, but you will believe me,
    has actually 2 LEDs and these 3
    
    0:22:20.169,0:22:27.489
    keys and 2 LEDs actually made the arm
    board which doesn't have any buttons on
    
    0:22:27.489,0:22:36.609
    it or status LEDs somewhat flashy with
    buttons. that's always useful on the
    
    0:22:36.609,0:22:41.889
    other hand here I would just want to
    share a few hints with you for a start
    
    0:22:41.889,0:22:47.320
    first numerate your pins because if you
    compared the the picture down there
    
    0:22:47.320,0:22:54.579
    which has seven wires and are numerated
    which is the second try be the first
    
    0:22:54.579,0:23:00.579
    nodes on the up you will see that in
    this case i thought that there was eight
    
    0:23:00.579,0:23:06.999
    wires so the deducing what is connected
    where when you have the wrong number of
    
    0:23:06.999,0:23:14.229
    wires is maybe not the good first step
    on the other hand we saw the keys what
    
    0:23:14.229,0:23:21.639
    about rotary encoders? for years I was
    trying to somehow persuade Raspberry Pi
    
    0:23:21.639,0:23:28.149
    1 as the lowest common denominator of
    all arm boards you know cheap slow and
    
    0:23:28.149,0:23:33.789
    so on to actually work with this exact
    rotary encoder the cheapest one from the
    
    0:23:33.789,0:23:41.589
    Aliexpress of course see the pattern
    I tried Python I try the attaching
    
    0:23:41.589,0:23:48.579
    interrupt into Python I tried C code and
    nothing worked at least didn't work
    
    0:23:48.579,0:23:56.859
    worked reliably and if you just write
    the small device tree say the correct
    
    0:23:56.859,0:24:01.809
    number of steps you have at your rotary
    encoder because by default it's 24 but
    
    0:24:01.809,0:24:08.589
    this particular one is 20 you will get
    perfect input device for your Linux with
    
    0:24:08.589,0:24:11.579
    just a few wires
    
    0:24:12.390,0:24:20.260
    amazing so we saw the buttons we saw the
    LEDs we have everything for IOT except
    
    0:24:20.260,0:24:25.840
    the relay so you saw on one of the
    previous pictures this relay box it's
    
    0:24:25.840,0:24:31.980
    basically four relays separated by
    optocouplers which is nice and my
    
    0:24:31.980,0:24:39.670
    suggestion since you can't in device
    three you can't say this pin will be
    
    0:24:39.670,0:24:45.790
    output but I want to initially drive it
    high or I want to initially drive it low
    
    0:24:45.790,0:24:52.330
    it seems like you can say that it's
    documented in documentation it's just
    
    0:24:52.330,0:24:56.440
    not implemented there on every arm
    architecture so you can write it in
    
    0:24:56.440,0:25:02.440
    device three but your device tree will
    ignore it. you but you can and this might be
    
    0:25:02.440,0:25:07.240
    somewhat important because for example
    this relay is actually powering all your
    
    0:25:07.240,0:25:11.220
    other boards and you don't want to
    reboot them just because you reboot the
    
    0:25:11.220,0:25:16.270
    machine which is actually driving the
    relay so you want to control that pin as
    
    0:25:16.270,0:25:24.310
    soon as possible so my suggestion is
    actually to explain to Linux kernel that
    
    0:25:24.310,0:25:30.310
    this relays is actually 4 LEDs which is
    somewhat true because the relay has the
    
    0:25:30.310,0:25:36.460
    LEDs on it and then use LEDs which do
    have the default state which works to
    
    0:25:36.460,0:25:41.410
    actually drive it as soon as possible as
    the kernel boot because kernel will boot
    
    0:25:41.410,0:25:45.640
    it will change the state of those pins
    from input to output and set them
    
    0:25:45.640,0:25:52.000
    immediately to correct value so you
    hopefully want want power cycle your
    
    0:25:52.000,0:25:56.410
    other boards, and then you can use the
    LEDs as you would normally use them in
    
    0:25:56.410,0:26:01.420
    any other way
    if LEDs are interesting to you have in
    
    0:26:01.420,0:26:06.340
    mind that on your on each of your
    computers you have at least two LEDs but
    
    0:26:06.340,0:26:10.810
    this caps lock and one is non lock on
    your keyboard and you can use those same
    
    0:26:10.810,0:26:15.190
    triggers I mentioned earlier on your
    existing Linux machine using those
    
    0:26:15.190,0:26:20.980
    triggers so for example your caps lock
    LED can blink as your network traffic
    
    0:26:20.980,0:26:29.380
    does something on your network really
    it's fun on the other hand if you have a
    
    0:26:29.380,0:26:36.370
    Raspberry Pi and you defined everything
    correctly you might hit into some kind
    
    0:26:36.370,0:26:42.370
    of problems that particular chip has
    default pull ups which you can't turn on
    
    0:26:42.370,0:26:49.059
    for some pins which are actually
    designed to be clocks of this kind or
    
    0:26:49.059,0:26:54.220
    another so even if you are not using
    that pin as the SPI clock whatever you
    
    0:26:54.220,0:26:59.110
    do in your device tree you won't be able to
    turn off, actually you will turn
    
    0:26:59.110,0:27:04.240
    off the the setting in the chip to for
    the pull up but the pull up will be
    
    0:27:04.240,0:27:08.140
    still there actually thought that there
    is a hardware resistor on board but
    
    0:27:08.140,0:27:14.980
    there isn't it's inside the chip just
    word of warning so if anything I would
    
    0:27:14.980,0:27:21.309
    like to push you towards using Linux
    kernel for the sensors which you might
    
    0:27:21.309,0:27:25.570
    not think of as the first choice if you
    just want to add some kind of simple
    
    0:27:25.570,0:27:32.080
    sensor to to your Linux instead of
    Arduino over serial port which I did and
    
    0:27:32.080,0:27:38.049
    this is the solution which might with
    much less moving parts or wiring pie and
    
    0:27:38.049,0:27:43.090
    in the end once you make your own shield
    for us but if I you will have to write
    
    0:27:43.090,0:27:49.480
    that device tree into the EEPROM anyway so
    it's good to start learning now so I
    
    0:27:49.480,0:27:53.890
    hope that this was at least useful very
    interesting and if you have any
    
    0:27:53.890,0:28:02.140
    additional questions I will be glad to
    to answer them and if you want to see
    
    0:28:02.140,0:28:07.780
    one of those all winner board which can
    be used with my software to show the pin
    
    0:28:07.780,0:28:12.460
    out here is one board which kost
    actually borrowed me yesterday and in which
    
    0:28:12.460,0:28:18.549
    yesterday evening I actually ported the
    my software which is basically just
    
    0:28:18.549,0:28:22.330
    writing the definition of those pins
    over here and the pins on the header
    
    0:28:22.330,0:28:26.950
    which I basically copy pasted from the
    excel sheet just to show that you can
    
    0:28:26.950,0:28:32.830
    actually do that for any board you have
    with just really pin out in textual file
    
    0:28:32.830,0:28:36.370
    it's really that simple
    here are some additional
    
    0:28:36.370,0:28:38.300
    links and do you have any questions?
    
    0:28:39.420,0:28:41.420
    [one?]
    
    
        
          

  • DORS/CLUC 2017: bro - what's in your network?

    This year on DORS/CLUC 2017, I talked about bro which is great network analysys tools everybody should know, but dispite it's long history is not as well known as you would suspect.

  • etckeeper, bind jnl files and git-pack memory problems

    For last few years, one of first tools which we install on each new server is etckeeper. It saved us couple of times, and provides nice documentation about changes on the system.

    However, git can take a lot of space if you have huge files which change frequently (at least daily since etckeeper has daily cron job to commit changes done that day). In our case, we have bind which stores jnl files in /etc/bind which results in about 500 Kb change each day for 11 zones we have defined.

    You might say that it doesn't seem to be so bad, but in four months, we managed to increase size of repository from 300 Mb to 11 Gb. Yes, this is not mistake, it's 11000 Mb which is increase of 36 times! Solution for this is to use git gc which will in turn call git-pack to compress files. But this is where problems start -- git needs a lot of RAM to do gc. Since this machine has only 1 Gb of RAM, this is not enough to run git gc without running out of memory.

    Last few times, I transferred git repository to other machine, run git gc there and than transfered it back (resulting in nice decrease from 11 Gb back to 300 Mb), however, this is not ideal solution. So, let's remove bind jnl files from etckeeper...

    Let's start with our 11 Gb git repo, copy it to another machine which has 64 Gb or RAM needed for this operation.

    root@dns01:/etc# du -ks .git
    11304708        .git
    
    root@dns01:~# rsync -ravP /etc/.git build.ffzg.hr:/srv/dns01/etc/
    
    Now, we will re-create local files because we need to find out which jnl files are used so we can remove them from repo.
    root@build:/srv/dns01/etc# git reset --hard
    
    ls bind/*.jnl | xargs -i git filter-branch -f --index-filter 'git rm --cache --ignore-unmatch {}'
    
    echo 'bind/*.jnl' >> .gitignore
    git commit -m 'ignore ind jnl files' .gitignore
    
    Now, finally we can shrink our 11 Gb repo!
    root@build:/srv/dns01/etc# du -kcs .git
    11427196        .git
    
    root@build:/srv/dns01/etc# git gc
    Counting objects: 38117, done.
    Delta compression using up to 18 threads.
    Compressing objects: 100% (27385/27385), done.
    Writing objects: 100% (38117/38117), done.
    Total 38117 (delta 27643), reused 12846 (delta 10285)
    Removing duplicate objects: 100% (256/256), done.
    
    root@build:/srv/dns01/etc# du -ks .git
    414224  .git
    
    # and now we can copy it back...
    
    root@dns01:/etc# rsync -ravP build.ffzg.hr:/srv/dns01/etc/.git .
    
    Just as side note, if you want to run git gc --aggressive on same repo, it won't finish with 60 Gb or RAM and 100 Gb of swap, which means that it needs more than 150 Gb of RAM.

    So, if you are storing modestly sized files which change a lot, have in mind that you might need more RAM to run git gc (and get disk usage under control) than you might have.

  • Let's hack cheap hardware - 2016 edition

    Last week I head pleasure to present at two conferences in two different cities: DORS/CLUC 2016 and Osijek Mini Maker Faire on topic of cheap hardware from China which can be improved with little bit of software or hardware hacking. It was well received, and I hope thet you will find tool or two in it which will fill your need.

    I hope to see more hacks of STM8 based devices since we have sdcc compiler with support for stm8, cheap SWIM programmer in form of ST-Link v2 (Chinese clones, which are also useful as ARM SWD programmers) and STM8 has comparable features to 8-bit AVR micro-controllers but cheaper.

  • Debian OpenLDAP with GnuTLS and OpenSSL certificates

    Every few years we have to renew SSL certificates. And there is always something which can go wrong. So I decided to reproduce exact steps here so that Google can find it for next unfortunate soul who has same problem.

    Let's examine old LDAP configuration:

    deenes:/etc/ldap/slapd.d# grep ssl cn\=config.ldif 
    olcTLSCACertificateFile: /etc/ssl/certs/chain-101-mudrac.ffzg.hr.pem
    olcTLSCertificateFile: /etc/ssl/certs/cert-chain-101-mudrac.ffzg.hr.pem
    olcTLSCertificateKeyFile: /etc/ssl/private/mudrac.ffzg.hr.gnutls.key
    
    We need to convert OpenSSL key into format which GnuTLS understands:
    deenes:/etc/ssl/private# certtool -k < star_ffzg_hr.key > /tmp/star_ffzg_hr.gnutls.key
    
    Than we need to create certificate which includes our certificate and required chain in same file:
    deenes:/etc/ldap/slapd.d# cat /etc/ssl/certs/star_ffzg_hr.crt /etc/ssl/certs/DigiCertCA.crt > /etc/ssl/certs/chain-star_ffzg_hr.crt
    
    All is not over yet. OpenLDAP doesn't run under root priviledges, so we have to make sure that it's user is in ssl-cert group and that our certificates have correct permissions:
    deenes:/etc/ldap/slapd.d# id openldap
    uid=109(openldap) gid=112(openldap) groups=112(openldap),104(ssl-cert)
    
    deenes:/etc/ldap/slapd.d# chgrp ssl-cert \
    /etc/ssl/certs/DigiCertCA.crt \
    /etc/ssl/certs/star_ffzg_hr.crt \
    /etc/ssl/certs/chain-star_ffzg_hr.crt \
    /etc/ssl/private/star_ffzg_hr.gnutls.key
    
    deenes:/etc/ldap/slapd.d# chmod 440 \
    /etc/ssl/certs/DigiCertCA.crt \
    /etc/ssl/certs/star_ffzg_hr.crt \
    /etc/ssl/certs/chain-star_ffzg_hr.crt \
    /etc/ssl/private/star_ffzg_hr.gnutls.key
    
    deenes:/etc/ldap/slapd.d# ls -al \
    /etc/ssl/certs/DigiCertCA.crt \
    /etc/ssl/certs/star_ffzg_hr.crt \
    /etc/ssl/certs/chain-star_ffzg_hr.crt \
    /etc/ssl/private/star_ffzg_hr.gnutls.key
    -r--r----- 1 root ssl-cert 3764 Jan 19 09:45 /etc/ssl/certs/chain-star_ffzg_hr.crt
    -r--r----- 1 root ssl-cert 1818 Jan 17 16:13 /etc/ssl/certs/DigiCertCA.crt
    -r--r----- 1 root ssl-cert 1946 Jan 17 16:13 /etc/ssl/certs/star_ffzg_hr.crt
    -r--r----- 1 root ssl-cert 5558 Jan 19 09:23 /etc/ssl/private/star_ffzg_hr.gnutls.key
    
    Finally, we can modify LDAP configuration to use new files:
    deenes:/etc/ldap/slapd.d# grep ssl cn\=config.ldif 
    olcTLSCACertificateFile: /etc/ssl/certs/DigiCertCA.crt
    olcTLSCertificateFile: /etc/ssl/certs/chain-star_ffzg_hr.crt
    olcTLSCertificateKeyFile: /etc/ssl/private/star_ffzg_hr.gnutls.key
    
    We are done, restart slapd and enjoy your new certificates!

  • FSec 2015 - Raspberry PI for all your GPIO needs

    When I started playing with Raspberry Pi, I was a novice in electronics (and I should probably note that I'm still one :-).

    But since then, I did learn a few things, and along that journey I also figured out that Raspberry Pi is great little device which can be used as 3.3V programmer for AVR, JTAG, SWD or CC111x devices (and probably more).

    I collected all my experiences in presentation embedded below which I had pleasure to present at FSec conference this year. I hope you will find this useful.

  • DORS/CLUC 2015: AVR component tester

    Few weeks ago, we had our annual conference DORS/CLUC 2015 on which I had interesting (hopefully) presentation about AVR component tester. Since then, we got video recording of conference, so below you can find embedded presentation and video recording (in Croatian).

  • Overview of ganeti cluster from command line: ps, kvm, proc and tap

    We have been running ganeti cluster in our institution for more than a year now. We did two cycles of machine upgrades during that time, and so far we where very pleased with ability of this cloud platform. However, last week we had a problem with our instances -- two of them got owned and started generating DoS service attack to external resources. From our side it seemed at first like our upstream link is over saturated, and we needed to way to figure out why it is.

    gnt-info.png

    At first, it seemed like this would be easy to do. Using dstat,i I found that we are generating over 3 Gb/s traffic every few seconds to outside world. We have 1 Gb/s upstream link, but our bonded interfaces on ganeti nodes can handle 3 Gb/s of traffic, so for a start we where saturating our own link.

    But which instance did that? I had to run dstat on every node in our cluster until I found two nodes which had instances which where overloading our link. Using iftop I was able to get hostname and IP address of instances which I wanted to shut down. However, this is where problems started. We didn't have DNS entries for them, and although I had IP and mac address of instances I didn't had easy way to figure our which instance has that mac.

    Than I figured out that I can get mac from kvm itself, using ps. Once I found instances it was easy to stop then and examine what happened with them.

    But, this got me thinking. Every time I have a troubleshooting problem with ganeti, I basically use more or less same command-line tools to figure out what is going on. But I didn't have a tool which would display me some basic stats about instance, but including mac addresses and network traffic (which in our configuration are tap devices added to bridges). So I wrote, gnt-info which presents nice overview of your instances in ganeti cluster which you can grep to drill-down into particular instance or host.

  • Controlling 315 MHz light sockets using Arduino

    We all read hackaday, and when I read Five Dollar RF Controlled Light Sockets post I decided that I have to buy some. However, if you read comments on original Cheap Arduino Controlled Light Sockets - Reverse Engineering RF post and especially comments, you will soon figure out that ordering same looking product from China might bring you something similar but with different internals.

    In my case, all four light sockets turn on or off with any button press on remote which was a shame. When I opened remote and socket, I also had bad surprise. My version didn't have any SPI eeprom, but just two chips, ST F081 FB 445 in remote and ST ED08 AFB422 in light bulb (in picture hidden below receiver board).

    remote.jpg socket-top.jpg socket-bottom.jpg

    But, I already had acquired two sets so I wanted to see what I can do with them. Since I couldn't read eeprom to figure out code, I decided to use rtl-sdr to sniff radio signals and try to command them using cheap 315 MHz Arduino module.

    I used gqrx to sniff radio signals and I was not pleased. Remote drifted all over the place mostly around 316 MHz and it was some trial and error to capture signals which are generated when buttons are pressed. However, I have verified that it's sending same signal multiple times no matter which keys I press (which would explain why four pins on remote are soldered together).

    After a while I had two traces (since I have two sets of light sockets) and could decode binary data which is sent from following picture:

    signals.png

    How I knew that one set is transmitting 1000100110110000000000010 and another one 1011001001011111000000010. From looking into timing in audacity, it seemed that each bit is encoded in short-long or long-short sequence where short one is about third of long one, and one bit is about 1200 ms. I cheated here a little and stuck scope into scope into transmit trace on remote to verify length of pulses just to be sure.

    So as next step I wrote simple Arduino sketch to try it out:

    #define TX_PIN 7
    #define LED_PIN 13
    
    char *code = "1000100110110000000000010";
    //char *code = "1011001001011111000000010";
    
    void setup() {
      pinMode(LED_PIN, OUTPUT);
      pinMode(TX_PIN, OUTPUT);
    }
    
    void loop() {
      digitalWrite(LED_PIN, HIGH);
    
      for(int i = 0; i < strlen(code); i++) {
        int i1 = 300;
        int i2 = 900;
        if (code[i] == '1' ) {
          i1 = 900;
          i2 = 300;
        }
        digitalWrite(TX_PIN, HIGH);
        delayMicroseconds(i1);
        digitalWrite(TX_PIN, LOW);
        delayMicroseconds(i2);
      }
      
      digitalWrite(LED_PIN, LOW);  
      delay(3000);
    }
    
    So, I compiled it, uploaded to Arduino and... nothing happens. Back to the drawing board, I guess.

    When I was looking into gqrx I could see that signal is sent as long as I'm holding button up to 10 seconds. From experience before I know that this cheap receivers need some tome to tune into frequency so next logical step was to send same signal multiple times. And guess what, when I sent same singal twice with 2000 ms delay between them everything started to work.

    Again somewhat. Light socket in far corner of hall seemed to have problems receiving signal which would put two light socket in hall in opposite state: one would be on and another would be off. This was fun, and could be fixed with simple antenna on Arduino module (since currently I don't have any) but I will conclude that your IoT device should send different codes for on and off state so something like this won't happen to you.

    Then I got carried away and added commands to change all parameters to experiment how sensitive receiver is. You can find full code at http://git.rot13.org/?p=Arduino;a=blob;f=light_sockets/light_sockets.ino With this experiments I found out that you don't have to be precise with timings (so my oscilloscope step was really not needed). Receiver works with 500 ms low and 1100 ms high (for total of 1600 ms per bit) on high end, down to 200 ms for low and 800 ms for high (for total of 1000 ms per bit).

    I suspect that chips are some kind of 26 bit remote encoders/decoders but I can't find any trace of datasheet on Internet. This is a shame, because I suspect that it's possible to program light sockets to respond to any code and in theory address each of them individually (which was my goal in beginning). However poor construction quality, and same code for on and off state (combined with poor reception) makes me wonder if this project is worth additional time.

  • Reusing servos from old printers with Arduino

    I must confess that I'm pack rat. When I see old printer, something inside my head tries to figure out what I can do with all parts inside it instead of passing it to land-fill. However, I'm sysadmin and software guy, so JTAGs and programming is more up my wally than hardware. However, I decided to figure out how to drive one of servos using Arduino and this is my journey through this experience.

    So I started with printer disassembly and got one stepper motor and some gears on it. It is Mitsumi M42SP-6TE. It has four wires and I couldn't find any data sheet about it. So what do I do now?

    Mitsumi-M42SP-6TE.jpg

    First some educated guesses.I assumed that it's 12V servo. This was somewhat influenced by examining similar Mitsumi MP42SP-6NK motor which have rating of 12V or 24V. Using unimer and taking ohm measurement between wires I confirmed that it has 10 Ω between coils which means it's bipolar, having two different coils which had both to be driven at the same time.

    stepper-coils.jpg

    To connect it to Arduino, I acquired some time ago clone of Adafruit motor shield. When you buy cheap clones you expect some problems, and mine was fact that screw terminals on board weren't cut flash with board, so I had to use flat cutters and shorten them to prevent motor power from shorting with ICSP header on Arduino and USB connector on Uno. I also used red electrical tape and put it on USB connector just to be safe(r).

    AFMotor.jpg

    I also needed to add power jumper (white on picture) to provide power from Arduino (which in turn is powered by 12V 1A adapter). However, in this configuration L293D H-bridge becomes very hot to touch, so for testing I modified StepperTest example to provide me with serial control and powered Arduino from USB port (from which it draws 0.42 A and stepper still works with 5V supply which makes my 12 V assumption somewhat questionable). This enabled me to deduce that this stepper is also 7.5° which takes 48 steps to do full turn (small red dot on stepper gear helped to verify this). I also verified that top gear has 13:1 ratio to stepper motor making gear mechanism useful for smaller movements and better tork.

    I hope this blog post will motive you to take old printers, scanners, faxes and similar devices apart and take useful parts out if it. Re-using boards for driving steppers is also very interesting, but this particular printer didn't come with power supply (and it has strange connector) and driver chip on it doesn't have any publicly available info, so this will have to wait some other printer which will decide to give up it's parts for my next project...

  • FSec 2014 - I can haz your board with JTAG

    fsec2014-jtag.jpg

    Last week I had pleasure of attending FSec 2014, annual security conference. Just like last year, I had hardware presentation, this time about reverse engineering NComputing CPLD dongle. You can find it on http://bit.ly/fsec2014-jtag or embedded below.

    I had great time at conference, but I'm somewhat wondering did audience got something from my lecture. It was very interesting for me to figure out JTAG pinout on this board, and connect it to various JTAG programmers (all with their's good and bad sides) and I noticed that there are not any introductory text on the web how to approach this problem for the first time. So, I decided to present this topic in hope that this will motivate other people to take a hack at some board which would otherwise end up on e-waste of even worse, land-fill. And, who can resist call of free hardware which you can re-purpose? :-)