<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Electricmonk.nl weblog &#187; tech</title>
	<atom:link href="http://www.electricmonk.nl/log/category/tech/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.electricmonk.nl/log</link>
	<description>Ferry Boender&#039;s ramblings</description>
	<lastBuildDate>Mon, 16 Jan 2012 15:23:04 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Stop Pingback/Trackback Spam on WordPress</title>
		<link>http://www.electricmonk.nl/log/2011/09/07/stop-pingbacktrackback-spam-on-wordpress/</link>
		<comments>http://www.electricmonk.nl/log/2011/09/07/stop-pingbacktrackback-spam-on-wordpress/#comments</comments>
		<pubDate>Wed, 07 Sep 2011 11:51:35 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[security]]></category>
		<category><![CDATA[sysadmin]]></category>
		<category><![CDATA[tech]]></category>

		<guid isPermaLink="false">http://www.electricmonk.nl/log/?p=4707</guid>
		<description><![CDATA[I guess the spammers finally found my blog, cause I&#039;ve been getting a lot of pignback/trackback spam. I tried some anti-spam plugins, but none really worked, so I disabled pingbacks altogether. Here&#039;s how: First, log into wordpress as an admin. Go to Settings &#8594; Discussion, and uncheck the Allow link notifications from other blogs (pingbacks [...]]]></description>
			<content:encoded><![CDATA[<p>I guess the spammers finally found my blog, cause I&#039;ve been getting a lot of pignback/trackback spam. I tried some anti-spam plugins, but none really worked, so I disabled pingbacks altogether. Here&#039;s how:</p>
<p>First, log into wordpress as an admin. Go to <tt>Settings &rarr; Discussion</tt>, and uncheck the <tt>Allow link notifications from other blogs (pingbacks and trackbacks.)</tt> box.</p>
<p>That&#039;s not all though, cause that just works for new articles. Old ones will still allow ping/trackbacks. As far as I could tell, WordPress doesn&#039;t have a feature to disable those for older posts, so we&#039;ll have to fiddle around in the database directly.</p>
<p>Connect to your MySQL server using the WordPress username and password. If you no longer remember those, you can find them in the <tt>wp-config.php</tt> file.</p>
<pre>$ <b>mysql -u USERNAME -p -h localhost</b>
Password: <b>PASSWORD</b>
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 1684228
Server version: 5.0.51a-24+lenny5 (Debian)

Type 'help;' or '\h' for help. Type '\c' to clear the buffer.

mysql&gt;</pre>
<p>At the MySQL prompt, we must now switch to our WordPress database. Again, if you don&#039;t remember the name, you can find it in the <tt>wp-config.php</tt> file. In my case, it is <tt>em_wordpress</tt></p>
<pre>mysql&gt; <b>USE em_wordpress;</b>
Database changed</pre>
<p>Finally, we update all posts and disable ping backs on them:</p>
<pre>mysql&gt; <b>UPDATE wp_posts SET ping_status = 'closed';</b>
Query OK, 1084 rows affected (0.10 sec)
Rows matched: 1084  Changed: 1084  Warnings: 0
</pre>
<p>There we go. No more ping- and trackback spam on old posts.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.electricmonk.nl/log/2011/09/07/stop-pingbacktrackback-spam-on-wordpress/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>This is why I don&#039;t use Apple products or DRM media</title>
		<link>http://www.electricmonk.nl/log/2011/05/11/this-is-why-i-dont-use-apple-products-or-drm-media/</link>
		<comments>http://www.electricmonk.nl/log/2011/05/11/this-is-why-i-dont-use-apple-products-or-drm-media/#comments</comments>
		<pubDate>Wed, 11 May 2011 10:30:46 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[freedom and privacy]]></category>
		<category><![CDATA[link]]></category>
		<category><![CDATA[tech]]></category>

		<guid isPermaLink="false">http://www.electricmonk.nl/log/?p=4613</guid>
		<description><![CDATA[This company is going out of business because they put all their eggs in a very delicate and quite frankly evil basket: BeamItDown Software and the iFlow Reader will cease operations as of May 31, 2011. We absolutely do not want to do this, but Apple has made it completely impossible for anyone but Apple [...]]]></description>
			<content:encoded><![CDATA[<p>This company <a href="https://www.iflowreader.com/Closing.aspx">is going out of business</a> because they put all their eggs in a very delicate and quite frankly evil basket:</p>
<blockquote><p>
BeamItDown Software and the iFlow Reader will cease operations as of May 31, 2011.  We absolutely do not want to do this, but Apple has made it completely impossible for anyone but Apple to make a profit selling contemporary ebooks on any iOS device.
</p></blockquote>
<p>If you&#039;re a company, and you do this:</p>
<blockquote><p>
We bet everything on Apple and iOS and then Apple killed us by changing the rules in the middle of the game.
</p></blockquote>
<p>you need to have your head examined :-) This is not the first time this has happened, and it will most certainly not be the last time. <b>Apple will do anything it can to make a buck over other company&#039;s back!</b></p>
<p>Not just the company is being royally screwed over by Apple:</p>
<blockquote><p>
Many of you have purchased books and would like to keep them.   You may still be able to read them using iFlow Reader although we cannot guarantee that it will work beyond May 31, 2011 [...] your computer which will let you access them with Adobe Digital Editions or any other ebook application that is compatible with Adobe DRM protected epubs.
</p></blockquote>
<p>So iFlowReader&#039;s have probably also lost all their ebooks because they had DRM on them. DRM (Digital Rights Management) is a technology which restricts media to a certain application or device; opening it in third-party applications is usually impossible. </p>
<p>And that&#039;s why I have never and will never buy an Apple product, or use any media that is DRM protected.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.electricmonk.nl/log/2011/05/11/this-is-why-i-dont-use-apple-products-or-drm-media/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Lessons on development of 64-bit C/C++ applications</title>
		<link>http://www.electricmonk.nl/log/2011/04/14/lessons-on-development-of-64-bit-cc-applications/</link>
		<comments>http://www.electricmonk.nl/log/2011/04/14/lessons-on-development-of-64-bit-cc-applications/#comments</comments>
		<pubDate>Thu, 14 Apr 2011 11:15:56 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[link]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[tech]]></category>

		<guid isPermaLink="false">http://www.electricmonk.nl/log/?p=4587</guid>
		<description><![CDATA[Lessons on development of 64-bit C/C++ applications: The course is devoted to creation of 64-bit applications in C/C++ language and is intended for the Windows developers who use Visual Studio 2005/2008/2010 environment. Developers working with other 64-bit operating systems will learn much interesting as well. The course will consider all the steps of creating a [...]]]></description>
			<content:encoded><![CDATA[<p><a href="">Lessons on development of 64-bit C/C++ applications</a>: </p>
<blockquote><p>
The course is devoted to creation of 64-bit applications in C/C++ language and is intended for the Windows developers who use Visual Studio 2005/2008/2010 environment. Developers working with other 64-bit operating systems will learn much interesting as well. The course will consider all the steps of creating a new safe 64-bit application or migrating the existing 32-bit code to a 64-bit system.
</p></blockquote>
]]></content:encoded>
			<wfw:commentRss>http://www.electricmonk.nl/log/2011/04/14/lessons-on-development-of-64-bit-cc-applications/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Google Calendar Holidays</title>
		<link>http://www.electricmonk.nl/log/2011/04/13/google-calendar-holidays/</link>
		<comments>http://www.electricmonk.nl/log/2011/04/13/google-calendar-holidays/#comments</comments>
		<pubDate>Wed, 13 Apr 2011 09:34:52 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[tech]]></category>

		<guid isPermaLink="false">http://www.electricmonk.nl/log/?p=4576</guid>
		<description><![CDATA[Just found this out: You can easily add all the holidays for your country (or particular religion) to your Google Calendar by going to: Other Calendars &#8594; Add &#8594; Browse Interesting Calendars. There you can subcribe to calendars containing your country&#039;s holidays.]]></description>
			<content:encoded><![CDATA[<p>Just found this out: You can easily add all the holidays for your country (or particular religion) to your Google Calendar by going to: <tt>Other Calendars &rarr; Add &rarr; Browse Interesting Calendars</tt>. There you can subcribe to calendars containing your country&#039;s holidays.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.electricmonk.nl/log/2011/04/13/google-calendar-holidays/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>BoxBackup on Debian/Ubuntu</title>
		<link>http://www.electricmonk.nl/log/2011/02/01/boxbackup-on-debianubuntu/</link>
		<comments>http://www.electricmonk.nl/log/2011/02/01/boxbackup-on-debianubuntu/#comments</comments>
		<pubDate>Tue, 01 Feb 2011 15:36:10 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[linux]]></category>
		<category><![CDATA[sysadmin]]></category>
		<category><![CDATA[tech]]></category>

		<guid isPermaLink="false">http://www.electricmonk.nl/log/?p=4555</guid>
		<description><![CDATA[(The lastest version of this article is always available in stand-alone HTML format and in PDF format. The original AsciiDoc source is also available. Please link to the HTML version, not this Blog post!) 1. Introduction BoxBackup is an online remote backup tool for Unix systems (BSDs, Linux, MacOSX). It is robust, secure, low on [...]]]></description>
			<content:encoded><![CDATA[<p>(The lastest version of this article is always available in <a href="http://www.electricmonk.nl/Writings/HomePage?action=download&#038;upname=boxbackup_debian.html">stand-alone HTML format</a> and in <a href="http://www.electricmonk.nl/Writings/HomePage?action=download&#038;upname=boxbackup_debian.pdf">PDF format</a>. The original <a href="http://www.electricmonk.nl/Writings/HomePage?action=download&#038;upname=boxbackup_debian.txt">AsciiDoc source</a> is also available. <b>Please link to the HTML version, not this Blog post!</b>)</p>
<h2 id="_introduction">1. Introduction</h2>
<div class="sectionbody">
<div class="paragraph">
<p>BoxBackup is an online remote backup tool for Unix systems (BSDs, Linux, MacOSX). It is robust, secure, low on resources and can perform both in continues backup mode and snapshotting. In continues backup mode changes will be pushed to the server soon after they happen; in snapshot mode mode BoxBackup behaves more like traditional backup programs and creates snapshots every fixed amount of time.</p>
</div>
<div class="paragraph">
<p>This article will describe how to set up a BoxBackup server and client on Debian and Ubuntu machines. Much of this article can also be used on other Unix-like systems, however it will not discuss how to compile BoxBackup.</p>
</div>
<p><span id="more-4555"></span></p>
<h3 id="_assumptions">1.1. Assumptions</h3>
<div style="clear:left"></div>
<div class="paragraph">
<p>This article assumes the following:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>
The server (where backups will be stored) is called <tt>server</tt>. Its FQDN will be <tt>server.example.com</tt>.
</p>
</li>
<li>
<p>
The client (which will be backed up) is called <tt>client</tt>. Its FQDN will be <tt>client.example.com</tt>.
</p>
</li>
<li>
<p>
Backups will be stored in a directory <tt>/storage/backup</tt> on <tt>server</tt>.</p>
</li>
</ul>
</div>
</div>
<h2 id="_for_the_lazy">2. For the lazy</h2>
<div class="sectionbody">
<div class="paragraph">
<p>This chapter is for the lazy. It quickly describes how to setup BoxBackup, but provides no in-depth information. Please note that commands are prefixed by a prompt that indicates on which machine and in which directory to run the command.</p>
</div>
<div class="paragraph">
<p>The server will allow the client 100Gb of storage with a hard limit of 120Gb. The client will have account ID <tt>00000001</tt> (more on account IDs later). BoxBackup&#039;s user-land RAID-like configuration will not be used. We will have to move some files between the <tt>client</tt> and the <tt>server</tt>. For this we use the <tt>scp</tt> program and the user account named <tt>user</tt> on both machines.</p>
</div>
<h3 id="_server_configuration">2.1. Server configuration</h3>
<div style="clear:left"></div>
<div class="paragraph">
<p>Install the server:</p>
</div>
<div class="literalblock">
<div class="content">
<pre><tt>server:/root# aptitude install boxbackup-server</tt></pre>
</div>
</div>
<div class="paragraph">
<p>Delete Debian&#039;s generated configuration (We&#039;ll recreate it ourselves):</p>
</div>
<div class="literalblock">
<div class="content">
<pre><tt>server:/root# rm -rf /etc/boxbackup/</tt></pre>
</div>
</div>
<div class="paragraph">
<p>Find out filesystem block size:</p>
</div>
<div class="literalblock">
<div class="content">
<pre><tt>server:/root# /sbin/dumpe2fs -h /dev/sdb1 | grep 'Block size'
dumpe2fs 1.41.4 (27-Jan-2009)
Block size:               4096</tt></pre>
</div>
</div>
<div class="paragraph">
<p>Create RAID-like configuration file:</p>
</div>
<div class="literalblock">
<div class="content">
<pre><tt>server:/root# raidfile-config  /etc/boxbackup/ 4096 /storage/</tt></pre>
</div>
</div>
<div class="paragraph">
<p>Create backup storage directory:</p>
</div>
<div class="literalblock">
<div class="content">
<pre><tt>server:/root# mkdir /storage/backup/
server:/root# chown bbstored:bbstored /storage/backup
server:/root# chmod 750 /storage/backup</tt></pre>
</div>
</div>
<div class="paragraph">
<p>Create BoxBackup server configuration and certificates:</p>
</div>
<div class="literalblock">
<div class="content">
<pre><tt>server:/root# bbstored-config /etc/boxbackup/ server.example.com bbstored
server:/root# bbstored-certs ca init
server:/root# bbstored-certs ca sign-server /etc/boxbackup/bbstored/server.example.com-csr.pem
server:/root# cp ca/servers/server.example.com-cert.pem /etc/boxbackup/bbstored
server:/root# cp ca/roots/clientCA.pem /etc/boxbackup/bbstored
server:/root# chown -R bbstored:bbstored /etc/boxbackup/
server:/root# chmod 700 /etc/boxbackup/</tt></pre>
</div>
</div>
<div class="paragraph">
<p>Start the server:</p>
</div>
<div class="literalblock">
<div class="content">
<pre><tt>server:/root# /etc/init.d/boxbackup-server start
server:/root# grep "Box Backup" /var/log/syslog
Jan 31 21:45:13 server Box Backup (bbstored)[30775]: NOTICE: Starting daemon, version 0.11rc2, config: /etc/boxbackup/bbstored.conf</tt></pre>
</div>
</div>
<div class="admonitionblock">
<table>
<tr>
<td class="icon">
<div class="title">Important</div>
</td>
<td class="content">Keep the <tt>/root/ca</tt> directory around. It is required to sign new BoxBackup clients&#039; certificate files.</td>
</tr>
</table>
</div>
<h3 id="_client_configuration">2.2. Client configuration</h3>
<div style="clear:left"></div>
<div class="paragraph">
<p>Create an account on the server:</p>
</div>
<div class="literalblock">
<div class="content">
<pre><tt>server:/root# bbstoreaccounts create 00000001 0 100g 120g</tt></pre>
</div>
</div>
<div class="paragraph">
<p>Install the client software:</p>
</div>
<div class="literalblock">
<div class="content">
<pre><tt>client:/root# aptitude install boxbackup-client
client:/root# rm /etc/boxbackup/bbackupd.conf
client:/root# rm /etc/boxbackup/bbackupd/*</tt></pre>
</div>
</div>
<div class="paragraph">
<p>Create client configuration and certificates:</p>
</div>
<div class="literalblock">
<div class="content">
<pre><tt>client:/root# bbackupd-config /etc/boxbackup/ lazy 00000001 server.example.com /var/run /var/lib/svn/
client:/root# scp /etc/boxbackup/bbackupd/00000001-FileEncKeys.raw user@server.example.com:
client:/root# scp /etc/boxbackup/bbackupd/00000001-csr.pem user@server.example.com:</tt></pre>
</div>
</div>
<div class="paragraph">
<p>Sign certificates on the server:</p>
</div>
<div class="literalblock">
<div class="content">
<pre><tt>server:/root# bbstored-certs ca sign /home/user/00000001-csr.pem
server:/root# scp ca/clients/00000001-cert.pem user@client.example.com:
server:/root# scp ca/roots/serverCA.pem user@client.example.com:
server:/root# /etc/init.d/boxbackup-server restart</tt></pre>
</div>
</div>
<div class="paragraph">
<p>Install signed certificates on the client and start client:</p>
</div>
<div class="literalblock">
<div class="content">
<pre><tt>client:/root# mv /home/user/00000001-cert.pem /etc/boxbackup/bbackupd/
client:/root# mv /home/user/serverCA.pem /etc/boxbackup/bbackupd/
client:/root# /etc/init.d/boxbackup-client start
client:/root# grep "Box Backup" /var/log/syslog
Jan 31 21:55:13 client Box Backup (bbackupd)[20975]: NOTICE: Starting daemon, version 0.11rc2, config: /etc/boxbackup/bbackupd.conf
Jan 31 21:55:13 client Box Backup (bbackupd)[20975]: NOTICE: Beginning scan of local files</tt></pre>
</div>
</div>
<div class="admonitionblock">
<table>
<tr>
<td class="icon">
<div class="title">Important</div>
</td>
<td class="content">Keep the <tt>0000001-FileEncKeys.raw</tt> file around. It is required to restore backups.</td>
</tr>
</table>
</div>
<div class="paragraph">
<p>If anything fails, please take a look at the rest of this document. It explains in more detail how to setup BoxBackup and may provide clues as to the problems you are encountering.</p>
</div>
</div>
<h2 id="_setting_up_the_server_bbstored">3. Setting up the server (bbstored)</h2>
<div class="sectionbody">
<h3 id="_installation">3.1. Installation</h3>
<div style="clear:left"></div>
<div class="paragraph">
<p>The first thing is setting up the server. This is where the backups will be stored. It will run the <tt>bbstored</tt> program, which is a server daemon that clients can connect to in order to upload data.</p>
</div>
<div class="paragraph">
<p>The server will be designated as <tt>server</tt> in the commands given in this chapter. Each command is prefixed with a shell-prompt to indicate on which machine (<tt>client</tt> or <tt>server</tt>) the command should be entered. The server&#039;s Fully Qualified Domain Name will be <tt>server.example.com</tt>. The client&#039;s will be <tt>client.example.com</tt>. We will have to move some files (certificates) around between the server and the client in order to sign them. For this we will use a user account with username <tt>user</tt>. It is assumed the root user on both systems can use secure copy (<tt>scp</tt>) to move files from one system to the other under this user account.</p>
</div>
<div class="paragraph">
<p>Let&#039;s get started by installing the BoxBackup server. We use Debian, but it should also work under Ubuntu. It is unknown to me which different versions of BoxBackup are compatible with each other, so I assume you&#039;ll be using the same version on both the client and the server. If you&#039;re not using Debian or Ubuntu, please check your distribution&#039;s package list to see if a pre-compiled version of BoxBackup is available. If not, you will have to compile it yourself. This is beyond the scope of this article, so check the BoxBackup documentation for instructions.</p>
</div>
<div class="literalblock">
<div class="content">
<pre><tt>server:/root# aptitude install boxbackup-server</tt></pre>
</div>
</div>
<div class="paragraph">
<p>Debian/Ubuntu will install the BoxBackup server and some configuration tools. It will also create a user called <tt>bbstored</tt>. The BoxBackup server (<tt>bbstored</tt>) will run as this user.</p>
</div>
<div class="paragraph">
<p>Debian also might generate a configuration file and certificates for you. We will <strong>delete</strong> those because they confuse the process of installing and configuring BoxBackup (as what Debian does for you and what you need to do manually is terribly documented and it stores things in the wrong place).</p>
</div>
<div class="literalblock">
<div class="content">
<pre><tt>server:/root# rm -rf /etc/boxbackup/</tt></pre>
</div>
</div>
<h3 id="_creating_a_store">3.2. Creating a store</h3>
<div style="clear:left"></div>
<div class="paragraph">
<p>BoxBackup server stores backups in a <tt>store</tt>. We will configure this store at <tt>/storage/backup</tt>. This directory will contain a store for each client that backs up using the server. E.g. the backups for the client with account ID <tt>00000001</tt> (more on account IDs later on) will be stored in <tt>/storage/backup/00000001/</tt>.</p>
</div>
<div class="paragraph">
<p>BoxBackup provides a RAID-like setup where backups are written to multiple locations; usually different physical disks. This RAID-like setup <strong>has nothing to do with actual RAID</strong>, so don&#039;t get confused by that. This article will <strong>not</strong> be using the RAID-like facilities of BoxBackup.</p>
</div>
<div class="paragraph">
<p>Before we can create our store, we must first determine the block size of our file system . This can be done using the dumpe2fs tool. Provide the proper device name to the tool:</p>
</div>
<div class="literalblock">
<div class="content">
<pre><tt>server:/root# mount | grep storage
/dev/sdb1 on /storage type ext3 (rw)</tt></pre>
</div>
</div>
<div class="paragraph">
<p>In this case the device is <tt>/dev/sdb1</tt>. Let&#039;s get the block size:</p>
</div>
<div class="literalblock">
<div class="content">
<pre><tt>server:/root# /sbin/dumpe2fs -h /dev/sdb1 | grep 'Block size'
dumpe2fs 1.41.4 (27-Jan-2009)
Block size:               4096</tt></pre>
</div>
</div>
<div class="paragraph">
<p>As we can see, our block size is 4096. We can now configure a Boxbackup store.</p>
</div>
<div class="literalblock">
<div class="content">
<pre><tt>server:/root# raidfile-config  /etc/boxbackup/ 4096 /storage/
WARNING: userland RAID is disabled.
Config file written.</tt></pre>
</div>
</div>
<div class="paragraph">
<p>If the BoxBackup user (<tt>bbstored</tt>) has write permissions to the <tt>/storage/</tt> directory, you can skip the following steps and continue with the <tt>bbstored-config</tt> step.</p>
</div>
<div class="paragraph">
<p>Now we create a directory for the backups and set the proper permissions:</p>
</div>
<div class="literalblock">
<div class="content">
<pre><tt>server:/root# mkdir /storage/backup/
server:/root# chown bbstored:bbstored /storage/backup
server:/root# chmod 750 /storage/backup</tt></pre>
</div>
</div>
<h3 id="_server_configuration_file_certificates">3.3. Server configuration file / certificates</h3>
<div style="clear:left"></div>
<div class="paragraph">
<p>Time to create the bbstored configuration. We do this with the <tt>bbstored-config</tt> tool. It takes three parameters:</p>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">
<tt>config_dir</tt></p>
</dt>
<dd>
<p>
    The <strong>configuration location</strong>. In our case, <tt>/etc/boxbackup/</tt>.
</p>
</dd>
<dt class="hdlist1">
<tt>server_name</tt>
</dt>
<dd>
<p>    The <strong>FQDN of the server</strong>. We use <tt>server.example.com</tt>.
</p>
</dd>
<dt class="hdlist1">
<tt>username</tt>
</dt>
<dd>
<p>
    The <strong>user which bbstored will run as</strong>. Debian created the <tt>bbstored</tt> user for us, so we&#039;ll use that. It&#039;s the same as the daemon name, which is customary.</p>
</dd>
</dl>
</div>
<div class="paragraph">
<p>Run the command:</p>
</div>
<div class="literalblock">
<div class="content">
<pre><tt>server:/root# bbstored-config /etc/boxbackup/ server.example.com  bbstored

Checking permissions on /storage//backup
Checking permissions on /storage//backup
Checking permissions on /storage//backup

Setup bbstored config utility

Configuration:
   Writing configuration file: /etc/boxbackup//bbstored.conf
   Writing empty accounts file: /etc/boxbackup//bbstored/accounts.txt
   Server hostname: server.example.com
   RaidFile config: /etc/boxbackup//raidfile.conf

Creating blank accounts file
Generating private key...
Generating RSA private key, 2048 bit long modulus
................................................................
............................................................................+++
.............................................................+++
e is 65537 (0x10001)
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:
State or Province Name (full name) [Some-State]:
Locality Name (eg, city) []:
Organization Name (eg, company) [Internet Widgits Pty Ltd]:
Organizational Unit Name (eg, section) []:
Common Name (eg, YOUR name) []:
Email Address []:

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:An optional company name []:

Writing configuration file /etc/boxbackup//bbstored.conf
===================================================================

bbstored basic configuration complete.

What you need to do now...
1) Sign /etc/boxbackup//bbstored/server.example.com-csr.pem
   using the bbstored-certs utility.
2) Install the server certificate and root CA certificate as
      /etc/boxbackup//bbstored/server.example.com-cert.pem
      /etc/boxbackup//bbstored/clientCA.pem
3) You may wish to read the configuration file
      /etc/boxbackup//bbstored.conf
   and adjust as appropraite.
4) Create accounts with bbstoreaccounts
5) Start the backup store daemon with the command
      /usr/local/bin/bbstored /etc/boxbackup//bbstored.conf
   in /etc/rc.local, or your local equivalent.
===================================================================</tt></pre>
</div>
</div>
<div class="paragraph">
<p>This will generate a configuration file at <tt>/etc/boxbackup/bbstored.conf</tt> and generate a server certificate sign request file at <tt>/etc/boxbackup/bbstored/server.example.com-csr.pem</tt>.</p>
</div>
<div class="paragraph">
<p>The next step is to create and sign the server certificate. For this we need to generate a root certificate first. We use the <tt>bbstored-certs</tt> tool to do this:</p>
</div>
<div class="literalblock">
<div class="content">
<pre><tt>server:/root# bbstored-certs ca init

Generating RSA private key, 2048 bit long modulus
...................................................................
.................................................................+++
................................................+++
e is 65537 (0x10001)
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:
State or Province Name (full name) [Some-State]:
Locality Name (eg, city) []:
Organization Name (eg, company) [Internet Widgits Pty Ltd]:
Organizational Unit Name (eg, section) []:
Common Name (eg, YOUR name) []:
Email Address []:

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:An optional company name []:

Signature ok
subject=/CN=Backup system client root
Getting Private key
Generating RSA private key, 2048 bit long modulus
.........................+++
............................................+++
e is 65537 (0x10001)
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:
State or Province Name (full name) [Some-State]:
Locality Name (eg, city) []:
Organization Name (eg, company) [Internet Widgits Pty Ltd]:
Organizational Unit Name (eg, section) []:
Common Name (eg, YOUR name) []:
Email Address []:

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:An optional company name []:

Signature ok
subject=/CN=Backup system server root
Getting Private key</tt></pre>
</div>
</div>
<div class="paragraph">
<p>This generates a <tt>co</tt> directory at our current location. This directory contains a bunch of certificates, including the root certificate. We need this root certificate to sign the server and client certificates.</p>
</div>
<div class="admonitionblock">
<table>
<tr>
<td class="icon">
<div class="title">Important</div>
</td>
<td class="content">We need to keep this <tt>ca</tt> directory around as it is required to sign client certificates! Store it in a <strong>secure</strong> location!</td>
</tr>
</table>
</div>
<div class="paragraph">
<p>Okay, let&#039;s sign the server certificate using our root certificate:</p>
</div>
<div class="literalblock">
<div class="content">
<pre><tt>server:/root# bbstored-certs ca sign-server /etc/boxbackup/bbstored/server.example.com-csr.pem

This certificate is for backup server

server.example.com

Signing the wrong certificate compromises the security of your backup system.

Would you like to sign this certificate? (type 'yes' to confirm)
yes
Signature ok
subject=/CN=server.example.com
Getting CA Private Key

Certificate signed

Install the files

  ca/servers/server.example.com-cert.pem
  ca/roots/clientCA.pem

on the server.</tt></pre>
</div>
</div>
<div class="paragraph">
<p>We do as the output says and copy the signed server certificates to the configuration directory:</p>
</div>
<div class="literalblock">
<div class="content">
<pre><tt>server:/root# cp ca/servers/server.electricmonk.nl-cert.pem /etc/boxbackup/bbstored
server:/root# cp ca/roots/clientCA.pem /etc/boxbackup/bbstored
server:/root# chown -R bbstored:bbstored /etc/boxbackup/
server:/root# chmod 700 /etc/boxbackup/</tt></pre>
</div>
</div>
<h3 id="_starting_the_server">3.4. Starting the server</h3>
<div style="clear:left"></div>
<div class="paragraph">
<p>That concludes the configuration part of the server. We will have to create client accounts, but that will be covered in the chapter on client configuration. Let&#039;s try out the server:</p>
</div>
<div class="literalblock">
<div class="content">
<pre><tt>server:/root# /etc/init.d/boxbackup-server start
Starting boxbackup-server: NOTICE: Starting daemon, version 0.11rc2, config: /etc/boxbackup/bbstored.conf
bbstored.</tt></pre>
</div>
</div>
<div class="paragraph">
<p>It seems to start. We can check <tt>/var/log/syslog</tt> to see if it really did:</p>
</div>
<div class="literalblock">
<div class="content">
<pre><tt>server:/root# grep "Box Backup" /var/log/syslog
Jan 31 21:53:14 server Box Backup (bbstored)[15884]: NOTICE: Starting daemon, version 0.11rc2, config: /etc/boxbackup/bbstored.conf</tt></pre>
</div>
</div>
<div class="paragraph">
<p>If that&#039;s all the output, everything is now okay. Final verifications to see if the server is really running can be made using <tt>ps</tt> and <tt>netstat</tt>:</p>
</div>
<div class="literalblock">
<div class="content">
<pre><tt>server:/root# ps axf | grep bbstored
 15884 ?        S      0:00 /usr/sbin/bbstored /etc/boxbackup/bbstored.conf
 15885 ?        S      0:14  \_ /usr/sbin/bbstored /etc/boxbackup/bbstored.conf</tt></pre>
</div>
</div>
<div class="paragraph">
<p>It&#039;s running.</p>
</div>
<div class="literalblock">
<div class="content">
<pre><tt>server:/root# netstat -pant | grep bbstored
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
tcp        0      0 82.171.91.37:2201       0.0.0.0:*               LISTEN      15884/bbstored</tt></pre>
</div>
</div>
<div class="paragraph">
<p>It&#039;s listening for incoming connections on IP <tt>82.171.91.37</tt>, at TCP port <tt>2201</tt>. Time to set up the client!</p>
</div>
</div>
<h2 id="_setting_up_a_client_bbackupd">4. Setting up a client (bbackupd)</h2>
<div class="sectionbody">
<div class="paragraph">
<p>In this chapter we will set up a client. The client will run the <tt>bbackupd</tt> program, which is a daemon that scans the files you want to backup and sends them to the server if it encounters new or modified files. It does this efficiently: if there are no changes, nothing is sent to the server. Otherwise it only sends the parts of the files that have changed; not the whole file is transmitted unless it is not yet on the server.</p>
</div>
<div class="paragraph">
<p>In this chapter we designate the client (the machine you wish to backup) as <tt>client</tt>. The backup server which will store our backups is designated <tt>server</tt>. Each command is prefixed with a shell-prompt to indicate on which machine (<tt>client</tt> or <tt>server</tt>) the command should be entered. The server&#039;s Fully Qualified Domain Name will be <tt>server.example.com</tt>. The client&#039;s will be <tt>client.example.com</tt>. We will have to move some files (certificates) around between the server and the client in order to sign them. For this we will use a user account with username <tt>user</tt>. It is assumed the root user on both systems can use secure copy (<tt>scp</tt>) to move files from one system to the other under this user account.</p>
</div>
<h3 id="_creating_an_account">4.1. Creating an account</h3>
<div style="clear:left"></div>
<div class="paragraph">
<p>Before we start installing things on the client machine, we should first create a BoxBackup store account on the server. We use the <tt>bbstoreaccounts</tt> tool for this. It takes five parameters:</p>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">
<tt>command</tt>
</dt>
<dd>
<p>
    The <tt>command</tt> determines <strong>which action</strong> we want to perform on the account. In this case we wish to create an account, so we will use the <tt>create</tt> command.</p>
</dd>
<dt class="hdlist1">
<tt>account_id</tt>
</dt>
<dd>
<p>
    The Account ID is a a <strong>hexdecimal account number</strong>. We will use 00000001. A second client would be 00000002, a tenth client would be 0000000A, etc.
</p>
</dd>
<dt class="hdlist1">
<tt>raid_disk</tt></p>
</dt>
<dd>
<p>
    We must specify <strong>a RAID (BoxBackup&#039;s userland RAID-like concept) disk</strong> on which to store the backups for this client. In our case, we didn&#039;t setup multiple RAID disks, so we have only one: <strong>0</strong>.
</p>
</dd>
<dt class="hdlist1">
<tt>soft_limit</tt></p>
</dt>
<dd>
<p>
    The <strong>Soft Limit</strong> determines when the client will voluntarily stop sending file changes to the server. Presumably (though I&#039;m not sure) it will not start transferring new changes when the soft limit has been exceeded on the server. However, if a single change exceeds the soft limit after the client has started uploading it, it will continue uploading until it hits the hard_limit. We&#039;ll set the soft limit to 100Gb.
</p>
</dd>
<dt class="hdlist1">
<tt>hard_limit</tt>
</dt>
<dd>
<p>
    The <strong>hard limit</strong>. This should NEVER be bigger than the free space you have. We set it too 120Gb.
</p>
</dd>
</dl>
</div>
<div class="paragraph">
<p>Let&#039;s create the account:</p>
</div>
<div class="literalblock">
<div class="content">
<pre><tt>server:/root# bbstoreaccounts create 00000001 0 100g 120g
NOTICE: Account 0x00000001 created.</tt></pre>
</div>
</div>
<h3 id="_installation_2">4.2. Installation</h3>
<div style="clear:left"></div>
<div class="paragraph">
<p>Time to move on to the actual client. Note that some of these commands are run on the client and some are run on the server. <strong>Double check the prompt to see on which machine the command needs to be run!</strong>.</p>
</div>
<div class="literalblock">
<div class="content">
<pre><tt>client:/root# aptitude install boxbackup-client</tt></pre>
</div>
</div>
<div class="paragraph">
<p>Debian will configure some things for us, but that&#039;s just confusing (and didn&#039;t work for me), so we <strong>remove Debian&#039;s configuration and keys</strong>:</p>
</div>
<div class="literalblock">
<div class="content">
<pre><tt>client:/root# rm /etc/boxbackup/bbackupd.conf
client:/root# rm /etc/boxbackup/bbackupd/*</tt></pre>
</div>
</div>
<h3 id="_client_configuration_certificates">4.3. Client configuration / certificates</h3>
<div style="clear:left"></div>
<div class="paragraph">
<p>Now we generate the configuration ourselves. We supply the <tt>lazy</tt> mode parameter which will continuously scan our system for changes. This sounds resource intensive, but it actually spreads the load better over time. We also supply the account ID (which we generated earlier on), the server name (FQDN), a run directory where BoxBackup can store temporary information and a path we want backed up. (We add more later on). We will be backing up <tt>/var/lib/svn</tt>.</p>
</div>
<div class="literalblock">
<div class="content">
<pre><tt>client:/root# bbackupd-config /etc/boxbackup/ lazy 00000001 server.electricmonk.nl /var/run /var/lib/svn/

Setup bbackupd config utility.

Configuration:
   Writing configuration file: /etc/boxbackup//bbackupd.conf
   Account: 00000001
   Server hostname: server.electricmonk.nl
   Directories to back up:
      /var/lib/svn/

Note: If other file systems are mounted inside these directories, then
they will NOT be backed up. You will have to create separate locations for
any mounted filesystems inside your backup locations.

Generating private key...
Generating RSA private key, 2048 bit long modulus
...................................+++
.................+++
e is 65537 (0x10001)
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:
State or Province Name (full name) [Some-State]:
Locality Name (eg, city) []:
Organization Name (eg, company) [Internet Widgits Pty Ltd]:
Organizational Unit Name (eg, section) []:
Common Name (eg, YOUR name) []:
Email Address []:

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:An optional company name []:

Generating keys for file backup
Writing notify script /etc/boxbackup//bbackupd/NotifySysadmin.sh
Writing configuration file /etc/boxbackup//bbackupd.conf

===================================================================

bbackupd basic configuration complete

What you need to do now...

1) Make a backup of /etc/boxbackup//bbackupd/00000001-FileEncKeys.raw
   This should be a secure offsite backup.
   Without it, you cannot restore backups. Everything else can
   be replaced. But this cannot.
   KEEP IT IN A SAFE PLACE, OTHERWISE YOUR BACKUPS ARE USELESS.
2) Send /etc/boxbackup//bbackupd/00000001-csr.pem
   to the administrator of the backup server, and ask for it to
   be signed.
3) The administrator will send you two files. Install them as
      /etc/boxbackup//bbackupd/00000001-cert.pem
      /etc/boxbackup//bbackupd/serverCA.pem
   after checking their authenticity.
4) You may wish to read the configuration file
      /etc/boxbackup//bbackupd.conf
   and adjust as appropriate. There are some
   notes in it on excluding files you do not
   wish to be backed up.
