<?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"
	>

<channel>
	<title>Rudd-O.com &#187; Linux</title>
	<atom:link href="http://rudd-o.com/archives/category/linux/feed/" rel="self" type="application/rss+xml" />
	<link>http://rudd-o.com</link>
	<description>We only do fun stuff.</description>
	<pubDate>Thu, 24 Jul 2008 20:34:45 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.6</generator>
	<language>en</language>
			<item>
		<title>Dear lazyweb: question about x86_64</title>
		<link>http://rudd-o.com/archives/2008/07/24/dear-lazyweb-question-about-x86_64/</link>
		<comments>http://rudd-o.com/archives/2008/07/24/dear-lazyweb-question-about-x86_64/#comments</comments>
		<pubDate>Thu, 24 Jul 2008 07:32:24 +0000</pubDate>
		<dc:creator>Rudd-O</dc:creator>
		
		<category><![CDATA[Linux]]></category>

		<guid isPermaLink="false">http://rudd-o.com/?p=1945</guid>
		<description><![CDATA[Dear readers: why do programs map an extra 2 MB of memory between libraries in Linux 86_64?  How can I get rid of that?  I assume this costs me big time when scheduling tasks, since find_vma is the biggest kernel CPU user according to my oprofile reports.
]]></description>
			<content:encoded><![CDATA[<p>Dear readers: why do programs map an extra 2 MB of memory between libraries in Linux 86_64?  How can I get rid of that?  I assume this costs me big time when scheduling tasks, since <code>find_vma</code> is the biggest kernel CPU user according to my oprofile reports.</p>
]]></content:encoded>
			<wfw:commentRss>http://rudd-o.com/archives/2008/07/24/dear-lazyweb-question-about-x86_64/feed/</wfw:commentRss>
		</item>
		<item>
		<title>NoMachine NX fails on Fedora 9 &#8212; here&#8217;s the solution</title>
		<link>http://rudd-o.com/archives/2008/07/20/nomachine-nx-fails-on-fedora-9-heres-the-solution/</link>
		<comments>http://rudd-o.com/archives/2008/07/20/nomachine-nx-fails-on-fedora-9-heres-the-solution/#comments</comments>
		<pubDate>Sun, 20 Jul 2008 19:27:31 +0000</pubDate>
		<dc:creator>Rudd-O</dc:creator>
		
		<category><![CDATA[Fedora]]></category>

		<category><![CDATA[Free software]]></category>

		<category><![CDATA[Linux]]></category>

		<guid isPermaLink="false">http://rudd-o.com/?p=1937</guid>
		<description><![CDATA[I am a heavy user of NoMachine NX.  After my move to Fedora 9, it fails with an error of The connection with the remote server was shut down.  Please check the state of your network connection.  The solution is simple: install the package xorg-x11-fonts-misc.  Here’s why that works:



The NX server [...]]]></description>
			<content:encoded><![CDATA[<p>I am a heavy user of NoMachine NX.  After my move to Fedora 9, it fails with an error of <q>The connection with the remote server was shut down.  Please check the state of your network connection</q>.  The solution is simple: install the package <code>xorg-x11-fonts-misc</code>.  Here’s why that works:</p>

<p><span id="more-1937"/></p>

<p>The NX server requires a font named <code>fixed</code> from the X core font subsystem when starting up.  Fedora 9 no longer has the X core font subsystem by default — they solved it by compiling <code>fixed</code> and <code>cursor</code> right into the X server.  Therefore, the X fonts package is no longer installed by default.</p>

<p>Without said fonts, the NX server fails.  Once you’ve installed them, NX works again.</p>

<p>You’re welcome.</p>
]]></content:encoded>
			<wfw:commentRss>http://rudd-o.com/archives/2008/07/20/nomachine-nx-fails-on-fedora-9-heres-the-solution/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Big win for ZFS on Linux today</title>
		<link>http://rudd-o.com/archives/2008/07/16/big-win-for-zfs-on-linux-today/</link>
		<comments>http://rudd-o.com/archives/2008/07/16/big-win-for-zfs-on-linux-today/#comments</comments>
		<pubDate>Wed, 16 Jul 2008 22:01:07 +0000</pubDate>
		<dc:creator>Rudd-O</dc:creator>
		
		<category><![CDATA[Free software]]></category>

		<category><![CDATA[Linux]]></category>

		<guid isPermaLink="false">http://rudd-o.com/?p=1934</guid>
		<description><![CDATA[ZFS through FUSE is now much faster on Linux thanks to a patch Ricardo Correia developed and I improved, against the latest code in the ZFS-FUSE repository.  Further big wins are expected soon.  Heads up: 64 bits are needed for high performance — I’m still running 32 bits so there’s lots of low-hanging [...]]]></description>
			<content:encoded><![CDATA[<p>ZFS through FUSE <a href="http://groups.google.com/group/zfs-fuse/browse_frm/thread/3393f58b221db75d/69bbb8ec2738e62a#69bbb8ec2738e62a">is now much faster on Linux</a> thanks to a patch <a href="http://zfs-fuse.googlegroups.com/web/cache-dentries.diff?gda=asJoGkQAAADdbq730B5lHM8UEAS1tBQ3RbTXWUo16thajjq948XfiGG1qiJ7UbTIup-M2XPURDTBS0dZeq_0AhD3cq2QChVJ19pBMJiXPCgyhKWF91LKHA">Ricardo Correia developed and I improved</a>, against the latest code in the ZFS-FUSE repository.  Further big wins are expected soon.  Heads up: 64 bits are needed for high performance — I’m still running 32 bits so there’s lots of low-hanging fruit to be reaped.  Here is why.</p>

<p><span id="more-1934"/></p>

<p>Why 64 instead of 32 bits?  Integer arithmetic.  <code>atomic_add_64</code>, the function in the ZFS sources that accounts for the most CPU time, is over twenty instructions of 32 bits assembler guarded by mutexes.  The same function in 64 bits is one instruction.  One.</p>
]]></content:encoded>
			<wfw:commentRss>http://rudd-o.com/archives/2008/07/16/big-win-for-zfs-on-linux-today/feed/</wfw:commentRss>
		</item>
		<item>
		<title>The document-centric and application-centric paradigms vs. streams</title>
		<link>http://rudd-o.com/archives/2008/06/24/the-document-centric-and-application-centric-paradigms-vs-streams/</link>
		<comments>http://rudd-o.com/archives/2008/06/24/the-document-centric-and-application-centric-paradigms-vs-streams/#comments</comments>
		<pubDate>Wed, 25 Jun 2008 03:17:19 +0000</pubDate>
		<dc:creator>Rudd-O</dc:creator>
		
		<category><![CDATA[Cool]]></category>

		<category><![CDATA[KDE]]></category>

		<category><![CDATA[Linux]]></category>

		<category><![CDATA[Ubuntu]]></category>

		<guid isPermaLink="false">http://rudd-o.com/archives/2008/06/24/the-document-centric-and-application-centric-paradigms-vs-streams/</guid>
		<description><![CDATA[I’d like to see the following ideas studied and implemented.  And you’re welcome to contribute to them (it’s on a wiki, after all).
]]></description>
			<content:encoded><![CDATA[<p>I’d like to see <a href="http://software-libre.rudd-o.com/Streams_vs._documents">the following ideas studied and implemented</a>.  And you’re welcome to contribute to them (it’s on a wiki, after all).</p>
]]></content:encoded>
			<wfw:commentRss>http://rudd-o.com/archives/2008/06/24/the-document-centric-and-application-centric-paradigms-vs-streams/feed/</wfw:commentRss>
		</item>
		<item>
		<title>ZFS on Linux: my story and HOWTO you can have it too</title>
		<link>http://rudd-o.com/archives/2008/06/24/zfs-on-linux-my-story-and-howto-you-can-have-it-too/</link>
		<comments>http://rudd-o.com/archives/2008/06/24/zfs-on-linux-my-story-and-howto-you-can-have-it-too/#comments</comments>
		<pubDate>Tue, 24 Jun 2008 14:45:42 +0000</pubDate>
		<dc:creator>Rudd-O</dc:creator>
		
		<category><![CDATA[Cool]]></category>

		<category><![CDATA[Linux]]></category>

		<category><![CDATA[Ubuntu]]></category>

		<guid isPermaLink="false">http://rudd-o.com/archives/2008/06/24/zfs-on-linux-my-story-and-howto-you-can-have-it-too/</guid>
		<description><![CDATA[Have you heard about ZFS?  It’s a generation-defining stable high-performance high-end filesystems, created by Jeff Bonwick at Sun, and ported over to Mac OS X and the BSD family.  Oh, and for Linux, using the FUSE (Filesystem in userspace) kernel abstraction.  Here’s my ZFS story.



I’m using Kubuntu Hardy, and my computer has [...]]]></description>
			<content:encoded><![CDATA[<p>Have you heard about ZFS?  <a href="http://opensolaris.org/os/community/zfs/docs/zfs_last.pdf">It&#8217;s a generation-defining stable high-performance high-end filesystems</a>, created by Jeff Bonwick at Sun, and ported over to Mac OS X and the BSD family.  <a href="http://zfs-on-fuse.blogspot.com/">Oh, and for Linux, using the FUSE</a> (Filesystem in userspace) kernel abstraction.  Here&#8217;s my ZFS story.</p>

<p><span id="more-1928"></span></p>

<p>I&#8217;m using Kubuntu Hardy, and my computer has two 400 GB SATA hard disks.  Yes, that&#8217;s all the storage I have at hand; as of three days ago, it was RAIDed using the multipath devices (<code>md</code>) kernel module, split in two LVM volumes: <code>/</code>and <code>/home</code>.  Oh, and two same-size byte-aligned swap partitions, one on each disk, <code>swapon</code>&#8216;ed <code>pri=0</code>.</p>

<p>I had been salivating over the thought of using ZFS in my workstation because of several killer features:</p>

<ul>
<li>The first one that comes to mind is end-to-end data integrity thanks to checksumming &#8212; I&#8217;ve already had many disks go bad on me, while others corrupted my data silently (which is, believe it or not, the most insidious thing ever, because after you&#8217;ve noticed it, backups won&#8217;t help you with that &#8212; you&#8217;ve probably already papered over your backups with new, bad data).</li>
<li>The second one is compression.  Together with tightly packed data, compression promises to increase performance and reduce disk utilization.</li>
<li>The third one is the advanced transactional algorithm that yields an always-consistent disk structure.  Unlike log-based filesystems, ZFS does copy-on-write and ripples the changes up through the filesystem tree; before the topmost node is updated, the changes don&#8217;t affect consistency; when the topmost node is updated, the disk is consistent as well.  Never <code>fsck</code> again!</li>
</ul>

<p>&#8220;Damn, gotta get me some of that, I thought&#8221;</p>

<p>Getting ZFS was actually a piece of cake:  <a href="http://www.wizy.org/wiki/ZFS_on_FUSE#head-228bbb4377ef0d3a01c17e3267f6f7a56cf7aaef">I went to the Mercurial repository for the project</a>, selected the tip view, and downloaded a nice tarball.  I then installed a couple of dependencies according to the README, and hit <code>scons</code> in a terminal window.  Five commands were built:</p>

<ul>
<li><code>zfs-fuse</code>, the daemon that serves FUSE requests.  The FUSE module is an odd beast: applications futzing with a FUSE-mounted filesystem talk to the kernel VFS, which talks to FUSE, which talks to the daemon backing that particular mount.  This userspace-kernelspace-userspace-kernelspace&#8211;userspace overhead, you will see, is a big deal.</li>
<li><code>zfs</code> and <code>zpool</code>, the main management commands that use IPC to talk to <code>zfs-fuse</code>.</li>
<li>two others that you won&#8217;t care and I won&#8217;t care either.</li>
</ul>

<p>A cursory inspection with such important system binaries was in order, so I <code>ldd</code> the daemon and the commands.  <code>zfs-fuse</code> links to <code>/usr/lib/libz*.so*</code>.  Not good, chicken and egg problem, linking to a library in a filesystem that will not be available before <code>zfs-fuse is running</code>?  I rebuild it using a modified <code>SConstruct</code> file so it statically links that library in.</p>

<p>I had decided that my filesystem layout would be:</p>

<ul>
<li>1 GB swap partition on each disk</li>
<li>1 GB <code>/</code> filesystem, composed of two RAID1 partitions (one on each disk), formatted with ext3 (in case of catastrophe, it&#8217;s nice to have something the kernel can boot without initial RAM disks)</li>
<li>398 GB ZFS volume, where I planned to drop <code>/usr</code>, <code>/home</code> and <code>/var</code></li>
</ul>

<p>But I didn&#8217;t have extra hard disks to make the switch.  No problem, <em>croupier</em>, everything I have on red please &#8212; and spin that wheel!  I installed ZFS directly on my running system.  How did I do it?  Well, if you must know:</p>

<ul>
<li>I offlined the second disk with <code>mdadm</code>.</li>
<li>I <code>swapoff</code>&#8216;ed its swap partition.  At this point the disk is no longer busy.</li>
<li>I repartitioned the disk (if the disk is non-busy, the kernel rereads the partition table just fine).</li>
<li>Then I relied on the first all the time.</li>
</ul>

<p>Yes, realtime no-boot filesystem switchover &#8212; or at least I thought it would be that easy (I was very wrong).</p>

<p>Then I <code>mkfs.ext3</code>ed the new 1 GB root filesystem, and <code>mkswap</code>&#8216;ed the swap one.  A couple of <code>rsyncs</code> later (which I scripted for consistency and repeatability), I had a new, working <code>/</code>.  I mounted it and went in it, to remove <code>mdadm.conf</code> and <code>lvm.conf</code> lines that could prove problematic on next boot.  At this point I was panicking because it was superstitiously conceivable that, after a reboot, <code>md</code> would want to rebuild the arrays and destroy the second disk.</p>

<p>I then copied the ZFS binaries in <code>/sbin</code> and ran it.  A cursory <code>lsof</code> inspection told me that the ZFS socket was on <code>/etc/zfs/zfs_socket</code>.  <code>zpool create</code> quickly gave me the 392 GB of disk space that were previously empty in the second disk, in which I created subvolumes, with adjusted mount points to end up under a temporary tree structure under <code>/newfs</code>.  Curiously, after creating a subvolume, it&#8217;s not mounted, but a <code>zfs mount -a</code> works as you probably would expect.</p>

<p>I enabled compression in the root volume (subvolumes inherit attributes) and started rsyncing <code>/var</code>, <code>/usr</code> and <code>/home</code> into each subvolume.  Cue the movie 32 hours later to have an idea of how slow it was.  It was unbelievably slow &#8212; un-frigging-believable, with both CPUs nearly pegged and regularly hovering at 150% combined user+system.  The worst part is, I was seeing disk throughput in the 2-3 MB/s range, using <code>iostat 1</code> and <code>zpool iostat 1</code>.  Keep in mind that performance (high write throughput, low responsiveness/latency during massive reads) is marketed as a ZFS selling point &#8212; and I don&#8217;t doubt the Sun guys&#8230; on Solaris, not Linux!</p>

<p>During that lengthy process I started finding out several things that would prove crucial later on:</p>

<ul>
<li>FUSE does not support <code>mmap</code> in the Linux kernel that my distribution uses.  Many, many applications rely on that feature to work.</li>
<li>There was no initscript for ZFS.  I would have to write an initscript from scratch.  On Kubuntu, where initscripts are being (1) phased out and (2) completely different to my beloved RPM distros.</li>
</ul>

<p>At this point I was a bit nervous, if you&#8217;ll allow me to understate.  But I wrote the initscript anyway:</p>

<p><pre>#! /bin/sh</pre></p>

<h3>BEGIN INIT INFO</h3>

<h1>Provides:          zfs</h1>

<h1>Required-Start:    mountall</h1>

<h1>Required-Stop:     sendsigs</h1>

<h1>Should-Start:</h1>

<h1>Should-Stop:</h1>

<h1>Default-Start:</h1>

<h1>Default-Stop:</h1>

<h1>Short-Description: Enable/disable the ZFS-FUSE subsystem</h1>

<h1>Description: Control ZFS-FUSE subsystem</h1>

<h3>END INIT INFO</h3>

<p>PIDFILE=/var/run/zfs-fuse.pid
LOCKFILE=/var/lock/zfs/zfs_lock</p>

<p>. /lib/init/vars.sh</p>

<p>. /lib/lsb/init-functions
. /lib/init/mount-functions.sh</p>

<p>export PATH=/sbin:/bin
unset LANG
ulimit -v unlimited</p>

<p>do_start() {
    test -x /sbin/zfs-fuse || exit 0
    PID=<code>cat "$PIDFILE" 2&amp;gt; /dev/null</code>
    if [ "$PID" != "" ]
    then
        if kill -0 $PID 2&gt; /dev/null
        then
            echo "ZFS-FUSE is already running"
            exit 3
        else
            # pid file is stale, we clean up shit
            log_action_begin_msg "Cleaning up stale ZFS-FUSE PID files"
            rm -f /var/run/sendsigs.omit.d/zfs-fuse "$PIDFILE"
            log_action_end_msg 0
        fi
    fi</p>

<pre><code>pre_mountall

log_action_begin_msg "Starting ZFS-FUSE process"
zfs-fuse -p "$PIDFILE"
ES_TO_REPORT=$?
if [ 0 = "$ES_TO_REPORT" ]
then
    true
else
    log_action_end_msg 1 "code $ES_TO_REPORT"
    post_mountall
    exit 3
fi

for a in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
do
    PID=`cat "$PIDFILE"`
     [ "$PID" != "" ] &amp;amp;&amp;amp; break
    sleep 1
done

if [ "$PID" = "" ]
then
    log_action_end_msg 1 "ZFS-FUSE did not start or create $PIDFILE"
    post_mountall
    exit 3
else
    log_action_end_msg 0
fi

log_action_begin_msg "Immunizing ZFS-FUSE against OOM kills and sendsigs signals"
mkdir -p /var/run/sendsigs.omit.d
cp "$PIDFILE" /var/run/sendsigs.omit.d/zfs-fuse
echo -17 &amp;gt; "/proc/$PID/oom_adj"
ES_TO_REPORT=$?
if [ 0 = "$ES_TO_REPORT" ]
then
    log_action_end_msg 0
else
    log_action_end_msg 1 "code $ES_TO_REPORT"
    post_mountall
    exit 3
fi

log_action_begin_msg "Mounting ZFS filesystems"

zfs mount -a
ES_TO_REPORT=$?
if [ 0 = "$ES_TO_REPORT" ]
then
    log_action_end_msg 0
else
    log_action_end_msg 1 "code $ES_TO_REPORT"
    post_mountall
    exit 3
fi

if [ -x /usr/bin/renice ] ; then
    log_action_begin_msg "Increasing ZFS-FUSE priority"
    /usr/bin/renice -15 -g $PID &amp;gt; /dev/null
    ES_TO_REPORT=$?
    if [ 0 = "$ES_TO_REPORT" ]
    then
        log_action_end_msg 0
    else
        log_action_end_msg 1 "code $ES_TO_REPORT"
        post_mountall
        exit 3
    fi
    true
fi

post_mountall
</code></pre>

<p>}</p>

<p>do_stop () {
    test -x /sbin/zfs-fuse || exit 0
    PID=<code>cat "$PIDFILE" 2&amp;gt; /dev/null</code>
    if [ "$PID" = "" ] ; then
        # no pid file, we exit
        exit 0
    elif kill -0 $PID 2&gt; /dev/null; then
        # pid file and killable, we continue
        true
    else
        # pid file is stale, we clean up shit
        log_action_begin_msg &#8220;Cleaning up stale ZFS-FUSE PID files&#8221;
        rm -f /var/run/sendsigs.omit.d/zfs-fuse &#8220;$PIDFILE&#8221;
        log_action_end_msg 0
        exit 0
    fi</p>

<pre><code>pre_mountall

log_action_begin_msg "Syncing disks"
sync
log_action_end_msg 0

log_action_begin_msg "Unmounting ZFS filesystems"
zfs unmount -a
ES_TO_REPORT=$?
if [ 0 = "$ES_TO_REPORT" ]
then
    log_action_end_msg 0
else
    log_action_end_msg 1 "code $ES_TO_REPORT"
    post_mountall
    exit 3
fi

post_mountall # restore /var/lock and /var/run to their right places

log_action_begin_msg "Terminating ZFS-FUSE process gracefully"
kill -TERM $PID

for a in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
do
    kill -0 $PID 2&amp;gt; /dev/null
    [ "$?" != "0" ] &amp;amp;&amp;amp; break
    sleep 1
done

if kill -0 $PID 2&amp;gt; /dev/null
then
    log_action_end_msg 1 "ZFS-FUSE refused to die after 15 seconds"
    post_mountall
    exit 3
else
    rm -f /var/run/sendsigs.omit.d/zfs-fuse "$PIDFILE"
    log_action_end_msg 0
fi

log_action_begin_msg "Syncing disks again"
sync
log_action_end_msg 0
</code></pre>

<p>}</p>

<p>case &#8220;$1&#8243; in
  start)
    do_start
    ;;
  stop)
    do_stop
    ;;
  status)
    PID=<code>cat "$PIDFILE" 2&amp;gt; /dev/null</code>
    if [ "$PID" = "" ] ; then
        echo &#8220;ZFS-FUSE is not running&#8221;
        exit 3
    else
        if kill -0 $PID
        then
            echo &#8220;ZFS-FUSE is running, pid $PID&#8221;
            zpool status
            exit 0
        else
            echo &#8220;ZFS-FUSE died, PID files stale&#8221;
            exit 3
        fi
    fi
    ;;
  restart|reload|force-reload)
    echo &#8220;Error: argument &#8216;$1&#8242; not supported&#8221; &gt;&amp;2
    exit 3
    ;;
  *)
    echo &#8220;Usage: $0 start|stop|status&#8221; &gt;&amp;2
    exit 3
    ;;
