IPv6 Automatic Configuration

The Information Technology folks at the place I work enabled IPv6 a few months ago. Things worked great for a while but I recently noticed that I was not able to reach the IPv6 Internet. A quick investigation showed that IT disabled IPv6 Stateless Address Autoconfiguration (SLAAC) and enabled DHCPv6:

router>sh ipv6 interface vlan 320 
Vlan320 is up, line protocol is up
  IPv6 is enabled, link-local address is FE80::208:E3FF:FEFF:FD90 
  No Virtual link-local address(es):
  Description: data320
  Global unicast address(es):
    20xx:xxx:xxx:xxx::1, subnet is 20xx:xxx:xxx:xxx::/64 
  Joined group address(es):
    FF02::1
    FF02::2
    FF02::A
    FF02::D
    FF02::16
    FF02::FB
    FF02::1:2
    FF02::1:FF00:1
    FF02::1:FFFF:FD90
  MTU is 1500 bytes
  ICMP error messages limited to one every 100 milliseconds
  ICMP redirects are disabled
  ICMP unreachables are disabled
  Input features: Verify Unicast Reverse-Path
  Output features: MFIB Adjacency HW Shortcut Installation
  Post_Encap features: HW shortcut
 IPv6 verify source reachable-via any
   0 verification drop(s) (process), 0 (CEF)
   9 suppressed verification drop(s) (process), 9 (CEF)
  ND DAD is enabled, number of DAD attempts: 1
  ND reachable time is 30000 milliseconds (using 30000)
  ND advertised reachable time is 0 (unspecified)
  ND advertised retransmit interval is 0 (unspecified)
  ND router advertisements are sent every 200 seconds
  ND router advertisements live for 1800 seconds
  ND advertised default router preference is Medium
  Hosts use DHCP to obtain routable addresses.
router>

Note the “Hosts use DHCP to obtain routable addresses” message — it used to be “Hosts use stateless autoconfig for addresses”.

I am using NetworkManager on Ubuntu 14.10 to manage my network configuration. The version of NetworkManager on Ubuntu 14.10 is 0.9.8.8-0ubuntu28. The IPv6 configuration methods available for NetworkManager can be seen in the following screenshot:

When SLAAC was enabled, I had my network interface configured using the “Automatic” IPv6 configuration method. After IT switched to DHCPv6 this setting prevented my computer from getting an IPv6 address.

After switching to the “Automatic, DHCP only” method I was able to obtain an IPv6 address.

Unfortunately, it seems like the version of NetworkManager in Ubuntu 14.10 has a bug that prevents the installation of a default route (which is not obtained via DHCPv6 but via Neighbor Discovery Router Advertisement messages). The root cause of the bug seems to be that NetworkManager instructs the kernel to ignore Router Advertisement messages. It looks like this bug is fixed in NetworkManager versions 0.9.10.0 and later, but I decided to just live in an IPv4 at work instead of trying to backport the fix to NetworkManager 0.9.8, or trying to build NetworkManager 0.9.10.0 or later for Ubuntu 14.10.

Note: This blog post was helpful for me to understand what was happening: http://mor-pah.net/2012/11/06/cisco-ios-disabling-ipv6-stateless-autoconfig/.

ZoneMinder Hash Logins

ZoneMinder is a fantastic Linux video camera security and surveillance solution dosierung cialis. I have a ZoneMinder installation at home that I use to monitor a few IP-based video cameras.

My ZoneMinder installation uses the built-in authentication system, which means that only authenticated users can access the system.

One problem with using the built-in authentication system, however, is that it makes it hard to access video from the cameras from outside of ZoneMinder. For example, if I wanted to take a snapshot from a shell script of what one of the ZoneMinder cameras is currently recording, that would not be very easy to accomplish because the shell script would have to somehow log in first, establish a fake web browsing session (session cookie, etc.), and then finally request the snapshot.

Fortunately, ZoneMinder offers a way to accomplish this without too much hassle via a  feature called “hash logins”, which is enabled by setting the option ZM_AUTH_HASH_LOGINS (Options->System->ZM_AUTH_HASH_LOGINS).

The way to use this is by appending a ‘&auth=<login hash>’ parameter to the ZoneMinder URL one wants to access. For example, running the following command would retrieve a snapshot (in JPEG format) from the camera with monitor ID 8:

shell$ curl 'http://www.example.comt/cgi-bin/nph-zms?mode=single&monitor=8&auth=d8b45b3cf3b24407d09cbc16123f3549' -o /tmp/snapshot.jpg
 % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
 Dload  Upload   Total   Spent    Left  Speed
 100 22813  100 22813    0     0   9488      0  0:00:02  0:00:02 --:--:--  9485

The only complicated part here is knowing how to generate the hash used in the “auth” parameter. This does not seem to be documented anywhere, nor could I find any examples, but a quick read of the ZoneMinder code provided the necessary clues: The hash is calculated by the function getAuthUser() in the file includes/functions.php like this:

$time = localtime( $now );
$authKey = ZM_AUTH_HASH_SECRET.$user['Username'].$user['Password'].$remoteAddr.$time[2].$time[3].$time[4].$time[5];
$authHash = md5( $authKey );

ZM_AUTH_HASH_SECRET is a string chosen by the user via ZoneMinder options. $user[‘Username’] and $user[‘Password’] come from the ‘Users’ table in the ZoneMinder database — getAuthUser() will iterate over all existing users trying to find a match. $time contains the local time and $time[2], $time[3], $time[4], and $time[5] contain the current hour, day of the month, month and year, respectively. The code tries to find a match in the last two hours (in other words a login hash will found to be valid for up to two hours).

A simple test program to generate the hash looks like this:

#!/usr/bin/php
 <?php
 //
 // Needs ZM_OPT_USE_AUTH and ZM_AUTH_HASH_SECRET and ZM_AUTH_HASH_LOGINS.
 // Better not to use ZM_AUTH_HASH_IPS as this will break authentication
 // when client is behind NAT because the IP address of the client is used
 // to calculate the hash if ZM_AUTH_HASH_IPS is set.
 //
 $time = localtime();
 $authKey = 'mykey' . 'myuser' . '*0945FE11CAC14C0A4A72A01234DD00388DE250EC' . $time[2] . $time[3] . $time[4] . $time[5];
 echo "\$authKey = $authKey\n";
 $authHash = md5($authKey);
 echo "\$authHash = $authHash\n";
 ?>

Note that the hashed password for the user needs to be provided to the script (the user password is passed through the MySQL PASSWORD() function to finally obtain the password hash that is stored in the ZoneMinder database).

How to make practical use of all this? A script could generate the login hash and then access some part of ZoneMinder via an HTTP request. One could use this, for example, in a script run via cron every few minutes to take snapshots to produce a time-lapse video. This is left as an exercise for the reader.

Slow SSH logins/spun-down disk woken during SSH logins

For a while I have been troubleshooting why SSH logins into my Ubuntu server running 14.04 LTS are seemingly slow. I enabled SSH debugs (LogLevel set to DEBUG in /etc/ssh/{sshd_config,ssh_config}) on both the client and the server and did not find anything that pointed to an issue with the SSH negotiation/login itself. Recently I discovered that the 10-second delay in logging in had to do with SSH logins causing a hard disk that I keep spun down to be spun up. That takes about 10 seconds, which explains the delay.

Turns out that by default, console and SSH logins cause the scripts in /etc/update-motd.d/ to be executed. The script /etc/update-motd.d/98-fsck-at-reboot in particular is what causes disks to be spun up.

The scripts in /etc/update-motd-d/ are responsible for generating the file /run/motd.dynamic, which looks like this:

Welcome to Ubuntu 14.04.1 LTS (GNU/Linux 3.13.0-37-generic x86_64)

 * Documentation:  https://help.ubuntu.com/

  System information as of Thu Oct  9 10:05:21 EDT 2014

  System load:  0.37                Processes:           164
  Usage of /:   18.1% of 915.51GB   Users logged in:     1
  Memory usage: 55%                 IP address for eth0: 10.10.13.10
  Swap usage:   12%

  Graph this data and manage this system at:
    https://landscape.canonical.com/

That is pretty and provides some good information but for me I rather have a shell prompt immediately after I hit the <Enter> key after typing “ssh <my server>”. I then can manually execute some useful commands like “w” to see who is logged in, the uptime, etc.

I have disabled execution of the /etc/update-motd.d/ scripts by tweaking the files /etc/pam.d/{login,sshd} in the following way:

# Prints the message of the day upon succesful login.
# (Replaces the `MOTD_FILE' option in login.defs)
# This includes a dynamically generated part from /run/motd.dynamic
# and a static (admin-editable) part from /etc/motd.
#session    optional   pam_motd.so  motd=/run/motd.dynamic noupdate
#session    optional   pam_motd.so

# Disable display of /run/motd.dynamic and add "noupdate" so
# scripts in /etc/update-motd.d/* are not called.
# peloy@chapus.net
# 20141009
session    optional   pam_motd.so noupdate

The first two commented out “session” lines are what were there by default. I commented them out and then added a new “session” line that has the “noupdate” keyword, which is actually what causes the pam_motd.so module to not execute the scripts in /etc/update-motd.d/. This uncommented “session” line is what will display the standard /etc/motd file (if it exists).

Now a SSH login is fast, does not provide a lot of information upon log in (which I like), and, most important, spun down disks are not spun up upon log in:

$ ssh altamira
You have new mail.
Last login: Thu Oct  9 10:23:44 2014 from 2003:450:e6a5:100:a412:6z7a:897d:1387
altamira$ # That was a very fast login!

The following askubuntu.com question is what pointed me in the right direction:

http://askubuntu.com/questions/282245/ssh-login-wakes-spun-down-storage-drives

This is an issue that seems to have been introduced when I upgraded this server from Ubuntu 12.04 LTS to 14.04LTS. In particular, my Ubuntu 12.04LTS installation did not have the file /etc/update-motd.d/98-fsck-at-reboot.

Buffer Overflow in Embedded Microcontroller. Ouch.

We have been chasing down a mysterious problem in a embedded application we are developing. It is a sprinkler timer to water our yard. The microcontroller is an ATmega AVR 328p, the same microcontroller that some of the Arduino platforms use.

The application has an RFM12B wireless transceiver from Hope RF, and we are using this RFM12 library: http://www.das-labor.org/wiki/RFM12_library/en.

The issue is that the application works fine for days, sending and receiving data through the RFM12B wireless transceiver, but all of the sudden, it would stop working. Resetting the device restores operation.

The device is outside, in our yard, right next to a garden bib. It is not easy to troubleshoot this problem because all connectivity that we have to the device is via the RFM12B transceiver, so if it the wireless subsystem of the application is hosed, then there really is nothing we can do to troubleshoot. In addition, the wireless command set in in the firmware is currently very limited so we do not have good debugging tools even if the wireless subsystem is up. The firmware does send debugging information through a serial port on the microcontroller, though, so we have to use that in absence of other debugging tools.

The first step we took to debug the issue was to provide remote access to the microcontroller’s serial port. For this, we used a Raspberry Pi with an USB-to-serial adapter and with a WiFi USB adapter. We then left minicom (a serial communication program for Linux) running and came back every once in while, via remote SSH session, to check. Today we found an occurrence of the issue and investigated. This is what we found:

First, we noticed that the wireless subsystem was not working when we saw the following messages on the device’s console:

[2014-08-06 17:26:53] rfm12_tx() error 3
[2014-08-06 17:26:58] rfm12_tx() error 3
[2014-08-06 17:27:03] rfm12_tx() error 3
[2014-08-06 17:27:08] rfm12_tx() error 3

We then ran a diagnostic command on the console:

# show rfm12
[2014-08-06 17:29:11] My RFM12 node ID: 111.
[2014-08-06 17:29:11] RFM12 status register: 0x023f.
[2014-08-06 17:29:11] RFM12 state = 0
[2014-08-06 17:29:11] RFM12 tx state = 162
[2014-08-06 17:29:11] Number of bytes to transmit or receive = 219
[2014-08-06 17:29:11] Current byte count = 1
[2014-08-06 17:29:11] Total tx bytes = 40622
[2014-08-06 17:29:11] Total errors = 29983

A few things caught our attention:

  1. The RFM12 node ID should be 12 but the output says that it is 111.
  2. There is no such thing as RFM12 tx state 162 in the RFM12 library; it goes up to 3 or 4.
  3. The command prompt should be “frontlawn# “, but it is just “# “.

Obviously, some bad memory corruption has taken place here. Let’s see what we find…

The other piece of information we found in the minicom history buffer was this:

[2014-08-06 14:36:29] frontlawn# RFM12 rx packet: flags AD., hdr = 0x6c, len = 13.                                                
[2014-08-06 14:37:46] 00000000  3445 7365 7420 7661 6c20 6f20 33        4Eset val o 3                                             
[2014-08-06 14:37:46]                                                                                                             
[2014-08-06 14:38:27] RFM12 rx packet: flags AD., hdr = 0x6c, len = 14.                                                           
[2014-08-06 14:38:27] 00000000  3446 7365 7420 7661 6c20 636c 2033      4Fset val cl 3                                            
[2014-08-06 14:38:27]                                                                                                             
[2014-08-06 15:07:10] RFM12 rx packet: flags ..., hdr = 0x0f, len = 254.                                                          
[2014-08-06 15:07:11] 00000000  3445 7365 7420 7661 6c20 6f20 336e 2033 4Eset val o 3n 3                                          
[2014-08-06 15:07:11] 00000010  ffff ffff 3337 fd7f fc0f fd1c 201e 07ff ....37...... ...                                          
[2014-08-06 15:07:11] 00000020  07fb 03df 407c 741f 2dd4 040c f721 a302 ....@|t.-....!..                                          
[2014-08-06 15:07:11] 00000030  3529 0b05 080e 0200 0000 0000 0000 0000 5)..............                                          
[2014-08-06 15:07:11] 00000040  0000 0000 0000 0000 0000 0000 0000 0000 ................                                          
[2014-08-06 15:07:11] 00000050  0000 0000 0000 0000 0000 0100 0000 008a ................                                          
[2014-08-06 15:07:11] 00000060  e955 ae3c b9e0 c7f0 6f10 179c bd65 625f .U.<....o....eb_                                          
[2014-08-06 15:07:11] 00000070  3aea 998e 925c 1f43 152b 6b49 5e0b cca2 :....\.C.+kI^...                                          
[2014-08-06 15:07:11] 00000080  cdd5 313e ae9e 1f75 9a3d 1eea d964 bfee ..1>...u.=...d..                                          
[2014-08-06 15:07:11] 00000090  bffe 96dc 5df9 6b2c fdb7 8dd5 daab b8aa ....].k,........                                          
[2014-08-06 15:07:11] 000000a0  8fc5 6e42 8df9 9e7b 53bf 3cf6 fd19 7737 ..nB...{S.<...w7                                          
[2014-08-06 15:07:11] 000000b0  2767 f67c 975b 8f5a a7ea 6e63 bd39 2258 'g.|.[.Z..nc.9"X                                          
[2014-08-06 15:07:11] 000000c0  756e a1bf 80fd 4b56 f0e3 e7fb bb28 ef93 un....KV.....(..                                          
[2014-08-06 15:07:11] 000000d0  e353 2308 50fe 49f6 7b4f 2300 b087 f1fa .S#.P.I.{O#.....                                          
[2014-08-06 15:07:12] 000000e0  9581 ff47 aba7 75a2 c0eb 91fa 6b7a 80e3 ...G..u.. cialis 20mg apotheke...kz..                                          
[2014-08-06 15:07:12] 000000f0  52e0 93c0 da66 bdfb 279b 8a07 af12      R....f..'.....                                            
[2014-08-06 15:07:12]                                                                                                             
[2014-08-06 15:07:12] Invalid valve number.                                                                                       
[2014-08-06 15:07:12] rfm12_tx() error 3                                                                                          
[2014-08-06 15:07:17] rfm12_tx() error 3

At 14:36:29 the controller received the command “set val o 3” (short for “set valve open 3”, which instructs the controller to open valve number 3).

At 14:38:27 the controller received the command “set val cl 3” (short for “set valve close 3”, which instructs the controller to close valve number 3).

We sent these commands and everything was good until this point.

However, at 15:07:10, we receive a giant packet of 254 bytes. That is the first sign of trouble — we only have 2048 bytes of RAM in an ATmega 328p microcontroller, so we have never configured such a large receive buffer in our application. We check the library source code and see that the size of the receive buffer is configurable and we have configured it to be 40 bytes.

Is it possible that the RFM12 library is buggy and is accepting such a large packet and storing it in a 40-byte buffer? No, we checked and it has the correct validations. This points to an issue in our code…

This is our code:

        if (rfm12_rx_status() == STATUS_COMPLETE) {
            pkt_hdr.__hdr_val = rfm12_rx_type();
            pkt_len = rfm12_rx_len();
            pkt_data = rfm12_rx_buffer();
            [...]
            if (pkt_len == 0)
                goto pkt_processed;

            /*
             * Action to take on received packet depends on the payload
             * type, which is the first byte of the payload.
             */
            if (pkt_data[0] == RFM12_PAYLOAD_CLICMD) {
                memcpy(cli_cmdbuf, pkt_data + 2, pkt_len - 2);
                cli_cmdbuf[pkt_len - 2] = '\0';
                cli_processcommand(cli_cmdbuf);
                [...]

The first byte of the packet (pkt_data[0]) is 0x34, according to the packet dump above. 0x34 happens to be RFM12_PAYLOAD_CLICMD, so the condition of the “if ()” statement is true and we take that code path. The first instruction in that code path is a memcpy() that will copy pkt_len – 2 bytes, i.e. 254 – 2 = 252 bytes into the array cli_cmdbuf[].

cli_cmdbuf[] is a global variable declared as:

/* A command cannot be longer that this many characters. */
#define CLI_MAX_CMDLEN 80

char cli_cmdbuf[CLI_MAX_CMDLEN];

Ouch! Yes, our buffer has been overflowed with this memcpy(). By 252 – 80 = 172 bytes! This explains the memory corruption and the failure of the wireless subsystem of the application.

A couple of observations about this whole issue:

  1. The received packet that caused the entire problem should not have been received. We have no idea who sent it, or why it is so large, but the fact of the matter is that we received it. Yes, it obviously is bogus, but we cannot allow a stray packet to bring us down like that. The lesson re-learned here is that our application needs to be able to handle exceptional conditions such as this.
  2. Of course, we were not aware of such exceptional condition before. Otherwise we would have put a check in place to prevent the disastrous memcpy(). The main problem here is that we were acting under the assumption that the low level RFM12 driver would not pass to us a packet that has a received, advertised length that is larger than the configured size of the receive buffer — the low level driver checks for the available space in the receive buffer and does not store more data if there is no more space left. However, it notifies the application that there is a packet ready to be handled, even if that packet is incomplete because it did not fit in the receive buffer. We guess this behavior is debatable because the application might want to consume that packet even if it is not complete (for example, do some error handling, print a debug message, etc.).
  3. In the world of embedded applications, the importance of debugging using a serial port cannot be overstated — we would have had a very hard time to find this issue if we had not seen the packet dump of that 254-byte packet on the serial console.

In terms of addressing the issue — we are going to try to address the problem by checking in our application that the size of the received advertised length of the packet is less than the size of the receive buffer. If the size is larger then we will ignore the packet. We will see how this plays out…

 

Designing Printed Circuit Boards

Designing Printed Circuit Boards (PCBs) is not as hard as it seems. A couple of years ago I got into embedded electronics as a hobby and since then I have designed a couple of boards for simple projects. I used CadSoft’s EAGLE PCB design software. The learning curve was (is, because I think I am still learning) steep but there are good tutorials to be found on-line, including a tutorial from CadSoft itself.

Obviously, after designing a board you will want to manufacture it, either by yourself or by paying someone to do it cialis 10mg bestellen. In either case, catching errors in the design before the board is manufactured will prevent frustrations after you have the board in your hands and notice during testing that it does not work because of some problem like incorrect part footprints, incorrect board size, etc.

What I have done a couple of times to try to catch problems before it is too late has been to make a 1:1 copy of the board, glue it to some material that allows to stick real parts to it, and then lay out the parts on top, as shown in the following picture:

Nothing earth-shattering but it definitely has been useful and saved me a couple of times.

Upload non-Arduino firmware to Arduino-compatible board

The Atmel AVR family of microcontrollers is our favorite solution for embedded electronic projects. As you know, this family is what the popular Arduino platform uses cialis preis apotheke. However, for our projects we have never used the Arduino integrated development environment (IDE), or Arduino libraries. Instead, we have stuck with AVR libc mainly so we can have more control over our firmware and to try to have firmware with a smaller footprint in terms of both execution and image size.

Because we have not been using the Arduino IDE, we have always uploaded firmware to the AVR microcontroller using an in-system programmer (ISP) (the ISP programmer we use is the inexpensive USBtiny). This has been a requirement because our microcontrollers do not normally have a boot loader that allows them to be flashed via the serial port, unlike the Arduino, which does not expose the SPI through a connector that allows someone to hookup an ISP programmer, and therefore has to be programmed

Recently, however, we bought a Moteino, a very nice Arduino-compatible board, that has a boot loader that is compatible with the Arduino IDE. This required us to come up with a way to upload firmware to this board. We originally thought about soldering an adapter to use the AVR’s Serial Peripheral Interface (SPI), which uses the three signals Serial ClocK (SCK), Master In-Slave Out (MISO) and Master Out-Slave In (MOSI), and then use our USBtiny ISP programmer.

However, it turns out that is a lot easier than that — the AVRDUDE software can actually program Arduino-compatible boards directly, without using the SPI interface. We probably should have guessed this because, as we understand it, the Arduino IDE actually uses AVRDUDE to upload firmware to the target.

A sample AVRDUDE invocation looks like this:

shell$ avrdude -p atmega328p -c arduino -P /dev/ttyUSB2   -y -U flash:w:primus.hex

This is what the command-line arguments do:

  • -p atmega328p: specifies the type of target microcontroller.
  • -c arduino: specifies the programmer type. We understand that stk500v1 should work, and we have seen online references that seem to indicate that is what the Arduino IDE uses, but stk500v1 did not work for us. Instead, our AVRDUDE executable (from Ubuntu 13.10) does have an “arduino” programmer that worked very well.
  • -P /dev/ttyUSB2: this is the device to use to talk to the Arduino-compatible target.
  • -U flash:w:primus.hex: this is the name of the firmware file to upload to the Arduino-compatible target.

When we use our ISP programmer, one argument that we like to use is -y, which increments a 16-bit counter stored in the last two bytes of the AVR EEPROM (this counter has to be initialized with a one-time AVRDUDE invocation that uses the arguments -W <initial counter value>). We found out that the boot loader used by Arduino and Arduino-compatible boards (apparently Optiboot) does not handle AVR EEPROM access, so the use of -y when invoking AVRDUDE to upload flash to the Arduino-compatible board is not possible (and neither is initializing the counter with -Y, nor uploading EEPROM data using -U eeprom:w:data.hex).

But this is a small price to pay for the convenience of uploading our AVR libc firmware without having to use the Arduino IDE.

Add More Disk Space To Existing Ubuntu 12.04 Server Installation

Recently we found ourselves regretting a decision we made when we installed Ubuntu Server 12.04LTS on a VMware ESXi virtual machine (VM) — when we created the VM, we allocated a very small hard disk (8 GBytes) thinking that for the specific purpose of that machine we were not going to need a bigger hard drive. It turns out that we were very wrong, which became apparent when we tried to download a 4+ GByte file and the download failed because of lack of free space.

Because we did not want to create a new VM and copy the existing installation over we decided to just increase the size of the existing disk and the partitions/physical volumes/logical volumes inside it. Turns out this was not as easy as we thought so we decided to document things here. We basically followed the instructions in this blog post (credit where credit is due):

http://www.joomlaworks.net/blog/item/168-resizing-the-disk-space-on-ubuntu-server-vms

Increasing the size of the actual hard disk is very easy because we are working with a virtual machine — all it takes is to is to edit the virtual machine settings, look for the virtual disk, and increase the size (we have done this for both VMware and VirtualBox virtual machines; the process is similar). The difficult part comes after increasing the size of the virtual disk — the existing stuff inside the hard disk needs to be resized as well.

Several links we found online talked about booting the machine with an Ubuntu LiveCD and then using GParted (a GUI-based partition utility) to resize the existing partition to make use of the new, extra unallocated space. We did not have any luck with that.

Instead, what we found worked for us was to just make use of the Linux Logical Volume Manager (LVM), which is what was set up by the Ubuntu installer when we first installed Ubuntu on this machine. Basically, the process looks like this:

  1. Create a new logical partition using the new unallocated space.
  2. Create a new physical volume that uses the new partition.
  3. Extend the existing Volume Group that was created during Ubuntu installation to make use of the new physical volume.
  4. Extend the Logical Volume to make use of the new available space.
  5. Resize the filesystem to make use of the new available space.

We will go in detail on each of these steps.

Create New Logical Partition

We used cfdisk. Basically, select the unallocated (free) space, then select the “New” option, then “Logical”, and allocate all the available space (shown by default). Select “Type” and enter “8e” (for Linux LVM). Finally select “Write”, confirm by typing “yes” followed by <Enter>, then “Quit”, and reboot the machine.

This is how the partition table looked before using cfdisk:

root@holyland:~# fdisk -l /dev/sda

Disk /dev/sda: 268.4 GB, 268435456000 bytes
255 heads, 63 sectors/track, 32635 cylinders, total 524288000 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x0009f8ab

   Device Boot      Start         End      Blocks   Id  System
/dev/sda1   *        2048      499711      248832   83  Linux
/dev/sda2          501758    16775167     8136705    5  Extended
/dev/sda5          501760    16775167     8136704   8e  Linux LVM

And this is how the partition table looks like after using cfdisk to create the new partition on the free space and rebooting the machine. Note the new partition /dev/sda6:

root@holyland:~# fdisk -l /dev/sda

Disk /dev/sda: 268.4 GB, 268435456000 bytes
255 heads, 63 sectors/track, 32635 cylinders, total 524288000 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x0009f8ab

   Device Boot      Start         End      Blocks   Id  System
/dev/sda1   *        2048      499711      248832   83  Linux
/dev/sda2          501758   524287999   261893121    5  Extended
/dev/sda5          501760    16775167     8136704   8e  Linux LVM
/dev/sda6        16775231   524287999   253756384+  8e  Linux LVM

Create New Physical Volume

To create a new physical volume in the new partition we used pvcreate:

root@holyland:~# pvcreate /dev/sda6
  Physical volume "/dev/sda6" successfully created

Extend Existing Volume Group

First, we need the name of the volume group. This can be obtained by running the vgdisplay command:

root@holyland:~# vgdisplay 
  --- Volume group ---
  VG Name               holyland
  System ID             
  Format                lvm2
  Metadata Areas        1
  Metadata Sequence No  3
  VG Access             read/write
  VG Status             resizable
  MAX LV                0
  Cur LV                2
  Open LV               2
  Max PV                0
  Cur PV                1
  Act PV                1
  VG Size               7.76 GiB
  PE Size               4.00 MiB
  Total PE              1986
  Alloc PE / Size       1978 / 7.73 GiB
  Free  PE / Size       8 / 32.00 MiB
  VG UUID               H5FfHu-lsxo-G9Od-k8S5-lnCQ-PuCq-059Xco

The output above (under “VG Name”) shows that the name of the volume group is “holyland” (the name of our server).

Next we use the vgextend command to extend the existing volume group to the new physical volume:

root@holyland:~# vgextend holyland /dev/sda6
  Volume group "holyland" successfully extended

Extend The Logical Volume

First, we need to obtain the name of the logical volume that we want to extend (this is because a volume group can contain several logical volumes). To obtain the name of the logical volume with use the lvdisplay command:

root@holyland:~# lvdisplay 
  --- Logical volume ---
  LV Name                /dev/holyland/root
  VG Name                holyland
  LV UUID                vNPQV1-s5OU-GYVP-FCMp-p3UY-7fhe-FXNsK8
  LV Write Access        read/write
  LV Status              available
  # open                 1
  LV Size                7.23 GiB
  Current LE             1851
  Segments               1
  Allocation             inherit
  Read ahead sectors     auto
  - currently set to     256
  Block device           252:0

  --- Logical volume ---
  LV Name                /dev/holyland/swap_1
  VG Name                holyland
  LV UUID                YxBsBD-we0S-ELCV-yCsz-RAdL-Qzcj-y4cpH9
  LV Write Access        read/write
  LV Status              available
  # open                 2
  LV Size                508.00 MiB
  Current LE             127
  Segments               1
  Allocation             inherit
  Read ahead sectors     auto
  - currently set to     256
  Block device           252:1

We are interested in extending the logical volume used for the root filesystem, which corresponds to the logical volume called “/dev/holyland/root” in the output above (under “LV Name”).

To extend the logical volume we are interested in, we use the lvextend command as follows:

root@holyland:~# lvextend -l 100%FREE /dev/holyland/root
  Extending logical volume root to 242.03 GiB
  Logical volume root successfully resized

Note the use of of the “-l 100%FREE” argument, which indicates that we want to extend the logical volume to use 100% of the free space.

Extend Filesystem

Finally, to extend the file system we use the resize2fs command:

root@holyland:~# resize2fs /dev/holyland/root 
resize2fs 1 cialis oral jelly.42 (29-Nov-2011)
Filesystem at /dev/holyland/root is mounted on /; on-line resizing required
old_desc_blocks = 1, new_desc_blocks = 16
The filesystem on /dev/holyland/root is now 63447040 blocks long.

To verify, we use the df command:

root@holyland:~# df -hT
Filesystem                Type      Size  Used Avail Use% Mounted on
/dev/mapper/holyland-root ext4      239G  3.8G  225G   2% /
udev                      devtmpfs  237M  4.0K  237M   1% /dev
tmpfs                     tmpfs      99M  260K   98M   1% /run
none                      tmpfs     5.0M     0  5.0M   0% /run/lock
none                      tmpfs     246M     0  246M   0% /run/shm
/dev/sda1                 ext2      228M   75M  141M  35% /boot

Now the root filesystem has a healthy size!

Mixed Content Blocking in Firefox 23

A website that I use at work all of the sudden started to render in a very broken way. Since we had had similar issues in the past I originally thought that it was a problem on the web application itself. However, after asking a co-worker I learned that the breakage is caused by a new feature that is enabled by default in Firefox 23: mixed content blocking. The feature is explained well at the following URL, but it basically boils down to “Firefox will block HTTP content referenced from a page served over HTTPS”.

https://blog.mozilla.org/tanvi/2013/04/10/mixed-content-blocking-enabled-in-firefox-23/

The feature is a nice security feature. However, I think it has been terribly implemented in my opinion — first, you cannot create persistent exceptions (whitelist); second, you cannot create exceptions for entire domain (you have to create them on a page by page basis) so next time you open a page on the same site that also has mixed content then the mixed content will be blocked too. For the second issue, reading the comments in Mozilla bug 873349 is enlightening.

So, I can appreciate all the work the Mozilla developers have put into this feature but I have no option other than to disable it because it really puts a dent on my productivity. Let’s see if this feature is enhanced in a future Firefox release.

ZoneMinder Memory-Mapped Files

After tweaking the capture image size of some of the IP cameras connected to our ZoneMinder installation we started to get the following error in the ZoneMinder log right after launching a viewer to watch the camera’s video stream:

Got unexpected memory map file size 36865192, expected 9217192

Googling for this error took us to this blog post:

http://jared-oberhaus-tech-notes.blogspot.com/2011/12/im-trying-to-capture-video-from-device.html

Which in turn took us to the ZoneMinder FAQ.

The recommendation is to increase the setting /proc/sys/kernel/shmmaxsize so ZoneMinder has enough memory to memory-map the files it needs during streaming.

However, upon checking our /proc/sys/kernel/shmmaxsize setting we found that it had pretty high setting (the recommended [in the ZoneMinder FAQ] 536870912, for 128 MB of maximum shared memory allocatable at a time), because we had run into the issue before and tried to fix it by following the recommendation in the ZoneMinder FAQ. In addition, the error message indicates that it expects a file with a size that is smaller than it currently has, so increasing the /proc/sys/kernel/shmmaxsize setting would not have fixed the problem.

It turns out that ZoneMinder had created the memory-mapped file for a specific capture image size:

$ ls -l /dev/shm/
 total 90016
 -rw------- 1 www-data www-data 36865192 Apr 9 08:24 zm.mmap.6
 [...]

And when we changed the capture image size to a smaller resolution, the required size of the memory-map filed decreased. However, because ZoneMinder had not been restarted, the memory-mapped file had not been recreated, and it still had the size that ZoneMinder allocated for the original, higher resolution video capture.

Re-starting ZoneMinder caused the memory-mapped file to be recreated, now with the correct size for the new (smaller) capture image size:

$ ls -l /dev/shm/
 total 63016
 -rw------- 1 www-data www-data 9217192 Apr 9 08:47 zm cialis online ohne rezept.mmap.6
 [...]

After this, ZoneMinder did not generate the error anymore.

Update 20130415:

We increased the capture image size of one of the ZoneMinder monitors and received again the “Got unexpected memory map file size …” message, this time indicating that the size of the file is smaller than expected. This makes sense and shows that the issue has nothing to do with the configured value in /proc/sys/kernel/shmmaxsize but with a memory-mapped filed created by ZoneMinder that is not recreated when the size of the image capture is changed. This should be considered a bug in ZoneMinder, in our opinion. We are running ZoneMinder 1.25.0.