5) Review the script
      /etc/boxbackup//bbackupd/NotifySysadmin.sh
   and check that it will email the right person when the store
   becomes full. This is important -- when the store is full, no
   more files will be backed up. You want to know about this.
6) Start the backup daemon with the command
      /usr/local/bin/bbackupd /etc/boxbackup//bbackupd.conf
   in /etc/rc.local, or your local equivalent.
   Note that bbackupd must run as root.
===================================================================

Remember to make a secure, offsite backup of your backup keys,
as described in step 1 above. If you do not, you have no backups.</tt></pre>
</div>
</div>
<h3 id="_signing_certificates">4.4. Signing certificates</h3>
<div style="clear:left"></div>
<div class="paragraph">
<p>The previous step has generated a file encryption key (<tt>/etc/boxbackup/bbackupd/00000001-FileEncKeys.raw</tt>) and a client SSL certificate sign request at <tt>/etc/boxbackup/bbackupd/00000001-csr.pem</tt>. These must be sent to the server so they can be signed and added to the server&#039;s known SSL certificates. Here we use <tt>scp</tt> to copy the files to the server, but you can use any other means to get them there.</p>
</div>
<div class="literalblock">
<div class="content">
<pre><tt>client:/root# scp /etc/boxbackup/bbackupd/00000001-FileEncKeys.raw user@server.electricmonk.nl:
    00000001-FileEncKeys.raw           100% 1024     1.0KB/s   00:00
