apc_mmap: mmap failed: Cannot allocate memory

While trying to increase the size of the APC segment on my development machine I suddenly started getting “apc_mmap: mmap failed: Cannot allocate memory” in my error_log. This also made Apache angry, so it refused to return any pages while the error message was present.

After removing the apc.shm_size again, things went back to working as normal.

A bit of psychic debugging and reading phpinfo() output revealed the culprit:

Do NOT include a “M” specifier when providing a size for apc.shm_size. Leave it off. It will assume MBs anyways. This solved the issue.

This is in contrast with the manual page, where it has been documented with a default value of “32M”, while phpinfo() says “32”. This behaviour change with APC 3.1.4, so if your version is older than that you’ll have to use the format without the M.

Space, Page Up, Page Down, Home, End Broken for Navigation in Firefox

While I initially thought I had gone crazy or were still dreaming, my fear was true – all my keyboard page navigation had stopped working in Firefox (3.6.3). I tried to move onto to the next by pressing space or page down, my hands trembled as I discovered that neither arrow keys or home / end keys worked. The friendly internet suggested that I should turn Caret Browsing (F7) off (.. so try that if you’re in this situation), but that just told me that I were turning Caret Browsing on (with a proper warning). No luck.

After a bit of tinkering I disabled all my add-ons (previously known as extensions), and voilá, everything worked as it were supposed to! Further problem hunting revealed the culprit: The Del.icio.us Bookmarks Add-on. Curse you, del.icio.us! Disabling the Add-on and re-enabling all the other addons solved the issue, and I’m now happily browsing the internet one page size at the time again.

Patch for Max Iterations for a foreach Block in Smarty

After running into a need for a max iteration count on a foreach block tonight and seeing that several others have had the need during the years, I’ve created a simple patch to add max= as an attribute to the foreach block. I tried to search the archives for a reason why this hadn’t already been included, so feel free to ignore this patch if there are proper reasons why this isn’t available as an argument. There are cases where a simple break in the loop is more efficient than making a copy with array_slice if you need the same data several places but in different slice sizes.

The patch also contains three tests to test the max attribute.

The patch is available here: smarty.foreach.max.patch. The patch is against the current SVN trunk of 2010-08-08.

Example:

{foreach item=x from=[0,1,2,3,4,5,6,7,8,9] max=5}{$x}{/foreach}

Output:

01234

I Made It Again (Again)!

It’s that time of the year again, where I spend a few saturdays out in the woods riding my bike together with a couple of thousand other interesting people. Today it was Grenserittet (“Cross Country Ride”, from Strömstad in Sweden to Halden in Norway) which I also did in 2009 and 2008.

This year’s course had to have an emergency fix after 30mms of rain on Thursday made parts of the track almost disappear. It was quite a minor change, as there was an alternative road almost parallel to the original one.

After getting up at 06:30 this morning and travelling to my parents home, my dad and me left for Strömstad and my 09:55 start. It was supposed to rain at the start, but in the late hours of last night the weather prognosis changed and promised sun with a few clouds. Spot on! As we rolled out from Strömstad light clouds covered the sky, making the temperature just right for a day out on gravel roads and forest trails!

I decided to bring along two gel packs (100g each) and one energy bar – this proved to be just about right for the trip (in addition to two water bottles, with refill at the service stations at each 20km). I also ate a piece of banana at each of the service stations and downed a cup of sports drink. The energy bar was consumed in two rounds between 30km and 50km.

The number bibs that each rider attaches to his or her bike and back had changed this year. Instead of having the contestant number as the largest feature, the organizers had decided to go with printing the first name of the rider instead. This worked great! It made the spectators cheer for you by name and made it a lot easier to keep track of people you were riding with! As Per Øyvind (.. if I remember correctly) said after 30kms, “hey, it’s Mats again! We’ve been riding together since the start!”. Getting a name attached to a person made it a lot easier to remember that you had seen these people before, if they had raced past you a couple of minutes ago, etc. Great stuff.

Anyways! Today’s result:

3:41:37

(2009: 4:45:57, 2008: 4:47:04)

A new personal best with over one hour, and just four minutes behind the cut off point for the “wow, you were fast!”-prices. Awesome. I had hopes of getting below four hours, but this was beyond my expectations.

The bike has been washed, the clothes are ready for the washing maching (and yes, I did carry one small Norwegian forest worth of mud home) and I’m feeling my muscles rebuild while relaxing on the couch writing this post.

Now we’ll have to see what I can do in this year’s Birkebeinerrittet and start planning for next year!

