<?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/"
	xmlns:georss="http://www.georss.org/georss" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:media="http://search.yahoo.com/mrss/"
	>

<channel>
	<title>John&#039;s Blog</title>
	<atom:link href="http://johnsofteng.wordpress.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://johnsofteng.wordpress.com</link>
	<description>http://bit.ly/e1pU0</description>
	<lastBuildDate>Tue, 01 Mar 2011 14:44:33 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.com/</generator>
<cloud domain='johnsofteng.wordpress.com' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>http://s2.wp.com/i/buttonw-com.png</url>
		<title>John&#039;s Blog</title>
		<link>http://johnsofteng.wordpress.com</link>
	</image>
	<atom:link rel="search" type="application/opensearchdescription+xml" href="http://johnsofteng.wordpress.com/osd.xml" title="John&#039;s Blog" />
	<atom:link rel='hub' href='http://johnsofteng.wordpress.com/?pushpress=hub'/>
		<item>
		<title>Useful Linux/Redhat Admin commands:chkconfig, rpm, firstboot, killproc</title>
		<link>http://johnsofteng.wordpress.com/2011/01/26/useful-linuxredhat-admin-commandschkconfig-rpm-firstboot-killproc/</link>
		<comments>http://johnsofteng.wordpress.com/2011/01/26/useful-linuxredhat-admin-commandschkconfig-rpm-firstboot-killproc/#comments</comments>
		<pubDate>Wed, 26 Jan 2011 19:58:48 +0000</pubDate>
		<dc:creator>johnsofteng</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[Services]]></category>

		<guid isPermaLink="false">http://johnsofteng.wordpress.com/?p=355</guid>
		<description><![CDATA[1. chkconfig chkconfig provides a simple command-line tool for maintaining the /etc/rc[0-6].d directory hierarchy by relieving system administrators of the task of directly manipulating the numerous symbolic links in those directories. examples: chkconfig &#8211;add servicename chkconfig &#8211;del servicename chkconfig &#8211;list Normally, we are using chkconfig to manage the initscripts of package or applications. 2. rpm [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=johnsofteng.wordpress.com&amp;blog=8263322&amp;post=355&amp;subd=johnsofteng&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>1. chkconfig</p>
<pre><strong>chkconfig</strong> provides a  simple  command-line  tool  for  maintaining  the
       /etc/rc[0-6].d  directory  hierarchy by relieving system administrators
       of the task of directly manipulating the  numerous  symbolic  links  in
       those directories.</pre>
<p>examples:</p>
<p>chkconfig &#8211;add servicename</p>
<p>chkconfig &#8211;del servicename</p>
<p>chkconfig &#8211;list</p>
<p>Normally, we are using chkconfig to manage the initscripts of package or applications.</p>
<p>2. rpm</p>
<p>RPM Package Manager is a package management system. The name RPM refers to two things: software packaged in the .rpm file format, and the package manager itself. RPM was intended primarily for GNU/Linux distributions; the file format is the baseline package format of the Linux Standard Base.<br />
Originally developed by Red Hat for Red Hat Linux, RPM is now used by many GNU/Linux distributions. It has also been ported to some other operating systems, such as Novell NetWare (as of version 6.5 SP3) and IBM&#8217;s AIX as of version 4.<br />
Originally standing for &#8220;Red Hat Package Manager&#8221;, RPM now stands for &#8220;RPM Package Manager&#8221;, a recursive acronym.</p>
<p>-  How to View Installation / Uninstallation Script Inside The RPM File ?</p>
<p>To list the package specific scriptlet(s) that are used as part of the installation and uninstallation processes pass &#8211;scripts option to rpm command. You also need to specify the following options:</p>
<pre>-q option : Query option
-p option : Query an (uninstalled) package PACKAGE_FILE. The PACKAGE_FILE may be specified as an ftp or http style URL, in which case the package header will be downloaded and querie).</pre>
<p>General syntax for uninstalled foo.rpm file</p>
<pre>$ rpm -qp --scripts foo.rpm
Find out Installation / Uninstallation scripts inside the rpm file called monit-4.9-2.el5.rf.x86_64.rpm:
$ rpm -qp --scripts monit-4.9-2.el5.rf.x86_64.rpm</pre>
<p>General syntax for installed httpd package</p>
<pre>$ rpm -q --scripts httpd</pre>
<p>3. firstboot</p>
<p>﻿﻿﻿﻿firstboot is the program that runs on the first boot of a Fedora or Red Hat Enterprise Linux system that allows you to configure more things than the installer allows.</p>
<p>4. rsyslog</p>
<p>Rsyslog has become the de-facto standard on modern Linux operating systems. It’s high-performance log processing, database integration, modularity and support for multiple logging protocols make it the sysadmin’s logging daemon of choice. The project was started in 2004 and has since then evolved rapidly.</p>
<p>The SIGHUP signal is used to reload the rsyslogd, not to kill it.</p>
<p> 5. killproc</p>
<pre><strong>killproc</strong> sends signals to all processes that use the specified executable.  If no signal name is  specified,  the
      signal  <strong>SIGTERM</strong>  is  sent. If this program is not called with the name <strong>killproc</strong> then <strong>SIGHUP</strong> is used. Note that if
      <strong>SIGTERM</strong> is used and does not terminate a process the signal <strong>SIGKILL</strong> is send after a few  seconds  (default  is  5
      seconds,  see  option <strong>-t</strong>).  If a program has been terminated successfully and a <strong>verified</strong> pid file was found, this
      pid file will be removed if the terminated process didn't already do so.</pre>
<p>References:</p>
<p><a href="http://man-wiki.net/index.php/8:killproc">http://man-wiki.net/index.php/8:killproc</a></p>
<p><a href="http://en.wikipedia.org/wiki/RPM_Package_Manager">http://en.wikipedia.org/wiki/RPM_Package_Manager</a></p>
<p><a href="http://blog.gerhards.net/2008/10/new-rsyslog-hup-processing.html">http://blog.gerhards.net/2008/10/new-rsyslog-hup-processing.html</a></p>
<p><a href="http://fedoraproject.org/wiki/FirstBoot">http://fedoraproject.org/wiki/FirstBoot</a></p>
<p><a href="http://www.cyberciti.biz/faq/rhel-list-package-specific-scriptlets/">http://www.cyberciti.biz/faq/rhel-list-package-specific-scriptlets/</a></p>
<p><a href="http://linuxcommand.org/man_pages/chkconfig8.html">http://linuxcommand.org/man_pages/chkconfig8.html</a></p>
<p><a href="http://www.linuxjournal.com/article/4445">http://www.linuxjournal.com/article/4445</a></p>
<p><a href="http://www.techrepublic.com/article/using-chkconfig-to-control-initscripts/5033660">http://www.techrepublic.com/article/using-chkconfig-to-control-initscripts/5033660</a></p>
<p><a href="http://krnjevic.com/wp/?p=76">http://krnjevic.com/wp/?p=76</a></p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/johnsofteng.wordpress.com/355/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/johnsofteng.wordpress.com/355/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/johnsofteng.wordpress.com/355/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/johnsofteng.wordpress.com/355/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/johnsofteng.wordpress.com/355/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/johnsofteng.wordpress.com/355/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/johnsofteng.wordpress.com/355/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/johnsofteng.wordpress.com/355/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/johnsofteng.wordpress.com/355/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/johnsofteng.wordpress.com/355/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/johnsofteng.wordpress.com/355/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/johnsofteng.wordpress.com/355/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/johnsofteng.wordpress.com/355/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/johnsofteng.wordpress.com/355/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=johnsofteng.wordpress.com&amp;blog=8263322&amp;post=355&amp;subd=johnsofteng&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://johnsofteng.wordpress.com/2011/01/26/useful-linuxredhat-admin-commandschkconfig-rpm-firstboot-killproc/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/53024032acd728facceb97bfe56c7bc9?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">johnsofteng</media:title>
		</media:content>
	</item>
		<item>
		<title>How to Use C&#8217;s volatile Keyword</title>
		<link>http://johnsofteng.wordpress.com/2010/04/15/how-to-use-cs-volatile-keyword/</link>
		<comments>http://johnsofteng.wordpress.com/2010/04/15/how-to-use-cs-volatile-keyword/#comments</comments>
		<pubDate>Thu, 15 Apr 2010 19:04:57 +0000</pubDate>
		<dc:creator>johnsofteng</dc:creator>
				<category><![CDATA[C/C++]]></category>
		<category><![CDATA[c]]></category>
		<category><![CDATA[embedded]]></category>
		<category><![CDATA[hardware]]></category>
		<category><![CDATA[optimize]]></category>
		<category><![CDATA[volatile]]></category>

		<guid isPermaLink="false">http://johnsofteng.wordpress.com/?p=347</guid>
		<description><![CDATA[by Nigel Jones The proper use of C&#8217;s volatile keyword is poorly understood by many programmers. This is not surprising, as most C texts dismiss it in a sentence or two. This article will teach you the proper way to do it. Have you experienced any of the following in your C or C++ embedded [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=johnsofteng.wordpress.com&amp;blog=8263322&amp;post=347&amp;subd=johnsofteng&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<div>
<p>by <a href="http://www.embeddedgurus.net/stack-overflow" target="_blank">Nigel Jones</a></p>
<p>The proper use of C&#8217;s volatile keyword is poorly understood by  many programmers. This is not surprising, as most C texts dismiss it in a  sentence or two. This article will teach you the proper way to do it.</p>
<p>Have you experienced any of the following in your C or C++ embedded code?</p>
<ul>
<li>Code that works fine&#8211;until you enable compiler optimizations</li>
<li>Code that works fine&#8211;until interrupts are enabled</li>
<li>Flaky hardware drivers</li>
<li>RTOS tasks that work fine in isolation&#8211;until some other task is spawned</li>
</ul>
<p>If you answered yes to any of the above, it&#8217;s likely that you didn&#8217;t use the  C keyword volatile. You aren&#8217;t alone. The use of volatile is poorly understood  by many programmers. Unfortunately, most books about the C programming language  dismiss volatile in a sentence or two.</p>
<p>C&#8217;s volatile keyword is a qualifier that is applied to a variable when it is  declared. It tells the compiler that the value of the variable may change at any  time&#8211;without any action being taken by the code the compiler finds nearby. The  implications of this are quite serious. However, before we examine them, let&#8217;s  take a look at the syntax.</p>
<h2>volatile keyword syntax</h2>
<p>To declare a variable volatile, include the keyword volatile before or after  the data type in the variable definition. For instance both of these  declarations will declare foo to be a volatile integer:</p>
<pre>volatile int foo;
int volatile foo;
</pre>
<p>Now, it turns out that pointers to volatile variables are very common,  especially with memory-mapped I/O registers. Both of these declarations declare  pReg to be a pointer to a volatile unsigned 8-bit integer:</p>
<pre>volatile uint8_t * pReg;
uint8_t volatile * pReg;
</pre>
<p>Volatile pointers to non-volatile data are very rare (I think I&#8217;ve used them  once), but I&#8217;d better go ahead and give you the syntax:</p>
<pre>int * volatile p;
</pre>
<p>And just for completeness, if you really must have a volatile pointer to a  volatile variable, you&#8217;d write:</p>
<pre>int volatile * volatile p;
</pre>
<p>Incidentally, for a great explanation of why you have a choice of where to  place volatile and why you should place it after the data type (for example, int  volatile * foo), read Dan Sak&#8217;s column &#8220;Top-Level cv-Qualifiers in Function  Parameters&#8221; (Embedded Systems Programming, February 2000, p. 63).</p>
<p>Finally, if you apply volatile to a struct or union, the entire contents of  the struct/union are volatile. If you don&#8217;t want this behavior, you can apply  the volatile qualifier to the individual members of the struct/union.</p>
<h2>Proper use of volatile</h2>
<p>A variable should be declared volatile whenever its value could change  unexpectedly. In practice, only three types of variables could change:</p>
<p>1. Memory-mapped peripheral registers</p>
<p>2. Global variables modified by an interrupt service routine</p>
<p>3. Global variables accessed by multiple tasks within a multi-threaded  application</p>
<p>We&#8217;ll talk about each of these cases in the sections that follow.</p>
<h3>Peripheral registers</h3>
<p>Embedded systems contain real hardware, usually with sophisticated  peripherals. These peripherals contain registers whose values may change  asynchronously to the program flow. As a very simple example, consider an 8-bit  status register that is memory mapped at address 0&#215;1234. It is required that you  poll the status register until it becomes non-zero. The naive and incorrect  implementation is as follows:</p>
<pre>uint8_t * pReg = (uint8_t *) 0x1234;

// Wait for register to become non-zero
while (*pReg == 0) { } // Do something else
</pre>
<p>This will almost certainly fail as soon as you turn compiler optimization on,  since the compiler will generate assembly language that looks something like  this:</p>
<pre>  mov ptr, #0x1234 mov a, @ptr

loop:
  bz loop
</pre>
<p>The rationale of the optimizer is quite simple: having already read the  variable&#8217;s value into the accumulator (on the second line of assembly), there is  no need to reread it, since the value will always be the same. Thus, in the  third line, we end up with an infinite loop. To force the compiler to do what we  want, we modify the declaration to:</p>
<pre>uint8_t volatile * pReg = (uint8_t volatile *) 0x1234;
</pre>
<p>The assembly language now looks like this:</p>
<pre>  mov ptr, #0x1234

loop:
  mov a, @ptr
  bz loop
</pre>
<p>The desired behavior is achieved.</p>
<p>Subtler problems tend to arise with registers that have special properties.  For instance, a lot of peripherals contain registers that are cleared simply by  reading them. Extra (or fewer) reads than you are intending can cause quite  unexpected results in these cases.</p>
<h3>Interrupt service routines</h3>
<p>Interrupt service routines often set  variables that are tested in mainline code. For example, a serial port interrupt  may test each received character to see if it is an ETX character (presumably  signifying the end of a message). If the character is an ETX, the ISR might set  a global flag. An incorrect implementation of this might be:</p>
<pre>int etx_rcvd = FALSE;

void main()
{
    ...
    while (!ext_rcvd)
    {
        // Wait
    }
    ...
}

interrupt void rx_isr(void)
{
    ...
    if (ETX == rx_char)
    {
        etx_rcvd = TRUE;
    }
    ...
}
</pre>
<p>With compiler optimization turned off, this code might work. However, any  half decent optimizer will &#8220;break&#8221; the code. The problem is that the compiler  has no idea that etx_rcvd can be changed within an ISR. As far as the compiler  is concerned, the expression !ext_rcvd is always true, and, therefore, you can  never exit the while loop. Consequently, all the code after the while loop may  simply be removed by the optimizer. If you are lucky, your compiler will warn  you about this. If you are unlucky (or you haven&#8217;t yet learned to take compiler  warnings seriously), your code will fail miserably. Naturally, the blame will be  placed on a &#8220;lousy optimizer.&#8221;</p>
<p>The solution is to declare the variable etx_rcvd to be volatile. Then all of  your problems (well, some of them anyway) will disappear.</p>
<h3>Multi-threaded applications</h3>
<p>Despite the presence of queues, pipes, and other scheduler-aware  communications mechanisms in real-time operating systems, it is still fairly  common for two tasks to exchange information via a shared memory location (that  is, a global). Even as you add a preemptive scheduler to your code, your  compiler has no idea what a context switch is or when one might occur. Thus,  another task modifying a shared global is conceptually identical to the problem  of interrupt service routines discussed previously. So all shared global  variables should be declared volatile. For example, this is asking for  trouble:</p>
<pre>int cntr;

void task1(void)
{
    cntr = 0; 

    while (cntr == 0)
    {
        sleep(1);
    }
    ...
}

void task2(void)
{
    ...
    cntr++;
    sleep(10);
    ...
}
</pre>
<p>This code will likely fail once the compiler&#8217;s optimizer is enabled.  Declaring cntr to be volatile is the proper way to solve the problem.</p>
<h2>Final thoughts</h2>
<p>Some compilers allow you to implicitly declare all variables as volatile.  Resist this temptation, since it is essentially a substitute for thought. It  also leads to potentially less efficient code.</p>
<p>Also, resist the temptation to blame the optimizer or turn it off. Modern  optimizers are so good that I cannot remember the last time I came across an  optimization bug. In contrast, I come across failures by programmers to use  volatile with depressing frequency.</p>
<p>If you are given a piece of flaky code to &#8220;fix,&#8221; perform a grep for volatile.  If grep comes up empty, the examples given here are probably good places to  start looking for problems.</p>
<hr />This article was published in the July 2001 issue of <a href="http://www.embedded.com/mag.htm" target="_blank">Embedded Systems Programming</a>. If you wish to cite  the article in your own work, you may find the following MLA-style information  helpful:</p>
<p>Jones, Nigel. &#8220;Introduction to the Volatile Keyword&#8221; Embedded  Systems Programming, July 2001</p>
</div>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/johnsofteng.wordpress.com/347/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/johnsofteng.wordpress.com/347/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/johnsofteng.wordpress.com/347/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/johnsofteng.wordpress.com/347/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/johnsofteng.wordpress.com/347/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/johnsofteng.wordpress.com/347/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/johnsofteng.wordpress.com/347/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/johnsofteng.wordpress.com/347/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/johnsofteng.wordpress.com/347/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/johnsofteng.wordpress.com/347/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/johnsofteng.wordpress.com/347/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/johnsofteng.wordpress.com/347/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/johnsofteng.wordpress.com/347/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/johnsofteng.wordpress.com/347/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=johnsofteng.wordpress.com&amp;blog=8263322&amp;post=347&amp;subd=johnsofteng&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://johnsofteng.wordpress.com/2010/04/15/how-to-use-cs-volatile-keyword/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/53024032acd728facceb97bfe56c7bc9?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">johnsofteng</media:title>
		</media:content>
	</item>
		<item>
		<title>Thrift vs. Protocol Buffers</title>
		<link>http://johnsofteng.wordpress.com/2010/03/21/thrift-vs-protocol-buffers/</link>
		<comments>http://johnsofteng.wordpress.com/2010/03/21/thrift-vs-protocol-buffers/#comments</comments>
		<pubDate>Sun, 21 Mar 2010 23:22:35 +0000</pubDate>
		<dc:creator>johnsofteng</dc:creator>
				<category><![CDATA[Computer Science]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[facebook]]></category>
		<category><![CDATA[Google]]></category>
		<category><![CDATA[protocol buffer]]></category>
		<category><![CDATA[thrift]]></category>

		<guid isPermaLink="false">http://johnsofteng.wordpress.com/2010/03/21/thrift-vs-protocol-buffers/</guid>
		<description><![CDATA[Google recently released its Protocol Buffers as open source. About a year ago, Facebook released a similar product called Thrift. I’ve been comparing them; here’s what I’ve found: Thrift Protocol Buffers Backers Facebook, Apache (accepted for incubation) Google Bindings C++, Java, Python, PHP, XSD, Ruby, C#, Perl, Objective C, Erlang, Smalltalk, OCaml, and Haskell C++, [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=johnsofteng.wordpress.com&amp;blog=8263322&amp;post=325&amp;subd=johnsofteng&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Google recently released its <a href="http://code.google.com/p/protobuf/">Protocol Buffers</a> as open source.  About a year ago, Facebook released a similar product called <a href="http://developers.facebook.com/thrift/">Thrift</a>. I’ve been comparing  them; here’s what I’ve found:</p>
<table id="comparison" border="0">
<tbody>
<tr>
<th width="20%"></th>
<th width="40%">Thrift</th>
<th width="40%">Protocol Buffers</th>
</tr>
<tr>
<th>Backers</th>
<td>Facebook, <a href="http://wiki.apache.org/incubator/ThriftProposal">Apache (accepted for incubation)</a></td>
<td>Google</td>
</tr>
<tr>
<th>Bindings</th>
<td>C++, Java, Python, PHP, XSD, Ruby, C#, Perl, Objective C, Erlang, Smalltalk,  OCaml, and Haskell</td>
<td>C++, Java, Python<br />
(Perl, Ruby, and C# under discussion)</td>
</tr>
<tr>
<th>Output Formats</th>
<td>Binary, JSON</td>
<td>Binary</td>
</tr>
<tr>
<th>Primitive Types</th>
<td>bool<br />
byte<br />
16/32/64-bit integersdouble<br />
string<br />
byte  sequence<br />
map&lt;t1,t2&gt;<br />
list&lt;t&gt;<br />
set&lt;t&gt;</td>
<td>bool32/64-bit integers<br />
float<br />
double<br />
string<br />
byte sequence</p>
<p>“repeated” properties act like lists</td>
</tr>
<tr>
<th>Enumerations</th>
<td>Yes</td>
<td>Yes</td>
</tr>
<tr>
<th>Constants</th>
<td>Yes</td>
<td>No</td>
</tr>
<tr>
<th>Composite Type</th>
<td>struct</td>
<td>message</td>
</tr>
<tr>
<th>Exception Type</th>
<td>Yes</td>
<td>No</td>
</tr>
<tr>
<th>Documentation</th>
<td>So-so</td>
<td>Good</td>
</tr>
<tr>
<th>License</th>
<td>Apache</td>
<td>BSD-style</td>
</tr>
<tr>
<th>Compiler Language</th>
<td>C++</td>
<td>C++</td>
</tr>
<tr>
<th>RPC Interfaces</th>
<td>Yes</td>
<td>Yes</td>
</tr>
<tr>
<th>RPC Implementation</th>
<td>Yes</td>
<td>No</td>
</tr>
<tr>
<th>Composite Type Extensions</th>
<td>No</td>
<td>Yes</td>
</tr>
</tbody>
</table>
<p>Overall, I think Thrift wins on features and Protocol Buffers win  on<br />
documentation. Implementation-wise, they’re quite similar. Both  use<br />
integer tags to identify fields, so you can add and remove  fields<br />
without breaking existing code. Protocol Buffers  support<br />
variable-width encoding of integers, which saves a few bytes.  (Thrift<br />
has an experimental output format with variable-width ints.)</p>
<p>The major difference is that Thrift provides a full client/server  RPC<br />
implementation, whereas Protocol Buffers only generate stubs to use  in<br />
your own RPC system.</p>
<p><strong>Update July 12, 2008:</strong> I haven’t tested for speed, but from a  cursory examination it seems that, at the binary level, Thrift and Protocol  Buffers are very similar. I think Thrift will develop a more coherent community  now that it’s under Apache incubation. It just moved to a new <a href="http://incubator.apache.org/thrift/">web site</a> and <a href="http://incubator.apache.org/thrift/mailing_lists.html">mailing list</a>, and the <a href="http://issues.apache.org/jira/browse/THRIFT">issue tracker</a> is  active.</p>
<p>Reference:</p>
<p>http://stuartsierra.com/2008/07/10/thrift-vs-protocol-buffers (Original Site)</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/johnsofteng.wordpress.com/325/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/johnsofteng.wordpress.com/325/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/johnsofteng.wordpress.com/325/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/johnsofteng.wordpress.com/325/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/johnsofteng.wordpress.com/325/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/johnsofteng.wordpress.com/325/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/johnsofteng.wordpress.com/325/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/johnsofteng.wordpress.com/325/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/johnsofteng.wordpress.com/325/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/johnsofteng.wordpress.com/325/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/johnsofteng.wordpress.com/325/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/johnsofteng.wordpress.com/325/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/johnsofteng.wordpress.com/325/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/johnsofteng.wordpress.com/325/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=johnsofteng.wordpress.com&amp;blog=8263322&amp;post=325&amp;subd=johnsofteng&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://johnsofteng.wordpress.com/2010/03/21/thrift-vs-protocol-buffers/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/53024032acd728facceb97bfe56c7bc9?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">johnsofteng</media:title>
		</media:content>
	</item>
		<item>
		<title>up and running with Cassandra</title>
		<link>http://johnsofteng.wordpress.com/2010/03/21/up-and-running-with-cassandra/</link>
		<comments>http://johnsofteng.wordpress.com/2010/03/21/up-and-running-with-cassandra/#comments</comments>
		<pubDate>Sun, 21 Mar 2010 22:29:58 +0000</pubDate>
		<dc:creator>johnsofteng</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Services]]></category>
		<category><![CDATA[cassandra]]></category>
		<category><![CDATA[database]]></category>
		<category><![CDATA[memory]]></category>

		<guid isPermaLink="false">http://johnsofteng.wordpress.com/?p=316</guid>
		<description><![CDATA[Cassandra is a hybrid non-relational database in the same class as Google&#8217;s BigTable. It is more featureful than a key/value store like Dynomite, but supports fewer query types than a document store like MongoDB. Cassandra was started by Facebook and later transferred to the open-source community. It is an ideal runtime database for web-scale domains [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=johnsofteng.wordpress.com&amp;blog=8263322&amp;post=316&amp;subd=johnsofteng&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<div>
<p><a href="http://wiki.apache.org/cassandra/">Cassandra</a> is a hybrid  non-relational database in the same class as Google&#8217;s BigTable. It is more  featureful than a key/value store like <a href="http://wiki.github.com/cliffmoon/dynomite">Dynomite</a>, but supports  fewer query types than a document store like <a href="http://www.mongodb.org/">MongoDB</a>.</p>
<p>Cassandra was started by Facebook and later transferred to the open-source  community. It is an ideal runtime database for web-scale domains like social  networks.</p>
<p>This post is both a tutorial and a &#8220;getting started&#8221; overview. You will learn  about Cassandra&#8217;s features, data model, API, and operational  requirements—everything you need to know to deploy a Cassandra-backed  service.</p>
<p><strong>Jan 8, 2010</strong>: post updated for Cassandra gem 0.7 and Cassandra version  0.5.</p>
<h2>features</h2>
<p>There are a number of reasons to choose Cassandra for your website. Compared  to other databases, three big features stand out:</p>
<ul>
<li><strong>Flexible schema</strong>: with Cassandra, like a document store, you don&#8217;t  have to decide what fields you need in your records ahead of time. You can add  and remove arbitrary fields on the fly. This is an incredible productivity  boost, especially in large deployments.</li>
<li><strong>True scalability</strong>: Cassandra scales horizontally in the purest sense.  To add more capacity to a cluster, turn on another machine. You don&#8217;t have  restart any processes, change your application queries, or manually relocate any  data.</li>
<li><strong>Multi-datacenter awareness</strong>: you can adjust your node layout to ensure  that if one datacenter burns in a fire, an alternative datacenter will have at  least one full copy of every record.</li>
</ul>
<p>Some other features that help put Cassandra above the competition :</p>
<ul>
<li><strong>Range queries</strong>: unlike most key/value stores, you can query for  ordered ranges of keys.</li>
<li><strong>List datastructures</strong>: super columns add a 5th dimension to the hybrid  model, turning columns into lists. This is very handy for things like per-user  indexes.</li>
<li><strong>Distributed writes</strong>: you can read and write any data to anywhere in  the cluster at any time. There is never any single point of failure.</li>
</ul>
<h2>installation</h2>
<p>You need a Unix system. If you are using Mac OS 10.5, all you need is Git.  Otherwise, you need to install Java 1.6, Git 1.6, Ruby, and Rubygems in some  reasonable way.</p>
<p>Start a terminal and run:</p>
<pre>sudo gem install cassandra</pre>
<p>If you are using Mac OS, you need to export the following environment  variables:</p>
<pre>export JAVA_HOME="/System/Library/Frameworks/JavaVM.framework/Versions/1.6/Home"
export PATH="/System/Library/Frameworks/JavaVM.framework/Versions/1.6/Home/bin:$PATH"</pre>
<p>Now you can build and start a test server with  <code>cassandra_helper</code>:</p>
<pre>cassandra_helper cassandra</pre>
<p>It runs!</p>
<h2>live demo</h2>
<p>The above script boots the server with a schema that we can interact with.  Open another terminal window and start <code>irb</code>, the Ruby shell:</p>
<pre>irb</pre>
<p>In the <code>irb</code> prompt, require the library:</p>
<pre>require 'rubygems'
require 'cassandra'
include Cassandra::Constants</pre>
<p>Now instantiate a client object:</p>
<pre>twitter = Cassandra.new('Twitter')</pre>
<p>Let&#8217;s insert a few things:</p>
<pre>user = {'screen_name' =&gt; 'buttonscat'}
twitter.insert(:Users, '5', user)  

tweet1 = {'text' =&gt; 'Nom nom nom nom nom.', 'user_id' =&gt; '5'}
twitter.insert(:Statuses, '1', tweet1)

tweet2 = {'text' =&gt; '@evan Zzzz....', 'user_id' =&gt; '5', 'reply_to_id' =&gt; '8'}
twitter.insert(:Statuses, '2', tweet2)</pre>
<p>Notice that the two status records do not have all the same columns. Let&#8217;s go  ahead and connect them to our user record:</p>
<pre>twitter.insert(:UserRelationships, '5', {'user_timeline' =&gt; {UUID.new =&gt; '1'}})
twitter.insert(:UserRelationships, '5', {'user_timeline' =&gt; {UUID.new =&gt; '2'}})</pre>
<p>The <code>UUID.new</code> call creates a collation key based on the current  time; our tweet ids are stored in the values.</p>
<p>Now we can query our user&#8217;s tweets:</p>
<pre>timeline = twitter.get(:UserRelationships, '5', 'user_timeline', :reversed =&gt; true)
timeline.map { |time, id| twitter.get(:Statuses, id, 'text') }
# =&gt; ["@evan Zzzz....", "Nom nom nom nom nom."]</pre>
<p>Two tweet bodies, returned in recency order—not bad at all. In a similar  fashion, each time a user tweets, we could loop through their followers and  insert the status key into their follower&#8217;s <code>home_timeline</code> relationship, for handling general status delivery.</p>
<h2>the data model</h2>
<p>Cassandra is best thought of as a 4 or 5 dimensional hash. The usual way to  refer to a piece of data is as follows: a <strong>keyspace</strong>, a <strong>column  family</strong>, a <strong>key</strong>, an <em>optional</em> <strong>super column</strong>, and a  <strong>column</strong>. At the end of that chain lies a single, lonely value.</p>
<p>Let&#8217;s break down what these layers mean.</p>
<ul>
<li><strong>Keyspace</strong> (also confusingly called &#8220;table&#8221;): the outer-most level of  organization. This is usually the name of the application. For example,  <code>'Twitter'</code> and <code>'Wordpress'</code> are both good keyspaces.  Keyspaces must be defined at startup in the <code>storage-conf.xml</code> file.</li>
<li><strong>Column family</strong>: a slice of data corresponding to a particular key. Each  column family is stored in a separate file on disk, so it can be useful to put  frequently accessed data in one column family, and rarely accessed data in  another. Some good column family names might be <code> <img src='http://s1.wp.com/wp-includes/images/smilies/icon_razz.gif' alt=':P' class='wp-smiley' /> osts</code>,  <code>:Users</code> and <code>:UserAudits</code>. Column families must be  defined at startup.</li>
<li><strong>Key</strong>: the permanent name of the record. You can query over ranges of  keys in a column family, like <code>:start =&gt; '10050', :finish =&gt;  '10070'</code>—this is the only index Cassandra provides for free. Keys are  defined on the fly.</li>
</ul>
<p>After the column family level, the organization can diverge—this is a feature  unique to Cassandra. You can choose either:</p>
<ul>
<li>A <strong>column</strong>: this is a tuple with a name and a value. Good columns might  be <code>'screen_name' =&gt; 'lisa4718'</code> or <code>'Google' =&gt;  'http://google.com'</code>.It is common to not specify a particular column name when requesting a key;  the response will then be an ordered hash of all columns. For example, querying  for <code>(:Users, '174927')</code> might return:
<pre>{'name' =&gt; 'Lisa Jones',
 'gender' =&gt; 'f',
 'screen_name' =&gt; 'lisa4718'}</pre>
<p>In this case, <code>name</code>, <code>gender</code>, and  <code>screen_name</code> are all column names. Columns are defined on the fly,  and different records can have different sets of column names, even in the same  keyspace and column family. This lets you use the column name itself as either  <strong>structure</strong> or <strong>data</strong>. Columns can be stored in recency order, or  alphabetical by name, and all columns keep a timestamp.</li>
<li>A <strong>super column</strong>: this is a named list. It contains standard columns,  stored in recency order.Say Lisa Jones has bookmarks in several categories. Querying  <code>(:UserBookmarks, '174927')</code> might return:
<pre>{'work' =&gt; {
    'Google' =&gt; 'http://google.com',
    'IBM' =&gt; 'http://ibm.com'},
 'todo': {...},
 'cooking': {...}}</pre>
<p>Here, <code>work</code>, <code>todo</code>, and <code>cooking</code> are all  super column names. They are defined on the fly, and there can be any number of  them per row. <code>:UserBookmarks</code> is the name of the <strong>super column  family</strong>. Super columns are stored in alphabetical order, with their sub  columns physically adjacent on the disk.</li>
</ul>
<p>Super columns and standard columns cannot be mixed at the same (4th) level of  dimensionality. You must define at startup which column families contain  standard columns, and which contain super columns with standard columns inside  them.</p>
<p>Super columns are a great way to store one-to-many indexes to other records:  make the sub column names TimeUUIDs (or whatever you&#8217;d like to use to sort the  index), and have the values be the foreign key. We saw an example of this  strategy in the demo, above.</p>
<p>If this is confusing, don&#8217;t worry. We&#8217;ll now look at two example schemas in  depth.</p>
<h2>twitter schema</h2>
<p>Here is the schema definition we used for the demo, above. It is based on  Eric Florenzano&#8217;s <a href="http://github.com/ericflo/twissandra/tree/master">Twissandra</a>:</p>
<pre>&lt;Keyspace Name="Twitter"&gt;
  &lt;ColumnFamily CompareWith="UTF8Type" Name="Statuses" /&gt;
  &lt;ColumnFamily CompareWith="UTF8Type" Name="StatusAudits" /&gt;
  &lt;ColumnFamily CompareWith="UTF8Type" Name="StatusRelationships"
    CompareSubcolumnsWith="TimeUUIDType" ColumnType="Super" /&gt;
  &lt;ColumnFamily CompareWith="UTF8Type" Name="Users" /&gt;
  &lt;ColumnFamily CompareWith="UTF8Type" Name="UserRelationships"
    CompareSubcolumnsWith="TimeUUIDType" ColumnType="Super" /&gt;
&lt;/Keyspace&gt;</pre>
<p>What could be in <code>StatusRelationships</code>? Maybe a list of users who  favorited the tweet? Having a super column family for both record types lets us  index each direction of whatever many-to-many relationships we come up with.</p>
<p>Here&#8217;s how the data is organized:</p>
<div><a href="http://blog.evanweaver.com/files/cassandra/twitter.jpg"><img src="http://blog.evanweaver.com/files/cassandra/twitter_small.jpg" alt="Click to enlarge" /></a></div>
<p>Cassandra lets you distribute the keys across the cluster either randomly, or  in order, via the <code>Partitioner</code> option in the  <code>storage-conf.xml</code> file.</p>
<p>For the Twitter application, if we were using the order-preserving  partitioner, all recent statuses would be stored on the same node. This would  cause hotspots. Instead, we should use the random partitioner.</p>
<p>Alternatively, we could preface the status keys with the user key, which has  less temporal locality. If we used <code>user_id:status_id</code> as the status  key, we could do range queries on the user fragment to get tweets-by-user,  avoiding the need for a <code>user_timeline</code> super column.</p>
<h2>multi-blog schema</h2>
<p>Here&#8217;s a another schema, suggested to me by <a href="http://spyced.blogspot.com/">Jonathan Ellis</a>, the primary Cassandra  maintainer. It&#8217;s for a multi-tenancy blog platform:</p>
<pre>&lt;Keyspace Name="Multiblog"&gt;
  &lt;ColumnFamily CompareWith="TimeUUIDType" Name="Blogs" /&gt;
  &lt;ColumnFamily CompareWith="TimeUUIDType" Name="Comments"/&gt;
&lt;/Keyspace&gt;</pre>
<p>Imagine we have a blog named &#8216;The Cutest Kittens&#8217;. We will insert a row when  the first post is made as follows:</p>
<pre>require 'rubygems'
require 'cassandra'
include Cassandra::Constants

multiblog = Cassandra.new('Multiblog')

multiblog.insert(:Blogs, 'The Cutest Kittens',
  { UUID.new =&gt;
    '{"title":"Say Hello to Buttons Cat","body":"Buttons is a cute cat."}' })</pre>
<p><code>UUID.new</code> generates a unique, sortable column name, and the JSON  hash contains the post details. Let&#8217;s insert another:</p>
<pre>multiblog.insert(:Blogs, 'The Cutest Kittens',
  { UUID.new =&gt;
    '{"title":"Introducing Commie Cat","body":"Commie is also a cute cat"}' })</pre>
<p>Now we can find the latest post with the following query:</p>
<pre>post = multiblog.get(:Blogs, 'The Cutest Kittens', :reversed =&gt; true).to_a.first</pre>
<p>On our website, we can build links based on the readable representation of  the UUID:</p>
<pre>guid = post.first.to_guid
# =&gt; "b06e80b0-8c61-11de-8287-c1fa647fd821"</pre>
<p>If the user clicks this string in a permalink, our app can find the post  directly via:</p>
<pre>multiblog.get(:Blogs, 'The Cutest Kittens', :start =&gt; UUID.new(guid), :count =&gt; 1)</pre>
<p>For comments, we&#8217;ll use the post UUID as the outermost key:</p>
<pre>multiblog.insert(:Comments, guid,
  {UUID.new =&gt; 'I like this cat. - Evan'})
multiblog.insert(:Comments, guid,
  {UUID.new =&gt; 'I am cuter. - Buttons'})</pre>
<p>Now we can get all comments (oldest first) for a post by calling:</p>
<pre>multiblog.get(:Comments, guid)</pre>
<p>We could paginate them by passing <code>:start</code> with a UUID. See <a href="http://www.slideshare.net/Eweaver/efficient-pagination-using-mysql">this  presentation</a> to learn more about token-based pagination.</p>
<p>We have sidestepped two problems with this data model: we don&#8217;t have to  maintain separate indexes for any lookups, and the posts and comments are stored  in separate files, where they don&#8217;t cause as much write contention. Note that we  didn&#8217;t need to use any super columns, either.</p>
<h2>storage layout and api comparison</h2>
<p>The storage strategy for Cassandra&#8217;s standard model is the same as  BigTable&#8217;s. Here&#8217;s a comparison chart:</p>
<table>
<tbody>
<tr>
<th></th>
<th colspan="2">multi-file</th>
<th>per-file</th>
<th colspan="4">intra-file</th>
</tr>
<tr>
<th>Relational</th>
<td>server</td>
<td>database</td>
<td>table*</td>
<td>primary key</td>
<td>column value</td>
<td></td>
<td></td>
</tr>
<tr>
<th>BigTable</th>
<td>cluster</td>
<td>table</td>
<td>column family</td>
<td>key</td>
<td>column name</td>
<td>column value</td>
<td></td>
</tr>
<tr>
<th>Cassandra, standard model</th>
<td>cluster</td>
<td>keyspace</td>
<td>column family</td>
<td>key</td>
<td>column name</td>
<td>column value</td>
<td></td>
</tr>
<tr>
<th>Cassandra, super column model</th>
<td>cluster</td>
<td>keyspace</td>
<td>column family</td>
<td>key</td>
<td>super column name</td>
<td>column name</td>
<td>column value</td>
</tr>
</tbody>
</table>
<p>* With fixed  column names.</p>
<p>Column families are stored in <strong>column-major</strong> order, which is why people  call BigTable a column-oriented database. This is not the same as a  column-oriented OLAP database like Sybase IQ—it depends on what you use the  column names for.</p>
<div><a href="http://blog.evanweaver.com/files/cassandra/row_oriented.jpg"><img src="http://blog.evanweaver.com/files/cassandra/row_oriented_small.jpg" alt="Click to enlarge" /></a></div>
<p>In row-orientation, the column names are the <strong>structure</strong>, and you think  of the column families as <strong>containing keys</strong>. This is the convention in  relational databases.</p>
<div><a href="http://blog.evanweaver.com/files/cassandra/column_oriented.jpg"><img src="http://blog.evanweaver.com/files/cassandra/column_oriented_small.jpg" alt="Click to enlarge" /></a></div>
<p>In column-orientation, the column names are the <strong>data</strong>, and the column  families are the structure. You think of the key as <strong>containing the column  family</strong>, which is the convention in BigTable. (In Cassandra, super columns  are also stored in column-major order—all the sub columns are together.)</p>
<p>In Cassandra&#8217;s Ruby API, parameters are expressed in storage order, for  clarity:</p>
<table>
<tbody>
<tr>
<th>Relational</th>
<td><code>SELECT `column` FROM `database`.`table` WHERE `id` =  key;</code></td>
</tr>
<tr>
<th>BigTable</th>
<td><code>table.get(key, "column_family:column")</code></td>
</tr>
<tr>
<th>Cassandra: standard model</th>
<td><code>keyspace.get("column_family", key,  "column")</code></td>
</tr>
<tr>
<th>Cassandra: super column model</th>
<td><code>keyspace.get("column_family", key,  "super_column", "column")</code></td>
</tr>
</tbody>
</table>
<p>Note that Cassandra&#8217;s internal Thrift interface mimics BigTable in some ways,  but this is being changed.</p>
<h2>going to production</h2>
<p>Cassandra is an alpha product and could, theoretically, lose your data. In  particular, if you change the schema specified in the  <code>storage-conf.xml</code> file, you must follow <a href="https://issues.apache.org/jira/browse/CASSANDRA-44">these instructions</a> carefully, or corruption will occur (this is going to be fixed). Also, the  on-disk storage format is expected to change in version 0.4.0. After that things  will be a bit more stable.</p>
<p>The biggest deployment is at Facebook, where hundreds of terabytes of token  indexes are kept in about a hundred Cassandra nodes. However, their use case  allows the data to be rebuilt if something goes wrong. Currently there are no  known deployments of non-transient data. Proceed carefully, keep a backup in an  <a href="http://mashable.com/2009/01/30/magnolia-data-loss/">unrelated storage  engine</a>&#8230;and submit patches if things go wrong.</p>
<p>That aside, here is a guide for deploying a production cluster:</p>
<ul>
<li><strong>Hardware</strong>: get a handful of commodity Linux servers. 16GB memory is  good; Cassandra likes a big filesystem buffer. You don&#8217;t need RAID. If you put  the commitlog file and the data files on separate physical disks, things will go  faster. Don&#8217;t use EC2 or friends except for testing; the virtualized I/O is too  slow.</li>
<li><strong>Configuration</strong>: in the <code>storage-conf.xml</code> schema file, set  the replication factor to 3. List the IP address of one of the nodes as the  seed. Set the listen address to the empty string, so the hosts will resolve  their own IPs. Now, adjust the contents of <code>cassandra.in.sh</code> for your  various paths and JVM options—for a 16GB node, set the JVM heap to 4GB.</li>
<li><strong>Deployment</strong>: build a package of Cassandra itself and your configuration  files, and deliver it to all your servers (I use <a href="http://en.wikipedia.org/wiki/Capistrano">Capistrano</a> for this). Start  the servers by setting <code>CASSANDRA_INCLUDE</code> in the environment to  point to your <code>cassandra.in.sh</code> file, and run  <code>bin/cassandra</code>. At this point, you should see join notices in the  Cassandra logs:
<pre>Cassandra starting up...
Node 10.224.17.13:7001 has now joined.
Node 10.224.17.14:7001 has now joined.</pre>
<p>Congratulations! You have a cluster. Don&#8217;t forget to turn off debug logging  in the <code>log4j.properties</code> file.</li>
<li><strong>Visibility</strong>: you can get a little more information about your cluster  via the tool <code>bin/nodeprobe</code>, included:
<pre>$ bin/nodeprobe --host 10.224.17.13 ring
Token(124007023942663924846758258675932114665)  3 10.224.17.13  |&lt;--|
Token(106858063638814585506848525974047690568)  3 10.224.17.19  |   ^
Token(141130545721235451315477340120224986045)  3 10.224.17.14  |--&gt;|</pre>
<p>Cassandra also exposes various statistics over <a href="http://en.wikipedia.org/wiki/Java_Management_Extensions">JMX</a>.</li>
</ul>
<p>Note that your client machines (not servers!) must have accurate clocks for  Cassandra to resolve write conflicts properly. Use <a href="http://en.wikipedia.org/wiki/Network_Time_Protocol">NTP</a>.</p>
<h2>conclusion</h2>
<p>There is a misperception that if someone advocates a non-relational database,  they either don&#8217;t understand SQL optimization, or they are generally a hater.  This is not the case.</p>
<p>It is reasonable to seek a new tool for a new problem, and database problems  have changed with the rise of web-scale distributed systems. This does not mean  that SQL as a general-purpose runtime and reporting tool is going away. However,  at web-scale, it is more flexible to separate the concerns. Runtime object  lookups can be handled by a low-latency, strict, self-managed system like  Cassandra. Asynchronous analytics and reporting can be handled by a  high-latency, flexible, un-managed system like <a href="http://hadoop.apache.org/core/">Hadoop</a>. And in neither case does SQL  lend itself to sharding.</p>
<p>I think that Cassandra is the most promising current implementation of a  runtime distributed database, but much work remains to be done. We&#8217;re beginning  to use Cassandra at Twitter, and here&#8217;s what I would like to happen  real-soon-now:</p>
<ul>
<li><strong>Interface cleanup</strong>: the  Thrift API for Cassandra is incomplete and inconsistent, which makes writing  clients very irritating.<br />
Done!</li>
<li><strong>Online migrations</strong>: restarting the cluster 3 times to add a column  family is silly.</li>
<li><strong>ActiveModel or DataMapper adapter</strong>: for interaction with business objects in  Ruby.<br />
Done! Michael Koziarski on the Rails core team wrote an <a href="http://github.com/NZKoz/cassandra_object">ActiveModel adapter</a>.</li>
<li><strong>Scala client</strong>: for interoperability with JVM middleware.</li>
</ul>
<p>Go ahead and jump on any of those projects—it&#8217;s a chance to get in on the  ground floor.</p>
<p>Cassandra has excellent performance. There some benchmark results for version  0.5 at the end of the <a href="http://www.brianfrankcooper.net/pubs/ycsb-v4.pdf">Yahoo performance  study</a>.</p>
<h2>further resources</h2>
<ul>
<li><a href="http://wiki.apache.org/cassandra/">Cassandra wiki</a></li>
<li>Presentation by Avinash Lakshman about Cassandra: <a href="http://www.slideshare.net/Eweaver/cassandra-presentation-at-nosql">slides</a>,  <a href="http://vimeo.com/5185526">video</a></li>
<li>The <a href="http://mail-archives.apache.org/mod_mbox/incubator-cassandra-user/">cassandra-user</a> and <a href="http://mail-archives.apache.org/mod_mbox/incubator-cassandra-user/">cassandra-dev</a> mailing lists</li>
<li>The #cassandra IRC channel on <a href="irc://irc.freenode.net/cassandra">irc.freenode.net</a></li>
<li>Cassandra&#8217;s <a href="http://issues.apache.org/jira/browse/CASSANDRA">bug  tracker</a></li>
<li>Twitter&#8217;s Ruby client: <a href="http://blog.evanweaver.com/files/doc/fauna/cassandra_client">docs</a>, <a href="http://github.com/fauna/cassandra_client/">source</a></li>
</ul>
</div>
<div>Reference(cited):</div>
<div>http://blog.evanweaver.com/articles/2009/07/06/up-and-running-with-cassandra/</div>
<div>http://www.facebook.com/note.php?note_id=24413138919&amp;id=9445547199&amp;index=9</div>
<div>http://nosql.mypopescu.com/post/407159447/cassandra-twitter-an-interview-with-ryan-king</div>
<div>http://highscalability.com/blog/2010/2/26/mysql-and-memcached-end-of-an-era.html</div>
<div>http://project-voldemort.com/</div>
<div>http://www.linux-mag.com/cache/7496/1.html</div>
<div>http://en.wikipedia.org/wiki/Redis_(data_store)</div>
<div>http://en.wikipedia.org/wiki/Cassandra_(database)</div>
<div>http://en.wikipedia.org/wiki/BigTable</div>
<div>http://en.wikipedia.org/wiki/Memcached</div>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/johnsofteng.wordpress.com/316/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/johnsofteng.wordpress.com/316/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/johnsofteng.wordpress.com/316/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/johnsofteng.wordpress.com/316/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/johnsofteng.wordpress.com/316/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/johnsofteng.wordpress.com/316/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/johnsofteng.wordpress.com/316/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/johnsofteng.wordpress.com/316/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/johnsofteng.wordpress.com/316/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/johnsofteng.wordpress.com/316/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/johnsofteng.wordpress.com/316/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/johnsofteng.wordpress.com/316/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/johnsofteng.wordpress.com/316/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/johnsofteng.wordpress.com/316/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=johnsofteng.wordpress.com&amp;blog=8263322&amp;post=316&amp;subd=johnsofteng&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://johnsofteng.wordpress.com/2010/03/21/up-and-running-with-cassandra/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/53024032acd728facceb97bfe56c7bc9?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">johnsofteng</media:title>
		</media:content>

		<media:content url="http://blog.evanweaver.com/files/cassandra/twitter_small.jpg" medium="image">
			<media:title type="html">Click to enlarge</media:title>
		</media:content>

		<media:content url="http://blog.evanweaver.com/files/cassandra/row_oriented_small.jpg" medium="image">
			<media:title type="html">Click to enlarge</media:title>
		</media:content>

		<media:content url="http://blog.evanweaver.com/files/cassandra/column_oriented_small.jpg" medium="image">
			<media:title type="html">Click to enlarge</media:title>
		</media:content>
	</item>
		<item>
		<title>Google Protocol Buffers and other data interchange formats</title>
		<link>http://johnsofteng.wordpress.com/2010/03/20/google-protocol-buffers-and-other-data-interchange-formats/</link>
		<comments>http://johnsofteng.wordpress.com/2010/03/20/google-protocol-buffers-and-other-data-interchange-formats/#comments</comments>
		<pubDate>Sat, 20 Mar 2010 23:26:13 +0000</pubDate>
		<dc:creator>johnsofteng</dc:creator>
				<category><![CDATA[Computer Science]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Services]]></category>
		<category><![CDATA[data interchange format]]></category>
		<category><![CDATA[etch]]></category>
		<category><![CDATA[facebook]]></category>
		<category><![CDATA[Google]]></category>
		<category><![CDATA[ice]]></category>
		<category><![CDATA[protocol buffer]]></category>

		<guid isPermaLink="false">http://johnsofteng.wordpress.com/?p=329</guid>
		<description><![CDATA[We’ve been planning on moving to a new messaging protocol for a while. We’ve looked at a lot of different solutions but had enough issues with every proposed solution to date that we haven’t made a decision. JR Boyens pointed us to Google’s announcement Protocol Buffers: Google’s Data Interchange Format in July. Glanced at it but [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=johnsofteng.wordpress.com&amp;blog=8263322&amp;post=329&amp;subd=johnsofteng&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<div>
<p>We’ve been planning on moving to a new messaging protocol for a  while. We’ve looked at a lot of different solutions but had enough issues with  every proposed solution to date that we haven’t made a decision. JR Boyens  pointed us to Google’s announcement <a href="http://google-opensource.blogspot.com/2008/07/protocol-buffers-googles-data.html">Protocol Buffers: Google’s Data Interchange Format</a> in July.  Glanced at it but then it got lost in the everyday noise. Recent work on a  project caused it to get more attention. I like what I see.</p>
<p>As part of a new offering we decided to add in our new messaging direction.  We’re processing realtime voice conversations. Some of our major considerations  are:</p>
<ol>
<li><strong>Latency and Performance</strong> – Latency matters to us. A LOT. I’m  including not only network transport but also memory and CPU. The total time it  takes for a message to get from it’s native format in the sender to it’s native  format in the receiver. We’re dealing with real time voice communications, too  much latency and best case is the callers experience suffers. Our labor model is  also sensitive to even small changes in latency. The smaller the latency the  more efficient we are, the happier our client’s customers are and the more money  we make. As greedy capitalist we see that as a good thing.</li>
<li><strong>Versioning</strong> – Our current system has no versioning. Yeah,  short sighted on my part. We have to fix it so it’s required for any new message  protocol. Protobuf fits our needs on this nicely. Different versions have to  coexist and interoperate. We could do this on a different layer than the  messaging but it makes sense to me to keep it at this level.</li>
<li><strong>Java and C++</strong> – Language independence is cool and all but in  practice if the protocol support Java and C++ we’re good to go. Maybe I’m being  a bit myopic but my feeling is the likely hood that whatever we choose will  expand to support more languages in the future is very high if it supports  several today.</li>
<li><strong>Internal</strong> – We control the end points. I don’t care if the  schema is external to the data package. In fact, for our use case that’s a plus.  For any external services we’ll still expose those using the usual standards.  Internally our applications will be using PB for their messaging format.</li>
</ol>
<div>In short, we’re all about high volume low latency messages.</div>
<h3>
<div><a href="http://code.google.com/apis/protocolbuffers/" target="_blank">Google  Protocol Buffers</a></div>
</h3>
<blockquote>
<div>Protocol buffers are a flexible, efficient, automated mechanism for  serializing structured data – think XML, but smaller, faster, and simpler. You  define how you want your data to be structured once, then you can use special  generated source code to easily write and read your structured data to and from  a variety of data streams and using a variety of languages. You can even update  your data structure without breaking deployed programs that are compiled against  the “old” format.</div>
<div>
<p>Protocol buffers have many advantages over XML for serializing structured  data. Protocol buffers:</p>
<ul>
<li>are simpler</li>
<li>are 3 to 10 times smaller</li>
<li>are 20 to 100 times faster</li>
<li>are less ambiguous</li>
<li>generate data access classes that are easier to use programmatically</li>
</ul>
</div>
</blockquote>
<div>Seems like a decent fit. OK, actually an awesome fit. One of our developers  has been doing some testing. It’s impressive.</div>
<h3>Alternatives</h3>
<h4><a href="http://www.json.org/">JSON</a></h4>
<p>To me protobuf feels like compiled JSON. They are very similar.  The main  difference being JSON sends data over the wire in text format verses protobuf’s  binary format. The latter has the advantage of a smaller size and being faster  for a computer to parse.</p>
<h4><a href="http://en.wikipedia.org/wiki/ASN.1" target="_blank">ASN.1</a></h4>
<p>Why not ASN.1? Seems like one of the best choices. Well understood and widely  used. Sure the full ASN.1 specification is complex but we’d only need a small  subset. I’m still struggling with this one a bit. Tool support seems a bit  better in protobuf and it’s definitely simpler.</p>
<h4><a href="http://developers.facebook.com/thrift/" target="_blank">Thrift</a></h4>
<p>Facebook’s Thrift is very similar to protobuf. Not surprising since the main  author interned at Google. It’s a strong offering and recently became an <a href="http://incubator.apache.org/thrift/" target="_blank">Apache project</a>.  Nice stuff. Stuart Sierra has a nice comparison on his blog, <a title="Permanent Link: Thrift vs. Protocol Buffers" rel="bookmark" href="http://stuartsierra.com/2008/07/10/thrift-vs-protocol-buffers">Thrift vs. Protocol Buffers</a>. Another worthy contender but not a  big enough advantage to stop the internal momentum protobuf already has.</p>
<h4><a href="http://www.hdfgroup.org/" target="_blank">HDF5</a></h4>
<p>The HDF wiki has an entry <a href="http://wiki.hdfgroup.org/Google+Protocol+Buffers+and+HDF5" target="_self">Google Protocol Buffers and HDF5</a> that concludes:</p>
<blockquote><p>In summary, Protocol Buffers and HDF5 were designed to serve different kinds  of data intensive applications: a network based transient message system, and a  high performance data storage system for very large datasets such as  multi-dimensional images, respectively. That said, both 1) offer open source  technologies that can reduce data management headaches for individual developers  and projects, 2) increase the ability to share data through the use of  well-defined binary formats and supporting libraries that run on a variety of  platforms, and 3) provide the ability to access data stored with “older”  versions of the data structures.</p></blockquote>
<p>Different design goals. HDF5 doesn’t fit our needs as well.</p>
<h4><a href="http://hessian.caucho.com/">Hessian</a></h4>
<p>The Hessian protocol has the following design goals:</p>
<ul>
<li>It must not require external IDL or schema definitions, i.e. the protocol  should be invisible to application code.</li>
<li>It must be language-independent.</li>
<li>It must be simple so it can be effectively tested and implemented.</li>
<li>It must be as fast as possible.</li>
<li>It must be as compact as possible.</li>
<li>It must support Unicode strings.</li>
<li>It must support 8-bit binary data (i.e. without encoding or using  attachments.)</li>
<li>It must support encryption, compression, signature, and transaction context  envelopes.</li>
</ul>
<p>I still haven’t figured out how/if you can version your messages. Can you add  and remove fields and still have compatibility (backwards and forwards)?  Cool  effort, still feels very rough in places. Another worthy effort to consider.</p>
<h4><a href="http://www.zeroc.com/">ZeroC ICE</a></h4>
<p>At it’s core it’s</p>
<blockquote><p>The Ice core library. Among many other features, the Ice core library manages  all the communication tasks using a highly efficient protocol (including  protocol compression and support for both TCP and UDP), provides a flexible  thread pool for multi-threaded servers, and offers additional functionality that  supports extreme scalability with potentially millions of Ice  objects.</p></blockquote>
<p>ICE is a comprehensive middleware system. It can even use PB as it’s  messaging layer. It’s messaging layer doesn’t handle adding or removing fields  as well as PB. We don’t need the RPC side of ICE. Just not a good fit for  us.</p>
<h4><a href="http://en.wikipedia.org/wiki/Service_Data_Objects" target="_self">SDO</a></h4>
<p>Service Data Objects provides a rather ambitious messaging architecture. It’s  concerns aren’t speed and efficiency. The <a href="http://www.osoa.org/download/attachments/287/SDO+V2.1+White+Paper.pdf?version=1">SDO  V2.1 White Paper</a> states</p>
<blockquote><p>SDO is intended to create a uniform data access layer that provides a data  access solution for heterogeneous data sources in an easy-to-use manner that is  amenable to tooling and frameworks.</p></blockquote>
<p>Interesting, not a fit.</p>
<h4><a href="http://developer.cisco.com/web/cuae/etch">Cisco Etch</a></h4>
<p>Primary focus is an RPC implementation, not a messaging protocol. Steve  Vinoski summarized it nicely in <a title="Permanent Link: Just What We Need: Another RPC Package" rel="bookmark" href="http://steve.vinoski.net/blog/2008/05/22/just-what-we-need-another-rpc-package/">Just What We Need: Another RPC Package</a>. In fairness Steve had  some negative thoughts on PB also in <a title="Permanent Link: Protocol Buffers: Leaky RPC" rel="bookmark" href="http://steve.vinoski.net/blog/2008/07/13/protocol-buffers-leaky-rpc/">Protocol Buffers: Leaky RPC</a>. However, his concerns are around  the undefined RPC features Google put in PB, not the IDL type aspects of PB.</p>
<h4>
<div>Some other XML based protocol</div>
</h4>
<div>Yeah, I know the problem with XML isn’t XML it’s with the parsers. Cute  argument. Getting my message from native format on one system to native format  on another as fast as possible is what matters to me. So oddly enough parsers  are part of the equation. Yeah, jaxb is fast but just how fast?</div>
<div>
<p>Remember, we’re all about high volume low latency messages. It’s not a focus  for XML. Yep, no one will take issue with that statement!</p>
<h4>Binary XML</h4>
<p>Enough said. Next.</p>
<h4>Corba/IIOP</h4>
<p>Well defined IDL, a bit complicated (because it addresses a wide range of  issues).  Built in to the JDK! Not designed for speed or efficiency. Bad  fit.</p>
<h3>Conclusion</h3>
<p>Several good choices. I’m sure there’s others I missed. We’re going with  protobuf. Early tests by our developers have been very impressive. Google fan  bois can rejoice and the Google haters gripe. In the meantime we’ve got a job to  do.</p>
<p>Reference:</p>
<p>http://dewpoint.snagdata.com/2008/10/21/google-protocol-buffers/ (Original)</p>
</div>
</div>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/johnsofteng.wordpress.com/329/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/johnsofteng.wordpress.com/329/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/johnsofteng.wordpress.com/329/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/johnsofteng.wordpress.com/329/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/johnsofteng.wordpress.com/329/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/johnsofteng.wordpress.com/329/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/johnsofteng.wordpress.com/329/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/johnsofteng.wordpress.com/329/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/johnsofteng.wordpress.com/329/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/johnsofteng.wordpress.com/329/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/johnsofteng.wordpress.com/329/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/johnsofteng.wordpress.com/329/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/johnsofteng.wordpress.com/329/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/johnsofteng.wordpress.com/329/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=johnsofteng.wordpress.com&amp;blog=8263322&amp;post=329&amp;subd=johnsofteng&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://johnsofteng.wordpress.com/2010/03/20/google-protocol-buffers-and-other-data-interchange-formats/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/53024032acd728facceb97bfe56c7bc9?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">johnsofteng</media:title>
		</media:content>
	</item>
		<item>
		<title>python thread.error: can&#8217;t start new thread</title>
		<link>http://johnsofteng.wordpress.com/2010/03/05/python-thread-error-cant-start-new-thread/</link>
		<comments>http://johnsofteng.wordpress.com/2010/03/05/python-thread-error-cant-start-new-thread/#comments</comments>
		<pubDate>Fri, 05 Mar 2010 07:37:57 +0000</pubDate>
		<dc:creator>johnsofteng</dc:creator>
				<category><![CDATA[Python]]></category>
		<category><![CDATA[error]]></category>
		<category><![CDATA[thread]]></category>
		<category><![CDATA[ulimit]]></category>

		<guid isPermaLink="false">http://johnsofteng.wordpress.com/?p=312</guid>
		<description><![CDATA[The python has thread.error such as: File "/usr/lib/python2.5/threading.py", line 440, in start _start_new_thread(self.__bootstrap, ()) thread.error: can't start new thread The &#8220;can&#8217;t start new thread&#8221; error almost certainly due to the fact that you have already have too many threads running within your python process, and due to a resource limit of some kind the request [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=johnsofteng.wordpress.com&amp;blog=8263322&amp;post=312&amp;subd=johnsofteng&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>The python has thread.error such as:</p>
<p><code>File "/usr/lib/python2.5/threading.py", line 440, in start<br />
_start_new_thread(self.__bootstrap, ())<br />
thread.error: can't start new thread</code></p>
<p>The &#8220;can&#8217;t start new thread&#8221; error almost certainly due to the fact that you have already have too many threads running within your python process, and due to a resource limit of some kind the request to create a new thread is refused.</p>
<p>You should probably look at the number of threads you&#8217;re creating(maybe in the /proc/<em>pid</em>/); the maximum number you will be able to create will be determined by your environment, but it should be in the order of hundreds at least. (Can try ulimit to solve this issue)</p>
<p>It would probably be a good idea to re-think your architecture here; seeing as this is running asynchronously anyhow, perhaps you could use a pool of threads to fetch resources from another site instead of always starting up a thread for every request.</p>
<p>Another improvement to consider is your use of Thread.join and Thread.stop; this would probably be better accomplished by providing a timeout value to the constructor.</p>
<p><code>Reference:</code></p>
<p><code><a href="http://stackoverflow.com/questions/1834919/error-cant-start-new-thread">http://stackoverflow.com/questions/1834919/error-cant-start-new-thread</a></code></p>
<p>http://adywicaksono.wordpress.com/2007/07/10/i-can-not-create-more-than-255-threads-on-linux-what-is-the-solutions/</p>
<p>http://www.afnog.org/archives/2008-September/004535.html</p>
<p>http://rcsg.rice.edu/rcsg/shared/ulimit.html</p>
<p>http://answers.google.com/answers/threadview/id/311442.html</p>
<p>http://ubuntuforums.org/archive/index.php/t-114071.html</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/johnsofteng.wordpress.com/312/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/johnsofteng.wordpress.com/312/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/johnsofteng.wordpress.com/312/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/johnsofteng.wordpress.com/312/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/johnsofteng.wordpress.com/312/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/johnsofteng.wordpress.com/312/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/johnsofteng.wordpress.com/312/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/johnsofteng.wordpress.com/312/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/johnsofteng.wordpress.com/312/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/johnsofteng.wordpress.com/312/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/johnsofteng.wordpress.com/312/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/johnsofteng.wordpress.com/312/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/johnsofteng.wordpress.com/312/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/johnsofteng.wordpress.com/312/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=johnsofteng.wordpress.com&amp;blog=8263322&amp;post=312&amp;subd=johnsofteng&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://johnsofteng.wordpress.com/2010/03/05/python-thread-error-cant-start-new-thread/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/53024032acd728facceb97bfe56c7bc9?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">johnsofteng</media:title>
		</media:content>
	</item>
		<item>
		<title>Interesting videos</title>
		<link>http://johnsofteng.wordpress.com/2010/02/27/interesting-videos/</link>
		<comments>http://johnsofteng.wordpress.com/2010/02/27/interesting-videos/#comments</comments>
		<pubDate>Sat, 27 Feb 2010 09:20:17 +0000</pubDate>
		<dc:creator>johnsofteng</dc:creator>
				<category><![CDATA[Python]]></category>
		<category><![CDATA[video]]></category>

		<guid isPermaLink="false">http://johnsofteng.wordpress.com/?p=306</guid>
		<description><![CDATA[1. Google I/O 2008 &#8211; Painless Python by Alex Martelli (Google) http://www.youtube.com/watch?v=bDgD9whDfEY http://www.youtube.com/watch?v=y7vwZ20SDzc<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=johnsofteng.wordpress.com&amp;blog=8263322&amp;post=306&amp;subd=johnsofteng&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>1. Google I/O 2008 &#8211; Painless Python by Alex Martelli (Google)</p>
<p><a href="http://www.youtube.com/watch?v=bDgD9whDfEY">http://www.youtube.com/watch?v=bDgD9whDfEY</a></p>
<p><a href="http://www.youtube.com/watch?v=y7vwZ20SDzc">http://www.youtube.com/watch?v=y7vwZ20SDzc</a></p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/johnsofteng.wordpress.com/306/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/johnsofteng.wordpress.com/306/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/johnsofteng.wordpress.com/306/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/johnsofteng.wordpress.com/306/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/johnsofteng.wordpress.com/306/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/johnsofteng.wordpress.com/306/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/johnsofteng.wordpress.com/306/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/johnsofteng.wordpress.com/306/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/johnsofteng.wordpress.com/306/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/johnsofteng.wordpress.com/306/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/johnsofteng.wordpress.com/306/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/johnsofteng.wordpress.com/306/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/johnsofteng.wordpress.com/306/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/johnsofteng.wordpress.com/306/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=johnsofteng.wordpress.com&amp;blog=8263322&amp;post=306&amp;subd=johnsofteng&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://johnsofteng.wordpress.com/2010/02/27/interesting-videos/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/53024032acd728facceb97bfe56c7bc9?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">johnsofteng</media:title>
		</media:content>
	</item>
		<item>
		<title>CKEditor</title>
		<link>http://johnsofteng.wordpress.com/2010/02/26/ckeditor/</link>
		<comments>http://johnsofteng.wordpress.com/2010/02/26/ckeditor/#comments</comments>
		<pubDate>Fri, 26 Feb 2010 07:05:32 +0000</pubDate>
		<dc:creator>johnsofteng</dc:creator>
				<category><![CDATA[Javascript]]></category>
		<category><![CDATA[Services]]></category>
		<category><![CDATA[ckeditor]]></category>
		<category><![CDATA[web]]></category>
		<category><![CDATA[word]]></category>

		<guid isPermaLink="false">http://johnsofteng.wordpress.com/?p=295</guid>
		<description><![CDATA[CKEditor (formerly FCKeditor) is an open source WYSIWYG text editor from CKSource that can be used in web pages. It aims to be lightweight and requires no client-side installation. Its core code is written in JavaScript, having server side interfaces with Active-FoxPro, ASP, ASP.NET, ColdFusion, Java, JavaScript, Lasso, Perl, PHP and Python.[3] CKEditor is compatible [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=johnsofteng.wordpress.com&amp;blog=8263322&amp;post=295&amp;subd=johnsofteng&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p><strong>CKEditor</strong> (formerly <strong>FCKeditor</strong>) is an <a title="Open source" href="http://en.wikipedia.org/wiki/Open_source">open source</a> <a title="WYSIWYG" href="http://en.wikipedia.org/wiki/WYSIWYG">WYSIWYG</a> <a title="Text editor" href="http://en.wikipedia.org/wiki/Text_editor">text editor</a> from CKSource that can be used in web pages. It aims to be lightweight and requires no client-side installation.</p>
<p>Its core code is written in <a title="JavaScript" href="http://en.wikipedia.org/wiki/JavaScript">JavaScript</a>, having server side interfaces with Active-FoxPro, <a title="Active Server Pages" href="http://en.wikipedia.org/wiki/Active_Server_Pages">ASP</a>, <a title="ASP.NET" href="http://en.wikipedia.org/wiki/ASP.NET">ASP.NET</a>, <a title="ColdFusion" href="http://en.wikipedia.org/wiki/ColdFusion">ColdFusion</a>, <a title="Java (Sun)" href="http://en.wikipedia.org/wiki/Java_%28Sun%29">Java</a>, <a title="JavaScript" href="http://en.wikipedia.org/wiki/JavaScript">JavaScript</a>, <a title="Lasso (programming language)" href="http://en.wikipedia.org/wiki/Lasso_%28programming_language%29">Lasso</a>, <a title="Perl" href="http://en.wikipedia.org/wiki/Perl">Perl</a>, <a title="PHP" href="http://en.wikipedia.org/wiki/PHP">PHP</a> and <a title="Python (programming language)" href="http://en.wikipedia.org/wiki/Python_%28programming_language%29">Python</a>.<sup><a href="http://en.wikipedia.org/wiki/CKEditor#cite_note-why-2">[3]</a></sup></p>
<p>CKEditor is compatible with most Internet browsers, including: <a title="Internet Explorer" href="http://en.wikipedia.org/wiki/Internet_Explorer">Internet Explorer</a> 6.0+ (<a title="Microsoft Windows" href="http://en.wikipedia.org/wiki/Microsoft_Windows">Windows</a>), <a title="Firefox" href="http://en.wikipedia.org/wiki/Firefox">Firefox</a> 2.0+, <a title="Safari (web browser)" href="http://en.wikipedia.org/wiki/Safari_%28web_browser%29">Safari</a> 3.0+, <a title="Google Chrome" href="http://en.wikipedia.org/wiki/Google_Chrome">Google Chrome</a> (Windows), <a title="Opera (web browser)" href="http://en.wikipedia.org/wiki/Opera_%28web_browser%29">Opera</a> 9.50+, and <a title="Camino" href="http://en.wikipedia.org/wiki/Camino">Camino</a> 1.0+ (<a title="Apple Inc." href="http://en.wikipedia.org/wiki/Apple_Inc.">Apple</a>).<sup><a href="http://en.wikipedia.org/wiki/CKEditor#cite_note-why-2">[3]</a></sup></p>
<p>Reference:</p>
<p>http://en.wikipedia.org/wiki/CKEditor</p>
<p>http://ckeditor.com/</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/johnsofteng.wordpress.com/295/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/johnsofteng.wordpress.com/295/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/johnsofteng.wordpress.com/295/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/johnsofteng.wordpress.com/295/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/johnsofteng.wordpress.com/295/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/johnsofteng.wordpress.com/295/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/johnsofteng.wordpress.com/295/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/johnsofteng.wordpress.com/295/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/johnsofteng.wordpress.com/295/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/johnsofteng.wordpress.com/295/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/johnsofteng.wordpress.com/295/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/johnsofteng.wordpress.com/295/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/johnsofteng.wordpress.com/295/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/johnsofteng.wordpress.com/295/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=johnsofteng.wordpress.com&amp;blog=8263322&amp;post=295&amp;subd=johnsofteng&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://johnsofteng.wordpress.com/2010/02/26/ckeditor/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/53024032acd728facceb97bfe56c7bc9?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">johnsofteng</media:title>
		</media:content>
	</item>
		<item>
		<title>NPAPI</title>
		<link>http://johnsofteng.wordpress.com/2010/02/25/npapi/</link>
		<comments>http://johnsofteng.wordpress.com/2010/02/25/npapi/#comments</comments>
		<pubDate>Thu, 25 Feb 2010 21:02:13 +0000</pubDate>
		<dc:creator>johnsofteng</dc:creator>
				<category><![CDATA[C/C++]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Mac]]></category>
		<category><![CDATA[Windows]]></category>
		<category><![CDATA[firefox]]></category>
		<category><![CDATA[NPAPI]]></category>
		<category><![CDATA[plugin]]></category>

		<guid isPermaLink="false">http://johnsofteng.wordpress.com/?p=292</guid>
		<description><![CDATA[Netscape Plugin Application Programming Interface (NPAPI) is a cross-platform plugin architecture used by many web browsers. It was first developed for the Netscape family of browsers starting with Netscape Navigator 2.0 but has subsequently been implemented in other browsers including Mozilla Application Suite, Mozilla Firefox, Safari, Google Chrome, Opera, Konqueror, and some older versions of [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=johnsofteng.wordpress.com&amp;blog=8263322&amp;post=292&amp;subd=johnsofteng&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p><strong>Netscape Plugin Application Programming Interface</strong> (<strong>NPAPI</strong>) is a <a title="Cross-platform" href="http://en.wikipedia.org/wiki/Cross-platform">cross-platform</a> <a title="Plugin" href="http://en.wikipedia.org/wiki/Plugin">plugin</a> architecture used by many <a title="Web browser" href="http://en.wikipedia.org/wiki/Web_browser">web browsers</a>.</p>
<p>It was first developed for the <a title="Netscape Communications Corporation" href="http://en.wikipedia.org/wiki/Netscape_Communications_Corporation">Netscape</a> family of browsers starting with <a title="Netscape Navigator" href="http://en.wikipedia.org/wiki/Netscape_Navigator">Netscape Navigator</a> 2.0 but has subsequently been implemented in other browsers including <a title="Mozilla Application Suite" href="http://en.wikipedia.org/wiki/Mozilla_Application_Suite">Mozilla Application Suite</a>, <a title="Mozilla Firefox" href="http://en.wikipedia.org/wiki/Mozilla_Firefox">Mozilla Firefox</a>, <a title="Safari (web browser)" href="http://en.wikipedia.org/wiki/Safari_%28web_browser%29">Safari</a>, <a title="Chrome (web browser)" href="http://en.wikipedia.org/wiki/Chrome_%28web_browser%29">Google Chrome</a>, <a title="Opera (web browser)" href="http://en.wikipedia.org/wiki/Opera_%28web_browser%29">Opera</a>, <a title="Konqueror" href="http://en.wikipedia.org/wiki/Konqueror">Konqueror</a>, and some older versions of <a title="Microsoft" href="http://en.wikipedia.org/wiki/Microsoft">Microsoft</a> <a title="Internet Explorer" href="http://en.wikipedia.org/wiki/Internet_Explorer">Internet Explorer</a>.</p>
<p>Its success can be partly attributed to its simplicity. A plugin declares that it handles certain <a title="MIME" href="http://en.wikipedia.org/wiki/MIME">content types</a> (e.g. &#8220;audio/mp3&#8243;) through exposed file information. When the browser encounters such content type it loads the associated plugin, sets aside the space within the browser content for the plugin to render itself and then streams data to it. The plugin is then responsible for rendering the data as it sees fit, be it visual, audio or otherwise. So a plugin runs in-place within the page, as opposed to older browsers that had to launch an external application to handle unknown content types.</p>
<p>The <a title="Application programming interface" href="http://en.wikipedia.org/wiki/Application_programming_interface">API</a> requires each plugin to implement and expose a comparatively small number of functions. There are approximately 15 functions in total for initializing, creating, destroying, and positioning plugins. The NPAPI also supports scripting, printing, full screen plugins, windowless plugins and content streaming.</p>
<p>Reference:</p>
<p>http://en.wikipedia.org/wiki/NPAPI</p>
<p>https://developer.mozilla.org/en/Plugins</p>
<p>http://colonelpanic.net/2009/03/building-a-firefox-plugin-part-one/</p>
<p>http://colonelpanic.net/2009/05/building-a-firefox-plugin-part-two/</p>
<p>http://colonelpanic.net/2009/08/building-a-firefox-plugin-%E2%80%93-part-three/</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/johnsofteng.wordpress.com/292/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/johnsofteng.wordpress.com/292/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/johnsofteng.wordpress.com/292/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/johnsofteng.wordpress.com/292/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/johnsofteng.wordpress.com/292/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/johnsofteng.wordpress.com/292/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/johnsofteng.wordpress.com/292/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/johnsofteng.wordpress.com/292/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/johnsofteng.wordpress.com/292/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/johnsofteng.wordpress.com/292/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/johnsofteng.wordpress.com/292/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/johnsofteng.wordpress.com/292/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/johnsofteng.wordpress.com/292/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/johnsofteng.wordpress.com/292/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=johnsofteng.wordpress.com&amp;blog=8263322&amp;post=292&amp;subd=johnsofteng&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://johnsofteng.wordpress.com/2010/02/25/npapi/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/53024032acd728facceb97bfe56c7bc9?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">johnsofteng</media:title>
		</media:content>
	</item>
		<item>
		<title>ubuntu livecd mount LVM2 fs</title>
		<link>http://johnsofteng.wordpress.com/2010/01/28/ubuntu-livecd-mount-lvm2-fs/</link>
		<comments>http://johnsofteng.wordpress.com/2010/01/28/ubuntu-livecd-mount-lvm2-fs/#comments</comments>
		<pubDate>Fri, 29 Jan 2010 06:52:30 +0000</pubDate>
		<dc:creator>johnsofteng</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[livecd]]></category>
		<category><![CDATA[lvm2]]></category>
		<category><![CDATA[lvm2pv]]></category>
		<category><![CDATA[lvm2_member]]></category>
		<category><![CDATA[mount]]></category>
		<category><![CDATA[ubuntu]]></category>

		<guid isPermaLink="false">http://johnsofteng.wordpress.com/?p=274</guid>
		<description><![CDATA[1. Startup ubuntu livecd 2. sudo apt-get install lvm2 do NOT reboot!! 3.if you mount as following: sudo mount -t auto /dev/sda2 /mnt you will get error: mount: unknown filesystem type &#8216;LVM2_member&#8217; 4. check the phisical disk [ubuntu] $sudo pvs PV VG Fmt Attr PSize PFree /dev/sda1 VolGroup00 lvm2 a- 100M 40.00M /dev/sda2 VolGroup01 lvm2 [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=johnsofteng.wordpress.com&amp;blog=8263322&amp;post=274&amp;subd=johnsofteng&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>1. Startup ubuntu livecd</p>
<p>2. sudo apt-get install lvm2</p>
<p>do NOT reboot!!</p>
<p>3.if you mount as following:</p>
<p>sudo mount -t auto /dev/sda2 /mnt</p>
<p>you will get error: mount: unknown filesystem type &#8216;LVM2_member&#8217;</p>
<p>4. check the phisical disk</p>
<p>[ubuntu] $sudo pvs</p>
<pre>PV          VG         Fmt  Attr PSize   PFree 
<pre>  /dev/sda1  VolGroup00 lvm2 a-   100M 40.00M</pre>
<p>/dev/sda2  VolGroup01 lvm2 a-   200G 40.00M</pre>
<p>5. check the volume</p>
<p>[ubuntu]$sudo vgs</p>
<pre> VG         #PV #LV #SN Attr   VSize   VFree
  VolGroup01   1   4   0 wz--n- 200G 40.00M
</pre>
<p>6. check the logical volume</p>
<pre>[ubuntu]lvdisplay
<pre>  --- Logical volume ---
  LV Name                /dev/VolGroup01/LogVol03
  VG Name                VolGroup01
  LV UUID                YhG8Fu-Zrek-zx8D-AzxC-Dz34-d32F-dfal23I
  LV Write Access        read/write
 <span style="color:#00ff00;"> LV Status              unenable</span>
  # open                 1
  LV Size                200GB
  Current LE             781
  Segments               1
  Allocation             inherit
  Read ahead sectors     auto
  - currently set to     256
  Block device           253:2</pre>
</pre>
<p>7. active the logic vol</p>
<pre>[ubuntu]vgchange -ay /dev/VolGroup01
</pre>
<p>8. Check the status again</p>
<pre>[ubuntu]lvdisplay
<pre>  --- Logical volume ---
  LV Name                /dev/VolGroup01/LogVol03
  VG Name                VolGroup01
  LV UUID                YhG8Fu-Zrek-zx8D-AzxC-Dz34-d32F-dfal23I
  LV Write Access        read/write
<span style="color:#00ff00;">  LV Status              available</span>
  # open                 1
  LV Size                200GB
  Current LE             781
  Segments               1
  Allocation             inherit
  Read ahead sectors     auto
  - currently set to     256
  Block device           253:2
</pre>
</pre>
<p>9. mount it</p>
<p>mount /dev/VolGroup01/LogVol03 /mnt</p>
<pre>
</pre>
<p>Reference:</p>
<p>http://fedoraforum.org/forum/archive/index.php/t-64964.html</p>
<p>http://forums.opensuse.org/install-boot-login/396994-mount-lvm2-partition.html</p>
<p>http://www.howtoforge.com/linux_lvm</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/johnsofteng.wordpress.com/274/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/johnsofteng.wordpress.com/274/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/johnsofteng.wordpress.com/274/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/johnsofteng.wordpress.com/274/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/johnsofteng.wordpress.com/274/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/johnsofteng.wordpress.com/274/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/johnsofteng.wordpress.com/274/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/johnsofteng.wordpress.com/274/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/johnsofteng.wordpress.com/274/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/johnsofteng.wordpress.com/274/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/johnsofteng.wordpress.com/274/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/johnsofteng.wordpress.com/274/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/johnsofteng.wordpress.com/274/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/johnsofteng.wordpress.com/274/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=johnsofteng.wordpress.com&amp;blog=8263322&amp;post=274&amp;subd=johnsofteng&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://johnsofteng.wordpress.com/2010/01/28/ubuntu-livecd-mount-lvm2-fs/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/53024032acd728facceb97bfe56c7bc9?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">johnsofteng</media:title>
		</media:content>
	</item>
		<item>
		<title>staticmethod vs classmethod in Python</title>
		<link>http://johnsofteng.wordpress.com/2010/01/19/staticmethod-vs-classmethod-in-python/</link>
		<comments>http://johnsofteng.wordpress.com/2010/01/19/staticmethod-vs-classmethod-in-python/#comments</comments>
		<pubDate>Wed, 20 Jan 2010 00:37:24 +0000</pubDate>
		<dc:creator>johnsofteng</dc:creator>
				<category><![CDATA[Python]]></category>
		<category><![CDATA[classmethod]]></category>
		<category><![CDATA[staticmethod]]></category>

		<guid isPermaLink="false">http://johnsofteng.wordpress.com/?p=272</guid>
		<description><![CDATA[Python’s static methods have a similar implementation as Java &#38; C++. Static methods were not introduced into Python until version 2.2 Example of version 2.2 and higher implementation: &#62;&#62;&#62; class Foo: ... def bar(arg): ... Foo.arg = arg ... bar = staticmethod(bar) ... &#62;&#62;&#62; Foo.bar('Hello World') &#62;&#62;&#62; Foo.arg 'Hello World' &#62;&#62;&#62; Foo().bar('Hello') &#62;&#62;&#62; Foo.arg 'Hello' [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=johnsofteng.wordpress.com&amp;blog=8263322&amp;post=272&amp;subd=johnsofteng&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Python’s static methods have a similar implementation as Java &amp; C++. Static methods were not introduced into Python until version 2.2</p>
<p><strong>Example of version 2.2 and higher implementation:</strong></p>
<pre><code>
&gt;&gt;&gt; class Foo:
...     def bar(arg):
...         Foo.arg = arg
...     bar = staticmethod(bar)
...
&gt;&gt;&gt; Foo.bar('Hello World')
&gt;&gt;&gt; Foo.arg
'Hello World'
&gt;&gt;&gt; Foo().bar('Hello')
&gt;&gt;&gt; Foo.arg
'Hello'
</code></pre>
<p>Static methods can be called either on the class (such as Foo.bar()) or on an instance (such as Foo().bar()). The instance is ignored except for its class.</p>
<p>In version 2.4, function decorator syntax was added, which allows another way to define a static method. If you are using 2.4 or above, this is the recommended way of creating a static method.</p>
<p><strong>Example of version 2.4 and higher implementation:</strong></p>
<pre><code>
&gt;&gt;&gt; class Foo:
...     @staticmethod
...     def bar(arg):
...         Foo.arg = arg
...
&gt;&gt;&gt; Foo.bar('Hello World')
&gt;&gt;&gt; Foo.arg
'Hello World'
&gt;&gt;&gt; Foo().bar('Hello')
&gt;&gt;&gt; Foo.arg
'Hello'
</code></pre>
<p>If you are looking to do more advanced static methods, look into using classmethod instead of staticmethod. One of the differences between the two is that class method receives the class as implicit first argument, just like an instance method receives the instance. For further reading on class method, refer to the <a href="http://docs.python.org/lib/built-in-funcs.html">built in functions page</a>.</p>
<p>&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-</p>
<dl>
<dt> <tt>classmethod</tt><big>(</big><em>function</em><big>)</big></dt>
<dd>Return a class method for <em>function</em>.</p>
<p>A class method receives the class as implicit first argument, just like an instance method receives the instance. To declare a class method, use this idiom:</p>
<div>
<div>
<pre>class C:
    @classmethod
    def f(cls, arg1, arg2, ...): ...
</pre>
</div>
</div>
<p>The <tt>@classmethod</tt> form is a function <a href="http://docs.python.org/glossary.html#term-decorator"><em>decorator</em></a> – see the description of function definitions in <a href="http://docs.python.org/reference/compound_stmts.html#function"><em>Function definitions</em></a> for details.</p>
<p>It can be called either on the class (such as <tt>C.f()</tt>) or on an instance (such as <tt>C().f()</tt>).  The instance is ignored except for its class. If a class method is called for a derived class, the derived class object is passed as the implied first argument.</p>
<p>Class methods are different than C++ or Java static methods. If you want those, see <a title="staticmethod" href="http://docs.python.org/library/functions.html#staticmethod"><tt>staticmethod()</tt></a> in this section.</p>
<p>For more information on class methods, consult the documentation on the standard type hierarchy in <a href="http://docs.python.org/reference/datamodel.html#types"><em>The standard type hierarchy</em></a>.</p>
<p>New in version 2.2.</p>
<p>Changed in version 2.4: Function decorator syntax added.</p>
</dd>
</dl>
<dl>
<dt> <tt>staticmethod</tt><big>(</big><em>function</em><big>)</big></dt>
<dd>Return a static method for <em>function</em>.</p>
<p>A static method does not receive an implicit first argument. To declare a static method, use this idiom:</p>
<div>
<div>
<pre>class C:
    @staticmethod
    def f(arg1, arg2, ...): ...
</pre>
</div>
</div>
<p>The <tt>@staticmethod</tt> form is a function <a href="http://docs.python.org/glossary.html#term-decorator"><em>decorator</em></a> – see the description of function definitions in <a href="http://docs.python.org/reference/compound_stmts.html#function"><em>Function definitions</em></a> for details.</p>
<p>It can be called either on the class (such as <tt>C.f()</tt>) or on an instance (such as <tt>C().f()</tt>).  The instance is ignored except for its class.</p>
<p>Static methods in Python are similar to those found in Java or C++. For a more advanced concept, see <a title="classmethod" href="http://docs.python.org/library/functions.html#classmethod"><tt>classmethod()</tt></a> in this section.</p>
<p>For more information on static methods, consult the documentation on the standard type hierarchy in <a href="http://docs.python.org/reference/datamodel.html#types"><em>The standard type hierarchy</em></a>.</p>
<p>New in version 2.2.</p>
<p>Changed in version 2.4: Function decorator syntax added.</p>
</dd>
</dl>
<p>&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;</p>
<p>Being educated under Java background, static method and class method are the same thing.</p>
<p>But not so in Python, there is subtle difference:</p>
<p>Say <em>function a()</em> is defined in <em>Parent</em> Class, while <em>Sub</em> Class extends <em>Parent</em> Class</p>
<p>If function <em>a()</em> has <strong>@staticmethod</strong> decorator, <em>Sub.a()</em> still refers to definition inside <em>Parent</em> Class. Whereas,</p>
<p>If function <em>a()</em> has <strong>@classmethod</strong> decorator, <em>Sub.a()</em> will points definition inside <em>Sub</em> Class.</p>
<p>Let’s talk about some definitions here:</p>
<p><strong>@staticmethod</strong> function is nothing more than a function defined inside a class. It is callable without instantiating the class first. It’s definition is immutable via inheritance.</p>
<p><strong>@classmethod</strong> function also callable without instantiating the class, but its definition follows Sub class, not Parent class, via inheritance. That’s because the first argument for @classmethod function must always be cls (class).</p>
<p>&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-</p>
<p>Usually, static methods would be used for Singleton or Factory Patterns (http://en.wikipedia.org/wiki/Factory_method_pattern), but if you review this page, you will see Python doesn’t require a static method to be used to implement the Factory pattern.</p>
<p>Coming up with an example for static methods can be difficult. I usually use static methods in python for organization purposes. For instance, if I made a DB abstraction layer and had a few functions that were related to the DB layer, but weren’t necessary used in the class, I would added them as static methods. Keeps those functions organized in once place, plus I find it easier to remember.</p>
<p>For example:</p>
<p>&gt;&gt;&gt; data = db_convertAsciiToHtml(”Foo &amp; Bar”)</p>
<p>OR</p>
<p>&gt;&gt;&gt; data = DB.convertAsciiToHtml(”Foo &amp; Bar”)</p>
<p>References:</p>
<p>http://www.techexperiment.com/2008/08/21/creating-static-methods-in-python/</p>
<p>http://docs.python.org/library/functions.html</p>
<p>http://rapd.wordpress.com/2008/07/02/python-staticmethod-vs-classmethod/</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/johnsofteng.wordpress.com/272/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/johnsofteng.wordpress.com/272/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/johnsofteng.wordpress.com/272/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/johnsofteng.wordpress.com/272/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/johnsofteng.wordpress.com/272/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/johnsofteng.wordpress.com/272/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/johnsofteng.wordpress.com/272/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/johnsofteng.wordpress.com/272/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/johnsofteng.wordpress.com/272/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/johnsofteng.wordpress.com/272/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/johnsofteng.wordpress.com/272/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/johnsofteng.wordpress.com/272/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/johnsofteng.wordpress.com/272/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/johnsofteng.wordpress.com/272/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=johnsofteng.wordpress.com&amp;blog=8263322&amp;post=272&amp;subd=johnsofteng&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://johnsofteng.wordpress.com/2010/01/19/staticmethod-vs-classmethod-in-python/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/53024032acd728facceb97bfe56c7bc9?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">johnsofteng</media:title>
		</media:content>
	</item>
		<item>
		<title>Major and Minor Numbers</title>
		<link>http://johnsofteng.wordpress.com/2010/01/18/major-and-minor-numbers/</link>
		<comments>http://johnsofteng.wordpress.com/2010/01/18/major-and-minor-numbers/#comments</comments>
		<pubDate>Tue, 19 Jan 2010 04:44:51 +0000</pubDate>
		<dc:creator>johnsofteng</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[Services]]></category>
		<category><![CDATA[device]]></category>
		<category><![CDATA[major]]></category>
		<category><![CDATA[minor]]></category>
		<category><![CDATA[number]]></category>

		<guid isPermaLink="false">http://johnsofteng.wordpress.com/?p=280</guid>
		<description><![CDATA[One of the basic features of the Linux kernel is that it abstracts the handling of devices. All hardware devices look like regular files; they can be opened, closed, read and written using the same, standard, system calls that are used to manipulate files. Every device in the system is represented by a file. For [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=johnsofteng.wordpress.com&amp;blog=8263322&amp;post=280&amp;subd=johnsofteng&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>One of the basic features of the Linux kernel is that it abstracts the  handling of devices. All hardware devices look like regular files; they can be  opened, closed, read and written using the same, standard, system calls that are  used to manipulate files. Every device in the system is represented by a file.  For block (disk) and character devices, these device files are created by the  <kbd>mknod</kbd> command and they describe the device using major and minor  device numbers. Network devices are also represented by device special files but  they are created by Linux as it finds and initializes the network controllers in  the system.</p>
<p>To <a href="modules.php?name=MContent&amp;obj=glossary&amp;term=UNIX" target="glossary">UNIX</a>, everything is a file. To write to the hard disk, you  write to a file. To read from the keyboard is to read from a file. To store  backups on a tape device is to write to a file. Even to read from memory is to  read from a file. If the file from which you are trying to read or to which you  are trying to write is a &#8220;normal&#8221; file, the process is fairly easy to  understand: the file is opened and you read or write data. If, however, the  device you want to access is a special device file (also referred to as a device  node), a fair bit of work needs to be done before the read or write operation  can begin.</p>
<p>One key aspect of understanding device files lies in the fact that different  devices behave and react differently. There are no keys on a hard disk and no  sectors on a keyboard, though you can read from both. The system, therefore,  needs a mechanism whereby it can distinguish between the various types of  devices and behave accordingly.</p>
<p>To access a device accordingly, the <a href="modules.php?name=MContent&amp;obj=glossary&amp;term=operating%20system" target="glossary">operating system</a> must be told what to do. Obviously, the  manner in which the kernel accesses a hard disk will be different from the way  it accesses a <a href="modules.php?name=MContent&amp;obj=glossary&amp;term=terminal" target="glossary">terminal</a>. Both can be read from and written to, but that&#8217;s  about where the similarities end. To access each of these totally different  kinds of devices, the <a href="modules.php?name=MContent&amp;obj=glossary&amp;term=kernel" target="glossary">kernel</a> needs to know that they are, in fact, different.</p>
<p>Inside the <a href="modules.php?name=MContent&amp;obj=glossary&amp;term=kernel" target="glossary">kernel</a> are functions for each of the devices the kernel is  going to access. All the routines for a specific device are jointly referred to  as the <a href="modules.php?name=MContent&amp;obj=glossary&amp;term=device%20driver" target="glossary">device driver</a>. Each device on the system has its own <a href="modules.php?name=MContent&amp;obj=glossary&amp;term=device%20driver" target="glossary">device driver</a>. Within each device driver are the functions  that are used to access the device. For devices such as a hard disk or <a href="modules.php?name=MContent&amp;obj=glossary&amp;term=terminal" target="glossary">terminal</a>, the system needs to be able to (among other  things) open the device, write to the device, read from the device, and close  the device. Therefore, the respective drivers will contain the routines needed  to open, write to, read from, and close (among other things) those devices.</p>
<p>The <a href="modules.php?name=MContent&amp;obj=glossary&amp;term=kernel" target="glossary">kernel</a> needs to be told how to access the device. Not only  does the kernel need to be told what kind of device is being accessed but also  any special information, such as the <a href="modules.php?name=MContent&amp;obj=glossary&amp;term=partition" target="glossary">partition</a> number if it&#8217;s a hard disk or density if it&#8217;s a  floppy, for example. This is accomplished by the <a href="modules.php?name=MContent&amp;obj=glossary&amp;term=major%20number" target="glossary">major number</a> and <a href="modules.php?name=MContent&amp;obj=glossary&amp;term=minor%20number" target="glossary">minor number</a> of that device.</p>
<p><!-- START copyrightDavid Rusling:1996-1999:GNU General Public License -->All  devices controlled by the same device driver have a common major device number.  The minor device numbers are used to distinguish between different devices and  their controllers. Linux maps the device special file passed in system calls  (say to mount a file system on a block device) to the device&#8217;s device driver  using the major device number and a number of system tables, for example the  character device table, chrdevs. <!-- END copyrightDavid Rusling:1996-1999:GNU General Public License -->The  major number is actually the offset into the kernel&#8217;s <a href="modules.php?name=MContent&amp;obj=glossary&amp;term=device%20driver" target="glossary">device driver</a> table, which tells the <a href="modules.php?name=MContent&amp;obj=glossary&amp;term=kernel" target="glossary">kernel</a> what kind of device it is (whether it is a hard disk  or a serial terminal). The <a href="modules.php?name=MContent&amp;obj=glossary&amp;term=minor%20number" target="glossary">minor number</a> tells the kernel special characteristics of the  device to be accessed. For example, the second hard disk has a different minor  number than the first. The COM1 port has a different minor number than the COM2  port, each partition on the primary IDE disk has a different minor device  number, and so forth. So, for example, /dev/hda2, the second partition of the  primary IDE disk has a major number of 3 and a minor number of 2.</p>
<p>It is through this table that the routines are accessed that, in turn, access  the physical hardware. Once the <a href="modules.php?name=MContent&amp;obj=glossary&amp;term=kernel" target="glossary">kernel</a> has determined what kind of device to which it is  talking, it determines the specific device, the specific location, or other  characteristics of the device by means of the <a href="modules.php?name=MContent&amp;obj=glossary&amp;term=minor%20number" target="glossary">minor number</a>.</p>
<p>The <a href="modules.php?name=MContent&amp;obj=glossary&amp;term=major%20number" target="glossary">major number</a> for the hd (IDE) driver is hard-coded at 3. The  minor numbers have the format</p>
<p>(&lt;unit&gt;*64)+&lt;part&gt;</p>
<p>where &lt;unit&gt; is the IDE drive number on the <em>first </em>controller,  either 0 or 1, which is then multiplied by 64. That means that all hd devices on  the first <a href="modules.php?name=MContent&amp;obj=glossary&amp;term=IDE" target="glossary">IDE</a> drive have a <a href="modules.php?name=MContent&amp;obj=glossary&amp;term=minor%20number" target="glossary">minor number</a> less than 64. &lt;part&gt; is the <a href="modules.php?name=MContent&amp;obj=glossary&amp;term=partition" target="glossary">partition</a> number, which can be anything from 1 to 20. Which  minor numbers you will be able to access will depend on how many partitions you  have and what kind they are (extended, logical, etc.). The <a href="modules.php?name=MContent&amp;obj=glossary&amp;term=minor%20number" target="glossary">minor number</a> of the device node that represents the whole  disk is 0. This has the node name hda, whereas the other <a href="modules.php?name=MContent&amp;obj=glossary&amp;term=device%20nodes" target="glossary">device nodes</a> have a name equal to their <a href="modules.php?name=MContent&amp;obj=glossary&amp;term=minor%20number" target="glossary">minor number</a> (i.e., /dev/hda6 has a minor number 6).</p>
<p>If you were to have a second <a href="modules.php?name=MContent&amp;obj=glossary&amp;term=IDE" target="glossary">IDE</a> on the first controller, the unit number would be 1.  Therefore, all of the minor numbers would be 64 or greater. The <a href="modules.php?name=MContent&amp;obj=glossary&amp;term=minor%20number" target="glossary">minor number</a> of the device node representing the whole disk  is 1. This has the node name hdb, whereas the other <a href="modules.php?name=MContent&amp;obj=glossary&amp;term=device%20nodes" target="glossary">device nodes</a> have a name equal to their <a href="modules.php?name=MContent&amp;obj=glossary&amp;term=minor%20number" target="glossary">minor number</a> plus 64 (i.e., /dev/hdb6 has a minor number  70).</p>
<p>If you have more than one <a href="modules.php?name=MContent&amp;obj=glossary&amp;term=IDE" target="glossary">IDE</a> controller, the principle is the same. The only  difference is that the <em>major</em> number is 22.</p>
<p>For <a href="modules.php?name=MContent&amp;obj=glossary&amp;term=SCSI" target="glossary">SCSI</a> devices, the scheme is a little different. When you  have a <a href="modules.php?name=MContent&amp;obj=glossary&amp;term=SCSI" target="glossary">SCSI</a> host adapter, you can have up to  seven hard disks. Therefore, we need a different way to refer to the partitions.  In general, the format of the device nodes is</p>
<p>sd&lt;drive&gt;&lt;partition&gt;</p>
<p>where sd refers to the <a href="modules.php?name=MContent&amp;obj=glossary&amp;term=SCSI" target="glossary">SCSI</a> disk driver, &lt;drive&gt; is a letter for the physical  drive, and &lt;partition&gt; is the <a href="modules.php?name=MContent&amp;obj=glossary&amp;term=partition" target="glossary">partition</a> number. Like the hd devices, when a device refers  to the entire disk, for example the device sda refers to the first disk.</p>
<p>The <a href="modules.php?name=MContent&amp;obj=glossary&amp;term=major%20number" target="glossary">major number</a> for all <a href="modules.php?name=MContent&amp;obj=glossary&amp;term=SCSI" target="glossary">SCSI</a> drives is 8. The <a href="modules.php?name=MContent&amp;obj=glossary&amp;term=minor%20number" target="glossary">minor number</a> is based on the drive number, which is  multiplied by 16 instead of 64, like the <a href="modules.php?name=MContent&amp;obj=glossary&amp;term=IDE" target="glossary">IDE</a> drives. The <a href="modules.php?name=MContent&amp;obj=glossary&amp;term=partition" target="glossary">partition</a> number is then added to this number to give the  minor.</p>
<p>The <a href="modules.php?name=MContent&amp;obj=glossary&amp;term=partition" target="glossary">partition</a> numbers are not as simple to figure out. Partition  0 is for the whole disk (i.e., sda). The four <a href="modules.php?name=MContent&amp;obj=glossary&amp;term=DOS" target="glossary">DOS</a> primary partitions are numbered 14. Then the extended  partitions are numbered 58. We then add 16 for each drive. For example:</p>
<pre>brw-rw----   1 root     disk       8,  22 Sep 12  1994
/dev/sdb6</pre>
<p>Because b is after the sd, we know that this is on the second drive.  Subtracting 16 from the minor, we get 6, which matches the <a href="modules.php?name=MContent&amp;obj=glossary&amp;term=partition" target="glossary">partition</a> number. Because it is between 4 and 8, we know  that this is on an extended <a href="modules.php?name=MContent&amp;obj=glossary&amp;term=partition" target="glossary">partition</a>. This is the second partition on the first  extended partition.</p>
<p>The floppy devices have an even more peculiar way of assigning minor numbers.  The <a href="modules.php?name=MContent&amp;obj=glossary&amp;term=major%20number" target="glossary">major number</a> is fairly easy its 2. Because the names are a  little easier to figure out, lets start with them. As you might guess, the  device names all begin with fd. The general format is</p>
<p>fd&lt;drive&gt;&lt;density&gt;&lt;capacity&gt;</p>
<p>where &lt;drive&gt; is the drive number (0 for A:, 1 for B:), &lt;density&gt;  is the density (d-double, h-high), and &lt;capacity&gt; is the capacity of the  drive (360Kb, 1440Kb). You can also tell the size of the drive by the density  letter, lowercase letter indicates that it is a i5.25&#8243; drive and an uppercase  letter indicates that it is a 3.5&#8243; driver. For example, a low-density 5.25&#8243;  drive with a capacity of 360Kb would look like</p>
<p>fd0d360</p>
<p>If your second drive was a high-density 3.5&#8243; drive with a capacity of 1440Kb,  the device would look like</p>
<p>fd1H1440</p>
<p>What the minor numbers represents is a fairly complicated process. In the  fd(4) <a href="modules.php?name=MContent&amp;obj=glossary&amp;term=man-page" target="glossary">man-page</a> there is an explanatory table, but it is not  obvious from the table why specific minor numbers go with each device. The  problem is that there is no logical progression as with the hard disks. For  example, there was never a 3.5&#8243; with a capacity of 1200Kb nor has there been a  5.25&#8243; with a capacity of 1.44Mb. So you will never find a device with H1200 or  h1440. So to figure out the device names, the best thing is to look at the <a href="modules.php?name=MContent&amp;obj=glossary&amp;term=man-page" target="glossary">man-page</a>.</p>
<p>The <a href="modules.php?name=MContent&amp;obj=glossary&amp;term=terminal" target="glossary">terminal</a> devices come in a few forms. The first is the  system console, which are the devices tty0-tty?. You can have up to 64 virtual  terminals on you system console, although most systems that I have seen are  limited five or six. All console terminals have a <a href="modules.php?name=MContent&amp;obj=glossary&amp;term=major%20number" target="glossary">major number</a> of 4. As we discussed earlier, you can reach  the low numbered ones with ALT-Fn, where n is the number of the function key. So  ALT-F4 gets you to the fourth virtual console. Both the <a href="modules.php?name=MContent&amp;obj=glossary&amp;term=minor%20number" target="glossary">minor number</a> and the tty number are based on the function  key, so /dev/tty4 has a <a href="modules.php?name=MContent&amp;obj=glossary&amp;term=minor%20number" target="glossary">minor number</a> 4 and you get to it with ALT-F4. (Check the  console(4) <a href="modules.php?name=MContent&amp;obj=glossary&amp;term=man-page" target="glossary">man-page</a> to see how to use and get to the other virtual  terminals.)</p>
<p>Serial devices can also have terminals hooked up to them. These terminals  normally use the devices /dev/ttySn, where n is the number of the serial port  (0, 1, 2, etc.). These also have a minor number of 4, but the minor numbers all  start at 64. (Thats why you can only have 63 virtual consoles.) The minor  numbers are this base of 64, plus the serial port number (04). Therefore, the  minor number of the third serial port would be 64+3=67.</p>
<p>Related to these devices are the modem control devices, which are used to  access modems. These have the same minor numbers but have a major number of 5.  The names are also based on the device number. Therefore, the <a href="modules.php?name=MContent&amp;obj=glossary&amp;term=modem" target="glossary">modem</a> device attached to the third serial port has a <a href="modules.php?name=MContent&amp;obj=glossary&amp;term=minor%20number" target="glossary">minor number</a> of 64+3=67 and its name is cua3.</p>
<p>Another device with a <a href="modules.php?name=MContent&amp;obj=glossary&amp;term=major%20number" target="glossary">major number</a> of 5 is /dev/tty, which has a <a href="modules.php?name=MContent&amp;obj=glossary&amp;term=minor%20number" target="glossary">minor number</a> of 0. This is a special device and is referred  to as the &#8220;controlling <a href="modules.php?name=MContent&amp;obj=glossary&amp;term=terminal" target="glossary">terminal</a>. &#8221; This is the terminal device for the currently  running process. Therefore, no matter where you are, no matter what you are  running, sending something to /dev/tty will always appear on your screen.</p>
<p>The pseudo-terminals (those that you use with <a href="modules.php?name=MContent&amp;obj=glossary&amp;term=network" target="glossary">network</a> connections or X) actually come in pairs. The  &#8220;slave&#8221; is the device at which you type and has a name like ttyp?, where ? is  the tty number. The device that the process sees is the &#8220;master&#8221; and has a name  like ptyn, where n is the device number. These also have a <a href="modules.php?name=MContent&amp;obj=glossary&amp;term=major%20number" target="glossary">major number</a> 4. However, the master devices all have minor  numbers based on 128. Therefore, pty0 has a <a href="modules.php?name=MContent&amp;obj=glossary&amp;term=minor%20number" target="glossary">minor number</a> of 128 and pty9 has a minor number of 137  (128+9). The slave device has minor numbers based on 192, so the slave device  ttyp0 has a <a href="modules.php?name=MContent&amp;obj=glossary&amp;term=minor%20number" target="glossary">minor number</a> of 192. Note that the tty numbers do not  increase numerically after 9 but use the letter af.</p>
<p>Other oddities with the device numbering and naming scheme are the memory  devices. These have a major number of 1. For example, the device to access <a href="modules.php?name=MContent&amp;obj=glossary&amp;term=physical%20memory" target="glossary">physical memory</a> is /dev/mem with a <a href="modules.php?name=MContent&amp;obj=glossary&amp;term=minor%20number" target="glossary">minor number</a> of 1. The <a href="modules.php?name=MContent&amp;obj=glossary&amp;term=kernel" target="glossary">kernel</a> memory device is /dev/kmem, and it has a <a href="modules.php?name=MContent&amp;obj=glossary&amp;term=minor%20number" target="glossary">minor number</a> of 2. The device used to access IO ports is  /dev/port and it has a <a href="modules.php?name=MContent&amp;obj=glossary&amp;term=minor%20number" target="glossary">minor number</a> of 4.</p>
<p>What about minor number 3? This is for device /dev/null, which is nothing. If  you direct output to this device, it goes into nothing, or just disappears.  Often the error output of a command is directed here, as the errors generated  are uninteresting. If you redirect from /dev/null, you get nothing as well.  Often I do something like this:</p>
<p>cat /dev/null &gt; file_name</p>
<p>This device is also used a lot in <a href="modules.php?name=MContent&amp;obj=glossary&amp;term=shell" target="glossary">shell</a> scripts where you do not want to see any output or  error messages. You can then redirect standard out or standard error to  /dev/null and the messages disappear. For details on standard out and error, see  the <a href="/modules.php?name=MContent&amp;pageid=21">section on  redirection</a>.</p>
<p>If file_name doesn&#8217;t exist yet, it is created with a length of zero. If it  does exist, the file is truncated to 0 bytes.</p>
<p>The device /dev/zero has a <a href="modules.php?name=MContent&amp;obj=glossary&amp;term=major%20number" target="glossary">major number</a> of 5 and its <a href="modules.php?name=MContent&amp;obj=glossary&amp;term=minor%20number" target="glossary">minor number</a> is 5. This behaves similarly to /dev/null in  that redirecting output to this device is the same as making it disappear.  However, if you direct input <em>from</em> this device, you get an unending stream  of zeroes. Not the number 0, which has an ASCII value of 48this is an <a href="modules.php?name=MContent&amp;obj=glossary&amp;term=ASCII" target="glossary">ASCII</a> 0.</p>
<p>Are those all the devices? Unfortunately not. However, I hope that this has  given you a start on how device names and minor numbers are configured. The file  &lt;linux/major.h&gt; contains a list of the currently used (at least well  known) major numbers. Some nonstandard package might add a <a href="modules.php?name=MContent&amp;obj=glossary&amp;term=major%20number" target="glossary">major number</a> of its own. Up to this point, they have been  fairly good about not stomping on the existing major numbers.</p>
<p>As far as the minor numbers go, check out the various man-pages. If there is  a <a href="modules.php?name=MContent&amp;obj=glossary&amp;term=man-page" target="glossary">man-page</a> for a specific device, the <a href="modules.php?name=MContent&amp;obj=glossary&amp;term=minor%20number" target="glossary">minor number</a> will probably be under the name of the driver.  This is in major.h or often the first letter of the device name. For example,  the parallel (printer) devices are lp?, so check out man lp.</p>
<p>The best overview of all the major and minor numbers is in the  /usr/src/linux/Documentation directory. The devices.txt is considered the  &#8220;authoritative&#8221; source for this information.</p>
<p>References:</p>
<p>http://www.linux-tutorial.info/modules.php?name=MContent&#038;pageid=94</p>
<p>http://www.linux-tutorial.info/modules.php?name=MContent&#038;obj=glossary&#038;term=man-page</p>
<p>http://www.kernel.org/pub/linux/docs/device-list/devices.txt</p>
<p>http://publib.boulder.ibm.com/infocenter/dsichelp/ds8000ic/index.jsp?topic=/com.ibm.storage.ssic.help.doc/f2c_linuxdevnaming_2hsag8.html</p>
<p>http://docsrv.sco.com/HDK_concepts/ddT_majmin.html</p>
<p>http://burks.brighton.ac.uk/burks/linux/rute/node18.htm</p>
<p>http://www.makelinux.info/ldd3/chp-3-sect-2.shtml</p>
<p>http://www.thegeekstuff.com/2009/06/how-to-identify-major-and-minor-number-in-linux/</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/johnsofteng.wordpress.com/280/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/johnsofteng.wordpress.com/280/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/johnsofteng.wordpress.com/280/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/johnsofteng.wordpress.com/280/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/johnsofteng.wordpress.com/280/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/johnsofteng.wordpress.com/280/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/johnsofteng.wordpress.com/280/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/johnsofteng.wordpress.com/280/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/johnsofteng.wordpress.com/280/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/johnsofteng.wordpress.com/280/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/johnsofteng.wordpress.com/280/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/johnsofteng.wordpress.com/280/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/johnsofteng.wordpress.com/280/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/johnsofteng.wordpress.com/280/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=johnsofteng.wordpress.com&amp;blog=8263322&amp;post=280&amp;subd=johnsofteng&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://johnsofteng.wordpress.com/2010/01/18/major-and-minor-numbers/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/53024032acd728facceb97bfe56c7bc9?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">johnsofteng</media:title>
		</media:content>
	</item>
		<item>
		<title>XenIntro</title>
		<link>http://johnsofteng.wordpress.com/2010/01/08/xenintro/</link>
		<comments>http://johnsofteng.wordpress.com/2010/01/08/xenintro/#comments</comments>
		<pubDate>Fri, 08 Jan 2010 07:15:52 +0000</pubDate>
		<dc:creator>johnsofteng</dc:creator>
				<category><![CDATA[C/C++]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Services]]></category>
		<category><![CDATA[Introduction]]></category>
		<category><![CDATA[Xen]]></category>

		<guid isPermaLink="false">http://johnsofteng.wordpress.com/?p=284</guid>
		<description><![CDATA[Xen Intro- version 1.0: Contents Introduction Xen and IA32 Protection Modes The Xend daemon: The Xen Store: VT-x (virtual technology) processors &#8211; support in Xen Vmxloader VT-i (virtual technology) processors &#8211; support in Xen AMD SVM Xen On Solaris Step by step example of creating guest OS with Virtual Machine Manager in Fedora Core 6 [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=johnsofteng.wordpress.com&amp;blog=8263322&amp;post=284&amp;subd=johnsofteng&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p><strong>Xen Intro- version 1.0:</strong></p>
<div>
<p>Contents</p>
<ol>
<li><a href="#head-ea24be3f9c1144310a32c4ca3047f6e4560a9e76">Introduction</a></li>
<li><a href="#head-968c8068db0952a2d509b95bc25099f2ff0de9ee">Xen and IA32  Protection Modes</a></li>
<li><a href="#head-e3024eb9a20e4883f753dae26df6a51fd71a861a">The Xend  daemon:</a></li>
<li><a href="#head-4e27782aeef9debb00d812d9041a8e180ca414f0">The Xen Store:</a></li>
<li><a href="#head-d945d0dd0a57135909a3beae9a74e15095af77fb">VT-x (virtual  technology) processors &#8211; support in Xen</a></li>
<li><a href="#head-44c34ecbd3536c6e5cbbc09f3b96b2c4e98a4b17">Vmxloader</a></li>
<li><a href="#head-0fdee3ed1d138dbd360a608763c478cd9a7e7aa9">VT-i (virtual  technology) processors &#8211; support in Xen</a></li>
<li><a href="#head-a3701c5d12c3e4e21e7f8bb447d2cbffc2e9cb53">AMD SVM</a></li>
<li><a href="#head-1ad72cde4abe7c93072cfbdfe5d66c421e9914a2">Xen On Solaris</a></li>
<li><a href="#head-b92d8b84fba2c72099710afd1027e8eafdad0f98">Step by step  example of creating guest OS with Virtual Machine Manager in Fedora Core 6</a></li>
<li><a href="#head-cbf18c0f662adf210024bf449d3329c509be4fa0">Physical  Interrupts</a></li>
<li><a href="#head-f812265f11277c6b2c3a10c94db485758e37e2bb">Backend  Drivers:</a></li>
<li><a href="#head-67f47b69a0c09a0788288c90045fe40bd11ac46d">Migration and Live  Migration:</a></li>
<li><a href="#head-8954d739f295a3245b7169929a5230b462260437">Creating of a  domain &#8211; behind the scenes:</a></li>
<li><a href="#head-ffc96b3ced09e70a8bcb5b0831d577e0892d96f6">HyperCalls Mapping  to code Xen 3.0.2</a></li>
<li><a href="#head-701c95eb311d0a6cc50e8383d4286257b99da7c8">Virtualization and  the Linux Kernel</a></li>
<li><a href="#head-aaf6e59ef45692cc4ad84e85656f0eb037d3c01e">Pre-Virtualization</a></li>
<li><a href="#head-1d44953614faab381fd32b0e8c63f0feb98f1d45">Xen Storage</a></li>
<li><a href="#head-5c45f5442fc5700fa30e6e295f5d38c5dbb9d2c6">kvm &#8211; Kernel-based  Virtualization Driver</a></li>
<li><a href="#head-4a9b7d3bea01ee522a0e4e8caa02e1332503f1af">Tip: How to build  Xen with your own tar ball</a></li>
<li><a href="#head-48cbb68fc6d8bf1f3434b03630923ef1a02c046c">Xen in the Linux  Kernel</a></li>
<li><a href="#head-4b3de967c546a9ad9fd12f7402b8163946940743">VMI : Virtual  Machine Interface</a></li>
<li><a href="#head-577cd69714b5d24297748902ae758fda4b7b9594">Links</a></li>
<li><a href="#head-e2e4a234896aa188a9addd5e326e818265ba2fea">Adding new device  and triggering the probe() functions</a>
<ol>
<li><a href="#head-b455c7944a07c5ceb05e6bc4f911a83ee7f6dfdc">deviceback.c</a></li>
<li><a href="#head-1cae230b42ee2ae00ed08ba606c2ada0ce3642c1">xenbus.c</a></li>
<li><a href="#head-fb3e5849588b78823d33560b09b74e4dc75c4055">common.h</a></li>
<li><a href="#head-e6fc3a609b28fe31fb9c8d8454c2918815be0f7b">Makefile</a></li>
</ol>
</li>
<li><a href="#head-a6b774bff231998a0cfbe74341467bd0451d724c">Adding a frontend  device</a>
<ol>
<li><a href="#head-e6fc3a609b28fe31fb9c8d8454c2918815be0f7b-2">Makefile</a></li>
<li><a href="#head-34dbb29222fb16906f7c963f7f125159a067744d">devicefront.c</a></li>
</ol>
</li>
<li><a href="#head-250800453b2dd8e8b359a030e3d6fa81ea9f374d">Discussion</a></li>
</ol>
</div>
<h3 id="head-ea24be3f9c1144310a32c4ca3047f6e4560a9e76">Introduction</h3>
<p>All of the following text refers to x86 platform of  Xen-unstable, unless otherwise explicitly said. We will deal only with Xen on  linux 2.6 ; We are not dealing at all with Xen on linux 2.4 (and as far as we  know, in the future, domain 0 is intended to be based ONLY on 2.6).  Moreover,currently the 2.4 linux tree is removed from Xen Tree (changeset  7263:f1abe953e401 from 8.10.05) but it can be that it will be back when some  problems will be fixed.</p>
<p>This document deals only with Xen 3.0 version unless explictily  said otherwise.</p>
<p>This is not intended to be a full and detailed documentation of  the Xen project but we hope it will be a starting point to anyone who is  interested in Xen and wants to learn more.</p>
<p>The Xen Project team is permitted to take part or all of this  document and integrate it with the official Xen documentation or put it as a  standalone document in the Xen Web Site if they wish, without any further  notice.</p>
<p>This is not a complete detailed document nor a full walkthrough  ,and many important issues are omitted. Any feedback is welcomed to : Rami Rosen  , <a href="mailto:ramirose@gmail.com">ramirose@gmail.com</a></p>
<h3 id="head-968c8068db0952a2d509b95bc25099f2ff0de9ee">Xen and IA32 Protection  Modes</h3>
<p>In the classical protection model of IA-32, there are 4  privilege levels; The highest ring is 0, where the kernel runs. (this level is  also called <a href="/xenwiki/SuperVisor">SuperVisor</a> Mode)  The lowest is ring 3, where User applications run (this level is also called  User Mode) Issuing some instructions , which are called &#8220;privileged  instructions&#8221; , from ring which is NOT ring 0, will cause a General Protection  Fault.</p>
<p>Ring 1,2 were not used through the years (except for in the  case of OS/2). When running Xen, we run a Hypervisor in ring 0 and the guest OS  in ring 1. The applications run unmodified at ring 3.</p>
<p>BTW, there are of course architectures which have a different  privilege models; for example, in PPC both domain 0 and the Unprivileged domains  run in supervisor mode. Diagram: Xen and IA32 Protection Modes</p>
<p><img title="rings" src="http://www.ipd.bth.se/ska/rings.png" alt="rings" /></p>
<h3 id="head-e3024eb9a20e4883f753dae26df6a51fd71a861a">The Xend daemon:</h3>
<p>The Xend Daemon handles requests issued from Domain 0; requests  can be, for example, creating a new domain (&#8220;xm create&#8221;) or listing the domains  (&#8220;xm list&#8221;), shutting down a domain (&#8220;xm destroy&#8221;). Running &#8220;xm help&#8221; will show  all possibilities.</p>
<p>You start the Xend daemon by running, after booting into  domain0, &#8220;xend start&#8221;. &#8220;xend start&#8221; creates two daemons: xenstored and  xenconsoled (see toos/misc/xend). It also creates an instance of a python <a href="/xenwiki/SrvDaemon">SrvDaemon</a> class and calls its  start() method. (see <em>tools/python/xen/xend/server/<a href="/xenwiki/SrvDaemon">SrvDaemon</a>.py</em>).</p>
<p>The <a href="/xenwiki/SrvDaemon">SrvDaemon</a> start() method is in fact the xend main  program.</p>
<p>In the past,the start() method of <a href="/xenwiki/SrvDaemon">SrvDaemon</a> eventually started an http socket (8000)  on which it listened to http requests. Now it does not open an http socket on  port 8000 anymore.</p>
<p>Note : There is an altenative to the management layer of Xen  which is called libvirt; see <a href="http://libvir.org/">http://libvir.org</a>. This is a free API (LGPL)</p>
<h3 id="head-4e27782aeef9debb00d812d9041a8e180ca414f0">The Xen Store:</h3>
<p>The Xen Store Daemon provides a simple tree-like database to  which we can read and write values. The Xen Store code is mainly under  tools\xenstore.</p>
<p>It replaces the XCS, which was a daemon handling control  messages.</p>
<p>The physical xenstore resides in one file:  /var/lib/xenstored/tdb. (previously it was sacttered in some files; the change  to using one file (named &#8220;tdb&#8221;) was probably to increase performance).</p>
<p>Both user space (&#8220;tools&#8221; in Xen terminology) and kernel code  can write to the <a href="/xenwiki/XenStore">XenStore</a>.The kernel code writes  to the <a href="/xenwiki/XenStore">XenStore</a> by using <a href="/xenwiki/XenBus">XenBus</a>.</p>
<p>The python scripts (under tools/python) uses lowlevel/xs.c to  read/write to the <a href="/xenwiki/XenStore">XenStore</a>.</p>
<p>The Xen Store Daemon is started in xenstored_core.c. It creates  a device file (&#8220;/dev/xen/evtchn&#8221;) in case such a device file does not exists and  it opens it. (see : domain_init() ,file  <strong>tools/xenstore/xenstored_domain.c</strong>).</p>
<p>It opens 2 TCP sockets (UNIX sockets). One of these sockets is  a Read-Only socket, and it resides under /var/run/xenstored/socket_ro. The  second is /var/run/xenstored/socket.</p>
<p>Connections on these sockets are represented by the connection  struct.</p>
<p>A connection can be in one of three states:</p>
<pre>        BLOCKED (blocked by a transaction)
        BUSY    (doing some action)
        OK      (completed it's transaction)
</pre>
<p>struct connection is declared in xenstore/xenstored_core.h;  When a socket is <a href="/xenwiki/ReadOnly">ReadOnly</a>,the  &#8220;can_write&#8221; member of it is false.</p>
<p>Then we start an endless loop in which we can get input/output  from three sources: the two sockets and the event channel, mentioned above.</p>
<p>Events, which are received in the event channel,are handled by  handle_event() method (file <em>xenstored_domain.c</em>).</p>
<p>There are six executables under tools/xenstore, five of which  are in fact made from the same module, which is xenstore_client.c, each time  built with a different DEFINE passed. (See the Makefile). The sixth tool is  built from xsls.c</p>
<p>These executables are : xenstore-exists, xenstore-list,  xenstore-read, xenstore-rm, xenstore-write and xsls.</p>
<p>You can use these executable for accessing xenstore. For  example: to view the list of fields of domain 0 which has a path  &#8220;local/domain/0&#8243;, you run:</p>
<pre>xenstore-list /local/domain/0
</pre>
<p>and a typical result can be the following list:</p>
<pre>cpu
memory
name
console
vm
domid
backend
</pre>
<p>The xsls command is very useful and recursively shows the  contents of a specified <a href="/xenwiki/XenStore">XenStore</a> path.  Essentially it does a xenstore-list and then a xenstore-read for each returned  field, displaying the fields and their values and then repeating this  recursively on each sub-path. For example: to view information about all VIFs  backends hosted in domain 0 you may use the following command.</p>
<pre>xsls /local/domain/0/backend/vif
</pre>
<p>and a typical result may be:</p>
<pre>14 = ""
 0 = ""
  bridge = "xenbr0"
  domain = "vm1"
  handle = "0"
  script = "/etc/xen/scripts/vif-bridge"
  state = "4"
  frontend = "/local/domain/14/device/vif/0"
  mac = "aa:00:00:22:fe:9f"
  frontend-id = "14"
  hotplug-status = "connected"
15 = ""
 0 = ""
  mac = "aa:00:00:6e:d8:46"
  state = "4"
  handle = "0"
  script = "/etc/xen/scripts/vif-bridge"
  frontend-id = "15"
  domain = "vm2"
  frontend = "/local/domain/15/device/vif/0"
  hotplug-status = "connected"
</pre>
<p>(The xenstored must be running for these six executables to  run; If xenstored is not running, then running theses executables will usually  hang. The Xend daemon can be stopped).</p>
<p>An instance of struct node is the elementary unit of the <a href="/xenwiki/XenStore">XenStore</a>. (struct node is defined in  xenstored_core.h). The actual writing to the <a href="/xenwiki/XenStore">XenStore</a> is done by write_node() method of  xenstored_core.c.</p>
<p>xen_start_info structure has a member named :store_evtchn.  (declared in public/xen.h as u16). This is the event channel for store  communication.</p>
<h3 id="head-d945d0dd0a57135909a3beae9a74e15095af77fb">VT-x (virtual technology)  processors &#8211; support in Xen</h3>
<p>Note: following text refers only to IA-32 unless explicitly  said otherwise.</p>
<p>Intel had announced Pentium® 4 672 and 662 processors in  November 2005 with virtualization support. (see, for example: <a href="http://www.physorg.com/news8160.html">http://www.physorg.com/news8160.html</a>).</p>
<p>How does Xen support the Intel Virtualization Technology ?</p>
<p>The VT extensions support in Xen3 code is mostly in  xen/arch/x86/hvm/vmx*.c.</p>
<ul>
<li>and xen/include/asm-x86/vmx*.h and  xen/arch/x86/x86_32/entry.S.</li>
</ul>
<p>arch_vcpu structure (<em>file  xen/include/asm-x86/domain.h</em>) contains a member which is called arch_vmx  and is an instance of arch_vmx_struct. This member is also important to  understand the VT-x mechanism.</p>
<p>But the most important structure for VT-x is the VMCS(  vmcs_struct in the code) which represents the VMCS region.</p>
<p>The definition (<em>file include/asm-x86/vmx_vmcs.h</em>) is  short:</p>
<p>struct vmcs_struct</p>
<ul>
<li>{ u32 vmcs_revision_id; unsigned char data  [0]; /* vmcs size is read from MSR */ };</li>
</ul>
<p>The VMCS region contains six logical regions; most relevant to  our discussions are Guest-state area and Host-state area. We will also deal with  the other four regions: VM-execution control fields,VM-exit control fields,  VM-entry control fields and VM-exit information fields.</p>
<p>Intel added 10 new opcodes in VT-x to support Intel  Virtualization Technology. They are detailed in the end of this section.</p>
<p>When using this technology, Xen runs in &#8220;VMX root operation  mode&#8221; while the guest domains (which are unmodified OSs) run in &#8220;VMX non-root  operation mode&#8221;. Since the guest domains run in &#8220;non-root operation&#8221; mode, it is  more restricted,meaning that certain actions will cause &#8220;VM exit&#8221; to the VM.</p>
<p>Xen enters VMX operation in start_vmx() method. (<em> file  xen/arch/x86/vmx.c</em>)</p>
<p>This method is called from init_intel() method (<em>file  xen/arch/x86/cpu/intel.c.</em>) (CONFIG_VMX should be defined).</p>
<p>First we check the X86_FEATURE_VMXE bit in ecx register to see  if the cpuid shows that there is support for VMX in the processor. In IA-32  Intel added in the CR4 control register a bit specifying whether we want to  enable VMX. So we must set this bit to enable VMX on the processor (by calling  set_in_cr4(X86_CR4_VMXE)); This bit is bit 13 in CR4 (VMXE).</p>
<p>Then we call _vmxon to start VMX operation. If we will try to  start VMX operation by _vmxon when the VMXE bit in CR4 is not set we will get  exception (#UD , for undefined opcode)</p>
<p>In IA-64, things are a little different due to different  architecture structure: Intel added a new bit in IA-64 in the Processor Status  Register (PSR). This is bit 46 and it&#8217;s called VM. It should be set to 1 in  guest OSs; and when it&#8217;s values is 1 , certain instructions cause virtualization  fault.</p>
<p>VM exit:</p>
<p>Some instructions can cause unconditionally VM exit and some  can cause VM exit under certain VM-execution control fields. (see the discussion  about VMX-region above)</p>
<p>The following instructions will cause VM exit unconditionally:  CPUID, INVD, MOV from CR3, RDMSR, WRMSR, and all the new VT-x instructions  (which are listed below).</p>
<p>There are other instruction like HLT,INVPLG (Invalidate TLB  Entry instruction) MWAIT and others which will cause VM exit if a corresponding  VM-execution control was set.</p>
<p>Apart from VM-execution control fields, there are 2 bitmpas  which are used for determining whether to perform VM exit: The first is the  exception bitmap (see EXCEPTION_BITMAP in vmcs_field enum , <em>file  xen/include/asm-x86/vmx_vmcs.h</em>). This bitmap is 32 bit field; when a bit is  set in this bitmap, this causes a VM exit if a corresponding exception occurs;  by default ,the entries which are set are EXCEPTION_BITMAP_PG (for page fault)  and EXCEPTION_BITMAP_GP (for General Protection). see  MONITOR_DEFAULT_EXCEPTION_BITMAP in vmx.h.</p>
<p>The second bitmap is the I/O bitmap (in fact, there are 2 I/O  bitmaps,A and B, each is 4KB in size) which controls I/O instructions on ports.  I/O bitmap A contains the ports in the range 0000-7FFF and I/O bitmap B contains  the ports in the range 8000-FFFF. (one bit for each I/O port). see IO_BITMAP_A  and IO_BITMAP_B in vmcs_field enum (VMCS Encordings).</p>
<p>When there is an &#8220;VM exit&#8221; we reach the  vmx_vmexit_handler(struct cpu_user_regs regs) in vmx.c. We handle the VM exit  according to the exit reason which we read from the VMCS region. We read the  vmcs by calling vmread() ; The return value of vmread is 0 in case of success.</p>
<p>We sometimes also need to read some additional data  (VM_EXIT_INTR_INFO) from the vmcs.</p>
<p>We get additional data by getting the &#8220;VM-exit interruption  information&#8221; which is a 32 bit field and the &#8220;Exit qualification&#8221; (64 bit  value).</p>
<p>For example, if the exception was NMI, we check if it is valid  by checking bit 31 (valid bit) of the VM-exit interruption field. In case it is  not valid we call _hvm_bug() to print some statistics and crash the domain.</p>
<p>Example of reading the &#8220;Exit qualification&#8221; field is in the  case where the VMEXIT was caused by issuing INVPLG instruction.</p>
<p>When we work with vt-x, the guest OSs work in shadow mode,  meaning they use shadow page tables; this is because the guest kernel in a VMX  guest does not know that it&#8217;s being virtualized. There is no software visible  bit which indicates that the processor is in VMX non-root operation. We set  shadow mode by calling shadow_mode_enable() in vmx_final_setup_guest() method  (<em>file vmx.c</em>).</p>
<p>There are 43 basic exit reasons &#8211; you can see part of them in  vmx.h (fields starting with EXIT_REASON_ like EXIT_REASON_EXCEPTION_NMI, which  is exit reason number 0, and so on).</p>
<p>In VT-x, Xen will probably use an emulated devices layer which  will send virtual interrupts to the VMM. We can prevent the OS from receiving  interrupts by setting the IF flag of EFLAGS.</p>
<p>The new ten opcodes which Intel added in Vt-x are detailed  below:</p>
<p>1) <strong>VMCALL</strong>: (VMCALL_OPCODE in vmx.h)</p>
<ul>
<li>This simply calls the VM monitor, causing vm  exit.</li>
</ul>
<p>2) <strong>VMCLEAR</strong>: (VMCLEAR_OPCODE in vmx.h)</p>
<ul>
<li>copies VMCS data to memory in case it does not  written there.</li>
<li>wrapper : _vmpclear (u64 addr) in vmx.h.</li>
</ul>
<p>3) <strong>VMLAUNCH</strong> (VMLAUNCH_OPCODE in vmx.h)</p>
<ul>
<li>launched a virtual machine; changes the launch  state of the VMCS to
<ul>
<li>launched (if it is clear)</li>
</ul>
</li>
</ul>
<p>4) <strong>VMPTRLD</strong> (VMPTRLD_OPCODE <em>file  vmx.h</em>)</p>
<ul>
<li>loads a pointer to the VMCS.
<ul>
<li>wrapper : _vmptrld (u64 addr) (<em>file vmx.h</em>)</li>
</ul>
</li>
</ul>
<p>5) <strong>VMPTRST</strong> (VMPTRST_OPCODE in vmx.h)</p>
<ul>
<li>stores a pointer to the VMCS.wrapper : _vmptrst (u64 addr) (<em>file vmx.h.</em>)</li>
</ul>
<p>6) <strong>VMREAD</strong> (VMREAD_OPCODE in vmx.h)</p>
<ul>
<li>read specified field from VMCS.</li>
<li>wrapper : _vmread(x, ptr) (<em>file vmx.h</em>)</li>
</ul>
<p>7) <strong>VMRESUME</strong> (VMRESUME_OPCODE in vmx.h)</p>
<ul>
<li>resumes a virtual machine ; in order it to  resume the VM,
<ul>
<li>the launch state of the VMCS should be &#8220;clear.</li>
</ul>
</li>
</ul>
<p> <img src='http://s2.wp.com/wp-includes/images/smilies/icon_cool.gif' alt='8)' class='wp-smiley' /> <strong>VMWRITE</strong> (VMWRITE_OPCODE in vmx.h)</p>
<ul>
<li>write specified field in VMCS. wrapper  _vmwrite (field, value).</li>
</ul>
<p>9) <strong>VMXOFF</strong> (VMXOFF_OPCODE in vmx.h)</p>
<ul>
<li>terminates VMX operation.
<ul>
<li>wrapper : _vmxoff (void) (<em>file vmx.h.</em>)</li>
</ul>
</li>
</ul>
<p>10) <strong>VMXON</strong> (VMXON_OPCODE in vmx.h)</p>
<ul>
<li>starts VMX operation.wrapper : _vmxon (u64 addr) (<em>file vmx.h.</em>)</li>
</ul>
<p><strong>QEMU and VT-D</strong> The io in Vt-x is performed by  using QEMU. The QEMU code which Xen uses is under tools/ioemu. It is based on  version 0.6.1 of QEMU. This version was patched accrording to Xen needs. Also  AMD SVM uses QEUMU emulation.</p>
<p>The default network card which QEMU uses in Vt-x is AMD  PCnet-PCI II Ethernet Controller. (<em>file tools/ioemu/hw/pcnet.c</em>). The  reason to prefer this nic emulation to the other alternative, ne2000, is that  pcnet uses DMA whereas ne2000 does not.</p>
<p>There is of course a performance cost for using QEMU, so there  are chances that usage of QEMU will be replaced in the future with different  soulutions which have lower performance costs.</p>
<p>Intel had annouced in March 2006 its VT-d Technology (Intel  Virtualization Technology for Directred I/O). This technology enables to assign  devices to virtual machines. It also enables DMA remapping, which can be  configured for each device. There is a cache called IOTLB which improves  performance.</p>
<h3 id="head-44c34ecbd3536c6e5cbbc09f3b96b2c4e98a4b17">Vmxloader</h3>
<p>There are some restrictions on VMX operation. Guest OSes in VMX  cannot operate in Real Mode. If bit PE (Protection Enabled) of CR0 is 0 or bit  PG (&#8220;Enable Paging&#8221;) of CR0 is 0, then trying to start the VMX operation (VMXON  instruction) fails.If after entering VMX operation you try to clear these bits,  you get an exception (General Protection Exception). When using a linux loader,  it starts in real mode. As a result, a vmxloader was written for vmx images.  (<em>file tools/firmware/vmxassist/vmxloader.c.</em>)</p>
<p>(In order to build vmxloader you must have dev86 package  installed; dev86 is a real mode 80&#215;86 assembler and linker).</p>
<p>After installing Xen, vmxloader is under /usr/lib/xen/boot. In  order to use it, you should specify kernel = &#8220;/usr/lib/xen/boot/vmxloader&#8221; in  the config file (which is an input to your &#8220;xm create&#8221; command.)</p>
<p>The vmxloader loads ROMBIOS at 0xF0000, then VGABIOS at  0xC0000, and then VMXAssist at D000:0000.</p>
<p>What is VMXAssist? The VMXAssist is an emulator for real mode  which uses the Virtual-8086 mode of IA32. After setting Virtual-8086 mode, it  executes in a 16-bit environment.</p>
<p>There are certain instructions which are not recognized in  virtual-8086 mode. For example, LIDT (Load Interrupt Register Table), or LGDT  (Load Global <a href="/xenwiki/DescriptorTable">DescriptorTable</a>).</p>
<p>These instructions cause #GP(0) when trying to run them in  protected mode.</p>
<p>So the VMXAssist assist checks the opcode of the instructions  which are being executed, and handles them so that they will not cause General  Protection Exception (as would have happened without its intervention).</p>
<h3 id="head-0fdee3ed1d138dbd360a608763c478cd9a7e7aa9">VT-i (virtual technology)  processors &#8211; support in Xen</h3>
<p>Note : the files mentioned in this sections are from the  unstable xen version).</p>
<p>In Vt-i extension for IA64 processors,intel added a bit to the  PSR (process status register). This bit is bit 46 of the PSR and is called  PSR.vm. When this bit is set, some instructions will cause a fault.</p>
<p>A new instruction called vmsw (Virtual Machine Switch) was  added. This instruction sets the PSR.vm to 1 or 0. This instruction can be used  to cause transition to or from a VM without causing an interruption.</p>
<p>Also a descriptor named VPD was added; this descriptor  represents the resources of a virtual processor. It&#8217;s size is 64 K. (It must be  32 aligned).</p>
<p>A VPD stands for &#8220;Virtual Processor Descriptor&#8221;. A structure  named vpd_t represents the VPD descriptor (<em>file  include/public/arch-ia64.h</em>).</p>
<p>Two vectors were added to the ivt: One is the External  Interrupt vector (0&#215;3400) and the other is the Virtualization vector (0&#215;6100).</p>
<p>The virtualization vector handler is called when an instruction  which need virtualization was called. This handler cannot be raised by IA-32  instructions.</p>
<p>Also nine PAL services were added. PAL stands for Processor  Abstraction Layer.</p>
<p>The services that were added are:  PAL_VPS_RESUME_NORMAL,PAL_VPS_RESUME_HANDLER,PAL_VPS_SYNC_READ,  PAL_VPS_SYNC_WRITE,PAL_VPS_SET_PENDING_INTERRUPT,PAL_VPS_THASH, PAL_VPS_TTAG,  PAL_VPS_RESTORE and PAL_VPS_SAVE, (<em>file include/asm-ia64/vmx_pal_vsa.h</em>)</p>
<h3 id="head-a3701c5d12c3e4e21e7f8bb447d2cbffc2e9cb53">AMD SVM</h3>
<p>AMD will hopefully release PACIFICA processors with  virtualization support in Q2 2006. (probably on June 2006). The IOMMU  virtualization support is to be out in 2007.</p>
<p>Them xen-unstable tree now includes both intel VT and SVM  support, using a common API which is called HVM.</p>
<p>The inclusion of HVM in the unstable tree is since changeset  8708 from 31/1/06, which is a &#8220;Big merge the HVM full-virtualisation  abstractions.&#8221;</p>
<p>You can download the code by: hg clone <a href="http://xenbits.xensource.com/xen-unstable.hg">http://xenbits.xensource.com/xen-unstable.hg</a></p>
<p>The code for AMD SVM is mostly under xen/arch/x86/hvm/svm.</p>
<p>The code is developed by AMD team: Tom Woller, Mats Petersson,  Travis Betak, Nagib Gulam, Leo Duran, Rosilmildo Dasilva and Wei Huang.</p>
<p>SVM stands for &#8220;Secure Virtual Machine&#8221;.</p>
<p>One major difference between Vt-x and AMD SVM is that the AMD  SVM virtualization extensions include tagged TLB (whereas Intel virtualization  extensions for IA-32 does not). The benefit of a tagged TLB is significantly  reducing the number of TLB flushes ; this is achieved by using an ASID (Address  Space Identifer) in the TLB. Using tagged TLB is common in RISC processors.</p>
<p>In AMD SVM, the most important struct (which is parallel to the  VT-x vmcs_struct) is the vmcb_struct. (<em>file  xen/include/asm-x86/hvm/svm/vmcb.h</em>). VMCB stands for Virtual Machine  Control Block.</p>
<p>AMD added the following eight instructions to the SVM  processor:</p>
<p><strong>VMLOAD</strong> loads the processor state from the  VMCB. <strong>VMMCALL</strong> enables the guest to communicate with the VMM.  <strong>VMRUN</strong> starts the operation of a guest OS.  <strong>VMSAVE</strong> store the processor state from the VMCB.  <strong>CLGI</strong> clears the global interrupt flag (GIF)  <strong>SLGI</strong> sets the global interrupt flag (GIF)  <strong>INVPLGA</strong> invalidates the TLB mapping of a specified virtual page</p>
<ul>
<li>and a specfied ASID.</li>
</ul>
<p><strong>SKINIT</strong> reinitilizes the CPU.</p>
<p>To issue these instructions SVM must be enabled. Enabling SVM  is done by setting bit 12 of the EFER MSR register.</p>
<p>In VT-x, the vmx_vmexit_handler() method handles VM Entries. In  AMD SVM, the svm_vmexit_handler() method is the one which handles VM exits.  (<em>file xen/arch/x86/hvm/svm/svm.c</em>) When VM exit occurs, the processor  saves the reason for this exit in the exit_code member of the VCMB. The  svm_vmexit_handler() handles the VM EXIT according to the exit_reason of the  VMCB.</p>
<h3 id="head-1ad72cde4abe7c93072cfbdfe5d66c421e9914a2">Xen On Solaris</h3>
<p>On 13 Feb 2006, Sun had released the Xen sources for Solaris  x86. See : <a href="http://opensolaris.org/os/community/xen/opening-day">http://opensolaris.org/os/community/xen/opening-day</a>.</p>
<p>This version currently supports 32 bit only ;it enables  openSolaris to be a guest OS where dom0 is a modifed Linux kernel running Xen.  Also this version is currently only for x86 (porting to SPARC processor is much  more difficult). The members of the Solaris Xen project are Tim Marsland, John  Levon, Mark Johnson, Stu Maybee, Joe Bonasera, Ryan Scott, Dave Edmondson and  others. Todd Clayton is leading the 64-bit solaris Xen project. In order to boot  the Solaris Xen guest many changes were done; can see more details in <a href="http://blogs.sun.com/roller/page/JoeBonasera">http://blogs.sun.com/roller/page/JoeBonasera</a>.</p>
<p>You can download the Xen Solaris sources from : <a href="http://dlc.sun.com/osol/xen/downloads/osox-src-12-02-2006.tar.gz">http://dlc.sun.com/osol/xen/downloads/osox-src-12-02-2006.tar.gz</a></p>
<p>Frontend net virtual device sources are in  <em>uts/common/io/xennet/xennetf.c</em>. (xennet is the net front virtual  driver.).</p>
<p>Frontend block virtual device sources are in uts/i86xen/io/xvbd  (xvbd is the block front virtual driver.).</p>
<p>Currently the front block device does not work. There are many  things which are similiar between Xen on Solaris and Xen on Linux.</p>
<p>In Xen Solaris Hypercall are also made by calling int 0&#215;82 .  (see #define TRAP_INSTR int $0&#215;82 (<em>file /uts/i86xen/ml/hypersubr.s</em>)</p>
<p>Sun also released in february 2006 the specs for the T1  prcoessor, which supports virtualization: see : <a href="http://opensparc.sunsource.net/nonav/opensparct1.html">http://opensparc.sunsource.net/nonav/opensparct1.html</a></p>
<p>see: <a href="http://www.prnewswire.com/cgi-bin/stories.pl?ACCT=104&amp;STORY=/www/story/02-14-2006/0004281587&amp;EDATE=">http://www.prnewswire.com/cgi-bin/stories.pl?ACCT=104&amp;STORY=/www/story/02-14-2006/0004281587&amp;EDATE=</a></p>
<p>Also the UltraSPARC T1 Hypervisor API Specification was  released: <a href="http://opensparc.sunsource.net/specs/Hypervisor_api-26-v6.pdf">http://opensparc.sunsource.net/specs/Hypervisor_api-26-v6.pdf</a></p>
<p>T1 virtualization:</p>
<p>The Hyperprivileged edition of the UltraSPARC Architecture 2005  Specification describes the Nonprivileged, Privileged, and Hyperprivileged  (hypervisor/virtual machine firmware) spec.</p>
<p>The virtual processor on Sun supports three privilege modes:</p>
<ul>
<li>1) User Mode 2) Privileged Mode3) <a href="/xenwiki/HyperPrivileged">HyperPrivileged</a> Mode.</li>
</ul>
<p>2 bits determine the privilege mode of the processor:  HPSTATE.hpriv and PSTATE.priv When both are 0 ,we are in nonprivileged mode When  both are 1 ,we are in privileged mode When HPSTATE.hpriv is 1 , we are in  Hyperprivileged mode (regardless of the value of PSTATE.priv). PSTATE is the  Processor State register. HPSTATE is the Hyperprivileged State register  HPSTATE.(64 bit). Each virtual processor has only one instance of the PSTATE and  HPSTATE registers. The HPSTATE is one of the HPR state registers, and it is also  called HPR 0. It can be read by the RDHPR instructions, and it can be written by  the WRHPR instruction.</p>
<h3 id="head-b92d8b84fba2c72099710afd1027e8eafdad0f98">Step by step example of  creating guest OS with Virtual Machine Manager in Fedora Core 6</h3>
<p>This secrion describes a step by step example of creating guest  OS based on FC6 i386 with Virtual Machine Manager in a Fedora Core 6 machine by  installing from a WEB URL:</p>
<p>Go to : Application-&gt;System Tools-&gt;Virtual Machine  Manager Choose : Local Xen Host Press New. Enter a name for the guest. You reach  now the &#8220;Locating installation media&#8221; dialog. In &#8220;install media URL&#8221; you should  enter a URL of Fedora Core 6 i386 download. For example, &#8220;<a href="http://download.fedora.redhat.com/pub/fedora/linux/core/6/i386/os/">http://download.fedora.redhat.com/pub/fedora/linux/core/6/i386/os/</a>&#8221;  then press forward. Choose simple file, and give a path to a non existing file  in some existing folder. than: File size: choose 3.5 GB for example ; if you  will assign less space, you will not be able to finish the installation,  assuming it is a typical , non custom, installation.</p>
<p>Then press forward ; accept the defaults for memory/cpu and  then press forward. Than press finish. That&#8217;s it! When insalling from web like  this it can take 2-4 hours, depending on your bandwidth. You will get to the  text mode installation of fedora core 6, and have to enter parameters for the  installation.</p>
<p>After the installation is finished and you want to restart the  guest OS , you do it by simply: &#8220;xm create /etc/xen/<a href="/xenwiki/NameOfGuest">NameOfGuest</a>&#8220;, where <a href="/xenwiki/NameOfGuest">NameOfGuest</a> is of course the name of guest you  choose in the installation.</p>
<h3 id="head-cbf18c0f662adf210024bf449d3329c509be4fa0">Physical  Interrupts</h3>
<p>In Xen, only the Hypervisor has an access to the hardware so  that to achieve isolation (it is dangerous to share the hardware and let other  domains access directly hardware devices simultaneously).</p>
<p>Let&#8217;s take a little walkthrough dealing with Xen interrupts:</p>
<p>Handling interrupts in Xen is done by using event channels.  Each domain can hold up to 1024 events. An event channel can have 2 flags  associated with it : pending and mask. The mask flag can be updated only by  guests. The hypervisor cannot update it. These flags are not part of the event  channel structure itself. (struct evtchn is defined in  <em>xen/include/xen/sched.h</em> ). There are 2 arrays in struct shared_info  which contains these flags: evtchn_pending[] and evtchn_mask[] ; each holds 32  elements. (<em>file xen/include/public/xen.h</em>)</p>
<p>(The shared_info is a member in domain struct; it is the domain  shared data area).</p>
<p>TBD: add info about event selectors (evtchn_pending_sel in  vcpu_info).</p>
<p>Registration (or binding) of irqs in guest domains:</p>
<p>The guest OS calls init_IRQ() when it boots (start_kernel()  method calls init_IRQ() ; <em>file init/main.c</em>).</p>
<p>(init_IRQ() is in <em>file  sparse/arch/xen/kernel/evtchn.c</em>)</p>
<p>There can be 256 physical irqs; so there is an array called  irq_desc with 256 entries. (<em>file sparse/include/linux/irq.h</em>)</p>
<p>All elements in this array are initialized in init_IRQ() so  that their status is disabled (IRQ_DISABLED).</p>
<p>Now, when a physical driver starts it usually calls  request_irq().</p>
<p>This method eventually calls setup_irq() (both in  <em>sparse/kernel/irq/manage.c</em>). which calls startup_pirq().</p>
<p>startup_pirq() send a hypercall to the hypervisor  (HYPERVISOR_event_channel_op) in order to bind the physical irq (pirq) . The  hypercall is of type EVTCHNOP_bind_pirq. See: startup_pirq() (<em>file  sparse/arch/xen/kernel/evtchn.c</em>)</p>
<p>On the Hypervisor side, handling this hypervisor call is done  in: evtchn_bind_pirq() method (<em>file /common/event_channel.c</em>) which  calls pirq_guest_bind() (<em>file arch/x86/irq.c</em>). The pirq_guest_bind()  changes the status of the corresponding irq_desc array element to be enabled  (~IRQ_DISABLED). it also calls startup() method.</p>
<p>Now when an interrupts arrives from the controller (the APIC),  we arrive at do_IRQ() method as is also in usual linux kernel (also in  arch/x86/irq.c). The Hypervisor handles only timer and serial interrupts. Other  interrupts are passed to the domains by calling _do_IRQ_guest() (In fact, the  IRQ_GUEST flag is set for all interrupts except for timer and serial  interrupts). _do_IRQ_guest() send the interrupt by calling send_guest_pirq() to  all guests who are registered on this IRQ. The send_guest_pirq() creates an  event channel (an instance of evtchn) and sets the pending flag of this event  channel. (by calling evtchn_set_pending()) Then, asynchronously, Xen will notify  this domain regarding this interrupt (unless it is masked).</p>
<p>TBD: shared interrupts; avoiding problems with shared  interrupts when using PCI express.</p>
<h3 id="head-f812265f11277c6b2c3a10c94db485758e37e2bb">Backend Drivers:</h3>
<p>The Backend Drivers are started from domain 0. We will deal  mainly with the network and block drivers. The network backend drivers reside  under sparse/drives/xen/netback, and the block backend drivers reside under  sparse/drives/xen/blkback.</p>
<p>There are many things in common between the netback and blkback  device drivers. There are some differences, though. The blkback device drivers  runs a kernel daemon thread (named <img src='http://s2.wp.com/wp-includes/images/smilies/icon_mad.gif' alt=':x' class='wp-smiley' /> enblkd) whereas the netback device driver  does not run any kernel thread.</p>
<p>The netback and blkback register themselves with <a href="/xenwiki/XenBus">XenBus</a> by calling xenbus_register_backend().</p>
<p>This method simply calls xenbus_register_driver_common(); both  are in <em>sparse/drivers/xen/xenbus/xenbus_probe.c.</em></p>
<p>(The xenbus_register_driver() method calls the generic kernel  method for registering drivers, driver_register()).</p>
<p>Both netback (network backend driver) and blkback (block  backend driver) has a module named xenbus.c. There are drivers which are not  splitted to backend/frontend drivers;for example, the balloon driver.The balloon  driver calls register_xenstore_notifier() in its initialization (balloon_init()  method). The register_xenstore_notifier() uses a generic linux callback  mechanism for passing status changes (notifier_block in  <em>include/linux/notifier.h</em>).</p>
<p>The USB driver also has a backend and frontend drivers;  currently it has no support to the xenbus/xenstore API so it does not have a  module named xenbus.c but it will probably be adjusted in the future. As of  writing of this document, the USB backend/frontend code was removed temporarily  from the sparse tree.</p>
<p>Each of the backend drivers registers two watches: one for the  backend and one for the frontend. The registration of the watches is done in the  probe method:</p>
<p>* In netback it is in netback_probe() method (<em>file  netback/xenbus.c</em>).</p>
<p>* In blkback it is in blkback_probe() method (<em>file  blkback/xenbus.c</em>).</p>
<p>A registration of a watch is done by calling the  xenbus_watch_path2() method. This method is implemented in  sparse/drivers/xen/xenbus/xenbus_client.c. Evntually the watch registration is  done by calling register_xenbus_watch(), which is implemented in  sparse/drivers/xen/xenbus/xenbus_xs.c.</p>
<p>In both cases, netback and blkback, the callback for the  backend watch is called backend_changed, and the callback for the forntend watch  is called frontend_changed.</p>
<p>xenbus_watch is a simple struct consisting of 3 elements:</p>
<p>A reference to a list of watches (list_head)</p>
<p>A pointer to a node (char*)</p>
<p>A callback function pointer.</p>
<p>The xenbus.c in both netback and blkback defines a struct  called backend_info; These structs have much in common: there are minor  differences between them. One difference is that in the netback the  communications channel is an instance of netif_t whereas in the blkback the  communications channel is an instance of blkif_t; In the case of blkback, it  includes also the major/minor numbers of the device and the mode (whereas these  members don&#8217;t exist in the backend_info struct of the netback).</p>
<p>In the case of netback, there is also a <a href="/xenwiki/XenbusState">XenbusState</a> member. The state machine for <a href="/xenwiki/XenBus">XenBus</a> includes seven states: Unknown, Initialising,  <a href="/xenwiki/InitWait">InitWait</a> (early initialisation  was finished, and xenbus is waiting for information from the peer or hotplug  scripts), Initialised (waiting for a connection from the peer), Connected,  Closing (due to an error or an unplug event) and Closed.</p>
<p>One of the members of this struct (backend_info) is an instance  of xenbus_device.(xenbus_device is declared in sparse/include/asm-xen/xenbus.h).  The nodename looks like a directory path, for example, dev-&gt;nodename in the  blkback case may look like:</p>
<pre>backend/vbd/94e11324-7eb1-437f-86e6-3db0e145136e/771
</pre>
<p>and dev-&gt;nodename in the netback may look like:</p>
<pre>backend/vif/94e11324-7eb1-437f-86e6-3db0e145136e/1
</pre>
<p>We create an event channel for communication between the two  domains by calling a bind_interdomain Hypervisor call.  (HYPERVISOR_event_channel_op).</p>
<p>For the networking,this is done in netif_map() in  netback/interface.c. For the block device, this is done in blkif_map() in  blkback/interface.c.</p>
<p>We use the grant tables to create shared memory between  frontend and backend domain. In the case of network drivers,this is done by  calling: gnttab_grant_foreign_transfer_ref(). (called in:  network_alloc_rx_buffers(), <em>file netfront.c</em>)</p>
<p>gnttab_grant_foreign_transfer_ref() sets a bit named  GTF_accept_transfer in the grant_entry.</p>
<p>In the case of block drivers,this is done by calling:  gnttab_grant_foreign_access_ref() in blkif_queue_request() (<em>file  blkfront.c</em>)</p>
<p>gnttab_grant_foreign_access_ref() sets a bit named  GTF_permit_access in the grant entry. grant entry (grant_entry_t) represents a  page frame which is shared between domains.</p>
<p>Diagram: Virtual Split Devices</p>
<p><img title="virtualDevices" src="http://www.ipd.bth.se/ska//virtualDevices.png" alt="virtualDevices" /></p>
<h3 id="head-67f47b69a0c09a0788288c90045fe40bd11ac46d">Migration and Live  Migration:</h3>
<p>Xend must be configured so that migration (which is also termed  relocation) will be enabled. In /etc/xen/xend-config.sxp, there is the  definition of the relocation-port, so the following line should be uncommented:</p>
<pre>(xend-relocation-port 8002)
</pre>
<p>The line &#8220;(xend-address localhost)&#8221; prevents remote connections  on the localhost,so this line must be commented.</p>
<p>Notice: if this line is commented in the side to which you want  to migrate your domain, you will most likely get the following error after  issuing the migrate command:</p>
<pre>"Error: can't connect: Connection refused"
</pre>
<p>This error can be traced to domain_migrate() method in  /tools/python/xen/xend/<a href="/xenwiki/XendDomain">XendDomain</a>.py which start a TCP connection on the  relocation port (which is by default 8002)</p>
<pre>...
...
def domain_migrate(self, domid, dst, live=False, resource=0):
        """Start domain migration."""
        dominfo = self.domain_lookup(domid)
        port = xroot.get_xend_relocation_port()
        try:
            sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            sock.connect((dst, port))
        except socket.error, err:
            raise XendError("can't connect: %s" % err[1])
...
...
</pre>
<p>See more details on the relocation protocol (implemented in  relocate.py) below.</p>
<p>The line &#8220;(xend-relocation-server yes)&#8221; should be uncommented  so the migration server will be running.</p>
<p>When we issue a migration command like &#8220;xm migrate #numOfDomain  ipAddress&#8221; or , if we want to use live-migration , we add the &#8211;live flag thus:  &#8220;xm migrate #numOfDomain &#8211;live ipAddress&#8221;, we call server.xend_domain_migrate()  after validating that the arguments are valid. (<em>file  /tools/python/xen/xm/migrate.py</em>)</p>
<p>We enter the domain_migrate() method of <a href="/xenwiki/XendDomain">XendDomain</a>, which first performs a domain lookup  and then creates a TCP connection for the migration with the target machine;  then it sends a &#8220;receive&#8221; packet (a packets which contains the string &#8220;receive&#8221;)  on port 8002. The other sides gets this message in in the dataReceived() method  (see of web/connection.py) and delegates it to dataReceived() of <a href="/xenwiki/RelocationProtocol">RelocationProtocol</a> (<em>file /tools/python/xen/xend/server/relocate.py</em>). Eventually it calls  the save() method of <a href="/xenwiki/XendChekpoint">XendChekpoint</a> to start the migration process.</p>
<p>We end up with a call to op_receive() which ultimately sends  back a &#8220;ready receive&#8221; message (also on port 8002). See op_receive() method in  relocation.py.</p>
<p>The save() method of <a href="/xenwiki/XendChekpoint">XendChekpoint</a> opens a thread which calls the  xc_save executable (which is in /usr/lib/xen/bin/xc_save). (<em>file  /tools/python/xen/xend/<a href="/xenwiki/XendCheckpoint">XendCheckpoint</a>.py</em>).</p>
<p>The xc_save executable is build from tools/xcutils/xc_save.c.</p>
<p>The xc_save executable calls xc_linux_save() in  tools/libxc/xc_linux_save, which in fact performs most of the migration process.  (see xc_linux_save() in /tools/libxc/xc_linux_save.c)</p>
<p>The xc_linux_save() returns 0 on success, and 1 in case of  failure.</p>
<p>Live migration is currently supported for 32-bit and 64-bit  architectures. TBD: find out if there is support for live-migration for pae  architectures. Jacob Gorm Hansen is doing an interesting work with migration in  Xen; see <a href="http://www.diku.dk/%7Ejacobg/self-migration">http://www.diku.dk/~jacobg/self-migration</a>.</p>
<p>He wrote code which performs Xen &#8220;self-migration&#8221; , which is a  migration which is done without the hypervisor involvement. The migration is  done by opening a User Space socket and reading from a special file  (/dev/checkpoint).</p>
<p>His code works with linux-2.6 bases xen-unstable.</p>
<p>You can get it by: hg clone <a href="http://www.distlab.dk/hg/index.cgi/xen-gfx.hg">http://www.distlab.dk/hg/index.cgi/xen-gfx.hg</a></p>
<p>His work was inspired by his own &#8216;NomadBIOS&#8217; for L4  microkernel, which also uses this approach of self-migration.</p>
<p>It might be that this new alternative to managed migration will  be adopted in future versions of Xen (time will tell).</p>
<p>Migration of operating systems has much in common with  migration of single processes. see Master&#8217;s thesis: &#8220;Nomadic Operating Systems&#8221;  Jacob G. Hansen , Asger kahl Henriksen,2002 <a href="http://nomadbios.sunsite.dk/NomadicOS.ps">http://nomadbios.sunsite.dk/NomadicOS.ps</a></p>
<p>You can find there a discussion about migration of single  processes in Mosix (Barak and La&#8217;adan).</p>
<h3 id="head-8954d739f295a3245b7169929a5230b462260437">Creating of a domain &#8211;  behind the scenes:</h3>
<p>We create a domain by:</p>
<pre>xm create configFile -c
</pre>
<p>A simple config file may look like (using ttylinux,as in the  user manual):</p>
<pre>kernel = "/boot/vmlinuz-2.6.12-xenU"
memory = 64
name = "ttylinux"
nics = 1
ip = "10.0.0.3"
disk = ['file:/home/work/downloads/tmp/ttylinux-xen,hda3,w']
root = "/dev/hda3 ro"
</pre>
<p>The create() method of <a href="/xenwiki/XendDomainInfo">XendDomainInfo</a> handles creation of domains.  When a domain is created it is assigned a unique id (uuid ) which is cretaed  using uuidgen command line utility of e2fsprogs.(<em>file  python/xen/xend/uuid.py</em>).</p>
<p>If the memory paramter specified a too high memory which the  hypervisor cannot allocate, we end up with the following message: &#8220;Error: Error  creating domain: The privileged domain did not balloon!&#8221;</p>
<p>The devices of a domain are created using the createDevice()  method which delegates the call to the createDevice() method of the Device  Controller (see <a href="/xenwiki/XendDomainInfo">XendDomainInfo</a>.py) The createDevice() in turn  calls writeDetails() method (also in <a href="/xenwiki/DevController">DevController</a>). This writeDetails() method  write the details in <a href="/xenwiki/XenStore">XenStore</a> to trigger the  creation of the device. The getDeviceDetails() is an abstract method which each  subclass of <a href="/xenwiki/DevController">DevController</a> implements. Writing to the store is done by calling Write() method of  xstransact. (<em>file tools/pyhton/xen/xend/xenstore/xstransact.py</em>) which  returns the id of the newly created device.</p>
<p>By using transaction you can batch together some actions to  perform against the xenstored (the common use is some read actions). You can  create a domain also without Xend and without Python bindings; Jacob Gorm Hansen  had demonstrated it in 2 little programs (businit.c and buscrate.c) (see <a href="http://lists.xensource.com/archives/html/xen-devel/2005-10/msg00432.html">http://lists.xensource.com/archives/html/xen-devel/2005-10/msg00432.html</a>).</p>
<p>However, true to now these programs should be adjusted beacuse  there were some API changes, especially that creation of interdomain event  channel is done now with sending ioctl to event_channel  (IOCTL_EVTCHN_BIND_INTERDOMAIN).</p>
<h3 id="head-ffc96b3ced09e70a8bcb5b0831d577e0892d96f6">HyperCalls Mapping to code  Xen 3.0.2</h3>
<p>Mapping of <a href="/xenwiki/HyperCalls">HyperCalls</a> to code :</p>
<p>Follwoing is the location of all hypercalls: The <a href="/xenwiki/HyperCalls">HyperCalls</a> appear according to  their order in xen.h.</p>
<p>The hypercall table itself is in  <em>xen/arch/x86/x86_32/entry.S</em> (ENTRY(hypercall_table)).</p>
<p><strong>HYPERVISOR_set_trap_table</strong> =&gt;  do_set_trap_table() (<em>file xen/arch/x86/traps.c</em>)</p>
<p><strong>HYPERVISOR_mmu_update</strong> =&gt; do_mmu_update()  (<em>file xen/arch/x86/mm.c</em>)</p>
<p><strong>HYPERVISOR_set_gdt</strong> =&gt; do_set_gdt()  (<em>file xen/arch/x86/mm.c</em>)</p>
<p><strong>HYPERVISOR_stack_switch</strong> =&gt;  do_stack_switch() (<em>file xen/arch/x86/x86_32/mm.c</em>)</p>
<p><strong>HYPERVISOR_set_callbacks</strong> =&gt;  do_set_callbacks() (<em>file xen/arch/x86/x86_32/traps.c</em>)</p>
<p><strong>HYPERVISOR_fpu_taskswitch</strong> =&gt;  do_fpu_taskswitch(int set) (<em>file xen/arch/x86/traps.c</em>)</p>
<p><strong>HYPERVISOR_sched_op_compat</strong> =&gt;  do_sched_op_compat() (<em>file xen/common/schedule.c</em>)</p>
<p><strong>HYPERVISOR_dom0_op</strong> =&gt; do_dom0_op()  (<em>file xen/common/dom0_ops.c</em>)</p>
<p><strong>HYPERVISOR_set_debugreg</strong> =&gt;  do_set_debugreg() (<em>file xen/arch/x86/traps.c</em>)</p>
<p><strong>HYPERVISOR_get_debugreg</strong> =&gt;  do_get_debugreg() (<em>file xen/arch/x86/traps.c</em>)</p>
<p><strong>HYPERVISOR_update_descriptor</strong> =&gt;  do_update_descriptor() (<em>file xen/arch/x86/mm.c</em>)</p>
<p><strong>HYPERVISOR_memory_op</strong> =&gt; do_memory_op()  (<em>file xen/common/memory.c</em>)</p>
<p><strong>HYPERVISOR_multicall</strong> =&gt; do_multicall()  (<em>file xen/common/multicall.c</em>)</p>
<p><strong>HYPERVISOR_update_va_mapping</strong> =&gt;  do_update_va_mapping() (<em>file /xen/arch/x86/mm.c</em>)</p>
<p><strong>HYPERVISOR_set_timer_op</strong> =&gt;  do_set_timer_op() (<em>file xen/common/schedule.c</em>)</p>
<p><strong>HYPERVISOR_event_channel_op</strong> =&gt;  do_event_channel_op() (<em>file xen/common/event_channel.c</em>)</p>
<p><strong>HYPERVISOR_xen_version</strong> =&gt; do_xen_version()  (<em>file xen/common/kernel.c</em>)</p>
<p><strong>HYPERVISOR_console_io</strong> =&gt; do_console_io()  (<em>file xen/drivers/char/console.c</em>)</p>
<p><strong>HYPERVISOR_physdev_op</strong> =&gt; do_physdev_op()  (<em>file xen/arch/x86/physdev.c</em>)</p>
<p><strong>HYPERVISOR_grant_table_op</strong> =&gt;  do_grant_table_op() (<em>file xen/common/grant_table.c</em>)</p>
<p><strong>HYPERVISOR_vm_assist</strong> =&gt; do_vm_assist()  (<em>file xen/common/kernel.c</em>)</p>
<p><strong>HYPERVISOR_update_va_mapping_otherdomain</strong> =&gt;</p>
<ul>
<li>do_update_va_mapping_otherdomain() (<em>file  xen/arch/x86/mm.c</em>)</li>
</ul>
<p><strong>HYPERVISOR_iret</strong> =&gt; do_iret() (<em>file  xen/arch/x86/x86_32/traps.c</em>) /* x86/32 only */</p>
<p><strong>HYPERVISOR_vcpu_op</strong> =&gt; do_vcpu_op()  (<em>file xen/common/domain.c</em>)</p>
<p><strong>HYPERVISOR_set_segment_base</strong> =&gt;  do_set_segment_base (<em>file xen/arch/x86/x86_64/mm.c</em>) /* x86/64 only */</p>
<p><strong>HYPERVISOR_mmuext_op</strong> =&gt; do_mmuext_op()  (<em>file xen/arch/x86/mm.c</em>)</p>
<p><strong>HYPERVISOR_acm_op</strong> =&gt; do_acm_op() (<em>file  xen/common/acm_ops.c</em>)</p>
<p><strong>HYPERVISOR_nmi_op</strong> =&gt; do_nmi_op() (<em>file  xen/common/kernel.c</em>)</p>
<p><strong>HYPERVISOR_sched_op</strong> =&gt; do_sched_op()  (<em>file xen/common/schedule.c</em>)</p>
<p>(Note: sometimes hypercalls are also called hcalls.)</p>
<h3 id="head-701c95eb311d0a6cc50e8383d4286257b99da7c8">Virtualization and the  Linux Kernel</h3>
<ul>
<li><em>Would PhD virtualization be when several people get a PhD  but only one is doing the work? :</em>
<ul>
<li><em><a href="/xenwiki/JoshTriplett">JoshTriplett</a> on Xen IRC (<a href="http://www.linode.com/xen/irc/logs/xen.log-2005-08-22">http://www.linode.com/xen/irc/logs/xen.log-2005-08-22</a>)</em></li>
</ul>
</li>
</ul>
<p><strong>Virtualization</strong> in computer context can be  thought of as extending the abilities of a computer beyond what a straight,  non-virtual implelmentation allows.</p>
<p>In this category we can include also virtual memory, which  allows a process to access 4GB virtual address space even though the physical  RAM is usually much lower.</p>
<p>We can also think of the Linux IP Virtual Server (which is now  a part of the linux kernel) as a kind of virtualization. By using the Linux IP  Virtual Server you can configure a router to redirect service requests from a  virtual server address to other machines (called real servers).</p>
<p>The IP Virtual Server is part of the kernel starting 2.6.10 (In  the 2.4.* kernels it is also available as a patch; the code for 2.6.10 and above  kernels is under net/ipv4/ipvs under the kernel tree ;there is still no  implementation for ipv6).</p>
<p>The Linux Virtual Server (LVS) was started quite a time ago,in  1998; see <a href="http://www.linuxvirtualserver.org/">http://www.linuxvirtualserver.org</a>.</p>
<p>The idea of <strong>virtualization</strong> in the sense of  enabling of running more than one operating system on a single platform is not  new and was researched for many years. However, it seems that the Xen project is  the first which produces performance benchmark metrics of such a feature which  make this idea more practical and more attractive.</p>
<p>Origins of the Xen project: The Xen project is based on the  Xenoservers project; It was originally built as part of the <a href="/xenwiki/XenoServer">XenoServer</a> project, see <a href="http://www.cl.cam.ac.uk/Research/SRG/netos/xeno">http://www.cl.cam.ac.uk/Research/SRG/netos/xeno</a>.</p>
<p>Also the arsenic project has some ideas which were used in Xen.  (see <a href="http://www.cl.cam.ac.uk/Research/SRG/netos/arsenic">http://www.cl.cam.ac.uk/Research/SRG/netos/arsenic</a>)</p>
<p>In the arsenic project, written by Ian Pratt and Keir Fraser, a  big part of the Linux kernel TCP/IP stack was ported to user space. The arsenic  project is based on Linux 2.3.29. After a short look at the Arsenic porject code  you can find some data structures which can remind of parallel data structures  in Xen, like the event rings. (for exmaple,the ring_control_block struct in  arsenic-1.0/acenic-fw-12.3.10/nic/common/nic_api.h)</p>
<p>Meiosys is a French Company which was purchased by IBM. It  deals with another different type of virtualization &#8211; Application  Virtualization.</p>
<p>see <a href="http://www.virtual-strategy.com/article/articleview/680/1/2/">http://www.virtual-strategy.com/article/articleview/680/1/2/</a> and <a href="http://www.infoworld.com/article/05/06/23/HNibmbuy_1.html">http://www.infoworld.com/article/05/06/23/HNibmbuy_1.html</a></p>
<p>In context of the Meiosys project, it is worth to mention that  a patch was sent recently to the Linux Kernel Mailing List from Serge E. Hallyn  (IBM): see <a href="http://lwn.net/Articles/160015">http://lwn.net/Articles/160015</a></p>
<p>This patch deals with process IDs. (the pid should stay the  same after starting anew the application in Meiosys).</p>
<p>Another article on PID virtualization can be found in &#8220;PID  virtualization: a wealth of choices&#8221; <a href="http://lwn.net/Articles/171017/?format=printable">http://lwn.net/Articles/171017/?format=printable</a> This article deals with PID virtualization in a context of a diffenet project  (openVZ).</p>
<p>There is also the colinux open source project (see:<a href="http://colinux.sourceforge.net/">http://colinux.sourceforge.net</a> for  more details) and the openvz project, which is based on Virtuozzo™. (Virtuozzo  is a commercial solution).</p>
<p>The openvz offers server virtualization, linux-based solution:  see <a href="http://openvz.org/">http://openvz.org</a>.</p>
<p>There are other projects which probably ispire virtualization;  to name of few:</p>
<p>Denali Project uses (uses paravirtualization). <a href="http://denali.cs.washington.edu/">http://denali.cs.washington.edu</a></p>
<p>A paper: Denali: Lightweight Virtual Machines for Distributed  and Networked Applications By Andrew Whitaker et al. <a href="http://denali.cs.washington.edu/pubs/distpubs/papers/denali_usenix2002.pdf">http://denali.cs.washington.edu/pubs/distpubs/papers/denali_usenix2002.pdf</a></p>
<p>Nemesis Operating System. <a href="http://www.cl.cam.ac.uk/Research/SRG/netos/old-projects/nemesis/index.html">http://www.cl.cam.ac.uk/Research/SRG/netos/old-projects/nemesis/index.html</a></p>
<p>Exokernel: see &#8220;Application Performance and Flexibility on  Exokernel Systems&#8221; by M. Frans Kaashoek et al <a href="http://www.cl.cam.ac.uk/%7Esmh22/docs/kaashoek97application.ps.gz">http://www.cl.cam.ac.uk/~smh22/docs/kaashoek97application.ps.gz</a></p>
<p>TBD: more details.</p>
<h3 id="head-aaf6e59ef45692cc4ad84e85656f0eb037d3c01e">Pre-Virtualization</h3>
<p>Another interesting virtulaization technique is  Pre-Virtualization; in this method, we rewite sensitive instructions using the  assembler files (whether generated by compiler, as is the usual case, or  assembler files created manually). There is a problem in this method because  there are instuctions which are sensitive only when they are performed in a  certain context. A solution for this is to generate profiling data of a guest OS  and then recompile the OS using the profiling data.</p>
<p>See:</p>
<p><a href="http://l4ka.org/projects/virtualization/afterburn/">http://l4ka.org/projects/virtualization/afterburn/</a></p>
<p>and an article: Pre-Virtualization: Slashing the Cost of  Virtualization Joshua <a href="/xenwiki/LeVasseur">LeVasseur</a>, Volkmar Uhlig, Matthew Chapman et al.  <a href="http://l4ka.org/publications/2005/previrtualization-techreport.pdf">http://l4ka.org/publications/2005/previrtualization-techreport.pdf</a></p>
<p>This technique is based on a paper by Hideki Eiraku and Yasushi  Shinjo, &#8220;Running BSD Kernels as User Processes by Partial Emulation and  Rewriting of Machine Instructions&#8221; <a href="http://www.usenix.org/publications/library/proceedings/bsdcon03/tech/eiraku/eiraku_html/index.html">http://www.usenix.org/publications/library/proceedings/bsdcon03/tech/eiraku/eiraku_html/index.html</a></p>
<h3 id="head-1d44953614faab381fd32b0e8c63f0feb98f1d45">Xen Storage</h3>
<p>You can use iscsi for Xen Storage. The xen-tools package of <a href="/xenwiki/OpenSuse">OpenSuse</a> has an example of using  iscsi, called xmexample.iscsi. The disk entry for iscsi in the configuration  file may look like: disk = [  'iscsi:iqn.2006-09.de.suse@0ac47ee2-216e-452a-a341-a12624cd0225,hda,w' ]</p>
<p>TBD: more on iSCSI in Xen.</p>
<p>Solutions for using CoW in Xen: blktap (part of the xen  project).</p>
<p>UnionFS: a stackable filesystem (used also in Knoppix Live-CD  and other Live-CDs)</p>
<p>dm-userspace (A tool which uses device-mapper and a daemon  called cowd; written by Dan Smith) You may download dm-userspace by:</p>
<ul>
<li>hg clone <a href="http://static.danplanet.com/hg/dm-userspace.ring">http://static.danplanet.com/hg/dm-userspace.ring</a></li>
</ul>
<p>To build as a module out-of-tree, copy dm-userspace.h to:  /lib/modules/<tt>uname -r</tt>/build/include/linux and then run  &#8220;make&#8221;.</p>
<p>Home of dm-userspace:</p>
<ul>
<li><a href="http://static.danplanet.com/dm-userspace/">http://static.danplanet.com/dm-userspace/</a></li>
</ul>
<p>Copy-on-write NFS server: see <a href="http://www.russross.com/CoWNFS.html">http://www.russross.com/CoWNFS.html</a></p>
<h3 id="head-5c45f5442fc5700fa30e6e295f5d38c5dbb9d2c6">kvm &#8211; Kernel-based  Virtualization Driver</h3>
<p>Kvm is as an open source virtualization project , written by  Avi Kivity and Yaniv Kamay from qumranet. See : <a href="http://kvm.sourceforge.net/">http://kvm.sourceforge.net</a>.</p>
<p>It is included in the linux kerel tree since 2.6.20-rc1; see:  <a href="http://lkml.org/lkml/2006/12/13/361">http://lkml.org/lkml/2006/12/13/361</a> (&#8220;kvm driver for all those crazy virtualization people to play with&#8221;)</p>
<p>Currently it deals with Intel processors with the virtual  extension (VT-X). and AMD SVM processors. You can know if your processor has  these extensions by issuing from the command line: &#8220;egrep &#8216;^flags.*(vmx|svm)&#8217;  /proc/cpuinfo&#8221;</p>
<p>kvm.ko is a kernel module which handles userspace requests  through ioctls. It works with a character device (/dev/kvm). The userspace part  is built from patched quemu. One of KVM advantages is that it uses linux kernel  mechanisms as they are without change (such as the linux scheduler). The Xen  project, for example, made many changes to parts of the kernel to enable  para-virtualization. Another advantage is the simplicty of the project: there is  a kernel part and a userspace part. An advantage of KVM is that future versions  of linux kernel will not entail changes in the kvm module code (and of course  not in the user space part). The project currently support SMP hosts and will  support SMP guests in the future.</p>
<p>Currently there is no support to live migration in KVM (but  there is support for ordinary migration, when the migrated OS is stopped and  than transfrerred to the target and than resumed).</p>
<p>In intel vt-x , VM-Exits are handled by the kvm module by  kvm_handle_exit() method in kvm_main.c according to the reason which caused them  (and which is specified and read from the VMCS). in AMD SVM , exit are handled  by handle_exit() in svm.c.</p>
<p>There is an interesting usage of memory slots . There is  already an rpm for openSUSE by Gerd Hoffman.</p>
<h3 id="head-4a9b7d3bea01ee522a0e4e8caa02e1332503f1af">Tip: How to build Xen with  your own tar ball</h3>
<p>If you want to run &#8220;make world&#8221; without downloading the kernel  (beacuse that you want to to your own tar ball which is a bit different from the  original one because you made few changes inside the kernel), then do the  following:</p>
<p>1) Let&#8217;s say that the kernel tar ball is named:  my_linux-2.6.18.tar.bz2.</p>
<ul>
<li>First, move my_linux-2.6.18.tar.bz2 to the  folder from where you build Xen</li>
</ul>
<p>2) Run from bash: XEN_LINUX_SOURCE=tarball make world</p>
<p>That&#8217;s it; it will use the my_linux-2.6.18.tar.bz2. tar ball  that you copied to that folder.</p>
<h3 id="head-48cbb68fc6d8bf1f3434b03630923ef1a02c046c">Xen in the Linux  Kernel</h3>
<p>According to the following thread from xen-devel: <a href="http://lists.xensource.com/archives/html/xen-devel/2005-10/msg00436.html">http://lists.xensource.com/archives/html/xen-devel/2005-10/msg00436.html</a>,  there is a mercurial repository in which xen is a subarch of i386 and x86_64 of  the linux kernel, and there is an intention to send releavant stuff to  Andrew/Linus for the upcoming 2.6.15 kernel. In 22/3/2006 , a patchest of 35  parts was sent to the Linux Kernel Mailing List (lkml) for Xen i386  paravirtualization support in the linux kernel: see <a href="http://www.ussg.iu.edu/hypermail/linux/kernel/0603.2/2313.html">http://www.ussg.iu.edu/hypermail/linux/kernel/0603.2/2313.html</a></p>
<h3 id="head-4b3de967c546a9ad9fd12f7402b8163946940743">VMI : Virtual Machine  Interface</h3>
<p>On 13/3/06 , a patchset titled &#8220;VMI i386 Linux virtualization  interface proposal&#8221; was sent to the LKML (Linux Kernel Mailing List) by Zachary  Amsden and othes. (see <a href="http://lkml.org/lkml/2006/3/13/140">http://lkml.org/lkml/2006/3/13/140</a>)  It suggests for a common interfcace which abstracts the specifics of each  hypervisor and thus can be used by many hypervisors. According to the  vmi_spec.txt of this patchset, when an OS is ported to a paravirtulizable x86  processor, it should access the hypervisor through the VMI layer.</p>
<p><strong>The VMI layer interface:</strong></p>
<p>The VMI is divided to the following 10 types of calls:</p>
<p><strong>CORE INTERFACE CALLS</strong> (like VMI_Init)</p>
<p><strong>PROCESSOR STATE CALLS</strong> (like VMI_<a href="/xenwiki/DisableInterrupts">DisableInterrupts</a>,  VMI_<a href="/xenwiki/EnableInterrupts">EnableInterrupts</a>,VMI_<a href="/xenwiki/GetInterruptMask">GetInterruptMask</a>)</p>
<p><strong>DESCRIPTOR RELATED CALLS</strong> (like  VMI_SetGDT,VMI_SetIDT)</p>
<p><strong>CPU CONTROL CALLS</strong> (like VMI_WRMSR,VMI_RDMSR)</p>
<p><strong>PROCESSOR INFORMATION CALLS</strong> (like VMI_CPUID)</p>
<p><strong>STACK/PRIVILEGE TRANSITION CALLS</strong> (like VMI_<a href="/xenwiki/UpdateKernelStack">UpdateKernelStack</a>,VMI_IRET)</p>
<p><strong>I/O CALLS</strong> (like VMI_INB,VMI_INW,VMI_INL)</p>
<p><strong>APIC CALLS</strong> (like VMI_APICWrite,VMI_APICRead)</p>
<p><strong>TIMER CALLS</strong> (VMI_<a href="/xenwiki/GetWallclockTime">GetWallclockTime</a>)</p>
<p><strong>MMU CALLS</strong> (like VMI_<a href="/xenwiki/SetLinearMapping">SetLinearMapping</a>)</p>
<h3 id="head-577cd69714b5d24297748902ae758fda4b7b9594">Links</h3>
<p>1) Xen Project <a href="/xenwiki/HomePage">HomePage</a> <a href="http://www.cl.cam.ac.uk/Research/SRG/netos/xen">http://www.cl.cam.ac.uk/Research/SRG/netos/xen</a></p>
<p>2) Xen Mailing Lists Pge: <a href="http://lists.xensource.com/">http://lists.xensource.com</a></p>
<p>(don&#8217;t forget to read the <a href="/xenwiki/XenUsersNetiquette">XenUsersNetiquette</a> before posting on the  lists)</p>
<p>3) Atricle : Analysis of the Intel Pentium&#8217;s Ability to Support  a Secure Virtual Machine Monitor <a href="http://www.usenix.org/publications/library/proceedings/sec2000/full_papers/robin/robin_html/index.html">http://www.usenix.org/publications/library/proceedings/sec2000/full_papers/robin/robin_html/index.html</a></p>
<p>4) Xen Summits: 2005: <a href="http://xen.xensource.com/xensummit/xensummit_2005.html">http://xen.xensource.com/xensummit/xensummit_2005.html</a> 2006 fall: <a href="http://xen.xensource.com/xensummit/xensummit_fall_2006.html">http://xen.xensource.com/xensummit/xensummit_fall_2006.html</a> 2006 winter: <a href="http://xen.xensource.com/xensummit/xensummit_winter_2006.html">http://xen.xensource.com/xensummit/xensummit_winter_2006.html</a> 2007 spring: <a href="http://xen.xensource.com/xensummit/xensummit_spring_2007.html">http://xen.xensource.com/xensummit/xensummit_spring_2007.html</a></p>
<p>5) Intel Virtualizatiuon technology: <a href="http://www.intel.com/technology/virtualization/index.htm">http://www.intel.com/technology/virtualization/index.htm</a></p>
<p>6) Article by Ryan Maueron Linux Journal in 2 parts:</p>
<p>6-1) Xen Virtualization and Linux Clustering, Part 1 <a href="http://www.linuxjournal.com/article/8812">http://www.linuxjournal.com/article/8812</a></p>
<p>6-2) Xen Virtualization and Linux Clustering, Part 2 <a href="http://www.linuxjournal.com/article/8816">http://www.linuxjournal.com/article/8816</a></p>
<p><strong>Commercial Companies:</strong> 7)<a href="/xenwiki/XenSource">XenSource</a>:</p>
<p><a href="http://www.xensource.com/">http://www.xensource.com/</a></p>
<p> <img src='http://s2.wp.com/wp-includes/images/smilies/icon_cool.gif' alt='8)' class='wp-smiley' /> Enomalism: <a href="http://www.enomalism.com/">http://www.enomalism.com/</a></p>
<p>9) Thoughtcrime is a brand new company specialising in  opensource virtualisation solutions see <a href="http://debian.thoughtcrime.co.nz/ubuntu/README.txt">http://debian.thoughtcrime.co.nz/ubuntu/README.txt</a></p>
<p><strong>IA64:</strong></p>
<p>10)IA64 Master Thesis HPC Virtualization with Xen on Itanium by  Havard K. F. Bjerke <a href="http://openlab-mu-internal.web.cern.ch/openlab-mu-internal/Documents/2_Technical_Documents/Master_thesis/Thesis_HarvardBjerke.pdf">http://openlab-mu-internal.web.cern.ch/openlab%2Dmu%2Dinternal/Documents/2_Technical_Documents/Master_thesis/Thesis_HarvardBjerke.pdf</a></p>
<p>11) vBlades: Optimized Paravirtualization for the Itanium  Processor Family Daniel J. Magenheimer and Thomas W. Christian <a href="http://www.usenix.org/publications/library/proceedings/vm04/tech/full_papers/magenheimer/magenheimer_html/index.html">http://www.usenix.org/publications/library/proceedings/vm04/tech/full_papers/magenheimer/magenheimer_html/index.html</a></p>
<p>12) Now and Xen Feature Story Article Written by Andrew  Warfield and Keir Fraser <a href="http://www.linux-mag.com/2004-10/xen_01.html">http://www.linux-mag.com/2004-10/xen_01.html</a></p>
<p>13) Self Migration: <a href="http://www.diku.dk/%7Ejacobg/self-migration">http://www.diku.dk/~jacobg/self-migration</a></p>
<p>14) online magazine: <a href="http://www.virtual-strategy.com/">http://www.virtual-strategy.com</a></p>
<p>15) Denali Project <a href="http://denali.cs.washington.edu/">http://denali.cs.washington.edu</a></p>
<p>general links about virtualization:</p>
<p>16) <a href="http://www.virtualization.info/">http://www.virtualization.info</a></p>
<p>17) <a href="http://www.kernelthread.com/publications/virtualization">http://www.kernelthread.com/publications/virtualization</a></p>
<p>18) A Survey on Virtualization Technologies Susanta Nanda  Tzi-cker Chiueh <a href="http://www.ecsl.cs.sunysb.edu/tr/TR179.pdf">http://www.ecsl.cs.sunysb.edu/tr/TR179.pdf</a></p>
<p><strong>AMD:</strong></p>
<p>19) AMD I/O virtualization technology (IOMMU) specification Rev  1.00 &#8211; February 03, 2006 <a href="http://www.amd.com/us-en/assets/content_type/white_papers_and_tech_docs/34434.pdf">http://www.amd.com/us-en/assets/content_type/white_papers_and_tech_docs/34434.pdf</a></p>
<p>20) AMD64 Architecture Programmer&#8217;s Manual: Vol 2 System  Programming : Revision 3.11 added chapter 15 on virtualization (&#8220;Secure Virtual  Machine&#8221;).(december 2005) <a href="http://www.amd.com/us-en/assets/content_type/white_papers_and_tech_docs/24593.pdf">http://www.amd.com/us-en/assets/content_type/white_papers_and_tech_docs/24593.pdf</a></p>
<p>21) AMD64 Architecture Programmer&#8217;s Manual: Vol 3:  General-Purpose and System Instructions Revision 3.11 added SVM instructions  (december 2005) <a href="http://www.amd.com/us-en/assets/content_type/white_papers_and_tech_docs/24594.pdf">http://www.amd.com/us-en/assets/content_type/white_papers_and_tech_docs/24594.pdf</a></p>
<p>22) AMD virtualization on the Xen Summit: <a href="http://www.xensource.com/files/xs0106_amd_virtualization.pdf">http://www.xensource.com/files/xs0106_amd_virtualization.pdf</a></p>
<p>23) AMD Press Release: SUNNYVALE, CALIF. &#8212; May 23, 2006:  availability of AMD processors with virtualization extensions: <a href="http://www.amd.com/us-en/Corporate/VirtualPressRoom/0">http://www.amd.com/us-en/Corporate/VirtualPressRoom/0</a>,,51_104_543~108605,00.html</p>
<p><strong>Open Solaris:</strong></p>
<p>24) Open Solaris Xen Forum: <a href="http://www.opensolaris.org/jive/category.jspa?categoryID=32">http://www.opensolaris.org/jive/category.jspa?categoryID=32</a></p>
<p>25) Update to opensolaris Xen: adding <a href="/xenwiki/OpenSolaris">OpenSolaris</a>-based dom0 capabilities, as well as  32-bit and 64-bit MP guest. 14/07/2006 <a href="http://www.opensolaris.org/os/community/xen/announcements/?monthYear=July+2006">http://www.opensolaris.org/os/community/xen/announcements/?monthYear=July+2006</a></p>
<p>26) Open Sparc Hypervisor Spec: <a href="http://opensparc.sunsource.net/nonav/Hypervisor_api-26-v6.pdf">http://opensparc.sunsource.net/nonav/Hypervisor_api-26-v6.pdf</a></p>
<p>27) Open Sparc T1 page: <a href="http://opensparc.sunsource.net/nonav/opensparct1.html">http://opensparc.sunsource.net/nonav/opensparct1.html</a> extension to the Solaris Zones: <a href="http://opensolaris.org/os/community/brandz">http://opensolaris.org/os/community/brandz</a></p>
<p>28) OSDL Development Wiki Homepage (Virtualization) <a href="http://www.osdl.org/cgi-bin/osdl_development_wiki.pl?Virtualization">http://www.osdl.org/cgi-bin/osdl_development_wiki.pl?Virtualization</a></p>
<p>29) fedora xen mailing list archive: <a href="https://www.redhat.com/archives/fedora-xen">https://www.redhat.com/archives/fedora-xen</a></p>
<p>30) Xen Quick Start for FC4 (Fedora Core 4). <a href="http://www.fedoraproject.org/wiki/FedoraXenQuickstart?highlight=%28xen%29">http://www.fedoraproject.org/wiki/FedoraXenQuickstart?highlight=%28xen%29</a></p>
<p>31) Xen Quick Start for FC5 (Fedora Core 5): <a href="http://www.fedoraproject.org/wiki/FedoraXenQuickstartFC5">http://www.fedoraproject.org/wiki/FedoraXenQuickstartFC5</a></p>
<p>32) Xen Quick Start for FC6 (Fedora Core 6): <a href="http://fedoraproject.org/wiki/FedoraXenQuickstartFC6">http://fedoraproject.org/wiki/FedoraXenQuickstartFC6</a></p>
<p>Fedora 7 quick start: <a href="http://fedoraproject.org/wiki/Docs/Fedora7VirtQuickStart">http://fedoraproject.org/wiki/Docs/Fedora7VirtQuickStart</a> Fedora 8 quick start: <a href="http://fedoraproject.org/wiki/Docs/Fedora8VirtQuickStart">http://fedoraproject.org/wiki/Docs/Fedora8VirtQuickStart</a></p>
<p>33) The Xen repository is handled by the mercurial version  system. mercurial download: <a href="http://www.selenic.com/mercurial/release">http://www.selenic.com/mercurial/release</a></p>
<p>34) Measuring CPU Overhead for I/O Processing in the Xen  Virtual Machine Monitor Cherkasova Ludmila and Gardner, Rob <a onclick="return mugicPopWin(this,event);" oncontextmenu="mugicRightClick(this);" href="http://www.hpl.hp.com/techreports/2005/HPL-2005-62.html">http://www.hpl.hp.com/techreports/2005/HPL-2005-62.html</a></p>
<p>35) <a href="/xenwiki/XenMon">XenMon</a>: QoS  Monitoring and Performance Profiling Tool Gupta Diwaker and Gardner Rob;  Cherkasova, Ludmila <a onclick="return mugicPopWin(this,event);" oncontextmenu="mugicRightClick(this);" href="http://www.hpl.hp.com/techreports/2005/HPL-2005-187.html">http://www.hpl.hp.com/techreports/2005/HPL-2005-187.html</a></p>
<p>36) Potemkin VMM: A virtual machine based on xen-unstable ;  used in a honeypot By Michael Vrable, Justin Ma, Jay Chen, David Moore, Erik  Vandekieft, Alex C. Snoeren, Geoffrey M. Voelker, and Stefan Savage. <a href="http://www.cs.ucsd.edu/%7Esavage/papers/Sosp05.pdf">http://www.cs.ucsd.edu/~savage/papers/Sosp05.pdf</a></p>
<p>37) Memory Resource Management in VMware ESX Server <a href="http://www.usenix.org/events/osdi02/tech/waldspurger.html">http://www.usenix.org/events/osdi02/tech/waldspurger.html</a></p>
<p><strong>books:</strong></p>
<p>38) Virtualization: From the Desktop to the Enterprise By Erick  M. Halter , Chris Wolf Published: May 2005 <a href="http://www.apress.com/book/bookDisplay.html?bID=449">http://www.apress.com/book/bookDisplay.html?bID=449</a></p>
<p>39) Virtualization with VMware ESX Server Publisher: Syngress;  2005 by Al Muller, Seburn Wilson, Don Happe, Gary J. Humphrey <a href="http://www.syngress.com/catalog/?pid=3315">http://www.syngress.com/catalog/?pid=3315</a></p>
<p>40) VMware ESX Server: Advanced Technical Design Guide by Ron  Oglesby, Scott Herold <a onclick="return mugicPopWin(this,event);" oncontextmenu="mugicRightClick(this);" href="http://www.amazon.com/exec/obidos/ASIN/0971151067/virtualizatio-20/002-5634453-4543251?creative=327641&amp;camp=14573&amp;link_code=as1">http://www.amazon.com/exec/obidos/ASIN/0971151067/virtualizatio-20/002-5634453-4543251?creative=327641&amp;camp=14573&amp;link_code=as1</a></p>
<p>41) <strong>PPC:</strong> Hollis Blanchard, IBM Linux  Technology Center Jimi Xenidis, IBM Research <a href="http://wiki.xensource.com/xenwiki/Xen/PPC">http://wiki.xensource.com/xenwiki/Xen/PPC</a></p>
<p>42) <a href="http://about-virtualization.com/mambo">http://about-virtualization.com/mambo</a></p>
<p>43) PID virtualization: a wealth of choices <a href="http://lwn.net/Articles/171017/?format=printable">http://lwn.net/Articles/171017/?format=printable</a></p>
<p>44) The Xen Hypervisor and its IO Subsystem: <a href="http://www.mulix.org/lectures/xen-iommu/xen-io.pdf">http://www.mulix.org/lectures/xen-iommu/xen-io.pdf</a></p>
<p>45) G. J. Popek and R. P. Goldberg, Formal requirements for  virtualizable third generation architectures, Commun. ACM, vol. 17, no. 7, pp.  412 421, 1974. <a href="http://www.cis.upenn.edu/%7Ecis700-6/04f/papers/popek-goldberg-requirements.pdf">http://www.cis.upenn.edu/~cis700-6/04f/papers/popek-goldberg-requirements.pdf</a></p>
<p>46) &#8220;Running multiple operating systems concurrently on an IA32  PC using virtualization techniques&#8221; by Kevin Lawton (1999). <a href="http://www.floobydust.com/virtualization/lawton_1999.txt">http://www.floobydust.com/virtualization/lawton_1999.txt</a></p>
<p>47) Automating Xen Virtual Machine Deployment (talks about  integrating <a href="/xenwiki/SystemImager">SystemImager</a> with Xen and more) by Kris Buytaert <a href="http://howto.x-tend.be/AutomatingVirtualMachineDeployment/">http://howto.x-tend.be/AutomatingVirtualMachineDeployment/</a></p>
<p>48)Virtualizing servers with Xen Evaldo Gardenali VI  International Conference of Unix at UNINET <a href="http://umeet.uninet.edu/umeet2005/talks/evaldoa/xen.pdf">http://umeet.uninet.edu/umeet2005/talks/evaldoa/xen.pdf</a></p>
<p>49)Survey of System Virtualization Techniques Robert Rose March  8, 2004 <a href="http://www.robertwrose.com/vita/rose-virtualization.pdf">http://www.robertwrose.com/vita/rose-virtualization.pdf</a></p>
<p><strong>NetBSD</strong></p>
<p>50)<a href="http://www.netbsd.org/Ports/xen/">http://www.netbsd.org/Ports/xen/</a></p>
<p>51)Interview on Xen with NetBSD develope Manuel Bouyer <a href="http://ezine.daemonnews.org/200602/xen.html">http://ezine.daemonnews.org/200602/xen.html</a></p>
<p>52) netbsd xen mailing list: <a href="http://www.netbsd.org/MailingLists/#port-xen">http://www.netbsd.org/MailingLists/#port-xen</a></p>
<p>53) NetBSD/xen Howto <a href="http://www.netbsd.org/Ports/xen/howto.html">http://www.netbsd.org/Ports/xen/howto.html</a></p>
<p>54) &#8220;C&#8221; API for Xen (LGPL) By Daniel Veillard and others</p>
<p><a href="http://libvir.org/">http://libvir.org/</a></p>
<p>55) Fraser Campbell page: <a href="http://goxen.org/">http://goxen.org/</a></p>
<p>56) Another page from Fraser Campbell : <a href="http://linuxvirtualization.com/">http://linuxvirtualization.com/</a></p>
<p>57) Virtualization blog</p>
<ul>
<li><a href="http://vmblog.com/">http://vmblog.com</a></li>
</ul>
<p>58)Hardware emulation with QEMU (article)</p>
<ul>
<li><a href="http://www.linux.com/article.pl?sid=05/10/24/1845248">http://www.linux.com/article.pl?sid=05/10/24/1845248</a></li>
</ul>
<p>59) <a href="http://linuxemu.retrofaction.com/">http://linuxemu.retrofaction.com</a></p>
<p>60) Linux Virtualization with Xen <a href="http://www.linuxdevcenter.com/pub/a/linux/2006/01/26/xen.html">http://www.linuxdevcenter.com/pub/a/linux/2006/01/26/xen.html</a></p>
<p>61) The virtues of Xen by Alex Maier <a href="http://www.redhat.com/magazine/014dec05/features/xen/">http://www.redhat.com/magazine/014dec05/features/xen/</a></p>
<p>62) Deploying <a href="/xenwiki/VirtualMachines">VirtualMachines</a> as Sandboxes for the Grid  Sriya Santhanam, Pradheep Elango, Andrea Arpaci Dusseau, Miron Livny <a href="http://www.cs.wisc.edu/%7Epradheep/SandboxingWorlds05.pdf">http://www.cs.wisc.edu/~pradheep/SandboxingWorlds05.pdf</a></p>
<p>63) article: Xen and the new processors:</p>
<ul>
<li><a href="http://lwn.net/Articles/182080/">http://lwn.net/Articles/182080/</a> May  2, 2006</li>
</ul>
<p>Infiniband:</p>
<p>64) Infiniband (Smart IO) wiki page <a href="http://wiki.xensource.com/xenwiki/XenSmartIO">http://wiki.xensource.com/xenwiki/XenSmartIO</a> hg repository: <a href="http://xenbits.xensource.com/ext/xen-smartio.hg">http://xenbits.xensource.com/ext/xen-smartio.hg</a></p>
<p>65) Novell Infiniband and virtualization, Patrick Mullaney ,  may 1, 2007: <a href="http://www.openfabrics.org/archives/spring2007sonoma/Monday%20April%2030/Novell%20xen-ib-presentation-sonoma.ppt">http://www.openfabrics.org/archives/spring2007sonoma/Monday%20April%2030/Novell%20xen-ib-presentation-sonoma.ppt</a></p>
<p>66) A Case for High Performance Computing with Virtual Machines  Wei Huangy, Jiuxing Liuz, Bulent Abaliz et al. <a href="http://nowlab.cse.ohio-state.edu/publications/conf-papers/2006/huangwei-ics06.pdf">http://nowlab.cse.ohio-state.edu/publications/conf-papers/2006/huangwei-ics06.pdf</a></p>
<p>67) High Performance VMM-Bypass I/O in Virtual Machines Wei  Huangy, Jiuxing Liuz, Bulent Abaliz et al. (usenix 06) <a href="http://nowlab.cse.ohio-state.edu/publications/conf-papers/2006/usenix06.pdf">http://nowlab.cse.ohio-state.edu/publications/conf-papers/2006/usenix06.pdf</a></p>
<p>68) User Mode Linux , a book By Jeff Dike. Bruce Perens&#8217; Open  Source Series. Published: Apr 12, 2006; <a href="http://www.phptr.com/title/0131865056">http://www.phptr.com/title/0131865056</a></p>
<p>69) Xen 3.0.3 features,schedule : <a href="http://lists.xensource.com/archives/html/xen-devel/2006-06/msg00390.html">http://lists.xensource.com/archives/html/xen-devel/2006-06/msg00390.html</a></p>
<p>70) Practical Taint-Based Protection using Demand Emulation  Alex Ho, Michael Fetterman, Christopher Clark et al. <a href="http://www.cs.kuleuven.ac.be/conference/EuroSys2006/papers/p29-ho.pdf">http://www.cs.kuleuven.ac.be/conference/EuroSys2006/papers/p29-ho.pdf</a></p>
<p>71) <a href="http://stateless.geek.nz/2006/09/11/current-virtualisation-hardware/">http://stateless.geek.nz/2006/09/11/current-virtualisation-hardware/</a> Current Virtualisation Hardware by Nicholas Lee</p>
<p>72) RAID: Installing Xen with RAID 1 on a Fedora Core 4 x86 64  SMP machine: <a href="http://www.freax.be/wiki/index.php/Installing_Xen_with_RAID_1_on_a_Fedora_Core_4_x86_64_SMP_machine">http://www.freax.be/wiki/index.php/Installing_Xen_with_RAID_1_on_a_Fedora_Core_4_x86_64_SMP_machine</a></p>
<p>73) RAID 1 and Xen (dom0) : (On Debian) <a href="http://wiki.kartbuilding.net/index.php/RAID_1_and_Xen_%28dom0">http://wiki.kartbuilding.net/index.php/RAID_1_and_Xen_(dom0</a>)</p>
<p>74) OpenVZ Virtualization Software Available for Power  Processors <a href="http://lwn.net/Articles/204275/">http://lwn.net/Articles/204275/</a></p>
<p>75) Kernel-based Virtual Machine patchset (Avi Kivity) adding  /dev/kvm which exposes the virtualization capabilities to userspace. <a href="http://lwn.net/Articles/205580">http://lwn.net/Articles/205580</a></p>
<p>76) Intel Technology Journal : Intel Virtulaization Technology:  articles by Intel Staff (96 pages) <a href="http://download.intel.com/technology/itj/2006/v10i3/v10_iss03.pdf">http://download.intel.com/technology/itj/2006/v10i3/v10_iss03.pdf</a></p>
<p>77) kvm site: (Avi Kivity and others) Includes a howto and a  white paper, download , faq sections. <a href="http://kvm.sourceforge.net/">http://kvm.sourceforge.net/</a></p>
<p>78) kvm on debian: <a href="http://people.debian.org/%7Ebaruch/kvm">http://people.debian.org/~baruch/kvm</a> <a href="http://baruch.ev-en.org/blog/Debian/kvm-in-debian">http://baruch.ev-en.org/blog/Debian/kvm-in-debian</a></p>
<p>79) Linux Virtualization Wiki</p>
<ul>
<li><a href="http://virt.kernelnewbies.org/">http://virt.kernelnewbies.org/</a></li>
</ul>
<p>80) &#8221; New virtualisation system beats Xen to Linux kernel&#8221;  (about kvm) <a href="http://www.techworld.com/opsys/news/index.cfm?newsID=7586&amp;pagtype=all">http://www.techworld.com/opsys/news/index.cfm?newsID=7586&amp;pagtype=all</a></p>
<p>81) article about kvm: <a href="http://linux.inet.hr/finally-user-friendly-virtualization-for-linux.html">http://linux.inet.hr/finally-user-friendly-virtualization-for-linux.html</a></p>
<p>82) Virtual Linux : An overview of virtualization methods,  architectures, and implementations An article by M. Tim Jones (auhor of  &#8220;GNU/Linux Application Programming&#8221;,&#8221;AI Application Programming&#8221;, and &#8220;BSD  Sockets Programming from a Multilanguage Perspective&#8221;. <a href="http://www-128.ibm.com/developerworks/library/l-linuxvirt/index.html">http://www-128.ibm.com/developerworks/library/l-linuxvirt/index.html</a></p>
<p>83) Lguest: The Simple x86 Hypervisor by Rusty Russel (formerly  lhype) <a href="http://lguest.ozlabs.org/">http://lguest.ozlabs.org/</a></p>
<p>84) &#8220;Infrastructure virtualisation with Xen advisory&#8221; &#8211; a wiki  atricle : using iscsi for Xen-clustering ; shared storage <a href="http://docs.solstice.nl/index.php/Infrastructure_virtualisation_with_Xen_advisory">http://docs.solstice.nl/index.php/Infrastructure_virtualisation_with_Xen_advisory</a></p>
<p>85) Xen with DRBD, GNBD and OCFS2 HOWTO <a href="http://xenamo.sourceforge.net/">http://xenamo.sourceforge.net/</a></p>
<p>86) Virtualization with Xen(tm): Including Xenenterprise,  Xenserver, and Xenexpress (Paperback) by David E Williams Syngress Publishing  (April 1, 2007) # ISBN-10: 1597491675 # ISBN-13: 978-1597491679 (Author)<a onclick="return mugicPopWin(this,event);" oncontextmenu="mugicRightClick(this);" href="http://www.amazon.com/Virtualization-Xen-Including-Xenenterprise-Xenexpress/dp/1597491675/ref=pd_bbs_sr_2/103-3574046-3264617?ie=UTF8&amp;s=books&amp;qid=1173899913&amp;sr=8-2">http://www.amazon.com/Virtualization-Xen-Including-Xenenterprise-Xenexpress/dp/1597491675/ref=pd_bbs_sr_2/103-3574046-3264617?ie=UTF8&amp;s=books&amp;qid=1173899913&amp;sr=8-2</a></p>
<p>Paperback: 512 pages</p>
<p>87) Professional XEN Virtualization (Paperback) by William von  Hagen (Author)</p>
<p># Paperback: 500 pages # Publisher: Wrox (August 27, 2007) #  Language: English # ISBN-10: 0470138114 # ISBN-13: 978-0470138113</p>
<p>88) Xen and the Art of Consolidation Tom Eastep Linuxfest NW.  April 29, 2007. <a href="http://www.shorewall.net/Linuxfest-2007.pdf">http://www.shorewall.net/Linuxfest-2007.pdf</a></p>
<p>89) Optimizing Network Virtualization in Xen</p>
<p>By Willy Zwaenepoel, Alan L. Cox, Aravind Menon, usenix 2006 <a href="http://www.usenix.org/events/usenix06/tech/menon/menon_html/paper.html">http://www.usenix.org/events/usenix06/tech/menon/menon_html/paper.html</a></p>
<p>90) Virtual Machine Checkpointing</p>
<p>Brendan Cully,University of British Columbia with Andrew  Warfield, University of Cambridge</p>
<p><a href="http://xcr.cenit.latech.edu/hapcw2006/program/papers/cr-xen-hapcw06-final.pdf">http://xcr.cenit.latech.edu/hapcw2006/program/papers/cr-xen-hapcw06-final.pdf</a></p>
<h3 id="head-e2e4a234896aa188a9addd5e326e818265ba2fea">Adding new device and  triggering the probe() functions</h3>
<p><strong> </strong></p>
<p>The following is a simple example which shows how to add a new  device and trigger the probe() function of a backend driver using xenstore-write  tool. This is relevant for Xen 3.1</p>
<p>Currently in Xen, triggering of the probe() method in a backend  driver or a frontend driver is done by writing some values to the xenstore into  directories where the xenbus poses watches. This writing to the xenstore is  currently done in Xen from the python code, and it is wrapped deep inside the  xend and/or xm commands. Eventually it is done in the writeDetails method of the  <a href="/xenwiki/DevController">DevController</a> class. (And  both blkif and netif use it).</p>
<p>For those who want who want to be able to trigger the probe()  function without diving too deeply into the python code, this should suffice.</p>
<p>For the purposes of this little tutorial, let&#8217;s assume that you  have built and installed Xen 3.1 from source and have used it to fire up a guest  domain at least once. After you&#8217;ve done that, let&#8217;s say we want to add new  device. We will add a device named &#8220;mydevice&#8221;. Let&#8217;s begin with the backend. For  this purpose, we will add a directory named &#8220;deviceback&#8221; to  linux-2.6-sparse/drivers/xen. This directory will store the backend portion of  our driver.</p>
<p>First, create linux-2.6-sparse/drivers/xen/deviceback. Next,  add the following three files to that directory: deviceback.c, xenbus.c,  common.h and Makefile.</p>
<p>Here is a minimal skeleton implementation of these files:</p>
<h4 id="head-b455c7944a07c5ceb05e6bc4f911a83ee7f6dfdc">deviceback.c</h4>
<pre>#include &lt;linux/module.h&gt;
#include "common.h"
static int __init deviceback_init(void)
{
        device_xenbus_init();
}
static void deviceback_cleanup()
{
}
module_init(deviceback_init);
module_exit(deviceback_cleanup);
</pre>
<h4 id="head-1cae230b42ee2ae00ed08ba606c2ada0ce3642c1">xenbus.c</h4>
<pre>#include &lt;xen/xenbus.h&gt;
#include &lt;linux/module.h&gt;
#include &lt;linux/slab.h&gt;
struct backendinfo
{
        struct xenbus_device* dev;
        long int frontend_id;
        struct xenbus_watch backend_watch;
        struct xenbus_watch watch;
        char* frontpath;
};
//////////////////////////////////////////////////////////////////////////////
static int device_probe(struct xenbus_device* dev,
                        const struct xenbus_device_id* id)
{
        struct backendinfo* be;
        char* frontend;
        int err;
        be = kmalloc(sizeof(*be),GFP_KERNEL);
        memset(be,0,sizeof(*be));
        be-&gt;dev = dev;
        printk("Probe fired!\n");
        return 0;
}
//////////////////////////////////////////////////////////////////////////////
static int device_uevent(struct xenbus_device* xdev,
                          char** envp, int num_envp,
                          char* buffer, int buffer_size)
{
        return 0;
}
static int device_remove(struct xenbus_device* dev)
{
        return 0;
}
//////////////////////////////////////////////////////////////////////////////
static struct xenbus_device_id device_ids[] =
{
        { "mydevice" },
        { "" }
};
//////////////////////////////////////////////////////////////////////////////
static struct xenbus_driver deviceback =
{
        .name    = "mydevice",
        .owner   = THIS_MODULE,
        .ids     = device_ids,
        .probe   = device_probe,
        .remove  = device_remove,
        .uevent  = device_uevent,
};
//////////////////////////////////////////////////////////////////////////////
void device_xenbus_init()
{
        xenbus_register_backend(&amp;deviceback);
}
</pre>
<h4 id="head-fb3e5849588b78823d33560b09b74e4dc75c4055">common.h</h4>
<pre>#ifndef COMMON_H
#define COMMON_H
void device_xenbus_init(void);
#endif
</pre>
<h4 id="head-e6fc3a609b28fe31fb9c8d8454c2918815be0f7b">Makefile</h4>
<pre>#Makefile
obj-y += xenbus.o deviceback.o
</pre>
<p>Next, we should add our new backend device to the Makefile in  linux-2.6-sparse/drivers/xen/Makefile. Add the following line to the bottom of  that file:</p>
<pre>obj-y += deviceback/
</pre>
<p>This will make sure that it will be included in the build.</p>
<p>Next, we need to add symlinks from  linux-2.6-sparse/drivers/xen/deviceback into  linux-2.6.18-xen/drivers/xen/deviceback:</p>
<ol type="1">
<li>Create linux-2.6.18-xen/drivers/xen/deviceback</li>
<li>Change into that directory</li>
<li>Add the symlinks: &#8216;ln -s  ../../../../linux-2.6-xen-sparse/./drivers/xen/deviceback/./* .&#8217;</li>
</ol>
<p>Now we should build the new drivers and reboot with the new Xen  image. You can do this by going back to the root directory of the source tree  (the place where you typed &#8216;make world&#8217; when doing your normal build before) and  do &#8216;make install-kernels&#8217;. (Note: This will overwrite the previous Xen kernel!)  Finally, reboot.</p>
<p>After the machine boots back up, go ahead and start a guest  domain and you should notice that device_probe() does not get executed. (Check  /var/log/syslog on dom0 to look for the printk() to show up.)</p>
<p>How can we trigger the probe() function of our backend driver?  We just need to write the correct key/value pairs into the xenstore.</p>
<p>The call to xenbus_register_backend() in xenbus.c causes xenbus  to set a watch on local/domain/0/backend/mydevice in the xenstore. Specifically,  anytime anything is written into that location in the store the watch fires and  checks for a specific set of key/value pairs that indicate the probe should be  fired.</p>
<p>So performing the following 4 calls using xenstore-write will  trigger our probe() function. Change the X with the ID of a running guest  domain. (Check &#8216;xm list&#8217; for this. If you&#8217;ve only started one guest, this number  is probably 1.)</p>
<pre>xenstore-write /local/domain/X/device/mydevice/0/state 1
xenstore-write /local/domain/0/backend/mydevice/X/0/frontend-id X
xenstore-write /local/domain/0/backend/mydevice/X/0/frontend /local/domain/X/device/mydevice/0
xenstore-write /local/domain/0/backend/mydevice/X/0/state 1
</pre>
<p>You should see the probe message appear the Dom0&#8242;s  /var/log/syslog. What happened here behind the scenes ,without going too deep,  is that the xenbus_register_backend() put a watch on the xenback directory of  /local/domain/0 in the xenstore. Once frontend, frontend-id, and state are all  written to the watched location, the xenbus driver will gather all of that  information, as well as the state of the frontend driver (written in that first  line) and use it to setup the appropriate data structures. From there, the  probe() function is finally fired.</p>
<h3 id="head-a6b774bff231998a0cfbe74341467bd0451d724c">Adding a frontend  device</h3>
<p>For this purpose,we will add a directory named &#8220;devicefront&#8221; to  linux-2.6-sparse/drivers/xen.</p>
<p>We will create 2 files there: devicefront.c and Makefile.</p>
<p>We will also add directories and symlinks as we did in the  deviceback case.</p>
<h4 id="head-e6fc3a609b28fe31fb9c8d8454c2918815be0f7b-2">Makefile</h4>
<pre>obj-y := devicefront.o
</pre>
<h4 id="head-34dbb29222fb16906f7c963f7f125159a067744d">devicefront.c</h4>
<p>The devicefront.c will be (a minimalist implementation):</p>
<pre>// devicefront.c
#include &lt;xen/xenbus.h&gt;
#include &lt;linux/module.h&gt;
#include &lt;linux/list.h&gt;
struct device_info
{
        struct list_head list;
        struct xenbus_device* xbdev;
};
//////////////////////////////////////////////////////////////////////////////
static int devicefront_probe(struct xenbus_device* dev,
                             const struct xenbus_device_id* id)
{
        printk("Frontend Probe Fired!\n");
        return 0;
}
//////////////////////////////////////////////////////////////////////////////
static struct xenbus_device_id devicefront_ids[] =
{
        {"mydevice"},
        {}
};
static struct xenbus_driver devicefront =
{
        .name  = "mydevice",
        .owner = THIS_MODULE,
        .ids   = devicefront_ids,
        .probe = devicefront_probe,
};
static int devicefront_init(void)
{
        printk("%s\n",__FUNCTION__);
        xenbus_register_frontend(&amp;devicefront);
}
module_init(devicefront_init);
</pre>
<p>We should also remember to add the following to the Makefile  under linux-2.6-sparse/drivers/xen:</p>
<pre>obj-y   += devicefront/
</pre>
<p>Getting the frontend driver to fire is a bit more complicated,  the following bash script should help you:</p>
<pre>#!/bin/bash
if [ $# != 2 ]
then
        echo "Usage: $0 &lt;device name&gt; &lt;frontend-id&gt;"
else
        # Write backend information into the location the frontend will look
        # for it.
        xenstore-write /local/domain/${2}/device/${1}/0/backend-id 0
        xenstore-write /local/domain/${2}/device/${1}/0/backend \
                       /local/domain/0/backend/${1}/${2}/0
        # Write frontend information into the location the backend will look
        # for it.
        xenstore-write /local/domain/0/backend/${1}/${2}/0/frontend-id ${2}
        xenstore-write /local/domain/0/backend/${1}/${2}/0/frontend \
                       /local/domain/${2}/device/${1}/0
        # Set the permissions on the backend so that the frontend can
        # actually read it.
        xenstore-chmod /local/domain/0/backend/${1}/${2}/0 r
        # Write the states.  Note that the backend state must be written
        # last because it requires a valid frontend state to already be
        # written.
        xenstore-write /local/domain/${2}/device/${1}/0/state 1
        xenstore-write /local/domain/0/backend/${1}/${2}/0/state 1
fi</pre>
<p>Here&#8217;s how to use it:</p>
<ul>
<li>Startup a Xen guest that contains your frontend driver, and be sure dom0  contains the backend driver.</li>
<li>Figure out the frontend-id for the guest. This is the ID field when running  xm list. Let&#8217;s say that number is 3.</li>
<li>Run the script as so: ./probetest.sh mydevice 3</li>
</ul>
<p>That should fire both the frontend driver. (You&#8217;ll have to  check /var/log/messages in the guest to verify that the probe was fired.)</p>
<h3 id="head-250800453b2dd8e8b359a030e3d6fa81ea9f374d">Discussion</h3>
<p><a href="/xenwiki/SimonKagstrom">SimonKagstrom</a>: Maybe it  would be a good idea to split this document into several pages? It&#8217;s starting to  be fairly long <img title=":)" src="/wiki/modern/img/smile.png" alt=":)" width="15" height="15" /> <a href="/xenwiki/TimPost">TimPost</a></p>
<p><a href="/xenwiki/TimPost">TimPost</a>: ACK, even if printed,  this is hard to digest as an intro</p>
<p>Reference:</p>
<p>http://wiki.xensource.com/xenwiki/XenIntro</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/johnsofteng.wordpress.com/284/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/johnsofteng.wordpress.com/284/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/johnsofteng.wordpress.com/284/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/johnsofteng.wordpress.com/284/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/johnsofteng.wordpress.com/284/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/johnsofteng.wordpress.com/284/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/johnsofteng.wordpress.com/284/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/johnsofteng.wordpress.com/284/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/johnsofteng.wordpress.com/284/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/johnsofteng.wordpress.com/284/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/johnsofteng.wordpress.com/284/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/johnsofteng.wordpress.com/284/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/johnsofteng.wordpress.com/284/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/johnsofteng.wordpress.com/284/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=johnsofteng.wordpress.com&amp;blog=8263322&amp;post=284&amp;subd=johnsofteng&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://johnsofteng.wordpress.com/2010/01/08/xenintro/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/53024032acd728facceb97bfe56c7bc9?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">johnsofteng</media:title>
		</media:content>

		<media:content url="http://www.ipd.bth.se/ska/rings.png" medium="image">
			<media:title type="html">rings</media:title>
		</media:content>

		<media:content url="http://www.ipd.bth.se/ska//virtualDevices.png" medium="image">
			<media:title type="html">virtualDevices</media:title>
		</media:content>

		<media:content url="/wiki/modern/img/smile.png" medium="image">
			<media:title type="html">:)</media:title>
		</media:content>
	</item>
		<item>
		<title>Strip attachments from an email message</title>
		<link>http://johnsofteng.wordpress.com/2009/12/07/strip-attachments-from-an-email-message/</link>
		<comments>http://johnsofteng.wordpress.com/2009/12/07/strip-attachments-from-an-email-message/#comments</comments>
		<pubDate>Mon, 07 Dec 2009 07:04:15 +0000</pubDate>
		<dc:creator>johnsofteng</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[attachment]]></category>
		<category><![CDATA[imap]]></category>
		<category><![CDATA[lib]]></category>
		<category><![CDATA[replace]]></category>

		<guid isPermaLink="false">http://johnsofteng.wordpress.com/?p=265</guid>
		<description><![CDATA[This recipe shows a simple approach to using the Python email package to strip out attachments and file types from an email message that might be considered dangerous. This is particularly relevant in Python 2.4, as the email Parser is now much more robust in handling mal-formed messages (which are typical for virus and worm [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=johnsofteng.wordpress.com&amp;blog=8263322&amp;post=265&amp;subd=johnsofteng&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<div id="description">
<p>This recipe shows a simple approach to using the Python email package to  strip out attachments and file types from an email message that might be  considered dangerous. This is particularly relevant in Python 2.4, as the email  Parser is now much more robust in handling mal-formed messages (which are  typical for virus and worm emails)</p>
</div>
<div id="blocks">
<div>
<table>
<tbody>
<tr>
<td></td>
<td>Python</td>
</tr>
</tbody>
</table>
<div>
<table>
<tbody>
<tr>
<td>
<pre> 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64</pre>
</td>
<td>
<div>
<pre>ReplaceString = """

This message contained an attachment that was stripped out. 

The original type was: %(content_type)s
The filename was: %(filename)s,
(and it had additional parameters of:
%(params)s)

"""

import re
BAD_CONTENT_RE = re.compile('application/(msword|msexcel)', re.I)
BAD_FILEEXT_RE = re.compile(r'(\.exe|\.zip|\.pif|\.scr|\.ps)$')

def sanitise(msg):
    # Strip out all payloads of a particular type
    ct = msg.get_content_type()
    # We also want to check for bad filename extensions
    fn = msg.get_filename()
    # get_filename() returns None if there's no filename
    if BAD_CONTENT_RE.search(ct) or (fn and BAD_FILEEXT_RE.search(fn)):
        # Ok. This part of the message is bad, and we're going to stomp
        # on it. First, though, we pull out the information we're about to
        # destroy so we can tell the user about it.

        # This returns the parameters to the content-type. The first entry
        # is the content-type itself, which we already have.
        params = msg.get_params()[1:]
        # The parameters are a list of (key, value) pairs - join the
        # key-value with '=', and the parameter list with ', '
        params = ', '.join([ '='.join(p) for p in params ])
        # Format up the replacement text, telling the user we ate their
        # email attachment.
        replace = ReplaceString % dict(content_type=ct,
                                       filename=fn,
                                       params=params)
        # Install the text body as the new payload.
        msg.set_payload(replace)
        # Now we manually strip away any paramaters to the content-type
        # header. Again, we skip the first parameter, as it's the
        # content-type itself, and we'll stomp that next.
        for k, v in msg.get_params()[1:]:
            msg.del_param(k)
        # And set the content-type appropriately.
        msg.set_type('text/plain')
        # Since we've just stomped the content-type, we also kill these
        # headers - they make no sense otherwise.
        del msg['Content-Transfer-Encoding']
        del msg['Content-Disposition']
    else:
        # Now we check for any sub-parts to the message
        if msg.is_multipart():
            # Call the sanitise routine on any subparts
            payload = [ sanitise(x) for x in msg.get_payload() ]
            # We replace the payload with our list of sanitised parts
            msg.set_payload(payload)
    # Return the sanitised message
    return msg

# And a simple driver to show how to use this
import email, sys
m = email.message_from_file(open(sys.argv[1]))
print sanitise(m)
</pre>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<div>
<h3>Discussion</h3>
<div>
<p>I&#8217;ve seen this come up a few times on comp.lang.python, so here&#8217;s a cookbook  entry for it. This recipe shows how to read in an email message, strip out any  dangerous or suspicious attachments, and replace them with a harmless text  message informing the user of this.</p>
<p>This is particularly important if the end-users are using something like  Outlook, which is targetted by unpleasant virus and worm messages on a daily  basis.</p>
<p>The email parser in Python 2.4 has been completely rewritten to be robust  first, correct second &#8211; prior to this, the parser was written for correctness  first. This was a problem, because many virus/worm messages would send email  messages that were broken and non-conformant &#8211; this made the old email parser  choke and die. The new parser is designed to never actually break when reading a  message &#8211; instead it tries it&#8217;s best to fix up whatever it can in the message.  (If you have a message that causes the parser to crash, please let us know &#8211;  that&#8217;s a bug, and we&#8217;ll fix it).</p>
<p>The code itself is heavily commented, and should be easy enough to follow. A  mail message consists of one or more parts &#8211; these can each contain nested  parts. We call the &#8216;sanitise()&#8217; function on the top level Message object, and it  calls itself recursively on the sub-objects. The sanitise() function checks the  Content-Type of the part, and if there&#8217;s a filename, also checks that, against a  known-to-be-bad list.</p>
<p>If the message part is bad, we replace the message itself with a short text  description describing the now-removed part, and clean out the headers that are  relevant. We set this message part&#8217;s Content-Type to &#8216;text/plain&#8217;, and remove  other headers that related to the now-removed message.</p>
<p>Finally, we check if the message is a multipart message. This means it has  sub-parts, so we recursively call the sanitise function on each of those. We  then replace the payload with our list of sanitised sub-parts.</p>
<p>Extensions, further work, etc:</p>
<p>Instead of destroying the attachment, it would be a small amount of work to  instead store the attachment away in a directory, and supply the user with a  link to the file.</p>
<p>You could add other filters into the sanitise() code &#8211; for instance, checking  other headers for known signs of worm or virus messages. Or removing all large  powerpoint files sent to you by your marketing department, if that&#8217;s what you  want to do.</p>
<p>Reference:</p>
<p>http://code.activestate.com/recipes/302086/</p>
</div>
</div>
</div>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/johnsofteng.wordpress.com/265/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/johnsofteng.wordpress.com/265/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/johnsofteng.wordpress.com/265/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/johnsofteng.wordpress.com/265/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/johnsofteng.wordpress.com/265/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/johnsofteng.wordpress.com/265/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/johnsofteng.wordpress.com/265/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/johnsofteng.wordpress.com/265/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/johnsofteng.wordpress.com/265/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/johnsofteng.wordpress.com/265/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/johnsofteng.wordpress.com/265/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/johnsofteng.wordpress.com/265/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/johnsofteng.wordpress.com/265/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/johnsofteng.wordpress.com/265/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=johnsofteng.wordpress.com&amp;blog=8263322&amp;post=265&amp;subd=johnsofteng&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://johnsofteng.wordpress.com/2009/12/07/strip-attachments-from-an-email-message/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/53024032acd728facceb97bfe56c7bc9?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">johnsofteng</media:title>
		</media:content>
	</item>
		<item>
		<title>Linux Network Setup/Monitor commands</title>
		<link>http://johnsofteng.wordpress.com/2009/11/30/linux-network-setupmonitor-commands/</link>
		<comments>http://johnsofteng.wordpress.com/2009/11/30/linux-network-setupmonitor-commands/#comments</comments>
		<pubDate>Tue, 01 Dec 2009 01:57:13 +0000</pubDate>
		<dc:creator>johnsofteng</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[check]]></category>
		<category><![CDATA[command]]></category>
		<category><![CDATA[NIC]]></category>
		<category><![CDATA[status]]></category>

		<guid isPermaLink="false">http://johnsofteng.wordpress.com/?p=269</guid>
		<description><![CDATA[1. check devices status: lspci  (dmidecode, lsusb, lshw , lspci) reference: http://ubuntuforums.org/showthread.php?t=320995 2.  Check the network status: mii-tool  (you should be root) ip link References: http://www.linuxforums.org/forum/redhat-fedora-linux-help/129167-how-detect-hardware-add-new-one.html 3. NIC card change sequence: nameif (hwinfo) /lib/udev/rename_netiface &#60;old&#62; &#60;new&#62; References: http://www.centos.org/modules/newbb/viewtopic.php?topic_id=10434 http://www.cyberciti.biz/faq/rhel-fedora-centos-howto-swap-ethernet-aliases/ http://www.linuxforums.org/forum/suse-linux-help/92280-how-change-ethx-ethy.html 4. iftop a good console bandwidth visualization tool that shows you active connections, where they [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=johnsofteng.wordpress.com&amp;blog=8263322&amp;post=269&amp;subd=johnsofteng&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>1. check devices status:</p>
<p>lspci  (dmidecode, lsusb, lshw , lspci)</p>
<p>reference: http://ubuntuforums.org/showthread.php?t=320995</p>
<p>2.  Check the network status:</p>
<p>mii-tool  (you should be root)</p>
<p>ip link</p>
<p>References:</p>
<p>http://www.linuxforums.org/forum/redhat-fedora-linux-help/129167-how-detect-hardware-add-new-one.html</p>
<p>3. NIC card change sequence:</p>
<p>nameif</p>
<p>(hwinfo)</p>
<p>/lib/udev/rename_netiface &lt;old&gt; &lt;new&gt;</p>
<p>References:</p>
<p>http://www.centos.org/modules/newbb/viewtopic.php?topic_id=10434</p>
<p>http://www.cyberciti.biz/faq/rhel-fedora-centos-howto-swap-ethernet-aliases/</p>
<p>http://www.linuxforums.org/forum/suse-linux-help/92280-how-change-ethx-ethy.html</p>
<p>4. iftop</p>
<p>a good console bandwidth visualization tool that shows you active<br />
connections, where they are going to/from and how much of your precious bandwidth<br />
they are using.</p>
<p><strong>iftop</strong> is a command-line <a title="System monitor" href="/wiki/System_monitor">system monitor</a> tool that produces a frequently-updated list of network connections. By default, the connections are ordered by bandwidth usage, with only the &#8220;top&#8221; bandwidth consumers shown.</p>
<p>Reference:</p>
<p><a href="http://en.wikipedia.org/wiki/Iftop">http://en.wikipedia.org/wiki/Iftop</a></p>
<p>5. iptraf</p>
<p>IPTraf is a console-based network statistics utility for Linux. It gathers a variety of figures such as TCP connection packet and byte counts, interface statistics and activity indicators, TCP/UDP traffic breakdowns, and LAN station packet and byte counts.</p>
<p><a href="http://iptraf.seul.org/">http://iptraf.seul.org/</a></p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/johnsofteng.wordpress.com/269/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/johnsofteng.wordpress.com/269/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/johnsofteng.wordpress.com/269/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/johnsofteng.wordpress.com/269/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/johnsofteng.wordpress.com/269/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/johnsofteng.wordpress.com/269/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/johnsofteng.wordpress.com/269/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/johnsofteng.wordpress.com/269/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/johnsofteng.wordpress.com/269/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/johnsofteng.wordpress.com/269/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/johnsofteng.wordpress.com/269/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/johnsofteng.wordpress.com/269/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/johnsofteng.wordpress.com/269/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/johnsofteng.wordpress.com/269/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=johnsofteng.wordpress.com&amp;blog=8263322&amp;post=269&amp;subd=johnsofteng&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://johnsofteng.wordpress.com/2009/11/30/linux-network-setupmonitor-commands/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/53024032acd728facceb97bfe56c7bc9?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">johnsofteng</media:title>
		</media:content>
	</item>
		<item>
		<title>BASH Shell: For Loop File Names With Spaces</title>
		<link>http://johnsofteng.wordpress.com/2009/11/20/bash-shell-for-loop-file-names-with-spaces/</link>
		<comments>http://johnsofteng.wordpress.com/2009/11/20/bash-shell-for-loop-file-names-with-spaces/#comments</comments>
		<pubDate>Fri, 20 Nov 2009 21:39:53 +0000</pubDate>
		<dc:creator>johnsofteng</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[Mac]]></category>
		<category><![CDATA[Shell]]></category>
		<category><![CDATA[bash]]></category>
		<category><![CDATA[loop]]></category>
		<category><![CDATA[newline]]></category>
		<category><![CDATA[spaces]]></category>

		<guid isPermaLink="false">http://johnsofteng.wordpress.com/2009/11/20/bash-shell-for-loop-file-names-with-spaces/</guid>
		<description><![CDATA[BASH for loop works nicely under UNIX / Linux / Windows and OS X while working on set of files. However, if you try to process a for loop on file name with spaces in them you are going to have some problem. for loop uses $IFS variable to determine what the field separators are. [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=johnsofteng.wordpress.com&amp;blog=8263322&amp;post=256&amp;subd=johnsofteng&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.cyberciti.biz/faq/bash-for-loop/">BASH for loop</a> works nicely under UNIX / Linux / Windows and OS X while working on set of files. However, if you try to process a for loop on file name with spaces in them you are going to have some problem. for loop uses $IFS variable to determine what the field separators are. By default $IFS is set to the space character. There are multiple solutions to this problem.</p>
<h2>Set $IFS variable</h2>
<p>Try it as follows:</p>
<pre>#!/bin/bash
SAVEIFS=$IFS
IFS=$(echo -en "\n\b")
for f in *
do
  echo "$f"
done
IFS=$SAVEIFS</pre>
<p>OR</p>
<pre>#!/bin/bash
SAVEIFS=$IFS
IFS=$(echo -en "\n\b")
# set me
FILES=/data/*
for f in $FILES
do
  echo "$f"
done
# restore $IFS
IFS=$SAVEIFS</pre>
<h3>More examples using $IFS and while loop</h3>
<p>Now you know that if the field delimiters are not whitespace, you can set IFS. For example, <a href="http://www.cyberciti.biz/faq/bash-while-loop/">while loop</a> can be used to get all fields from /etc/passwd file:</p>
<pre>....
while IFS=: read userName passWord userID groupID geCos homeDir userShell
do
      echo "$userName -&gt; $homeDir"
done &lt; /etc/passwd</pre>
<h2>Using old good find command to process file names</h2>
<p>To process the output of <a href="http://www.cyberciti.biz/tips/tag/find-command">find</a> with a command, try as follows:</p>
<pre>find . -print0 | while read -d $'' file
do
  echo -v "$file"
done</pre>
<p>Try to copy files to /tmp with spaces in a filename using <a href="http://www.cyberciti.biz/faq/tag/find-command/">find command</a> and shell pipes:</p>
<pre>find . -print0 | while read -d $'' file; do cp -v "$file" /tmp; done</pre>
<h2>Processing filenames using an array</h2>
<p>Sometimes you need <a href="http://www.cyberciti.biz/faq/finding-bash-shell-array-length-elements/">read a file into an array</a> as one array element per line. Following script will read file names into an array and you can process each file using for loop. This is useful for complex tasks:</p>
<pre>#!/bin/bash
DIR="$1"

# failsafe - fall back to current directory
[ "$DIR" == "" ] &amp;&amp; DIR="." 

# save and change IFS
OLDIFS=$IFS
IFS=$'\n' 

# read all file name into an array
fileArray=($(find $DIR -type f))

# restore it
IFS=$OLDIFS

# get length of an array
tLen=${#fileArray[@]}

# use for loop read all filenames
for (( i=0; i&lt;${tLen}; i++ ));
do
  echo "${fileArray[$i]}"
done</pre>
<h3>Playing mp3s with spaces in file names</h3>
<p>Place following code in your ~/.bashrc file:</p>
<pre>mp3(){
	local o=$IFS
	IFS=$(echo -en "\n\b")
	/usr/bin/beep-media-player "$(cat  $@)" &amp;
	IFS=o
}</pre>
<p>Keep list of all mp3s in a text file such as follows (~/eng.mp3.txt):</p>
<pre>/nas/english/Adriano Celentano - Susanna.mp3
/nas/english/Nick Cave &amp; Kylie Minogue - Where The Wild Roses Grow.mp3
/nas/english/Roberta Flack - Kiling Me Softly With This Song.mp3
/nas/english/The Beatles - Girl.mp3
/nas/english/John Lennon - Stand By Me.mp3
/nas/english/The Seatbelts, Cowboy Bebop - 01-Tank.mp3</pre>
<p>To play just type:<br />
<code>$ mp3 eng.mp3.txt</code></p>
<p><code>Another example about IFS:</code></p>
<blockquote><p><code>#!/bin/bash</code></p>
<p>IFS=$&#8217;\n&#8217;<br />
set $(cat my.file)</p>
<p># Now the lines are stored in $1, $2, $3, &#8230;</p>
<p>echo $1<br />
echo $2<br />
echo $3<br />
echo $4</p></blockquote>
<p><code>Reference:</code></p>
<p><code><a href="http://www.cyberciti.biz/tips/handling-filenames-with-spaces-in-bash.html">http://www.cyberciti.biz/tips/handling-filenames-with-spaces-in-bash.html</a></code></p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/johnsofteng.wordpress.com/256/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/johnsofteng.wordpress.com/256/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/johnsofteng.wordpress.com/256/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/johnsofteng.wordpress.com/256/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/johnsofteng.wordpress.com/256/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/johnsofteng.wordpress.com/256/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/johnsofteng.wordpress.com/256/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/johnsofteng.wordpress.com/256/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/johnsofteng.wordpress.com/256/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/johnsofteng.wordpress.com/256/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/johnsofteng.wordpress.com/256/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/johnsofteng.wordpress.com/256/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/johnsofteng.wordpress.com/256/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/johnsofteng.wordpress.com/256/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=johnsofteng.wordpress.com&amp;blog=8263322&amp;post=256&amp;subd=johnsofteng&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://johnsofteng.wordpress.com/2009/11/20/bash-shell-for-loop-file-names-with-spaces/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/53024032acd728facceb97bfe56c7bc9?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">johnsofteng</media:title>
		</media:content>
	</item>
	</channel>
</rss>