client:/root# scp /etc/boxbackup/bbackupd/00000001-csr.pem user@server.electricmonk.nl:
    00000001-csr.pem                   100%  899     0.9KB/s   00:00</tt></pre>
</div>
</div>
<div class="paragraph">
<p>Now we must sign the certificate on the server. <strong>Note</strong> that the following commands are ran <strong>on the server, not the client</strong>. Also note that your current working directory must be the one in which we previously ran the <tt>bbstored-certs ca init</tt> command. (the <tt>ca</tt> directory must be present).</p>
</div>
<div class="literalblock">
<div class="content">
<pre><tt>server:/root# bbstored-certs ca sign /home/user/00000001-csr.pem

This certificate is for backup account

00000001

Ensure this matches the account number you are expecting. The filename is

/home/user/00000001-csr.pem

which should include this account number, and additionally, you should check
that you received it from the right person.

Signing the wrong certificate compromises the security of your backup system

Would you like to sign this certificate? (type 'yes' to confirm)
yes
Signature ok
subject=/CN=BACKUP-00000001
Getting CA Private Key

Certificate signed.

Send the files

  ca/clients/00000001-cert.pem
  ca/roots/serverCA.pem

to the client.</tt></pre>
</div>
</div>
<div class="paragraph">
<p>We send the signed certificate and the server&#039;s certificate to the client:</p>
</div>
<div class="literalblock">
<div class="content">
<pre><tt>server:/root# scp ca/clients/00000001-cert.pem user@client:
    00000001-cert.pem          100%  997     1.0KB/s   00:00
