<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss 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/" version="2.0">

<channel>
	<title>joe.topjian.net</title>
	
	<link>http://joe.topjian.net</link>
	<description>Homepage of Joe Topjian</description>
	<lastBuildDate>Sat, 10 Oct 2009 17:57:46 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.4</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" href="http://feeds.feedburner.com/JoeTopjian" type="application/rss+xml" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com" /><item>
		<title>Modifying Vixie Cron for Fun</title>
		<link>http://joe.topjian.net/development/modifying-vixie-cron-for-fun.html</link>
		<comments>http://joe.topjian.net/development/modifying-vixie-cron-for-fun.html#comments</comments>
		<pubDate>Thu, 24 Sep 2009 22:47:01 +0000</pubDate>
		<dc:creator>joe</dc:creator>
				<category><![CDATA[Development]]></category>

		<guid isPermaLink="false">http://joe.topjian.net/?p=200</guid>
		<description><![CDATA[Introduction

Cron is an essential *nix package that silently runs in the background running scheduled jobs. The most common version of cron is Vixie Cron. Coincidentally Vixie Cron  is also the most vanilla version &#8212; it doesn&#8217;t provide any flashy features that other variants have, just the ability to read from a crontab and run [...]]]></description>
			<content:encoded><![CDATA[<h3>Introduction</h3>

<p>Cron is an essential *nix package that silently runs in the background running scheduled jobs. The most common version of cron is Vixie Cron. Coincidentally Vixie Cron  is also the most vanilla version &#8212; it doesn&#8217;t provide any flashy features that other variants have, just the ability to read from a crontab and run scheduled jobs.</p>

<p>This, of course, is fine for most servers, but if a server is configured to run several cron jobs every minute, the server could easily get overloaded. I recently ran into this problem and rather than replace the standard cron package with something like <a href="http://fcron.free.fr/">fcron</a> I decided to hack Vixie Cron for fun to see what I could do myself.</p>

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

<h3>What Changes I Wanted to Make</h3>

<p>When cron wakes up every minute, it checks to see what jobs need to be run and executes them all at once. So if there are 100 jobs configured to run, 100 jobs will run at once. I wanted to stop this from happening, so the main feature I wanted to add was for cron to be able to queue jobs.</p>

<p>The second modification is related to the first: while I could hard-code a queue length inside the cron source, I would rather have the administrator be able to specify what the length should be. I wanted to add this feature as a command-line switch.</p>

<h3>Disclaimer</h3>

<p>I am not an expert at C programming. What follows is simply me fooling around for fun. And while I was able to correctly get this to work, I would highly advise against running this in production. Even I did not.</p>

<p>Also, unfortunately I did this several months ago and have only been able find the time to write about it now. While I was able to trace back my work, hopefully what I dug up is detailed enough.</p>

<h3>Tools and Setup</h3>

<p>I worked on Vixie Cron 4.1 from CentOS 5.3. The build and test machine was a standard install of CentOS 5.3.</p>

<p>I followed the instructions at <a href="http://www.owlriver.com/tips/patching_srpms/">Owl River</a> about how to create an RPM patching and development environment. As that page explains how to do this much better than I could, I would recommend just reading it there.</p>

<p>One difference, though, is that RHEL provides 70 patches to the base vixie cron source. I did not realize this when I first made my changes, so when I created my final patch, it did not apply correctly over the other 70. Therefore, please patch the source files with all included patches before proceeding. I applied them in the order that they are listed in the vixie-cron.spec file.</p>

<h3>Dissecting Cron</h3>

<p>Once I had my environment setup, I proceeded to read through the source code and try to find my way around.</p>

<p>For how widespread and important cron is, vixie cron is very simple.</p>

<h3>Adding the Command Line Switch</h3>

<p><code>cron.c</code> is the file that contains the <code>main()</code> function. This file also contains the area where cron parses the command line options. Interestingly, the unpatched version of Vixie Cron does not use a <code>getopt</code> feature &#8212; it manually parses the command line options itself. One of the RHEL patches added <code>getopt</code> later.</p>

<p>I decided to use <code>q</code>, for &#8220;queuing&#8221;, as the switch letter. The original line looked like:</p>

<pre name="code" class="c">
while (-1 != (argch = getopt(argc, argv, "npx:m:"))) {
</pre>

<p>And my edit changed it to:</p>

<pre name="code" class="c">
while (-1 != (argch = getopt(argc, argv, "npx:m:q:"))) {
</pre>

<p>Below that, I added my case for the switch statement:</p>

<pre name="code" class="c">
        case 'q':
            NumProcs = atoi(optarg);
            NumProcs += 1;
            break;
</pre>

<p>Of course, with C, all variables have to be pre-declared, so somewhere at the top, I added:</p>

<pre name="code" class="c">
NumProcs = -1;
</pre>

<p>I later found I also had to add a line to <code>globals.h</code> to make <code>NumProcs</code> global to all files:</p>

<pre name="code" class="c">
XTRN int       NumProcs INIT(0);
</pre>

<p>With these changes, my new command line switch was in place. If an administrator wanted to make cron only run 2 jobs in the queue at a time, he or she would specify:</p>

<pre name="code" class="c">
crond -q2
</pre>

<p>Now it&#8217;s time to add the queueing feature.</p>

<h3>Queuing</h3>

<p><code>job.c</code> is the file which controls the job execution. The function <code>job_runqueue()</code> is where the execution actually happens. It&#8217;s here where you can see why the jobs all run at once. There is no timing control in the <code>for</code> loop &#8212; the job queue is looped and all jobs are fired off as fast as the CPU can run.</p>

<p>I did some quick reading on UNIX processes and forking and came up with the following modifications to the function.</p>

<p>Here is the original:</p>

<pre name="code" class="c">
job_runqueue(void) {
    job *j, *jn;
    int run = 0;

    for (j = jhead; j; j = jn) {
        do_command(j->e, j->u);
        jn = j->next;
        free(j);
        run++;
    }
    jhead = jtail = NULL;
    return (run);
}
</pre>

<p>And here is my modified version:</p>

<pre name="code" class="c">
int
job_runqueue(void) {
    job *j, *jn;
    int run = 0;
    int numRunning = 0;
    WAIT_T waiter;
    PID_T pid;

    for (j = jhead; j; j = jn) {
        numRunning += 1;
        if (NumProcs != -1) {
            if (numRunning >= NumProcs) {
                while ((pid = wait(&#038;waiter)) < OK &#038;&#038; errno == EINTR)
                    ;
                numRunning -= 1;
            }
        }
        do_command(j->e, j->u);
        jn = j->next;
        free(j);
        run++;
    }
    jhead = jtail = NULL;
    return (run);
}
</pre>

<p>First I added a variable to keep track of how many jobs are running. I then created variables for the process control: <code>wait</code> and <code>pid</code>.</p>

<p>When the function runs the loop, it checks to see if <code>NumProcs</code> is not set to <code>-1</code> &#8212; or in other words, if no <code>q</code> switch was supplied. If it is not <code>-1</code>, it then applies the control.</p>

<p>The control simply says if the number of jobs currently running are greater than or equal to the number of processes specified with <code>q</code>, run <code>wait()</code> and wait for one or more jobs to finish. When a job does finish, decrement the number of jobs currently running by 1.</p>

<h3>First Run</h3>

<p>I created a cron table with some test jobs:</p>

<pre name="code" class="c">
* * * * * sleep 10; echo `date` >> /home/jtopjian/t2.txt
* * * * * sleep 10; echo `date` >> /home/jtopjian/t2.txt
* * * * * sleep 10; echo `date` >> /home/jtopjian/t2.txt
* * * * * sleep 75; echo `date` >> /home/jtopjian/t2.txt
</pre>

<p>I ran cron on the command line in Debug mode. Everything worked perfectly. If I set the queue to 1, only one job would run at a time.</p>

<p>Unfortunately, I found a problem. If all jobs took more than 60 seconds to run, cron would skip the next minute&#8217;s crons. This was very bad as potentially important jobs would never run.</p>

<p>I re-read the code to find the problem. After an hour of reading and researching, it finally made sense: cron is a single-threaded program. There is no possible way it can keep track of its schedule plus run scheduled jobs. The reason why cron executes all jobs at once is because it needs to return to its sleep schedule as quick as possible so it won&#8217;t miss the next run.</p>

<p>In order to solve my problem, I would need to turn cron into a multi-threaded program. My idea was that any time the job queue needed to run, a new thread would be created. The thread would act like its own entity and run the queued jobs without worry of any other part of the program. Though changing the architecture of cron in this way sounded daunting, it actually wasn&#8217;t hard at all.</p>

<h3>Adding Threading Support</h3>

<p><a href="http://www.yolinux.com/TUTORIALS/LinuxTutorialPosixThreads.html">YoLinux</a> provides a wonderful tutorial on Linux Threads. It was all I needed to learn how to add in my threading support.</p>

<p>As I mentioned earlier, I did this a few months ago. Unfortunately, since then, I&#8217;ve forgotten what I learned. I am just going to list my changes but not provide details.</p>

<p>The first step was to include the threading library into both <code>cron.c</code> and <code>job.c</code>:</p>

<pre name="code" class="c">
#include &lt;pthread.h&gt;
</pre>

<p>I then had to declare some variables which would control and work with the threads:</p>

<pre name="code" class="c">
pthread_t thread1;
pthread_mutex_t mutex1 = PTHREAD_MUTEX_INITIALIZER;
int rc1;
</pre>

<p>Next, I modified the way <code>job_runqueue()</code> was called in <code>cron.c</code>. It originally looked simply like:</p>

<pre name="code" class="c">
job_runqueue();
</pre>

<p>With my modifications:</p>

<pre name="code" class="c">
if ((rc1 = pthread_create(&#038;thread1, NULL, job_runqueue, NULL))) {
    Debug(DSCH, ("[%ld] thread failed\n", (long)getpid()));
}
pthread_join(thread1, NULL);
</pre>

<p>The next step was to modify the <code>job.c</code> file and add threading support. The final <code>job_runqueue()</code> function looked like this:</p>

<pre name="code" class="c">
int
job_runqueue(void) {
    job *j, *jn;
    int run = 0;
    int numRunning = 0;
    WAIT_T waiter;
    PID_T pid;
    pthread_mutex_t mutex1 = PTHREAD_MUTEX_INITIALIZER;

    Debug(DSCH, ("[%ld] thread number %ld\n", (long)getpid(), pthread_self()));
    pthread_mutex_lock(&#038;mutex1);
    for (j = jhead; j; j = jn) {
        numRunning += 1;
        if (NumProcs != -1) {
            if (numRunning >= NumProcs) {
                while ((pid = wait(&#038;waiter)) < OK &#038;&#038; errno == EINTR)
                    ;
                numRunning -= 1;
            }
        }
        do_command(j->e, j->u);
        jn = j->next;
        free(j);
        run++;
    }
    jhead = jtail = NULL;
    pthread_mutex_unlock(&#038;mutex1);
    return (run);
}
</pre>

<p>The final step was to edit the <code>Makefile</code> so cron compiled with the <code>pthreads</code> library:</p>

<pre name="code" class="c">
LDFLAGS     =   -g -lpthread
</pre>

<h3>Second Run</h3>

<p>With all of these changes made, I re-ran my tests. The threading library worked perfectly. Even if a queue of jobs took over a minute to complete, cron would create another thread with a whole new bank of jobs.</p>

<h3>Conclusion</h3>

<p>By toying around with the cron source code, I was able to learn the detailed workings of vixie cron as well as some basic UNIX C programming.</p>

<p>I&#8217;ve uploaded my final <a href="http://joe.topjian.net/wp-content/uploads/2009/09/vixie-cron-4.1-queuing.patch">patch</a> and my modified <a href="http://joe.topjian.net/wp-content/uploads/2009/09/vixie-cron.spec">vixie-cron.spec</a> file so readers can compile this version of cron themselves.</p>

<p>If anyone has any input, corrections, comments, or ideas on this topic and the changes I made, I would love to hear them.</p>

<p>I realize this article is rather unorganized and missing a lot of details. If anyone needs anything clarified, please let me know.</p>
]]></content:encoded>
			<wfw:commentRss>http://joe.topjian.net/development/modifying-vixie-cron-for-fun.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>64-bit On A Personal Level</title>
		<link>http://joe.topjian.net/administration/64-bit-on-a-personal-level.html</link>
		<comments>http://joe.topjian.net/administration/64-bit-on-a-personal-level.html#comments</comments>
		<pubDate>Sat, 19 Sep 2009 17:03:18 +0000</pubDate>
		<dc:creator>joe</dc:creator>
				<category><![CDATA[Administration]]></category>

		<guid isPermaLink="false">http://joe.topjian.net/?p=187</guid>
		<description><![CDATA[I never paid much attention to 64-bit. I figured 64-bit operating systems were just a natural evolutionary step and I&#8217;d just casually start running 64-bit Linux distros whenever it was convenient. I understood the technical benefits with larger integers and stuff, but in my experience, Apache, MySQL, et al ran just the same whether it [...]]]></description>
			<content:encoded><![CDATA[<p>I never paid much attention to 64-bit. I figured 64-bit operating systems were just a natural evolutionary step and I&#8217;d just casually start running 64-bit Linux distros whenever it was convenient. I understood the technical benefits with larger integers and stuff, but in my experience, Apache, MySQL, et al ran just the same whether it was 32 or 64.</p>

<p>That view changed the other day, though.</p>

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

<p>I needed to poll a group of servers for network activity. Since I just needed the NIC&#8217;s byte count, I wrote a few custom scripts instead of using a full package like <a href="http://www.cacti.net/">Cacti</a>. The counts were fed into RRD where I&#8217;m generating Daily and Weekly graphs.</p>

<p>On a few of the servers, the graphs showed weird spikes in activity. Usually that would mean a lot of bandwidth was being used at the time &#8212; except that the data being graphed was a negative value and the spikes were going in the opposite direction.</p>

<p><a href="http://joe.topjian.net/wp-content/uploads/2009/09/graph.png"><img src="http://joe.topjian.net/wp-content/uploads/2009/09/graph-300x102.png" alt="graph" title="graph" width="300" height="102" class="aligncenter size-medium wp-image-194" /></a></p>

<p>The reason for this was that the byte counts that <code>ifconfig</code> was reporting were resetting. Since this was only happening on a few of the servers, I was getting pretty confused on the source of the problem.</p>

<p>Finally I noticed that these servers were all running a 32-bit version of CentOS while the working servers are 64-bit. The byte counts were just reaching their 32-bit integer max.</p>

<p>I&#8217;m the type that learns from personal experience. Seeing this negative graphing spike in action has made me fully aware of the benefits to 64-bit.</p>
]]></content:encoded>
			<wfw:commentRss>http://joe.topjian.net/administration/64-bit-on-a-personal-level.html/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Making a Plain Website</title>
		<link>http://joe.topjian.net/development/making-a-plain-website.html</link>
		<comments>http://joe.topjian.net/development/making-a-plain-website.html#comments</comments>
		<pubDate>Wed, 02 Sep 2009 22:07:47 +0000</pubDate>
		<dc:creator>joe</dc:creator>
				<category><![CDATA[Development]]></category>

		<guid isPermaLink="false">http://joe.topjian.net/?p=179</guid>
		<description><![CDATA[Introduction

For the past few years, Unix Mages was running on Wordpress. The site has not changed in over two years as I was no longer writing content for it. So instead of leaving a stale and possibly insecure Wordpress installation on the web, I decided to turn it into an old fashioned static website.



What I [...]]]></description>
			<content:encoded><![CDATA[<h3>Introduction</h3>

<p>For the past few years, <a href="http://unixmages.com">Unix Mages</a> was running on Wordpress. The site has not changed in over two years as I was no longer writing content for it. So instead of leaving a stale and possibly insecure Wordpress installation on the web, I decided to turn it into an old fashioned static website.</p>

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

<h3>What I Used</h3>

<p>I enjoy using <a href="http://www.panic.com/coda/">Coda</a> as an editor due to its excellent remote functionality. I started creating a simple website consisting of two files: <code>index.html</code> and <code>style.css</code>.</p>

<p>I soon became tired of trying to lay out all of the elements manually, so I decided to include <a href="http://www.blueprintcss.org/">Blueprint</a>.</p>

<p>Once I started working on the other pages, I realized copying and pasting text was severely inefficient if any future changes needed made. So I broke the pages up into a body, header, and footer and glued everything together using <a href="http://httpd.apache.org/docs/2.0/howto/ssi.html">Apache SSI</a>.</p>

<h3>Enabling mod_include for Ubuntu 8.04</h3>

<p>Apache <code>mod_include</code> is turned off by default. To enable it, simply do:</p>

<pre><code>a2enmod include
</code></pre>

<p>A few configuration changes needed made in order to get SSI to work:</p>

<pre name="code" class="html">

&lt;Directory /path/to/document/root&gt;
    Options +Includes
    AddOutputFilter INCLUDES .html
&lt;/Directory&gt;

</pre>

<p>I&#8217;m now able to include my <code>header.html</code> and <code>footer.html</code> files in any webpage by using:</p>

<pre name="code" class="html">

&lt;!--#include virtual="/header.html" --&gt;

</pre>

<h3>Conclusion</h3>

<p>Today it seems the standard way to create a website is to install Wordpress, Drupal, or any other type of Blogging or CMS engine &#8212; even if the site will only have a few static pages. I thought it was an excellent practice, if not only for nostalgic reasons, to detail how to create a simple, old fashioned website.</p>
]]></content:encoded>
			<wfw:commentRss>http://joe.topjian.net/development/making-a-plain-website.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Understanding TCP/IP</title>
		<link>http://joe.topjian.net/reviews/understanding-tcpip.html</link>
		<comments>http://joe.topjian.net/reviews/understanding-tcpip.html#comments</comments>
		<pubDate>Thu, 23 Jul 2009 03:17:54 +0000</pubDate>
		<dc:creator>joe</dc:creator>
				<category><![CDATA[Reviews]]></category>

		<guid isPermaLink="false">http://joe.topjian.net/?p=177</guid>
		<description><![CDATA[Understanding TCP/IP (or The Book with the Frog Touching Himself) is a great, new book from Packt. As the title suggests, it covers the TCP/IP protocol suite &#8212; similar to one of my all-time favorite technical books, TCP/IP Illustrated. However, the similarities between the two books stop there. Understanding TCP/IP also contains discussion on IPV6, [...]]]></description>
			<content:encoded><![CDATA[<p>Understanding TCP/IP (or The Book with the Frog Touching Himself) is a great, new book from Packt. As the title suggests, it covers the TCP/IP protocol suite &#8212; similar to one of my all-time favorite technical books, TCP/IP Illustrated. However, the similarities between the two books stop there. Understanding TCP/IP also contains discussion on IPV6, application protocols, and even a primer in Cisco routers.</p>

<p>Perfect for beginners, Understanding TCP/IP explains the TCP/IP protocol suite in a very understandable text. Even more, the book is wonderfully illustrated with diagrams and flowcharts detailing everything discussed. The discussion on the application protocols (which include HTTP, FTP, DNS, Email and more) is also top-notch. It&#8217;s like having a non-sleep-inducing RFC available to learn how each of these protocols work.</p>

<p>While I&#8217;ll always swear to TCP/IP Illustrated, I suppose that book becomes more dated as time goes on. If you&#8217;re a novice System Administrator who&#8217;s looking for a great primer to TCP/IP and networking, I think you should give this book a chance. It covers everything about the suite &#8212; including application protocols &#8212; in a single, well illustrated book.</p>
]]></content:encoded>
			<wfw:commentRss>http://joe.topjian.net/reviews/understanding-tcpip.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Time Management For System Administrators</title>
		<link>http://joe.topjian.net/reviews/time-management-for-system-administrators.html</link>
		<comments>http://joe.topjian.net/reviews/time-management-for-system-administrators.html#comments</comments>
		<pubDate>Thu, 23 Jul 2009 03:16:55 +0000</pubDate>
		<dc:creator>joe</dc:creator>
				<category><![CDATA[Reviews]]></category>

		<guid isPermaLink="false">http://joe.topjian.net/?p=175</guid>
		<description><![CDATA[System Administrators are one group of people who never seem to have enough time. This is mostly a result from the haphazard schedule we have &#8212; one day the office can be totally quiet and the next as noisy as a broken computer fan. Because of that, most time management skills go right out the [...]]]></description>
			<content:encoded><![CDATA[<p>System Administrators are one group of people who never seem to have enough time. This is mostly a result from the haphazard schedule we have &#8212; one day the office can be totally quiet and the next as noisy as a broken computer fan. Because of that, most time management skills go right out the window. Luckily, Time Management for System Administrators does a pretty good job filling in the missing lessons.</p>

<p>The first thing I noticed about this book is that it&#8217;s very easy to read. Pages and pages of theory and definitions of what time and management are simply do not exist. Instead, Thomas gives brief statements backed with examples and practice &#8212; just what System Administrators like.</p>

<p>Secondly, this book will not teach you how to format a piece of graph paper to chart your lists or how to organize your desk for maximum performance. Screw that. You save the company every day by stopping pesky foreign hackers out to rule the world. Someone telling you how to make a pile of paper is a slap in the face. Instead, you&#8217;ll learn about topics like interruptions, automation, and routines.</p>

<p>Mr. Limoncelli also goes over his own personal Time Management System he calls The Cycle. It&#8217;s a nice system to learn off of and possibly base your own on. My personal opinion is that time management systems are not compatible from person to person &#8212; and if you&#8217;re unable to create your own, you&#8217;re in more trouble than you think.</p>

<p>This book is worth a read. Time is a wonderful thing if it&#8217;s used correctly and the concepts Mr. Limoncelli covers will definitely help you achieve that.</p>
]]></content:encoded>
			<wfw:commentRss>http://joe.topjian.net/reviews/time-management-for-system-administrators.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>The Definitive Guide to SQLite</title>
		<link>http://joe.topjian.net/reviews/the-definitive-guide-to-sqlite.html</link>
		<comments>http://joe.topjian.net/reviews/the-definitive-guide-to-sqlite.html#comments</comments>
		<pubDate>Thu, 23 Jul 2009 03:15:08 +0000</pubDate>
		<dc:creator>joe</dc:creator>
				<category><![CDATA[Reviews]]></category>

		<guid isPermaLink="false">http://joe.topjian.net/?p=172</guid>
		<description><![CDATA[SQLite is the database for minimalists: it requires no back-end daemons, and as such, does not follow the client-server architecture of the other popular RDMS&#8217;s. Instead, SQLite is based on flat files and can access data with either the SQLite shell or through its several language extensions.

The Definitive Guide to SQLite is the perfect book [...]]]></description>
			<content:encoded><![CDATA[<p>SQLite is the database for minimalists: it requires no back-end daemons, and as such, does not follow the client-server architecture of the other popular RDMS&#8217;s. Instead, SQLite is based on flat files and can access data with either the SQLite shell or through its several language extensions.</p>

<p>The Definitive Guide to SQLite is the perfect book about SQLite. It covers everything needed to start working with SQLite including installation, using the SQLite shell, and programming with SQLite using six different language extensions. Another feature of this book is the impressive discussion on basic SQL and SQL theory. I&#8217;m glad this was included with the book as it gives more depth to the SQLite topics. For example, when the reader learns about database locks and how SQLite&#8217;s locks are based on the filesystem, they gain more of an understanding of what&#8217;s happening to the actual database file instead of just blindly believing in some SQL theory.</p>

<p>With System Administration, I always try to be as much of a minimalist as I can. Doing so helps keep everything quiet and simple and eliminates several unnecessary problems. When possible, using SQLite instead of a full RDBMS can only strengthen this methodology &#8212; and The Definitive Guide to SQLite is a great resource to learn SQLite from.</p>
]]></content:encoded>
			<wfw:commentRss>http://joe.topjian.net/reviews/the-definitive-guide-to-sqlite.html/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>The Definitive Guide to Apache mod_rewrite</title>
		<link>http://joe.topjian.net/reviews/the-definitive-guide-to-apache-mod_rewrite.html</link>
		<comments>http://joe.topjian.net/reviews/the-definitive-guide-to-apache-mod_rewrite.html#comments</comments>
		<pubDate>Thu, 23 Jul 2009 03:14:28 +0000</pubDate>
		<dc:creator>joe</dc:creator>
				<category><![CDATA[Reviews]]></category>

		<guid isPermaLink="false">http://joe.topjian.net/?p=170</guid>
		<description><![CDATA[The wonderful folks over at Apress sent me a preview copy of The Definitive Guide to Apache mod_rewrite. Before reading this book, I knew the very basics about mod_rewrite and only used it once or twice to mangle a URL. However, after reading, I&#8217;m amazed at everything this single module can accomplish.

The Definitive Guide to [...]]]></description>
			<content:encoded><![CDATA[<p>The wonderful folks over at Apress sent me a preview copy of <em>The Definitive Guide to Apache mod_rewrite</em>. Before reading this book, I knew the very basics about mod_rewrite and only used it once or twice to mangle a URL. However, after reading, I&#8217;m amazed at everything this single module can accomplish.</p>

<p><em>The Definitive Guide to Apache mod_rewrite</em> is exactly that &#8212; the definitive guide. Unless I&#8217;m clearly mistaken, everything about the module is discussed. After the usual coverage of installation and configuration (as well as a quick guide on Regular Expressions), Mr. Bowen goes over the three main pieces to mod_rewrite: RewriteRule, RewriteCond, and RewriteMap. Next it&#8217;s time to put those pieces to work with two chapters of practice. Advanced usage such as Proxying and Virtual Hosting also make an appearance.</p>

<p>Though there are set chapters covering the usage of mod_rewrite, several other examples exist scattered throughout the book when needed.  Further, when there&#8217;s a better or alternative way to accomplish an action, Rich comes right out and tells us. For example: after learning how to set Environment Variables, we&#8217;re taught how to stop bandwidth-hogging image theft. Or instead of using mod_rewrite to block clients based on their IP, we&#8217;re told it&#8217;s more efficient to so using a simple Deny directive. By doing this, we&#8217;re presented with hands-on, beneficial information while the original topic is still fresh in our head. Or simply put: we learn stuff.</p>
]]></content:encoded>
			<wfw:commentRss>http://joe.topjian.net/reviews/the-definitive-guide-to-apache-mod_rewrite.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>The ABCs of LDAP</title>
		<link>http://joe.topjian.net/reviews/the-abcs-of-ldap.html</link>
		<comments>http://joe.topjian.net/reviews/the-abcs-of-ldap.html#comments</comments>
		<pubDate>Thu, 23 Jul 2009 02:42:38 +0000</pubDate>
		<dc:creator>joe</dc:creator>
				<category><![CDATA[Reviews]]></category>

		<guid isPermaLink="false">http://joe.topjian.net/?p=168</guid>
		<description><![CDATA[I was looking for a good book on LDAP and ran across The ABCs of LDAP by Reinhard Voglmaier. Even though, according to Amazon, it&#8217;s not a very popular book, it&#8217;s the best book on the subject I&#8217;ve found yet.

This book has a nice balance of theory and practice. It starts out with the basics [...]]]></description>
			<content:encoded><![CDATA[<p>I was looking for a good book on LDAP and ran across The ABCs of LDAP by Reinhard Voglmaier. Even though, according to Amazon, it&#8217;s not a very popular book, it&#8217;s the best book on the subject I&#8217;ve found yet.</p>

<p>This book has a nice balance of theory and practice. It starts out with the basics of the LDAP protocol in a very readable tone. From there, it slowly blends in each different topic of LDAP very smoothly. For example, one of the first hands-on pieces of the book shows you how to add objects to LDAP via the command line. It then shows you how to search for those same objects. Though the reader doesn&#8217;t know it yet, the format these examples are using is standard LDIF &#8212; so when it&#8217;s time to use LDIF files, the reader thinks, &#8220;Oh! I know this already!&#8221;</p>

<p>OpenLDAP is the implementation used in the book, but there&#8217;s also footnotes throughout the text giving hints to the reader on other LDAP packages. Everything about LDAP is covered here: the basics, networking, replication, system administration, and programming. The programming section was particularly useful with the added bonus of example code in 4 languages.</p>

<p>So overall, I&#8217;m extremely impressed with this book. Why it isn&#8217;t more popular is beyond me. Maybe it&#8217;s the steep price tag, but I personally think it&#8217;s worth it.</p>
]]></content:encoded>
			<wfw:commentRss>http://joe.topjian.net/reviews/the-abcs-of-ldap.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>TCP/IP Illustrated Volume 1</title>
		<link>http://joe.topjian.net/reviews/tcpip-illustrated-volume-1.html</link>
		<comments>http://joe.topjian.net/reviews/tcpip-illustrated-volume-1.html#comments</comments>
		<pubDate>Thu, 23 Jul 2009 02:42:05 +0000</pubDate>
		<dc:creator>joe</dc:creator>
				<category><![CDATA[Reviews]]></category>

		<guid isPermaLink="false">http://joe.topjian.net/?p=166</guid>
		<description><![CDATA[After I did my first ever Unix install (FreeBSD 2.2.5), I was absolutely clueless on where to go next. I knew I wanted to learn more about how the Internet works, so I was pointed to this book. What I was really looking for were a few books on how to set up a web [...]]]></description>
			<content:encoded><![CDATA[<p>After I did my first ever Unix install (FreeBSD 2.2.5), I was absolutely clueless on where to go next. I knew I wanted to learn more about how the Internet works, so I was pointed to this book. What I was really looking for were a few books on how to set up a web / email / dns server but the person misunderstood me and thought I wanted something on the underlying protocols. So instead of me learning how to drive, I bought a book on car schematics and blueprints. Jesus Christ, was I confused.</p>

<p>Fast forward 3 years to when I finally had somewhat of a grasp on what I was originally looking for. Now this book made sense. It even made a ton of other things more clear. This book really is how the Internet works. Anyone who has a full time job that involves a server or networking device needs to read this book. Yes, it will hurt. Yes, you will fall asleep after every third paragraph &#8212; but you will come out a better person in the end. So much so that the next time you&#8217;re watching a tcpdump stream, you&#8217;ll be able to pick out Blonde, Brunette, Redhead.</p>
]]></content:encoded>
			<wfw:commentRss>http://joe.topjian.net/reviews/tcpip-illustrated-volume-1.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Spring Into Technical Writing</title>
		<link>http://joe.topjian.net/reviews/spring-into-technical-writing.html</link>
		<comments>http://joe.topjian.net/reviews/spring-into-technical-writing.html#comments</comments>
		<pubDate>Thu, 23 Jul 2009 02:41:27 +0000</pubDate>
		<dc:creator>joe</dc:creator>
				<category><![CDATA[Reviews]]></category>

		<guid isPermaLink="false">http://joe.topjian.net/?p=164</guid>
		<description><![CDATA[I originally saw this book over at Rootprompt and decided to read it myself. Overall, it&#8217;s a nice book. Some of the topics it covers might seem common sense, but after they sink in, you think, &#8220;Yeah! That&#8217;s a good idea!&#8221;

Some of the more notable parts of the book were the sections on figures, tables, [...]]]></description>
			<content:encoded><![CDATA[<p>I originally saw this book over at Rootprompt and decided to read it myself. Overall, it&#8217;s a nice book. Some of the topics it covers might seem common sense, but after they sink in, you think, &#8220;Yeah! That&#8217;s a good idea!&#8221;</p>

<p>Some of the more notable parts of the book were the sections on figures, tables, and lists; typograhphy and formatting; and types of documents to write.</p>

<p>Concerning the Tables and Lists, Rosenberg explained clean formatting, headings, and what to do when full sentences proceed lists. The typography and formatting piece gave a nice explanation of serif and sans-serif fonts and when (and when not) to use them. Finally, the types of documents received the biggest portion of the book. Examples of lab reports, manuals, proposals, and even PowerPoint presentations were given. Having reference to all of these documents in one book is really nice. The proposal part was the most detailed of all the other types &#8212; with good reason! There are several different types of proposals you can make and anytime you write a proposal, chances are it has a lot of importance.</p>

<p>Like I mentioned in the beginning, this was a nice book. There were a bunch of other little topics covered such as punctuation and vocab, but I think they weren&#8217;t given a lot of attention because of the myriad of other books written on these subjects.</p>
]]></content:encoded>
			<wfw:commentRss>http://joe.topjian.net/reviews/spring-into-technical-writing.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
