This web log is meant to be both technical and personal, generally detailing my exploits and adventures as well as providing notes and ideas.
- Bert JW Regeer (畢傑龍)

An engineers technical notebook (a.k.a new blog)

If you are still reading this blog (all 5 of you out there according to Google Webmaster*), then you may have noticed that most of the content has been technical in nature, at least, that is what most of it has been lately. The idea is to save notes about setups I have done so that I can refer back to them at a later time, for a long time I've been wanting to do that on a domain called usingnamespace.com, but I just never really like the name for just a blog, I have other ideas for it.

Recently I was going through domain registration again and I was looking at a list of domains that I wanted, but couldn't get because at the time I looked they were already taken. I got lucky, I finally got funcptr.net/com and immediately purchased the two.

So without further ado, I introduce my new technical notebook named funcptr which is where I will be writing longer length, well thought out (hopefully) articles. The whole idea is for me to start writing down the solutions to technical problems I have encountered in both software engineering as well as system administration and various other technical tasks. It won't be strictly limited to software but will also include hardware projects, and electronics.

I hope you go over and take a look. I am slowly but surely migrating technical content from this blog to funcptr such as my NAT with pf on an interface with multiple IP addresses article that describes a problem I ran into with PF automatically enabling round-robin causing issues because the secondary IP address was not on the same network as the default gateway and thus NAT didn't function as you'd expect. I am setting up 301 redirects so if you have linked to a post here before, don't worry, it will transparently send you to the correct location!

Let me know if you have any suggestions, you can find my contact information on my portfolio site: contact Bert.

* I think Google Webmaster shows me the amount of people that have my RSS feed added to Google Reader... not entirely sure how else they are getting that statistic.

Bug in Boost 1.4.7 when compiling with clang and c++0x support

This bug:

http://comments.gmane.org/gmane.comp.compilers.clang.devel/15926

still exists in 1.4.7.

Here is a small example:


$ cat test.cc
#include <boost/thread/thread.hpp>

int main()
{
    return 0;
}
$ clang++ test.cc
$ clang++ -std=c++0x test.cc
In file included from test.cc:1:
In file included from /usr/local/include/boost/thread/thread.hpp:17:
/usr/local/include/boost/thread/pthread/thread_data.hpp:36:17: error: call to deleted constructor of 
'boost::shared_ptr<boost::detail::tss_cleanup_function>'
                func(func_),value(value_)
                ^    ~~~~~
/usr/local/include/boost/smart_ptr/shared_ptr.hpp:164:25: 
               note: function has been explicitly marked deleted here
template<class T> class shared_ptr
                        ^
In file included from test.cc:1:
In file included from /usr/local/include/boost/thread/thread.hpp:22:
/usr/local/include/boost/thread/detail/thread.hpp:395:13: error: 
            call to deleted constructor of 'detail::thread_data_ptr' (aka 'shared_ptr<boost::detail::thread_data_base>')
            thread_data(thread_data_)
            ^           ~~~~~~~~~~~~
/usr/local/include/boost/smart_ptr/shared_ptr.hpp:464:36: 
            note: function has been explicitly marked deleted here
    template<class Y> friend class shared_ptr;
                                   ^
/usr/local/include/boost/smart_ptr/shared_ptr.hpp:301:9: error: functional-style cast from 
'const boost::shared_ptr<boost::detail::thread_data_base>' to 'this_type' (aka 'shared_ptr<boost::detail::thread_data_base>') 
uses deleted function
        this_type(r).swap(*this);
        ^~~~~~~~~~~
/usr/local/include/boost/thread/detail/thread.hpp:181:24: note: in instantiation of member function 
'boost::shared_ptr<boost::detail::thread_data_base>::operator=' requested here
            thread_info=other.thread_info;
                       ^
/usr/local/include/boost/smart_ptr/shared_ptr.hpp:464:36: note: candidate constructor (the implicit copy constructor) has 
            been explicitly deleted
    template<class Y> friend class shared_ptr;
                                   ^
/usr/local/include/boost/smart_ptr/shared_ptr.hpp:227:5: note: candidate constructor [with Y = boost::detail::thread_data_base]
    shared_ptr( shared_ptr<Y> const & r, typename boost::detail::sp_enable_if_convertible<Y,T>::type = boost::detail::sp_empty() )
    ^
3 errors generated.

Steve Jobs - 1955 - 2011

