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

<channel>
	<title>The blog of Karl Majer... &#187; Work</title>
	<atom:link href="http://www.karlmajer.com/category/work/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.karlmajer.com</link>
	<description>Life on my own terms...</description>
	<lastBuildDate>Mon, 28 Mar 2011 17:04:40 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.4</generator>
		<item>
		<title>Dell Streak OEM Version Codes</title>
		<link>http://www.karlmajer.com/2011/02/08/dell-streak-oem-version-codes/</link>
		<comments>http://www.karlmajer.com/2011/02/08/dell-streak-oem-version-codes/#comments</comments>
		<pubDate>Wed, 09 Feb 2011 01:54:08 +0000</pubDate>
		<dc:creator>Karl Majer</dc:creator>
				<category><![CDATA[Android]]></category>
		<category><![CDATA[Mobile Devices]]></category>

		<guid isPermaLink="false">http://www.karlmajer.com/?p=158</guid>
		<description><![CDATA[I&#8217;ve been doing quite a bit of work on modifying the Dell Streak for one of my clients. The problem is that while there are quite a few images out there available to download, I wasn&#8217;t able to find any key mapping OEM version to telco carrier so I could figure out which telco&#8217;s handset [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been doing quite a bit of work on modifying the Dell Streak for one of my clients. The problem is that while there are quite a few images out there available to download, I wasn&#8217;t able to find any key mapping OEM version to telco carrier so I could figure out which telco&#8217;s handset I was modifying. I&#8217;ve finally tracked it down and this should hopefully save others some pain:</p>
<p>Last 2 digits of OEM String &#8211; Carrier<br />00 &#8211; Unlocked<br />21 &#8211; O2 UK<br />31 &#8211; AT&amp;T<br />32 &#8211; Rogers<br />33 &#8211; T-Mobile</p>
<p>Enjoy,</p>
<p>Karl</p>
]]></content:encoded>
			<wfw:commentRss>http://www.karlmajer.com/2011/02/08/dell-streak-oem-version-codes/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Quick root on Nexus S</title>
		<link>http://www.karlmajer.com/2011/01/29/quick-root-on-nexus-s/</link>
		<comments>http://www.karlmajer.com/2011/01/29/quick-root-on-nexus-s/#comments</comments>
		<pubDate>Sat, 29 Jan 2011 18:53:35 +0000</pubDate>
		<dc:creator>Karl Majer</dc:creator>
				<category><![CDATA[Android]]></category>
		<category><![CDATA[Hacking]]></category>
		<category><![CDATA[Mobile Devices]]></category>
		<category><![CDATA[Work]]></category>
		<category><![CDATA[nexusS]]></category>

		<guid isPermaLink="false">http://www.karlmajer.com/?p=151</guid>
		<description><![CDATA[Capturing some data here so that its not lost when I go looking for it again. I discovered quite by accident that the Clockwork recovery image allows adb to connect to it while sitting at the recovery menu. The adb shell is a root shell. You can use clockwork to mount whatever filesystems you may [...]]]></description>
			<content:encoded><![CDATA[<p>Capturing some data here so that its not lost when I go looking for it again.</p>
<p>I discovered quite by accident that the Clockwork recovery image allows adb to connect to it while sitting at the recovery menu. The adb shell is a root shell. You can use clockwork to mount whatever filesystems you may need to work on. This means that you can take any of the su binaries floating around the net, or even hack a bit and then build the su thats in the Android tree,  and dump it in /system/bin/su while in the recovery menu and then chmod it 4755 to suid it root.</p>
<p>So basically:</p>
<ul>
<li>boot nexus S into fastboot with vol up and  power</li>
<li>pick recovery off the menu</li>
<li>from the recovery menu:
<ul>
<li>mount /system partition</li>
</ul>
</li>
<li>from adb:
<ul>
<li>adb push /path/to/your/su/binary  /system/bin/su</li>
<li>adb shell
<ul>
<li>chmod 4755 /system/bin/su</li>
</ul>
</li>
</ul>
</li>
<li>from the recovery menu:
<ul>
<li>reboot device</li>
</ul>
</li>
</ul>
<p>When the handset comes back up, adb in as normal, and then issue an su command and you should be root.</p>
<p>&gt;&gt;&gt;Karl</p>
]]></content:encoded>
			<wfw:commentRss>http://www.karlmajer.com/2011/01/29/quick-root-on-nexus-s/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Setting up a Android (Froyo) build environment on EC2</title>
		<link>http://www.karlmajer.com/2011/01/21/setting-up-a-android-froyo-build-environment-on-ec2/</link>
		<comments>http://www.karlmajer.com/2011/01/21/setting-up-a-android-froyo-build-environment-on-ec2/#comments</comments>
		<pubDate>Fri, 21 Jan 2011 16:39:15 +0000</pubDate>
		<dc:creator>Karl Majer</dc:creator>
				<category><![CDATA[Android]]></category>
		<category><![CDATA[Mobile Devices]]></category>
		<category><![CDATA[Froyo]]></category>

		<guid isPermaLink="false">http://www.karlmajer.com/?p=149</guid>
		<description><![CDATA[I had to prep an EC2 instance for some Android handset build work I&#8217;m doing for a client. My VMs weren&#8217;t cutting it anymore. This is basically me documenting the quick and dirty steps required to prep an Ubuntu 10.04 instance on EC2 (AMI: be0ffed7). I&#8217;m assuming you have basic knowledge of how to use EC2, [...]]]></description>
			<content:encoded><![CDATA[<p>I had to prep an EC2 instance for some Android handset build work I&#8217;m doing for a client. My VMs weren&#8217;t cutting it anymore. This is basically me documenting the quick and dirty steps required to prep an Ubuntu 10.04 instance on EC2 (AMI: be0ffed7).</p>
<p>I&#8217;m assuming you have basic knowledge of how to use EC2, but if not, in very very generalized terms (and from memory):</p>
<ul>
<li>Go register for an account</li>
<li>Add EC2 to your account</li>
<li>Select the EC2 dashboard.</li>
<li>Select volumes and create an EBS volume for your build partition.
<ul>
<li> I used a 50G partition</li>
</ul>
</li>
<li>Select AMIs and search for the particular flavor of Ubuntu you&#8217;re after
<ul>
<li>You may need to change the filters at the top of the results box to get it to display all of the options, I believe it defaults on just your own.</li>
<li>I used 10.04 64 bit ami, specifically ami-be0ffed7</li>
<li>Make sure its an EBS ami and not an instance image, the difference being the EBS is permanent and your changes will not be lost across reboots</li>
</ul>
</li>
<li>Hit the launch button and then answer the questions about the type of machine you wish to run on.</li>
<li>You will need to create a set of keypairs used to log in to the machine once its up on the network. </li>
<li>You will also probably be asked questions about the security groups at some point during the question and answer process. 
<ul>
<li>All I did for my EC2 instance was add ssh so I could get into it remotely. For all I know I&#8217;ve left a truck sized security hole in the config.</li>
</ul>
</li>
<li>Go back to the volumes and associate your build partition with the AMI you just built. It will ask you to assign a device path, I used /dev/sdf<br /> 
<ul>
</ul>
</li>
<li>At some point on the instances panel you will see that your instance is up and running, select the instance, select actions and pick connect. Follow the instructions and log in.
<ul>
<li>use the user ubuntu and not root.</li>
</ul>
</li>
</ul>
<p>By now you should be sitting at a prompt on your freshly started instance. Go ahead and label, mkfs, and mount the build volume and then cd into that partition.</p>
<p>I originally used the instance hosts instead of the EBS hosts, so I had to rebuild the environment every time I used the instance. I&#8217;d since figured out how to use an EBS ami but I&#8217;d done it so often that I&#8217;d written the script below to handle installing all the packages that were required. I pulled the java package from java.sun.com.</p>
<blockquote>
<p>#!/bin/sh</p>
<p>#update the repos, I had some issues with the ec2 default ubuntu repos, this fixed it.<br />sudo aptitude update</p>
<p># any bitness<br />sudo apt-get install git-core gnupg flex bison gperf libsdl-dev libesd0-dev libwxgtk2.6-dev build-essential zip curl libncurses5-dev zlib1g-dev</p>
<p>#generally useful for all<br />sudo apt-get install valgrind</p>
<p>#64bit<br />sudo apt-get install ia32-libs lib32z1-dev lib32ncurses5-dev gcc-multilib g++-multilib</p>
<p>#java<br />echo &#8220;Installing already unpackaged java to /usr/local/&#8221;<br />sudo tar -cpvf &#8211; jdk1.5.0_22 |sudo  tar -C /usr/local -xpf -</p>
<p>echo &#8220;Adding export JAVA_HOME=/usr/local/jdk1.5.0_22 to your .bashrc&#8221;<br />echo &#8220;Adding export ANDROID_JAVA_HOME=\$JAVA_HOME to your .bashrc&#8221;</p>
<p>echo &#8220;export JAVA_HOME=/usr/local/jdk1.5.0_22&#8243; &gt;&gt; ~/.bashrc<br />echo &#8220;export ANDROID_JAVA_HOME=\$JAVA_HOME &#8221; &gt;&gt; ~/.bashrc</p>
<p>echo &#8220;Updating your path&#8221;<br />echo &#8220;export PATH=/build/codeaurora/prebuilt/linux-x86/toolchain/arm-eabi-4.4.0/bin/:/usr/local/jdk1.5.0_22/bin:$PATH&#8221; &gt;&gt; ~/.bashrc~</p>
</blockquote>
<p>Now you should be able to checkout and build whatever flavor of Android you&#8217;re working with. I used the froyo-almod from the codeaurora forums.</p>
<p>&gt;&gt;&gt;Karl</p>
]]></content:encoded>
			<wfw:commentRss>http://www.karlmajer.com/2011/01/21/setting-up-a-android-froyo-build-environment-on-ec2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>ADB on VMWare Fusion &#124;&#124; CentOS</title>
		<link>http://www.karlmajer.com/2011/01/11/adb-on-vmware-fusion-centos/</link>
		<comments>http://www.karlmajer.com/2011/01/11/adb-on-vmware-fusion-centos/#comments</comments>
		<pubDate>Tue, 11 Jan 2011 15:24:42 +0000</pubDate>
		<dc:creator>Karl Majer</dc:creator>
				<category><![CDATA[Android]]></category>
		<category><![CDATA[Hacking]]></category>
		<category><![CDATA[Virtualization]]></category>
		<category><![CDATA[Hardware Hacking]]></category>

		<guid isPermaLink="false">http://www.karlmajer.com/?p=147</guid>
		<description><![CDATA[A note to myself really, I was trying to get ADB to run on both my CentOS 5.5 machine and a VMWare Fusion Virtual Machine running Ubunto. Both flavors of linux protested my using adb with something along the lines of: majer@ubuntu:~/android$ sudo ~/bin/adb devices List of devices attached ????????????    no permissions   After a [...]]]></description>
			<content:encoded><![CDATA[<p>A note to myself really, I was trying to get ADB to run on both my CentOS 5.5 machine and a VMWare Fusion Virtual Machine running Ubunto. Both flavors of linux protested my using adb with something along the lines of:</p>
<blockquote>
<pre>majer@ubuntu:~/android$ sudo ~/bin/adb devices</pre>
<pre>List of devices attached ????????????    no permissions</pre>
<pre> </pre>
</blockquote>
<p>After a considerable amount of digging I found the one line change that needed to be made on both OSes. Add the following to /etc/udev/rules.d/51-android.rules:</p>
<blockquote>
<pre>SUBSYSTEM=="usb", SYSFS{idVendor}=="0bb4", MODE="0666"
</pre>
</blockquote>
<p>And then restart the adb services with a:</p>
<blockquote>
<pre>[majer@ubuntu:~/android/] sudo ~/bin/adb kill-server</pre>
<pre>[majer@ubuntu:~/android/] sudo ~/bin/adb start-server
</pre>
</blockquote>
<p>The adb command will work as expected now.</p>
<p>&gt;&gt;&gt; Karl</p>
]]></content:encoded>
			<wfw:commentRss>http://www.karlmajer.com/2011/01/11/adb-on-vmware-fusion-centos/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>A Week with an iPad</title>
		<link>http://www.karlmajer.com/2010/04/10/a-week-with-an-ipad/</link>
		<comments>http://www.karlmajer.com/2010/04/10/a-week-with-an-ipad/#comments</comments>
		<pubDate>Sat, 10 Apr 2010 13:30:06 +0000</pubDate>
		<dc:creator>Karl Majer</dc:creator>
				<category><![CDATA[Mobile Devices]]></category>
		<category><![CDATA[Play]]></category>
		<category><![CDATA[iPhone/iPad]]></category>

		<guid isPermaLink="false">http://www.karlmajer.com/2010/04/10/a-week-with-an-ipad/</guid>
		<description><![CDATA[So I&#8217;ve had an iPad for a week now. I&#8217;m one of those that pre-ordered the device shortly after they were available on the Apple store. I thought I&#8217;d take a moment and jot down my thoughts on the device in no particular order. Context is everything with this device. If you were hoping to [...]]]></description>
			<content:encoded><![CDATA[<p>So I&#8217;ve had an iPad for a week now. I&#8217;m one of those that pre-ordered the device shortly after they were available on the Apple store. I thought I&#8217;d take a moment and jot down my thoughts on the device in no particular order.</p>
<p>Context is everything with this device. If you were hoping to replace a laptop or skip out on getting that netbook by buying an iPad, I&#8217;m afraid you&#8217;re in for a rude awakening. I have gotten in the habit of reading technical manuals on my laptop prior to going to bed at night. I wanted to simplify things and purchase something smaller and lighter to let me continue my light reading in the evenings. I contemplated buying a Kindle at first, but decided to hold off after Apple first made mention of their device. </p>
<p>With that point of view in mind, the device has been quite successful in meeting, if not exceeding, my expectations. I have iBooks, Kindle for iPad, and GoodReader for iPad installed on the iPad and between the three applications, there is little I cannot read. I do wish that the iTunes Bookstore carried technical books, but I can always pull down the kindle versions of those, or buy pdf versions and view them in GoodReader. </p>
<p>Just a quick kudos to the GoodReader guys. The app offers almost a dozen different ways to get data into it from your iPad. When I first tried it, I was having issues with the iTunes integrated sync, but then realized that the app has an integrated webserver that can be connected to as a network folder (I&#8217;m on a mac) and then it was literally just drag and drop. I&#8217;ve also have yet to find a pdf that it can&#8217;t open and read. Well done guys.</p>
<p>So, using the iPad as an ebook works splendidly. The screen doesn&#8217;t require ambient light like the kindle does, and the controls on the various readers let you adjust the brightness/contrast as needed. I&#8217;ve already chewed through a few books in my nightly habit of reading for at least an hour.</p>
<p>As to the bonuses, the iPad is just the right size to comfortably lay in bed and watch content from iTunes U. Some of the Stanford lectures are outstanding and are free as an added bonus. I have also found its just the right size to keep up with my RSS feeds that I tend to consume as well.  And when I feel like relaxing, the free Netflix client (account required) streams a decent selection of movies right to me.</p>
<p>There are a few downsides. The iWorks suite that can be purchased is tolerable at best on the virtual keyboard. I&#8217;m used to Excel and so caught a double whammy with the mind shift to how Numbers does things, and not having a full keyboard for data entry. Keynote was actually the best of the three, I was able to throw together a quick presentation without too much effort, and Pages works fine for a quick note, but I wouldn&#8217;t want to try and take notes in a class or a meeting on the device. I can almost touch type on the virtual keyboard until I hit a need for a special character. Then you&#8217;re flipping to another keyboard screen to get access to those. They should really move the apostrophe to the first keyboard.</p>
<p>So as I said, based on what I intended to use the device for,  the iPad exceeds my expectations. I know there are other people whining about not being able to code on it, and/or it still being limited because its running iPhoneOS instead of MacOSX (which would have absolutely rocked), but frankly, at the end of the day I&#8217;d rather read a book than stare at more code.</p>
<p>&gt;&gt;&gt; Karl</p>
]]></content:encoded>
			<wfw:commentRss>http://www.karlmajer.com/2010/04/10/a-week-with-an-ipad/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Fun with macs, CACs, and Certs (and iPhone dev).</title>
		<link>http://www.karlmajer.com/2010/02/23/fun-with-macs-cacs-and-certs-and-iphone-dev/</link>
		<comments>http://www.karlmajer.com/2010/02/23/fun-with-macs-cacs-and-certs-and-iphone-dev/#comments</comments>
		<pubDate>Tue, 23 Feb 2010 14:47:09 +0000</pubDate>
		<dc:creator>Karl Majer</dc:creator>
				<category><![CDATA[Coding]]></category>
		<category><![CDATA[Mobile Devices]]></category>
		<category><![CDATA[Systems Administration]]></category>
		<category><![CDATA[Work]]></category>
		<category><![CDATA[iPhone/iPad]]></category>
		<category><![CDATA[cac cards]]></category>
		<category><![CDATA[iphone]]></category>
		<category><![CDATA[win7]]></category>

		<guid isPermaLink="false">http://www.karlmajer.com/?p=132</guid>
		<description><![CDATA[Just a quick post to save others some time and a little pain: OSX 10.6.2 + SCR3110 CAC reader + new GX4 CAC card == No love on OSX. Keychain sees the card as empty. However, 10.6.2 + VMWare + win7-64 + reader + CAC card + IE works just fine without any of the [...]]]></description>
			<content:encoded><![CDATA[<p>Just a quick post to save others some time and a little pain:</p>
<p>OSX 10.6.2 + SCR3110 CAC reader + new GX4 CAC card == No love on OSX. Keychain sees the card as empty.</p>
<p>However, 10.6.2 + VMWare + win7-64 + reader + CAC card + IE works just fine without any of the add-on software used on XP. You&#8217;ll need to pass the reader through to the VM by clicking on the little USB icons in the bottom right.</p>
<p>On another note, a Verisign EAC Certificate loaded in your keychain will cause codesign to hang for 8-10 minutes while it asks oscpd to validate the cert. This also happens when you use Keychain Access to go try and figure out why its taking so long to sign things. Work around it by either dropping your network when you need to sign things, or more permanently, drop your network and then use Keychain Access to remove the cert altogether. Save yourself the pain and load the EAC cert directly into firefox and use that browser to access the EAC enabled sites.</p>
<p>And finally, if you have the reader plugged in with a card in it and try to sign an iPhone application you will probably get the error: CSSMERR_DL_MISSING_VALUE. Keychain Access on 10.6.2 recognizes the reader and if the card is plugged in, Keychain Access seems to want to try and use it for signing. Take the card out of the reader and try again.</p>
<p>>>> Karl</p>
]]></content:encoded>
			<wfw:commentRss>http://www.karlmajer.com/2010/02/23/fun-with-macs-cacs-and-certs-and-iphone-dev/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Experiences with cfengine.</title>
		<link>http://www.karlmajer.com/2008/05/19/experiences-with-cfengine/</link>
		<comments>http://www.karlmajer.com/2008/05/19/experiences-with-cfengine/#comments</comments>
		<pubDate>Mon, 19 May 2008 12:45:19 +0000</pubDate>
		<dc:creator>Karl Majer</dc:creator>
				<category><![CDATA[Systems Administration]]></category>
		<category><![CDATA[Work]]></category>
		<category><![CDATA[Cfengine]]></category>

		<guid isPermaLink="false">http://www.karlmajer.com/?p=27</guid>
		<description><![CDATA[At a customer site I’ve had both the pleasure and pain of working with cfengine as a means to control the environment from a single touchpoint. The client decided to save the precious little time they had and to use readily available packages for the software instead of building the software from scratch. This resulted [...]]]></description>
			<content:encoded><![CDATA[<p>At a customer site I’ve had both the pleasure and pain of working with cfengine as a means to control the environment from a single touchpoint. The client decided to save the precious little time they had and to use readily available packages for the software instead of building the software from scratch. This resulted in mixed versions between the RedHat and Solaris machines with RedHat running the 2.2.x series code and Solaris on 2.1.x. What followed over the months were several exercises in frustration.<br />
Cfengine was picked after an evaluation showed that it was capable of updating system files across machines and pushing files from the repository to the individual hosts. With the proof of concept working and with high hopes from the functionality referred to in the documentation, cfengine was rolled onto the network.<br />
The first task was relatively straightforward; insure that the staff member’s logins were always present in the sudoers file. The site was using several group aliases to define various sudoers functions, which leaded to order dependencies in the file. The solution found was to delete all of the aliases and groups definitions and re-add them each pass. This was found to work until it was realized that this would happen from cron every 15 minutes. Not quite what was hoped for. The configuration was ultimately altered to explicitly look for a lack of team members before beginning any of the updates.<br />
The next task was to distribute a dozen or so files from the central repository to all 250 or so machines. This worked almost perfectly and required only a bit of tuning on the MaxConnections, MaxCfengins, and Splay time directives. The current challenge with this task now is to ensure that all of the installed machines do the pull on an update as it seems that occasionally some small percentage of them, typically Solaris, refuse to pull the files without some manual cfrun intervention.<br />
An Editfiles directive is provided to allow the editing of arbitrary files. Using this for the next task, editing the crontab on linux was straightforward and linux cron noticed the change immediately. On solaris this was not the case. Editing the files was the easy part. After editing the file the cron daemon needs to be made aware of the change, and so either the process needs to be restarted or the crontab command needs to be used to reread the file. Unfortunately, the Process directive proved to be little use on the older cfengine and the Shell directive was used to write custom inline shell scripts to handle the stopping and starting of cron.<br />
The most recent change to the network involved manipulating the fstab on both OSes, removing an NFS mount, and then changing the former mount point from a directory to a symlink. There is an Unmount directive that would have worked beautifully had it worked on both OSes. It worked fine with Linux, unmounting the FS and deleting the entry and directory for us. Sadly, on Solaris it did nothing. To promote overall consistency it was opted to do manipulations on both operating systems in the same manner. An Editfiles stanza was used to manipulate the (v)fstabs, while a long chain of shell commands to ensure that the filesystem was unmounted, the fstabs were edited, and the symlink was created. Each component set a success or failure flag to enable the script to proceed to the next step or fail and alert as the case may be. This is probably the most complex script used at the customer site.<br />
I’m unable to say for certain how much of the pain with the software is caused by the mixed versions being used on the network. It could be that if there was time to build and upgrade the software across the machines to the same version that the problems would magically disappear. It could also be that while powerful and seemingly capable, cfengine does things in a slightly different manner than a sysadmin, making the would-be cfengine administrator configuring it have to double check everything they write. (An example of this is the symlink directive which uses target-&gt;source whereas the ln command uses source-&gt;target.) Documentation and error reporting for the product was also a challenge, especially with the mixed version. The version specific source was often referred to understand what an error means or to determine why a specific section of code was being ignored. Cfengine will remain in place at the customer site for the foreseeable future, as despite its issues it is still better than touching each machine individually. Only time will tell if a complete upgrade to a consistent version will remove some of the pain or if this is simply the way of cfengine.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.karlmajer.com/2008/05/19/experiences-with-cfengine/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Performance Testing &#8211; Tools of the Trade</title>
		<link>http://www.karlmajer.com/2008/02/18/performance-testing-tools-of-the-trade/</link>
		<comments>http://www.karlmajer.com/2008/02/18/performance-testing-tools-of-the-trade/#comments</comments>
		<pubDate>Tue, 19 Feb 2008 04:15:20 +0000</pubDate>
		<dc:creator>Karl Majer</dc:creator>
				<category><![CDATA[Systems Administration]]></category>
		<category><![CDATA[Work]]></category>
		<category><![CDATA[perf testing]]></category>

		<guid isPermaLink="false">http://www.karlmajer.com/2008/02/18/performance-testing-tools-of-the-trade/</guid>
		<description><![CDATA[In the previous article we covered a brief load test scenario. It involved running load against a webserver and driving the server to failure to determine its capacity. What I did not discuss were the specific tools that could have been used during the testing period. Client Side: Wget – A non-interactive command line tool [...]]]></description>
			<content:encoded><![CDATA[<p>In the previous article we covered a brief load test scenario. It involved running load against a webserver and driving the server  to failure to determine its capacity. What I did not discuss were the specific tools that could have been used during the testing period.</p>
<p>Client Side:</p>
<p>Wget – A non-interactive command line tool to fetch https, http, and ftp items. It can easily be run from inside a script in a tight loop or used in recursive/mirror mode for crawling. It can be found at http://www.gnu.org/software/wget/.<br />
cURL- Another non-interactive command line tool. Much more extensive in its protocol support.  Available from http://curl.haxx.se/.  This tool was designed to fetch single URLs. It requires integration into a script to mirror/copy websites if such a behavior is desired.</p>
<p>The server side has several options depending on the OS being run. There are a few commands that are present on all OSes by default, and then there are OS specific commands as well.</p>
<p>Server Side:</p>
<p>Iostat provides thorough IO statstics for the machine. The command is native on Solaris as well as linux with the installation of the sysstat package. After watching the output run over time you can tell if the disk is lightly used, overloaded, or somewhere in-between. You can also tell if the drives are overwhelmed with many small transactions or content with large streaming writes. This is a good all round tool to get familiar with.</p>
<p>Next in line in the *stat family is vmstat. While iostat gives us a view into the disk subsystem, vmstat provides similar insight into the memory subsystem on the host. The command is natively present on Solaris and Linux. Vmstat is capable of showing you statistics on swap, memory paging characteristics, memory fault characteristics, and some additional information about run queues on the machine and CPU utilization. This is another good general tool to be familiar with.</p>
<p>Top is the next tool I used, and is probably the single most popular tool for getting an at-a-glance view to what the system is doing. It is a curses based application that periodically updates itself and constantly shows the top 20ish running items sorted by CPU utilization. While present in Linux, the application is not in the default Solaris installation. www.sunfreeware.com offers the package for download. Top typically requires minimal skill to interpret its output which makes it a good first line tool to see why a machine is behaving oddly.</p>
<p>Solaris offers two additional tools for observing system behavior: prstat and mpstat [edit: Seems Linux offers mpstat as well. It contains similar information to the Solaris version].</p>
<p>Prstat is very similar to top and shows  the top 20 or so processes by CPU utilization but through various command line options, can provide insight into threads and offer microstate accounting information  as well.</p>
<p>Mpstat is more in line with the vm/iostat line of commands and shows per cpu, or  processor set, statistics such as context switches, systems calls, etc.  The command can be used to determine if an application is thrashing the cpus in the machine or generally what the machine&#8217;s CPUs are doing.</p>
<p>Netstat is a utility which allows the user to see what the network stack on a machine is doing. It is useful for looking at the number of open sessions as well as the number of sessions in TIME_WAIT.</p>
<p>Finally, the sar command is also available to see what a given host is doing. The command is natively present on both linux and solaris. I personally tend not to use that as I can generally determine what I need from watching the *stat commands .</p>
<p>There is one additional tool which I use on Solaris and OSX, and that is dtrace. Dtrace is capable of instrumenting virtually anything on the fly and can provide amazing insight into what an application, or even the host, is doing at that moment without resulting to the instrumentation of binaries or adding typical splatterprint debug code to the binaries.</p>
<p>Essentially, I use the commands in approximately this order: top/prstat first to get a general overview of what the machine is doing. For more insight I open additional sessions on the machine and run iostat, vmstat, netstat, and possibly mpstat if available. Finally if I&#8217;m still unable to determine what the host is doing, and the server is running Solaris or OSX, I&#8217;ll use dtrace to look into the kernel or at the application for insight into whatever problem I&#8217;m chasing.</p>
<p>Whichever commands you decide to use, and whatever order you run them in, keep in mind one important point. Observing an experiment can affect the output of said experiment. This means that running all of those tools on a very burdened server may be enough to push the machine over the edge of unresponsiveness.</p>
<p>This concludes our brief introduction to the tools of the trade. If there is a demand and time permits I intend to write articles on the best practices for each of the commands.</p>
<p>If you like what you’ve read, please share the blog with others. If you have any questions or comments, feel free to send me email at kmajer at karlmajer dot com.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.karlmajer.com/2008/02/18/performance-testing-tools-of-the-trade/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Performance Testing &#8211; First Example &#8211; Notes</title>
		<link>http://www.karlmajer.com/2008/02/04/performance-testing-first-example-notes/</link>
		<comments>http://www.karlmajer.com/2008/02/04/performance-testing-first-example-notes/#comments</comments>
		<pubDate>Mon, 04 Feb 2008 12:05:41 +0000</pubDate>
		<dc:creator>Karl Majer</dc:creator>
				<category><![CDATA[Systems Administration]]></category>
		<category><![CDATA[Work]]></category>
		<category><![CDATA[estimation]]></category>
		<category><![CDATA[perf testing]]></category>

		<guid isPermaLink="false">http://www.karlmajer.com/2008/02/04/performance-testing-first-example-notes/</guid>
		<description><![CDATA[In our first example we did several things that I perhaps took for granted. A reader asked why I chose to use CLI load generation tools instead of surfing with a browser, and if the initial numbers generated are even reasonable. Allow me to address both points. There is nothing stopping a tester from performing [...]]]></description>
			<content:encoded><![CDATA[<p>In our first example we did several things that I perhaps took for granted. A reader asked why I chose to use CLI load generation tools instead of surfing with a browser, and if the initial numbers generated are even reasonable.  Allow me to address both points.</p>
<p>There is nothing stopping a tester from performing their load test using a browser or other GUI based load generation tool. Providing the tool has some manner of minimal controllability and repeatability, feel free to use any tool you so desire. Should you choose to use a browser, such as Firefox, be sure to recognize that the plugins are capable of altering the behavior and characteristics of the browser considerably and all future testing would need to be done using the same exact browser, machine, and plugin combination for the numbers to be comparable.</p>
<p>Essentially, I choose to use a CLI tool, such as wget, because it behaves the same every time and I can wrap the application in a shell script to guarantee both the same behavior, and instrument things further.</p>
<p>Second, the first cut performance numbers. When trying to rapidly determine a speed of light, its more important to get to the right magnitude first and then refine than it is to try and get the exact answer on the first pass.</p>
<p>For example, we know that we cannot move more packets across the network than we can fit through a single network interface. Therefore, if the size of the interface is N bytes per second, regardless of what we do, we will never be able to push more than N+1 total bytes through the interface. Similarly, if we know that we have M sized pages, then we will never be able to push N/M pages through the interface at a single point in time.</p>
<p>What this does for us is provide an upper bound for our testing. If our results indicated that we were able to do N/M + 5302 transactions per second, we know know that something was wrong with our calculation as those last 5302 operations/second would simply not fit through the pipe. However, if our results indicated 5302, and N/M is 8192, then we know that our result is a reasonable number.</p>
<p>It is important to obtain the speed of light at the start and then refine using the bounding boxes we know to be true. This ideal holds whether testing network, disk I/O, cpu, etc. If we know what the fastest possible speed of a given component is, then we know that if our results report numbers faster than what we know to be possible, then we must question the results and find them to be true because of another reason, or discard them and start over.</p>
<p>And a few thoughts just to provide a bit of context as to when speed of light may be false. When testing disk I/O, if the file size is sufficiently small, the file will be loaded directly into the buffer cache. This is a section of machine memory dedicated to buffering all disk I/O transactions and provides access times and speeds comparable to system memory and not the disk subsystem. Ie, the speed of light for the buffer cache is based off of a 50ns access time and not an 80ms access time.</p>
<p>I’d like to thank the reader that brought the questions to me and invite others to comment or email me with any questions they may have. I can be reached at kmajer at karlmajer dot com.</p>
<p>&gt;&gt;&gt; Karl</p>
]]></content:encoded>
			<wfw:commentRss>http://www.karlmajer.com/2008/02/04/performance-testing-first-example-notes/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Performance Testing &#8211; First Example</title>
		<link>http://www.karlmajer.com/2008/02/01/performance-testing-first-example/</link>
		<comments>http://www.karlmajer.com/2008/02/01/performance-testing-first-example/#comments</comments>
		<pubDate>Fri, 01 Feb 2008 23:30:25 +0000</pubDate>
		<dc:creator>Karl Majer</dc:creator>
				<category><![CDATA[Systems Administration]]></category>
		<category><![CDATA[Work]]></category>
		<category><![CDATA[perf testing]]></category>
		<category><![CDATA[scientific method]]></category>

		<guid isPermaLink="false">http://www.karlmajer.com/2008/02/01/performance-testing-first-example/</guid>
		<description><![CDATA[This article is second in a series on performance and performance testing. The principles of the scientific method were discussed in the first article and now this article will detail a basic and slightly simplistic example of a performance task. The developers you support as a systems administrator are considering moving the static content for [...]]]></description>
			<content:encoded><![CDATA[<p>This article is second in a series on performance and performance testing. The principles of the scientific method were discussed in the first article and now this article will detail a basic and slightly simplistic example of a performance task.</p>
<p>The developers you support as a systems administrator are considering moving the static content for the company website www.somefamoussite.com to its own webserver to free up resources for the dynamic page generation and generally speed things up. They are curious how fast an apache serving only static content will be able to serve requests.</p>
<p>In order to accomplish this task, we must examine the steps of the scientific method and see how each plays its part in providing us a sound and thorough roadmap to provide the developers with their answer.</p>
<ol>
<li><strong>First, define the question:</strong> “<em>How fast can an apache webserver go serving static content.</em>”</li>
<li><strong>Next gather information and resources:</strong></li>
<p>It would benefit us to know the number of static items and the size of them to determine how best to answer the question, so we ask development that question and are handed a tarball containing 256 images with an average size of 6k each.</p>
<p>Since we setup the hardware that is being used, we know that the servers have gigabit ethernet cards in them.  	We also expand the tarball into the tree on our webserver and use a find to create a logfile full of relative links to use to fetch the static content.</p>
<blockquote><p> 	find . -type f | awk ‘{print “/path/to/images/$1”}’ &gt; logfile.out<br />
cat logfile.out logfile.out logfile.out logfile.out &gt; logfile.1k<br />
cat logfile.1k logfile.1k logfile.1k logfile.1k &gt; logfile.4k<br />
cat logfile.4k logfile.4k logfile.4k logfile.4k &gt; logfile.16k</p></blockquote>
<li><strong>Form the hypothesis:</strong></li>
<p>Based on an average size of 6KBytes, and knowing that the hardware has gigabit ethernet, we can compute that in lab conditions with perfect network, the machines can do no more than approximately 21,845 requests/second.</p>
<p>( (1Gbit/sec == 128 MBytes/sec) / 6KBytes avg size == 21,845.3 objects/sec)</p>
<p>Our hypothesis, therefore, based solely on the network capacity of the hardware, is “<em>A server can do no more than 21,845 operations/second.</em>”</p>
<li><strong>Perform the experiment(s) and collect data:</strong></li>
<p>You&#8217;ll want to run top on the webserver to get a rough idea of how much free cpu there is.</p>
<p>Copy the logfile.16k to each of the load generators. In this example there will be 4 load generators.</p>
<p>Use wget on one of the load generators to mark the logfile with something we can search for later.</p>
<blockquote><p>wget http://www.myserver.com/images/TESTSTARTEDHERE</p></blockquote>
<p>Use wget on each load generator to fetch the images</p>
<blockquote><p>wget -i logfile.16k -o wget.out</p></blockquote>
<p>Fire off all four wget’s at the same time and let it run.</p>
<p>Watch top running on the webserver and keep rough track of our idle cpu. Time passes and the load generators will eventually run out of logs, probably within a few minutes.</p>
<p>Use wget to mark the logfile again.</p>
<blockquote><p>	wget http://www.myserver.com/images/TETENDEDHERE</p></blockquote>
<li><strong>Analyze the data:</strong></li>
<p>With each load generator having a 16k logfile, we had the potential load capability of 64k instantaneous requests. This is unlikely, however, as there is a certain amount of overhead between requests that must be accounted for. A reasonable assumption would be that each generator could generate close to 8k instantaneous requests, the four of which still totaling over the ~22k maximum of the network.</p>
<p>Using the logfile from the apache we can determine how much traffic we received.</p>
<p>First use sed or perl or your language of choice and extract the logfile.</p>
<blockquote><p>	sed -n /TESTSTARTEDHERE/,/TESTENDEDHERE/p access.log &gt; test.log</p></blockquote>
<p>Next determine the starting time by looking at the next line after STARTED line in the test.log and looking at the timestamp on the line</p>
<blockquote><p>	head -2 test.log</p></blockquote>
<p>Do the same for the ending time by looking at the second to last line of test.log.</p>
<blockquote><p>	tail -2 test.log</p></blockquote>
<p>Determine the total test time by subtracting the two times from each other.</p>
<p>Determine the total number of lines in the logfile and removing 2 for the header and footers.</p>
<blockquote><p>	wc -l test.log</p></blockquote>
<p>This will likely be 64k unless you interrupted the test prematurely.</p>
<p>Now extract the successful image retrievals using grep.</p>
<blockquote><p>	grep “HTTP/…. 200” test.log &gt; 200.log</p></blockquote>
<p>Count the number of successful requests</p>
<blockquote><p>	wc -l 200.log</p></blockquote>
<p>Now compute the average request speed</p>
<blockquote><p> Good Requests / Total Time in minutes == Average Good Requests/Minute</p></blockquote>
<p>Next, determine the number of requests per unit. Typically a 5 minute unit works best but for simplicity we will use a 1 minute unit.<br />
Extract column 4 (the timestamp in a CLF apache log) from the 200.log file</p>
<blockquote><p>	awk ‘{print $4}’ 200.log &gt; timestamp.out</p></blockquote>
<p>Truncate the seconds from the logfile using either cut or awk</p>
<blockquote><p>	cut -d: -f 1,2,3 timestamp.out &gt; trunctime.out</p></blockquote>
<p>Uniq and count the truncated timestampts to get the number occuring during each minute:</p>
<blockquote><p>	uniq -c trunctime.out &gt; counttime.out</p></blockquote>
<p>Now reverse the two columns to make the graphic easier and add a closing bracket.</p>
<blockquote><p>	 awk ‘{print $2”] ”$1}’ counttime.out &gt; graphdata.out</p></blockquote>
<p>It is now possible to look through the logfile at this time and see a rough estimate of how the webserver did, however it is more valuable if we can graph this data and examine it visually.</p>
<p>Import the data into excel, pages, or use gnuplot on the command line and plot the graph using a line graph.</p>
<p><img src="http://www.karlmajer.com/images/loadgraph.jpg" alt="Load Graph" align="middle" border="1" height="350" width="500" /></p>
<p>The graph above was manufactured to illustrate the desired point. Note that the middle of the graph plateaus around 8500 requests/second. The flatness of the graph suggests that we’ve hit a bottleneck of some point. Since we know that the network is capable of nearly 22k request/second, and the network on each load client is presumably similar, we know that we’re either hitting the limitations of the disk subsystem or that we’ve pushed the webserver out of CPU.</p>
<p>If, during the test, you saw the idle CPU approach single digits, then we have reasonable confidence that we pushed the machine to its limit of CPU otherwise we may be pushing the limits of I/O.</p>
<li><strong>Interpret the data and draw conclusions:</strong></li>
<p>Now, by using the graph, we can decide on a limit for the webserver. The flat line starts approximately around 8500 req/sec. A reasonable buffer is 10% of that number, and so we would say that the max capacity of the webserver is 7650 req/sec. If you wish to be more conservative, and you should, you could leave yourself 25% capacity and call it 6325.</p>
<p>As a general rule you want to leave sufficient capacity on the machines to handle any excess load from failed hosts. If you have 2 machines, each machine should be able to handle all of the load. If you have 3 machines, then each should be able to handle 66% of the total load, and so forth.</p>
<li><strong>Publish Findings:</strong></li>
<p>With this simplistic testing done, you could approach development and tell them that you have some confidence that based on the preliminary testing you’ve done, the webserver can do 6325 ops/sec. Additionally, you should then provide the developers with your step by step guide as to how to get their own numbers to both allow them to validate your work, and to enable them to do this level of testing on their own in the future.</ol>
<p>This concludes our first example. There are several more to come.</p>
<p>If you like what you’ve read, please share the blog with others. If you have any questions or comments, feel free to send me email at kmajer at karlmajer dot com.</p>
<p>&gt;&gt;&gt; Karl</p>
]]></content:encoded>
			<wfw:commentRss>http://www.karlmajer.com/2008/02/01/performance-testing-first-example/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

