<?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>zomo tech</title>
	<atom:link href="http://www.zomo.co.uk/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.zomo.co.uk</link>
	<description>Is it done yet?</description>
	<lastBuildDate>Sun, 28 Apr 2013 22:13:44 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.5.1</generator>
		<item>
		<title>Bulk Tumblr Image Posting</title>
		<link>http://www.zomo.co.uk/2013/03/bulk-tumblr-image-posting/</link>
		<comments>http://www.zomo.co.uk/2013/03/bulk-tumblr-image-posting/#comments</comments>
		<pubDate>Sun, 17 Mar 2013 13:00:56 +0000</pubDate>
		<dc:creator>lemon</dc:creator>
				<category><![CDATA[sw]]></category>

		<guid isPermaLink="false">http://www.zomo.co.uk/?p=659</guid>
		<description><![CDATA[I didn&#8217;t really get along with the current offerings of bulk image uploaders, so I wrote one: tumblr-tools]]></description>
				<content:encoded><![CDATA[<p>I didn&#8217;t really get along with the current offerings of bulk image uploaders, so I wrote one: <a href="https://github.com/zomo/tumblr-tools">tumblr-tools</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.zomo.co.uk/2013/03/bulk-tumblr-image-posting/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>freebsd-update and custom kernels</title>
		<link>http://www.zomo.co.uk/2013/03/freebsd-update-and-custom-kernels/</link>
		<comments>http://www.zomo.co.uk/2013/03/freebsd-update-and-custom-kernels/#comments</comments>
		<pubDate>Sat, 16 Mar 2013 16:34:07 +0000</pubDate>
		<dc:creator>lemon</dc:creator>
				<category><![CDATA[stash]]></category>
		<category><![CDATA[sw]]></category>

		<guid isPermaLink="false">http://www.zomo.co.uk/?p=522</guid>
		<description><![CDATA[This post is search fodder, mostly. If you&#8217;re using freebsd-update to upgrade FreeBSD and you run a custom kernel and temporarily using the generic kernel isn&#8217;t an option and it&#8217;s been ages since you&#8217;ve done this, then welcome! $ sudo freebsd-update upgrade -r 9.1-RELEASE [ warnings about custom kernel ] $ sudo freebsd-update install [ [...]]]></description>
				<content:encoded><![CDATA[<p>This post is search fodder, mostly.</p>
<p>If you&#8217;re using <code>freebsd-update</code> to upgrade FreeBSD <em>and</em> you run a custom kernel <em>and</em> temporarily using the generic kernel isn&#8217;t an option <em>and</em> it&#8217;s been ages since you&#8217;ve done this, then welcome!</p>
<p><code>$ sudo freebsd-update upgrade -r 9.1-RELEASE</p>
<p>[ warnings about custom kernel ]</p>
<p>$ sudo freebsd-update install</p>
<p>[ this is when the new generic kernel is installed if we weren't running a custom kernel ]</p>
<p>$ cd /usr<br />
$ mv src{,-8.2}<br />
$ sudo svn co https://svn.freebsd.org/base/releng/9.1/<br />
$ sudo cp src{-8.2,}/sys/i386/conf/PULP<br />
$ cd src</p>
<p>$ sudo rsync -a /boot/kernel{,-8.2}/<br />
$ sudo make kernel-toolchain<br />
$ sudo make buildkernel KERNCONF=PULP<br />
$ sudo make installkernel KERNCONF=PULP</p>
<p>$ sudo reboot</p>
<p>$ sudo freebsd-update install<br />
$ sudo reboot<br />
</code></p>
<p>The <code>kernel-toolchain</code> bit is the important one. In the Old Days<sup><a href="http://www.zomo.co.uk/2013/03/freebsd-update-and-custom-kernels/#footnote_0_522" id="identifier_0_522" class="footnote-link footnote-identifier-link" title="not really, but binary updating is way nicer">1</a></sup> of <code>buildworld</code> the new kernel is built with the new world&#8217;s compiler, linker etc instead of what&#8217;s currently installed. Going directly to <code>buildkernel</code> during the <code>freebsd-update</code> dance means the custom kernel builds with the toolchain that&#8217;s about to be replaced.</p>
<p>Trying to build the new kernel with the old toolchain results in </p>
<ul>
<li>warnings-as-errors in random modules</li>
<li>old kernel linker unable to parse new kernel link data</li>
</ul>
<p>and no kernel.</p>
<ol class="footnotes"><li id="footnote_0_522" class="footnote">not really, but binary updating is way nicer</li></ol>]]></content:encoded>
			<wfw:commentRss>http://www.zomo.co.uk/2013/03/freebsd-update-and-custom-kernels/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Extracting voicememo name and file location from iTunes</title>
		<link>http://www.zomo.co.uk/2013/03/extracting-voicememo-name-file-location-from-itunes/</link>
		<comments>http://www.zomo.co.uk/2013/03/extracting-voicememo-name-file-location-from-itunes/#comments</comments>
		<pubDate>Sat, 02 Mar 2013 16:23:29 +0000</pubDate>
		<dc:creator>lemon</dc:creator>
				<category><![CDATA[sw]]></category>

		<guid isPermaLink="false">http://www.zomo.co.uk/?p=516</guid>
		<description><![CDATA[iTunes helpfully copies voicememos from the phone to a handy local directory, but the filenames are just timestamps, which isn&#8217;t so great if you&#8217;ve diligently named them. The voicememo&#8217;s title is visible in iTunes, but it&#8217;s coy about revealing which file it corresponds to. So into the iTunes database we go&#8230; with xmlstarlet. Because every [...]]]></description>
				<content:encoded><![CDATA[<p>iTunes helpfully copies voicememos from the phone to a handy local directory, but the filenames are just timestamps, which isn&#8217;t so great if you&#8217;ve diligently named them. The voicememo&#8217;s title is visible in iTunes, but it&#8217;s coy about revealing which file it corresponds to. So into the iTunes database we go&#8230; with <a href="http://xmlstar.sourceforge.net">xmlstarlet</a>.</p>
<p><script src="https://gist.github.com/zomo/5071720.js"></script></p>
<p>Because every Saturday morning needs some XML, right?</p>
]]></content:encoded>
			<wfw:commentRss>http://www.zomo.co.uk/2013/03/extracting-voicememo-name-file-location-from-itunes/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>URL handlers on OS X</title>
		<link>http://www.zomo.co.uk/2012/04/url-handlers-on-os-x/</link>
		<comments>http://www.zomo.co.uk/2012/04/url-handlers-on-os-x/#comments</comments>
		<pubDate>Fri, 20 Apr 2012 02:41:05 +0000</pubDate>
		<dc:creator>lemon</dc:creator>
				<category><![CDATA[sw]]></category>

		<guid isPermaLink="false">http://www.zomo.co.uk/?p=500</guid>
		<description><![CDATA[Update 2012-04-25 Corrected the plist key to CFBundleIdentifier. I&#8217;ve often wondered about how to do this without monkeying in Objective C. It&#8217;s doable in (ugh) Applescript with some property list editing. Whimsical XKCD handler such that xkcd://627 behaves like http://xckd.com/627: on open location uri &#160;&#160;set delimiter to AppleScript's text item delimiters &#160;&#160;set AppleScript's text item [...]]]></description>
				<content:encoded><![CDATA[<p><em>Update 2012-04-25</em> Corrected the <code>plist</code> key to <code>CFBundleIdentifier</code>.</p>
<p>I&#8217;ve often wondered about how to do this without monkeying in Objective C. It&#8217;s doable in (ugh) Applescript with some property list editing. Whimsical XKCD handler such that <a href="xkcd://627"><code>xkcd://627</code></a> behaves like <a href="http://xkcd.com/627"><code>http://xckd.com/627</code></a>:</p>
<p><code><br />
on open location uri<br />
&nbsp;&nbsp;set delimiter to AppleScript's text item delimiters<br />
&nbsp;&nbsp;set AppleScript's text item delimiters to "//"<br />
&nbsp;&nbsp;set comic to text item 2 of uri<br />
&nbsp;&nbsp;set page to "http://xkcd.com/" &#038; comic<br />
&nbsp;&nbsp;tell application "Safari"<br />
&nbsp;&nbsp;&nbsp;&nbsp;activate<br />
&nbsp;&nbsp;&nbsp;&nbsp;open location page<br />
&nbsp;&nbsp;end tell<br />
&nbsp;&nbsp;set AppleScript's text item delimiters to delimiter<br />
end open location<br />
</code></p>
<p>Save as an Application rather than a Script. Open its <code>info.plist</code> and add<br />
<code><br />
&nbsp;&lt;key&gt;CFBundleIdentifier&lt;/key&gt;<br />
&nbsp;&lt;string&gt;uk.co.zomo.xkcd-handler&lt;/string&gt;<br />
&nbsp;&lt;key&gt;CFBundleURLTypes&lt;/key&gt;<br />
&nbsp;&lt;array&gt;<br />
&nbsp;&nbsp;&lt;dict&gt;<br />
&nbsp;&nbsp;&nbsp;&lt;key&gt;CFBundleURLName&lt;/key&gt;<br />
&nbsp;&nbsp;&nbsp;&lt;string&gt;XKCD helper&lt;/string&gt;<br />
&nbsp;&nbsp;&nbsp;&lt;key&gt;CFBundleURLSchemes&lt;/key&gt;<br />
&nbsp;&nbsp;&nbsp;&lt;array&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&lt;string&gt;xkcd&lt;/string&gt;<br />
&nbsp;&nbsp;&nbsp;&lt;/array&gt;<br />
&nbsp;&nbsp;&lt;/dict&gt;<br />
&nbsp;&lt;/array&gt;<br />
</code></p>
<p>To nudge OS X to notice changed a plist:<br />
<code><br />
/System/Library/Frameworks/CoreServices.framework/Frameworks/LaunchServices.framework/Support/lsregister -v -f ~/Library/Scripts/xkcd-handler.app<br />
</code></p>
<p>Links:</p>
<ul>
<li><a href="http://applescript123.com/linktrigger/">http://applescript123.com/linktrigger/</a></li>
<li><a href="http://stackoverflow.com/questions/8981749/how-do-i-refresh-application-metadata-url-handlers-web-browsers-after-insta">http://stackoverflow.com/questions/8981749/how-do-i-refresh-application-metadata-url-handlers-web-browsers-after-insta</a></li>
<li><a href="http://www.rubicode.com/Software/RCDefaultApp/">http://www.rubicode.com/Software/RCDefaultApp/</a>
</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.zomo.co.uk/2012/04/url-handlers-on-os-x/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>httperf on Linux</title>
		<link>http://www.zomo.co.uk/2012/04/httperf-on-linux/</link>
		<comments>http://www.zomo.co.uk/2012/04/httperf-on-linux/#comments</comments>
		<pubDate>Mon, 16 Apr 2012 07:34:29 +0000</pubDate>
		<dc:creator>lemon</dc:creator>
				<category><![CDATA[stash]]></category>
		<category><![CDATA[sw]]></category>

		<guid isPermaLink="false">http://www.zomo.co.uk/?p=491</guid>
		<description><![CDATA[&#8220;httperf is a tool for measuring web server performance. It provides a flexible facility for generating various HTTP workloads and for measuring server performance.&#8221; Set open files to 65535 via ulimit -n Recompile httperf with /usr/include/bits/typesizes.h&#8216;s __FD_SETSIZE dialled up to 655351 Twiddle the TCP stack for faster socket recycling23 : echo 1 > /proc/sys/net/ipv4/tcp_tw_recycle echo [...]]]></description>
				<content:encoded><![CDATA[<p>&#8220;<a href="http://code.google.com/p/httperf/" title="httperf">httperf</a> is a tool for measuring web server performance. It provides a flexible facility for generating various HTTP workloads and for measuring server performance.&#8221;</p>
<ul>
<li>Set open files to 65535 via <code>ulimit -n</code></li>
<li>Recompile <code>httperf</code> with <code>/usr/include/bits/typesizes.h</code>&#8216;s <code>__FD_SETSIZE</code> dialled up to 65535<sup><a href="http://www.zomo.co.uk/2012/04/httperf-on-linux/#footnote_0_491" id="identifier_0_491" class="footnote-link footnote-identifier-link" title=" http://gom-jabbar.org/articles/2009/02/04/httperf-and-file-descriptors ">1</a></sup> </li>
<li>Twiddle the TCP stack for faster socket recycling<sup><a href="http://www.zomo.co.uk/2012/04/httperf-on-linux/#footnote_1_491" id="identifier_1_491" class="footnote-link footnote-identifier-link" title=" http://www.speedguide.net/articles/linux-tweaking-121 ">2</a></sup><sup><a href="http://www.zomo.co.uk/2012/04/httperf-on-linux/#footnote_2_491" id="identifier_2_491" class="footnote-link footnote-identifier-link" title="http://serverfault.com/questions/331513/httperf-hangs-when-using-hog">3</a></sup> :<br />
<code><br />
echo 1 > /proc/sys/net/ipv4/tcp_tw_recycle<br />
echo 1 > /proc/sys/net/ipv4/tcp_tw_reuse<br />
</code><code></code></li>
</ul>
<ol class="footnotes"><li id="footnote_0_491" class="footnote"> http://gom-jabbar.org/articles/2009/02/04/httperf-and-file-descriptors </li><li id="footnote_1_491" class="footnote"> http://www.speedguide.net/articles/linux-tweaking-121 </li><li id="footnote_2_491" class="footnote">http://serverfault.com/questions/331513/httperf-hangs-when-using-hog</li></ol>]]></content:encoded>
			<wfw:commentRss>http://www.zomo.co.uk/2012/04/httperf-on-linux/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Moving disks from Xen to KVM</title>
		<link>http://www.zomo.co.uk/2012/04/moving-disks-from-xen-to-kvm/</link>
		<comments>http://www.zomo.co.uk/2012/04/moving-disks-from-xen-to-kvm/#comments</comments>
		<pubDate>Sun, 08 Apr 2012 07:17:35 +0000</pubDate>
		<dc:creator>lemon</dc:creator>
				<category><![CDATA[stash]]></category>

		<guid isPermaLink="false">http://www.zomo.co.uk/?p=477</guid>
		<description><![CDATA[Overview Moving virtual machines from Xen to KVM The storage for both is under LVM Under Xen the storage for each VM isn&#8217;t partitioned as a disk, it&#8217;s just a filesystem. GRUB under KVM will need to see a boot sector and a partition table. Under Xen the storage for each VM doesn&#8217;t contain a [...]]]></description>
				<content:encoded><![CDATA[<h3>Overview</h3>
<ul>
<li>Moving virtual machines from Xen to KVM</li>
<li>The storage for both is under LVM</li>
<li>Under Xen the storage for each VM isn&#8217;t partitioned as a disk, it&#8217;s just a filesystem. GRUB under KVM will need to see a boot sector and a partition table.</li>
<li>Under Xen the storage for each VM doesn&#8217;t contain a kernel. GRUB under KVM will need one to boot the VM.</li>
</ul>
<h3>Sequence</h3>
<ul>
<li>Measure disks on Xen server, create on KVM server. Create the new root disk 10MB larger than its counterpart.<sup><a href="http://www.zomo.co.uk/2012/04/moving-disks-from-xen-to-kvm/#footnote_0_477" id="identifier_0_477" class="footnote-link footnote-identifier-link" title=" Later we align the original root filesystem at cylinder 1 on this new disk. A LVM cylinder is roughly 8MB ">1</a></sup><br />
<code><br />
kyero@xen03 ~ $ sudo lvscan<br />
  ACTIVE            '/dev/vg4/mail-root' [20.00 GB] inherit<br />
  ACTIVE            '/dev/vg4/mail-swap' [1.00 GB] inherit<br />
</code><br />
<code><br />
[kyero@vm02 ~]$ sudo lvcreate -L20490M -n mail-root vg4<br />
[kyero@vm02 ~]$ sudo lvcreate -L2G -n mail-swap vg4<br />
</code>
</li>
<li>Create a boot disk on the KVM server. We make it 4 cylinders long, roughly 32MB.<sup><a href="http://www.zomo.co.uk/2012/04/moving-disks-from-xen-to-kvm/#footnote_1_477" id="identifier_1_477" class="footnote-link footnote-identifier-link" title=" File backed disk is used rather than LVM owing to grief with GRUB and LVM (Error 22: No such partition) ">2</a></sup><br />
<code><br />
[kyero@vm02 ~]$ sudo dd if=/dev/zero of=/var/boot-images/mail-boot bs=32901120 count=1<br />
</code>
</li>
<li>Partition the boot disk with one partition starting at cylinder zero<br />
<code><br />
[kyero@vm02 ~]$ sudo sfdisk /var/boot-images/mail-boot<br />
last_lba(): I don't know how to handle files with mode 81a4<br />
Warning: /var/boot-images/mail-boot is not a block device<br />
Disk /var/boot-images/mail-boot: cannot get geometry</p>
<p>Disk /var/boot-images/mail-boot: 4 cylinders, 255 heads, 63 sectors/track</p>
<p>sfdisk: ERROR: sector 0 does not have an msdos signature<br />
 /var/boot-images/mail-boot: unrecognized partition table type<br />
Old situation:<br />
No partitions found<br />
Input in the following format; absent fields get a default value.<br />
&lt;start&gt; &lt;size&gt; &lt;type [E,S,L,X,hex]&gt; &lt;bootable [-,*]&gt; &lt;c,h,s&gt; &lt;c,h,s&gt;\nUsually you only need to specify &lt;start&gt; and &lt;size&gt; (and perhaps &lt;type&gt;).</p>
<p>/var/boot-images/mail-boot1 :0<br />
/var/boot-images/mail-boot1          0+      3       4-     32129+  83  Linux<br />
/var/boot-images/mail-boot2 :<br />
/var/boot-images/mail-boot2          0       -       0          0    0  Empty<br />
/var/boot-images/mail-boot3 :<br />
/var/boot-images/mail-boot3          0       -       0          0    0  Empty<br />
/var/boot-images/mail-boot4 :<br />
/var/boot-images/mail-boot4          0       -       0          0    0  Empty<br />
New situation:<br />
Units = cylinders of 8225280 bytes, blocks of 1024 bytes, counting from 0</p>
<p>   Device Boot Start     End   #cyls    #blocks   Id  System<br />
/var/boot-images/mail-boot1          0+      3       4-     32129+  83  Linux<br />
/var/boot-images/mail-boot2          0       -       0          0    0  Empty<br />
/var/boot-images/mail-boot3          0       -       0          0    0  Empty<br />
/var/boot-images/mail-boot4          0       -       0          0    0  Empty<br />
Warning: no primary partition is marked bootable (active)<br />
This does not matter for LILO, but the DOS MBR will not boot this disk.<br />
Do you want to write this to disk? [ynq] y<br />
Successfully wrote the new partition table</p>
<p>Re-reading the partition table ...<br />
BLKRRPART: Inappropriate ioctl for device</p>
<p>If you created or changed a DOS partition, /dev/foo7, say, then use dd(1)<br />
to zero the first 512 bytes:  dd if=/dev/zero of=/dev/foo7 bs=512 count=1<br />
(See fdisk(8).)</p>
<p></code>
</li>
<li>Format and mount the partition<br />
<code><br />
[kyero@vm02 ~]$ sudo kpartx -av /var/boot-images/mail-boot<br />
add map loop1p1 : 0 64259 linear /dev/loop1 1</p>
<p>[kyero@vm02 ~]$ sudo mke2fs /dev/mapper/loop1p1<br />
mke2fs 1.39 (29-May-2006)<br />
Filesystem label=<br />
OS type: Linux<br />
Block size=1024 (log=0)<br />
Fragment size=1024 (log=0)<br />
8032 inodes, 32128 blocks<br />
1606 blocks (5.00%) reserved for the super user<br />
First data block=1<br />
Maximum filesystem blocks=33030144<br />
4 block groups<br />
8192 blocks per group, 8192 fragments per group<br />
2008 inodes per group<br />
Superblock backups stored on blocks:<br />
        8193, 24577</p>
<p>Writing inode tables: done<br />
Writing superblocks and filesystem accounting information: done</p>
<p>This filesystem will be automatically checked every 34 mounts or<br />
180 days, whichever comes first.  Use tune2fs -c or -i to override.</p>
<p>[kyero@vm02 ~]$ sudo mount /dev/mapper/loop1p1 /mnt/boot/</p>
<p>[kyero@vm02 ~]$ df -h /mnt/boot<br />
Filesystem            Size  Used Avail Use% Mounted on<br />
/dev/mapper/loop1p1    31M  389K   29M   2% /mnt/boot<br />
</code>
</li>
<li>Copy a kernel to it, configure GRUB&#8217;s notion of the root device and install the boot sector.<br />
<code><br />
[kyero@vm02 ~]$ sudo rsync -a /boot/ /mnt/boot/<br />
[kyero@vm02 ~]$ sudo vi /mnt/boot/grub/menu.lst<br />
[kyero@vm02 ~]$ sudo touch /mnt/boot/kvm-boot-image<br />
[kyero@vm02 ~]$ sudo grub --device-map=/dev/null</p>
<p>    GNU GRUB  version 0.97  (640K lower / 3072K upper memory)</p>
<p> [ Minimal BASH-like line editing is supported.  For the first word, TAB<br />
   lists possible command completions.  Anywhere else TAB lists the possible<br />
   completions of a device/filename.]<br />
grub> device (hd0) /var/boot-images/mail-boot<br />
device (hd0) /var/boot-images/mail-boot<br />
grub> find /kvm-boot-image<br />
find /kvm-boot-image<br />
 (hd0,0)<br />
grub> root (hd0,0)<br />
root (hd0,0)<br />
 Filesystem type is ext2fs, partition type 0x83<br />
grub> setup (hd0)<br />
setup (hd0)<br />
 Checking if "/boot/grub/stage1" exists... no<br />
 Checking if "/grub/stage1" exists... yes<br />
 Checking if "/grub/stage2" exists... yes<br />
 Checking if "/grub/e2fs_stage1_5" exists... yes<br />
 Running "embed /grub/e2fs_stage1_5 (hd0)"... failed (this is not fatal)<br />
 Running "embed /grub/e2fs_stage1_5 (hd0,0)"... failed (this is not fatal)<br />
Done.<br />
grub> quit</p>
<p>[kyero@vm02 ~]$ sudo umount /mnt/boot<br />
[kyero@vm02 ~]$ sudo kpartx -d /var/boot-images/mail-boot<br />
loop deleted : /dev/loop1</p>
<p></code></li>
<li>Populate the new root disk with one cylinder of zeros and a copy of the old root disk.<br />
The first cylinder will contain the MBR and not much else. The padding means it&#8217;s easy to align the old root disk at cylinder one.<br />
Use <code>pv</code> so we can see the copy progress.<br />
The <code>dd-lvm-out</code> script is mostly just a <code>sudo</code>-blessed wrapper.<br />
<code>[kyero@vm02 ~]$ ( dd if=/dev/zero bs=8225280 count=1 ; ssh xen03.local -l kyero sudo /data/system/bin/dd-lvm-out.sh mail-root ) | pv -e -r -s 21474836480 | sudo dd bs=1048577 of=/dev/vg4/mail-root<br />
1+0 records in<br />
1+0 records out<br />
8225280 bytes (8.2 MB) copied, 0.03395 seconds, 242 MB/s<br />
20480+0 records in<br />
20480+0 records out<br />
21474836480 bytes (21 GB) copied, 611.215 s, 35.1 MB/s<br />
0+662630 records in<br />
0+662630 records out<br />
21483061795 bytes (21 GB) copied, 615.249 seconds, 34.9 MB/s<br />
</code>
</li>
<li>Partition the new root disk with a single partition starting at cylinder one.<br />
<code>[kyero@vm02 ~]$ sudo sfdisk /dev/vg4/mail-root<br />
Checking that no-one is using this disk right now ...<br />
BLKRRPART: Invalid argument<br />
OK</p>
<p>Disk /dev/vg4/mail-root: 2614 cylinders, 255 heads, 63 sectors/track</p>
<p>sfdisk: ERROR: sector 0 does not have an msdos signature<br />
 /dev/vg4/mail-root: unrecognized partition table type<br />
Old situation:<br />
No partitions found<br />
Input in the following format; absent fields get a default value.<br />
&lt;start&gt; &lt;size&gt; &lt;type [E,S,L,X,hex]&gt; &lt;bootable [-,*]&gt; &lt;c,h,s&gt; &lt;c,h,s&gt;\nUsually you only need to specify &lt;start&gt; and &lt;size&gt; (and perhaps &lt;type&gt;).</p>
<p>/dev/vg4/mail-root1 :1<br />
/dev/vg4/mail-root1          1    2613    2613   20988922+  83  Linux<br />
/dev/vg4/mail-root2 :<br />
/dev/vg4/mail-root2          0+      0       1-      8032   83  Linux<br />
/dev/vg4/mail-root3 :<br />
/dev/vg4/mail-root3          0       -       0          0    0  Empty<br />
/dev/vg4/mail-root4 :<br />
/dev/vg4/mail-root4          0       -       0          0    0  Empty<br />
New situation:<br />
Units = cylinders of 8225280 bytes, blocks of 1024 bytes, counting from 0</p>
<p>   Device Boot Start     End   #cyls    #blocks   Id  System<br />
/dev/vg4/mail-root1          1    2613    2613   20988922+  83  Linux<br />
/dev/vg4/mail-root2          0+      0       1-      8032   83  Linux<br />
/dev/vg4/mail-root3          0       -       0          0    0  Empty<br />
/dev/vg4/mail-root4          0       -       0          0    0  Empty<br />
Warning: no primary partition is marked bootable (active)<br />
This does not matter for LILO, but the DOS MBR will not boot this disk.<br />
Do you want to write this to disk? [ynq] y<br />
Successfully wrote the new partition table</p>
<p>Re-reading the partition table ...<br />
BLKRRPART: Invalid argument</p>
<p>If you created or changed a DOS partition, /dev/foo7, say, then use dd(1)<br />
to zero the first 512 bytes:  dd if=/dev/zero of=/dev/foo7 bs=512 count=1<br />
(See fdisk(8).)</p>
<p></code></li>
<li>Mount the new root filesystem<br />
<code>[kyero@vm02 ~]$ sudo kpartx -av /dev/vg4/mail-root<br />
add map mail-root1 : 0 41977845 linear /dev/vg4/mail-root 16065<br />
add map mail-root2 : 0 16064 linear /dev/vg4/mail-root 1<br />
[kyero@vm02 ~]$ sudo e2fsck /dev/mapper/mail-root1<br />
e2fsck 1.39 (29-May-2006)<br />
/dev/mapper/mail-root1: clean, 435213/1310720 files, 4086961/5242880 blocks</p>
<p>[kyero@vm02 ~]$ sudo mount /dev/mapper/mail-root1 /mnt/tmp<br />
</code></li>
<li>Add the new kernel&#8217;s modules, tweak filesystem mounts, disable swap, check console.<br />
<code><br />
[kyero@vm02 ~]$ sudo rsync -a /lib/modules/ /mnt/tmp/lib/modules/</p>
<p>[kyero@vm02 ~]$ sudo vi /mnt/tmp/etc/fstab</p>
<p>[kyero@vm02 ~]$ sudo vi /mnt/tmp/etc/inittab<br />
</code>
</li>
<li>Create the KVM guest, assigning the boot, root and swap storage<br />
<code>[kyero@vm02 ~]$ sudo virt-install -n mail -r 1024 --vcpus 1 --os-type linux --os-variant generic26 --accelerate --disk path=/var/boot-images/mail-boot --disk path=/dev/mapper/vg4-mail--root,bus=ide,format=raw --disk path=/dev/mapper/vg4-mail--swap,bus=ide,format=raw --network bridge:br0 --network bridge:br1 --import --noreboot<br />
Starting install...<br />
Guest installation complete... you can restart your domain<br />
by running 'virsh start mail'</p>
<p>[kyero@vm02 ~]$ sudo virsh dumpxml mail<br />
...<br />
    &lt;disk type='file' device='disk'&gt;<br />
      &lt;driver name='qemu' type='raw' cache='none'/&gt;<br />
      &lt;source file='/var/boot-images/mail-boot'/&gt;<br />
      &lt;target dev='hda' bus='ide'/&gt;<br />
      &lt;address type='drive' controller='0' bus='0' unit='0'/&gt;<br />
    &lt;/disk&gt;<br />
    &lt;disk type='block' device='disk'&gt;<br />
      &lt;driver name='qemu' type='raw' cache='none'/&gt;<br />
      &lt;source dev='/dev/mapper/vg4-mail--root'/&gt;<br />
      &lt;target dev='hdb' bus='ide'/&gt;<br />
      &lt;address type='drive' controller='0' bus='0' unit='1'/&gt;<br />
    &lt;/disk&gt;<br />
    &lt;disk type='block' device='disk'&gt;<br />
      &lt;driver name='qemu' type='raw' cache='none'/&gt;<br />
      &lt;source dev='/dev/mapper/vg4-mail--swap'/&gt;<br />
      &lt;target dev='hdd' bus='ide'/&gt;<br />
      &lt;address type='drive' controller='0' bus='1' unit='1'/&gt;<br />
    &lt;/disk&gt;<br />
...<br />
</code>
</li>
<li>Boot the KVM guest<br />
<code><br />
[kyero@vm02 ~]$ sudo virsh start mail<br />
[kyero@vm02 ~]$ sudo virsh autostart mail<br />
[kyero@vm02 ~]$ sudo virsh console mail<br />
</code>
</li>
<li>Log into KVM guest, partition <code>/dev/hdd</code> and configure it as swap, update <code>/etc/fstab</code>.
</li>
</ul>
<ol class="footnotes"><li id="footnote_0_477" class="footnote"> Later we align the original root filesystem at cylinder 1 on this new disk. A LVM cylinder is roughly 8MB </li><li id="footnote_1_477" class="footnote"> File backed disk is used rather than LVM owing to grief with GRUB and LVM (<code>Error 22: No such partition</code>) </li></ol>]]></content:encoded>
			<wfw:commentRss>http://www.zomo.co.uk/2012/04/moving-disks-from-xen-to-kvm/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Directory sizes and filesystems</title>
		<link>http://www.zomo.co.uk/2012/03/directory-sizes-and-filesystems/</link>
		<comments>http://www.zomo.co.uk/2012/03/directory-sizes-and-filesystems/#comments</comments>
		<pubDate>Mon, 19 Mar 2012 04:23:37 +0000</pubDate>
		<dc:creator>lemon</dc:creator>
				<category><![CDATA[sw]]></category>

		<guid isPermaLink="false">http://www.zomo.co.uk/?p=445</guid>
		<description><![CDATA[kyero@fs02 ~/log $ du -hs . 1.7M kyero@fs02 ~/log $ ls &#124; wc -l 24 kyero@fs02 ~/log $ ls -ild . 909313 drwxr-xr-x 2 kyero kyero 1630208 Mar 19 05:25 . This log directory was allowed to grow indefinitely (ahem) until I trimmed it this morning. Now it is mostly empty (1.7MB), but the directory [...]]]></description>
				<content:encoded><![CDATA[<p><code><br />
kyero@fs02 ~/log $ du -hs .<br />
1.7M<br />
kyero@fs02 ~/log $ ls | wc -l<br />
24<br />
kyero@fs02 ~/log $ ls -ild .<br />
909313 drwxr-xr-x 2 kyero kyero 1630208 Mar 19 05:25 .<br />
</code></p>
<p>This log directory was allowed to grow indefinitely (ahem) until I trimmed it this morning. Now it is mostly empty (1.7MB), but the directory <em>entry</em> is still huge (at 1.6MB, compared to the default 4kB). I had a vague idea of why this happens but realised I was unclear on the specifics so it was time for The Learning.</p>
<p>On traditional filesystems (here, FFS on FreeBSD and ext2 on GNU/Linux) directories look much like files, just with special content. They have an inode that points to either blocks on disk or to indirection blocks that themselves point to blocks (or to other indirection blocks, up to three levels of indirection). The contents of these directory blocks are reasonably straightforward: they&#8217;re a sequence of <a href="http://en.wikipedia.org/wiki/Dirent.h"><code>dirent</code></a> structures that generally contain a filename and that file&#8217;s inode number along with some small housekeeping data.</p>
<p>As a directory fills this sequence of <code>dirent</code>s grows to fill all the direct blocks, then starts on the indirect blocks and so on. Each time the sequence crosses a block boundary the directory&#8217;s own size, rather than the total of the files it contains, grows by another block. Since filenames have variable length a single block will contain a variable number of <code>dirent</code>s.</p>
<p>So far so good. What happens you delete a file from a directory? Other than freeing the actual file&#8217;s inode and respective blocks something must happen to its <code>dirent</code> entry in the directory&#8217;s data. What doesn&#8217;t happen is that the <code>dirent</code> is removed and all the ones after it get bumped towards the front of the list, which would lead to fewer overall directory blocks given enough deletions and ultimately smaller directories.</p>
<p>Why this doesn&#8217;t happen partly relates to the guarantees that <code>telldir</code> and friends make to programs with the directory open: a file&#8217;s relative position in the sequence of <code>dirent</code> will not change for any process that has the directory open. The deletion process can&#8217;t compact the directory itself without breaking that guarantee. Both FFS and ext2 blank out the file&#8217;s inode in the <code>dirent</code> record (<a href="http://fxr.watson.org/fxr/source/fs/ext2fs/ext2_lookup.c#L923">ext2 with zero,</a> <a href="http://fxr.watson.org/fxr/source/ufs/ufs/ufs_lookup.c?im=excerpts#L1182">FFS with a special value</a>). Subsequent directory operations will ignore this blanked <code>dirent</code>, and processes which knew its sequence number via <code>telldir</code> will error if they attempt operations on it.</p>
<p>To recover the disk space used by a directory that has ballooned and then contracted its simplest to simply delete it entirely and recreate it. ext2 has an option (<code>-D</code>) in its filesystem check to compact the directory offline.</p>
<p>Interestingly this behaviour isn&#8217;t present on all filesystems, particularly those that use indexes instead of special files for directories: for example ZFS and HFS+. They can remove a file&#8217;s entry in the directory index yet still keep the remaining files appearing at their same positions by informed updates to the index.</p>
<p>Here is these four filesystem&#8217;s compared by</p>
<ul>
<li>Creating an empty directory</li>
<li>Filling it with a million files</li>
<li>Removing all but one of those files</li>
</ul>
<p>The comparison shows how on ext2 and FFS the directory itself remains at its peak size after the test files are removed, whereas ZFS and HFS+ contract.</p>
<h3>ext2</h3>
<p><code>[build@centos-x86-64-build tmp]$ df -ih .<br />
Filesystem            Inodes   IUsed   IFree IUse% Mounted on<br />
/dev/sdb                1.3M      11    1.3M    1% /mnt/tmp<br />
[build@centos-x86-64-build tmp]$ ls -ild .<br />
2 drwxr-xr-x. 3 build build 4096 Mar 19 08:58 .</p>
<p>[build@centos-x86-64-build tmp]$ seq --format 'f%06g' 0 999999 | xargs touch<br />
[build@centos-x86-64-build tmp]$ df -ih .<br />
Filesystem            Inodes   IUsed   IFree IUse% Mounted on<br />
/dev/sdb                1.3M    977K    304K   77% /mnt/tmp<br />
[build@centos-x86-64-build tmp]$ ls -ild .<br />
2 drwxr-xr-x. 3 build build 23224320 Mar 19 08:59 .</p>
<p>[build@centos-x86-64-build tmp]$ seq --format 'f%06g' 0 999998 | xargs rm<br />
[build@centos-x86-64-build tmp]$ df -ih .<br />
Filesystem            Inodes   IUsed   IFree IUse% Mounted on<br />
/dev/sdb                1.3M      12    1.3M    1% /mnt/tmp<br />
[build@centos-x86-64-build tmp]$ ls -ild .<br />
2 drwxr-xr-x. 3 build build 23224320 Mar 19 09:02 .<br />
</code></p>
<h3>FFS</h3>
<p><code>[lemon@zest ~/tmp]$ df -ih .<br />
Filesystem            Size    Used   Avail Capacity iused ifree %iused  Mounted on<br />
/dev/mirror/gm0s1a     19G     10G    7.5G    58%    587k  2.1M   22%   /<br />
[lemon@zest ~/tmp]$ ls -ild .<br />
521826 drwxr-xr-x  2 lemon  lemon  512 Mar 19 14:50 .</p>
<p>[lemon@zest ~/tmp]$ jot -w "f%06d" 1000000 0 | xargs touch<br />
[lemon@zest ~/tmp]$ df -ih .<br />
Filesystem            Size    Used   Avail Capacity iused ifree %iused  Mounted on<br />
/dev/mirror/gm0s1a     19G     10G    7.5G    58%    1.6M  1.1M   60%   /<br />
[lemon@zest ~/tmp]$ ls -ild .<br />
521826 drwxr-xr-x  2 lemon  lemon  16000512 Mar 20 01:10 .</p>
<p>[lemon@zest ~/tmp]$ jot -w "f%06d" 999999 0 | xargs rm<br />
[lemon@zest ~/tmp]$ df -ih .<br />
Filesystem            Size    Used   Avail Capacity iused ifree %iused  Mounted on<br />
/dev/mirror/gm0s1a     19G     10G    7.5G    58%    587k  2.1M   22%   /<br />
[lemon@zest ~/tmp]$ ls -ild .<br />
521826 drwxr-xr-x  2 lemon  lemon  16000512 Mar 20 01:44 .<br />
</code></p>
<h3>ZFS</h3>
<p><code>[lemon@zest /mnt/ark/tmp]$ df -ih .<br />
Filesystem    Size    Used   Avail Capacity iused ifree %iused  Mounted on<br />
ark           207G    686M    206G     0%     58k  432M    0%   /mnt/ark<br />
[lemon@zest /mnt/ark/tmp]$ ls -ild<br />
5 drwxrwsr-x  2 root  wheel  2 Mar 20 06:18 .</p>
<p>[lemon@zest /mnt/ark/tmp]$ jot -w "f%06d" 1000000 0 | xargs touch<br />
[lemon@zest /mnt/ark/tmp]$ df -ih .<br />
Filesystem    Size    Used   Avail Capacity iused ifree %iused  Mounted on<br />
ark           207G    859M    206G     0%    1.1M  432M    0%   /mnt/ark<br />
[lemon@zest /mnt/ark/tmp]$ ls -ild .<br />
5 drwxrwsr-x  2 root  wheel  1000002 Mar 20 07:53 .</p>
<p>[lemon@zest /mnt/ark/tmp]$ jot -w "f%06d" 999999 0 | xargs rm<br />
[lemon@zest /mnt/ark/tmp]$ df -ih .<br />
Filesystem    Size    Used   Avail Capacity iused ifree %iused  Mounted on<br />
ark           207G    727M    206G     0%     58k  432M    0%   /mnt/ark<br />
[lemon@zest /mnt/ark/tmp]$ ls -ild<br />
5 drwxrwsr-x  2 root  wheel  3 Mar 20 09:27 .<br />
</code></p>
<h3>HFS+</h3>
<p><code><br />
[lemon@further tmp] 0 $ df -ih .<br />
Filesystem   Size   Used  Avail Capacity  iused    ifree %iused  Mounted on<br />
/dev/disk1  233Gi  185Gi   48Gi    80% 48506927 12484688   80%   /<br />
[lemon@further tmp] 0 $ ls -ild .<br />
12149971 drwxr-xr-x  2 lemon  staff  68 19 Mar 16:06 .</p>
<p>[lemon@further tmp] 0 $ jot -w "f%06d" 1000000 0 | xargs touch<br />
[lemon@further tmp] 0 $ df -ih .<br />
Filesystem   Size   Used  Avail Capacity  iused    ifree %iused  Mounted on<br />
/dev/disk1  233Gi  185Gi   48Gi    80% 48492686 12498929   80%   /<br />
[lemon@further tmp] 0 $ ls -ild .<br />
12149971 drwxr-xr-x  2 lemon  staff  34000068 19 Mar 17:32 .</p>
<p>[lemon@further tmp] 0 $ jot -w "f%06d" 999999 0 | xargs rm<br />
[lemon@further tmp] 0 $ df -ih .<br />
Filesystem   Size   Used  Avail Capacity  iused    ifree %iused  Mounted on<br />
/dev/disk1  233Gi  185Gi   48Gi    80% 48524492 12467123   80%   /<br />
[lemon@further tmp] 0 $ ls -ild .<br />
12149971 drwxr-xr-x  2 lemon  staff  102 19 Mar 19:08 .<br />
</code></p>
]]></content:encoded>
			<wfw:commentRss>http://www.zomo.co.uk/2012/03/directory-sizes-and-filesystems/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>pf on OS X 10.7</title>
		<link>http://www.zomo.co.uk/2011/09/pf-on-os-x-10-7/</link>
		<comments>http://www.zomo.co.uk/2011/09/pf-on-os-x-10-7/#comments</comments>
		<pubDate>Wed, 14 Sep 2011 07:54:18 +0000</pubDate>
		<dc:creator>lemon</dc:creator>
				<category><![CDATA[sw]]></category>
		<category><![CDATA[10.6]]></category>
		<category><![CDATA[10.7]]></category>
		<category><![CDATA[ipfw]]></category>
		<category><![CDATA[lion]]></category>
		<category><![CDATA[osx]]></category>
		<category><![CDATA[pf]]></category>
		<category><![CDATA[snow leopard]]></category>

		<guid isPermaLink="false">http://www.zomo.co.uk/?p=423</guid>
		<description><![CDATA[Today&#8217;s the first day that my new laptop, which runs OS X 10.7 (Lion), will sit on an untrusted network so I figured it was time to port my firewall rules across from the old one, that ran OS X 10.6 (Snow Leopard). I cut my UNIX teeth at a cryptoanarchist shop whose culture of [...]]]></description>
				<content:encoded><![CDATA[<p>Today&#8217;s the first day that my new laptop, which runs OS X 10.7 (Lion), will sit on an untrusted network so I figured it was time to port my firewall rules across from the old one, that ran OS X 10.6 (Snow Leopard).</p>
<p>I cut my UNIX teeth at a cryptoanarchist shop whose culture of paranoia makes me wary of Apple&#8217;s own firewall with its emphasis on letting all the hot shinyness Just Work rather than being overly fussy about inbound connections. Furthermore, with IPv6 tunnels like <a href="http://www.sixxs.net/tools/aiccu/">aiccu</a>, you aren&#8217;t behind the warm fuzzy comfort of NAT, you&#8217;re just there on the net with all the fun that entails. So, worth having some extra protection I reckon.</p>
<p>10.6 (and earlier) came with <a href="http://www.freebsd.org/cgi/man.cgi?ipfw"><code>ipfw</code></a>, a packet filter that&#8217;s knocked around the BSD world for some time. It works but isn&#8217;t overly featuresome (for example, it doesn&#8217;t support NAT in-kernel, so you monkey about passing packets to <a href="http://www.freebsd.org/cgi/man.cgi?natd">an external daemon</a>). But it was Good Enough for an end system so I supplemented the system&#8217;s &#8220;Application Firewall&#8221; with an additional <code>ipfw</code> ruleset to give an approximation of safety when out and about, and way more permissive when on networks I trust.</p>
<p>On 10.6 I used <a href="http://www.hanynet.com/waterroof/">WaterRoof</a> to sort-of manage the <code>ipfw</code> rules: in that I only really used its <a href="http://en.wikipedia.org/wiki/Launchd">launchd</a> loader and would hack on the rules by hand. In the spirit of decrufting I figured I&#8217;d sort that myself and went to remind myself how to load <code>ipfw</code> rules enmasse. I noticed at the top of man page:<br />
<code><br />
NAME<br />
     ipfw -- IP firewall and traffic shaper control program (DEPRECATED)<br />
...<br />
DESCRIPTION<br />
     Note that use of this utility is DEPRECATED. Please use pfctl(8) instead<br />
</code></p>
<p>Deprecated? Use <code>pfctl</code> instead? <a href="http://www.zomo.co.uk/wp-content/uploads/2011/09/good-news.jpg">Good news everyone</a> &#8211; OS X 10.7 now comes with <code>pf</code>, another BSD packet filter that I&#8217;ve chosen of <code>ipfw</code> on BSD hosts for years off the back of its featureset (native NAT, state syncing between failover firewall pairs, traffic queing&#8230;).</p>
<p>Anyway, the point of this post is to point out a few things I noticed which are intriguing. Firstly, <code>pf</code> is not enabled by default. Further, Apple have added some moving parts around how it <em>is</em> enabled. From <code>/etc/pf.conf</code>:<br />
<code><br />
# This file contains the main ruleset, which gets automatically loaded<br />
# at startup.  PF will not be automatically enabled, however.  Instead,<br />
# each component which utilizes PF is responsible for enabling and disabling<br />
# PF via -E and -X as documented in pfctl(8).  That will ensure that PF<br />
# is disabled only when the last enable reference is released.<br />
</code><br />
These two flags, <code>-E</code> and <code>-X</code>, are absent from <code>pf</code> on BSD. Here&#8217;s how they&#8217;re documented on OS X:<br />
<code><br />
     -E      Enable the packet filter and increment the pf enable reference count.<br />
     -X token<br />
             Release the pf enable reference represented by the token passed.<br />
</code><br />
This suggests that different system components might choose to enable and disable <code>pf</code>, and this is the mechanism to coordinate that. There&#8217;s a clue about which components in <code>/etc/pf.anchors/com.apple</code>, which is loaded by the main <code>/etc/pf.conf</code>. It defines additional rule anchors:<br />
<code><br />
anchor "100.InternetSharing/*"<br />
anchor "200.AirDrop/*"<br />
anchor "250.ApplicationFirewall/*"<br />
</code></p>
<p>Interestingly, this host&#8217;s ApplicationFirewall has a bunch of entries in when viewed in the Preferences GUI, yet the <code>pf</code> anchor of the same name is empty (and <code>pf</code> was disabled when I started out):<br />
<code><br />
$ sudo pfctl -a com.apple/250.ApplicationFirewall -s rules<br />
Password:<br />
No ALTQ support in kernel<br />
ALTQ related functions disabled<br />
</code><br />
so I&#8217;m unsure what the status of this mechanism is. I&#8217;ve not had occasion to use AirDrop or connection sharing, but would be curious to see if either use these anchors and enable <code>pf</code> temporarily.</p>
<p>Finally, what&#8217;s the token that&#8217;s passed to <code>-X</code>? You can ask <code>pfctl</code> for the current tokens:<br />
<code><br />
$ sudo pfctl -s References<br />
No ALTQ support in kernel<br />
ALTQ related functions disabled<br />
TOKENS:<br />
PID      Process Name                 TOKEN                    TIMESTAMP<br />
17013    pfctl                        18446743524308110600     0 days 01:05:50<br />
</code><br />
I enabled <code>pf</code> with <code>pfctl</code>, so that makes sense. When I did so it didn&#8217;t inform me of the token, but I suppose an enabling process would spelunk the token shortly after enabling <code>pf</code> by merit of its name and <code>PID</code> and pass it back when it&#8217;s finished with <code>pf</code>.</p>
<p>Now, on with the actual job of ruleset writing and puzzling out the <code>launchd</code> voodoo required to enable it at boot.</p>
<p>Minor whinge: Apple could do with updating <code>/etc/protocols</code>:<br />
<code><br />
# $FreeBSD: src/etc/protocols,v 1.14 2000/09/24 11:20:27 asmodai Exp $<br />
</code><br />
Why whinge? It doesn&#8217;t know <code>icmp6</code> is a valid alias for <code>ipv6-icmp</code>. Yep, minor.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.zomo.co.uk/2011/09/pf-on-os-x-10-7/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Cyrus saslauthd and passwords containing quote marks</title>
		<link>http://www.zomo.co.uk/2011/06/cyrus-saslauthd-and-passwords-containing-quote-marks/</link>
		<comments>http://www.zomo.co.uk/2011/06/cyrus-saslauthd-and-passwords-containing-quote-marks/#comments</comments>
		<pubDate>Sat, 11 Jun 2011 15:33:06 +0000</pubDate>
		<dc:creator>lemon</dc:creator>
				<category><![CDATA[sw]]></category>

		<guid isPermaLink="false">http://www.zomo.co.uk/?p=404</guid>
		<description><![CDATA[n the back of reading how affordable and powerful GPUs make for insanely fast brute-force software (eg: whitepixel2) I recently did a round of password strengthening, even for accounts that aren&#8217;t immediately vulnerable to 30 billion MD5s a second (yes!) attacks. I then found then whenever I sent mail using authenticated SMTP my mail server [...]]]></description>
				<content:encoded><![CDATA[<p><img src="http://jhische.com/dailydropcap/O-10-cap.png" title="Daily Drop Cap by Jessica Hische" align="left" alt="O"/>n the back of reading how affordable and powerful GPUs make for insanely fast brute-force software (eg: <a href="http://blog.zorinaq.com/?e=43">whitepixel2</a>) I recently did a round of password strengthening, even for accounts that aren&#8217;t immediately vulnerable to 30 billion MD5s a second (yes!) attacks.</p>
<p>I then found then whenever I sent mail using authenticated SMTP my mail server would lock up with <code>saslauthd</code> chewing the CPU. This authentication daemon is the glue between the MTA (<a href="http://www.exim.org/">Exim</a>) and the IMAP server (<a href="http://www.courier-mta.org/imap/">Courier</a>) &#8211; it logs into the IMAP service to test the SMTP user&#8217;s credentials. This little kink of indirection comes about because the IMAP daemon is downstream from the Exim host, in a <a href="http://en.wikipedia.org/wiki/FreeBSD_jail">BSD jail</a> host, so its own authentication mechanisms aren&#8217;t visible to the MTA.</p>
<p>My new mail password contained a double-quote mark, which made me wonder if the password wasn&#8217;t being quoted properly. Testing a bit with <code>openssl</code>:<br />
<code><br />
$ openssl s_client -starttls smtp -connect localhost:25<br />
CONNECTED(00000003)<br />
---<br />
250 HELP<br />
EHLO localhost<br />
250-svc9.zomo.co.uk Hello localhost [127.0.0.1]<br />
250-SIZE 52428800<br />
250-PIPELINING<br />
250-AUTH PLAIN LOGIN<br />
250 HELP<br />
AUTH PLAIN AGZvbwAi < -- this is Base64 for username foo, password "</p>
<p>[ hang ]</p>
<p></code><br />
Compiling a </code><code>-g</code> debug variant of the daemon and aiming <code>gdb</code> at it:<br />
<code><br />
$ sudo gdb /usr/local/sbin/saslauthd-debug 97103<br />
GNU gdb 6.1.1 [FreeBSD]<br />
Copyright 2004 Free Software Foundation, Inc.<br />
...<br />
(gdb) bt<br />
#0  0x284250d1 in strchr () from /lib/libc.so.7<br />
#1  0x0804a823 in qstring ()<br />
#2  0x0804ac45 in auth_rimap ()<br />
#3  0x0804f8e3 in do_auth ()<br />
#4  0x0804e1f4 in do_request ()<br />
#5  0x0804e53b in ipc_loop ()<br />
#6  0x0805018d in main ()<br />
</code></p>
<p>What&#8217;s <code>qstring()</code>? It&#8217;s a function for escaping the quote marks in strings passed to the IMAP daemon. Turns out count-the-quotemark logic wasn&#8217;t properly advancing along the string, so it would sit there spinning forever.<br />
<script src="https://gist.github.com/1020643.js"> </script><br />
Trivial patch<sup><a href="http://www.zomo.co.uk/2011/06/cyrus-saslauthd-and-passwords-containing-quote-marks/#footnote_0_404" id="identifier_0_404" class="footnote-link footnote-identifier-link" title="Gist if it&amp;#8217;s not inlined above">1</a></sup> fixes:<br />
<code><br />
$ openssl s_client -starttls smtp -connect localhost:25<br />
CONNECTED(00000003)<br />
---<br />
250 HELP<br />
EHLO localhost<br />
250-svc9.zomo.co.uk Hello localhost [127.0.0.1]<br />
250-SIZE 52428800<br />
250-PIPELINING<br />
250-AUTH PLAIN LOGIN<br />
250 HELP<br />
AUTH PLAIN AGZvbwAi<br />
535 Incorrect authentication data<br />
</code></p>
<p>Better :)</p>
<ol class="footnotes"><li id="footnote_0_404" class="footnote"><a href="https://gist.github.com/1020643">Gist</a> if it&#8217;s not inlined above</li></ol>]]></content:encoded>
			<wfw:commentRss>http://www.zomo.co.uk/2011/06/cyrus-saslauthd-and-passwords-containing-quote-marks/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Competing webserver workloads</title>
		<link>http://www.zomo.co.uk/2011/02/competing-webserver-workloads/</link>
		<comments>http://www.zomo.co.uk/2011/02/competing-webserver-workloads/#comments</comments>
		<pubDate>Thu, 17 Feb 2011 21:57:30 +0000</pubDate>
		<dc:creator>lemon</dc:creator>
				<category><![CDATA[sw]]></category>
		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://www.zomo.co.uk/?p=363</guid>
		<description><![CDATA[Recently a client was receiving complaints that their busy server hosting both their WordPress sites and their OpenX1 banner delivery was underperforming. Specifically, sites including their banners were seeing page loads hang on them. If you&#8217;re in the business of selling banners this is bad news. There were reports of the WordPress sites being slow [...]]]></description>
				<content:encoded><![CDATA[<style type="text/css"><!--
th,td { font-size: 10px; align: center;}
li { margin-top: 0.25em; margin-right: 2em;}
.hr {margin-top: 0.25em; border-color: black; border-bottom-style: solid;}
.titre	{background: #20D0D0;color: #000000; font-weight: bold;}
.total	{background: #20D0D0;color: #ffff80;}
.frontend	{background: #e8e8d0;}
.backend	{background: #e8e8d0;}
.active0	{background: #ff9090;}
.active1	{background: #ffd020;}
.active2	{background: #ffffa0;}
.active3	{background: #c0ffc0;}
.active4	{background: #ffffa0;}
.active5	{background: #a0e0a0;}
.active6	{background: #e0e0e0;}
.backup0	{background: #ff9090;}
.backup1	{background: #ff80ff;}
.backup2	{background: #c060ff;}
.backup3	{background: #b0d0ff;}
.backup4	{background: #c060ff;}
.backup5	{background: #90b0e0;}
.backup6	{background: #e0e0e0;}
.rls      {letter-spacing: 0.2em; margin-right: 1px;}
table.tbl { border-collapse: collapse; border-style: none;}
table.tbl td { border-width: 1px 1px 1px 1px; border-style: solid solid solid solid; padding: 2px 3px; border-color: gray;}
table.tbl th { border-width: 1px; border-style: solid solid solid solid; border-color: gray;}
table.tbl th.pxname {background: #b00040; color: #ffff40; font-weight: bold; border-style: solid solid none solid; padding: 2px 3px; white-space: nowrap;}
table.tbl th.empty { border-style: none; empty-cells: hide; background: white;}
table.tbl th.desc { background: white; border-style: solid solid none solid; text-align: left; padding: 2px 3px;}
table.lgd { border-collapse: collapse; border-width: 1px; border-style: none none none solid; border-color: black;}
table.lgd td { border-width: 1px; border-style: solid solid solid solid; border-color: gray; padding: 2px;}
table.lgd td.noborder { border-style: none; padding: 2px; white-space: nowrap;}
-->
</style>
<p>Recently a client was receiving complaints that their busy server hosting both their <a href="http://wordpress.org/">WordPress</a> sites and their <a href="http://www.openx.org/">OpenX</a><sup><a href="http://www.zomo.co.uk/2011/02/competing-webserver-workloads/#footnote_0_363" id="identifier_0_363" class="footnote-link footnote-identifier-link" title=" advertising is a necessary evil, right? ">1</a></sup>  banner delivery was underperforming. Specifically, sites including their banners were seeing page loads hang on them. If you&#8217;re in the business of selling banners this is bad news. There were reports of the WordPress sites being slow too, but mostly from administrators<sup><a href="http://www.zomo.co.uk/2011/02/competing-webserver-workloads/#footnote_1_363" id="identifier_1_363" class="footnote-link footnote-identifier-link" title=" and that turned out to be a pagination issue ">2</a></sup> rather than site visitors.</p>
<p>I sorted out a bunch of <a href="http://www.zomo.co.uk/2011/01/timeouts-and-failing-fast/">request amplification issues</a> but still things still weren&#8217;t right, so I added a second server to help out. Instead of just chucking the combined traffic at both servers I used <a href="http://haproxy.1wt.eu/">HAProxy</a> to separate out the traffic to each, with a view to adding more OpenX servers as necessary.</p>
<p>Here&#8217;s what HAProxy&#8217;s stats had to say after some time running the sites split:</p>
<table class="tbl" width="100%">
<tbody>
<tr class="titre" align="center">
<th class="pxname" width="10%">wordpress</th>
</tr>
<tr class="titre" align="center">
<th rowspan="2"></th>
<th colspan="3">Queue</th>
<th colspan="3">Session rate</th>
<th colspan="5">Sessions</th>
<th colspan="2">Bytes</th>
</tr>
<tr class="titre" align="center">
<th>Cur</th>
<th>Max</th>
<th>Limit</th>
<th>Cur</th>
<th>Max</th>
<th>Limit</th>
<th>Cur</th>
<th>Max</th>
<th>Limit</th>
<th>Total</th>
<th>LbTot</th>
<th>In</th>
<th>Out</th>
</tr>
<tr class="active3" align="center">
<td>app01</td>
<td align="right">0</td>
<td align="right">0</td>
<td align="right">-</td>
<td align="right">1</td>
<td align="right">367</td>
<td align="right"></td>
<td align="right">2</td>
<td align="right">454</td>
<td align="right">-</td>
<td align="right"><span class="rls">1</span>75<span class="rls">8</span>026</td>
<td align="right"><span class="rls">1</span>75<span class="rls">8</span>026</td>
<td align="right"><span class="rls">1</span>33<span class="rls">6</span>54<span class="rls">1</span>933</td>
<td align="right">3<span class="rls">0</span>06<span class="rls">2</span>77<span class="rls">7</span>594</td>
</tr>
</tbody>
</table>
<table class="tbl" width="100%">
<tbody>
<tr class="titre" align="center">
<th class="pxname" width="10%">openx</th>
</tr>
<tr class="titre" align="center">
<th rowspan="2"></th>
<th colspan="3">Queue</th>
<th colspan="3">Session rate</th>
<th colspan="5">Sessions</th>
<th colspan="2">Bytes</th>
</tr>
<tr class="titre" align="center">
<th>Cur</th>
<th>Max</th>
<th>Limit</th>
<th>Cur</th>
<th>Max</th>
<th>Limit</th>
<th>Cur</th>
<th>Max</th>
<th>Limit</th>
<th>Total</th>
<th>LbTot</th>
<th>In</th>
<th>Out</th>
</tr>
<tr class="active3" align="center">
<td>app02</td>
<td align="right">0</td>
<td align="right">0</td>
<td align="right">-</td>
<td align="right">19</td>
<td align="right">45</td>
<td align="right"></td>
<td align="right">3</td>
<td align="right">75</td>
<td align="right">-</td>
<td align="right"><span class="rls">5</span>58<span class="rls">8</span>327</td>
<td align="right"><span class="rls">5</span>58<span class="rls">8</span>293</td>
<td align="right"><span class="rls">4</span>21<span class="rls">6</span>68<span class="rls">7</span>748</td>
<td align="right">1<span class="rls">1</span>87<span class="rls">8</span>95<span class="rls">1</span>168</td>
</tr>
</tbody>
</table>
<p>Some of these I found unsurprising &#8211; WordPress serves a higher volume of data, it is content heavy compared to banner delivery and related click handling. Conversely the inbound data volume for OpenX is up because it&#8217;s loaded with click information.</p>
<p>What&#8217;s interesting is that the WordPress sites have a higher maximum concurrent session count, yet the total sessions is far higher for the OpenX banners. This illustrates the benefit of separating out different server loads: one server is churning away pushing out fat content and even when heavily cached this burns enough resource that requests get queued and gum up, whilst another is fielding quick-in quick-out requests. When it&#8217;s not contending with its laggard sibling it can get on with its business unhindered.</p>
<p>Ultimately the visibility HAProxy affords beats an Apache <a href="http://httpd.apache.org/docs/2.2/mod/mod_status.html">scoreboard</a> when that Apache is fielding two differently focused workloads.</p>
<ol class="footnotes"><li id="footnote_0_363" class="footnote"> advertising is a necessary evil, right? </li><li id="footnote_1_363" class="footnote"> and that turned out to be a <a href="http://twitter.com/zomoco/status/32487132966686720">pagination</a> issue </li></ol>]]></content:encoded>
			<wfw:commentRss>http://www.zomo.co.uk/2011/02/competing-webserver-workloads/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