Yesterday the world lost a great visionary and leader. Whether you hated the guy or are an admirer you can't deny the fact that Steve Jobs had a great amount of influence in shaping the world of technology as it exists today.

He was always a step ahead of everyone else, knew what people wanted before they wanted it and was able to give it to them in beautiful product that people fell in love with; and still do fall in love with.

You may disagree with his business practices, you may dislike him, but he lived the American dream. He started from nothing in a garage and ended up as the CEO of one of the biggest and richest corporations of our time. We may not be able to follow in his footsteps, we are at least able to gain wisdom and knowledge from his experiences and missteps so that we too may one day be as great of a man as he was.

He did what he loved, he ran Apple until his last breath. I hope that one day I may be so lucky as to say that I too did what I loved until the day I died. May we all be so lucky as to die doing what we love surrounded by loved ones and friends.

At the end of Stanfords Commencement address in 2005, Steve Jobs quoted a magazine he used to read called the "Whole Earth Catalog", and they said on the back of their last issue "Stay Hungry. Stay Foolish".

It is one of the quotes that has stuck with me from that address, it is something that I truly believe in. It is something I attempt to follow every day. Every person interprets it differently, and that is the beauty of it. I find it apt then to end this article by thanking Steve Jobs for bringing my attention to these four words and how they have changed me.

Thanks for everything Steve. You made a huge dent in the universe, I can only hope to scratch the surface compared to what you accomplished. May you rest in peace.

Stay Hungry. Stay Foolish.

NAT with PF on an interface with multiple IP addresses

In my previous blog post Setting up jails with multiple IPs and providing it with internet access I suggested the following PF configuration:

ext_if="em0"
jail_if="bridge0"

# Set some options
set optimization aggressive
set block-policy drop
set skip on lo

# NAT on the external interface when coming from the jail interface
nat on $ext_if from $jail_if:network:0 to any -> ($ext_if)

# We just pass everything
pass quick all

To do nat from the jail interface (either bridge0 or lo1 is what I am using now). The syntax used, ($ext_if) says that PF should look at the interface to find out what the IP address is that it should translate to. This works wonderfully when the address is assigned by DHCP and there is only a single address. The thing is that on a new server I've got we've got two lagg interfaces (one internal, one external) and the external lagg interface has two IP addresses assigned to it. PF in FreeBSD 8.2 apparently does the wrong thing and causes all kinds of issues with FTP connections when an interface has two IP addresses, so instead of using ($ext_if) just put in the main IP address.

ext_if="lagg1"
int_if="lagg0"
jail_if="lo1"

set optimization aggressive
set block-policy drop
set skip on lo

nat on $int_if from $jail_if:network:0 to 10.0.0.0/8 -> ($int_if)
nat on $ext_if from $jail_if:network:0 to any -> 192.168.99.3

pass quick all

FreeBSD running within KVM: Serial Console

I am currently setting up a Linux laptop to contain some FreeBSD images, instead of going with the trusted VMWare or VirtualBox I decided I would use the built-in KVM virtualisation technology. Besides a few hiccups it is fast and so far has not failed.

I used virt-manager, a graphical tool, to set up everything, including creating the virtual machine, I didn't want to have to deal with XML configuration files and whatnot. After installing FreeBSD there are a few changes I made to get a virtual console working, this allows virsh console <domain> to function as expected.

First we add a new file to the root file system (which should be the first slice on the drive):

echo "-Dh" > /boot.config

See man 5 boot.config for more information. Basically -D says that FreeBSD should boot with a dual console configuration (built-in over VGA) and serial console, and -h says to force the serial console to on.

If you were to reboot now and use the virsh command:

virsh console FreeBSD

you would see the system go through the boot process and show output starting from when the boot block gains control, at this point however you still have no way to login to this new console since we never specified that we wanted any ttys on the serial console, for that we need to edit /etc/ttys.

We are looking for the ttyu0 entry, we want to make sure to change dialup to vt100, and off to on, so that it should look like this:

ttyu0 "/usr/libexec/getty std.9600" vt100 on secure

Now when we reboot once more we will get the usual login display that we have come to expect of console on FreeBSD, and we can login over the serial console. This way we don't have to open up the virtual machine manager to get a console, and can continue to do almost everything from a terminal window.

PostgreSQL setup for external connections

After compiling and installing PostgreSQL, we want to init the database, and want to start with some sane defaults.

Add the following to /etc/rc.conf
postgresql_initdb_flags="-D /usr/local/pgsql/data -W -A md5"
postgresql_enable="YES"