server:/root# scp ca/roots/serverCA.pem user@client:
    serverCA.pem               100% 1021     1.0KB/s   00:00</tt></pre>
</div>
</div>
<div class="paragraph">
<p>And <strong>on the client we install them</strong> in the correct directory:</p>
</div>
<div class="literalblock">
<div class="content">
<pre><tt>client:/root# mv /home/user/00000001-cert.pem /etc/boxbackup/bbackupd/
client:/root# mv /home/user/serverCA.pem /etc/boxbackup/bbackupd/</tt></pre>
</div>
</div>
<h3 id="_starting_the_client">4.5. Starting the client</h3>
<div style="clear:left"></div>
<div class="paragraph">
<p>Now we can start the client:</p>
</div>
<div class="literalblock">
<div class="content">
<pre><tt>client:# /etc/init.d/boxbackup-client start</tt></pre>
</div>
</div>
<div class="paragraph">
<p>In the syslog on the <strong>client</strong> we should see:</p>
</div>
<div class="literalblock">
<div class="content">
<pre><tt>Jan 31 21:55:13 client Box Backup (bbackupd)[20975]: NOTICE: Starting daemon, version 0.11rc2, config: /etc/boxbackup/bbackupd.conf
Jan 31 21:55:13 client Box Backup (bbackupd)[20975]: NOTICE: Beginning scan of local files
Jan 31 21:55:14 client Box Backup (bbackupd)[20975]: NOTICE: About to notify administrator about event backup-start, running script '/etc/boxbackup//bbackupd/NotifySysadmin.sh backup-start'
Jan 31 21:59:45 client Box Backup (bbackupd)[20975]: NOTICE: Finished scan of local files
Jan 31 21:59:46 client Box Backup (bbackupd)[20975]: NOTICE: About to notify administrator about event backup-finish, running script '/etc/boxbackup//bbackupd/NotifySysadmin.sh backup-finish'
Jan 31 21:59:46 client Box Backup (bbackupd)[20975]: NOTICE: File statistics: total file size uploaded 36012577, bytes already on server 0, encoded size 7161527</tt></pre>
</div>
</div>
<div class="paragraph">
<p>In the syslog on the <strong>server</strong> we should see:</p>
</div>
<div class="literalblock">
<div class="content">
<pre><tt>Jan 31 21:55:13 server Box Backup (bbstored)[15884]: WARNING: Message from child process 16488: Incoming connection from 213.19.146.55 port 52963
Jan 31 21:55:13 server Box Backup (bbstored)[16488]: NOTICE: Login from Client ID 0x00000001 Read/Write
Jan 31 21:58:46 server Box Backup (bbstored)[19666]: NOTICE: Session finished for Client ID 0x00000001</tt></pre>
</div>
</div>
<h3 id="_verifying_backups">4.6. Verifying backups</h3>
<div style="clear:left"></div>
<div class="paragraph">
<p>After the initial backup is done, we can verify that files have been transfered using the <tt>bbackupquery</tt> tool. This tool should be run on the client:</p>
</div>
<div class="literalblock">
<div class="content">
<pre><tt>client:/root# bbackupquery
NOTICE: Box Backup Query Tool v0.11rc2, (c) Ben Summers and contributors 2003-2008
Login complete.