esac</p>

<p>:</p>

<p>The script should explain itself.</p>

<p>There were two problems, though.  I derived my script from the NFS one and, in the process, I discovered that NFS was symlinked to be started at slot 31 in level 6 and 0.  This means that the initscripts subsystem would call that script with a <code>start</code> argument when in reality, the action was in the <code>stop</code> block.  Since I couldn&#8217;t figure out what kind of magic the Upstart initscripts compatibility subsystem does to get a <code>stop</code> block to run when a <code>start</code> block is requested by its configuration, I just created two glue scripts: one to start ZFS no matter what, and one to stop ZFS no matter what:</p>

<p><pre>-rwxr-xr-x 1 root root 481 2008-06-18 04:09 /etc/init.d/mountzfs
-rwxr-xr-x 1 root root 488 2008-06-18 04:09 /etc/init.d/umountzfs</pre></p>

<p>Then I studied the Kubuntu boot sequence very carefully, and used some elbow grease (<code>update-rc.d</code>) to symlink them to get the results I wanted:</p>

<p><pre>lrwxrwxrwx 1 root root 19 2008-06-18 03:52 /etc/rc0.d/S35umountzfs -&gt; ../init.d/umountzfs
lrwxrwxrwx 1 root root 19 2008-06-18 03:52 /etc/rc6.d/S35umountzfs -&gt; ../init.d/umountzfs
lrwxrwxrwx 1 root root 18 2008-06-18 03:52 /etc/rcS.d/S36mountzfs -&gt; ../init.d/mountzfs</pre></p>