And then run:

mkdir -p /usr/local/pgsql/data
chown pgsql:pgsql /usr/local/pgsql/data
/usr/local/etc/rc.d/postgresql initdb

After this we need to modify a few files to get it to listen to TCP/IPv4 connections, first we start with postgresql.conf and add:

listen_addresses = '10.99.12.1'

Then in pg_hba.conf we add a new line:

host all all 10.99.12.0/24 md5

This allows anyone in the 10.99.12.0/24 range to connect to our PostgreSQL instance and to use the databases. This is exactly what we want to allow, now we start PostgreSQL using the rc script:

/usr/local/etc/rc.d/postgresql start

Setting up jails with multiple IPs and providing it with internet access

I have multiple VMs up and running and generally I have an internal to the VMs only network set up, in the current project I am working on I have three completely different networks set up.

1. DHCP assigned network that routes to the outside network on the host (192.168.0.1/24)
2. An internal to the VM's network interface (10.99.12.1/24)
3. A network that is tied to the hosts wireless network (setup to be an AP) (10.99.11.1/24)

So within my FreeBSD VM I have the following: em0, em1, em2 as "network cards". In my FreeBSD VM, I am creating two jails that are going to contain different pieces of server software. The jails need ip's in the following ranges, 10.99.12.1/24 (to connect to another VM), 10.99.11.1/24 (Wifi network) and then it needs to have an IP address that is considered "local" and we can NAT on, so in addition to the above networks we also needed to add another network. The easiest way to create new interface with IP address' is using a bridge. They can be assigned IP addresses, which is all we need.

At this point inside of a jail it kinda looks like this:

em0: flags=8843 metric 0 mtu 1500
options=209b
ether 52:54:00:6b:6a:49
media: Ethernet autoselect (1000baseT )
status: active
em1: flags=8843 metric 0 mtu 1500
options=209b
ether 52:54:00:2f:a5:55
inet 10.99.12.4 netmask 0xffffffff broadcast 10.99.12.4
media: Ethernet autoselect (1000baseT )
status: active
em2: flags=8843 metric 0 mtu 1500
options=209b
ether 52:54:00:bb:b6:43
inet 10.99.11.14 netmask 0xffffffff broadcast 10.99.11.14
media: Ethernet autoselect (1000baseT )
status: active
lo0: flags=8049 metric 0 mtu 16384
options=3
bridge0: flags=8843 metric 0 mtu 1500
ether da:de:63:c9:55:6c
inet 10.0.1.4 netmask 0xffffffff broadcast 10.0.1.4
id 00:00:00:00:00:00 priority 32768 hellotime 2 fwddelay 15
maxage 20 holdcnt 6 proto rstp maxaddr 100 timeout 1200
root id 00:00:00:00:00:00 priority 32768 ifcost 0 port 0

em0 doesn't have an address since that is our DHCP address, em1, em2 and bridge0 all have IP addresses, in the jail configuration the bridge0 IP address is listed first, and thus when something binds or sends it sends from that IP address. The thing is that at this point the jail does not have internet access.

Jail's inherit the routing table from their host environment (yes, you can compile in more routing tables ... but I don't want to modify stock), any traffic that goes to the outside is going to go out over the default route, thing is you'd expect that traffic to show up on bridge0 where the IP address exists, instead using tcpdump you see it show up on em0, which is where the default route is. I would have expected having to do NAT on the bridge, not just the external interface.

Here is the pf configuration.

ext_if="em0"
jail_if="bridge0"

set optimization aggressive
set block-policy drop
set skip on lo

nat on $ext_if from $jail_if:network:0 to any -> ($ext_if)

pass quick all

And we've got internet within our jail. I am looking forward to setting this all up when the new VIMAGE stuff lands in 9.0-RELEASE so that I can have virtual network cards that are not tied to a physical network card!

StackOverflow and other StackExchange websites

StackOverflow and friends are question and answer sites, StackOverflow specifically was created to edge out Experts-Exchange (not linked on purpose) in Google rankings for programmer questions, specifically because Experts-Exchange likes to make their answer sites are confusion as possible, with many different ads and hiding parts of questions until you cough up a membership fee.

Overall StackOverflow has done an outstanding job in doing what their core mission statement was when they started it, and recently has begun branching out into various other territories using the brand name StackExchange. I am very happy that these sites exist, and that they provide much better results for the same questions.