Type "help" for a list of commands.

query &gt; ls
00000002 -d---- var-lib-svn-
00001798 -d---- etc-
query &gt; cd var-lib-svn-
query &gt; ls
00000003 f----- .htpasswd
00000004 f----- .svnaccess
query &gt; exit</tt></pre>
</div>
</div>
<div class="paragraph">
<p>Not all files may have been transferred initially. For instance, Box Backup doesn&#039;t transfer files if they&#039;ve been modified recently. It will try again later. If a file is continuously modified, it will eventually (after a max age) upload the file anyway.</p>
</div>
<h3 id="_adding_additional_paths">4.7. Adding additional paths</h3>
<div style="clear:left"></div>
<div class="paragraph">
<p>If you want to add additional paths which need to backed up, edit the <tt>/etc/boxbackup/bbackupd.conf</tt> file and search for the <tt>BackupLocations</tt> directive. You can add paths here. For example, to backup <tt>/var/lib/svn</tt> and <tt>/etc</tt>:</p>
</div>
<div class="literalblock">
<div class="content">
<pre><tt>BackupLocations
{
        var-lib-svn-
        {
                Path = /var/lib/svn/
        }
        etc-
        {
                Path = /etc/
        }
}</tt></pre>
</div>
</div>
<div class="paragraph">
<p>Afterwards simply restart <tt>bbackupd</tt>:</p>
</div>
<div class="literalblock">
<div class="content">
<pre><tt>client:/root# /etc/init.d/bbackupd restart</tt></pre>
</div>
</div>
</div>
<h2 id="_troubleshooting">5. Troubleshooting</h2>
<div class="sectionbody">
<div class="paragraph">
<p>The primary methods of troubleshooting are experimentation and the <tt>/var/log/syslog</tt> file.</p>
</div>
<h3 id="_server_connectivity">5.1. Server connectivity</h3>
<div style="clear:left"></div>
<div class="paragraph">
<p>We can use various tools to test if the server is running and can be reached. To check if the server is running, use <tt>ps</tt>:</p>
</div>
<div class="literalblock">
<div class="content">
<pre><tt>server:/root# ps axf | grep bbstored
 15884 ?        S      0:00 /usr/sbin/bbstored /etc/boxbackup/bbstored.conf
 15885 ?        S      0:14  \_ /usr/sbin/bbstored /etc/boxbackup/bbstored.conf</tt></pre>