<p>Trust me, writing the script was the easy part &#8212; figuring out how it interacts with the rest of the system was much harder.</p>

<p>Finally, I rebooted to my new root filesystem on the second disk.  If you thought that my system booted correctly, you would be very, very wrong indeed.  Eighty percent of the boot sequence were red <code>[ fail ]</code>s and <code>sh: command not found</code> errors.  At the end, the system dropped me into a recovery console, where I could finally switch the ZFS mount points to their final destinations.  Then, just to try out: <code>zfs mount -a</code>.</p>

<p><code>/home</code>mounted.  <code>/var</code> couldn&#8217;t be mounted, because the boot process graciously created incredibly important missing directories in it.  And then, deadlock.</p>

<p>Crap, what was wrong?</p>

<p><code>Alt+SysRq+R</code>.  Boot again.  What&#8217;s wrong?  No idea.  Try <code>strace</code>.  The friggin&#8217; command is in <code>/usr</code>.  Hypotheses ran through my head for two hours.  With me in front of a very, very broken system.  I tried everything under the Sun that I could get my hands on &#8212; which is not much when you don&#8217;t have a CD-ROM drive, mind you.</p>

<p>And (summarizing two hours) then, I tried this: <code>zfs set mountpoint=/tmp/usr vault/usr ; mkdir -p /tmp/usr ; zfs mount vault/usr</code>.</p>