Today I was reading a blog post created by Joel Spolsky, titled "The Wikipedia of Long Tail Programming Questions", in it he brings up some core features that StackOverflow supports, such as everyone editing community questions at 100 rep, and editing any questions or answers at 2000 rep. Rep in this case can be compared to karma on Reddit or Slashdot. Rep is earned by answering questions accurately and having other users "upvote" your posts. Rep may also be lost, but that is outside the scope of this discussion.

Some of the suggestions that Joel makes are as follows:

  1. Don’t answer questions that have already been answered elsewhere.
  2. If you’re going to close a user’s question as a duplicate, it has to be a real duplicate.
  3. It is OK to edit a question to make it more general.
  4. Help us build a great library of canonical answers.

I agree with all of them except the first. Now, if you quickly take an interlude from this blog and go check out my StackOverflow profile page you'd see that sometime in March (only for two days actually) I suddenly became very active on StackOverflow answering a lot of questions and helping many people, and gaining reputation rapidly. It was shortly thereafter that I slowed down, mainly because the rate at which I was going was only possible because I was on school break, and because I started working on some new projects. Since then every so often when I stumble across a question I will attempt to answer it.

In attempting to adhere to number one as outlined above I tend to do some searches to see if maybe the question has already been answered elsewhere, and also to adhere to number two it takes me at least a minute or two per question.

Then scenario one is as follows: During that time others are doing the same, or maybe already know it is a duplicate and close the question (hopefully linking to another question that it duplicates), those are two minutes I just spent doing some research to provide a better answer that is then not necessarily wasted, as generally I will learn a thing or two, but at the same time I wish the submitter had searched for himself.

Scenario two is as follows: However if the topic is not closed, and is a fairly simple question during the time that I am doing my duplicate search others will have posted a one or two sentence reply that will somewhat help the author of the question. Those will then get upvoted rapidly as people consider those easy questions answered. At that point I will type out a full thoughtful reply that will get ignored and will stick around at 0 upvotes as people don't tend to come back into questions after it has already been answered a couple of times.

This has made me apprehensive of answering questions as they come up on StackOverflow as generally those that I feel qualified to answer will get glossed over and there is really no incentive for me to continue doing so unless I go for the long tail (hope that within the next coming years people find the reply through Google and upvote it then). I feel that the quality of responses on StackOverflow has gone down mostly because you can get one or two upvotes before scenario one plays out and the thread is closed. This means that on duplicates it becomes who can quickly answer and post (hence the one or two sentences) before the mods get around to it. While I really enjoy responding and that should be enough to entice me to respond more, I feel like I am being alienated by lesser quality posts that don't provide nearly the quality that I have come to expect of StackOverflow.

The answers are starting to look more and more like those on Experts-Exchange, the barrier to entry is very low on StackOverflow, mostly on purpose but I also feel that it detracts from the quality the website is required to have to stay useful in the foreseeable future.

One way I can see this being "fixed" is Slashdot style (for people who want to "moderate"). On Slashdot before you get mod points you have to do a couple of different tests to see if you are in-line with the majority, you get to see comments and context and you have to decide what you'd moderate the comment. On StackOverflow a newer user before being given the ability to upvote/downvote answers would then have to first do a small test to see if they are able to decide what is a good comment and what is a bad comment. Then when they start posting other users will judge their replies, and if they are short and don't contain a very good answer they are limited from posting replies in threads that are newer than X minutes. This would give the power users that have earned it the time to do the proper research, write out a good reply, or close the thread as a duplicate without people being able to farm for karma by posting two sentence replies that are completely useless.

Is this feasible to implement? I don't know. Would it provide a higher barrier for entry, absolutely. I think that is a good thing. In closing, I would like to state that I absolutely love the various StackExchange websites, and the ease at which knowledge is now spread, but I have been becoming more and more distanced from the website since the quality of answers went down tremendously, and I am much less likely to spend time answering a question when it is already saturated with one or two sentence answers thus having my quality answer sit at the bottom of the list at 0 upvote points.

Apache mod_fastcgi and PHP with PHP-FPM

Recently I did a server migration from an older server to a newer server and in an attempt to help stability I wanted to see if there was a better way to do PHP FastCGI. In my research I came across running PHP using the fastCGI server that spins up a PHP on a TCP/IP port and allows the web server to connect to it. However this doesn't help with spawning or keeping track of instances or error recovery.

This is where PHP FPM comes in handy. It does all of the hard work for us, it spawns the processes and has a bunch of really awesome features that help run PHP as various different users as required with different PHP ini files and memory limits. After setting up PHP FPM I had to set up Apache.