</div>
</div>
<div class="paragraph">
<p>If it&#039;s not running, check <tt>/var/log/syslog</tt> for any errors.</p>
</div>
<div class="paragraph">
<p>To see if the server is listening for incoming connections from the clients:</p>
</div>
<div class="literalblock">
<div class="content">
<pre><tt>server:/root# netstat -pant | grep bbstored
tcp        0      0 82.171.91.37:2201       0.0.0.0:*               LISTEN      15884/bbstored</tt></pre>
</div>
</div>
<div class="paragraph">
<p>This shows the server is listening on IP <tt>82.171.91.37</tt> on TCP port <tt>2201</tt>. The daemon should listen on an which can be reached by the clients. If it listens on IP <tt>0.0.0.0</tt>, it will accept connections from any machine.</p>
</div>
<div class="paragraph">
<p>To test if we can reach the server from the client, we can use a port scanner such as <tt>nmap</tt>:</p>
</div>
<div class="literalblock">
<div class="content">
<pre><tt>client:/root#  nmap -p 2201 server.example.com
Starting Nmap 4.62 ( http://nmap.org ) at 2011-02-01 14:21 CET
Interesting ports on server.example.com (82.171.91.37):
PORT     STATE SERVICE
2201/tcp open  ats</tt></pre>
</div>
</div>
<div class="paragraph">
<p>If <tt>nmap</tt> lists the port as <tt>open</tt>, the client can reach the server.</p>
</div>
<h3 id="_syslog_errors_and_warning">5.2. Syslog errors and warning</h3>
<div style="clear:left"></div>
<div class="paragraph">
<p>Both the server and the client will log errors to <tt>/var/log/syslog</tt>. Here are a couple of errors you might run into:</p>
</div>
<h4 id="_expired_certificate">5.2.1. Expired certificate</h4>
<div class="paragraph">
<p>If you spot this in the syslog:</p>
</div>
<div class="literalblock">
<div class="content">
<pre><tt>Jan 31 17:32:45 server Box Backup (bbstored)[30775]: WARNING: Message from child process 31604: Incoming connection from 213.19.146.55 port 59381
Jan 31 17:32:45 server Box Backup (bbstored)[31604]: ERROR: SSL error during Accept: error:14094415:SSL routines:SSL3_READ_BYTES:sslv3 alert certificate expired
Jan 31 17:32:45 server Box Backup (bbstored)[31604]: WARNING: Exception thrown: ConnectionException(Conn_TLSHandshakeFailed) at SocketStreamTLS.cpp(245)
Jan 31 17:32:45 server Box Backup (bbstored)[31604]: ERROR: Error in child process, terminating connection: exception Connection TLSHandshakeFailed(7/30)</tt></pre>
</div>
</div>
<div class="paragraph">
<p>One of the certificates has expired. You may be dealing with a bug in older Debian/Ubuntu versions. More information is available here:</p>
</div>
<div class="literalblock">
<div class="content">
<pre><tt>http://www.mail-archive.com/debian-bugs-rc@lists.debian.org/msg242206.html</tt></pre>
</div>
</div>
<h4 id="_certificates_missing">5.2.2. Certificates missing</h4>
<div class="paragraph">
<p>THe following error is reported when certificates can&#039;t be loaded. In this case, because they couldn&#039;t be found.</p>
</div>
<div class="literalblock">
<div class="content">
<pre><tt>Jan 31 18:38:32 server Box Backup (bbstored)[12102]: ERROR: SSL error during Load certificates: error:02001002:system library:fopen:No such file or directory
Jan 31 18:38:32 server Box Backup (bbstored)[12102]: ERROR: SSL error during Load certificates: error:20074002:BIO routines:FILE_CTRL:system lib
Jan 31 18:38:32 server Box Backup (bbstored)[12102]: ERROR: SSL error during Load certificates: error:140DC002:SSL routines:SSL_CTX_use_certificate_chain_file:system lib
Jan 31 18:38:32 server Box Backup (bbstored)[12102]: WARNING: Exception thrown: ServerException(TLSLoadCertificatesFailed) at TLSContext.cpp(118)
Jan 31 18:38:32 server Box Backup (bbstored)[12102]: FATAL: Terminating due to exception Server TLSLoadCertificatesFailed (3/25)</tt></pre>
</div>
</div>
<div class="paragraph">
<p>Double check the instructions to make sure you&#039;ve moved certificates to the correct place.</p>
</div>
<h4 id="_permission_denied">5.2.3. Permission denied</h4>
<div class="paragraph">
<p>Various permission denied problems may arise:</p>
</div>
<div class="literalblock">
<div class="content">
<pre><tt>Feb  1 10:47:21 server Box Backup[29518]: ERROR: FileHandleGuard: failed to open file '/etc/boxbackup/bbstored.conf': Permission denied
Feb  1 10:47:21 server Box Backup[29518]: WARNING: Exception thrown: CommonException(OSFileOpenError) at ../../lib/common/Guards.h(81)</tt></pre>
</div>
</div>
<div class="paragraph">
<p>Check the permission and ownership on the server to make sure that the files in <tt>/etc/boxbackup</tt> belong to the user <tt>bbstored</tt>. Also check that the <tt>bbstored</tt> user can write to <tt>/storage/backup</tt>.</p>
</div>
<h4 id="_certificate_verification_failure">5.2.4. Certificate verification failure</h4>
<div class="paragraph">
<p>On the <strong>client</strong>, you may see the following error:</p>
</div>
<div class="literalblock">
<div class="content">
<pre><tt>Jan 31 17:32:46 client Box Backup (bbackupd)[7339]: ERROR: SSL error during Connect: error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed
Jan 31 17:32:46 client Box Backup (bbackupd)[7339]: WARNING: Exception thrown: ConnectionException(Conn_TLSHandshakeFailed) at SocketStreamTLS.cpp(250)
Jan 31 17:32:46 client Box Backup (bbackupd)[7339]: NOTICE: About to notify administrator about event backup-error, running script '/etc/boxbackup//bbackupd/NotifySysadmin.sh backup-error'
Jan 31 17:32:46 client Box Backup (bbackupd)[7339]: ERROR: Exception caught (Connection TLSHandshakeFailed 7/30), reset state and waiting to retry...
Jan 31 17:32:56 client Box Backup (bbackupd)[7339]: NOTICE: File statistics: total file size uploaded 0, bytes already on server 0, encoded size 0
Jan 31 17:33:13 client Box Backup (bbackupd)[7339]: NOTICE: Terminating daemon</tt></pre>
</div>
</div>
<div class="paragraph">
<p>This might be related to the Debian bug mentioned in the <em>Expired certificate</em> troubleshooting chapter. Check the server&#039;s <tt>/var/log/syslog</tt> for more details.</p>
</div>
<h4 id="_network_connectivity_problem">5.2.5. Network connectivity problem</h4>
<div class="paragraph">
<p>In case of the following:</p>
</div>
<div class="literalblock">
<div class="content">
<pre><tt>Jan 31 18:34:28 client Box Backup (bbackupd)[27060]: ERROR: Failed to connect to socket (type 1, name server.example.com, port 2201): Connection refused (111)
Jan 31 18:34:28 client Box Backup (bbackupd)[27060]: WARNING: Exception thrown: ConnectionException(Conn_SocketConnectError) at SocketStream.cpp(223)
Jan 31 18:34:28 client Box Backup (bbackupd)[27060]: NOTICE: About to notify administrator about event backup-error, running script '/etc/boxbackup/bbackupd/NotifySysadmin.sh backup-error'
Jan 31 18:34:29 client Box Backup (bbackupd)[27060]: ERROR: Exception caught (Connection SocketConnectError (Probably a network issue between client and server, bad hostname, or server not running.) 7/15), reset state and waiting to retry...
Jan 31 18:34:39 client Box Backup (bbackupd)[27060]: NOTICE: File statistics: total file size uploaded 0, bytes already on server 0, encoded size 0</tt></pre>
</div>
</div>
<div class="paragraph">
<p>Perform the checks given in <em>Server connectivity</em> part of the troubleshooting chapter.</p>
</div>
<h3 id="_missing_files">5.3. Missing files</h3>
<div style="clear:left"></div>
<div class="paragraph">
<p>Sometimes, after a backup, files may not be present on the remote server. Not all files may have been transferred initially. For instance, Box Backup doesn&#039;t transfer files if they&#039;ve been modified recently. It will try again later. If a file is continuously modified, it will eventually (after a max age) upload the file anyway.</p>
</div>
<h4 id="_other_problems">5.3.1. Other problems</h4>
<div class="paragraph">
<p>The BoxBackup homepage lists some other possible problems:</p>
</div>
<div class="literalblock">
<div class="content">
<pre><tt>http://boxbackup.org/trouble.html</tt></pre>
</div>
</div>
</div>
<h2 id="_about_this_document">6. About this document</h2>
<div class="sectionbody">
<h3 id="_copyright_license">6.1. Copyright / License</h3>
<div style="clear:left"></div>
<div class="paragraph">
<p>Copyright (c) 2008, Ferry Boender</p>
</div>
<div class="paragraph">
<p>This document may be freely distributed, in part or as a whole, on any medium, without the prior authorization of the author, provided that this Copyright notice remains intact, and there will be no obstruction as to the further distribution of this document. You may not ask a fee for the contents of this document, though a fee to compensate for the distribution of this document is permitted.</p>
</div>
<div class="paragraph">
<p>Modifications to this document are permitted, provided that the modified document is distributed under the same license as the original document and no copyright notices are removed from this document. All contents written by an author stays copyrighted by that author.</p>
</div>
<div class="paragraph">
<p>Failure to comply to one or all of the terms of this license automatically revokes your rights granted by this license</p>
</div>
<div class="paragraph">
<p>All brand and product names mentioned in this document are trademarks or registered trademarks of their respective holders.</p>
</div>
<h3 id="_feedback">6.2. Feedback</h3>
<div style="clear:left"></div>
<div class="paragraph">
<p>All feedback on this document is welcome at &lt;ferry DOT boender AT gmail DOT com&gt;.</p>
</div>
</div>
</div>
<div id="footnotes">
<hr /></div>
<div id="footer">
<div id="footer-text">
Version 1.0<br />
Last updated 2011-02-01 16:08:40 CEST
</div>
</div>
]]></content:encoded>
			<wfw:commentRss>http://www.electricmonk.nl/log/2011/02/01/boxbackup-on-debianubuntu/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>MacOS X on VirtualBox</title>
		<link>http://www.electricmonk.nl/log/2010/11/05/macos-x-on-virtualbox/</link>
		<comments>http://www.electricmonk.nl/log/2010/11/05/macos-x-on-virtualbox/#comments</comments>
		<pubDate>Fri, 05 Nov 2010 18:12:40 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[sysadmin]]></category>
		<category><![CDATA[tech]]></category>

		<guid isPermaLink="false">http://www.electricmonk.nl/log/?p=4508</guid>
		<description><![CDATA[I&#039;ve been trying to get MacOS X working on VirtualBox for a while now, and it never worked due to some ACPI problems. The latest versions of VirtualBox have added MacOS X Server as a guest possibility, and it also seems to have fixed some problems with running the normal Mac OS X. I got [...]]]></description>
			<content:encoded><![CDATA[<p>I&#039;ve been trying to get MacOS X working on VirtualBox for a while now, and it never worked due to some ACPI problems. The latest versions of VirtualBox have added MacOS X Server as a guest possibility, and it also seems to have fixed some problems with running the normal Mac OS X. </p>
<p>I got this working on the following hardware/software. If your hardware/software differs, your mileage may vary:</p>
<ul>
<li>CPU: Intel Pentium(R) Dual-Core  CPU E5300  @ 2.60GHz</li>
<li>Videocard:  Intel Corporation 4 Series Chipset Integrated Graphics Controller (rev 03) (Some Intel integrated piece of crap).</li>
<li>Ubuntu GNU/Linux v10.04</li>
<li>VirtualBox <b>v3.2</b> (important)</li>
</ul>
<p>Here are the instructions:</p>
<ul>
<li>First, you&#039;ll need to get get MacOS X. I used a pre-made illegal VMWare image I got from <a href="http://thepiratebay.org/torrent/4707572/MacOS_10.5.5_VMWARE_image">here</a>. (I&#039;m sure Apple&#039;s legal team will be on my neck soon, but fuck it). </li>
<li>Second, you need the latest VirtualBox. I&#039;m using the Non-OSI v3.2.10. You can get it from the <a href="http://www.virtualbox.org/wiki/Downloads">VirtualBox download page</a>.</li>
<li>Now, add a new VirtualBox guest and select &#039;<tt>MacOS X</tt>&#039; as the Operating System and either &#039;Mac OS X Server&#039; or &#039;Mac OS X Server (64 bits)&#039; as the version. I&#039;m not quite sure it works on 32 bits host processors/operating systems, but it does work on 64 bits hosts.</li>
<li>You need at least 1024 Mb of memory. Less will NOT work</li>
<li>For the Virtual Hard Disk add the Mac OS X vmdk image as a harddisk</li>
</ul>
<p>Okay, now you&#039;ll have to through the settings and match them to the following settings:</p>
<p><a href="http://www.electricmonk.nl/log/wp-content/uploads/2010/11/mox1.png"><img src="http://www.electricmonk.nl/log/wp-content/uploads/2010/11/mox1.png" alt="" title="mox1" width="650" height="481" class="alignnone size-full wp-image-4509" /></a></p>
<p><a href="http://www.electricmonk.nl/log/wp-content/uploads/2010/11/mox2.png"><img src="http://www.electricmonk.nl/log/wp-content/uploads/2010/11/mox2.png" alt="" title="mox2" width="650" height="481" class="alignnone size-full wp-image-4511" /></a></p>
<p><a href="http://www.electricmonk.nl/log/wp-content/uploads/2010/11/mox3.png"><img src="http://www.electricmonk.nl/log/wp-content/uploads/2010/11/mox3.png" alt="" title="mox3" width="650" height="481" class="alignnone size-full wp-image-4512" /></a></p>
<p><a href="http://www.electricmonk.nl/log/wp-content/uploads/2010/11/mox4.png"><img src="http://www.electricmonk.nl/log/wp-content/uploads/2010/11/mox4.png" alt="" title="mox4" width="650" height="481" class="alignnone size-full wp-image-4513" /></a></p>
<p><a href="http://www.electricmonk.nl/log/wp-content/uploads/2010/11/mox51.png"><img src="http://www.electricmonk.nl/log/wp-content/uploads/2010/11/mox51.png" alt="" title="mox5" width="650" height="481" class="alignnone size-full wp-image-4519" /></a></p>
<p><a href="http://www.electricmonk.nl/log/wp-content/uploads/2010/11/mox6.png"><img src="http://www.electricmonk.nl/log/wp-content/uploads/2010/11/mox6.png" alt="" title="mox6" width="650" height="481" class="alignnone size-full wp-image-4515" /></a></p>
<p><a href="http://www.electricmonk.nl/log/wp-content/uploads/2010/11/mox7.png"><img src="http://www.electricmonk.nl/log/wp-content/uploads/2010/11/mox7.png" alt="" title="mox7" width="650" height="481" class="alignnone size-full wp-image-4516" /></a></p>
<p><a href="http://www.electricmonk.nl/log/wp-content/uploads/2010/11/mox9.png"><img src="http://www.electricmonk.nl/log/wp-content/uploads/2010/11/mox9.png" alt="" title="mox9" width="650" height="481" class="alignnone size-full wp-image-4517" /></a></p>
<p>The rest of the settings do not seem to matter, at least for getting MacOS X to boot succefully. To recap:</p>
<ul>
<li><tt>Enable IO APIC</tt> must be ON.</li>
<li><tt>Enable absolute pointing device</tt> must be ON.</li>
<li>You must enable only ONE SINGLE CPU. Mac OS X will not boot on VirtualBox with two or more CPUs</li>
<li><tt>Enable PAE/NX</tt> must be ON.</li>
<li><tt>Enable VT-x/AMD-v</tt> must be ON. This also means your hardware must support it. For Linux users, run the following command to check if your hardware has support for virtualisation enhancements:
<p><tt>grep "vm" /proc/cpuinfo</tt>. </p>
<p>You should see one or more of these lines: </p>
<p><code><br />
flags		: fpu <b>vme</b> de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx lm constant_tsc arch_perfmon pebs bts rep_good aperfmperf pni dtes64 monitor ds_cpl <b>vmx</b> est tm2 ssse3 cx16 xtpr pdcm xsave lahf_lm tpr_shadow vnmi flexpriority<br />
</code></p>
<p>If it&#039;s not there, but you have a recent CPU, you may have to enable VT-x in your BIOS</li>
<li><tt>Enable nested paging</tt> must be OFF</li>
<li><tt>Enable 3D acceleration</tt> must be ON. This also means your hardware AND host operating system has to have support for 3D acceleration. Linux users can use the &#039;<tt>glxgears</tt>&#039; and &#039;<tt>glxinfo</tt>&#039; commands to see if 3D acceleration is working correctly.</li>
<li>Virtual <tt>Storage</tt> must use a SATA controller of the <tt>AHCI</tt> type, and must NOT <tt>use host I/O cache</tt></li>
</ul>
<p><b>IMPORTANT</b>: You MAY have to boot Mac OS X with the <tt>-v</tt> boot option. Directly after starting up the Virtual Machine, hit <tt>enter</tt> and at the <tt>boot:</tt> prompt, enter <tt>-v</tt>. I had to do this the first time to get Mac OS X successfully booted. After the first successful boot, it doesn&#039;t seem necessary anymore. Safe-mode may also help in case of problems.</p>
<p>The Mac OS X image I linked to at the top of this post has its language set to Russian. <a href="http://davidtse916.wordpress.com/2007/11/19/changing-the-system-language-in-mac-os-x/">Here&#039;s a nice blog post about how to change it</a>, including screenshots.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.electricmonk.nl/log/2010/11/05/macos-x-on-virtualbox/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>I&#039;m ditching Chrome because of the http:// stripping.</title>
		<link>http://www.electricmonk.nl/log/2010/04/16/im-ditching-chrome-because-of-the-http-stripping/</link>
		<comments>http://www.electricmonk.nl/log/2010/04/16/im-ditching-chrome-because-of-the-http-stripping/#comments</comments>
		<pubDate>Fri, 16 Apr 2010 09:59:56 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[opinion]]></category>
		<category><![CDATA[tech]]></category>

		<guid isPermaLink="false">http://www.electricmonk.nl/log/?p=4467</guid>
		<description><![CDATA[New development builds, and apparently the Beta build of Chrome for the Mac, strip the &#039;http://&#039; part from the URL input field. Since I run Chromium for Linux, which uses nightly builds of Chrome, I am already affected by this retarded decision. For this reason I will no longer be using Chrome, nor will I [...]]]></description>
			<content:encoded><![CDATA[<p>New development builds, and apparently the Beta build of Chrome for the Mac, strip the &#039;http://&#039; part from the URL input field. Since I run Chromium for Linux, which uses nightly builds of Chrome, I am already affected by this retarded decision. </p>
<p>For this reason I will no longer be using Chrome, nor will I recommend Chrome to anybody anymore. In fact, I will actively recommend using <b>any</b> browser other than Chrome, including Internet Explorer 6. </p>
<p>I could explain why such a &#039;trivial&#039; change upsets me so much that I&#039;d stop using an otherwise&#8230; promising.. product, but life is too short to argue with stupid people, so I&#039;ll just leave it at that. </p>
]]></content:encoded>
			<wfw:commentRss>http://www.electricmonk.nl/log/2010/04/16/im-ditching-chrome-because-of-the-http-stripping/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>SQuirreL SQL database browser</title>
		<link>http://www.electricmonk.nl/log/2010/03/19/squirrel-sql-database-browser/</link>
		<comments>http://www.electricmonk.nl/log/2010/03/19/squirrel-sql-database-browser/#comments</comments>
		<pubDate>Fri, 19 Mar 2010 13:26:01 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[libre software]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[sql]]></category>
		<category><![CDATA[tech]]></category>

		<guid isPermaLink="false">http://www.electricmonk.nl/log/?p=4460</guid>
		<description><![CDATA[I finally found a decent replacement for the MySQLcc database browser: SQuirreL SQL SQuirreL SQL Client is a graphical Java program that will allow you to view the structure of a JDBC compliant database, browse the data in tables, issue SQL commands etc It&#039;s Java, so it&#039;s slow, but it does everything I want, and [...]]]></description>
			<content:encoded><![CDATA[<p>I finally found a decent replacement for the MySQLcc database browser:</p>
<p><a href="http://www.squirrelsql.org/">SQuirreL SQL</a></p>
<blockquote><p>SQuirreL SQL Client is a graphical Java program that will allow you to view the structure of a JDBC compliant database, browse the data in tables, issue SQL commands etc</p></blockquote>
<p>It&#039;s Java, so it&#039;s slow, but it does everything I want, and more:</p>
<ol>
<li>Syntax highlighting</li>
<li>Multiple query tabs</li>
<li>Multiple queries in the same tab (select the query and press ctrl-enter to run it)</li>
<li>Export results</li>
</ol>
<p>It has tons of options you can tweak, and it&#039;s got plugins if you want to extend it. It supports just about every relational (and some non-relational) database out there. </p>
<p>Awesome.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.electricmonk.nl/log/2010/03/19/squirrel-sql-database-browser/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Simple Revision Control with RCS</title>
		<link>http://www.electricmonk.nl/log/2009/06/09/simple-revision-control-with-rcs/</link>
		<comments>http://www.electricmonk.nl/log/2009/06/09/simple-revision-control-with-rcs/#comments</comments>
		<pubDate>Tue, 09 Jun 2009 18:53:07 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[programming]]></category>
		<category><![CDATA[tech]]></category>

		<guid isPermaLink="false">http://www.electricmonk.nl/log/?p=4388</guid>
		<description><![CDATA[I do a lot of stuff in text file on my system. I keep notes and todo&#039;s in them, I write drafts using a text editor and even complete user guides and other documentation. I also keep my personal planning in Gnome Planner which stores its data in an XML file, which in essence is [...]]]></description>
			<content:encoded><![CDATA[<p>I do a lot of stuff in text file on my system. I keep notes and todo&#039;s in them, I write drafts using a text editor and even complete user guides and other documentation. I also keep my personal planning in Gnome Planner which stores its data in an XML file, which in essence is also text. Every so often I wish I could revert a draft back to an older version, or perhaps just have little peak at how it was a couple of days ago. I also really wanted to be able to look back at my planning to see where I made mistakes and underestimated the time required for a particular task.</p>
<p>A revision control system would be ideal in these circumstances. However a full-featured revision control system such as Subversion or Git would be a little overkill in this situation. Enter our old and forgotten friend RCS. RCS has been around since at least 1982, and has since been deprecated by CVS, Subversion and the various other centralized and decentralized versioning systems. It is however perfectly suited for keeping revision histories of single or a small collection of files. RCS is easier to understand than just about any other revision control system too.</p>
<p>Let&#039;s look at how it works. First, we have to install it. It used to be installed by default on most systems, but that&#039;s no longer the case. If you&#039;re running a Debian-based distribution (such as Ubuntu), you can simply install it by typing:</p>
<pre><code><b>aptitude install rcs</b>
</code></pre>
<p>We&#039;ve now got the RCS revision system installed, and we can start using it.</p>
<p>Let&#039;s create an empty text file, called &#039;simple<em>revision</em>control<em>with</em>rcs.txt&#039; in the &#039;drafts&#039; directory:</p>
<pre><code>~$ <b>cd drafts</b>
~/drafts$ <b>touch simple_revision_control_with_rcs.txt</b>
</code></pre>
<p>RCS consists of a couple of simple command-line utilities:</p>
<ul>
<li>&#039;ci&#039;: Check In RCS revisions. This allows you to save the changes made to a file that is managed by RCS.</li>
<li>&#039;co&#039;: Check out RCS working copy. This command retrieves a specific version (the latest by default) of a file in a RCS repository.</li>
</ul>
<p>So let&#039;s convert our empty draft to an RCS repository by checking it in. This means RCS will create a file based on the file you want to check in with the appropriate information such as when it has been been changed, what changed, etc. </p>
<pre><code>~/drafts/$ <b>ci simple_revision_control_with_rcs.txt</b>
simple_revision_control_with_rcs.txt,v  &lt;--  simple_revision_control_with_rcs.txt
enter description, terminated with single '.' or end of file:
NOTE: This is NOT the log message!
&gt;&gt; <b>Simple revision control with RCS</b>
&gt;&gt; .
initial revision: 1.1
done
</code></pre>
<p>There. Our initial empty file is gone, and in its place is a file under RCS revision control: &#039;simple<em>revision</em>control<em>with</em>rcs.txt,v&#039;. It has been given a revision number by RCS: revision 1.1.</p>
<p>We can now make a working copy of this file by doing a checkout. This will retrieve the latest modifications from the text file and create a new file with the original name in the current directory. The first thing we should do though, is to turn off locking. We&#039;re working on this file ourselves, and it will never be shared, so we don&#039;t care about locking at all. Locking can be turned off using the &#039;-U&#039; option of the &#039;rcs&#039; tool:</p>
<pre><code>~/drafts$ <b>rcs -U ./simple_revision_control_with_rcs.txt,v </b>
RCS file: ./simple_revision_control_with_rcs.txt,v
done
</code></pre>
<p>Now we can do a checkout so we can edit our draft. Let&#039;s do this, and add a line to it:</p>
<pre><code>~/drafts$ <b>co simple_revision_control_with_rcs.txt,v </b>
simple_revision_control_with_rcs.txt,v  --&gt;  simple_revision_control_with_rcs.txt
revision 1.1
done
~/drafts$ <b>echo "Hello world" &gt; simple_revision_control_with_rcs.txt</b>
</code></pre>
<p>Now let&#039;s commit this change to the repository so RCS knows about it:</p>
<pre><code>~/drafts$ <b>ci simple_revision_control_with_rcs.txt</b>
simple_revision_control_with_rcs.txt,v  &lt;--  simple_revision_control_with_rcs.txt
new revision: 1.2; previous revision: 1.1
enter log message, terminated with single '.' or end of file:
&gt;&gt; <b>Added greeting.</b>
&gt;&gt; .
done
</code></pre>
<p>RCS keeps an entire history of all changes made to the files it keeps under revision each time you do a check in. Take a look at the history of the file with the command &#039;rlog&#039;:</p>
<pre><code>~/drafts$ <b>rlog ./simple_revision_control_with_rcs.txt,v</b>
RCS file: ./simple_revision_control_with_rcs.txt,v
Working file: simple_revision_control_with_rcs.txt
head: 1.2
branch:
locks: non-strict
access list:
symbolic names:
keyword substitution: kv
total revisions: 2; selected revisions: 2
description:
Simple revision control with RCS
----------------------------
revision 1.2
date: 2009/06/09 07:48:50;  author: todsah;  state: Exp;  lines: +1 -0
Added greeting.
----------------------------
revision 1.1
date: 2009/06/09 07:46:24;  author: todsah;  state: Exp;
Initial revision
=============================================================================
</code></pre>
<p>That lists some basic information on the file, the repository and the two revisions we&#039;ve made so far. We can now easily check out earlier revisions of the file by specifying a specific revision, or a date:</p>
<pre><code>~/drafts$ <b>co -r1.1 simple_revision_control_with_rcs.txt</b>
simple_revision_control_with_rcs.txt,v  --&gt;  simple_revision_control_with_rcs.txt
revision 1.1
done
~/drafts$ <b>cat simple_revision_control_with_rcs.txt</b>
~/drafts$
</code></pre>
<p>RCS has given us back our file as it existed at revision 1.1, which was the empty file. Let&#039;s retrieve the version of the file as it was at 14:00 today:</p>
<pre><code>~/drafts$ <b>co -d"14:00" simple_revision_control_with_rcs.txt,v</b>
simple_revision_control_with_rcs.txt,v  --&gt;  simple_revision_control_with_rcs.txt
revision 1.2
writable simple_revision_control_with_rcs.txt exists; remove it? [ny](n): <b>y</b>
done
</code></pre>
<p>In conclusion: RCS may appear to be completely dead, but it still has its uses. I know many people out there will think to themselves &#034;Why not just use Git or Subversion&#034;? I understand the attraction of very powerful tools, but I also really believe in keeping things simple, and using the right tool for the job. I don&#039;t know much about Git, so perhaps it is ideal for such a simple requirement, but I don&#039;t really feel like learning it just to version control a single file. </p>
]]></content:encoded>
			<wfw:commentRss>http://www.electricmonk.nl/log/2009/06/09/simple-revision-control-with-rcs/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Performance optimization: The first thing to do</title>
		<link>http://www.electricmonk.nl/log/2009/04/19/performance-optimization-the-first-thing-to-do/</link>
		<comments>http://www.electricmonk.nl/log/2009/04/19/performance-optimization-the-first-thing-to-do/#comments</comments>
		<pubDate>Sun, 19 Apr 2009 19:21:45 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[opinion]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[tech]]></category>

		<guid isPermaLink="false">http://www.electricmonk.nl/log/?p=4328</guid>
		<description><![CDATA[In the last couple of years, I&#039;ve done a lot of performance optimization. I&#039;ve optimized raw C, Python and PHP code. I&#039;ve optimized databases: tweaked settings, memory usage, caches, SQL code, the query analyzer, hardware and indexes. I&#039;ve optimized templates for disk I/O, compilation and rendering. I&#039;ve optimize various caches and all kinds of other [...]]]></description>
			<content:encoded><![CDATA[<p>In the last couple of years, I&#039;ve done a lot of performance optimization. I&#039;ve optimized raw C, Python and PHP code. I&#039;ve optimized databases: tweaked settings, memory usage, caches, SQL code, the query analyzer, hardware and indexes. I&#039;ve optimized templates for disk I/O, compilation and rendering. I&#039;ve optimize various caches and all kinds of other stuff like VMWare configurations. </p>
<p>As I&#039;ve done a lot of optimization, I&#039;ve noticed a couple of things. One of these things is how persons in different roles look at optimization:</p>
<p><i>Programmers</i> always want to optimize the code. The code isn&#039;t optimal, and a lot of speed can be gained from optimizing the code. This usually boils down to optimizing algorithms to be more efficient with either CPU cycles or memory. In contrast to the programmer, the <i>system administrator</i> always wants to tweak the configuration of either the Operating System, the application itself, or some piece of middle-ware in between. Meanwhile, <i>managers</i> always want to optimize the hardware. &#034;Developer time is more expensive than hardware&#034;, they quip, so they decide to throw money at faster and more hardware, instead of letting the developer optimize the code.</p>
<p>What none of them realise is that they&#039;re all wrong. None of these approaches are any good. When it comes to optimizations, all of the people above are stuck in their own little world. Of course managers just <i>love</i> the fact that programmers &#034;don&#039;t understand cost versus benefit&#034;, and a nice saying such as &#034;Developer time is more expensive than hardware&#034; has a really nice ring to it. Managers have a high-level view of the application&#039;s eco-system, and so they search for the solution in the cheapest component: hardware. Programmers, on the other hand, know the system from a very low-level point of view. And they naturally <i>love</i> the fact that managers don&#039;t understand technology. They are intimately familiar with the code of their application, or the database running behind it, and so they know a lot of its weak spots. Of course, they&#039;ll assume the optimization is best performed there. The system Systems administrators have limited options either way, so they stick to what they can influence: configuration. </p>
<p>An excellent example of this is <a href="http://joelonsoftware.com/items/2009/03/27.html">a recent post</a> on the JoelOnSoftware blog. I&#039;ll recap the main points I&#039;d like to illustrate here:</p>
<blockquote><p>
One of the FogBugz developers complained that compiling was pretty slow (about 30 seconds). [...] He asked if it would be OK if someone spent a few weeks looking for ways to parallelize and speed it up, since we all have multiple CPU cores and plenty of memory. [...] I thought it might be a good idea to just try throwing money at the problem first, before we spent a lot of (expensive and scarce) developer time. [...] so I thought I&#039;d experiment with replacing some of the hard drives around here with solid state, flash hard drives to see if that helped.</p>
<p>Suddenly everything was faster. Booting, launching apps&#8230; even Outlook is ready to use in about 1 second. This was a really great upgrade. But&#8230; compile time. Hmm. That wasn&#039;t much better. I got it down from 30 seconds to &#8230; 30 seconds. Our compiler is single threaded, and, I guess, a lot more CPU-bound than IO bound.
</p></blockquote>
<p>This is an excellent example of how a manager would try to solve optimization problems. At the start of the quote we see the typical way a developer would tackle the problem: parallelize and speed up. In other words: low-level optimizations.</p>
<p>Now it turns out Joel was wrong. Solid State disks didn&#039;t help at all, since their problem wasn&#039;t with disk I/O at all. But that doesn&#039;t mean the developer was right <i>either</i>! I like to see it as a kind of Schr&ouml;dinger&#039;s Cat situation: <i>both</i> are wrong, until one is proven right. Why is that? Because they <i>have no idea what the problem is!</i>. All they&#039;re doing is guessing away at the problem in the hopes of finding out what exactly will solve it, without having any clue about the actual problem! We can see this quite clearly: after having dismissed disk I/O as the problem, they assume it must be because <i>&#034;our compiler is single threaded, and, I guess, a lot more CPU-bound than IO bound.&#034;</i>. Again, they jump to conclusions without knowing what the problem is. So now they might not only waste a lot of time on solid state disks without fixing the problem, but they&#039;re about to spend weeks of developer time without knowing if that will fix the problem.</p>
<p>So, here is my point:</p>
<p><b>The most important thing about optimization is <i>analysis</i></b>.</p>
<p>You can&#039;t fix a problem by simply trying different solutions to see if they work. In order to fix a problem, you have to <i>understand</i> the problem first.</p>
<p>So, please, if you&#039;re a developer, don&#039;t assume saving a couple of CPU cycles here or there will solve the problem. And if you&#039;re a manager, don&#039;t assume some new hardware will solve the problem. Do some analysis first. Finding out if disk I/O, memory, CPU cycles or single threading is the problem is really not that hard if you spend a little time thinking about it and benchmarking various things. And in the end, you&#039;ll have a much better overview of the situation and the problem, and you&#039;ll be able to come up with specific solutions which will actually work. </p>
<p>And <i>that&#039;s</i> how you save money.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.electricmonk.nl/log/2009/04/19/performance-optimization-the-first-thing-to-do/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>