<p>Miracle of miracles, it worked.  I copied the entire cast of characters of Linux Debugging: The Movie into the very tightly packed <code>/</code>.  I <code>strace --ff</code>ed the hell out of <code>zfs-fuse</code> and I found the problem.  The moronic <code>mount.fuse</code> subcommand, that actually connects the kernel and user endpoints, tries to read <code>/usr/lib/locale/locale-archive</code> right in the middle of mounting the filesystem!  Instant deadlock that you can only get out of by using the SysRq OOM key (yes, <code>zfs-fuse</code> is actually a great OOM candidate &#8212; 1.5 GB VM size on this 1.0 GB RAM computer; yes, I discovered that on my own before I wrote the OOM immunization code in the initscript).</p>

<p>I then discovered two things: <code>zfs-fuse</code> didn&#8217;t deadlock when started from the recovery command, but it did lockup when starting it from the initscript.  What you can&#8217;t see is that the version of the initscript that I initially wrote was sourcing the <code>LANG</code> variable from a configuration script in <code>/etc</code>.  OK, so how do you solve locale problems?  Instant fixup: <code>unset LANG</code> before running the command.</p>

<p>OK, so do I have a booting system now, or what?  Wrong again.  Some processes get started before the actual mounting of filesystems, and the ZFS subsystem can&#8217;t actually be started earlier in the boot process without creating an <code>initramfs</code> dependency or another, different, chicken-and-egg problem.  So I moved what I could move from the ZFS volume&#8217;s <code>/var</code> into the <code>/var</code> directory of the <code>/</code> filesystem.  I ended up with this structure backed up by ZFS (and the rest, you can safely assume, in a very tightly crammed <code>ext3</code> filesystem):</p>

<p><pre>zfs list
NAME              USED  AVAIL  REFER  MOUNTPOINT
vault             294G  69,8G    18K  none
vault/home        290G  69,8G   290G  /home
vault/usr        3,36G  69,8G  3,36G  /usr
vault/var         842M  69,8G    18K  none
vault/var/cache   515M  69,8G   515M  /var/cache
vault/var/lib     282M  69,8G   282M  /var/lib
vault/var/tmp    44,5M  69,8G  44,5M  /var/tmp</pre></p>

<p>Boot again.  Oh, yeah, I&#8217;m enjoying the 3-minute boot time on this formerly-a-screamer machine.  D-Bus fails to start.  D-Bus is actually very required for many things in Kubuntu, but I manage to start a GUI session up, if only to Google up what was wrong with it.  That was probably not the best moment to find out that just starting the KDE 3.5 session took over ten minutes.  All of this with less than 1 MB/s from the disk, according to <code>iostat</code> and 160% CPU usage, according to <code>top</code>.</p>

<p>Then I discovered the <a href="http://groups.google.com/group/zfs-fuse">zfs-fuse Google group</a>.  It&#8217;s a fantastic place where everyone (including Ricardo Correia) received me very well and had lots of tips.  Only there did I find out what was wrong with D-Bus &#8212; <a href="https://bugs.launchpad.net/dbus/+bug/241619">a bug that manifests itself only with FUSE filesystems</a>, <a href="https://bugs.freedesktop.org/show_bug.cgi?id=15922">for which a patch exists</a> and works.</p>

<p>At this point I&#8217;m extremely exhausted from this marathon session, so I basically just try to backport the patch into the <code>dbus</code> source package for my distribution.  You&#8217;ve probably heard that Debian (and, by extension, Ubuntu) has a fantastic build system &#8212; it failed on me.  Not only was <code>apt</code> not working (remember the <code>mmap</code> issue?), but <a href="https://bugs.launchpad.net/ubuntu/+source/dpkg/+bug/241633"><code>dpkg-source</code> also failed while trying to apply the patches for the source package</a>.  Oh, yes, I manage to solve this problem by learning, on-the-spot, how the <code>apt</code> build &#8220;system&#8221; actually works, and manually replicating the entire process that should be automated.  Many thanks to the gents at #debian in Freenode for their kind responses to my questions.</p>

<p>Bam, built <a href="content:projects/files/dbus/">dbus (it&#8217;s yours if you want it</a>).  Installed it.  Started it.  And the chain of daemons that were depending on it just start up and take life.  Neat trick, Upstart!</p>

<p>Back to performance questions and ZFS.  Do you know what the real performance killer is?  You&#8217;ll never guess it&#8230;</p>

<p>&#8230;icons!  While GTK+ applications take marginally more time to start under a ZFS regime, KDE applications take an order of magnitude more.  Before, on a warm working set, a KDE application took about 2 seconds to start.  Today, Kmail takes in excess of five minutes to start.  Why?  <a href="post:linux-filesystems-and-fecal-encephalopathy-why-oh-why-cant-it-be-better">Here&#8217;s why</a> &#8212; multiply that by fifty thousand and you&#8217;ll get the idea.  Each icon that the application requests results in thousands and thousands of <code>access()</code> and <code>stat()</code> calls.  FUSE doesn&#8217;t use a kernel cache by default (there are several reasons for that), so the only cache that backs those requests up is the ARC cache, which is an impressive caching regime and technical achievement but, in this case, it&#8217;s very much like caching your car keys somewhere in Europe, because of the transatlantic userspace-kernelspace-userspace-kernelspace-userspace barrier.  Per-call.  When this is taking place, the CPUs remain pegged at 190%, eaten by ZFS alive, and the 12 case fans jump to 11.000 RPM.</p>

<p>The zfs-fuse Google groups guys came up with a couple of suggestions (all documented in the list, which I&#8217;m too lazy to link to again).  These all are compile-time options, so a ZFS rebuild is in order for every one of them:</p>

<ul>
<li><code>scons debug=0</code>.  A very slight CPU usage decrease.</li>
<li>Increasing the ARC cache.  I doubled it from 128 to 256 MB.  Turns out it&#8217;s not a caching problem and it doesn&#8217;t help at all.</li>
<li>Mount option <code>big_writes</code> for FUSE filesystems.  Here&#8217;s what I did about that:</li>
</ul>

<p>Recompiled ZFS, this time enabling a FUSE mount option named <code>big_writes</code> that I&#8217;ve read about in the Google group.  Yes, the daemon needs to be recompiled, and it&#8217;s not fast.  No, I&#8217;m not actually jumping to the part where I actually compiled ZFS with <code>big_writes</code> first, then booted, only to find out that I needed a new kernel.  Oh, wait, I just did.  Fortunately, I did back <code>zfs-fuse</code> up.</p>

<p>Next up?  Latest 2.6.26-rc6 kernel, because of:</p>

<ul>
<li>Hey, writable <code>mmap</code> is there for FUSE filesystems!  Yeah!  Now I can have <code>apt-get</code> back!</li>
<li><code>big_writes</code>.</li>
</ul>

<p>When was the last time a kernel compile took four hours for you?  Mine was yesterday.  But it&#8217;s actually fun &#8212; the process hasn&#8217;t changed that much from 1998, and the distro already comes with a nice <code>.config</code> that you can reuse with  <code>make oldconfig</code>.  And, this time, you get to do out-of-tree kernel builds!  Yay!</p>

<p>Well, I ticked the wrong option in <code>make menuconfig</code> anyway, because my kernel modules don&#8217;t fit my puny <code>/</code>, now at 400 MB free.  Jeez, four hours.  Google some more.  Turns out I turned a debugging option on.</p>

<p>After this, FUSE userspace itself was due for a recompile.  <a href="content:projects/files/fuse/">Another odyssey, whose fruits you can reap here</a> (warning: CVS checkout).</p>

<p>OK, redo the initial RAM disk, adjust GRUB configuration, reboot with the latest kernel.  It&#8217;s all good.  More surprisingly,  I&#8217;m actually getting some of my performance back.  Some of it.  As in &#8220;Kmail no longer takes five minutes to start &#8212; only three&#8221;.</p>

<p>And, most importantly, applications that depend on <code>mmap</code> now work correctly.  My boot process isn&#8217;t an epic <code>[ fail ]</code> anymore &#8212; and that&#8217;s incredibly reassuring.</p>

<p>This is the point where my journey turns into smooth sailing.  I <code>zpool scrub</code>ed my new baby.  After five hours, with the solid guarantee that my data was OK and nothing&#8217;d been lost or corrupted during the <code>rsync</code>, I nuked my first disk, replicated the new partition structure on it.  A nice RAID1 array for the final <code>/</code>.  A short <code>rsync</code> for the <code>/</code> filesystem.  A quick <code>mkswap</code> for the new swap partition.  A fast adjustment in <code>/etc/fstab</code> and another one in <code>mdadm.conf</code> for the new array.  Reinstall and reconfigure GRUB on the first disk.  And, finally, I leave the best for the latest:</p>

<p><code>zpool attach vault /dev/by-id/second-disk-huge-partition /dev/by-id/first-disk-huge-partition</code></p>

<p>Man, that rocked.  It was unbelievably fast &#8212; like, disk-platter fast, around 40 to 50 MB per second, and the system didn&#8217;t get that much more slow when it was resilvering the first disk.  Which kind of makes lots of sense, because <code>zfs-fuse</code> is now crossing the userspace-kernelspace barrier just once per operation.  How do I know this?  Well, <code>strace</code>: I know that what <code>zfs-fuse</code> does is, it opens the disk partition in direct I/O mode and then manages it for itself, responding to FUSE requests &#8212; but the resilvering process doesn&#8217;t involve FUSE at all, it&#8217;s just the two disks practically chatting with each other through <code>zfs-fuse</code>.  Now I know for sure that ZFS will give me platter speeds.  It&#8217;s just a matter of time (and maybe me pestering Ricardo Correia to collaborate with me on this same issue).</p>

<p>Questions that I haven&#8217;t solved yet?  Sure, there are a lot.  Two that haunt me:</p>

<ul>
<li>No root filesystem on ZFS.  Others on the Google group have managed it.  Me?  I didn&#8217;t want to mess with /etc/zfs inside the <code>initramfs</code>, thank you very much.</li>
<li>I know this for sure: the only active cache now is the userspace ARC cache from ZFS; I read the FUSE kernel code, and it clearly flushes files from the cache when programs <code>open()</code> them.  Honestly, if I could wish for something to just become true overnight, I&#8217;d wish for the ARC to be moved into the kernel and to have it replace the page cache, but that won&#8217;t happen anytime soon.  There&#8217;s a FUSE <code>kernel_cache</code> option, but I&#8217;m wary of enabling it.  When I have been sufficiently reassured that the option won&#8217;t corrupt my precious data, I will enable it.  That will be a couple of hours of reading someone else&#8217;s code, so I&#8217;m inclined to defer it for a few days.  But, in theory, this should give me platter speeds instead of giving my 12 case fans &#8217;speed&#8217;.  At the hefty cost of RAM for two redundant caches.</li>
<li>Do filesystem readahead and Linux disk scheduler algorithms mess up in some way with ZFS&#8217; control of the platter?  The data integrity question is closed, because the writes are submitted with barriers, but I&#8217;m worried that the Linux I/O scheduler is second-guessing the decisions of ZFS&#8217; one.</li>
<li>The <code>/etc/init.d/sendsigs</code> <code>omit.d</code> protocol I&#8217;m using on the initscript <a href="https://bugs.launchpad.net/ubuntu/+source/sysvinit/+bug/151580">plain fails</a>.  I had to shunt the script with an <code>exit 0</code> right before the <code>killall5</code> in <code>sendsigs</code> because <code>killall5</code> plain hung instead of ignoring ZFS as it should have done &#8212; and it needs to ignore ZFS because ZFS is unmounted later.  <a href="http://blogs.sun.com/bonwick/en_US/entry/casablanca">This won&#8217;t be a problem once we get our own kernelspace ZFS implementation</a>.</li>
</ul>

<p>OK, that was my journey.  I&#8217;m on ZFS now, my machine&#8217;s rock-solid (if a bit CPU-tired) and my data&#8217;s never been so safe.  I also got compression, which saved me about 6 GB.  Furthermore, I&#8217;ve given you the initscript, the steps and <a href="content:projects/files/dbus/">the</a> <a href="content:projects/files/dbus/">software</a> (except ZFS, but you can compile that yourself).</p>

<p>Go wild.</p>
]]></content:encoded>
			<wfw:commentRss>http://rudd-o.com/archives/2008/06/24/zfs-on-linux-my-story-and-howto-you-can-have-it-too/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Filesystems vs. fecal encephalopathy in Linux applications &#8212; why, oh why, can&#8217;t it be better?</title>
		<link>http://rudd-o.com/archives/2008/06/19/linux-filesystems-and-fecal-encephalopathy-why-oh-why-cant-it-be-better/</link>
		<comments>http://rudd-o.com/archives/2008/06/19/linux-filesystems-and-fecal-encephalopathy-why-oh-why-cant-it-be-better/#comments</comments>
		<pubDate>Thu, 19 Jun 2008 13:24:59 +0000</pubDate>
		<dc:creator>Rudd-O</dc:creator>
		
		<category><![CDATA[Linux]]></category>

		<category><![CDATA[Sucks!]]></category>

		<category><![CDATA[Ubuntu]]></category>

		<guid isPermaLink="false">http://rudd-o.com/archives/2008/06/19/linux-filesystems-and-fecal-encephalopathy-why-oh-why-cant-it-be-better/</guid>
		<description><![CDATA[Look, I’m a fan of Linux.  But nothing can excuse the stupid behavior of KDE applications under Kubuntu:



What you’re about to see is just a twenty-line snippet representing standard pathological behavior of a widely used KDE application that comes with Kubuntu.  I’m at a loss of words, because what you’re about to see [...]]]></description>
			<content:encoded><![CDATA[<p>Look, I’m a fan of Linux.  But <strong>nothing</strong> can excuse the stupid behavior of KDE applications under Kubuntu:</p>

<p><span id="more-1927"/></p>

<p>What you’re about to see is just a twenty-line snippet representing standard pathological behavior of a widely used KDE application that comes with Kubuntu.  I’m at a loss of words, because what you’re about to see repeats itself (I kid you not) <strong>at least a twenty thousand times</strong>:</p>

<p><pre>access("/usr/share/icons/crystalproject/24x24/devices/mail_todo.xpm", R_OK) = -1 ENOENT (No such file or directory)
access("/usr/share/icons/crystalproject/24x24/filesystems/mail_todo.xpm", R_OK) = -1 ENOENT (No such file or directory)
access("/usr/share/icons/crystalproject/24x24/filesystems/mail_todo.xpm", R_OK) = -1 ENOENT (No such file or directory)
access("/usr/share/icons/crystalproject/24x24/mimetypes/mail_todo.xpm", R_OK) = -1 ENOENT (No such file or directory)
access("/usr/share/icons/crystalproject/24x24/mimetypes/mail_todo.xpm", R_OK) = -1 ENOENT (No such file or directory)
access("/usr/share/icons/crystalproject/32x32/actions/mail_todo.xpm", R_OK) = -1 ENOENT (No such file or directory)
access("/usr/share/icons/crystalproject/32x32/actions/mail_todo.xpm", R_OK) = -1 ENOENT (No such file or directory)
access("/usr/share/icons/crystalproject/32x32/apps/mail_todo.xpm", R_OK) = -1 ENOENT (No such file or directory)
access("/usr/share/icons/crystalproject/32x32/apps/mail_todo.xpm", R_OK) = -1 ENOENT (No such file or directory)
access("/usr/share/icons/crystalproject/32x32/devices/mail_todo.xpm", R_OK) = -1 ENOENT (No such file or directory)
access("/usr/share/icons/crystalproject/32x32/devices/mail_todo.xpm", R_OK) = -1 ENOENT (No such file or directory)
access("/usr/share/icons/crystalproject/32x32/filesystems/mail_todo.xpm", R_OK) = -1 ENOENT (No such file or directory)
access("/usr/share/icons/crystalproject/32x32/filesystems/mail_todo.xpm", R_OK) = -1 ENOENT (No such file or directory)
access("/usr/share/icons/crystalproject/32x32/mimetypes/mail_todo.xpm", R_OK) = -1 ENOENT (No such file or directory)</pre></p>

<p>Now, let me ask you: <strong>what kind of engineering is this?</strong>  <q>Oh, I’ll just look for the icon named mail_todo of types XPM, SVG, SVGZ, PNG, JPG across thousands of directories and if I can’t find it, I just won’t draw it</q>.</p>

<p>Modern desktop environments package all that shit up in a single icon cache and use <code>mmap</code> to quickly find it.  Well, <em>guess again, loser who invented that band-aid</em>.  I’m using a filesystem that doesn’t support <code>mmap</code>.  Now my filesystem has to consume inordinate amounts of CPU to find each one of those two hundred icons your application uses, because you couldn’t find a better algorithm to find the motherfucking icon.</p>

<p>Oh, by the way, every time I delete an e-mail from KMail’s listing, the entire process is repeated again.  I guess I can safely omit the part where Kicker (the panel) and Kopete all do the same things for each icon that they display.  Woops, I didn’t omit it.</p>

<p>Just another tale of living in the bleeding edge of Linux computing.</p>

<p><em>In the interest of full disclosure: I’m using the CPU-heavy <a href="http://groups.google.com/group/zfs-fuse/">ZFS</a> filesystem from <a href="http://www.sun.com/">Sun</a>.  I’m testing it because it offers <a href="http://opensolaris.org/os/community/zfs/docs/zfs_last.pdf">unsurpassed reliability</a>.  Yes, it’s CPU-heavy.  Yes, it runs through FUSE.  But that’s not the point — the point is that this wouldn’t matter if KDE apps (and, I’m sure, many others as well) wouldn’t suck so much to find a motherfucking icon.  After the latest <a href="http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git">torvalds kernel recompile</a> and another ZFS recompile for performance (which failed), I have gained quite a lot of performance: now KMail doesn’t take 10 minutes to launch — it only takes four.  On a dual-core Xeon, with 1 GB RAM and 7200 RPM dual platters.  Four motherfucking minutes.  I now fully agree with Cox when he said userspace does stupid things.</em></p>
]]></content:encoded>
			<wfw:commentRss>http://rudd-o.com/archives/2008/06/19/linux-filesystems-and-fecal-encephalopathy-why-oh-why-cant-it-be-better/feed/</wfw:commentRss>
		</item>
		<item>
		<title>The history meme</title>
		<link>http://rudd-o.com/archives/2008/04/15/the-history-meme/</link>
		<comments>http://rudd-o.com/archives/2008/04/15/the-history-meme/#comments</comments>
		<pubDate>Tue, 15 Apr 2008 19:14:16 +0000</pubDate>
		<dc:creator>Rudd-O</dc:creator>
		
		<category><![CDATA[Linux]]></category>

		<category><![CDATA[Tips]]></category>

		<category><![CDATA[Yo]]></category>

		<guid isPermaLink="false">http://rudd-o.com/archives/2008/04/15/the-history-meme/</guid>
		<description><![CDATA[Since it’s been around my corners of the Internets, I guess it’s time for me to post this meme as well:



rudd-o@karen: ~ $
history | awk '{a[$2]++}END{for(i in a){print a[i] " " i}}' | sort -rn | head
76 cd
38 mv
36 svn
34 python
31 rm
30 ls
19 git
14 dpkg
14 aptitude
13 find

Please note: I have history set up so it [...]]]></description>
			<content:encoded><![CDATA[<p>Since it&#8217;s been around my corners of the Internets, I guess it&#8217;s time for me to post this meme as well:</p>

<p><span id="more-1897"></span></p>

<p><pre>rudd-o@karen: ~ $
history | awk '{a[$2]++}END{for(i in a){print a[i] " " i}}' | sort -rn | head
76 cd
38 mv
36 svn
34 python
31 rm
30 ls
19 git
14 dpkg
14 aptitude
13 find</pre></p>

<p>Please note: I have history set up so it doesn&#8217;t record repeated commands.  So this count is a count of unique, different commands each.</p>

<p>Want the <code>graphwatch</code> version?  Here it is:</p>

<p><pre>cd 70 #################################################
      mv 36 #########################
  python 34 #######################
     svn 32 ######################
      rm 29 ####################
      ls 29 ####################
     git 16 ###########
    dpkg 14 #########
aptitude 14 #########
    nano 13 #########</pre></p>

<p>Here&#8217;s what I did to generate that graph:</p>

<ol>
<li><code>history &gt; x</code></li>
<li><code>graphwatch 'cat x | awk '\''{a[$2]++}END{for(i in a){print a[i] &#8221; &#8221; i}}&#8217;\&#8221; | sort -rn | head | awk &#8216;\&#8221; { print $2 &#8221; &#8221; $1 } &#8216;\&#8221;&#8217; &#8221; &#8220;</code></li>
</ol>

<p><code>graphwatch</code> is a nice Python script that takes a properly quoted shell pipeline that will be run through <code>bash</code> and a field separator (in this case, a sngle empty space).  My extra <code>awk</code> invocation there swaps the first and second fields so the first column is the label, and the second column is the value &#8212; <code>graphwatch</code> plots a nice set of proportional horizontal bars.</p>

<p>But that&#8217;s not it.  The command is run once every second, so if the contents of the file <code>x</code> (or the output of the supplied command) change, the graph is re-plotted.  Very nifty to watch tabular numeric output in graphical form, in real-time &#8212; imagine using it with iostat and you&#8217;ll get the idea.</p>

<p>Here&#8217;s the code.  I will release it as a proper package with enhancements (it&#8217;s a quick hack right now) later on:</p>

<p><pre>#!/usr/bin/env python</pre></p>

<p>from time import sleep
from subprocess import PIPE,Popen
from sys import argv,exit,stdout
import os</p>

<p>try:
    cmd = argv[1]
    sep = argv[2]
except IndexError, e:
    print "usage: graphwatch 'shell pipeline' 'separator'"
    exit(os.EX_USAGE)
print "Running this command in a shell:"
print "&gt;", cmd</p>

<p>def getstdout(cmdline):
    p = Popen(["bash","-c",cmdline],stdout=PIPE)
    output = p.communicate()[0]
    if p.returncode != 0: raise Exception, "Command %s return code %s"%(cmdline,p.returncode)
    return output</p>

<p>try:
    while True:</p>

<pre><code>    output = getstdout(cmd).strip()
    stdout.write(getstdout("clear"))

    labels = []
    values = []
    for l in output.splitlines():
        try:
            label,value= l.strip().split(sep,1)
            label,value = label.strip(),value.strip()
        except ValueError, e: label,value = None,l.strip()
        labels.append(label)
        try: values.append(float(value))
        except ValueError, e: values.append(0.0)

    try:
        maximum_value = max(values + [maximum_value] )
    except NameError, e:
        maximum_value = max(values)

    try:
        longest_label = max( [len(l) for l in labels if l is not None ] )
        label_fmt = "%" + str(longest_label) + "s"
    except ValueError, e:
        longest_label = -1 # to compensate for the extra -2 below
        pass # nothing will happen later

    longest_number = max( [ len(str(int(i))) for i in values if type(i) is float ] )
    number_fmt = "%" + str(longest_number) + ".0f"

    column_width = 61
    leftover_for_plot = column_width - longest_label - longest_number - 2


    for value,label in zip(values,labels):
        if label is not None:
            print label_fmt%label,
        print number_fmt%value,
        print "#"*int(value/maximum_value*leftover_for_plot)

    sleep(1)
</code></pre>

<p>except KeyboardInterrupt, e:
    exit(0)</p>
]]></content:encoded>
			<wfw:commentRss>http://rudd-o.com/archives/2008/04/15/the-history-meme/feed/</wfw:commentRss>
		</item>
		<item>
		<title>dpkg is braindead.  Jason, you&#8217;re wrong.</title>
		<link>http://rudd-o.com/archives/2008/04/13/dpkg-is-braindead-jason-youre-wrong/</link>
		<comments>http://rudd-o.com/archives/2008/04/13/dpkg-is-braindead-jason-youre-wrong/#comments</comments>
		<pubDate>Mon, 14 Apr 2008 03:45:30 +0000</pubDate>
		<dc:creator>Rudd-O</dc:creator>
		
		<category><![CDATA[Linux]]></category>

		<category><![CDATA[Sucks!]]></category>

		<category><![CDATA[Ubuntu]]></category>

		<guid isPermaLink="false">http://rudd-o.com/archives/2008/04/13/dpkg-is-braindead-jason-youre-wrong/</guid>
		<description><![CDATA[Jason, you said in your post something that left me thinking:



Proposed solution: make PackageKit do exactly what synaptic has been doing for the past three years: when a package install process blocks on file descriptor 0, unhide a hidden VTE widget. As it stands now, none of the publicly facing Ubuntu or Debian PacketKit pages [...]]]></description>
			<content:encoded><![CDATA[<p>Jason, <a href="http://jasondclinton.livejournal.com/65533.html">you said in your post something that left me thinking</a>:</p>

<p><span id="more-1895"/></p>

<blockquote>Proposed solution: make PackageKit do exactly what synaptic has been doing for the past three years: when a package install process blocks on file descriptor 0, unhide a hidden VTE widget. As it stands now, none of the publicly facing Ubuntu or Debian PacketKit pages have proposed any other solution to the problem, and it appears there’s no other proposed solution on the mailing list. (Take care to note that this has nothing to do with debconf.)</blockquote>

<p>I absolutely disagree with you.&nbsp; This goddamned practice of letting packages interrupt the upgrade process willy-nilly on the packager’s whim is idiotic and should have dealt with years ago (preferably with death by fire).&nbsp; Don’t tell me that the Debian project had a breakthrough invention when they “invented” the “hey, let’s interrupt package installation to ask the user a dpkg-configure question or to run a postinstall script”.  That is not a breakthrough; it’s a practice that should have long been abandoned.</p>

<p>The reason why dpkg has this brain damage is pretty clear: the installation/upgrade process and the post-install configuration process aren’t clearly separated.  It boils down to a single question: it’s fine by me if you want to include a package that needs extra user input for configuration — so, why don’t you ask me for the configuration at first-run time, and ship a package with sane defaults?</p>

<p>The RPM take on this issue has a huge advantage: by limiting user interaction during upgrades/installations, it forces packagers to distribute sanely preconfigured packages.  That’s the reason you can install Dovecot, Postfix, and SquirrelMail on Fedora, and have a working mail server right out of the box — save, perhaps, for changing the listening interface setting on the Postfix configuration file.</p>

<p>The Debian way, on the other hand, creates a moral incentive for the packager to punt configuration questions to the user.  Honestly, you can’t expect end-users to interact with a shell.  The minute I show my dad a Synaptic VTE question, is the minute my dad stops using Linux.</p>

<p>This is one of the things that suck big time in dpkg.  RPM-based distros don’t have this problem.  On Fedora, I can make an unattended upgrade and it will work 100% of the time, knowing that the configuration files won’t be replaced but I will have a way to diff those configuration files.  Not so with Ubuntu.  Not so with Debian.  I’m being candid here: I’ve had to answer tens of questions after a Debian dist-upgrade.  I’ve never had to answer a single question after a <code>smart upgrade</code>.  Yes, I know I could tell dpkg-configure not to ask me questions, but I wonder when Debian will default to that behavior.</p>

<p>What’s more, the RPM way has a fantastic consequence: upgrades are fully transactional.  You can’t make a transactional upgrade if you’re interrupting the upgrade process by opening <code>stdin</code> to ask bullshit questions or other hackery.  Honest, the need to run <code>apt-get -f install</code> bullshit is something I’ve never, ever in my life experienced with Fedora’s or Red Hat’s RPM.  And it’s a weekly fucking occurrence in Ubuntu!</p>

<p>Just now, I had temporarily turned Nagios2 off with <code>/etc/init.d/nagios2 stop</code>, and the goddamned <code>apt-get -f install</code> won’t finish because it insists on dpkg-configuring Nagios2, and the dpkg-configure process fails because it attempts to shut down Nagios2 and that fails, leaving my system in a circle-jerk of partial configuredness, that I wouldn’t know how to fix if I didn’t have ten years of Linux experience.</p>

<p>Oh, and for the record, the other reasons are:</p>

<ol>
<li>You can’t have two versions of the package with the same name installed in the system (I have visited this argument before).  Not very used in the RPM world either, but I have put that use into practice.</li>
<li>You can’t do an <code>rpm -Va</code>, and have dpkg check for permissions, dates, times, and file sizes/sums.  What the hell were the dpkg developers thinking?  This is practically the first thing I use to audit a server right before I take it under my wing, just to get a clear idea of what the people before me did with it.</li>
<li>When you remove a package with dpkg, the configuration files remain unless you purge it.  Why can’t dpkg do like RPM — erasing configuration files unless they were modified by the user?  Two different remove operations are one too many.</li>
<li><a href="http://rudd-o.com/archives/2008/01/04/a-short-rant-on-ubuntu-and-dpkg-fuck-you-dpkg/" title="A short rant on Ubuntu and dpkg: fuck you, dpkg">dpkg happily lets you destroy your system</a>.</li>
</ol>

<p>And, quoting you:</p>

<blockquote>This has the added benefit of making it possible for any user on any distro. to unhide the VTE window when something goes wrong–and we all know that something goes wrong with package managers all the time.</blockquote>

<p>I dunno about your experiences with Red Hat or Fedora, but when I use a GUI package manager on Fedora, and something goes wrong, what I’m interested in is the output of <code>stderr</code>.  All GUI package managers neatly show these messages nowadays.  And I rarely see any error dialog box with <code>stderr</code> contents.  So don’t start with the “something goes wrong with package managers all the time” bullshit.</p>

<p>So, let’s amend your last paragraph: let’s make PackageKit redirect <code>/dev/null</code> into the dpkg subprocess.  That should take care of things neatly, and screw all braindead packages out there.  What’s more, if the package somehow refuses to continue installing, let’s send dpkg a SIGKILL after a while, then prompt the user to change to a non-braindead distribution.  So PackageKit doesn’t support your favorite brain damaged behavior?  Sucks to be you.</p>

<p>Jeez, how much more of this obsolescent crap and stupid policy do we have to swallow, just because it’s the policy of the most widely used distro?  I thought open source and free software were about meritocracy, not the tyranny of the majority.  And I wish that the portion of the brain of the developer that conceived this “installation is interruptible” brain damage would just necrotize thanks to an aneurysm.</p>
]]></content:encoded>
			<wfw:commentRss>http://rudd-o.com/archives/2008/04/13/dpkg-is-braindead-jason-youre-wrong/feed/</wfw:commentRss>
		</item>
		<item>
		<title>The latest PulseAudio on Ubuntu</title>
		<link>http://rudd-o.com/archives/2008/01/05/the-latest-pulseaudio-on-ubuntu/</link>
		<comments>http://rudd-o.com/archives/2008/01/05/the-latest-pulseaudio-on-ubuntu/#comments</comments>
		<pubDate>Sat, 05 Jan 2008 16:56:40 +0000</pubDate>
		<dc:creator>Rudd-O</dc:creator>
		
		<category><![CDATA[Linux]]></category>

		<category><![CDATA[Software bacán]]></category>

		<category><![CDATA[Tips]]></category>

		<category><![CDATA[Ubuntu]]></category>

		<guid isPermaLink="false">http://rudd-o.com/archives/2008/01/05/the-latest-pulseaudio-on-ubuntu/</guid>
		<description><![CDATA[If you want to install the latest and greatest PulseAudio (now on version 0.9.8) on Ubuntu — a worthwhile thing to do, because of the fixes in the latest version — here are some packages you can use.



These packages are built from the source code of the next release of Ubuntu, Hardy.  They work [...]]]></description>
			<content:encoded><![CDATA[<p>If you want to install the latest and greatest <a href="http://pulseaudio.org/">PulseAudio</a> (now on version 0.9.8) on Ubuntu — a worthwhile thing to do, because of the fixes in the latest version — here are some packages you can use.</p>

<p><span id="more-1851"/></p>

<p>These packages are built from the source code of the next release of Ubuntu, Hardy.  They work flawlessly on my home machines (yes, plural).  I built these packages myself for my usage:</p>

<ul>
<li><a href="http://rudd-o.com/wp-content/uploads/pulseaudio-0.9.8/libpulse-browse0_0.9.8-1ubuntu3_i386.deb">libpulse-browse0_0.9.8-1ubuntu3_i386.deb</a></li>
<li><a href="http://rudd-o.com/wp-content/uploads/pulseaudio-0.9.8/libpulse-mainloop-glib0_0.9.8-1ubuntu3_i386.deb">libpulse-mainloop-glib0_0.9.8-1ubuntu3_i386.deb</a></li>
<li><a href="http://rudd-o.com/wp-content/uploads/pulseaudio-0.9.8/libpulse0_0.9.8-1ubuntu3_i386.deb">libpulse0_0.9.8-1ubuntu3_i386.deb</a></li>
<li><a href="http://rudd-o.com/wp-content/uploads/pulseaudio-0.9.8/libpulsecore5_0.9.8-1ubuntu3_i386.deb">libpulsecore5_0.9.8-1ubuntu3_i386.deb</a></li>
<li><a href="http://rudd-o.com/wp-content/uploads/pulseaudio-0.9.8/pulseaudio-esound-compat_0.9.8-1ubuntu3_i386.deb">pulseaudio-esound-compat_0.9.8-1ubuntu3_i386.deb</a></li>
<li><a href="http://rudd-o.com/wp-content/uploads/pulseaudio-0.9.8/pulseaudio-module-gconf_0.9.8-1ubuntu3_i386.deb">pulseaudio-module-gconf_0.9.8-1ubuntu3_i386.deb</a></li>
<li><a href="http://rudd-o.com/wp-content/uploads/pulseaudio-0.9.8/pulseaudio-module-hal_0.9.8-1ubuntu3_i386.deb">pulseaudio-module-hal_0.9.8-1ubuntu3_i386.deb</a></li>
<li><a href="http://rudd-o.com/wp-content/uploads/pulseaudio-0.9.8/pulseaudio-module-lirc_0.9.8-1ubuntu3_i386.deb">pulseaudio-module-lirc_0.9.8-1ubuntu3_i386.deb</a></li>
<li><a href="http://rudd-o.com/wp-content/uploads/pulseaudio-0.9.8/pulseaudio-module-x11_0.9.8-1ubuntu3_i386.deb">pulseaudio-module-x11_0.9.8-1ubuntu3_i386.deb</a></li>
<li><a href="http://rudd-o.com/wp-content/uploads/pulseaudio-0.9.8/pulseaudio-module-zeroconf_0.9.8-1ubuntu3_i386.deb">pulseaudio-module-zeroconf_0.9.8-1ubuntu3_i386.deb</a></li>
<li><a href="http://rudd-o.com/wp-content/uploads/pulseaudio-0.9.8/pulseaudio-utils_0.9.8-1ubuntu3_i386.deb ">pulseaudio-utils_0.9.8-1ubuntu3_i386.deb </a></li>
<li><a href="http://rudd-o.com/wp-content/uploads/pulseaudio-0.9.8/pulseaudio_0.9.8-1ubuntu3_i386.deb">pulseaudio_0.9.8-1ubuntu3_i386.deb</a></li>
</ul>

<p>Download them all in a folder, then just open a terminal window there and type:</p>

<p><pre>sudo dpkg -i *deb</pre></p>

<p>That should upgrade you to the latest PulseAudio.  I was gonna write a tutorial, but then you would have had to download hundreds of megabytes of development packages.</p>
]]></content:encoded>
			<wfw:commentRss>http://rudd-o.com/archives/2008/01/05/the-latest-pulseaudio-on-ubuntu/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Hola a Planeta Ubuntu.ec</title>
		<link>http://rudd-o.com/archives/2008/01/05/hola-a-planeta-ubuntuec/</link>
		<comments>http://rudd-o.com/archives/2008/01/05/hola-a-planeta-ubuntuec/#comments</comments>
		<pubDate>Sat, 05 Jan 2008 16:46:48 +0000</pubDate>
		<dc:creator>Rudd-O</dc:creator>
		
		<category><![CDATA[Linux]]></category>

		<category><![CDATA[Mi weblog]]></category>

		<category><![CDATA[Ubuntu]]></category>

		<category><![CDATA[Yo]]></category>

		<guid isPermaLink="false">http://rudd-o.com/archives/2008/01/05/hola-a-planeta-ubuntuec/</guid>
		<description><![CDATA[Muy aparte de que estoy muy contento por el crecimiento de Ubuntu en nuestra comunidad, también estoy orgulloso de aparecer en planeta.Ubuntu.ec.  Hola con todos aquí!  Mi nombre es Manuel Amador, y escribo sobre tecnología — particularmente, sobre Linux.  Espero mis artículos los entretengan — visítenme y subscríbanse!
]]></description>
			<content:encoded><![CDATA[<p>Muy aparte de que estoy muy contento por el crecimiento de Ubuntu en nuestra comunidad, también estoy orgulloso de aparecer en <a href="http://planeta.ubuntu.ec/">planeta.Ubuntu.ec</a>.  Hola con todos aquí!  Mi nombre es Manuel Amador, y escribo sobre tecnología — particularmente, sobre Linux.  Espero mis artículos los entretengan — <a href="http://rudd-o.com/">visítenme</a> y subscríbanse!</p>
]]></content:encoded>
			<wfw:commentRss>http://rudd-o.com/archives/2008/01/05/hola-a-planeta-ubuntuec/feed/</wfw:commentRss>
		</item>
		<item>
		<title>A short rant on Ubuntu and dpkg: fuck you, dpkg</title>
		<link>http://rudd-o.com/archives/2008/01/04/a-short-rant-on-ubuntu-and-dpkg-fuck-you-dpkg/</link>
		<comments>http://rudd-o.com/archives/2008/01/04/a-short-rant-on-ubuntu-and-dpkg-fuck-you-dpkg/#comments</comments>
		<pubDate>Fri, 04 Jan 2008 23:04:10 +0000</pubDate>
		<dc:creator>Rudd-O</dc:creator>
		
		<category><![CDATA[Fedora]]></category>

		<category><![CDATA[Linux]]></category>

		<category><![CDATA[RPM]]></category>

		<category><![CDATA[Ubuntu]]></category>

		<guid isPermaLink="false">http://rudd-o.com/archives/2008/01/04/a-short-rant-on-ubuntu-and-dpkg-fuck-you-dpkg/</guid>
		<description><![CDATA[A long long time ago, in a gal… in an older computer, I had Fedora.  RPM — the packaging system in Fedora — was amazing in several aspects.  And the aspect that continually amazed me was the transactionality of software installs: a set of packages either gets installed, or it doesn’t.  No [...]]]></description>
			<content:encoded><![CDATA[<p>A long long time ago, in a gal… in an older computer, I had Fedora.  RPM — the packaging system in Fedora — was amazing in several aspects.  And the aspect that continually amazed me was the transactionality of software installs: a set of packages either gets installed, or it doesn’t.  No halfway installs, no broken shit.  Ever.</p>

<p><span id="more-1849"/></p>

<p>Fast-forward to my contemporary Kubuntu system. I just installed (using <code>dpkg -i</code>) a series of packages, and dpkg happily unpacked them all on my filesystem, only to nonchalantly tell me — when the files were already replaced on my (now very broken) computer — that it could not configure these packages, because the version of my C library is too old.</p>

<p><strong>With the new files are already on my system!  A tad too late to blow up on my face, isn’t it?</strong>  Now I have a badly broken system, and I can’t back out without resorting to manually downloading and installing old packages.</p>

<p>Question to the dpkg developers: <em>If the version of my C library is too fucking old — and dpkg knows this fact — why the fuck does dpkg proceed with file installation, only to barf in the middle of the installation process, leaving me with a broken computer?</em>  <strong>If the dependencies don’t fucking fit, don’t fucking let me install the packages in the first place!</strong></p>

<p>It’s not like transactional package installation is rocket science to get right, is it?  Otherwise, how did the RPM guys figure this out so well?</p>

<p>In b4 “dpkg is not like RPM” comments:</p>

<ol>
<li>Software installation transactionality is an elementary requirement of contemporary systems, so get your damn act together and make dpkg like RPM with regards to this issue.</li>
<li>Even better: ask yourselves the following question: in what universe is this dpkg behavior (namely, enabling users to badly break their systems) a good thing?</li>
</ol>

<p>And, please, let me rant some more, this time on the topic of package dependencies.  Why does a simple 100 KB program from Hardy require me to upgrade my <em>system C library</em> (hence, my entire operating system) to Hardy?  I thought glibc hadn’t changed in years!  I hardly doubt that 100 KB program would have any trouble running if I unpacked the binary directly!  So why does the package builder automatically require the latest version of the library — forcing me to download gigabytes of packages — when an old one would work just as well?</p>

<p>I’m a sysadmin, for fuck’s sake, I want my computer to be easily manageable, not harder to manage.  What are you waiting for?</p>
]]></content:encoded>
			<wfw:commentRss>http://rudd-o.com/archives/2008/01/04/a-short-rant-on-ubuntu-and-dpkg-fuck-you-dpkg/feed/</wfw:commentRss>
		</item>
		<item>
		<title>A primer into software package management using RPM</title>
		<link>http://rudd-o.com/archives/2007/11/14/a-primer-into-software-package-management-using-rpm/</link>
		<comments>http://rudd-o.com/archives/2007/11/14/a-primer-into-software-package-management-using-rpm/#comments</comments>
		<pubDate>Wed, 14 Nov 2007 18:29:45 +0000</pubDate>
		<dc:creator>Rudd-O</dc:creator>
		
		<category><![CDATA[Linux]]></category>

		<category><![CDATA[RPM]]></category>

		<category><![CDATA[Tutorials]]></category>

		<guid isPermaLink="false">http://rudd-o.com/archives/2007/11/14/a-primer-into-software-package-management-using-rpm/</guid>
		<description><![CDATA[Since apparently my last article ignited a small flamewar, let’s talk a bit about package management in RPM-based distros.  Yeah, Fedora, Red Hat, SuSE, Mandrake, those.  And when I say package management, all I mean is software installation, really.



This will be a command-line tutorial-style article, and we’re gonna get down to basics, so [...]]]></description>
			<content:encoded><![CDATA[<p>Since apparently <a href="http://rudd-o.com/archives/2007/11/14/i-dunno-what-people-say-when-they-talk-about-rpm-hell/" title="I dunno what people mean when they talk about RPM hell">my last article ignited a small flamewar</a>, let’s talk a bit about package management in RPM-based distros.  Yeah, Fedora, Red Hat, SuSE, Mandrake, those.  And when I say package management, all I mean is software installation, really.</p>

<p><span id="more-1819"/></p>

<p>This will be a command-line tutorial-style article, and we’re gonna get down to basics, so no GUIs or automated installatinos from the Internet (automated dependency management) here.  I will, however, make a recommendation as to which dependency management system you should use, because nowadays it would be rather insane to do the following work manually — except for very particular cases in which this tutorial will come in very handy.</p>

<h2>Installing packages</h2>

<p>You want new software?  You have to install it.  First you download it from the ‘Net (you’re gonna be looking for a file ending in <code>.rpm</code>), then you install it on your system.  As simple as that… in theory.</p>

<p>The basic installation operation in RPM is <code>rpm -i packagename-x.y.z.rpm</code>.  I tend to combine it with the <code>-vh</code> arguments which cause a progress bar to appear, and verbose messages to be printed onscreen for a variety of operations within the transaction.</p>

<p><em>Transaction</em>.  With RPM, to ensure the integrity of your computer, either the package installation happens, or it doesn’t happen at all.  If you request to install 450 packages in a single command (which you could easily do), and one of them cannot be fit into the system, the transaction fails and your system remains untouched.  Reasons for a failure may include that:</p>

<ul>
<li>the package you requested to install is already installed, whether the installed one is an older or a newer version </li>
<li>the package would trample on files owned by another installed package</li>
<li>the package is bad</li>
<li>the package requires another package or set of packages installed beforehand — this is called a <em>dependency</em></li>
</ul>

<p>All of those reasons, and a couple more, could leave your system broken if RPM were actually to go through with installation.  Therefore, RPM stops when it detects any of these conditions.</p>

<h3><code>--force</code></h3>

<p>Unless you augment the command with the <code>--force</code> argument.  Trust me when I say this: if RPM is refusing to install a package, under no circumstances should you use <code>--force</code> even if you badly need to.  RPM is probably much better informed than you are as to what the system actually needs to continue functioning properly, and you should trust it.  <code>--force</code> is only handy when you’re absolutely sure of how the different related components of your system relate to each other.</p>

<h3>Upgrades and downgrades</h3>

<p>We see that <code>rpm -i</code> will fail if you attempt to install a newer or an older version:</p>

<ul>
<li>If you really need to downgrade, you can always append <code>--oldpackage</code> to the command line, and if the integrity checks are A-OK, RPM will downgrade a package for you.</li>
<li>Conversely, if you want to upgrade, you use <code>rpm -U</code> instead of <code>rpm -i</code>.  As a matter of fact, <code>rpm -U</code> will both install and upgrade packages happily, so you can just use <code>rpm -U</code> most of the time, and forget about <code>-i</code>.</li>
</ul>

<p>RPM will also, in the spirit of preserving your system as pure and functional as possible, refuse to overwrite custom configuration files in your computer.  It will, however, deposit them in the folder where they were meant to live, by appending a <code>.rpmnew</code> extension to the new file — so you can use the standard <code>find</code> command to find and inspect these config files, see if they bring anything new and useful to the table.</p>

<h3>Controlled mass upgrades of what you already have</h3>

<p>What if your best friend shared a CD-ROM with the latest updates — say, 850 RPM files — for your Linux distribution?  You could go one by one and install each.  That’s not gonna go well, because many of those updates may not be installed on your system.</p>

<p>What you could do instead is use <code>rpm -F</code>.  Like issuing a command <code>rpm -Fvh *.rpm</code> while on the CD-ROM directory.  <code>-F</code> means <em>freshen</em> — it will only upgrade packages for which older version are already installed on your system.</p>

<p>In theory, you could perform an entire operating system upgrade this way.  In practice, it’s a little more complicated because as distros evolve, they start requiring more base packages which you don’t have installed, and <code>-F</code> won’t know which ones are these (although it will tell you which dependency it failed to find installed!).  When I say in practice, I mean it — I have used this method to upgrade a machine that just didn’t have enough RAM to run an installer on — and I succeeded, but I had to go in smaller batches of <code>rpm -F</code>’s with some <code>rpm -U</code>’s in between.</p>

<h2>Package removal</h2>

<p>Want to remove a package? <code>rpm -e</code> is what you’re looking for.  As discussed in the previous section, if a removal would break your system, RPM would not let you perform.</p>

<p>Config files are also dealt with gracefully.  If you’ve changed any, RPM will save them with the same file name, and a <code>.rpmsave</code> extension.  This is incredibly well-thought-out, because you will often need them sooner or later!</p>

<h2>Listing and inspecting packages on your system</h2>

<p>Do <code>rpm -qa</code>.  The <code>-q</code> stands for <em>query</em>, and the <code>-a</code> stands for <em>all</em>.  Most RPM commands accept <code>-a</code> as an argument to say <em>all</em> anyway, so it’s good to keep it in mind.</p>

<p>By default, it will present you a one-column list with all the package names and currently installed versions of them.  If you want more specific information, <code>rpm -qi packagename</code> (note the use of a package name as opposed to a file name) is usually what you want.  And <code>rpm -qpi packagename-x.y.z.rpm</code> (note the filename) is used to inspect uninstalled RPM packages on disk.</p>

<p>Want to know which package a file belongs to? <code>rpm -qf /path/to/said/file</code> will tell you.  Very handy!</p>

<h2>Integrity verification</h2>

<p>Want to see if any files have been modified, and how?  <code>rpm -V packagename</code> is the command.  It will display a series of lines, one for each file that has been modified, or nothing at all if no files have been touched.  Several aspects are displayed in a column-packed display: file times, permissions, integrity and a whole lotta more are included.  Checkt he RPM manual page to see what each column means.</p>

<p>Perhaps you’d like a full audit of what’s on your system and what’s been changed?  Combine two popluar arguments into <code>rpm -Va</code>.  Verify all.  It will probably be a long list so make sure to redirect the output to a file.</p>

<h2>Getting packages for your distro</h2>

<p>Easy.  Go to Google, type the name of the package followed by a space and the letters “RPM”.  Lots of results will follow.  Find those results that appear from RPM repositories (those sites usually say they are RPM repositories, so you’ll have no problem).  If one of your packages has a dependency problem, you can also type the dependency name into Google followed by “RPM” — and that will most likely help you solve dependency problems.</p>

<h3>Get Smart!</h3>

<p>But, honestly, that’s inefficient.  Just get <a href="http://www.smartpm.org/">Smart</a>, where you’ll be able to add said repositories to the Smart configuration (don’t panic, it’s usually an URL that needs to go into a file in <code>/etc/smart/channels</code> plus a command to import the security key of the repository — and repositories explain this procedure quite more eloquently than I do when I’m this sleepy).  Then you will be able to invoke Smart via the command line or the nice GUI it has, request a particular package and install it.  Smart will automatically download all the depended packages and install them for you.</p>

<p>Don’t forget to read the Smart manual page!</p>

<h2>Conclusions</h2>

<p>And that concludes our RPM crash course.  If you have any doubts, please add them as comments below.  And discuss!</p>
]]></content:encoded>
			<wfw:commentRss>http://rudd-o.com/archives/2007/11/14/a-primer-into-software-package-management-using-rpm/feed/</wfw:commentRss>
		</item>
		<item>
		<title>I dunno what people mean when they talk about RPM hell</title>
		<link>http://rudd-o.com/archives/2007/11/14/i-dunno-what-people-say-when-they-talk-about-rpm-hell/</link>
		<comments>http://rudd-o.com/archives/2007/11/14/i-dunno-what-people-say-when-they-talk-about-rpm-hell/#comments</comments>
		<pubDate>Wed, 14 Nov 2007 07:10:25 +0000</pubDate>
		<dc:creator>Rudd-O</dc:creator>
		
		<category><![CDATA[Linux]]></category>

		<category><![CDATA[RPM]]></category>

		<category><![CDATA[dpkg]]></category>

		<guid isPermaLink="false">http://rudd-o.com/archives/2007/11/14/i-dunno-what-people-say-when-they-talk-about-rpm-hell/</guid>
		<description><![CDATA[When people talk about RPM dependency hell, I really have no idea what they’re talking about.  Here’s a factual look into RPM that should set the record straight:



Warning ahead: please note that I’m not gonna discuss Debian vs. Red Hat, but dpkg vs. RPM.

RPM, combined with a good package manager such as Smart, is [...]]]></description>
			<content:encoded><![CDATA[<p>When people talk about RPM dependency hell, I really have no idea what they’re talking about.  Here’s a factual look into RPM that should set the record straight:</p>

<p><span id="more-1817"/></p>

<p><em>Warning ahead: please note that I’m not gonna discuss Debian vs. Red Hat, but dpkg vs. RPM.</em></p>

<p>RPM, combined with a good package manager such as <a href="http://www.smartpm.org/">Smart</a>, is vastly superior to the competition:</p>

<h2>The strengths of RPM</h2>

<ul>
<li>No indirections — 100% of the times, the manifest corresponds to the installed files.  Have you seen dpkg detours/indirections (dunno their name in English)?</li>
<li>Built-in integrity checking.  <code>rpm -V</code>.  Can’t get any easier than that.</li>
<li>The dependency system is cleaner. It allows and actually by default generates dependencies on files, which rocks when several packages provide the same functionality.</li>
<li>The RPM philosophy doesn’t allow interruptions during package installation or removal.  No stupid questions about config files getting replaced or not, license agreements and configuration questions.  This guarantees unattended transactional installations/upgrades (dpkg does not guarantee it without extra effort, because it defaults to interactive behavior) whereas with dpkg, if you answer one question wrong, your system may stay unconfigured.  I know it because I lived it.  I’d very much rather have the package come in a default useful configuration then configure it than have an assistant interrupt me upon installation to ask me how I want to configure it.</li>
<li>RPM supports two versions of a package with the same name, whereas dpkg does not.  I know this because I have a machine with <code>kdelibs</code> 3.5.7 and <code>kdelibs</code> 1.4 to support Katalog from KDE 1.0, and no broken dependencies.  However, this is regrettably a theoretical advantage because as of late many RPM-based distros have picked up the bad habit of naming stuff after Debian package conventions (think libXXX2.2); the Debian practice is both unneeded in the RPM world and stupid because the version of the package does not conceptually belong in the package name, and doing that constitutes a hacky workaround around inferior technology which RPM does not need.</li>
</ul>

<h2>The disadvantages</h2>

<p>The only things RPM has going against it?  It’s a bit harder to prepare spec files for RPMs, and it’s hard to prepare distro-agnostic RPMs, which has the logical consequence of reducing availability of RPMs ready to install.  RPM-based distros should take a clue from deb-based ones right now, or else they risk continuing to get kicked in the ass for the foreseeable future.</p>

<p>Discuss.</p>
]]></content:encoded>
			<wfw:commentRss>http://rudd-o.com/archives/2007/11/14/i-dunno-what-people-say-when-they-talk-about-rpm-hell/feed/</wfw:commentRss>
		</item>
		<item>
		<title>How PulseAudio works</title>
		<link>http://rudd-o.com/archives/2007/11/05/how-pulseaudio-works/</link>
		<comments>http://rudd-o.com/archives/2007/11/05/how-pulseaudio-works/#comments</comments>
		<pubDate>Mon, 05 Nov 2007 22:56:38 +0000</pubDate>
		<dc:creator>Rudd-O</dc:creator>
		
		<category><![CDATA[Free software]]></category>

		<category><![CDATA[Linux]]></category>

		<guid isPermaLink="false">http://rudd-o.com/archives/2007/11/05/how-pulseaudio-works/</guid>
		<description><![CDATA[In an effort to better understand how each of the PulseAudio components interact with each other, I’ve done a small diagram that roughly shows how each component connects and interacts:






You’re free to use this diagram on your own site or documentation, as per the license that covers it (see the footer).  However, I do [...]]]></description>
			<content:encoded><![CDATA[<p>In an effort to better understand how each of the PulseAudio components interact with each other, I’ve done a small diagram that roughly shows how each component connects and interacts:</p>

<p><span id="more-1805"/></p>

<p style="text-align:center">
<a href="http://rudd-o.com/archives/2007/11/05/how-pulseaudio-works/pulseaudio-system-diagram-version-2/" rel="attachment wp-att-1808" title="PulseAudio system diagram, version 2"><img src="http://rudd-o.com/wp-content/uploads/2007/11/pulseaudio-diagram.png" alt="PulseAudio system diagram, version 2"/></a></p>

<p>You’re free to use this diagram on your own site or documentation, as per the license that covers it (see the footer).  However, I do ask you for credit and attribution if you use it.  The image is also licensed under the GFDL, just in case you need it for free documentation.</p>

<p>The diagram is also available as a Dia diagram.</p>
]]></content:encoded>
			<wfw:commentRss>http://rudd-o.com/archives/2007/11/05/how-pulseaudio-works/feed/</wfw:commentRss>
		</item>
		<item>
		<title>How to divide and conquer a problem the UNIX way</title>
		<link>http://rudd-o.com/archives/2007/11/02/how-to-divide-and-conquer-a-problem-the-unix-way/</link>
		<comments>http://rudd-o.com/archives/2007/11/02/how-to-divide-and-conquer-a-problem-the-unix-way/#comments</comments>
		<pubDate>Fri, 02 Nov 2007 16:37:59 +0000</pubDate>
		<dc:creator>Rudd-O</dc:creator>
		
		<category><![CDATA[Linux]]></category>

		<category><![CDATA[Programming]]></category>

		<category><![CDATA[Python]]></category>

		<category><![CDATA[Tutorials]]></category>

		<guid isPermaLink="false">http://rudd-o.com/archives/2007/11/02/how-to-divide-and-conquer-a-problem-the-unix-way/</guid>
		<description><![CDATA[If you’re one of our regular readers, you’ll remember reading the article and script I wrote on automating BitTorrent downloads with TorrentFlux and rsync.  The script has come to be quite handy to me, but the process of writing it is much more fun and appealing.  Here’s how I did it.



What you’re about [...]]]></description>
			<content:encoded><![CDATA[<p>If you&#8217;re one of our regular readers, you&#8217;ll remember reading the article and script I wrote on <a href="post:how-to-automate-torrent-downloads-using-torrentflux-b4rt-cron-and-rsync">automating BitTorrent downloads with TorrentFlux and rsync</a>.  The script has come to be quite handy to me, but the process of writing it is much more fun and appealing.  Here&#8217;s how I did it.</p>

<p><span id="more-1796"></span></p>

<p>What you&#8217;re about to read is a short, true story that details how I went from idea to solution, using the &#8220;UNIX way&#8221; (divide a problem in little pieces, then jump each hurdle with the help of a domain-specific solution, and finally combine each response).</p>

<p>The story is &#8212; honest! &#8212; more about the underlying thought process than the technology I used &#8212; in fact, while I do know Python and I&#8217;ve grown white hairs using Linux, most of the stuff you&#8217;ll see here I taught myself in the course of this challenge.</p>

<h2>TorrentFlux: what it is, how it works</h2>

<p>TorrentFlux is a very interesting Web application you can install on your Web server.  Once installed, it lets you in to a nice interface like any other BitTorrent program where you get to add .torrent files so the torrent gets downloaded directly in your Web server.  Here it is:</p>

<p style="text-align:center"><a href="post:torrentflux-b4rt" rel="attachment wp-att-1800" title="TorrentFlux-b4rt"><img src="content:2007/11/torrentflux.jpg" alt="TorrentFlux-b4rt"/></a></p>

<h3>Advantages of using TorrentFlux</h3>

<p>The reasons to use such a program instead of a normal desktop BitTorrent client are varied:</p>

<ul>
<li>you would like to have a particular, big file (think Linux distro) right away on the server instead of uploading it through your ISP&#8217;s connection</li>
<li>your ISP throttles or blocks BitTorrent (think Comcast)</li>
<li>you would like to avoid downloading through 50 TCP connections at home, and just use one (think speedier Web browsing)</li>
<li>you want to take advantage of the (usually) higher bandwidths available in your Web server during the day, and you&#8217;d like to download the file once it&#8217;s done, from beginning to end (think videos)</li>
<li>you would like to queue up a download while away from home (think vacations)</li>
</ul>

<h3>Disadvantages</h3>

<p>The disadvantages, compared to a regular BitTorrent client, are that:</p>

<ul>
<li>if you want the download in your PC, you need to queue it up separately in a download manager on your PC through FTP,</li>
<li>you need to check TorrentFlux periodically to see if the torrent is done downloading, because you can&#8217;t download a torrent to your PC until the torrent is done,</li>
<li>you can&#8217;t queue up downloads from TorrentFlux to your home PC if you&#8217;re away from your computer, can you?</li>
<li>disk space might be limited in your Web server.</li>
</ul>

<p>What we&#8217;ll do in this article is destroy these disadvantages.</p>

<h2>The problem in a nutshell</h2>

<p>From the aforementioned disadvantages we can clearly see what the problem is.  Being the lazy bastards we are, we want the downloads in our home computer ASAP, without manual intervention.  Our ultimate goal is to:</p>

<ol>
<li>queue up a BitTorrent download in TorrentFlux, and</li>
<li>as soon as it&#8217;s finished, have our home PC automatically &#8220;check it out from the counter&#8221;, and then</li>
<li>erase the file from the TorrentFlux server.</li>
</ol>

<p>Let&#8217;s go do it.</p>

<h2>How I solved it</h2>

<h3>Remoting my server</h3>

<p>How am I going to talk to my server?  This question crossed my mind many times.  In the end, I chose SSH, because it&#8217;s extremely easy to automate and have it work securely without constant interruptions &#8212; remember, we don&#8217;t want to be interrupted with password prompts or anything like it.</p>

<p>I wrote the code that more or less provided enough help for it to work.  As programming languages go, Python is by far the best for the task at hand, so I used it.  OK, I&#8217;ll admit it, I&#8217;m a Python junkie:</p>

<p><pre>#!/usr/bin/env python</pre></p>

<p>from subprocess import Popen,PIPE,STDOUT,call
import fcntl
import re
import os
import sys
import signal</p>

<p>def getstdout(cmdline):
        p = Popen(cmdline,stdout=PIPE)
        output = p.communicate()[0]
        if p.returncode != 0: raise Exception, "Command %s return code %s"%(cmdline,p.returncode)
        return output
def getstdoutstderr(cmdline,inp=None): # return stoud and stderr in a single string object
        p = Popen(cmdline,stdin=PIPE,stdout=PIPE,stderr=STDOUT)
        output = p.communicate(inp)[0]
        if p.returncode != 0: raise Exception, "Command %s return code %s"%(cmdline,p.returncode)
        return output
def passthru(cmdline): return call(cmdline) # return status code, pass the outputs thru
def getssh(cmd): return getstdout(["ssh","-o","BatchMode yes","-o","ForwardX11 no",torrentflux_server] + [cmd]) # return stdout of ssh.  doesn't return stderr
def sshpassthru(cmd): return call(["ssh","-o","BatchMode yes","-o","ForwardX11 no",torrentflux_server] + [cmd]) # return status code from a command executed using ssh</p>

<p>Interesting, isn&#8217;t it?  Now I have two functions:</p>

<ul>
<li>one that gets me the text of a command executed by SSH, and</li>
<li>another that discards the text but returns the return value of the executed command &#8212; which, if you know the UNIX convention, it&#8217;s zero for success, and anything else for errors.</li>
</ul>

<h3>Determining which torrents are done</h3>

<p>The first hurdle I need to surpass: which torrents from the torrent list are already done?  After a little poking around the Web, I discovered that with the help of a command called <code>fluxcli</code> that ships with TorrentFlux, I can get a list of active torrents in text form.</p>

<p>So that&#8217;s solved.  All I needed is some code that parses the rows returned, selects only those rows that say Done or Seeding in the status column, and that should return the name of each torrent that&#8217;s ready to download.</p>

<p>The code in question is this:</p>

<p><pre>def get_finished_torrents():
        stdout = getssh("%s transfers"%fluxcli)
        stdout = stdout.splitlines()[2:-5]
        stdout = [ re.match("^- (.+) - [0123456789.]+ MB - (Seeding|Done)",line) for line in stdout ]
        return [ match.group(1) for match in stdout if match ]</pre></p>

<p>Stupidly simple, and it makes use of the SSH remoting functions (dare I say hacks?) I wrote before.  And, may I say, only three lines, really.  It returns a list with the names of the torrents.</p>

<p>Next up, getting the file names inside the torrents.</p>
]]></content:encoded>
			<wfw:commentRss>http://rudd-o.com/archives/2007/11/02/how-to-divide-and-conquer-a-problem-the-unix-way/feed/</wfw:commentRss>
		</item>
	</channel>
</rss>