mod_fcgid doesn't allow for remote connections, and as such I was unable to use it for what I needed it for. mod_fastcgi provides the FastCGIExternalServer configuration key, which is exactly what I needed.

"The FastCgiExternalServer directive defines filename as an external FastCGI application. If filename does not begin with a slash (/) then it is assumed to be relative to the ServerRoot. The filename does not have to exist in the local filesystem. URIs that Apache resolves to this filename will be handled by this external FastCGI application."

What this documentation does not state is that the path up to the last part of it has to exist in the local file system. So in my first couple of attempts I pointed it at /usr/local/www/fastcgi/php5.fcgi without having an actual fastcgi directory located in /usr/local/www/. There are a lot of examples that require creating a new FastCGIExternalServer for each and every VirtualHost this is unacceptable to me, the reason they require it is because they set the FastCGIExternalServer path to the folder where they are going to be serving files from.

In the end I found that after creating the /usr/local/www/fastcgi directory (and reading the mod_fastcgi source code) that all it does is make Apache believe a file exists in a certain directory, much like Alias, except Alias allows full paths to be aliased, not so here.

The AddType and Action add custom types and what the action should be when such a type is encountered. In this case the action is to redirect the request to /php5.fcgi which will handle the rest of the request. This does not require another FastCGI section per VirtualHost as each PHP request will just get shuttled to the php handler.

Do take note that I have specifically disallowed Apache to serve anything from the /usr/local/www/fastcgi/ folder, except for a single file php5.fcgi which is our FastCGIExternalServer file.

<IfModule mod_fastcgi.c>
	Alias /php5.fcgi /usr/local/www/fastcgi/php5.fcgi
	FastCGIExternalServer /usr/local/www/fastcgi/php5.fcgi -flush -host 127.0.0.1:9000
	AddType application/x-httpd-fastphp5 .php
	Action application/x-httpd-fastphp5 /php5.fcgi

	<Directory "/usr/local/www/fastcgi/">
		Order deny,allow
		Deny from all
		<Files "php5.fcgi">
			Order allow,deny
			Allow from all
		</Files>
	</Directory>
</IfModule>

Note that even-though in my last post concerning mod_fastcgi I as moving away from it, I am now doing the opposite, instead of moving from mod_fastcgi to mod_fcgid I'm back to mod_fastcgi, only because mod_fcgid doesn't offer the same functionality.

So far this has provided far more stability, along with PHP-FPM doing all of the process management I can now use a single PHP instance that is running on a single port for the various web servers I am testing. At the moment I have both Lighttpd and Apache using the same PHP-FPM running instance. It is faster, less memory is wasted and PHP-FPM is much better at process management than mod_fastcgi or mod_fcgid.

CSS 3 needs to be adopted now

This is a simple error that I ran into the past couple of days. I was not aware that the width of an item was calculated as follows:

left border width + left margin + left padding + width + right padding + right margin + right border width.

Well, that off course does not work well when you want to float two items next to each other with the following:

#cont1 { float: left; width: 75%; border: 1px solid black; }
#cont2 { float: right; width: 25%; border: 0; }

These will not float next to each other since #cont1 is bigger than 75% meaning that the other one being 25% gets pushed beneath it.

CSS3 fixes this with the box-sizing: border-box;, this property will make it so that all of the padding, margins and borders are calculated within the allocated width, that means a width of 75% means the entire element will be 75% and everything else will be calculated within it.

You can use it now with the following snippet:

box-sizing: border-box;

-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;

However IE won't render the boxes correctly, nor will older versions of Safari, Chrome, or FireFox. Until CSS3 is ratified and starts being accepted by all major browsers without the browsers specific keywords it is not really that useful. In my case I have reverted to the alternate version of using a wrapper element that wraps around the element, and doesn't have margin, padding and a border.

#cont1wrap { float: left; width: 75%; border: 0; margin: 0; padding: 0; }
#cont1 { border: 1px solid black; }
#cont2wrap { float: right; width: 25%; border: 0; margin: 0; padding: 0; }
#cont2 { padding: 10px; border: 0; }

It does mean that you need twice the amount of tags in HTML, one with an id of #cont1wrap and another inside of that with an id of #cont1, same with #cont2. Not an ideal solution but until CSS3 is made the new king of layout it is the only choice we have that is mostly compliant with most browsers.

Syndicate content