PowerDNS (pdns) and Supermasters

After spending an hour trying to find out why my slave didn’t attempt to sync with my supermaster server (my domains were set to MASTER, axfr worked from the slave, etc..), I came across the fact that even though your server is authorative and will handle requests, it will not pretend to be an actual MASTER server unless master=yes is set in the configuration file.

One reload and suddenly all the domains synced magically.

Do check that one if you’re not seeing any notify-requests or any entries in your logfiles at all when updating or requesting a sync (through pdns_control).

Trac and “ClearSilver not installed” message

After updating our debian installation on one of our servers we were left with a non-functioning Trac installation. An exception were thrown with a message about ClearSilver suddenly missing from our installation.

Solution: Debian packages ClearSilver ready for python:

apt-get install python-clearsilver

.. and party like it’s 2010!

Install rdiff-backup and librsync on RedHat Enterprise Linux 4

We’ve just installed rdiff-backup on some of our older RedHat Enterprise Linux 64-bit servers. We decided to install the .tar.gz-distributions and you can build your own rpms from these source packages (I won’t cover that here). There are a few pitfalls you’ll have to avoid.

First: librsync needs to be built with the 64-bit lib directory as the standard linkage, and needs to be compiled as a shared module.

To do this, provide configure with a few hints:

./configure LDFLAGS=-L/usr/lib64 --enable-shared --enable-lib64

Then make and make installldconfig to be sure that your LD cache has been updated (make install should do this, but .. just to be sure.)

The “.. can not be used when making a shared object; recompile with -fPIC” error for librsync will occur if you build it without –enable-shared, while “/usr/lib/libpopt.so: could not read symbols: File in wrong format” will occur if you build the library with the standard 32 bit libraries.

After this rdiff-backup compiled as it should:

python setup.py install

After rdiff-backup builds it python module and other small items, you might have to run ldconfig again (if you get “ImportError: librsync.so.1: cannot open shared object file: No such file or directory”, try this):

ldconfig

If you still get the above error, check that the directory where librsync was installed is present in either one of the files in /etc/ld.so.conf.d/ or in /etc/ld.so.conf itself. After adding the path to the library directory (which by default will be /usr/local/lib), run ldconfig again.

rdiff-backup should now (hopefully) work as expected.

Solr, Tomcat and HTTP/1.1 505 HTTP Version Not Supported

During today’s hacking aboot I came across the above error from our Solr query library. The error indicates that some part of Tomcat was unable to parse the “GET / HTTP/1.1” string – where it is unable to determine the “HTTP/1.1” part. A problem like this could be introduced by having a space in the query string (and it not being escaped properly), so that the request would have been for “GET /?a=b c HTTP/1.1”. After running through both the working and non-working query through ngrep and wireshark, this did however not seem to be the problem. My spaces were properly escaped using plus signs (GET /?a=b+c HTTP/1.1).

There does however seem to be a problem (at least with our version of Tomcat – 6.0.20) which results in the +-s being resolved before the request is handed off to the code that attempts to parse the header, so even though it is properly escaped using “+”, it still barfs.

The solution:

Use %20 to escape spaces instead of + signs; simply adding str_replace(” “, “%20”, ..); in our query layer solved the problem.

Making Friends With Emacs and UTF-8

After having a few issues with UTF-8 support in Emacs earlier (I .. well .. err .. use emacs as my .. mail editor.), I finally found a solution that works with both putty and gterm as my terminals.

The important settings I ended up using in my .emacs:

(prefer-coding-system       'utf-8)
(set-default-coding-systems 'utf-8)
(set-terminal-coding-system 'utf-8)
(set-keyboard-coding-system 'utf-8)

(setq x-select-request-type '(UTF8_STRING COMPOUND_TEXT TEXT STRING))

Archived for my own use at a later time.

Simple PHP Hack to Print an Integer in Binary Form

Today: Using my own blog as a simple pastebin to remember a helper function I wrote while debugging a good selection of binary operations on integers in PHP. This will simply output the provided value as bit values (0 / 1). Wrap it in <pre>-s if you’re running it in a web context.

$len allows you do change how many bits it will print (starting from lsb – least significant bit), $blockSize adjust the amount of bits before throwing in a space.

function printBinary($val, $len = 32, $blockSize = 8)
{
    print("\n");

    for($i = $len - 1; $i >= 0; $i--)
    {
        print(($val & 0x1<<$i) ? 1 : 0);

        if ($i%$blockSize == 0)
        {
            print (" ");
        }
    }

    print ("\n");
}