<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-8144285405079538181</id><updated>2012-01-14T04:52:21.917-08:00</updated><category term='Illumos'/><category term='Python'/><category term='MacOSX'/><category term='JVM'/><category term='vi'/><category term='Zones'/><category term='Clojure'/><category term='OCaml'/><category term='FreeBSD'/><category term='DragonflyBSD'/><category term='TOR'/><category term='D'/><category term='Mercurial'/><category term='Haskell'/><category term='C++'/><category term='C#'/><category term='OpenIndiana'/><category term='LLVM'/><category term='OpenSolaris'/><category term='ksh93'/><category term='Scala'/><category term='Git'/><category term='Politik'/><category term='Ruby'/><category term='Linux'/><category term='Debugging'/><category term='Dtrace'/><category term='ZFS'/><category term='ZSH'/><title type='text'>raichoo :: λpunk</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://raichoo.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://raichoo.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><link rel='next' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default?start-index=101&amp;max-results=100'/><author><name>Björn 'raichoo' Herzig</name><uri>https://profiles.google.com/102273886131939895778</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-KxzzpA_pbkc/AAAAAAAAAAI/AAAAAAAAARI/yHTIB2nrp8I/s512-c/photo.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>113</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-8144285405079538181.post-590035234520260232</id><published>2012-01-04T08:20:00.000-08:00</published><updated>2012-01-04T08:20:40.496-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Dtrace'/><category scheme='http://www.blogger.com/atom/ns#' term='Illumos'/><category scheme='http://www.blogger.com/atom/ns#' term='Haskell'/><category scheme='http://www.blogger.com/atom/ns#' term='OpenIndiana'/><title type='text'>Building GHC under Illumos</title><content type='html'>&lt;p&gt;I like the bleeding edge, that's why I always want to have the newest compilers for my favorite languages and Haskell is one of those languages. In this blogpost I'm going to show you how to build the latest and greatest GHC on the &lt;a href="https://www.illumos.org/"&gt;Illumos&lt;/a&gt; distribution &lt;a href="http://openindiana.org/"&gt;OpenIndiana&lt;/a&gt;. If you don't want to build it yourself you can pick up a fairly recent version of GHC from the &lt;a href="http://wiki.openindiana.org/oi/Spec+Files+Extra+Repository"&gt;SFE Repository&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;To make things easier let's get our hand on a GHC binary from which we can bootstrap our environment, luckily there is a package for &lt;a href="http://www.haskell.org/ghc/dist/7.0.3/maeder/ghc-7.0.3-i386-unknown-solaris2.tar.bz2"&gt;GHC 7.0.3 for Solaris&lt;/a&gt; which works just fine under Illumos. Just install it and put it in your PATH environment variable.&lt;/p&gt;&lt;p&gt;Due to it's Solaris heritage, Illumos currently ships with a pretty outdated version of GCC. I recommend that you install the GCC provided by the &lt;a href="http://wiki.openindiana.org/oi/Spec+Files+Extra+Repository"&gt;SFE Repository&lt;/a&gt; since the shipped version causes some linking problems when dealing with the hidden attribute. If you have to use the old compiler you can get rid of this issue by using this quick and dirty patch which just gets rid of some pragmas and macros:&lt;pre&gt;&lt;code&gt;&lt;br /&gt;diff --git a/includes/Rts.h b/includes/Rts.h&lt;br /&gt;index 91ec76d..adbbe54 100644&lt;br /&gt;--- a/includes/Rts.h&lt;br /&gt;+++ b/includes/Rts.h&lt;br /&gt;@@ -52,7 +52,7 @@ extern "C" {&lt;br /&gt; // with visibility "hidden" to hide them outside the RTS shared&lt;br /&gt; // library.&lt;br /&gt; #if defined(HAS_VISIBILITY_HIDDEN)&lt;br /&gt;-#define RTS_PRIVATE  GNUC3_ATTRIBUTE(visibility("hidden"))&lt;br /&gt;+#define RTS_PRIVATE  //GNUC3_ATTRIBUTE(visibility("hidden"))&lt;br /&gt; #else&lt;br /&gt; #define RTS_PRIVATE  /* disabled: RTS_PRIVATE */&lt;br /&gt; #endif&lt;br /&gt;diff --git a/rts/BeginPrivate.h b/rts/BeginPrivate.h&lt;br /&gt;index 6471b92..1af4c90 100644&lt;br /&gt;--- a/rts/BeginPrivate.h&lt;br /&gt;+++ b/rts/BeginPrivate.h&lt;br /&gt;@@ -6,5 +6,5 @@&lt;br /&gt;        error: visibility attribute not supported in this configuration; ignored&lt;br /&gt;    */&lt;br /&gt; #if defined(HAS_VISIBILITY_HIDDEN) &amp;&amp; !defined(freebsd_HOST_OS)&lt;br /&gt;-#pragma GCC visibility push(hidden)&lt;br /&gt;+//#pragma GCC visibility push(hidden)&lt;br /&gt; #endif&lt;br /&gt;diff --git a/rts/EndPrivate.h b/rts/EndPrivate.h&lt;br /&gt;index 4cfb68f..c2e3154 100644&lt;br /&gt;--- a/rts/EndPrivate.h&lt;br /&gt;+++ b/rts/EndPrivate.h&lt;br /&gt;@@ -1,3 +1,3 @@&lt;br /&gt; #if defined(HAS_VISIBILITY_HIDDEN) &amp;&amp; !defined(freebsd_HOST_OS)&lt;br /&gt;-#pragma GCC visibility pop&lt;br /&gt;+//#pragma GCC visibility pop&lt;br /&gt; #endif&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;&lt;p&gt;Now we are good to go. Get your hands on some fresh tarball, perhaps the latest and greatest RC. To configure your future GHC just run something like:&lt;pre&gt;&lt;code&gt;&lt;br /&gt;./configure --prefix=~/Library/GHC/version --with-gmp-includes=/usr/include/gmp&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;I usually install self compiled software in &lt;code&gt;~/Library/program/version&lt;/code&gt;. From here I can manage everything using softlinks but feel free to use any other prefix.&lt;/p&gt;&lt;p&gt;Be sure to run the GNU Make (&lt;code&gt;gmake&lt;/code&gt;) command and not the Illumos one. Sadly &lt;code&gt;gmake&lt;/code&gt; seems to be unable to handle multiple jobs when compiling GHC so our final step looks like this:&lt;pre&gt;&lt;code&gt;&lt;br /&gt;gmake &amp;&amp; gmake install&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;&lt;p&gt;From here on you should be able to build pretty much every version you wish for. If you pick a version that is supported by &lt;code&gt;cabal-install&lt;/code&gt; installing additional packages from &lt;a href="http://hackage.haskell.org/packages/hackage.html"&gt;hackage&lt;/a&gt; is a piece of cake. I usually have more than one GHC installed, the one that is shipped with the current &lt;a href="http://hackage.haskell.org/platform/"&gt;Haskell Platform&lt;/a&gt; and the latest version with all the hot new features.&lt;/p&gt;&lt;p&gt;Illumos has the potential to be one of the best platforms for developing Haskell since it has exquisite &lt;a href="http://de.wikipedia.org/wiki/DTrace"&gt;DTrace&lt;/a&gt; support. If you want to help to improve the Haskell experience on Illumos, feel free to contact me in #openindiana on freenode.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8144285405079538181-590035234520260232?l=raichoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://raichoo.blogspot.com/feeds/590035234520260232/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8144285405079538181&amp;postID=590035234520260232' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/590035234520260232'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/590035234520260232'/><link rel='alternate' type='text/html' href='http://raichoo.blogspot.com/2012/01/building-ghc-under-illumos.html' title='Building GHC under Illumos'/><author><name>Björn 'raichoo' Herzig</name><uri>https://profiles.google.com/102273886131939895778</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-KxzzpA_pbkc/AAAAAAAAAAI/AAAAAAAAARI/yHTIB2nrp8I/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8144285405079538181.post-1181192278170939255</id><published>2011-08-24T11:21:00.000-07:00</published><updated>2011-08-28T04:39:39.912-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Scala'/><title type='text'>More Fun with Scala "Dependent" Types</title><content type='html'>In &lt;a href="http://raichoo.blogspot.com/2011/08/taste-of-dependent-types-in-scala.html"&gt;my last post&lt;/a&gt; I wrote about lists that encode their length within their type and the possibilities that gives us to ensure correctness of our code. In this post I want to expand these ideas.&lt;br /&gt;&lt;br /&gt;Let's assume that we have a list with an even number of elements. By knowing that the length is even we could do various things like extracting pairs. Odd length is not very suitable for this… no shit Sherlock!&lt;br /&gt;&lt;br /&gt;To make this happen we first need boolean values in the type system to represent that a proposition is actually true and we need to be able to negate them.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;blockquote&gt;&lt;font color="#ff9900"&gt;sealed&lt;/font&gt; &lt;font color="#ff9900"&gt;trait&lt;/font&gt; Bool {&lt;br /&gt;  &lt;font color="#ff9900"&gt;type&lt;/font&gt; Not &lt;: Bool&lt;br /&gt;}&lt;br /&gt;&lt;font color="#ff9900"&gt;sealed&lt;/font&gt; &lt;font color="#ff9900"&gt;trait&lt;/font&gt; True &lt;font color="#ff9900"&gt;extends&lt;/font&gt; Bool {&lt;br /&gt;  &lt;font color="#ff9900"&gt;type&lt;/font&gt; Not = False&lt;br /&gt;}&lt;br /&gt;&lt;font color="#ff9900"&gt;sealed&lt;/font&gt; &lt;font color="#ff9900"&gt;trait&lt;/font&gt; False &lt;font color="#ff9900"&gt;extends&lt;/font&gt; Bool {               &lt;br /&gt;  &lt;font color="#ff9900"&gt;type&lt;/font&gt; Not = True&lt;br /&gt;}&lt;/blockquote&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;In the next step we have to extend our type-level natural numbers. Let's give them a predecessor and a property that indicates if a number is even.&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;blockquote&gt;&lt;br /&gt;&lt;font color="#ff9900"&gt;sealed&lt;/font&gt; &lt;font color="#ff9900"&gt;trait&lt;/font&gt; Nat {&lt;br /&gt;  &lt;font color="#ff9900"&gt;type&lt;/font&gt; IsEven &lt;: Bool&lt;br /&gt;  &lt;font color="#ff9900"&gt;type&lt;/font&gt; Pred &lt;: Nat&lt;br /&gt;}&lt;br /&gt;&lt;font color="#ff9900"&gt;sealed&lt;/font&gt; &lt;font color="#ff9900"&gt;trait&lt;/font&gt; Z &lt;font color="#ff9900"&gt;extends&lt;/font&gt; Nat {&lt;br /&gt;  &lt;font color="#ff9900"&gt;type&lt;/font&gt; IsEven = True&lt;br /&gt;  &lt;font color="#ff9900"&gt;type&lt;/font&gt; Pred = Z&lt;br /&gt;}&lt;br /&gt;&lt;font color="#ff9900"&gt;sealed&lt;/font&gt; &lt;font color="#ff9900"&gt;trait&lt;/font&gt; S[A &lt;: Nat] &lt;font color="#ff9900"&gt;extends&lt;/font&gt; Nat {          &lt;br /&gt;  &lt;font color="#ff9900"&gt;type&lt;/font&gt; IsEven = A#IsEven#Not&lt;br /&gt;  &lt;font color="#ff9900"&gt;type&lt;/font&gt; Pred = A&lt;br /&gt;}&lt;br /&gt;&lt;/blockquote&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;To make it a little nicer to read and write we will add a witness that represents that a natural number is even we check this with the &lt;code&gt;=:=&lt;/code&gt; type constraint which witnesses that two types are equal.&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;blockquote&gt;&lt;br /&gt;&lt;font color="#ff9900"&gt;sealed&lt;/font&gt; &lt;font color="#ff9900"&gt;trait&lt;/font&gt; Even[A &lt;: Nat]&lt;br /&gt;&lt;font color="#ff9900"&gt;object&lt;/font&gt; Even {&lt;br /&gt;  &lt;font color="#ff9900"&gt;implicit&lt;/font&gt; &lt;font color="#ff9900"&gt;def&lt;/font&gt; isEven[A &lt;: Nat](&lt;font color="#ff9900"&gt;implicit&lt;/font&gt; e: A#IsEven =:= True): Even[A] =&lt;br /&gt;    &lt;font color="#ff9900"&gt;new&lt;/font&gt; Even[A]{}                                                                                                                           &lt;br /&gt;}&lt;br /&gt;&lt;/blockquote&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;Now the fun part. We now start building our list with a getPairs method that only works on lists with an even length. Here is our interface for this NList: &lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;blockquote&gt;&lt;br /&gt;&lt;font color="#ff9900"&gt;sealed&lt;/font&gt; &lt;font color="#ff9900"&gt;trait&lt;/font&gt; NList[A &lt;: Nat, +B] {                                                                             &lt;br /&gt;  &lt;font color="#ff9900"&gt;type&lt;/font&gt; Length = A&lt;br /&gt;  &lt;font color="#ff9900"&gt;def&lt;/font&gt; getPairs(&lt;font color="#ff9900"&gt;implicit&lt;/font&gt; e: Even[Length]): List[(B, B)]&lt;br /&gt;  &lt;font color="#ff9900"&gt;def&lt;/font&gt; head: B&lt;br /&gt;  &lt;font color="#ff9900"&gt;def&lt;/font&gt; tail: NList[Length#Pred, B]&lt;br /&gt;}&lt;br /&gt;&lt;/blockquote&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;The first case again is trivial, we are dealing with an empty list, the only thing that we can extract is an empty list.&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;blockquote&gt;&lt;br /&gt;&lt;font color="#ff9900"&gt;case&lt;/font&gt; &lt;font color="#ff9900"&gt;object&lt;/font&gt; NNil &lt;font color="#ff9900"&gt;extends&lt;/font&gt; NList[Z, Nothing] {                                      &lt;br /&gt;  &lt;font color="#ff9900"&gt;def&lt;/font&gt; getPairs(&lt;font color="#ff9900"&gt;implicit&lt;/font&gt; e: Even[Length]): List[(Nothing, Nothing)] =&lt;br /&gt;    Nil&lt;br /&gt;  &lt;font color="#ff9900"&gt;def&lt;/font&gt; head = sys.error("empty list")&lt;br /&gt;  &lt;font color="#ff9900"&gt;def&lt;/font&gt; tail = sys.error("empty list")&lt;br /&gt;}&lt;br /&gt;&lt;/blockquote&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;Now this one is a little more tricky, we might know that a natural number &lt;code&gt;A&lt;/code&gt; is even but what the typesystem does not know if &lt;code&gt;A#Pred#Pred&lt;/code&gt; is also even when we call &lt;code&gt;getPairs&lt;/code&gt; recursively. We now need to to create a witness that &lt;code&gt;A#Pred#Pred&lt;/code&gt; is even when &lt;code&gt;A&lt;/code&gt; is even. We can do this with another method that generates a witness when you hand it the witness for &lt;code&gt;A&lt;/code&gt;'s evenness, let's call that method &lt;code&gt;predPredEven&lt;/code&gt;.&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;blockquote&gt;&lt;br /&gt;&lt;font color="#ff9900"&gt;sealed&lt;/font&gt; &lt;font color="#ff9900"&gt;case&lt;/font&gt; &lt;font color="#ff9900"&gt;class&lt;/font&gt; NCons[A &lt;: Nat, B](h: B, t: NList[A, B])&lt;br /&gt;&lt;font color="#ff9900"&gt;extends&lt;/font&gt; NList[S[A], B] {&lt;br /&gt;  &lt;font color="#ff9900"&gt;private&lt;/font&gt; &lt;font color="#ff9900"&gt;def&lt;/font&gt; predPredEven[A](e: Even[Length]): Even[Length#Pred#Pred] =                                       &lt;br /&gt;    &lt;font color="#ff9900"&gt;new&lt;/font&gt; Even[Length#Pred#Pred]{}&lt;br /&gt;  &lt;font color="#ff9900"&gt;def&lt;/font&gt; getPairs(&lt;font color="#ff9900"&gt;implicit&lt;/font&gt; e: Even[Length]): List[(B, B)] =&lt;br /&gt;      (head, tail.head) :: tail.tail.getPairs(predPredEven(e))&lt;br /&gt;  &lt;font color="#ff9900"&gt;def&lt;/font&gt; head: B = h&lt;br /&gt;  &lt;font color="#ff9900"&gt;def&lt;/font&gt; tail: NList[Length#Pred, B] = t&lt;br /&gt;}&lt;br /&gt;&lt;/blockquote&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;That's all. How does this look when we put it into action?&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;blockquote&gt;&lt;br /&gt;scala&amp;gt; val lo = NCons(1, NNil)&lt;br /&gt;lo: nlist.NCons[nlist.Z,Int] = NCons(1,NNil)&lt;br /&gt;scala&amp;gt; le.getPairs&lt;br /&gt;res0: List[(Int, Int)] = List((1,2))&lt;br /&gt;scala&amp;gt; NNil.getPairs&lt;br /&gt;res1: List[(Nothing, Nothing)] = List()&lt;br /&gt;scala&amp;gt; lo.getPairs&lt;br /&gt;&lt;console&gt;:12: error: could not find implicit value for parameter e: nlist.Even[lo.Length]&lt;br /&gt;            lo.getPairs&lt;br /&gt;               ^&lt;br /&gt;&lt;/console&gt;&lt;/blockquote&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;Very nice! &lt;code&gt;getPairs&lt;/code&gt; only works on lists with an even length, otherwise we get a compile error. Once again: If you want to play with this code check out this &lt;a href="https://gist.github.com/1168922"&gt;gist&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;In future blogposts I'd like to show you how a language that bears these techniques in mind handles these problems.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8144285405079538181-1181192278170939255?l=raichoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://raichoo.blogspot.com/feeds/1181192278170939255/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8144285405079538181&amp;postID=1181192278170939255' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/1181192278170939255'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/1181192278170939255'/><link rel='alternate' type='text/html' href='http://raichoo.blogspot.com/2011/08/more-fun-with-scala-dependent-types.html' title='More Fun with Scala &quot;Dependent&quot; Types'/><author><name>Björn 'raichoo' Herzig</name><uri>https://profiles.google.com/102273886131939895778</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-KxzzpA_pbkc/AAAAAAAAAAI/AAAAAAAAARI/yHTIB2nrp8I/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8144285405079538181.post-5850487787997671544</id><published>2011-08-22T11:43:00.001-07:00</published><updated>2011-08-22T14:19:41.747-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Scala'/><title type='text'>A Taste of Dependent Types in Scala</title><content type='html'>One thing starts to cross my way very frequently is dependent typing. While I'm not an expert on this topic I found some very interesting things in various papers that I would like to be able to do in Scala. Dependent types help to verify that your program does what it's supposed to do by proving theorems.&lt;br /&gt;Since Scala is not dependently typed we need to become a little tricky, but let's give it a try.&lt;br /&gt;&lt;br /&gt;Think about the type signature of the following method called &lt;code&gt;zap&lt;/code&gt; (which stands for zip-apply):&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;&lt;blockquote&gt;def zap[A, B](l: List[A], fs: List[A =&amp;gt; B]): List[B]&lt;/blockquote&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;By looking at the signature it should become obvious what the method does. You have a list &lt;code&gt;l&lt;/code&gt; that provides elements of type &lt;code&gt;A&lt;/code&gt; and a list &lt;code&gt;fs&lt;/code&gt; that provides a function from &lt;code&gt;A&lt;/code&gt; to &lt;code&gt;B&lt;/code&gt; for each element in &lt;code&gt;l&lt;/code&gt;. Lets look at the implementation:&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;&lt;blockquote&gt;def zap[A, B](l: List[A], fs: List[A =&amp;gt; B]): List[B] =&lt;br /&gt; (l, fs) match {&lt;br /&gt;   case (_, Nil) | (Nil, _) =&amp;gt; Nil&lt;br /&gt;   case (a :: as, b :: bs)  =&amp;gt; b(a) :: zap(as, bs)&lt;br /&gt; }&lt;/blockquote&gt;  &lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;That's a pretty straight forward example, but there is a problem with this code. What if we do  provide lists with different length? In one case we would not execute some functions in the other case we would lose data. So what can we do? We could throw an exception but that's already to late, our program is already in a state where things don't make sense anymore, we have to avoid this situation at all and the best thing to achieve this is that such code does not compile at all.&lt;br /&gt;&lt;br /&gt;In a dependently typed language we could create a list that encodes it's length within the type of the list itself and write &lt;code&gt;zap&lt;/code&gt; in a way so that it would only accept lists of the same length. But since we are not in a dependently typed language we cannot do that, this concludes this blogpost, see you in another episode… ok, just kidding. We actually CAN do that in Scala. Here is how:&lt;br /&gt;&lt;br /&gt;The first thing we need is: natural numbers in the type system to encode the length of our list. That is easy:&lt;br /&gt;&lt;pre&gt;&lt;/code&gt;&lt;br /&gt;&lt;blockquote&gt;sealed trait Nat&lt;br /&gt;sealed trait Z extends Nat&lt;br /&gt;sealed trait S[A &amp;lt;: Nat] extends Nat&lt;/blockquote&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;code&gt;Z&lt;/code&gt; is our zero here and &lt;code&gt;S[A &amp;lt;: Nat]&lt;/code&gt; is the successor of the natural number &lt;code&gt;A&lt;/code&gt;, so we can create the natural numbers recursively: &lt;code&gt;Z&lt;/code&gt; == 0, &lt;code&gt;S[Z]&lt;/code&gt; == 1, &lt;code&gt;S[S[Z]]&lt;/code&gt; == 2 etc.&lt;br /&gt;&lt;br /&gt;Now let's start with the fun part, the list itself.&lt;br /&gt;&lt;br /&gt;The first thing we need is the &lt;code&gt;trait&lt;/code&gt; for our &lt;code&gt;NList&lt;/code&gt;.&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;&lt;blockquote&gt;trait NList[A &lt;: Nat, +B] {&lt;br /&gt;  type Length = A&lt;br /&gt;  def zap[C](l: NList[Length, B =&gt; C]): NList[Length, C]&lt;br /&gt;}&lt;/blockquote&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;We can now see that the type of &lt;code&gt;zap&lt;/code&gt; enforces that the both lists need to have the same length &lt;code&gt;A&lt;/code&gt;. We can now create our first case where we are zapping two lists of length 0 (or &lt;code&gt;Z&lt;/code&gt;). The implementation is rather trivial.&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;&lt;blockquote&gt;case object NNil extends NList[Z, Nothing] {&lt;br /&gt; def zap[A](l: NList[Length, Nothing =&amp;gt; A]): NNil.type =&lt;br /&gt;   NNil&lt;br /&gt;}&lt;/blockquote&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;The next case is not as simple (if someone has a better idea of how to implement this, I would love to see it. Please drop a comment).&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;&lt;blockquote&gt;case class NCons[A &lt;: Nat, B](head: B, tail: NList[A, B])&lt;br /&gt;extends NList[S[A], B] {&lt;br /&gt;  def zap[C](l: NList[Length, B =&gt; C]): NList[Length, C] = &lt;br /&gt;    l match {&lt;br /&gt;      case NCons(f, fs) =&gt;  &lt;br /&gt;        NCons(f(head), tail zap fs) &lt;br /&gt;    }   &lt;br /&gt;}&lt;/blockquote&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;We can see that our &lt;code&gt;NCons&lt;/code&gt; is actually a &lt;code&gt;NList&lt;/code&gt; that is one element longer&lt;br /&gt;than it's tail which has length &lt;code&gt;A&lt;/code&gt;, the pattern match inside our zap method only has to handle the cons case since the type signature does not allow anything else.&lt;br /&gt;&lt;br /&gt;Now let's put that little bugger to the test:&lt;br /&gt;&lt;br /&gt;First lets define some &lt;code&gt;NList&lt;/code&gt;s&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;&lt;blockquote&gt;scala&gt; val l1 = NCons(1, NCons(2, NCons(3, NNil)))&lt;br /&gt;scala&gt; val l2 = NCons(1, NCons(2, NNil))&lt;br /&gt;scala&gt; val f = (_: Int) + 1&lt;br /&gt;scala&gt; val f1 = NCons(f, NCons(f, NCons(f, NNil)))&lt;br /&gt;scala&gt; val f2 = NCons(f, NCons(f, NNil))&lt;/blockquote&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;Zapping lists with the same length:&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;&lt;blockquote&gt;scala&gt; l1 zap f1&lt;br /&gt;res1: nlist.NList[l1.Length,Int] = NCons(2,NCons(3,NCons(4,NNil)))&lt;br /&gt;&lt;br /&gt;scala&gt; l2 zap f2&lt;br /&gt;res2: nlist.NList[l2.Length,Int] = NCons(2,NCons(3,NNil))&lt;/blockquote&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;This works just fine, now lets see what happens if we &lt;code&gt;zap&lt;/code&gt; two lists with a different length:&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;&lt;blockquote&gt;scala&gt; l1 zap f2&lt;br /&gt;&lt;console&gt;:14: error: type mismatch;&lt;br /&gt; found   : nlist.NCons[nlist.S[nlist.Z],Int =&gt; Int]&lt;br /&gt; required: nlist.NList[l1.Length,Int =&gt; ?]&lt;br /&gt;              l1 zap f2&lt;/blockquote&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;Exactly what we wanted! This code does not even compile since it doesn't make any sense.&lt;br /&gt;This is a very basic example of what we can do with the Scala type system. Stay tuned for more!&lt;br /&gt;&lt;br /&gt;If you would like to play around with the code check out my &lt;a href="https://gist.github.com/1163522"&gt;gist&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8144285405079538181-5850487787997671544?l=raichoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://raichoo.blogspot.com/feeds/5850487787997671544/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8144285405079538181&amp;postID=5850487787997671544' title='2 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/5850487787997671544'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/5850487787997671544'/><link rel='alternate' type='text/html' href='http://raichoo.blogspot.com/2011/08/taste-of-dependent-types-in-scala.html' title='A Taste of Dependent Types in Scala'/><author><name>Björn 'raichoo' Herzig</name><uri>https://profiles.google.com/102273886131939895778</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-KxzzpA_pbkc/AAAAAAAAAAI/AAAAAAAAARI/yHTIB2nrp8I/s512-c/photo.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8144285405079538181.post-3964985449796648320</id><published>2011-07-10T04:08:00.000-07:00</published><updated>2011-08-20T02:26:17.526-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Scala'/><title type='text'>From Functions to Monads in Scala</title><content type='html'>"Monad" that's a word you hear quite often these days. There is a lot of unjustified FUD whenever this word pops up. People seem to be downright scared about it. You can tell by the amount of rhetorical trick words people use to scare others away from trying to understand monads at all. "Academic", "no use in real world programming" etc etc. I find it quite frustrating to hear something like that even within the Scala community from time to time (even though this is getting rarer and rarer), since these are the "arguments" people bring up when they try to scare others away from Scala.&lt;br /&gt;&lt;br /&gt;First of all, I'm not a category theorist. These things just fascinate me, and I enjoy reading about this in my free time. I'm your ordinary "Joe, the programmer" working at a small software company.&lt;br /&gt;&lt;br /&gt;Still, I find these things useful in my day job. Why? Because as a programmer I'm building mathematical machines (namely software) all day long and these concepts help me to order my thoughts and make at easier to reason about my software and design stuff.&lt;br /&gt;&lt;br /&gt;In this blogpost I want to show how to derive Monads from what you already know and give names to things you maybe never even thought about.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Categories&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Since monads come from Category Theory we first have to define what a &lt;b&gt;category&lt;/b&gt; is. &lt;br /&gt;&lt;br /&gt;A category &lt;b&gt;&lt;i&gt;C&lt;/i&gt;&lt;/b&gt; basically consists of 2 sets &lt;i&gt;ob&lt;/i&gt;(&lt;i&gt;&lt;b&gt;C&lt;/b&gt;&lt;/i&gt;) and &lt;i&gt;hom&lt;/i&gt;(&lt;i&gt;&lt;b&gt;C&lt;/b&gt;&lt;/i&gt;) where we call &lt;i&gt;ob&lt;/i&gt;(&lt;i&gt;&lt;b&gt;C&lt;/b&gt;&lt;/i&gt;) the &lt;b&gt;objects&lt;/b&gt; of &lt;b&gt;&lt;i&gt;C&lt;/i&gt;&lt;/b&gt; and &lt;i&gt;hom&lt;/i&gt;(&lt;i&gt;&lt;b&gt;C&lt;/b&gt;&lt;/i&gt;) the &lt;b&gt;morphisms&lt;/b&gt; of &lt;b&gt;&lt;i&gt;C&lt;/i&gt;&lt;/b&gt;. Morphisms are maps that go between objects.&lt;br /&gt;&lt;br /&gt;Never saw a &lt;b&gt;Category&lt;/b&gt; in your every day programming? Sure? There is a &lt;b&gt;Category&lt;/b&gt; called &lt;b&gt;&lt;i&gt;Hask&lt;/i&gt;&lt;/b&gt;, its objects are the Haskell types and its morphisms are Haskell functions. So you can think about that in a Scala context: &lt;br /&gt;&lt;br /&gt;Let &lt;code&gt;f&lt;/code&gt; be a function of type &lt;code&gt;Int =&gt; String&lt;/code&gt;. &lt;code&gt;Int&lt;/code&gt; and &lt;code&gt;String&lt;/code&gt; are both elements of &lt;i&gt;ob&lt;/i&gt;(&lt;i&gt;&lt;b&gt;C&lt;/b&gt;&lt;/i&gt;) and &lt;code&gt;f&lt;/code&gt; is an element of &lt;i&gt;hom&lt;/i&gt;(&lt;i&gt;&lt;b&gt;C&lt;/b&gt;&lt;/i&gt;).&lt;br /&gt;&lt;br /&gt;There's more to a &lt;b&gt;Category&lt;/b&gt;, we need to be able to compose morphisms and there has to be a special element called &lt;b&gt;identity&lt;/b&gt;. Lets looks at composition first.&lt;br /&gt;&lt;br /&gt;Let f and g be functions:&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;f: A =&gt; B&lt;br /&gt;g: B =&gt; C&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;We can compose those 2 functions in Scala by using the &lt;code&gt;compose&lt;/code&gt; method to get a new function.&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;g compose f // yields a function of type A =&gt; C&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;OK, that's half the rent. Now we just need the special element called &lt;b&gt;identity&lt;/b&gt; which basically is a function that does nothing. It just takes a value and returns it unmodified. So when we &lt;code&gt;compose&lt;/code&gt; a function &lt;code&gt;f&lt;/code&gt; with &lt;code&gt;identity&lt;/code&gt; we get back a function that is equivalent to &lt;code&gt;f&lt;/code&gt; and it should not matter if we compose &lt;code&gt;f&lt;/code&gt; with &lt;code&gt;identity&lt;/code&gt; or &lt;code&gt;identity&lt;/code&gt; with &lt;code&gt;f&lt;/code&gt;.&lt;br /&gt;&lt;br /&gt;In short: The following 3 functions are equivalent (which means: when fed with the same input values they will yield the exact same result)&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;f // A =&gt; B&lt;br /&gt;f compose id // A =&gt; B&lt;br /&gt;id compose f // A =&gt; B&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;Now we know that a &lt;b&gt;Category&lt;/b&gt; is (well, at least we know enough to start, a real category theorist can take you on a breathtaking journey from here :)). Let's move on!&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Enter Higher-Kinded-Types&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Next "scary word", but again: You use them all the time. First we need to know what a &lt;b&gt;kind&lt;/b&gt; is. We know what types and values are. You can think of them as levels. A value like &lt;code&gt;1&lt;/code&gt; and &lt;code&gt;x =&gt; x&lt;/code&gt; (that's a function value, yes those are values too!) live a the value level while types like &lt;code&gt;Int&lt;/code&gt; and &lt;code&gt;Int =&gt; Int&lt;/code&gt; live at the type level. We group values into types. &lt;code&gt;true&lt;/code&gt; and &lt;code&gt;false&lt;/code&gt; are both values of type &lt;code&gt;Boolean&lt;/code&gt; (think of types as sets of values).&lt;br /&gt;&lt;br /&gt;OK, if we group values into types, can we group types? Yes, we can! We can group types into… *drumroll* KINDS! Now we have a third level and our world looks something like this:&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;  kinds  &lt;br /&gt;---------&lt;br /&gt;  types&lt;br /&gt;---------&lt;br /&gt;  values&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;In most languages we only deal with one kind called &lt;code&gt;*&lt;/code&gt; (pronounced &lt;i&gt;type&lt;/i&gt;) that groups all types, but there are languages that allow infinite levels (I might cover one of them in future blog posts).&lt;br /&gt;&lt;br /&gt;We now have a basic idea of what kinds are, so what are &lt;b&gt;higher kinded types&lt;/b&gt;? Like High-Order-Functions (functions that take functions as arguments and yield functions e.g. compose)&lt;br /&gt;higher kinded types are type constructors that take types as arguments and yield types.&lt;br /&gt;&lt;br /&gt;"Wait a minute… are you talking about generics?"&lt;br /&gt;&lt;br /&gt;Yes, sort of. Think about &lt;code&gt;List&lt;/code&gt;. It's not a type by itself, you need to feed it a type as an argument to get a type. This is called a &lt;b&gt;Type Constructor&lt;/b&gt;.&lt;code&gt;List&lt;/code&gt; takes one type and returns a type, hence &lt;code&gt;List&lt;/code&gt; has the kind &lt;code&gt;* -&gt; *&lt;/code&gt; (this notation is borrowed from Haskell). The Scala notation for a higher kinded type like &lt;code&gt;List&lt;/code&gt; is &lt;code&gt;List[_]&lt;/code&gt;.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Functors&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Now that we have &lt;b&gt;higher kinded types&lt;/b&gt;, let's take a look at our functions &lt;code&gt;f&lt;/code&gt; and &lt;code&gt;g&lt;/code&gt; from the beginning and lets add a &lt;b&gt;higher kinded type&lt;/b&gt; &lt;code&gt;F[_]&lt;/code&gt; to the mix (this is Scala notation and means: takes one type and yields a type). We can now produce a whole new set of types with this higher kind (e.g. &lt;code&gt;F[Int]&lt;/code&gt;, &lt;code&gt;F[String]&lt;/code&gt; etc.). We could now create functions that work with these types… hey I know this. This sounds like… a &lt;b&gt;Category&lt;/b&gt;! Yes, it is! It's actually a &lt;b&gt;Subcategory&lt;/b&gt; of our &lt;b&gt;Hask&lt;/b&gt; &lt;b&gt;Category&lt;/b&gt; we introduced at the beginning. Let's call this new &lt;b&gt;Category&lt;/b&gt; &lt;b&gt;&lt;i&gt;D&lt;/i&gt;&lt;/b&gt; (so we don't confuse it with the &lt;b&gt;higher kinded type&lt;/b&gt; F). So elements of &lt;i&gt;ob&lt;/i&gt;(&lt;i&gt;&lt;b&gt;D&lt;/b&gt;&lt;/i&gt;) would be something like F[A] and for &lt;i&gt;hom&lt;/i&gt;(&lt;i&gt;&lt;b&gt;D&lt;/b&gt;&lt;/i&gt;) it would be something like F[A] =&gt; F[B].&lt;br /&gt;&lt;br /&gt;Now wouldn't it be cool if there was a morphism between those two categories, one that preservers composition and the identity rule? Something that could map a function of type &lt;code&gt;A =&gt; B&lt;/code&gt; to a function of type &lt;code&gt;F[A] =&gt; F[B]&lt;/code&gt;? That's what's we call a &lt;b&gt;Functor&lt;/b&gt;, it's a morphism between categories. &lt;br /&gt;&lt;br /&gt;"Why is this useful?" you might ask. Just think about the kind of code reuse you could achieve. Let's look at &lt;code&gt;Option&lt;/code&gt; as a concrete example. It's a &lt;b&gt;higher kinded type&lt;/b&gt;. So how do we map a function of type &lt;code&gt;Int =&gt; Int&lt;/code&gt; to a function of type &lt;code&gt;Option[Int] =&gt; Option[Int]&lt;/code&gt;? Can't you tell by now? The answer is the &lt;code&gt;map&lt;/code&gt; method of Option ;). &lt;br /&gt;&lt;br /&gt;Let's check it out:&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;scala&gt; val f = (_: Int) + 1&lt;br /&gt;f: (Int) =&gt; Int = &amp;lt;function1&amp;gt;&lt;br /&gt;&lt;br /&gt;scala&gt; Some(1) map f&lt;br /&gt;res0: Option[Int] = Some(2)&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;We could now reuse our function &lt;code&gt;f&lt;/code&gt; with &lt;code&gt;Option&lt;/code&gt;, there was no need to write a special version of &lt;code&gt;f&lt;/code&gt; that works with &lt;code&gt;Option&lt;/code&gt;.&lt;br /&gt;&lt;br /&gt;The second ingredient we need to make our &lt;b&gt;Functor&lt;/b&gt; complete is a morphism that maps a value of type &lt;code&gt;A&lt;/code&gt; to a value of type &lt;code&gt;F[A]&lt;/code&gt;. In the case of &lt;code&gt;Option&lt;/code&gt; this is just the factory function:&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;scala&gt; Some(_: Int)&lt;br /&gt;res0: (Int) =&gt; Some[Int] = &lt;function1&gt;&lt;br /&gt;&lt;br /&gt;scala&gt; Option(_: Int)&lt;br /&gt;res1: (Int) =&gt; Option[Int] = &lt;function1&gt;&lt;br /&gt;&lt;br /&gt;scala&gt; Option(1)&lt;br /&gt;res2: Option[Int] = Some(1)&lt;br /&gt;&lt;br /&gt;scala&gt; Some(1)&lt;br /&gt;res3: Some[Int] = Some(1)&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Endofunctors&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Now, let's assume that we want something like this:&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;scala&gt; Some(1) map {&lt;br /&gt;     | case x if x % 2 == 0 =&gt; Some("YES!")&lt;br /&gt;     | case _               =&gt; None&lt;br /&gt;     | }&lt;br /&gt;res1: Option[Option[java.lang.String]] = Some(None)&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;We want to use a function of type &lt;code&gt;Int =&gt; Option[String]&lt;/code&gt; with &lt;code&gt;Option&lt;/code&gt;'s &lt;code&gt;map&lt;/code&gt; method. But what's that? We get an &lt;code&gt;Option[Option[String]]&lt;/code&gt;. That's stupid, now I have to unpack one &lt;code&gt;Option&lt;/code&gt; to get the result I actually wanted.&lt;br /&gt;&lt;br /&gt;What happened here? Remember how we mapped a function of type &lt;code&gt;A =&gt; B&lt;/code&gt; to a function of type &lt;code&gt;F[A] =&gt; F[B]&lt;/code&gt; in the previous section about functors? What we did now is: we mapped a function of type &lt;code&gt;Int =&gt; Option[String]&lt;/code&gt; to a function of &lt;code&gt;Option[Int] =&gt; Option[Option[String]]&lt;/code&gt;. Yikes, we went a little bit over the top here, huh? We kind of like mapped something into an &lt;code&gt;Option&lt;/code&gt; and into an &lt;code&gt;Option&lt;/code&gt; this is how we ended up with an &lt;code&gt;Option[Option[String]]&lt;/code&gt;. You can think of this as a result of a composition of 2 &lt;code&gt;Option&lt;/code&gt; &lt;b&gt;Functors&lt;/b&gt;.&lt;br /&gt;&lt;br /&gt;This is a special kind of &lt;b&gt;Functor&lt;/b&gt; that maps a category into itself and is called an &lt;b&gt;Endofunctor&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Natural Transformations&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Now that we have morphisms between objects of a &lt;b&gt;Category&lt;/b&gt; which are Scala functions and &lt;b&gt;Functors&lt;/b&gt; which are basically morphisms between categories it's time to introduce morphisms between &lt;b&gt;Functors&lt;/b&gt;. &lt;br /&gt;&lt;br /&gt;Why do we need this? Well in the last example we ended up with an &lt;b&gt;Endofunctor&lt;/b&gt; (we mapped a &lt;b&gt;Category&lt;/b&gt; into itself). We need to get rid of one of the &lt;code&gt;Option&lt;/code&gt;s. We do this with a morphism that maps the composition of 2 &lt;b&gt;Functors&lt;/b&gt; &lt;i&gt;&lt;b&gt;F&lt;/b&gt;&lt;/i&gt; (&lt;i&gt;&lt;b&gt;F&lt;/b&gt;&lt;/i&gt; composed with &lt;i&gt;&lt;b&gt;F&lt;/b&gt;&lt;/i&gt;) to the &lt;b&gt;Functor&lt;/b&gt; &lt;i&gt;&lt;b&gt;F&lt;/b&gt;&lt;/i&gt;.&lt;br /&gt;&lt;br /&gt;Lets do a concrete example that involves &lt;code&gt;List&lt;/code&gt;&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;scala&gt; List(1,2,3) map { x =&gt; List(x + 1) }&lt;br /&gt;res0: List[List[Int]] = List(List(2), List(3), List(4))&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;It happened again, but this time we ended up with a &lt;code&gt;List[List[Int]]&lt;/code&gt;! We now need a &lt;b&gt;Natural Transformation&lt;/b&gt; to join those lists together, this &lt;b&gt;Natural Transformation&lt;/b&gt; is called &lt;code&gt;flatten&lt;/code&gt; in Scala.&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;scala&gt; List(1,2,3) map { x =&gt; List(x + 1) } flatten&lt;br /&gt;res1: List[Int] = List(2, 3, 4)&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;code&gt;List&lt;/code&gt; comes with a method that does both in one step, it's called &lt;code&gt;flatMap&lt;/code&gt;.&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;scala&gt; List(1,2,3) flatMap { x =&gt; List(x + 1) }&lt;br /&gt;res2: List[Int] = List(2, 3, 4)&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;This enables us to chain functions together in a very convenient way. &lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;scala&gt; Some(1) flatMap { x =&gt; Some(2) flatMap { y =&gt; Some(x + y) } }&lt;br /&gt;res3: Option[Int] = Some(3)&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;or a little more concise&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;scala&gt; Some(1) flatMap { x =&gt; Some(2) map { y =&gt; x + y } }&lt;br /&gt;res4: Option[Int] = Some(3)&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Monads&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;This is actually what makes up a &lt;b&gt;Monad&lt;/b&gt;. It's an Endofunctor with two &lt;b&gt;Natural Transformations&lt;/b&gt; called &lt;i&gt;unit&lt;/i&gt; and &lt;i&gt;join&lt;/i&gt; (which is called &lt;code&gt;flatten&lt;/code&gt; in Scala). They are such a fundamental concept that Scala features a syntactic sugar for them, the &lt;code&gt;for&lt;/code&gt;-comprehension. Do NOT confuse this with a mere &lt;code&gt;for&lt;/code&gt;-loop, this is a different animal. The last example above can be written in the following way:&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;scala&gt; for {&lt;br /&gt;     | x &lt;- Some(1)&lt;br /&gt;     | y &lt;- Some(2)&lt;br /&gt;     | } yield x + y&lt;br /&gt;res5: Option[Int] = Some(3)&lt;br /&gt;&lt;br /&gt;//translates to&lt;br /&gt;&lt;br /&gt;scala&gt; Some(1) flatMap { x =&gt; Some(2) map { y =&gt; x + y } }&lt;br /&gt;res6: Option[Int] = Some(3)&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Conclusion&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;This is an introduction on how to think about &lt;b&gt;monads&lt;/b&gt; and how to derive them from simple building blocks. They are a very powerful abstraction that pops up all the time. You use them all the time without knowing. Since programming is all about abstraction it's useful to recognize those underlying patterns. Don't let others fool you into believing that this is just some bizarre functional stuff that has no use in the real world. This is just the tip of the iceberg, an amazing journey lies ahead. Let's learn!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8144285405079538181-3964985449796648320?l=raichoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://raichoo.blogspot.com/feeds/3964985449796648320/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8144285405079538181&amp;postID=3964985449796648320' title='7 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/3964985449796648320'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/3964985449796648320'/><link rel='alternate' type='text/html' href='http://raichoo.blogspot.com/2011/07/from-functions-to-monads-in-scala.html' title='From Functions to Monads in Scala'/><author><name>Björn 'raichoo' Herzig</name><uri>https://profiles.google.com/102273886131939895778</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-KxzzpA_pbkc/AAAAAAAAAAI/AAAAAAAAARI/yHTIB2nrp8I/s512-c/photo.jpg'/></author><thr:total>7</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8144285405079538181.post-2543322074343292897</id><published>2011-07-09T05:45:00.000-07:00</published><updated>2011-07-09T15:01:08.152-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Scala'/><category scheme='http://www.blogger.com/atom/ns#' term='MacOSX'/><category scheme='http://www.blogger.com/atom/ns#' term='FreeBSD'/><category scheme='http://www.blogger.com/atom/ns#' term='JVM'/><category scheme='http://www.blogger.com/atom/ns#' term='Dtrace'/><category scheme='http://www.blogger.com/atom/ns#' term='Illumos'/><category scheme='http://www.blogger.com/atom/ns#' term='OpenIndiana'/><title type='text'>DTrace and it's impact on JVM performance</title><content type='html'>So, I did this &lt;a href="http://raichoo.blogspot.com/2011/07/dtrace-and-scala.html"&gt;blogpost&lt;/a&gt; that gave a very shallow introduction to what DTrace can do with the JVM and I got an amazing feedback after that. Actually I'm quite flattered that it had such an impact. &lt;br /&gt;&lt;br /&gt;One message I received pointed out that DTrace probes are having a significant impact on the JVM's performance, he (the author) would never recommend using the DTrace JVM integration, and then he pointed me… well, a product by his own company (which shall remain nameless, since I don't want to advertise commercial products on this blog). To be fair: I admit that I would do the same. When you put a lot of effort into a piece of software you do it for reasons you believe in.&lt;br /&gt;&lt;br /&gt;However, he gave me a link to some benchmarks that showed some impressive results and diagrams about how much the performance of the JVM suffers when DTrace probes are enabled. The bar diagrams were scary, DTrace looked pretty bad compared to the "rival" technology (you can't really call it a rival since DTrace has a completely different objective). But something was fishy about this, and that was: the axes of the diagrams were not labeled. They did show a small blue bar and a big green bar and nothing else. The code for the test case was provided as a gif (no copy and paste to reproduce the results nice and easy). Numbers were not put into any perspective. And blog comments were disabled.&lt;br /&gt;&lt;br /&gt;None the less, this was interesting enough to start a little bit of research on the topic.&lt;br /&gt;&lt;br /&gt;The benchmarks seemed to focus on how much enabled probes did slow down method calls. I personally don't like benchmarks that use extremely unrealistic cases as a foundation (look how fast I can increment them integers in a tight loop suckaz! Mah language iz teh fast!) but this time I will just go with the flow because this is pretty much what they did in that benchmark (don't try this at home kids, use realistic conditions to benchmark your stuff). I'm not using the same test code here but the idea seems to be pretty much the same.&lt;br /&gt;&lt;br /&gt;The system I'm running this on is a Thinkpad X201 with a core i7 and 8 gigs of RAM (yeah I know, I'm just compensating, get over it ;)). The operating system is OpenIndiana Build 151-beta with DTrace 1.7. Java is at 1.6.0_25.&lt;br /&gt;&lt;br /&gt;The stupid test case I will be using is this Java program:&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;class Test {&lt;br /&gt;&lt;br /&gt;  public int callTest(int i) {&lt;br /&gt;    if (i != 0)&lt;br /&gt;      callTest(i - 1);&lt;br /&gt;&lt;br /&gt;    return i;&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  public static void main(String[] args) {&lt;br /&gt;    Test t = new Test();&lt;br /&gt;&lt;br /&gt;    long starttime = System.currentTimeMillis();&lt;br /&gt;    for (int i = 0; i &lt; 1000000; i++)&lt;br /&gt;      callTest(100)&lt;br /&gt;    long endtime = System.currentTimeMillis();&lt;br /&gt;&lt;br /&gt;    System.out.println(endtime - starttime);&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;Once again, this is not a realistic example. I will just use it to demonstrate that there really is an impact.&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;&gt; java Test&lt;br /&gt;118&lt;br /&gt;&gt; java -XX:+ExtendedDTraceProbes Test&lt;br /&gt;4106&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;Wow, this really seems to hurt… the programm is about 35 times slower with DTrace probes enabled.&lt;br /&gt;&lt;br /&gt;To put this into perspective I will commit a capital crime in programming. I will compare this stupid program in language A to the same stupid program written in language B. Let language B be Python in this case. To be crystal clear about this: this is NOT a comparison of Python and Java performance. I just need some landmarks to make all those numbers meaningful (at least to some extent since this is a very badly chosen scenario to begin with).&lt;br /&gt;&lt;br /&gt;Here is our Python test case.&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;import time                                                                     &lt;br /&gt;&lt;br /&gt;def callTest(i):&lt;br /&gt;  if not i == 0:&lt;br /&gt;    callTest(i - 1)&lt;br /&gt;&lt;br /&gt;  return i&lt;br /&gt;&lt;br /&gt;r = range(0,1000000)&lt;br /&gt;&lt;br /&gt;starttime = time.time()&lt;br /&gt;&lt;br /&gt;for i in r:&lt;br /&gt;  callTest(100)&lt;br /&gt;&lt;br /&gt;endtime = time.time()&lt;br /&gt;print (endtime - starttime)&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;And the result:&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;&gt; python test.py&lt;br /&gt;21.9892270565&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;OK, our software runs slower with probes enabled, but we are still faster than Python and Python's performance is acceptable for a lot of use cases. We now have a slower JVM that can be instrumented. So I'd say: No real harm done.&lt;br /&gt;&lt;br /&gt;Now let's use those probes and aggregate some real data. For this test I will use a slightly modified version of &lt;code&gt;j_methodcalls.d&lt;/code&gt;, a script by &lt;a href="http://twitter.com/brendangregg"&gt;Brendan Gregg&lt;/a&gt; that is shipped with the &lt;a href="http://hub.opensolaris.org/bin/view/Community+Group+dtrace/dtracetoolkit"&gt;DTrace Toolkit&lt;/a&gt;. &lt;font color="red"&gt;The script is licensed under &lt;a href="http://opensource.org/licenses/CDDL-1.0"&gt;CDDL&lt;/a&gt;&lt;/font&gt; but I did remove the license header here to make it more concise and blog-friendly.&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;#!/usr/sbin/dtrace -Zs                                                          &lt;br /&gt;&lt;br /&gt;hotspot$target:::method-entry&lt;br /&gt;{&lt;br /&gt;  this-&gt;class = (char *)copyin(arg1, arg2 + 1); &lt;br /&gt;  this-&gt;class[arg2] = '\0';&lt;br /&gt;  this-&gt;method = (char *)copyin(arg3, arg4 + 1); &lt;br /&gt;  this-&gt;method[arg4] = '\0';&lt;br /&gt;  this-&gt;name = strjoin(strjoin(stringof(this-&gt;class), "."),&lt;br /&gt;                       stringof(this-&gt;method));&lt;br /&gt;  @calls[pid, this-&gt;name] = count();&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;Let's run it!&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;&gt; pfexec ./j_methodcalls.d -c "java -XX:+ExtendedDTraceProbes Test"&lt;br /&gt;[…snip…]&lt;br /&gt;249126&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;OK, this is A LOT slower, even slower than Python. 4 Minutes!&lt;br /&gt;&lt;br /&gt;We are now aggregating data and that means we are copying data from userspace into kernelspace from where it can be fetched by DTrace consumers (in our case the &lt;code&gt;dtrace&lt;/code&gt; command line tool). What data did we get in this amount of time? Actually: A LOT. It flooded my terminal and I had to pipe the result into &lt;code&gt;less&lt;/code&gt; to be able to read all of it. DTrace recorded every method call that happened in the JVM while the program was running. It counted the calls per method, and the class the method belongs to. Keep in mind that we did not need to modify our code to get these results. We don't even need to restart a running JVM to enable the probes we can activate them by using the &lt;code&gt;jinfo&lt;/code&gt; command. And we could have used DTrace to gather system wide data in the same script (something I might demonstrate sometime on this blog)&lt;br /&gt;&lt;br /&gt;Now lets use the most naive debugging technique on earth. We will print out "CALLED!" every time our &lt;code&gt;callTest&lt;/code&gt; method gets called (if you ever did this before you know how disastrous the result well be). This gives us pretty much no information. We just know that a particular method has been called and we need to modify our code, recompile and load it into running JVM. &lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;&gt; time java Test&lt;br /&gt;[…snip…]&lt;br /&gt;CALLED!&lt;br /&gt;5958514&lt;br /&gt;&lt;br /&gt;real 1h39m18.15s&lt;br /&gt;user 3m53.29s&lt;br /&gt;sys 7m55.68s&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;As we expected, the result is a disaster. Calling print in a tight loop is an extremely stupid thing to do. We could have used a counter that get incremented with every method call, proxy objects, interceptors etc. (all of them would have been significantly faster).&lt;br /&gt;&lt;br /&gt;To do something similar like the print example with DTrace I just a another clause to the script:&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;tick-1s {&lt;br /&gt;  printa(@calls);&lt;br /&gt;  trunc(@calls);&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;This addition prints out what happened in 1 second intervals&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;  1  75779               :tick-1s &lt;br /&gt;     4028  Test.callTest          400379&lt;br /&gt;&lt;br /&gt;  1  75779               :tick-1s &lt;br /&gt;     4028  Test.callTest          404720&lt;br /&gt;&lt;br /&gt;  1  75779               :tick-1s &lt;br /&gt;     4028  Test.callTest          402135&lt;br /&gt;&lt;br /&gt;  1  75779               :tick-1s&lt;br /&gt;     4028  Test.callTest          398934&lt;br /&gt;&lt;br /&gt;253064&lt;br /&gt;dtrace: pid 4028 has exited&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;real 4m14.23s&lt;br /&gt;user 4m13.89s&lt;br /&gt;sys 0m0.46s&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;The performance impact stays pretty much the same with DTrace, we are done in 4 Minutes while we are presented with a readable stream of information.&lt;br /&gt;&lt;br /&gt;There are a lot of ways to generate similar data, but most of them require code changes, are not able to do system wide tracing, are limited to one process and/or just one specific runtime.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Conclusion&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Tracing the JVM costs (this shows especially in this pathological use case), but DTrace provides us with a very broad spectrum of probes. The JVM ones are just one source of data. We can actually instrument every part of the system with our DTrace script. Maybe a problem is not even related to our program at all, maybe it's NFS misbehaving, something is wrong with the database or there is some heavy IO going on. With DTrace the whole system becomes transparent. This changes the whole "blame game" and that's the whole point of DTrace. Looking at the system as a whole.&lt;br /&gt;&lt;br /&gt;The bottom line is: trace the JVM only if you need to and be aware of the performance impact. This tool is for hunting down problems that are very hard or even impossible to analyze with traditional tools. I did use it to trace obscure memory leaks and dead-locks (both in non-Java contexts) and I was able to exactly pinpoint the culprit.&lt;br /&gt;&lt;br /&gt;Don't use DTrace when there is a tool that does a better job for this specific task. Use it wisely. Anyway, it's a great utility to have in your toolbox.&lt;br /&gt;&lt;br /&gt;Last but not least: use realistic use cases for benchmarking, label your diagram axes, and compare tools that have the same objective.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8144285405079538181-2543322074343292897?l=raichoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://raichoo.blogspot.com/feeds/2543322074343292897/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8144285405079538181&amp;postID=2543322074343292897' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/2543322074343292897'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/2543322074343292897'/><link rel='alternate' type='text/html' href='http://raichoo.blogspot.com/2011/07/dtrace-and-its-impact-on-jvm.html' title='DTrace and it&apos;s impact on JVM performance'/><author><name>Björn 'raichoo' Herzig</name><uri>https://profiles.google.com/102273886131939895778</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-KxzzpA_pbkc/AAAAAAAAAAI/AAAAAAAAARI/yHTIB2nrp8I/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8144285405079538181.post-980040917390959366</id><published>2011-07-06T11:48:00.000-07:00</published><updated>2011-07-06T14:15:07.284-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Scala'/><category scheme='http://www.blogger.com/atom/ns#' term='MacOSX'/><category scheme='http://www.blogger.com/atom/ns#' term='FreeBSD'/><category scheme='http://www.blogger.com/atom/ns#' term='Dtrace'/><category scheme='http://www.blogger.com/atom/ns#' term='Illumos'/><category scheme='http://www.blogger.com/atom/ns#' term='OpenIndiana'/><title type='text'>DTrace and Scala</title><content type='html'>&lt;a href="http://en.wikipedia.org/wiki/DTrace"&gt;DTrace&lt;/a&gt; is one of my favorite technologies ever, it absolutely redefined my view on software and how it can be debugged. In a lot of situations you are basically forced to debug your software by vomiting print-statements just all over the place. To make things worse you have to take them out when you are actually shipping your software, leaving you blind to errors to come. In other cases you probably are missing some print-statements to trace down a very nasty bug, or the bug is hidden in some 3rd-party lib that would take hours to recompile with your new print statement (don't start thinking about libs that you don't have the code of…). In most cases this can become a very unpleasant situation (to put it mildly). DTrace takes a lot of the hassle away by providing you with a mechanism that can modify your program while it's running without stopping it.&lt;br /&gt;Pretty amazing, huh? Wait, it gets better. You can even trace into the runtime of some high level languages (if they provide the probes). This is also true for the JVM, and that means we can instrument a running Scala program.&lt;br /&gt;&lt;br /&gt;In this post I will walk you through a very basic script that shows what methods from &lt;code&gt;Predef&lt;/code&gt; get called by your program. DTrace is a tool that reaches deep down into  the lower levels of your machine. Sounds scary? Nah not really, one of the design goals of DTrace is safety. Your scripts run in a managed environment that keeps it from doing harmful things.&lt;br /&gt;&lt;br /&gt;OK, enough sweet-talk. Time to get our hands dirty by writing a very simple Scala program:&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;import scala.annotation.tailrec&lt;br /&gt;&lt;br /&gt;object Main {&lt;br /&gt;  @tailrec&lt;br /&gt;  def sayHallo() {&lt;br /&gt;    println("HALLO!")&lt;br /&gt;    Thread.sleep(1000)&lt;br /&gt;    sayHallo()&lt;br /&gt;  }&lt;br /&gt;                                                                                &lt;br /&gt;  def main(args: Array[String]) {&lt;br /&gt;    sayHallo()&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;This just prints out "HALLO!" in 1 second intervals (not exactly rocket science, but I put a little sugar on top of it by replacing the while loop with a tail recursive function for fun and profit).&lt;br /&gt;&lt;br /&gt;What's that? When running my program DTrace is not showing me ANY probes!!?!?! FFFFUUUUUUUU! That's because we have to enable them first, we can instruct a running JVM to do this by using &lt;code&gt;jinfo&lt;/code&gt;. Since I only got one JVM running on this box I will fetch the PID with &lt;code&gt;pgrep&lt;/code&gt;.&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;jinfo -flag +ExtendedDTraceProbes $(pgrep java)&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;The JVM probes are now armed and "dangerous" (just kiddin') and you will have access to the &lt;code&gt;hotspot&lt;/code&gt; provider.&lt;br /&gt;&lt;br /&gt;Now lets write the DTrace script. Keep in mind: this script is running in kernel space, so we have to copy in some information from userspace, we do this by using &lt;code&gt;copyin&lt;/code&gt; and we have to &lt;code&gt;NULL&lt;/code&gt;-terminate the strings ourselves. Yep, this is what it feels like to program low-level stuff, it's not as pretty as FP but aaaaaaaaaanyway, here is the little bugger.&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;#!/usr/sbin/dtrace -s                                                           &lt;br /&gt;&lt;br /&gt;#pragma D option quiet&lt;br /&gt;&lt;br /&gt;hotspot$$target:::method-entry&lt;br /&gt;{&lt;br /&gt;  this-&gt;class = (char *) copyin(arg1, arg2 + 1); &lt;br /&gt;  this-&gt;class[arg2] = '\0';&lt;br /&gt;  self-&gt;tracefunc = stringof(this-&gt;class);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;hotspot$$target:::method-entry&lt;br /&gt;/self-&gt;tracefunc == "scala/Predef$"/&lt;br /&gt;{&lt;br /&gt;  this-&gt;method = (char *) copyin(arg3, arg4 + 1); &lt;br /&gt;  this-&gt;method[arg4] = '\0';&lt;br /&gt;  printf("%s %Y\n", stringof(this-&gt;method), walltimestamp);&lt;br /&gt;  self-&gt;tracefunc = 0;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;hotspot$$target:::method-entry&lt;br /&gt;/self-&gt;tracefunc/&lt;br /&gt;{&lt;br /&gt;  self-&gt;tracefunc = 0;&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;This thing will fire whenever a function from &lt;code&gt;Predef&lt;/code&gt; is called and will give us the function name (in our test case this is just &lt;code&gt;println&lt;/code&gt;) and the time when this function was being called. I run this on &lt;a href="http://www.openindiana.org"&gt;OpenIndiana&lt;/a&gt; build151-beta by issuing &lt;code&gt;pfexec dtrace ./tracescript.d -p $(pgrep java)&lt;/code&gt; after I enabled the &lt;code&gt;hotspot&lt;/code&gt; provider on the JVM. (&lt;code&gt;pfexec&lt;/code&gt; is kind of like &lt;code&gt;sudo&lt;/code&gt;, just use whatever gives you the permission to run &lt;code&gt;dtrace&lt;/code&gt; on your box)&lt;br /&gt;The output will look like this:&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;println 2011 Jul  6 21:27:34&lt;br /&gt;println 2011 Jul  6 21:27:35&lt;br /&gt;println 2011 Jul  6 21:27:36&lt;br /&gt;println 2011 Jul  6 21:27:37&lt;br /&gt;println 2011 Jul  6 21:27:38&lt;br /&gt;println 2011 Jul  6 21:27:39&lt;br /&gt;println 2011 Jul  6 21:27:40&lt;br /&gt;println 2011 Jul  6 21:27:41&lt;br /&gt;println 2011 Jul  6 21:27:42&lt;br /&gt;println 2011 Jul  6 21:27:43&lt;br /&gt;println 2011 Jul  6 21:27:44&lt;br /&gt;println 2011 Jul  6 21:27:45&lt;br /&gt;println 2011 Jul  6 21:27:46&lt;br /&gt;println 2011 Jul  6 21:27:47&lt;br /&gt;println 2011 Jul  6 21:27:48&lt;br /&gt;println 2011 Jul  6 21:27:49&lt;br /&gt;println 2011 Jul  6 21:27:50&lt;br /&gt;println 2011 Jul  6 21:27:51&lt;br /&gt;println 2011 Jul  6 21:27:52&lt;br /&gt;println 2011 Jul  6 21:27:53&lt;br /&gt;println 2011 Jul  6 21:27:54&lt;br /&gt;println 2011 Jul  6 21:27:55&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;WTF IS THIS I DON'T EVEN!?!?!? TL;DR&lt;br /&gt;&lt;br /&gt;OK, this is not even the tip of the iceberg but I think I will wrap it up because there is a lot of ground to cover when it comes to DTrace. If you are hungry for more you should check out the "&lt;a href="http://www.youtube.com/watch?v=6chLw2aodYQ"&gt;DTrace Review&lt;/a&gt;" by &lt;a href="http://twitter.com/bcantrill"&gt;@bcantrill&lt;/a&gt;, this stuff will blow your mind (seriously, WATCH IT!) or buy the &lt;a href="http://www.amazon.com/DTrace-Dynamic-Tracing-Solaris-FreeBSD/dp/0132091518/ref=sr_1_1?ie=UTF8&amp;qid=1309980847&amp;sr=8-1"&gt;book&lt;/a&gt; by &lt;a href="http://twitter.com/brendangregg"&gt;@brendangregg&lt;/a&gt;. I will make sure to dig deeper on the topic, so stay tuned. Tell me what you think, good tool or best tool? :P&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8144285405079538181-980040917390959366?l=raichoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://raichoo.blogspot.com/feeds/980040917390959366/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8144285405079538181&amp;postID=980040917390959366' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/980040917390959366'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/980040917390959366'/><link rel='alternate' type='text/html' href='http://raichoo.blogspot.com/2011/07/dtrace-and-scala.html' title='DTrace and Scala'/><author><name>Björn 'raichoo' Herzig</name><uri>https://profiles.google.com/102273886131939895778</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-KxzzpA_pbkc/AAAAAAAAAAI/AAAAAAAAARI/yHTIB2nrp8I/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8144285405079538181.post-16524206348715226</id><published>2011-07-06T10:56:00.000-07:00</published><updated>2011-07-06T15:01:53.638-07:00</updated><title type='text'>English, please!</title><content type='html'>It took me quite some time to make up my mind about this… should I switch the language of this blog to English or should leave it just the way it is. I think it's worth to give this a try, since twitter brought me towards a mostly non-German audience which I also would like to address. This is also a great opportunity to polish my language skills a little since they got kind of neglected in the last few years (so bear with me ;)&lt;br /&gt;&lt;br /&gt;So, to all my new readers, here is a little overview on what this blog is about. I work as a developer at a German software company so quite a lot of stuff you will find here will focus on programming and debugging. In my free time I like to play around with different operating systems (mainly &lt;a href="http://www.illumos.org"&gt;Illumos&lt;/a&gt;, &lt;a href="http://www.freebsd.org"&gt;FreeBSD&lt;/a&gt; and &lt;a href="http://www.dragonflybsd.org"&gt;DragonFlyBSD&lt;/a&gt;) so this place will be stuffed with information about OS specific wizardry :3&lt;br /&gt;&lt;br /&gt;OK, folks! Let's give this a shot!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8144285405079538181-16524206348715226?l=raichoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://raichoo.blogspot.com/feeds/16524206348715226/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8144285405079538181&amp;postID=16524206348715226' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/16524206348715226'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/16524206348715226'/><link rel='alternate' type='text/html' href='http://raichoo.blogspot.com/2011/07/english-please.html' title='English, please!'/><author><name>Björn 'raichoo' Herzig</name><uri>https://profiles.google.com/102273886131939895778</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-KxzzpA_pbkc/AAAAAAAAAAI/AAAAAAAAARI/yHTIB2nrp8I/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8144285405079538181.post-3872481708668722928</id><published>2011-02-23T05:30:00.001-08:00</published><updated>2011-02-23T13:51:27.318-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Scala'/><category scheme='http://www.blogger.com/atom/ns#' term='Clojure'/><title type='text'>Dynamic-Dispatch in Scala</title><content type='html'>Ich bin ja hin und wieder schon mal richtig neidisch auf &lt;a href="http://clojure.org/multimethods"&gt;Clojures Multimethods&lt;/a&gt;, möchte aber nicht wirklich meine statisch typisierte Welt verlassen (auch wenn Clojure vermutlich die einzige Sprache wäre die ich von allen dynamischen Sprachen wählen würde).&lt;br /&gt;&lt;br /&gt;Lange Rede, kurzer Unsinn: Ich will Multimethods in Scala! Auf den ersten Blick klingt das als würde man sich eine Sprache zu etwas hinbiegen wollen was sie gar nicht ist, aber in Scala geht das ganze erschreckend schmerzlos.&lt;br /&gt;&lt;br /&gt;Zum dispatchen verwende ich einfach ein paar partielle Funktionen die man mit &lt;code&gt;orElse&lt;/code&gt; beliebig aneinanderketten kann. Der Vorteil davon ist das ich keinen Code aufmachen muss wenn ich einen weiteren Fall hinzufügen will sondern durch Komposition zum Ziel komme.&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;trait Dynamic&lt;br /&gt;&lt;br /&gt;class A extends Dynamic&lt;br /&gt;class B extends Dynamic&lt;br /&gt;&lt;br /&gt;object Dynamic {&lt;br /&gt;  // 2 dynamische argumente&lt;br /&gt;  type Dyn2 = (Dynamic, Dynamic)&lt;br /&gt;&lt;br /&gt;  // infix notation fuer PartialFunction&lt;br /&gt;  type ~&gt;[A, B] = PartialFunction[A, B]&lt;br /&gt;                                                                             &lt;br /&gt;  val f: Dyn2 ~&gt; String = {&lt;br /&gt;    case (a: A, b: A) =&gt; "A A"&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  val g: Dyn2 ~&gt; String = {&lt;br /&gt;    case (a: A, b: B) =&gt; "A B"&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  // d ist die dispatchfunktion&lt;br /&gt;  def dispatch[A, B](d: A ~&gt; B, a: A): Option[B] =&lt;br /&gt;    if (d.isDefinedAt(a)) Some(d(a))&lt;br /&gt;    else None&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;In Aktion sieht das Ganze so aus:&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;&lt;br /&gt;scala&gt; :l ./dynamic.scala                                            &lt;br /&gt;Loading ./dynamic.scala...&lt;br /&gt;defined trait Dynamic&lt;br /&gt;defined class A&lt;br /&gt;defined class B&lt;br /&gt;defined module Dynamic&lt;br /&gt;&lt;br /&gt;scala&gt; import Dynamic._&lt;br /&gt;import Dynamic._&lt;br /&gt;&lt;br /&gt;scala&gt; dispatch(f, (new A, new A))&lt;br /&gt;res0: Option[String] = Some(A A)&lt;br /&gt;&lt;br /&gt;scala&gt; dispatch(f, (new A, new B))&lt;br /&gt;res1: Option[String] = None&lt;br /&gt;&lt;br /&gt;scala&gt; dispatch(f orElse g, (new A, new B))&lt;br /&gt;res2: Option[String] = Some(A B)&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;Wie man schön sehen kann werden auch die nicht abgedeckten Fälle behandelt indem wir einfach eine &lt;code&gt;Option &lt;/code&gt; verwenden, dadurch könnten wir unseren Dispatch auch in einer &lt;code&gt;for&lt;/code&gt;-Comprehension verwenden (Monaden für den Gewinn!)&lt;br /&gt;&lt;br /&gt;Viel Spass beim ausprobieren ;)&lt;br /&gt;&lt;br /&gt;Hier &lt;a href="http://nice.sourceforge.net/visitor.html"&gt;ein kleiner Nachtra&lt;/a&gt;g wozu Multimethods gut sind. Für alle die Das Visitorpattern schon immer gehasst haben ;)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8144285405079538181-3872481708668722928?l=raichoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://raichoo.blogspot.com/feeds/3872481708668722928/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8144285405079538181&amp;postID=3872481708668722928' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/3872481708668722928'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/3872481708668722928'/><link rel='alternate' type='text/html' href='http://raichoo.blogspot.com/2011/02/dynamic-dispatch-in-scala.html' title='Dynamic-Dispatch in Scala'/><author><name>Björn 'raichoo' Herzig</name><uri>https://profiles.google.com/102273886131939895778</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-KxzzpA_pbkc/AAAAAAAAAAI/AAAAAAAAARI/yHTIB2nrp8I/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8144285405079538181.post-7977571351272280669</id><published>2011-02-21T13:54:00.000-08:00</published><updated>2011-02-21T14:14:04.542-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Scala'/><category scheme='http://www.blogger.com/atom/ns#' term='OCaml'/><title type='text'>Scala: Besseres Pattern-Matching mit Sealed Classes</title><content type='html'>Neulich bin ich auf eine &lt;a href="http://www.mail-archive.com/jvm-languages@googlegroups.com/msg00121.html"&gt;recht interessante Mai&lt;/a&gt;l in der jvm-languages Google Group gestossen. Ein Vergleich von Scala und OCaml! Wie spannend!&lt;br /&gt;Besonders interessant fand ich folgendes Beispiel:&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;# let foo = function&lt;br /&gt;    | true, _ -&gt; 0&lt;br /&gt;    | _, false -&gt; 1;; &lt;br /&gt;Warning P: this pattern-matching is not exhaustive.&lt;br /&gt;Here is an example of a value that is not matched:&lt;br /&gt;(false, true)&lt;br /&gt;val foo : bool * bool -&gt; int = &lt;fun&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;OCaml liefert hier beim kompilieren einen Fehler: Das Patternmatching würde nicht alle Möglichkeiten erschöpfen. Zusätzlich bekommt man noch ein Beispiel wo der Match fehlschlägt. Tolle Sache! Das Scala Beispiel sieht hier doch eher ernüchternd aus.&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;scala&gt; def foo(b: (Boolean, Boolean)): Int = b match {&lt;br /&gt;     |   case (true, _) =&gt; 0&lt;br /&gt;     |   case (_, false) =&gt; 0&lt;br /&gt;     | }&lt;br /&gt;foo: ((Boolean, Boolean))Int&lt;br /&gt;&lt;br /&gt;scala&gt; foo(false, true)&lt;br /&gt;scala.MatchError: (false,true)&lt;br /&gt;   at .foo(&lt;console&gt;:4)&lt;br /&gt;   at .&lt;init&gt;(&lt;console&gt;:5)&lt;br /&gt;   at .&lt;clinit&gt;(&lt;console&gt;)&lt;br /&gt;   at java.lang.Class.initializeClass(libgcj.so.81)&lt;br /&gt;   at RequestResult$.&lt;init&gt;(&lt;console&gt;:3)&lt;br /&gt;   at RequestResult$.&lt;clinit&gt;(&lt;console&gt;)&lt;br /&gt;   at java.lang.Class.initializeClass(libgcj.so.81)&lt;br /&gt;   at RequestResult$result(&lt;console&gt;)&lt;br /&gt;   at java.lang.reflect.Method.invoke(libgcj.so.81)&lt;br /&gt;  ...&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;Anscheinend ist Scala wohl nicht in der Lage herauszufinden welche Fälle möglich sind und kann so nicht testen ob das Matching auch wirklich alle Möglichkeiten ausschöpft. Aber genau dieser Effekt lässt sich mit Sealed Classes erreichen.&lt;br /&gt;&lt;br /&gt;Als Beispiel definiere ich einen eigenen Booltypen mit einem Subtypen für jeweils true und false (ich nehme hier Objects da wir nicht mehr als eine Instanz von True bzw. False brauchen). Das gleiche Beispiel schlägt hier mit einer ähnlichen Fehlermeldung wie bei OCaml fehl:&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;abstract sealed class MyBool&lt;br /&gt;case object True extends MyBool&lt;br /&gt;case object False extends MyBool&lt;br /&gt;&lt;br /&gt;object MyBool {&lt;br /&gt;  def test(a: (MyBool, MyBool)): Unit = a match {&lt;br /&gt;    case (True, _) =&gt; ()&lt;br /&gt;    case (_, False) =&gt; ()&lt;br /&gt;  }&lt;br /&gt;} &lt;br /&gt;&lt;br /&gt;MyBool.scala:6: warning: match is not exhaustive!&lt;br /&gt;missing combination          False          True&lt;br /&gt;&lt;br /&gt;  def test(a: (MyBool, MyBool)): Unit = a match {&lt;br /&gt;      ^&lt;br /&gt;one warning found&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;Die Sealed Class hat zur Folge das wir keine weiteren Subtypen außerhalb unser Quelldatei anlegen können, der Compiler hat jetzt also alle Information die er braucht um den Match zu prüfen.&lt;br /&gt;&lt;br /&gt;Mehr zum diesem Thema gibt es wieder mal &lt;a href="http://gleichmann.wordpress.com/2011/02/05/functional-scala-algebraic-datatypes-sum-and-product-types/"&gt;bei Mario Gleichmann&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8144285405079538181-7977571351272280669?l=raichoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://raichoo.blogspot.com/feeds/7977571351272280669/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8144285405079538181&amp;postID=7977571351272280669' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/7977571351272280669'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/7977571351272280669'/><link rel='alternate' type='text/html' href='http://raichoo.blogspot.com/2011/02/scala-besseres-pattern-matching-mit.html' title='Scala: Besseres Pattern-Matching mit Sealed Classes'/><author><name>Björn 'raichoo' Herzig</name><uri>https://profiles.google.com/102273886131939895778</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-KxzzpA_pbkc/AAAAAAAAAAI/AAAAAAAAARI/yHTIB2nrp8I/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8144285405079538181.post-2497218615390195664</id><published>2011-01-31T10:36:00.000-08:00</published><updated>2011-01-31T11:09:00.873-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Scala'/><title type='text'>Scala: Spass mit Streams</title><content type='html'>Ich wurde ja neulich mal gefragt ob ich mal was über Streams in Scala bloggen könnte (auch wenn es hier eher um IO ging). Da mir da allerdings ein gutes Beispiel gefehlt hat, habe ich das erst einmal auf die lange Bank geschoben (irgendwie blogge ich derzeit glaub ich etwas zu wenig :/).&lt;br /&gt;&lt;br /&gt;Aber ok, dank eines &lt;a href="http://gleichmann.wordpress.com/2011/01/30/functional-scala-algebraic-datatypes-enumerated-types/"&gt;hervorragenden Posts von Mario Gleichmann&lt;/a&gt; bin ich dann doch noch auf eine ganz brauchbare Idee gekommen. (Schon allein Vollständigkeit halber empfehle ich den Post von Mario zu lesen!)&lt;br /&gt;&lt;br /&gt;Im folgenden Code geht es einfach nur darum die nachfolgende Jahreszeit zu bestimmen.&lt;br /&gt;&lt;code&gt;&lt;pre&gt;&lt;br /&gt;sealed abstract class Season&lt;br /&gt;case object Spring extends Season&lt;br /&gt;case object Summer extends Season&lt;br /&gt;case object Fall extends Season&lt;br /&gt;case object Winter extends Season&lt;br /&gt;&lt;br /&gt;object Main {&lt;br /&gt;  lazy val seasons: Stream[Season] =&lt;br /&gt;    Spring #:: Summer #:: Fall #:: Winter #:: seasons&lt;br /&gt;&lt;br /&gt;  def nextSeason(now: Season): Season = {&lt;br /&gt;    @scala.annotation.tailrec&lt;br /&gt;    def getNextFromStream(s: Stream[Season]): Season =                                                                                              &lt;br /&gt;      s match {&lt;br /&gt;        case a @ x #:: y #:: _ =&gt;&lt;br /&gt;          if (now eq x)&lt;br /&gt;            y&lt;br /&gt;          else&lt;br /&gt;            getNextFromStream(a tail)&lt;br /&gt;      }&lt;br /&gt;    getNextFromStream(seasons)&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  def main(args: Array[String]): Unit = { &lt;br /&gt;    println(nextSeason(Spring))&lt;br /&gt;    println(nextSeason(Summer))&lt;br /&gt;    println(nextSeason(Fall))&lt;br /&gt;    println(nextSeason(Winter))&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;Um die Jahreszeiten abzubilden nutze ich hier einen Stream (also eine unendliche Liste) die ich rekursiv durchgehe bis ich die aktuelle Jahreszeit gefunden habe und einfach die Nächste ausgebe.&lt;br /&gt;&lt;br /&gt;Dieses Beispiel wirkt zugegebenermaßen etwas wie mit Kanonen auf Spatzen zu schiessen, zeigt aber die Ausdrucksstärke von Streams und Lazy-Evaluation. Ein sehr realer Anwendungsfall ist hier z.B. ein Roundrobin-Verfahren. Anstelle also stumpf eine Liste durchzugehen und am Ende wieder an den Anfang springen in Zukunft einfach mal über einen Stream nachdenken ;)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8144285405079538181-2497218615390195664?l=raichoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://raichoo.blogspot.com/feeds/2497218615390195664/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8144285405079538181&amp;postID=2497218615390195664' title='4 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/2497218615390195664'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/2497218615390195664'/><link rel='alternate' type='text/html' href='http://raichoo.blogspot.com/2011/01/scala-spass-mit-streams.html' title='Scala: Spass mit Streams'/><author><name>Björn 'raichoo' Herzig</name><uri>https://profiles.google.com/102273886131939895778</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-KxzzpA_pbkc/AAAAAAAAAAI/AAAAAAAAARI/yHTIB2nrp8I/s512-c/photo.jpg'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8144285405079538181.post-7778315490826873457</id><published>2010-12-25T05:57:00.000-08:00</published><updated>2010-12-25T07:06:39.077-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='MacOSX'/><title type='text'>Die Sache mit Apple</title><content type='html'>"Hallo, ich bin raichoo und ich habe ein MacBook". Das sind Sätze mit denen man in vielen Kreisen schnell Freunde finden kann (Vorsicht Ironie!). Aber mal ehrlich, in den letzten Tagen kann man sich besonders schöne Kommentare gefallen lassen. Mein Favorit ist hier "Apfelnazi" (Goodwin's Law lässt grüßen). Die Diskussionskultur lässt hier ziemlich zu wünschen übrig, wer Leute nach dem Betriebssystem beurteilt hat in meinen Augen doch eher einen massiven Schaden.&lt;br /&gt;&lt;br /&gt;Aber was bewegt die Leute dazu so zu reagieren? Auf der einen Seite mag das ganze auf einem pseudoelitären Gefühl basieren. Apple ist Mainstream. Gegen Mainstream sein ist rebellisch, cool und was weiß ich noch alles. Ich bin ja selber keine Ausnahme, meine Lebensweise ist sicherlich nicht die eines Ottonormalverbrauchers. Aber diese extremen Anfeindungen gehen doch echt schon zu weit.&lt;br /&gt;Doch zurück zu den Beweggründen. Wikileaks ist im Moment sicherlich ein sehr bewegendes Thema, und das Verhalten vieler Firmen wie Visa, Paypal, Mastercard und auch Apple ist nicht nur verwerflich, es ist in meinen Augen auch undemokratisch.&lt;br /&gt;Was also machen? Boykottieren? Guter Plan, Boykott war immer schon die wirksamste Waffe des Verbrauchers, denkt man sich. Die Problematik die sich hieraus aber ergibt ist folgende: der überwiegende Großteil der Firmen wird so reagieren. Ein bisschen Druck vom Staat eventuell noch ein paar Zuwendungen unter der Hand und schon wird der Stecker gezogen. Unsere Freiheit wird also potentiell von jeder Firma beschnitten die nur den nötigen Einfluss hat, oben genannte Beispiele befinden sich nur gerade in dieser Situation besonders in so einer Position. Man kann sich also praktisch totboykottieren, der Hydra wachsen die Köpfe einfach nach.&lt;br /&gt;&lt;br /&gt;Wie also reagieren? Alle Apple Produkte aus dem Fenster werfen in den nächsten Mediamarkt rennen, ein Plastikwaffeleisen kaufen das nach einem Jahr auseinanderfällt und Ubuntu installieren? Ich sag es ehrlich: Linux ist derzeit einfach technisch keine Alternative für mich, und FreeBSD's Treibersituation auf Notebooks ist auch nicht wirklich berauschend. Windows mag ich nicht, usw.. Erreicht wird damit doch praktisch eh nichts. In meinen Augen ist beim Thema Wikileaks das effektivste Mittel doch eh: so hartnäckig spenden wie es nur geht. Wege dafür gibt es genug. Unterstützung ist weitaus mächtiger als Boykott.&lt;br /&gt;&lt;br /&gt;Wenn mir also jemand ein Notebook mit 13" Formfaktor, 6 Stunden+ Akkulaufzeit, Alugehäuse, großen Touchpad auf dem mindestens ein FreeBSD rennt (damit meine ich das ALLE Komponenten auch zuverlässige Treiber haben) und das dazu auch noch KEINERLEI Komponenten von irgendeiner Firma enthält die irgendwo mal Scheisse gebaut hat zeigen kann, bring it on. (Das ist ernst gemeint, würde mich interessieren ob es da draußen irgendwas gibt was dem auch nur ansatzweise entspricht)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8144285405079538181-7778315490826873457?l=raichoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://raichoo.blogspot.com/feeds/7778315490826873457/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8144285405079538181&amp;postID=7778315490826873457' title='2 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/7778315490826873457'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/7778315490826873457'/><link rel='alternate' type='text/html' href='http://raichoo.blogspot.com/2010/12/die-sache-mit-apple.html' title='Die Sache mit Apple'/><author><name>Björn 'raichoo' Herzig</name><uri>https://profiles.google.com/102273886131939895778</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-KxzzpA_pbkc/AAAAAAAAAAI/AAAAAAAAARI/yHTIB2nrp8I/s512-c/photo.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8144285405079538181.post-6494140572612689937</id><published>2010-09-20T10:39:00.000-07:00</published><updated>2010-09-20T14:05:36.416-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Scala'/><title type='text'>Scala: Klassen erweitern mal anders</title><content type='html'>Datentypen erweitern ist mehr oder weniger etwas das man des öfteren machen muss, und das ist nicht umbedingt immer unproblematisch. Nehmen wir mal an wir hätten folgende Klasse:&lt;br /&gt;&lt;code&gt;&lt;pre&gt;&lt;br /&gt;class Test(val x: Int)&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;Ganz klar: hochkomplizierter Code. &lt;code&gt;Test&lt;/code&gt; quillt an Features nur so über, aber uns fehlt gerade eine Methode damit&lt;br /&gt;wir Objekte dieser Klasse in unserem Code nahtlos verwenden können. Diese Methode nennen wir &lt;code&gt;bla&lt;/code&gt;. Das Problem ist allerdings: Wir haben den Code von &lt;code&gt;Test&lt;/code&gt; nicht und können ihn deswegen nicht um bla erweitern.&lt;br /&gt;Jetzt gibt es verschiedene Wege wie wir diese Methode in &lt;code&gt;Test&lt;/code&gt; einbinden könnten. Der offensichtlichste ist sicherlich Vererbung. Blöd ist nur: Wir haben &lt;code&gt;bla&lt;/code&gt; schon geschrieben und würden ihn ungern duplizieren, vor allem weil wir den Code bereits schön generalisiert haben.&lt;br /&gt;&lt;br /&gt;Eine Lösung ist hier ziemlich elegant mit Traits, Selftyping und Structural Types zu machen.&lt;br /&gt;&lt;br /&gt;Als erstes definieren wir einen Structural Type der eine genaue Schnittstelle definiert. Wir nennen ihn &lt;code&gt;xAble&lt;/code&gt; und er macht nichts weiter als zu definieren das alle Klassen die eine Methode &lt;code&gt;x&lt;/code&gt; anbieten vom Typ &lt;code&gt;xAble&lt;/code&gt; sind.&lt;br /&gt;&lt;code&gt;&lt;pre&gt;&lt;br /&gt;type xAble = { def x: Int }&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;Was wir jetzt brauchen ist unsere generalisierte Implementation von &lt;code&gt;bla&lt;/code&gt;. Hier verwenden wir, Selftyping. Das ist ein Feature das es uns erlaubt innerhalb eines Traits so zu tun als wäre es von einem bestimmten Typ ohne davon zu erben.&lt;br /&gt;&lt;code&gt;&lt;pre&gt;&lt;br /&gt;trait Gimme[A &lt;: xAble] {&lt;br /&gt;  self: A =&gt;&lt;br /&gt;  def bla(): Unit = println(self.x + 1)                                                              &lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;Wie man sieht muss der muss der Typparameter &lt;code&gt;A&lt;/code&gt; ein Subtyp von &lt;code&gt;xAble&lt;/code&gt; sein, also die methode &lt;code&gt;x&lt;/code&gt; liefern.&lt;br /&gt;&lt;br /&gt;Alles was wir jetzt noch machen müssen ist das Trait &lt;code&gt;Gimme&lt;/code&gt; in das Objekt des Typs &lt;code&gt;Test&lt;/code&gt; zu mischen und wir haben das ganze um &lt;code&gt;bla&lt;/code&gt; erweitert.&lt;br /&gt;&lt;code&gt;&lt;pre&gt;&lt;br /&gt;object Main {&lt;br /&gt;&lt;br /&gt;  class Test(val x: Int)&lt;br /&gt;&lt;br /&gt;  type xAble = { def x: Int }&lt;br /&gt;&lt;br /&gt;  trait Gimme[A &lt;: xAble] {&lt;br /&gt;    self: A =&gt;&lt;br /&gt;    def bla(): Unit = println(self.x + 1)&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  def main(args: Array[String]): Unit = {&lt;br /&gt;    val t = new Test(666) with Gimme[Test]                                                             &lt;br /&gt;    t.bla()&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;Das ganze Zeit mal wieder wie extrem mächtig das Scala Typsystem ist und was für elegante Features die Sprache zum lösen immer wiederkehrender Probleme bietet. Ich hoffe dieses Beispiel gibt euch eine kleine Idee was man damit machen kann. ;)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8144285405079538181-6494140572612689937?l=raichoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://raichoo.blogspot.com/feeds/6494140572612689937/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8144285405079538181&amp;postID=6494140572612689937' title='3 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/6494140572612689937'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/6494140572612689937'/><link rel='alternate' type='text/html' href='http://raichoo.blogspot.com/2010/09/scala-wie-man-das-expressionproblem.html' title='Scala: Klassen erweitern mal anders'/><author><name>Björn 'raichoo' Herzig</name><uri>https://profiles.google.com/102273886131939895778</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-KxzzpA_pbkc/AAAAAAAAAAI/AAAAAAAAARI/yHTIB2nrp8I/s512-c/photo.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8144285405079538181.post-8924468782216230667</id><published>2010-06-24T12:58:00.000-07:00</published><updated>2010-06-24T13:04:17.590-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='FreeBSD'/><category scheme='http://www.blogger.com/atom/ns#' term='JVM'/><title type='text'>FreeBSD 8.1 und die JVM</title><content type='html'>Alios hat gerade seinen Server auf den neusten Stand gebracht und prompt funktionierte Sakura natürlich wieder nicht. Das Problem war das die JVM wohl anscheinen den IPv6 Stack genommen hat und sich damit nicht verträgt, ein Workaround ist die JVM einfach dazu zu zwingen den IPv4 Stack zu nehmen. Das geht mit der &lt;code&gt;-Djava.net.preferIPv4Stack=true&lt;/code&gt; Option.&lt;br /&gt;&lt;br /&gt;Wenn euch also das nächste mal ein Socket beim Connect aus unerfindlichen Gründen abraucht, versucht es mal damit.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8144285405079538181-8924468782216230667?l=raichoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://raichoo.blogspot.com/feeds/8924468782216230667/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8144285405079538181&amp;postID=8924468782216230667' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/8924468782216230667'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/8924468782216230667'/><link rel='alternate' type='text/html' href='http://raichoo.blogspot.com/2010/06/freebsd-81-und-die-jvm.html' title='FreeBSD 8.1 und die JVM'/><author><name>Björn 'raichoo' Herzig</name><uri>https://profiles.google.com/102273886131939895778</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-KxzzpA_pbkc/AAAAAAAAAAI/AAAAAAAAARI/yHTIB2nrp8I/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8144285405079538181.post-565441632817087332</id><published>2010-06-24T12:56:00.001-07:00</published><updated>2010-06-24T12:56:34.621-07:00</updated><title type='text'>100 Posts!</title><content type='html'>&lt;object width="480" height="385"&gt;&lt;param name="movie" value="http://www.youtube.com/v/YFqtye2_3E4&amp;hl=en_US&amp;fs=1&amp;"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/YFqtye2_3E4&amp;hl=en_US&amp;fs=1&amp;" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="480" height="385"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8144285405079538181-565441632817087332?l=raichoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://raichoo.blogspot.com/feeds/565441632817087332/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8144285405079538181&amp;postID=565441632817087332' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/565441632817087332'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/565441632817087332'/><link rel='alternate' type='text/html' href='http://raichoo.blogspot.com/2010/06/100-posts.html' title='100 Posts!'/><author><name>Björn 'raichoo' Herzig</name><uri>https://profiles.google.com/102273886131939895778</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-KxzzpA_pbkc/AAAAAAAAAAI/AAAAAAAAARI/yHTIB2nrp8I/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8144285405079538181.post-4892164900276958920</id><published>2010-06-21T09:09:00.000-07:00</published><updated>2010-06-21T09:24:49.932-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Scala'/><title type='text'>Spass mit Scala Infixtypen</title><content type='html'>In Scala gibt es das interessante Konzept der Infix Typen, dabei handelt es sich um nichts weiter als Typen die zwei Parameter erwarten. Scala erlaubt hier Infix Notation.&lt;br /&gt;&lt;code&gt;&lt;pre&gt;&lt;br /&gt;object Main {&lt;br /&gt;  class FooBar[A, B]&lt;br /&gt;&lt;br /&gt;  def main(args: Array[String]): Unit = { &lt;br /&gt;    //zwei unterschiedliche Schreibweisen die das gleiche&lt;br /&gt;    //meinen&lt;br /&gt;    var x: FooBar[Int, BigInt] = null&lt;br /&gt;    var y: Int FooBar BigInt   = null&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;Damit eröffnen sich interessante Möglichkeiten des Typsystems, z.B: "Operatoren" aus Typen erstellen die wiederum Typen erstellen. Verwirrt? In Scala gibt es bereits &lt;code&gt;=:=,&lt;/code&gt; &lt;code&gt;&amp;lt;:&amp;lt;&lt;/code&gt; und &lt;code&gt;&amp;lt;%&amp;lt;&lt;/code&gt;, diese Konstrukte kann man sich unter anderem auch selbst zusammenbasteln, im folgenden Beispiel bauen wir uns einen &lt;code&gt;&amp;lt;@@@&amp;lt;&lt;/code&gt; "Operator"&lt;br /&gt;&lt;code&gt;&lt;pre&gt;&lt;br /&gt;abstract class &amp;lt;@@@&amp;lt;[A, B] extends (A =&amp;gt; B)&lt;br /&gt;&lt;br /&gt;class Test[T &amp;lt;: (Int =&amp;gt; Int)]&lt;br /&gt;&lt;br /&gt;object Main {&lt;br /&gt;  def main(args: Array[String]) = { &lt;br /&gt;    val t = new Test[Int &amp;lt;@@@&amp;lt; Int]&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;Ziemlich cool, jetzt kann man sich Operatoren basteln die Typen erstellen und sich anfühlen wie native Features der Sprache :)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8144285405079538181-4892164900276958920?l=raichoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://raichoo.blogspot.com/feeds/4892164900276958920/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8144285405079538181&amp;postID=4892164900276958920' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/4892164900276958920'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/4892164900276958920'/><link rel='alternate' type='text/html' href='http://raichoo.blogspot.com/2010/06/spass-mit-scala-infixtypen.html' title='Spass mit Scala Infixtypen'/><author><name>Björn 'raichoo' Herzig</name><uri>https://profiles.google.com/102273886131939895778</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-KxzzpA_pbkc/AAAAAAAAAAI/AAAAAAAAARI/yHTIB2nrp8I/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8144285405079538181.post-6598245489307319512</id><published>2010-06-02T13:11:00.000-07:00</published><updated>2010-06-02T14:46:28.475-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Scala'/><title type='text'>Paralleles Primzahlsieb in Scala</title><content type='html'>Nach der Präsentation von Google Go habe ich mich gefragt ob man das parallele Primzahlsieb auch in Scala so machen kann. Ich muss sagen das ich das Resultat sogar einfacher und eleganter finde als die Go Implementation. Sicherlich gibt es performantere Algorithmen aber hier geht es einfach um das Prinzip zu zeigen wie einfach man Parallelisieren kann.&lt;br /&gt;&lt;br /&gt;HINWEIS: Das Programm terminiert nicht, da für jede Primzahl ein eigener "Thread" (Actors die per react warten verhalten sich nicht ganz so wie Threads die in einem Loop warten, sondern sind leichtgewichtiger)  gestartet wird und diese weiter auf Futter warten. Es ist auf jeden Fall möglich das das ganze anhält, ich will lediglich das Prinzip zeigen und das Beispiel nicht unnötig aufblasen.&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;pre&gt;&lt;br /&gt;import scala.actors.Actor&lt;br /&gt;import scala.actors.Actor._&lt;br /&gt;&lt;br /&gt;class Prime(value: Int) extends Actor {&lt;br /&gt;  var next: Option[Prime] = None&lt;br /&gt;&lt;br /&gt;  println(value)&lt;br /&gt;  start&lt;br /&gt;&lt;br /&gt;  def act(): Unit = loop {&lt;br /&gt;      react {&lt;br /&gt;        case x: Int if ((x % value) != 0) =&gt;  &lt;br /&gt;          next match {&lt;br /&gt;            case Some(p: Prime) =&gt; p ! x &lt;br /&gt;            case None =&gt; next = Some(new Prime(x))&lt;br /&gt;          }   &lt;br /&gt;      }   &lt;br /&gt;    }   &lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;object Main {&lt;br /&gt;  def main(args: Array[String]): Unit = { &lt;br /&gt;    val primer = new Prime(2)&lt;br /&gt;    3 to args(0).toInt map (primer ! _)&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8144285405079538181-6598245489307319512?l=raichoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://raichoo.blogspot.com/feeds/6598245489307319512/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8144285405079538181&amp;postID=6598245489307319512' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/6598245489307319512'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/6598245489307319512'/><link rel='alternate' type='text/html' href='http://raichoo.blogspot.com/2010/06/paralleles-primzahlsieb-in-scala.html' title='Paralleles Primzahlsieb in Scala'/><author><name>Björn 'raichoo' Herzig</name><uri>https://profiles.google.com/102273886131939895778</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-KxzzpA_pbkc/AAAAAAAAAAI/AAAAAAAAARI/yHTIB2nrp8I/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8144285405079538181.post-6165770339065915047</id><published>2010-05-10T13:26:00.000-07:00</published><updated>2010-05-10T13:29:49.980-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Scala'/><title type='text'>Mergesort in Scala</title><content type='html'>Und aus der Kategorie "Sortieren für Besessene" kommt heute mal wieder ein Beispiel, aber ausnahmsweise kein Quicksort ;)&lt;br /&gt;&lt;br /&gt;Was ich besonders toll an diesem Beispiel finde ist das auf gleich 2 Listen gleichzeitig gematcht wird wie es auch in Haskell geht. Da hat Scala mal wieder richtig Spass gemacht.&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;pre&gt;&lt;br /&gt;object Main {&lt;br /&gt;&lt;br /&gt;  def merge[T &lt;% Ordered[T]](l: List[T], r: List[T]): List[T] = &lt;br /&gt;    (l,r) match {&lt;br /&gt;      case (x::xs, y::ys) =&gt; if (x &lt; y)&lt;br /&gt;                               x::(merge(xs, r)) &lt;br /&gt;                             else&lt;br /&gt;                               y::(merge(l, ys))&lt;br /&gt;      case (xs,  Nil) =&gt; xs&lt;br /&gt;      case (Nil, ys)  =&gt; ys&lt;br /&gt;    }   &lt;br /&gt;&lt;br /&gt;  def mergesort[T &lt;% Ordered[T]](list: List[T]): List[T] =   &lt;br /&gt;    if (list.length &gt; 1) { &lt;br /&gt;      val (l, r) = list splitAt (list length)/2&lt;br /&gt;      merge(mergesort(l), mergesort(r))&lt;br /&gt;    } else list&lt;br /&gt;&lt;br /&gt;  def main(args: Array[String]): Unit = { &lt;br /&gt;    println(mergesort(List(4,5,9,1,2,4,5,9,8,7)))&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8144285405079538181-6165770339065915047?l=raichoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://raichoo.blogspot.com/feeds/6165770339065915047/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8144285405079538181&amp;postID=6165770339065915047' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/6165770339065915047'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/6165770339065915047'/><link rel='alternate' type='text/html' href='http://raichoo.blogspot.com/2010/05/mergesort-in-scala.html' title='Mergesort in Scala'/><author><name>Björn 'raichoo' Herzig</name><uri>https://profiles.google.com/102273886131939895778</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-KxzzpA_pbkc/AAAAAAAAAAI/AAAAAAAAARI/yHTIB2nrp8I/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8144285405079538181.post-5004203368429763531</id><published>2010-05-08T17:22:00.000-07:00</published><updated>2010-05-08T17:24:01.536-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Scala'/><title type='text'>Scala in der Warpzone</title><content type='html'>&lt;object width="400" height="300"&gt;&lt;param name="allowfullscreen" value="true" /&gt;&lt;param name="allowscriptaccess" value="always" /&gt;&lt;param name="movie" value="http://vimeo.com/moogaloop.swf?clip_id=11585013&amp;amp;server=vimeo.com&amp;amp;show_title=1&amp;amp;show_byline=1&amp;amp;show_portrait=0&amp;amp;color=&amp;amp;fullscreen=1" /&gt;&lt;embed src="http://vimeo.com/moogaloop.swf?clip_id=11585013&amp;amp;server=vimeo.com&amp;amp;show_title=1&amp;amp;show_byline=1&amp;amp;show_portrait=0&amp;amp;color=&amp;amp;fullscreen=1" type="application/x-shockwave-flash" allowfullscreen="true" allowscriptaccess="always" width="400" height="300"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;p&gt;&lt;a href="http://vimeo.com/11585013"&gt;Scala in der warpzone Münster&lt;/a&gt; from &lt;a href="http://vimeo.com/user3772791"&gt;raichoo&lt;/a&gt; on &lt;a href="http://vimeo.com"&gt;Vimeo&lt;/a&gt;.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8144285405079538181-5004203368429763531?l=raichoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://raichoo.blogspot.com/feeds/5004203368429763531/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8144285405079538181&amp;postID=5004203368429763531' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/5004203368429763531'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/5004203368429763531'/><link rel='alternate' type='text/html' href='http://raichoo.blogspot.com/2010/05/scala-in-der-warpzone.html' title='Scala in der Warpzone'/><author><name>Björn 'raichoo' Herzig</name><uri>https://profiles.google.com/102273886131939895778</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-KxzzpA_pbkc/AAAAAAAAAAI/AAAAAAAAARI/yHTIB2nrp8I/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8144285405079538181.post-4893667907199231832</id><published>2010-04-17T01:43:00.001-07:00</published><updated>2010-04-17T01:51:57.930-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Git'/><category scheme='http://www.blogger.com/atom/ns#' term='ksh93'/><title type='text'>Git-Mode für die KSH</title><content type='html'>Ich habe gerade mal meine Git Erweiterung für die &lt;a href="http://kornshell.org/"&gt;Kornshell&lt;/a&gt; in meinen &lt;a href="http://bitbucket.org/raichoo/"&gt;Bitbucket&lt;/a&gt; gestellt. Das ganze liegt zwar noch unter "Mercurial-Integration" aber sollte zu finden sein ;). Wie schon beim &lt;a href="http://raichoo.blogspot.com/2010/02/ksh93-mercurial-promptmode.html"&gt;Mercurial mode&lt;/a&gt; wechselt man mit &lt;code&gt;mode git&lt;/code&gt; in den entsprechenden Modus. Die Farbe der Commit ID wechselt von Rot (uncommited changes) zu Gelb (nicht die aktuellste Revision) zu Grün (aktuellste Revision und nichts zu commiten). Außerdem wird der aktuelle Branch angezeigt und im Falle eines "detached HEAD" Zustands visuell gewarnt. Viel Spass damit!&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_3VHVa9AP0ZM/S8l1Wc1UlII/AAAAAAAAAN0/Zkv58GiA1Kw/s1600/Screen+shot+2010-04-17+at+10.25.57+AM.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 214px;" src="http://1.bp.blogspot.com/_3VHVa9AP0ZM/S8l1Wc1UlII/AAAAAAAAAN0/Zkv58GiA1Kw/s320/Screen+shot+2010-04-17+at+10.25.57+AM.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5461025051720848514" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8144285405079538181-4893667907199231832?l=raichoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://raichoo.blogspot.com/feeds/4893667907199231832/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8144285405079538181&amp;postID=4893667907199231832' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/4893667907199231832'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/4893667907199231832'/><link rel='alternate' type='text/html' href='http://raichoo.blogspot.com/2010/04/git-mode-fur-die-ksh.html' title='Git-Mode für die KSH'/><author><name>Björn 'raichoo' Herzig</name><uri>https://profiles.google.com/102273886131939895778</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-KxzzpA_pbkc/AAAAAAAAAAI/AAAAAAAAARI/yHTIB2nrp8I/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_3VHVa9AP0ZM/S8l1Wc1UlII/AAAAAAAAAN0/Zkv58GiA1Kw/s72-c/Screen+shot+2010-04-17+at+10.25.57+AM.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8144285405079538181.post-8234114700788082563</id><published>2010-04-17T00:13:00.001-07:00</published><updated>2010-04-17T00:54:23.437-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Git'/><title type='text'>Git happens</title><content type='html'>Ich bin kein besonders großer Fan von &lt;a href="http://git-scm.com/"&gt;Git&lt;/a&gt;, allerdings kommt man hin und wieder einfach nicht drum herum. Da mein Standard-Workflow derzeit einfach darin besteht Commits im Nirvana verschwinden zu lassen gibt es eigentlich nur 2 Alternativen für mich:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Eine Selbsthilfegruppe für Git-Geschädigte aufsuchen&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Ein paar Skripten schreiben die mir das Leben leichter machen&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;Zweiteres klang bei näherer Betrachtung einfach attraktiver.&lt;br /&gt;&lt;br /&gt;Da ich im privaten Umfeld mehr &lt;a href="http://mercurial-scm.org/"&gt;Mercurial&lt;/a&gt; nutze platzt meine &lt;code&gt;.gitconfig&lt;/code&gt; derzeit durch Aliase auseinander die meinen Workflow erhalten, 2 davon replizieren in etwa das Verhalten von &lt;code&gt;incoming&lt;/code&gt; und &lt;code&gt;outgoing&lt;/code&gt;, oder anders gesagt: sie zeigen mir eingehende bzw. ausstehende Commits an.&lt;br /&gt;&lt;br /&gt;Beispiel:&lt;br /&gt;&lt;code&gt;&lt;pre&gt;&lt;br /&gt;// commits die noch nicht in origin/master&lt;br /&gt;// eingeflossen sind&lt;br /&gt;git out origin/master&lt;br /&gt;&lt;br /&gt;// commit aus origin/master die noch nicht&lt;br /&gt;// in meinem lokalen Branch liegen&lt;br /&gt;git in origin/master&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;Die beiden Aliase sind nicht besonders spektakulär aber nützlich:&lt;br /&gt;&lt;code&gt;&lt;pre&gt;&lt;br /&gt;  out = "log --stat HEAD --not"&lt;br /&gt;  in  = "!f() { git log --stat $1 --not HEAD; }; f"&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;Ein weiteres Alias reproduziert das verhalten von &lt;code&gt;hg log -G&lt;/code&gt; und zeigt mit die History in einem halbwegs lesbaren Graphen an (bei komplexeren Bäumen greife ich aber lieber zu einem Tool wie GitX)&lt;br /&gt;&lt;code&gt;&lt;pre&gt;&lt;br /&gt;  graph = "log --graph --pretty=oneline --abbrev-commit --decorate --all"&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;Das alles hilft aber noch nicht bei meinem eigentlichen Problem: Commits schrotten.&lt;br /&gt;Hierfür habe ich mir eine kleine Erweiterung geschrieben… Also nicht zum schrotten, sondern zum wiederherstellen ^^.&lt;br /&gt;Mit &lt;code&gt;git orphans&lt;/code&gt; werden mir sogenannte "dangling commits" angezeigt, das sind Commits die auf normalem Wege nicht mehr erreichbar sind. Da git ohne Garbage Collection (&lt;code&gt;git gc&lt;/code&gt; oder &lt;code&gt;git prune&lt;/code&gt;) nicht so ohne weiteres Commits wegwirft sondern als "dangling commits" im Nirvana vorhält, kann ich mit &lt;code&gt;git reset --hard SHA1&lt;/code&gt; (oder in meinem Fall mit dem Alias &lt;code&gt;git rollback SHA1&lt;/code&gt;) meinen HEAD auf gerade verlorene Commits umbiegen und alles ist wieder beim Alten. &lt;code&gt;git orphans&lt;/code&gt; verifiziert Commitobjekte und zeigt mir den dazugehören History Eintrag an. Das Ganze ist ein simples Shellskript das man einfach zu den anderen git Kommandos (welche bei mir in &lt;/code&gt;libexec/git-core&lt;/code&gt; liegen) unter dem Namen &lt;code&gt;git-orphans&lt;/code&gt; abglegt.&lt;br /&gt;&lt;code&gt;&lt;pre&gt;&lt;br /&gt;#!/bin/sh&lt;br /&gt;&lt;br /&gt;USAGE=''&lt;br /&gt;OPTIONS_SPEC=&lt;br /&gt;. git-sh-setup&lt;br /&gt;&lt;br /&gt;if [ "$#" != "0" ]&lt;br /&gt;then&lt;br /&gt;    usage&lt;br /&gt;fi&lt;br /&gt;&lt;br /&gt;git fsck --lost-found |&lt;br /&gt;while read dangling type sha1&lt;br /&gt;do&lt;br /&gt;  case "$type" in&lt;br /&gt;  commit)&lt;br /&gt;    if git rev-parse -q --verify "$sha1" &gt;/dev/null&lt;br /&gt;    then&lt;br /&gt;      git log --color -n 1 "$sha1"&lt;br /&gt;      echo ""&lt;br /&gt;    fi  &lt;br /&gt;    ;;  &lt;br /&gt;  esac&lt;br /&gt;done | git_pager&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;Für mich sind das ein paar sehr brauchbare Anpassungen, ich hoffe der ein oder andere findet sie ebenso brauchbar :)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8144285405079538181-8234114700788082563?l=raichoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://raichoo.blogspot.com/feeds/8234114700788082563/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8144285405079538181&amp;postID=8234114700788082563' title='2 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/8234114700788082563'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/8234114700788082563'/><link rel='alternate' type='text/html' href='http://raichoo.blogspot.com/2010/04/git-happens.html' title='Git happens'/><author><name>Björn 'raichoo' Herzig</name><uri>https://profiles.google.com/102273886131939895778</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-KxzzpA_pbkc/AAAAAAAAAAI/AAAAAAAAARI/yHTIB2nrp8I/s512-c/photo.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8144285405079538181.post-2129110760626890967</id><published>2010-04-14T11:52:00.000-07:00</published><updated>2010-04-14T12:07:33.104-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='C++'/><title type='text'>C++ "Lazy Evaluation" für Streams</title><content type='html'>Manchmal will man nicht das ein Stream überhaupt Sachen ausgibt (z.B. für Debugstreams die sich bei Bedarf zuschalten kann) und dann will man natürlich auch nicht das die Parameter die durch den Streamoperator gehen abgearbeitet werden da sich dort eventuell komplexe Parsereien verstecken könnten.&lt;br /&gt;&lt;br /&gt;Hierfür gibt es einen denkbar einfachen Trick mit C-Macros (jaja ich weiß, aber hin und wieder bin sogar ich da pragmatisch :P ).&lt;br /&gt;&lt;code&gt;&lt;pre&gt;&lt;br /&gt;#include &amp;lt;iostream&amp;gt;&lt;br /&gt;#define DEBUGSTREAM if (!debug); else std::cerr&lt;br /&gt;&lt;br /&gt;int main() {&lt;br /&gt;  bool debug = false;&lt;br /&gt;  DEBUGSTREAM &amp;lt;&amp;lt; "Test\n";&lt;br /&gt;  return 0;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;In diesem Code wird nichts ausgegeben und auch nichts ausgewertet, das Verhalten lässt sich einfach zur Laufzeit ändern. Tada! "Lazy Evaluation" on demand :)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8144285405079538181-2129110760626890967?l=raichoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://raichoo.blogspot.com/feeds/2129110760626890967/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8144285405079538181&amp;postID=2129110760626890967' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/2129110760626890967'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/2129110760626890967'/><link rel='alternate' type='text/html' href='http://raichoo.blogspot.com/2010/04/c-lazy-evaluation-fur-streams.html' title='C++ &quot;Lazy Evaluation&quot; für Streams'/><author><name>Björn 'raichoo' Herzig</name><uri>https://profiles.google.com/102273886131939895778</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-KxzzpA_pbkc/AAAAAAAAAAI/AAAAAAAAARI/yHTIB2nrp8I/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8144285405079538181.post-1590487500638695421</id><published>2010-04-14T11:33:00.000-07:00</published><updated>2010-04-14T11:44:58.614-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='C++'/><title type='text'>C++ Steams dressieren</title><content type='html'>Manchmal möchte man gerne bestimmte Aktionen auslösen die sich nach dem Abwickeln einer Streambefüllung zutragen sollen (z.B. das ein Lock freigeben). Hier ist ein kleiner Trick der genau das macht und in bestimmten Situationen durchaus hilfreich sein kann: wenn z.B. man durch widrige Umstände nicht in der Lage ist den Scope zu begrenzen.&lt;br /&gt;&lt;code&gt;&lt;pre&gt;&lt;br /&gt;#include &amp;lt;iostream&amp;gt; &lt;br /&gt;#include &amp;lt;tr1/memory&amp;gt; &lt;br /&gt; &lt;br /&gt;class Tester { &lt;br /&gt;  public: &lt;br /&gt; &lt;br /&gt;    Tester&amp; operator&amp;lt;&amp;lt;(std::string s) { &lt;br /&gt;      std::cout &amp;lt;&amp;lt; s; &lt;br /&gt;      return *this; &lt;br /&gt;    }   &lt;br /&gt; &lt;br /&gt;    ~Tester() { &lt;br /&gt;      std::cout &amp;lt;&amp;lt; "End\n"; &lt;br /&gt;    }   &lt;br /&gt;}; &lt;br /&gt; &lt;br /&gt;std::tr1::shared_ptr&amp;lt;Tester&amp;gt; wrapper() { &lt;br /&gt;  std::cout &amp;lt;&amp;lt; "Begin\n"; &lt;br /&gt;  return std::tr1::shared_ptr&amp;lt;Tester&amp;gt;(new Tester()); &lt;br /&gt;} &lt;br /&gt; &lt;br /&gt;int main() { &lt;br /&gt;  *(wrapper()) &amp;lt;&amp;lt; "A "&amp;lt;&amp;lt;  "test!\n"; &lt;br /&gt;  std::cout &amp;lt;&amp;lt; "Ending scope\n"; &lt;br /&gt;  return 0; &lt;br /&gt;} &lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8144285405079538181-1590487500638695421?l=raichoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://raichoo.blogspot.com/feeds/1590487500638695421/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8144285405079538181&amp;postID=1590487500638695421' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/1590487500638695421'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/1590487500638695421'/><link rel='alternate' type='text/html' href='http://raichoo.blogspot.com/2010/04/c-steams-dressieren.html' title='C++ Steams dressieren'/><author><name>Björn 'raichoo' Herzig</name><uri>https://profiles.google.com/102273886131939895778</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-KxzzpA_pbkc/AAAAAAAAAAI/AAAAAAAAARI/yHTIB2nrp8I/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8144285405079538181.post-7172637773086909727</id><published>2010-04-14T09:55:00.000-07:00</published><updated>2010-04-17T01:10:46.862-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Debugging'/><category scheme='http://www.blogger.com/atom/ns#' term='Dtrace'/><title type='text'>Deadlocks jagen mit DTrace</title><content type='html'>Deadlocks gehören so ziemlich zu den widerlichsten Phänomenen die man sich so beim Programmieren vorstellen kann. Vor allem wenn sie nur sporadisch auftreten. Irgendein Thread weigert sich einfach ein Lock wieder freizugeben und wir hängen. Mit dem gleichen Problem durfte ich mich neulich auch rumschlagen, leider tappten wir total im Dunkeln da nicht lokalisieren war wer das Lock eigentlich in Beschlag genommen hat. Hier musste wieder mal meine Lieblingswunderwaffe ran und das Problem mit einem D Skript eingekreist werden.&lt;br /&gt;&lt;br /&gt;Was dieses Skript macht ist nichts anderes als sich zu jedem Lock der geschlossen wird den Stacktrace zu merken und sobald wir an den Punkt kommen an dem das Deadlock auftritt uns zu zeigen wer gerade das Lock hält das uns am weitergehen hindert. Das ganze ist ein unglaublicher Speicherfresser (ich muss dazu sagen das die jeweiligen Stacktraces einfach nur abnorm waren) da ich hier Speculations verwende (siehe letzter Eintrag ;) ) und DTrace bereinigt den Speicher nur in bestimmten Intervallen, was in bei der Menge an Locks einfach zu langsam war. Außerdem hat man nur eine begrenzte Anzahl an Speculations zur Verfügung. Aber DTrace wär nicht das was es ist wenn man das nicht auch "aushebeln" könnte ;)&lt;br /&gt;&lt;br /&gt;&lt;code&gt;nspec&lt;/code&gt; dient dazu die Anzahl der möglichen Speculations hochzusetzen und &lt;code&gt;cleanrate&lt;/code&gt; bestimmt die Frequenz der Garbagecollection, mit &lt;code&gt;-b&lt;/code&gt; schrauben wir den Gesamtpuffer auf 128MB hoch.&lt;br /&gt;&lt;br /&gt;Also, ohne weitere Umschweife: der Star des gestrigen Tages!&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;pre&gt;&lt;br /&gt;#!/usr/sbin/dtrace -b 128m -x nspec=20 -x cleanrate=101 -s&lt;br /&gt;&lt;br /&gt;pid$target::deadlockgoeshere:entry&lt;br /&gt;{&lt;br /&gt;  self-&gt;traceme = 1;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;pid$target::deadlockgoeshere:return&lt;br /&gt;/self-&gt;traceme/&lt;br /&gt;{&lt;br /&gt;  self-&gt;traceme = 0;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;pid$target::pthread_mutex_lock:entry &lt;br /&gt;/spec[arg0] == 0/&lt;br /&gt;{&lt;br /&gt;  spec[arg0] = speculation();&lt;br /&gt;  speculate(spec[arg0]);&lt;br /&gt;  ustack();&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;pid$target::pthread_mutex_lock:entry&lt;br /&gt;/spec[arg0] &amp;&amp; self-&gt;traceme/&lt;br /&gt;{&lt;br /&gt;  commit(spec[arg0]); &lt;br /&gt;  spec[arg0] = 0;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;pid$target::pthread_mutex_lock:entry&lt;br /&gt;/spec[arg0] &amp;&amp; self-&gt;traceme == 0/&lt;br /&gt;{&lt;br /&gt;  discard(spec[arg0]);  &lt;br /&gt;  spec[arg0] = 0;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;pid$target::pthread_mutex_unlock:entry&lt;br /&gt;{&lt;br /&gt;  discard(spec[arg0]);&lt;br /&gt;  spec[arg0] = 0;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8144285405079538181-7172637773086909727?l=raichoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://raichoo.blogspot.com/feeds/7172637773086909727/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8144285405079538181&amp;postID=7172637773086909727' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/7172637773086909727'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/7172637773086909727'/><link rel='alternate' type='text/html' href='http://raichoo.blogspot.com/2010/04/deadlocks-jagen-mit-dtrace.html' title='Deadlocks jagen mit DTrace'/><author><name>Björn 'raichoo' Herzig</name><uri>https://profiles.google.com/102273886131939895778</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-KxzzpA_pbkc/AAAAAAAAAAI/AAAAAAAAARI/yHTIB2nrp8I/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8144285405079538181.post-8638448616875229864</id><published>2010-03-30T13:43:00.000-07:00</published><updated>2010-03-30T14:15:58.586-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='MacOSX'/><category scheme='http://www.blogger.com/atom/ns#' term='OpenSolaris'/><category scheme='http://www.blogger.com/atom/ns#' term='Dtrace'/><title type='text'>Spekulatives Tracen mit DTrace</title><content type='html'>Spekulieren ist ja nicht erst seit der "Finanzkrise" der letzte Schrei, auch wir Programmierer stehen hin und wieder mal vor der Situation das wir Kram anhäufen von dem wir nicht wissen ob wir ihn später noch gebrauchen können. Besonders beim Debuggen fallen oft Daten an bei denen wir erst wissen ob sie interessant sind wenn wir schon bis zum Hals in Messwerten stecken. Wie also die Spreu vom Weizen trennen? DTrace hat ein Feature das leider viel zu wenig Beachtung bekommt: &lt;i&gt;&lt;b&gt;Speculations&lt;/i&gt;&lt;/b&gt;.&lt;br /&gt;&lt;br /&gt;Ein einfaches Beispiel: Wir interessieren uns für alles was im Kernel während des Öffnens einer Datei passiert, allerdings wollen wir das Ergebnis nur wissen wenn das Öffnen fehlschlägt. Das macht folgendes D-Script:&lt;br /&gt;&lt;code&gt;&lt;pre&gt;&lt;br /&gt;#!/usr/sbin/dtrace -s&lt;br /&gt;&lt;br /&gt;syscall::open:entry&lt;br /&gt;/execname == "a.out"/ {&lt;br /&gt;  self-&gt;spec = speculation();&lt;br /&gt;  speculate(self-&gt;spec);&lt;br /&gt;  printf("%s",copyinstr(arg0));&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;fbt:::&lt;br /&gt;/self-&gt;spec/ {&lt;br /&gt;  speculate(self-&gt;spec);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;syscall::open:return&lt;br /&gt;/self-&gt;spec &amp;&amp; arg1 == -1/ {&lt;br /&gt;  commit(self-&gt;spec);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;syscall::open:return&lt;br /&gt;/self-&gt;spec/ {&lt;br /&gt;  discard(self-&gt;spec);&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Ok, gehen wir das Ganze mal durch: &lt;code&gt;self-&gt;spec = speculation();&lt;/code&gt; legt threadlokal einen Puffer unter dem Namen &lt;code&gt;spec&lt;/code&gt; an. Eine Speculation ist also nichts anderes als ein Puffer in dem wir Messwerte zwischenspeichern und darauf warten ob sie wichtig werden.&lt;br /&gt;Um in einer Klausel das "Aufzeichnen" zu starten reicht ein &lt;code&gt;speculate(self-&gt;spec)&lt;/code&gt;, alle darauf folgenden Messwerte wandern in unseren Puffer. Tritt ein Ereignis ein das unseren Werten im Puffer Bedeutung verleiht können wir sie mit &lt;code&gt;commit(self-&gt;spec);&lt;/code&gt; ausgeben oder im gegenteiligen Fall mit &lt;code&gt;discard(self-&gt;spec);&lt;/code&gt; verwerfen.&lt;br /&gt;&lt;br /&gt;ACHTUNG: Puffer zu füllen ist eine kostspielige Angelegenheit, denkt daran das wir uns hier im Kernelkontext befinden. Also solltet ihr Daten die ihr nicht mehr braucht auch sofort verwerfen. Wachsen eure Puffer ungehindert weiter wird die DTrace VM euch einen Strich durch die Rechnung ziehen und selbst anfangen Daten zu verwerfen damit ihr das System nicht in den Abgrund zieht. Des weiteren ist der Trace den ich oben beschrieben habe auch schon recht "brutal" da der Puffer mit einem kompletten &lt;code&gt;fbt&lt;/code&gt; Messdatensatz befüllt wird. Das bremst open-systemcalls übel aus, also: HANDLE WITH CARE!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8144285405079538181-8638448616875229864?l=raichoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://raichoo.blogspot.com/feeds/8638448616875229864/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8144285405079538181&amp;postID=8638448616875229864' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/8638448616875229864'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/8638448616875229864'/><link rel='alternate' type='text/html' href='http://raichoo.blogspot.com/2010/03/spekulatives-tracen-mit-dtrace.html' title='Spekulatives Tracen mit DTrace'/><author><name>Björn 'raichoo' Herzig</name><uri>https://profiles.google.com/102273886131939895778</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-KxzzpA_pbkc/AAAAAAAAAAI/AAAAAAAAARI/yHTIB2nrp8I/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8144285405079538181.post-6610206499195429638</id><published>2010-03-16T14:02:00.000-07:00</published><updated>2010-04-17T01:40:45.759-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='MacOSX'/><category scheme='http://www.blogger.com/atom/ns#' term='Dtrace'/><title type='text'>Ganz viel DTrace :D</title><content type='html'>Heute war ein ziemlich voller Tag. Ich habe unter anderem meinen Vortrag über DTrace den ich schon einmal in der &lt;a href="http://warpzone.ms"&gt;warpzone&lt;/a&gt; gegeben habe bei der &lt;a href="http://www.mac-gt.de/"&gt;Mac User Group Gütersloh&lt;/a&gt; gehalten. Ich hab versucht dieses doch sehr technische Thema möglichst einfach rüber zu bringen da die Folien eigentlich eher für ein sehr technophiles Publikum gedacht waren. Hoffe ihr habt trotzdem Spass daran ;)&lt;br /&gt;&lt;br /&gt;&lt;center&gt;&lt;object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="480" height="386" id="utv255101" name="utv_n_240829"&gt;&lt;param name="flashvars" value="loc=%2F&amp;amp;autoplay=false&amp;amp;vid=5494078" /&gt;&lt;param name="allowfullscreen" value="true" /&gt;&lt;param name="allowscriptaccess" value="always" /&gt;&lt;param name="src" value="http://www.ustream.tv/flash/video/5494078" /&gt;&lt;embed flashvars="loc=%2F&amp;amp;autoplay=false&amp;amp;vid=5494078" width="480" height="386" allowfullscreen="true" allowscriptaccess="always" id="utv255101" name="utv_n_240829" src="http://www.ustream.tv/flash/video/5494078" type="application/x-shockwave-flash"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;/center&gt;&lt;br /&gt;Für alle die was auf die Ohren wollen hatte ich die Ehre eine &lt;a href="http://www.pofacs.de/#071"&gt;Sendung mit Mario Heide von Pofacs&lt;/a&gt; zu machen. Also: die volle Dröhung DTrace :D&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8144285405079538181-6610206499195429638?l=raichoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://raichoo.blogspot.com/feeds/6610206499195429638/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8144285405079538181&amp;postID=6610206499195429638' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/6610206499195429638'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/6610206499195429638'/><link rel='alternate' type='text/html' href='http://raichoo.blogspot.com/2010/03/ganz-viel-dtrace-d.html' title='Ganz viel DTrace :D'/><author><name>Björn 'raichoo' Herzig</name><uri>https://profiles.google.com/102273886131939895778</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-KxzzpA_pbkc/AAAAAAAAAAI/AAAAAAAAARI/yHTIB2nrp8I/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8144285405079538181.post-7999612700209239170</id><published>2010-02-22T15:39:00.000-08:00</published><updated>2010-02-22T15:46:13.774-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Scala'/><title type='text'>Quicksort in Scala</title><content type='html'>Ich weiß, ich weiß. Nicht schon wieder ein Quicksort. Dem ein oder anderen wird es sicher schon zur Nase rausquillen, aber generische Quicksort Algorithmen sind wirklich ein guter Weg um eine neue Sprachen kennenzulernen (zumindest empfinde ich das so ^^) Dieser hier ist mit ein wenig Hilfe zustande gekommen. Warum ist das ganze überhaupt wert gepostet zu werden? Erstmal ist Scala eine sehr interessante Sprache die den Versuch unternimmt FP und OOP zu vereinen (ohne dabei in das Kitchen-Sink Muster zu verfallen), des weiteren läuft sie auf der JVM was einem die Möglichkeit gibt auf den reichhaltigen Fundus an Java-Libs zurückzugreifen und die Vorzüge der JVM zu nutzen. Spannende Sprache für alle die mal was ganz anderes sehen wollen ;)&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;pre&gt;&lt;br /&gt;object Main {&lt;br /&gt;  def qs[T &lt;% Ordered[T]](list: List[T]): List[T] = &lt;br /&gt;    list match {&lt;br /&gt;      case Nil   =&gt; Nil &lt;br /&gt;      case x::xs =&gt; {&lt;br /&gt;        val (l, g) = xs partition (_ &lt; x)&lt;br /&gt;        qs(l) ++ (x::qs(g))&lt;br /&gt;      }   &lt;br /&gt;    }   &lt;br /&gt;&lt;br /&gt;  def main(args: Array[String]): Unit = { &lt;br /&gt;    val a = List(5,3,2,1,7,8,9,4,6)&lt;br /&gt;    println(qs(a))&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8144285405079538181-7999612700209239170?l=raichoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://raichoo.blogspot.com/feeds/7999612700209239170/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8144285405079538181&amp;postID=7999612700209239170' title='1 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/7999612700209239170'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/7999612700209239170'/><link rel='alternate' type='text/html' href='http://raichoo.blogspot.com/2010/02/quicksort-in-scala.html' title='Quicksort in Scala'/><author><name>Björn 'raichoo' Herzig</name><uri>https://profiles.google.com/102273886131939895778</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-KxzzpA_pbkc/AAAAAAAAAAI/AAAAAAAAARI/yHTIB2nrp8I/s512-c/photo.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8144285405079538181.post-1061516948726368164</id><published>2010-02-01T08:05:00.000-08:00</published><updated>2010-04-17T01:17:21.092-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Mercurial'/><title type='text'>Bitbucket Repository für Codeschnipsel</title><content type='html'>Ich werde immer mal wieder nach Config-Files oder Codeschnipseln gefragt die ich dann meistens auf meinen Blog stelle. Diese sind aber dank von Blogspot schwer bis gar nicht lesbar, also habe ich sie einfach mal auf &lt;a href="http://bitbucket.org/raichoo/"&gt;Bitbucket&lt;/a&gt; geschoben. Dann haben alle was davon ;)&lt;br /&gt;&lt;code&gt;&lt;pre&gt;&lt;br /&gt;hg clone https://raichoo@bitbucket.org/raichoo/ksh-mercurial-integration/&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;Viel Spass beim rumspielen. Ich hoffe ihr könnt was damit anfangen und habt vielleicht den ein oder anderen Verbesserungsvorschlag.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;UPDATE&lt;/b&gt;: Links aktualisiert&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8144285405079538181-1061516948726368164?l=raichoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://raichoo.blogspot.com/feeds/1061516948726368164/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8144285405079538181&amp;postID=1061516948726368164' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/1061516948726368164'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/1061516948726368164'/><link rel='alternate' type='text/html' href='http://raichoo.blogspot.com/2010/02/bitbucket-repository-fur-codeschnipsel.html' title='Bitbucket Repository für Codeschnipsel'/><author><name>Björn 'raichoo' Herzig</name><uri>https://profiles.google.com/102273886131939895778</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-KxzzpA_pbkc/AAAAAAAAAAI/AAAAAAAAARI/yHTIB2nrp8I/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8144285405079538181.post-5934681941523669681</id><published>2010-02-01T05:32:00.000-08:00</published><updated>2010-04-17T01:17:55.839-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ksh93'/><category scheme='http://www.blogger.com/atom/ns#' term='Mercurial'/><title type='text'>KSH93: Mercurial Promptmode</title><content type='html'>Nach dem großartigen &lt;a href="http://stevelosh.com/blog/2010/02/my-extravagant-zsh-prompt/#oh-my-zsh"&gt;Blogeintrag von Steve Losh&lt;/a&gt; und seinem ZSH-Mercurial Prompt habe ich mir gedacht: "Ok, das geht auch mit der KSH". Ich verfolge allerdings einen etwas anderen Ansatz. Anstatt das meine Shell bei jedem Kommando selbst überprüft ob sie in einem Repository ist (zuviel Overhead meines Erachtens nach) habe ich unterschiedliche Modes definiert (ksh für "shell" und hg für "mercurial") zwischen denen ich mit &lt;code&gt;mode&lt;/code&gt; wechseln kann.&lt;br /&gt;Der Prompt färbt sich rot wenn sich der Status verändert hat und zeigt mir neben der Revisionsnummer auch noch den Namen das Branches an auf dem ich gerade bin :)&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_3VHVa9AP0ZM/S2bZliOqV_I/AAAAAAAAANI/RCc1uQlkayY/s1600-h/Screen+shot+2010-02-01+at+2.31.04+PM.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 214px;" src="http://1.bp.blogspot.com/_3VHVa9AP0ZM/S2bZliOqV_I/AAAAAAAAANI/RCc1uQlkayY/s320/Screen+shot+2010-02-01+at+2.31.04+PM.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5433269239335770098" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;code&gt;&lt;pre&gt;&lt;br /&gt;&lt;br /&gt;_checkrevision() {&lt;br /&gt;    set -A HGOUTPUT $(hg id -n -b -t 2&gt; /dev/null)&lt;br /&gt;    if [[ ${HGOUTPUT[0]} != "" ]]&lt;br /&gt;    then&lt;br /&gt;        if grep '+' &lt;(echo ${HGOUTPUT[0]}) &gt; \&lt;br /&gt;/dev/null 2&gt; /dev/null&lt;br /&gt;        then&lt;br /&gt;            print ":${BOLD}${RED}${HGOUTPUT[0]}${NORM}\&lt;br /&gt;@${CYAN}${HGOUTPUT[1]}${NORM}" &amp;&amp; return&lt;br /&gt;        elif grep -v 'tip' &lt;(echo ${HGOUTPUT[*]}) &gt; \&lt;br /&gt;/dev/null 2&gt; /dev/null&lt;br /&gt;        then&lt;br /&gt;            print ":${BOLD}${YELLOW}${HGOUTPUT[0]}${NORM}\&lt;br /&gt;@${CYAN}${HGOUTPUT[1]}${NORM}"\&lt;br /&gt; &amp;&amp; return&lt;br /&gt;        else&lt;br /&gt;            print ":${BOLD}${GREEN}${HGOUTPUT[0]}${NORM}\&lt;br /&gt;@${CYAN}${HGOUTPUT[1]}${NORM}"\&lt;br /&gt; &amp;&amp; return&lt;br /&gt;        fi  &lt;br /&gt;    fi  &lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;mode() {&lt;br /&gt;    if [[ $1 == 'ksh' ]]&lt;br /&gt;    then&lt;br /&gt;        export PS1='${NORM}\[${USERCOL}${USER}${NORM}\@\&lt;br /&gt;${HOSTCOL}${HOSTNAME}${NORM}\:${BLUE}$(_checkdir)\&lt;br /&gt;${NORM}]\:${RED}${HISTCMD}${NORM}\&gt; '&lt;br /&gt;    elif [[ $1 == 'hg' ]]&lt;br /&gt;    then&lt;br /&gt;        export PS1='${PURPLE}☿${NORM}$(_checkrevision)&gt; ' &lt;br /&gt;    fi  &lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;Das ist jetzt die erste Version. Mal sehen wie sich das gute Stück noch weiterentwickelt :)&lt;br /&gt;&lt;br /&gt;&lt;b&gt;UPDATE&lt;/b&gt;: Hab den Code noch mal um einiges verbessert.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8144285405079538181-5934681941523669681?l=raichoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://raichoo.blogspot.com/feeds/5934681941523669681/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8144285405079538181&amp;postID=5934681941523669681' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/5934681941523669681'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/5934681941523669681'/><link rel='alternate' type='text/html' href='http://raichoo.blogspot.com/2010/02/ksh93-mercurial-promptmode.html' title='KSH93: Mercurial Promptmode'/><author><name>Björn 'raichoo' Herzig</name><uri>https://profiles.google.com/102273886131939895778</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-KxzzpA_pbkc/AAAAAAAAAAI/AAAAAAAAARI/yHTIB2nrp8I/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_3VHVa9AP0ZM/S2bZliOqV_I/AAAAAAAAANI/RCc1uQlkayY/s72-c/Screen+shot+2010-02-01+at+2.31.04+PM.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8144285405079538181.post-1867310326496134517</id><published>2010-01-04T16:49:00.000-08:00</published><updated>2010-01-04T17:44:35.195-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Python'/><title type='text'>Quicksort in Python</title><content type='html'>Und einfach nochmal weils so schön ist:&lt;br /&gt;&lt;code&gt;&lt;pre&gt;&lt;br /&gt;def partition(f, a): &lt;br /&gt;    l = []&lt;br /&gt;    r = []&lt;br /&gt;    for i in a:&lt;br /&gt;        if f(i):&lt;br /&gt;            l.append(i)&lt;br /&gt;        else:&lt;br /&gt;            r.append(i)&lt;br /&gt;    return l,r &lt;br /&gt;&lt;br /&gt;def qs(a):&lt;br /&gt;    if a == []: &lt;br /&gt;        return a&lt;br /&gt;    return  qs([x for x in a[1:] if x &lt; a[0]]) \&lt;br /&gt;            + [a[0]] + \&lt;br /&gt;            qs([x for x in a[1:] if x &gt;= a[0]])&lt;br /&gt;&lt;br /&gt;def qs2(a):&lt;br /&gt;    if a == []: &lt;br /&gt;        return a&lt;br /&gt;    l,g = partition(lambda x: x &lt; a[0], a[1:])&lt;br /&gt;    return qs2(l) + [a[0]] + qs2(g)&lt;br /&gt;&lt;br /&gt;a = [4,6,3,5,1,2,7,0,9,8]&lt;br /&gt;&lt;br /&gt;print qs(a)&lt;br /&gt;print qs2(a)&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;Und die Ersties bei mir an der Uni beschweren sich darüber das sie funktionale Programmierung lernen müssen -_-&lt;br /&gt;&lt;br /&gt;&lt;b&gt;UPDATE&lt;/b&gt;: Das ganze geht noch schöner mit Python List Comprehensions&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8144285405079538181-1867310326496134517?l=raichoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://raichoo.blogspot.com/feeds/1867310326496134517/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8144285405079538181&amp;postID=1867310326496134517' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/1867310326496134517'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/1867310326496134517'/><link rel='alternate' type='text/html' href='http://raichoo.blogspot.com/2010/01/quicksort-in-python.html' title='Quicksort in Python'/><author><name>Björn 'raichoo' Herzig</name><uri>https://profiles.google.com/102273886131939895778</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-KxzzpA_pbkc/AAAAAAAAAAI/AAAAAAAAARI/yHTIB2nrp8I/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8144285405079538181.post-2340340534295544617</id><published>2010-01-04T11:55:00.000-08:00</published><updated>2010-01-04T14:16:30.901-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='Python'/><title type='text'>Ein Hauch von Python</title><content type='html'>Ich spiele ja in letzter Zeit sehr viel mit Ruby und Python herum. Was mir an Python besonders gefällt sind unter anderem Generatoren. Damit kann man schöne Sachen machen.&lt;br /&gt;&lt;code&gt;&lt;pre&gt;&lt;br /&gt;def test():&lt;br /&gt;    for i in range(0,3):&lt;br /&gt;        yield i&lt;br /&gt;&lt;br /&gt;x = test()&lt;br /&gt;&lt;br /&gt;for i in x:&lt;br /&gt;    print i&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;Einen ähnlichen Effekt kann man unter Ruby mit Enumeratoren hinkriegen&lt;br /&gt;&lt;code&gt;&lt;pre&gt;&lt;br /&gt;class Test&lt;br /&gt;    def each&lt;br /&gt;        if block_given?&lt;br /&gt;            for i in 0...3&lt;br /&gt;                yield i&lt;br /&gt;            end&lt;br /&gt;        else&lt;br /&gt;            Enumerator.new(self)&lt;br /&gt;        end &lt;br /&gt;    end &lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;t = Test.new&lt;br /&gt;e = t.each&lt;br /&gt;&lt;br /&gt;for i in e&lt;br /&gt;    puts i&lt;br /&gt;end&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;Ich gebe zu das ich hier ziemlich geschummelt habe und Python Generatoren über das hinausgehen was ich hier in Ruby zeige. Aber es kann hin und wieder mal recht praktisch sein ;)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8144285405079538181-2340340534295544617?l=raichoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://raichoo.blogspot.com/feeds/2340340534295544617/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8144285405079538181&amp;postID=2340340534295544617' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/2340340534295544617'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/2340340534295544617'/><link rel='alternate' type='text/html' href='http://raichoo.blogspot.com/2010/01/ein-hauch-von-python.html' title='Ein Hauch von Python'/><author><name>Björn 'raichoo' Herzig</name><uri>https://profiles.google.com/102273886131939895778</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-KxzzpA_pbkc/AAAAAAAAAAI/AAAAAAAAARI/yHTIB2nrp8I/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8144285405079538181.post-188442553724528939</id><published>2010-01-04T08:41:00.001-08:00</published><updated>2010-01-04T17:45:28.900-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Ruby'/><title type='text'>Quicksort in Ruby</title><content type='html'>Angestachelt vom Alios' kurzer Illustration von Quicksort in Haskell hab ich mir mal überlegt ob man das gleiche auch in Ruby 1.9 so schreiben kann. Man kann ;)&lt;br /&gt;&lt;code&gt;&lt;pre&gt;&lt;br /&gt;def qs(a)&lt;br /&gt;    return a if a == []&lt;br /&gt;    (qs a.drop(1).find_all{|x| x &lt; a[0]}) \&lt;br /&gt;    + [a[0]] + \&lt;br /&gt;    (qs a.drop(1).find_all{|x| x &gt;= a[0]})&lt;br /&gt;end&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;Ich finde das ganze zeigt sehr eindrucksvoll wie mächtig moderne Sprachen sind die OOP und FP vereinen. Prinzipiell kann man das Ding auch twittern :P (darum die kurzen Namen)&lt;br /&gt;&lt;br /&gt;&lt;b&gt;UPDATE&lt;/b&gt;: Da konnte man noch etwas verkürzen ^^&lt;br /&gt;&lt;br /&gt;&lt;b&gt;UPDATE 2&lt;/b&gt;: Für alle denen 2 Array Durchläufe mit find_all zuviel sind gibts hier auch noch eine etwas nettere Version ;)&lt;br /&gt;&lt;code&gt;&lt;pre&gt;&lt;br /&gt;def qs(a)&lt;br /&gt;    return a if a.empty?&lt;br /&gt;    l, g = a.drop(1).partition{|x| x &lt; a[0]}&lt;br /&gt;    (qs l) + [a[0]] + (qs g)&lt;br /&gt;end&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8144285405079538181-188442553724528939?l=raichoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://raichoo.blogspot.com/feeds/188442553724528939/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8144285405079538181&amp;postID=188442553724528939' title='2 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/188442553724528939'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/188442553724528939'/><link rel='alternate' type='text/html' href='http://raichoo.blogspot.com/2010/01/quicksort-in-ruby.html' title='Quicksort in Ruby'/><author><name>Björn 'raichoo' Herzig</name><uri>https://profiles.google.com/102273886131939895778</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-KxzzpA_pbkc/AAAAAAAAAAI/AAAAAAAAARI/yHTIB2nrp8I/s512-c/photo.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8144285405079538181.post-1239463290550277159</id><published>2009-11-06T02:10:00.000-08:00</published><updated>2009-11-06T02:47:40.172-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='MacOSX'/><category scheme='http://www.blogger.com/atom/ns#' term='FreeBSD'/><category scheme='http://www.blogger.com/atom/ns#' term='ksh93'/><category scheme='http://www.blogger.com/atom/ns#' term='OpenSolaris'/><title type='text'>By popular demand: Meine .kshrc</title><content type='html'>Ich werde des öfteren mal nach meinen Einstellungen für die ksh93 die ich als meine Defaultshell auf allen Systemen die ich derzeit aktiv verwende einsetze. Der Commandeditor fc hat es mir in dieser Shell besonders angetan ganz zu schweigen davon das sie im Vergleich zu anderen Shells ziemlich bugfrei ist.&lt;br /&gt;&lt;br /&gt;Für alle nicht vi-User &lt;b&gt;VORSICHT&lt;/b&gt;: Diese Config kommt mit aktiviertem vi-Modus daher ;) Außerdem habe ich PS ein wenig blogtauglicher formatiert.&lt;br /&gt;&lt;br /&gt;Noch ein Tipp für die Mac-User: die ksh in der Standardinstallation ist ziemlich veraltet. Schnappt euch &lt;a href="http://www.macports.org"&gt;Macports&lt;/a&gt; und installiert sie euch daraus. Danach die neue Shell in die &lt;code&gt;/etc/shells&lt;/code&gt; eintragen und &lt;code&gt;sudo chsh -s /opt/local/bin/ksh username&lt;/code&gt; und ksh93 ist eure Defaultshell.&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;pre&gt;&lt;br /&gt;set -o noclobber&lt;br /&gt;set -o ignoreeof&lt;br /&gt;set -o globstar&lt;br /&gt;set -o vi&lt;br /&gt;&lt;br /&gt;HISTFILE=$HOME/.histfile.$(tty | cut -d/ -f 3)&lt;br /&gt;RED=$(print -n "\033[0;31m")&lt;br /&gt;GREEN=$(print -n "\033[0;32m")&lt;br /&gt;YELLOW=$(print -n "\033[0;33m")&lt;br /&gt;BLUE=$(print -n "\033[0;34m")&lt;br /&gt;PURPLE=$(print -n "\033[0;35m")&lt;br /&gt;CYAN=$(print -n "\033[0;36m")&lt;br /&gt;WHITE=$(print -n "\033[0;38m")&lt;br /&gt;&lt;br /&gt;export HOSTNAME=$(hostname)&lt;br /&gt;export EDITOR="vim"&lt;br /&gt;export HISTEDIT="vim"&lt;br /&gt;&lt;br /&gt;_checkdir() {&lt;br /&gt;    if [[ $PWD == $HOME ]]&lt;br /&gt;    then&lt;br /&gt;        print -n "~"&lt;br /&gt;    elif [[ $PWD == "/" ]]&lt;br /&gt;    then&lt;br /&gt;        print $PWD&lt;br /&gt;    else&lt;br /&gt;        print -n ${PWD##*/} &lt;br /&gt;    fi&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;if [[ $(uname) == "Darwin" ]]&lt;br /&gt;then&lt;br /&gt;    export PS1='${WHITE}[${GREEN}${USER}${WHITE}@${YELLOW}\&lt;br /&gt;${HOSTNAME}${WHITE}:${BLUE}$(_checkdir)${WHITE}]:\&lt;br /&gt;${RED}$HISTCMD${WHITE}&gt; '&lt;br /&gt;    alias ls='ls -FG'&lt;br /&gt;    alias pkill='killall'&lt;br /&gt;    alias pgrep='ps -A | grep -i'&lt;br /&gt;    alias grep='grep --color=always'&lt;br /&gt;elif [[ $(uname) == "SunOS" ]]&lt;br /&gt;then&lt;br /&gt;    export PS1='[${WHITE}[${GREEN}${USER}${WHITE}@${CYAN}\&lt;br /&gt;${HOSTNAME}${WHITE}:${BLUE}$(_checkdir)${WHITE}]:\&lt;br /&gt;${RED}${HISTCMD}${WHITE}&gt; '&lt;br /&gt;    export PATH="/bin:/sbin:/usr/bin:/usr/sbin:\&lt;br /&gt;/opt/SunStudioExpress/bin:$PATH"&lt;br /&gt;    alias ls='ls -F'&lt;br /&gt;elif [[ $(uname) == "FreeBSD" ]]&lt;br /&gt;then&lt;br /&gt;    export PS1='[${WHITE}[${GREEN}${USER}${WHITE}@${PURPLE}\&lt;br /&gt;${HOSTNAME}${WHITE}:${BLUE}$(_checkdir)${WHITE}]:\&lt;br /&gt;${RED}${HISTCMD}${WHITE}&gt; '&lt;br /&gt;    alias ls='ls -FG'&lt;br /&gt;    alias pkill='killall'&lt;br /&gt;    alias grep='grep --color=always'&lt;br /&gt;    alias pgrep='ps -A | grep -i'&lt;br /&gt;fi&lt;br /&gt;     &lt;br /&gt;alias !!='fc -s -1'&lt;br /&gt;alias vi='vim'&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8144285405079538181-1239463290550277159?l=raichoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://raichoo.blogspot.com/feeds/1239463290550277159/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8144285405079538181&amp;postID=1239463290550277159' title='2 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/1239463290550277159'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/1239463290550277159'/><link rel='alternate' type='text/html' href='http://raichoo.blogspot.com/2009/11/by-popular-demand-meine-kshrc.html' title='By popular demand: Meine .kshrc'/><author><name>Björn 'raichoo' Herzig</name><uri>https://profiles.google.com/102273886131939895778</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-KxzzpA_pbkc/AAAAAAAAAAI/AAAAAAAAARI/yHTIB2nrp8I/s512-c/photo.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8144285405079538181.post-7576549850318826334</id><published>2009-09-15T05:58:00.001-07:00</published><updated>2009-09-15T06:05:28.252-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Politik'/><title type='text'>Gespiegelt: Festnahme auf "Freiheit statt Angst"</title><content type='html'>Ich bin so frei und spiegele ebenfalls &lt;a href="http://www.alios.org/blog/2009/09/mein-festnahme-bei-der-freiheit-statt-angst-2009/"&gt;einen Blogeintrag&lt;/a&gt; der dazu führt das diverse Blogs derzeit den Geist unter der Last aufgeben.&lt;br /&gt;&lt;br /&gt;&lt;i&gt;Am Wochenende des 11.-13. September 2009 fand in Berlin die Demonstration „Freiheit statt Angst“ statt. Ich war am Freitag gegen Abend in Berlin angekommen und kam am frühen Samstag Mittag mit der U-Bahn am Potsdamer Platz an, von dem aus die Demonstration starten sollte. Beim Betreten des Platzes zwischen Sony Center und Daimler Chrysler City wurde ich von einem Polizisten der Bereitschaftspolizei freundlich angesprochen, ob er einen Blick in meinen Rucksack werfen dürfe. Ich gestattete ihm dies ebenso freundlich. Während er den Inhalt meines Rucksacks untersuchte (eine Regenjacke, eine Wasserflasche) fragte er, ob ich irgendwelche spitzen Gegenstände mit mir führte. Tatsächlich hatte ich – wie immer – mein Letherman Tool, eine Art Multifunktionswerkzeug, im Rucksack. Dies gab ich an und suchte es auf Nachfrage aus dem Rucksack. Ich erklärte mein Letherman dem Polizisten, der das Werkzeug nicht kannte und zeigte ihm auch, dass sich ein Messer zwischen den Werkzeugen befindet. Der Polizist begutachtete das Tool und erklärte mir dann, dass das Mitführen eines Messers auf Demonstrationen nicht erlaubt sei. Er fragte, ob ich das Messer noch schnell nach Hause bringen könnte. Das konnte ich nicht, denn ich bin ja kein Berliner. Der Polizist bot mir daraufhin an, das Messer bei der Polizei vor Ort abzugeben und es nach der Veranstaltung wieder abzuholen. Ich willigte ein. &lt;br /&gt;Gemeinsam gingen wir um die Ecke in die Potsdamer Straße, wo mehrere Einsatzwagen der Polizei standen. Der mich begleitende Polizist erklärte seinen Kollegen, dass ich das Tool abgeben wolle. Der Ton der dort wartenden Beamten war deutlich unfreundlicher, ich wurde abgetastet und sollte meinen Rucksack in einen der Mannschaftswagen stellen. Auf Nachfrage wurde mir gesagt, dass dies aus Sicherheitsgründen geschehe, damit ich keine Waffe aus dem Rucksack ziehen könne. Meinen Personalausweis stellte ich bereitwillig zur Verfügung, um das Ausstellen der Formulare zu erleichtern. Während nun ein weiterer Polizist abseits an einem anderen Wagen die Formulararbeit machte, erklärte der Beamte, der mich ursprünglich angesprochen hatte, seinen Kollegen, dass er das Tool nicht gefunden hätte, sondern dass ich es ihm ausgehändigt hätte, wonach die Behandlung und der Ton mir gegenüber deutlich freundlicher wurde.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Ich erkundigte mich, wo ich das Tool später wieder abholen könne. Ich könne es im “Abschnitt 34″, Alt Moabit 145 wieder abholen, wurde mir mitgeteilt. Dann wurde ich gefragt, ob ich “schon mal Kontakt mit der Polizei” gehabt habe: Nein. Auf Nachfrage, warum mir diese Frage gestellt wurde, sagte mir der Beamte, dass eine routinemäßige Kontrolle über Funk meiner Person erfolgen würde. Kurze Zeit später kam der Polizist mit dem Formular wieder und eröffnete mir, dass über Funk die Order ergangen sei, dass gegen mich eine Anzeige geschrieben werden müsse. Ich war total entsetzt, doch die umstehenden Polizisten versicherten mir, dies sei kein Problem und nur ein formaler Akt; die Staatsanwaltschaft würde das Verfahren voraussichtlich automatisch wieder einstellen.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Meinen Schrecken minderte das wenig, doch als erstes sollte ich das Protokoll über die, wie es mittlerweile hieß, “Beschlagnahme” des Tools unterschreiben, was ich auch tat. Wider Erwarten durfte ich nun nicht zur Demonstration gehen, sondern musste mit aufs Polizeipräsidium kommen, ein Fahrzeug war bereits auf dem Weg, um mich abzuholen. Der Polizist, der mich am Platz angesprochen hatte, registrierte meine aufkeimende Panik und versuchte, mich zu beruhigen. Auch er habe damit nicht gerechnet. Aber er könne nichts tun. Dies sei eine Anweisung “von oben”.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Eine Anweisung von oben war offensichtlich auch der vergitterte Wagen, in dessen Zelle ich eingeschlossen und abtransportiert wurde. Zu diesem Zeitpunkt hatte ich nichts mehr bei mir außer den Durchschlag des Formulars über die Beschlagnahme. Mein Rucksack mit komplettem Inhalt (Handy, Fotoapparat, Schlüssel, Geldbörse etc.) hatte der Beamte in der Fahrerkabine. Ich studierte den Durchschlag: Dort war angekreuzt: Festgenommen. Nun brach ich erstmal vollständig zusammen… Auf Nachfrage, was mir vorgeworfen würde und warum ich festgenommen sei und warum ich in einer Gefängniszelle sitze wurde mir gesagt, dies würde ich auf dem Präsidium erfahren, es sei aber alles nicht so schlimm und festgenommen höre sich viel schlimmer an als es sei.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Der Wagen wollte gerade losfahren, hielt dann aber noch mal wieder an – es sei noch zu einer weiteren Festnahme gekommen und wir müssen noch kurz warten um eine weitere Person mitzunehmen. Der Polizist der bis dahin noch mit hinten im Wagen (außerhalb der Zelle) saß und sozusagen meinen einzigen Ansprechpartner dar stellte, verließ daraufhin das Fahrzeug wieder und ließ mich allein. Total aufgelöst versuchte ich den Beamten vorne im Fahrzeug anzusprechen: was los sei und ob ich noch mal an die frische Luft könne, da mir schlecht sei von der stickigen Luft (und der Situation) sei. Erst nach mehrmalige Ansprache sagte er kurz es ginge gleich weiter und schob das Sichtfenster zwischen Fahrer Bereich und dem hinteren Teil des Wagens zu.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Nach geschätzten 10 Minuten stiegen der Beamte von zuvor, eine Kollegin und ein weiterer scheinbar festgenommener Junge ein Wir fuhren darauf hin los. Nach etwa 10min Fahrt kamen wir an einer PolizeiwWache an und wurden hinein geführt. Nach kurzem Warten vor einer Tür wurden wir herein gelassen und ich wurde in eine Zelle geführt,die Tür wurde hinter mir verschlossen. Kurz Zeit später wurde ich wieder aus der Zelle geholt und sollte mich auf dem Flur vor eine Wand stellen, wo ein Beamter mit einer Digitalkamera Fotos von mir machte. Anschließend wurde ich wieder in die Zelle zurück geführt. Nach geschätzten weitern 10 Minuten wurde ich in einen weiteren Raum geführt, wo zwei Beamten auf mich warteten. Mein Rucksack wurde nun noch mal vollständig entleert und der Inhalt protokolliert. Während dessen fragte mich einer der Protokoll führende Beamte ob ich mit einer Blutprobe einverstanden sei; ich fragte, wozu. Mir wurde erklärt, dies sei eine StandardfFrage für ein Standardformular und es würde jeder gefragt. Darauf verweigerte ich die Entnahme eine Blutprobe formell, was in dem Formular vermerkt wurde.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Im Anschluss wurde ich aufgefordert mich bis auf die Unterhose auszuziehen (das Recht diese doch recht unangenehme Situation verweigern zu können kannte ich zu dem Zeitpunkt leider nicht) und meine Anziehsachen wurden erneut durchsucht. Nach kurzer Zeit erhielt ich sie zurück, durfte ich mich wieder anziehen, musste noch meinen Gürtel und meine Schnürsenkel abgeben und unterschrieb das Protokoll in dem alles was ich bei mir hatte aufgeführt war.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Mein Frage was mir denn nun vorgeworfen würde konnte der Beamte wieder nicht beantwortet: “das wisse er nicht, er sei nur dazu da meine Sachen aufzunehmen”. Ich fragte was den nun passieren würde und er sagte mir, dass ich vermutlich gleich befragt würde und ich dann auch Antwort auf meine Fragen erhalten würde. Ich schilderte den beiden anwesenden Beamten noch mal den Sachverhalt und sie erklärten mir, ich würde bestimmt schnell wieder entlassen, er führe schließlich auch meist sein Taschenmesser mit sich und ich hätte es ja freiwillig abgegeben.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Nach dem ich anschließend wieder in eine Zelle gesperrt worden war, begann das lange Warten. Von Zeit zu Zeit wurde die Tür kurz geöffnet und direkt wieder geschlossen – bei jedem Mal dachte ich, es würde nun endlich weiter gehen und ich würde endlich erfahren, was mir eigentlich vorgeworfen wurde, dem war aber leider nicht so. Als wieder einmal die Tür geöffnet wurde, fragte ich schnell nach der Uhrzeit – es war mittlerweile 16.15 Uhr. Ich saß also mittlerweile seit fast 4 Stunden fest und wusste immer noch nicht, warum. Es muss etwa 17.00 Uhr gewesen sein, als ich endlich aufgefordert wurde, mitzukommen. Meine Hoffnung nun endlich mit einem Ermittler sprechen zu können um den ganzen Sachverhalt aufzuklären, wurde aber leider wieder enttäuscht. Stattdessen wurde in einen Raum, ein Stockwerk tiefer, zum “LKA Berlin Erkennungsdienst” geführt.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Auch den drei Beamten dort schilderte ich unter Tränen nochmals den ganzen Sachverhalt und fragte, ob ich der Erkennungsdienstlichen Erfassung denn wenigstens formell widersprechen könne, da es sich doch ganz klar um ein Missverständnis handele – dies wurde verneint und ein Schild an der Wand wies mich mittels eines Paragraphen darauf hin, dass die Erkennungsdienstlichen Maßnahmen notfalls auch mit Gewalt durchgeführt werden könnten. Ich könne aber mit Hilfe eines Anwalts im Nachhinein der Maßnahme widersprechen, wozu er mir auch raten würde. Meine Frage, wer die Maßnahme angeordnet hätte, wurde mir mit einem Buchstabenabkürzung beantwortet, deren Bedeutung mir die anwesenden Beamten aber nicht erklären konnten oder wollten. Es wurden meine Fingerabdrücke von beiden Händen (alle Finger und komplette Hand), in doppelter Ausführung genommen, sowie erneut Fotos, offensichtlich für die Verbrecherkartei,gemacht.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Zurück in der Zelle betätigte ich nach kurzer Zeit die Klingel, es muss mittlerweile etwa 18.00 gewesen sein, um darum zu bitten meinen Rechtsanwalt anrufen zu können, da ich anfing zu befürchten auch noch die Nacht in der Zelle zuzubringen zu müssen. Wieso hast du das denn nichtvorher gefragt? Kommt hier komisch. Dies konnte der Polizist nicht entscheiden, versprach mir aber, seinen Vorgesetzten zu informieren und ihn zu mir zu schicken. Als nach einer geschätzten halben Stunde immer noch nichts passiert war, schellte ich erneut – ich fühlte mich zu diesem Zeitpunkt schon völlig ausgelaugt und fertig, was man mir auch anzusehen schien, da die Beamtin mit der ich sprach mir sagte es würden „jetzt erstmal die Sanitäter kommen“.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Zum Glück bestätigte sich meine erste Befürchtung, nun auch noch in eine psychiatrische Klinik verlegt zu werden, nicht (nichts erschien mir mehr unmöglich), sondern der Polizeisanitäter holte mich ab und wir gingen in seinen Behandlungsraum. Physiologisch wies ich zu diesem Zeitpunkt eine ausgeprägte Hypertonie (hoher Blutdruck) und einen sehr schnellen Puls auf. Die Vermutung, dass ich vermutlich absolut dehydriert war, schien plausibel, denn außer eine Tasse Kaffe zum Frühstück und einen kleinen Plastikbecher Tee, den ich nach mehrmaliger Nachfrage erhalten hatte, hatte ich den ganzen Tag noch nichts getrunken. Hier kam ich das erste Mal wieder etwas zur Ruhe und hatte das Gefühl als Mensch ernst- und wahrgenommen zu werden. Der Beamte sagte mir dann auch, dass er gehört hätte, dass ich vermutlich in der nächsten Stunde entlassen würde.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Nach einem anschließenden weiteren kurzen Aufenthalt in der Zelle erhielt ich gegen 19.30 tatsächlich alle meine Sachen (bis auf das Letherman Tool) zurück und konnte die Polizeiwache verlassen.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Bis zum heute weiß ich nicht was mir eigendlich vorgeworfen wurde. Meinen Anwalt habe ich bereits kontaktiert und es wird sich wohl in den nächsten Wochen zeigen wie es weiter geht. Mein vorrangiges Ziel ist natürlich mit meinen Fingerabdrücken und meinen Fotos wieder aus der Datei des LKAs heraus zu kommen.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Ich kann sagen, daß die Ereignisse vom Samstag das schlimmste sind was mir in meinem Leben bisher passiert ist. Die Aussage das Freiheitsentzug mit das brutalste ist, was man einer menschlichen Seele antun kann, kann ich voll bestätigen – nie zuvor habe ich mich so ängstlich und hilflos gefühlt.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Das man Angst haben muss, und die habe ich im Moment noch, auf einer friedlichen Demonstartion scheinbar grundlos von der Polizei verprügelt oder verhaftet zu werden, kommt in meinen Augen faktisch einer massiven Einschränkung des Demonstrationsrechts gleich.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Ebenfalls schockierend fand ich wie der Staatsapperat einmal ins Rollen gebracht, nicht wieder zu stoppen war. Persöhnlich kann man wohl kaum einem der Beteiligten der Exekutive einen Vorwurf machen – ein Jeder der Beteiligten konnte sich darauf berufen nur Befehle und Anweisungen ausgeführt zu haben. Diese Argumentation habe ich bisher nur von Angehörigen ehemaliger Unrechtsregimen gehört – ich habe mir eigendlich immer verboten ernsthaft zu glauben, daß so etwas im Rechtsstaat Bundesrepublik Deutschland tatsächlich möglich ist – wurde aber schmerzlich eines besseren belehrt.&lt;/i&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8144285405079538181-7576549850318826334?l=raichoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://raichoo.blogspot.com/feeds/7576549850318826334/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8144285405079538181&amp;postID=7576549850318826334' title='2 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/7576549850318826334'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/7576549850318826334'/><link rel='alternate' type='text/html' href='http://raichoo.blogspot.com/2009/09/gespiegelt-festname-auf-freiheit-statt.html' title='Gespiegelt: Festnahme auf &quot;Freiheit statt Angst&quot;'/><author><name>Björn 'raichoo' Herzig</name><uri>https://profiles.google.com/102273886131939895778</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-KxzzpA_pbkc/AAAAAAAAAAI/AAAAAAAAARI/yHTIB2nrp8I/s512-c/photo.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8144285405079538181.post-333769403169312452</id><published>2009-09-06T03:32:00.000-07:00</published><updated>2009-09-06T04:46:10.021-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='MacOSX'/><category scheme='http://www.blogger.com/atom/ns#' term='FreeBSD'/><category scheme='http://www.blogger.com/atom/ns#' term='DragonflyBSD'/><category scheme='http://www.blogger.com/atom/ns#' term='C++'/><title type='text'>Bug: Snow Leopard's dynamic_cast und explizit instanziierte C++ Templates</title><content type='html'>Derzeit arbeite ich an einem Projekt welches ich auf dem Mac (allerdings nicht für den Mac) entwickle. Dabei verwende ich unter anderem auch gerne die RTTI (RunTime Type Information) Fähigkeiten von C++ die mir unter anderem auch sichere Downcasts zur Verfügung stellen (Ist ein Downcast nicht möglich wird der Nullpointer zurückgegeben). Das alles klappt durchaus gut, es sei denn ich schreibe eine Lib in der ich bereits die Templates instanziiere die ich später in meiner Applikation nutzen will. Alles kompiliert zwar wunderbar und das Template lässt sich ebenfalls nutzen sobald ich aber auf Polymorphie zurückgreife wird es hässlich, da anscheinend die Typinformationen verloren gehen und dynamic_cast nicht mehr in der Lage ist richtig zu arbeiten.&lt;br /&gt;&lt;br /&gt;Der ganze Fehler lässt sich mit folgendem Testfall reproduzieren:&lt;br /&gt;&lt;code&gt;&lt;pre&gt;&lt;br /&gt;&lt;br /&gt;//TestLib.hpp&lt;br /&gt;class Base {&lt;br /&gt;public:&lt;br /&gt;    virtual ~Base() {}&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;template &amp;lt;typename T&amp;gt;&lt;br /&gt;class Derived : public Base {&lt;br /&gt;public:&lt;br /&gt;    Derived();&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;/*TestLib.cpp&lt;br /&gt;* compile with: g++ -dynamiclib TestLib.cpp -o libTestLib.dylib&lt;br /&gt;*/&lt;br /&gt;#include "TestLib.hpp"&lt;br /&gt;#include &amp;lt;typeinfo&amp;gt;&lt;br /&gt;#include &amp;lt;iostream&amp;gt;&lt;br /&gt;&lt;br /&gt;template &amp;lt;typename T&amp;gt;&lt;br /&gt;Derived&amp;lt;T&amp;gt;::Derived() {&lt;br /&gt;    std::cout &amp;lt;&amp;lt; typeid(*this).name() &amp;lt;&amp;lt; std::endl;    &lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;template class Derived&amp;lt;int&amp;gt;;&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;Wie man in der letzten Zeile sieht wird das Template &lt;code&gt;Derived&lt;/code&gt; explizit mit &lt;code&gt;int&lt;/code&gt; in TestLib.cpp instanziiert. Diesen Typen werden wir jetzt in einer kleinen Anwendung etwas durch die Typhierarchie scheuchen und ein sehr seltsames Verhalten beobachten.&lt;br /&gt;&lt;code&gt;&lt;pre&gt;&lt;br /&gt;/* main.cpp&lt;br /&gt;* compile with: g++ -L. -lTestLib main.cpp -o main&lt;br /&gt;*/&lt;br /&gt;#include "TestLib.hpp"&lt;br /&gt;#include &amp;lt;iostream&amp;gt;&lt;br /&gt;&lt;br /&gt;int main() {&lt;br /&gt;    Derived&amp;lt;int&amp;gt;* i = new Derived&amp;lt;int&amp;gt;();&lt;br /&gt;    std::cout &amp;lt;&amp;lt; typeid(*i).name() &amp;lt;&amp;lt; std::endl;&lt;br /&gt;    Base *o = i;&lt;br /&gt;    std::cout &amp;lt;&amp;lt typeid(*o).name() &amp;lt;&amp;lt std::endl;&lt;br /&gt;    std::cout &amp;lt;&amp;lt o &amp;lt;&amp;lt std::endl;&lt;br /&gt;    std::cout &amp;lt;&amp;lt dynamic_cast&amp;lt; Derived&amp;lt;int&amp;gt;* &amp;gt;(o) &amp;lt;&amp;lt std::endl;&lt;br /&gt;    std::cout &amp;lt;&amp;lt typeid(*o).name() &amp;lt;&amp;lt std::endl;&lt;br /&gt;    delete i;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;Wir erhalten folgende Ausgabe:&lt;br /&gt;&lt;code&gt;&lt;pre&gt;&lt;br /&gt;7DerivedIiE&lt;br /&gt;7DerivedIiE&lt;br /&gt;0x100100080&lt;br /&gt;0&lt;br /&gt;7DerivedIiE&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;Die Typid verändert sich nicht und trotzdem liefert ein gültiger Downcast den Nullpointer zurück. Ich habe den Code ebenfalls unter FreeBSD und DragonflyBSD getestet, in beiden Fällen war der Downcast erfolgreich. Meines Wissens tritt dieses Verhalten erst seit Snow Leopard auf, aber da ich derzeit nirgends eine aktuelle Version von Leopard laufen habe kann ich nicht testen ob es sich hier um einen neuen Bug handelt.&lt;br /&gt;&lt;br /&gt;Der einzige Workaround der mir derzeit einfällt ist die Instanziierung des Templates in die Compilezeit der Anwendung zu verlegen.&lt;br /&gt;&lt;br /&gt;UPDATE: Mal ein delete nachgebessert, nicht das sich hier noch jemand beschwert das mein Testcase leakt :P&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8144285405079538181-333769403169312452?l=raichoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://raichoo.blogspot.com/feeds/333769403169312452/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8144285405079538181&amp;postID=333769403169312452' title='2 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/333769403169312452'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/333769403169312452'/><link rel='alternate' type='text/html' href='http://raichoo.blogspot.com/2009/09/bug-snow-leopards-dynamiccast-und.html' title='Bug: Snow Leopard&apos;s dynamic_cast und explizit instanziierte C++ Templates'/><author><name>Björn 'raichoo' Herzig</name><uri>https://profiles.google.com/102273886131939895778</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-KxzzpA_pbkc/AAAAAAAAAAI/AAAAAAAAARI/yHTIB2nrp8I/s512-c/photo.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8144285405079538181.post-1438091840444261319</id><published>2009-08-15T09:55:00.001-07:00</published><updated>2009-08-19T14:01:42.642-07:00</updated><title type='text'>Ein Hackerspace für Münster und Umgebung.</title><content type='html'>Kaffee ist eine wunderbare Sache, vor allem wenn man ihn trinkt während man Ideen ausarbeitet. Heute war wieder einer dieser Tage. Angestachelt vom CRE zum Thema Hackerspaces hat ein Freund von mir den Entschluss gefasst ein solches Projekt in die Wege zu leiten. Ein Name war schnell gefunden: Warpzone.&lt;br /&gt;&lt;br /&gt;Die Grundidee der Warpzone ist es, ein angemessenes Umfeld für kreative Köpfe allen Alters und Geschlechts zu bieten in dem sie sich frei entfalten können. Ein Stück Kultur also. Während so ziemlich jede Subkultur einen Platz hat an dem sie Freitag und Samstag abends rausgeht und sich selbst feiert, sind Nerds und Hacker oft isoliert im stillen Kämmerlein. Das ist hin und wieder schon gewünscht aber sozialer Kontakt wird doch schon mal hin und wieder vermisst und unter Gleichgesinnten ist man oft zu kreativen Leistungen im stande die man selber nicht für möglich gehalten hätte.&lt;br /&gt;&lt;br /&gt;Was soll die Warpzone werden? Atmosphäre hat eine ziemlich motivierende Kraft und genau das soll die Warpzone bieten. Wie die C-Base soll sie ihren eigenen Charakter entwickeln und sich mit ihren Besuchern weiterentwickelt. Ihr hab eine Idee wie man das Treiben in der Zone noch verbessern kann? Klasse, such dir ein paar Leute und Gründe eine Initiative die das ganze umsetzt. Außerdem soll mindestens einmal die Woche die ein Vortrag gehalten werden, jeder der etwas zu erzählen hat und etwas präsentieren will, sei es eine Neuentdeckung die man umbedingt bekannter machen will oder ein Projekt das man selber an den Start gebracht hat. Bringt euch ein und erschafft etwas!&lt;br /&gt;&lt;br /&gt;Was soll die Warpzone nicht werden? Sie soll kein Stammtisch werden in der man sich ein oder zweimal im Monat trifft und redet was man denn alles so gemacht hat. Das kann man im Zweifelsfall auch in einer Kneipe. Sie soll kein dröger Raum mit ein paar Stühlen sein in der in Redner an einem Flipchart stundenlang referiert. Wer die Warpzone betritt verlässt die normale Welt.&lt;br /&gt;&lt;br /&gt;Nun handelt es sich bei einem solchen Projekt um ein aufwändiges Unterfangen, braucht man doch Räumlichkeiten, Möbel und einfach angemessene Infrastruktur (Nerds brauchen Netz und Werkzeug). Vor allem brauchen wir aber erst einmal Leute und Ideen mit denen sich ein solches Projekt durchziehen lässt. Im Moment sind wir zwei und die Idee ist gerade mal ein paar Stunden alt. Aber bereits eine Menge Input der sich bereits realisieren lässt, jetzt fehlst nur noch DU!&lt;br /&gt;&lt;br /&gt;Ernsthafte Interessenten erreichen mich am besten über Jabber oder Twitter (siehe mein Profil). Also meldet euch und schafft ein Stück Hackerkultur im kreativen Vakuum ;)&lt;br /&gt;&lt;br /&gt;UPDATE: Wir habe inzwischen einen &lt;a href="irc://irc.freenode.org/warpzone"&gt;Chatroom auf irc.freenode.org #warpzone&lt;/a&gt; und eine &lt;a href="https://lists.dodekatex.de/cgi-bin/mailman/listinfo/warpzone"&gt;Mailing Liste&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_3VHVa9AP0ZM/SobsqQY5aQI/AAAAAAAAAME/z8OuEAqcz-w/s1600-h/00_mario_pipe.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 240px; height: 320px;" src="http://3.bp.blogspot.com/_3VHVa9AP0ZM/SobsqQY5aQI/AAAAAAAAAME/z8OuEAqcz-w/s320/00_mario_pipe.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5370239816383949058" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8144285405079538181-1438091840444261319?l=raichoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://raichoo.blogspot.com/feeds/1438091840444261319/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8144285405079538181&amp;postID=1438091840444261319' title='1 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/1438091840444261319'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/1438091840444261319'/><link rel='alternate' type='text/html' href='http://raichoo.blogspot.com/2009/08/ein-hackerspace-fur-munster-und.html' title='Ein Hackerspace für Münster und Umgebung.'/><author><name>Björn 'raichoo' Herzig</name><uri>https://profiles.google.com/102273886131939895778</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-KxzzpA_pbkc/AAAAAAAAAAI/AAAAAAAAARI/yHTIB2nrp8I/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_3VHVa9AP0ZM/SobsqQY5aQI/AAAAAAAAAME/z8OuEAqcz-w/s72-c/00_mario_pipe.jpg' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8144285405079538181.post-2547939898666321181</id><published>2009-08-14T11:47:00.001-07:00</published><updated>2009-08-14T11:48:28.128-07:00</updated><title type='text'>Auch ich leiste meinen Beitrag</title><content type='html'>Auch wenn ich der Partei nicht angehöre, konnte ich einem Remix des Plakates nicht widerstehen :D&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_3VHVa9AP0ZM/SoWxTuTRv_I/AAAAAAAAAL8/vrOyHw0iG44/s1600-h/Pirataaaaa.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 248px; height: 320px;" src="http://3.bp.blogspot.com/_3VHVa9AP0ZM/SoWxTuTRv_I/AAAAAAAAAL8/vrOyHw0iG44/s320/Pirataaaaa.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5369893083113701362" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8144285405079538181-2547939898666321181?l=raichoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://raichoo.blogspot.com/feeds/2547939898666321181/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8144285405079538181&amp;postID=2547939898666321181' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/2547939898666321181'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/2547939898666321181'/><link rel='alternate' type='text/html' href='http://raichoo.blogspot.com/2009/08/auch-ich-leiste-meinen-beitrag.html' title='Auch ich leiste meinen Beitrag'/><author><name>Björn 'raichoo' Herzig</name><uri>https://profiles.google.com/102273886131939895778</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-KxzzpA_pbkc/AAAAAAAAAAI/AAAAAAAAARI/yHTIB2nrp8I/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_3VHVa9AP0ZM/SoWxTuTRv_I/AAAAAAAAAL8/vrOyHw0iG44/s72-c/Pirataaaaa.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8144285405079538181.post-764927830187652096</id><published>2009-08-09T13:56:00.001-07:00</published><updated>2009-08-16T15:03:52.355-07:00</updated><title type='text'>Podcasts und Chaosradio Express</title><content type='html'>Heute will ich mal nicht von irgendetwas technischem schreiben sondern mich mal mit dem Medium Podcast befassen, genauer mit Chaosradio Express, einem "Spin-Off" der Mutter aller deutschen Nerd-Podcasts: dem Chaosradio. (vor allem da wir &lt;a href="https://twitter.com/timpritlove"&gt;Tim&lt;/a&gt; damit bestechen sollen Folgen zu releasen :D)&lt;br /&gt;&lt;br /&gt;Für mich selber wurde CRE eine ansprechende Alternative als es im original Chaosradio immer mehr um das Thema Überwachung und Politik ging. Versteht mich nicht falsch, das sind wichtige Themen, aber auf Weg in die Stadt oder im Zug hab ich ganz einfach auch mal gerne etwas was mich nicht total aufregt sondern "weiterbildet" (den Wutclown kann ich auch zuhause noch prügeln ^^).&lt;br /&gt;&lt;br /&gt;CRE ist für mich ein Ansporn mich mit Sachen zu befassen auf die ich oft selber gar nicht so ohne weiteres komme, sei es nur weil das Lesen von Dokumentation in vielen Fällen einfach zu mühselig ist. Der Mensch ist halt ein faules Tier.&lt;br /&gt;&lt;br /&gt;Was gefällt mir besonders gut an CRE? In erster Linie sind es die sehr technischen Themen. Meistens im Bereich Betriebssysteme oder Programmiersprachen (jeder der mich kennt weiß das ich da schnell in Sammelwut verfallen und teilweise schon selber die Übersicht verliere ^^). Hier bietet CRE eine ziemlich reichhaltige Sammlung auch an etwas esoterischeren Themen wie z.B. der Sprache &lt;a href="http://www.opendylan.org/"&gt;Dylan&lt;/a&gt; (von der ich bis heute keinen lauffähigen Compiler gefunden habe -_-). Ein besonderes Highlight war für mich der &lt;a href="http://chaosradio.ccc.de/cre063.html"&gt;C++ Podcast&lt;/a&gt; mit &lt;a href="https://twitter.com/pavel23"&gt;Pavel Mayer&lt;/a&gt;, vor allem wegen der grandiosen Buchtipps (mehr davon! Ich bin süchtig nach Fachliteratur!). Auch sehr spannend war der &lt;a href="http://chaosradio.ccc.de/cre048.html"&gt;Podcast über FreeBSD&lt;/a&gt;. Ich muss zu meiner Schande gestehen das ich mich mit BSD erst befasst habe als sich einige wenige in der Linuxwelt gegenüber ZFS (gibt es &lt;a href="http://chaosradio.ccc.de/cre049.html"&gt;auch einen CRE&lt;/a&gt; zu ;) in meinem Augen ziemlich blöd verhalten haben (Erläuterung was ich damit meine bitte in den Kommentaren nachlesen;) ). CRE hat mir hier eine sehr schöne Einführung in die BSD Welt gegeben.&lt;br /&gt;&lt;br /&gt;Was verspreche ich mir von CRE? In erster Linie ist es Futter fürs Hirn wenn meine Hände mit etwas anderem beschäftigt sind (trainieren oder einfach unterwegs sein). Ich möchte mich am liebsten permanent weiterbilden und das überall wo ich bin. Podcasts bieten dort eine Möglichkeit Neugierde auf bestimmte Themen zu machen oder einen einfach mal in die richtige Richtung zu schubsen wenn man selber den Wald vor lauter Bäumen nicht sieht. (You are doing it WRONG!). Auch bieten sie einem ein gewisses Gefühl an Zugehörigkeit, man sieht halt das man mit seiner Nerdigkeit nicht ganz alleine ist. Ein Gefühl was man auf dem Lande gerne mal bekommt ^^. Sie sind ein Sprachrohr unserer Kultur, einem Haufen Coder, Admins und Katzenliebhaber. Vor allem woher diese Katzenbilder eigentlich kommen war mal sehr interessant zu erfahren (auch wenn ich den Podcast im Fitnessstudio gehört habe und im Fernsehen gerade eine Raubkatze eine Kürbis verspeist hat... ich glaube ich habe selten so doof gegrinst...i can haz pumpkin?). &lt;br /&gt;&lt;br /&gt;Für die Zukunft würde ich mir sicher noch mehr technisches Zeug wünschen, das Problem ist da aber sicherlich das es auch an geeigneten Leuten gibt. Klar könnte ich mich mit Tim in einen Raum setzen und 2 Stunden über OpenSolaris quatschen, aber ob das Endresultat jetzt so brauchbar wäre stell ich einfach mal dahin. Oft sind es auch Podcasts die man gar nicht so auf dem Schirm hatte die einen begeistern, wie z.B. über das Thema &lt;a href="http://chaosradio.ccc.de/cre119.html"&gt;Kaffee&lt;/a&gt;. Plötzlich rennt man von einem Laden zum anderen und wundert sich warum man das nicht schon viel früher gemacht hat. (Auch wenn ich immer noch kein schlechtes gewissen habe diese Instant Trinkpisse von Ja! zu trinken ^^)&lt;br /&gt;&lt;br /&gt;So. Ich habe keine Ahnung ob das Bestechung genug ist. Ich habe wieder mal das Gefühl von Hölzchen auf Stöckchen gekommen zu sein und nur um den heißen Brei geredet zu haben. Aber bei Texten ohne geschweifte Klammern tu ich mich manchmal sehr schwer ^^.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_3VHVa9AP0ZM/Sn9AILjbYZI/AAAAAAAAAL0/DoZCQj4T4GQ/s1600-h/2327580596_959405a9d2.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 256px; height: 320px;" src="http://1.bp.blogspot.com/_3VHVa9AP0ZM/Sn9AILjbYZI/AAAAAAAAAL0/DoZCQj4T4GQ/s320/2327580596_959405a9d2.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5368079790133436818" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Erm... Pic unrelated!&lt;br /&gt;&lt;br /&gt;Dieses war der erste Streich, doch &lt;a href="http://www.marvelous.at/?p=56"&gt;der ZWEITE&lt;/a&gt; folgt sogleich! (Incoming Blogkette FTW!)&lt;br /&gt;Und "previously on Lo... erm Blogkette". &lt;a href="http://tim.geekheim.de/2009/08/09/cre-kettenblogging-fr-den-weltfrieden/"&gt;Der Blogpost mit dem alles angefangen hat&lt;/a&gt;!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8144285405079538181-764927830187652096?l=raichoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://raichoo.blogspot.com/feeds/764927830187652096/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8144285405079538181&amp;postID=764927830187652096' title='4 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/764927830187652096'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/764927830187652096'/><link rel='alternate' type='text/html' href='http://raichoo.blogspot.com/2009/08/podcasts-und-chaosradio-express.html' title='Podcasts und Chaosradio Express'/><author><name>Björn 'raichoo' Herzig</name><uri>https://profiles.google.com/102273886131939895778</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-KxzzpA_pbkc/AAAAAAAAAAI/AAAAAAAAARI/yHTIB2nrp8I/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_3VHVa9AP0ZM/Sn9AILjbYZI/AAAAAAAAAL0/DoZCQj4T4GQ/s72-c/2327580596_959405a9d2.jpg' height='72' width='72'/><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8144285405079538181.post-2023007343700142061</id><published>2009-07-20T14:49:00.000-07:00</published><updated>2009-07-20T15:07:24.302-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='MacOSX'/><category scheme='http://www.blogger.com/atom/ns#' term='C#'/><title type='text'>C Funktionen aus C# rufen</title><content type='html'>Für mich ist es immer wichtig das Sprachen nicht isoliert dastehen. Ich möchte von jeder Sprache oder Laufzeitumgebung ungehindert mit dem System kommunizieren. Da ich mich meistens auf diversen UNIX Systemen herumtreibe ist das größtenteils C. Gerade im Moment hat es mir C# ein wenig angetan und auch hier kann man ohne weiteres mit dem System schnacken. Darum hier mal ein kleines Beispiel das eventuell dem ein oder anderen weiterhilft. Das ganze wurde auf MacOSX mit Mono getestet läuft aber genauso gut unter *BSD und Linux.&lt;br /&gt;&lt;br /&gt;Als erstes legen wir eine kleine Library an die die Funktion enthält die wir später aufrufen wollen.&lt;br /&gt;&lt;code&gt;&lt;pre&gt;&lt;br /&gt;//compile with gcc -dynamiclib test.c -o test.dylib&lt;br /&gt;#include &lt;stdio.h&gt;&lt;br /&gt;&lt;br /&gt;int test(const char* s) {&lt;br /&gt;    printf("Printing from C: %s\n",s);&lt;br /&gt;    return 666;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;Nichts dramatisches, unser Programm soll lediglich etwas Text übernehmen ausgeben und einen Integer an unser C# Programm zurück liefern. Nach dem kompilieren erhalten wir eine dynamische Bibliothek mit Namen &lt;i&gt;test.dylib&lt;/i&gt;.&lt;br /&gt;&lt;br /&gt;Unser C# Code ist ähnlich spektakulär aufgebaut:&lt;br /&gt;&lt;code&gt;&lt;pre&gt;&lt;br /&gt;using System;&lt;br /&gt;using System.Runtime.InteropServices;&lt;br /&gt;&lt;br /&gt;class PTest {&lt;br /&gt;    [DllImport("test.dylib")]&lt;br /&gt;    public static extern int test(string s); &lt;br /&gt;&lt;br /&gt;    public static void Main() {&lt;br /&gt;        Console.WriteLine(test("this is a test"));&lt;br /&gt;    }   &lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;Eine interessante Anmerkung nebenbei: test.dylib muss zum Zeitpunkt der Übersetzung nicht existieren.&lt;br /&gt;&lt;br /&gt;Jetzt ist man also ohne weiteres in der Lage mit Libs wie z.B. libzfs oder libdtrace von C# aus zu kommunizieren um stark integrierte (aber logischerweise nicht mehr plattformunabhängige) Applikationen zu schreiben.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8144285405079538181-2023007343700142061?l=raichoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://raichoo.blogspot.com/feeds/2023007343700142061/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8144285405079538181&amp;postID=2023007343700142061' title='2 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/2023007343700142061'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/2023007343700142061'/><link rel='alternate' type='text/html' href='http://raichoo.blogspot.com/2009/07/c-funktionen-aus-c-rufen.html' title='C Funktionen aus C# rufen'/><author><name>Björn 'raichoo' Herzig</name><uri>https://profiles.google.com/102273886131939895778</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-KxzzpA_pbkc/AAAAAAAAAAI/AAAAAAAAARI/yHTIB2nrp8I/s512-c/photo.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8144285405079538181.post-1985186295784185394</id><published>2009-07-11T19:05:00.001-07:00</published><updated>2009-07-11T19:10:05.293-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Politik'/><title type='text'>"Spielt nicht mit Schmuddelkindern!"</title><content type='html'>Die Junge Union ist entrüstet über den Zuspruch den die Piratenpartei unter Studenten findet, spricht gar von einem Mangel an Werten. Es muss weh tun wenn man keiner mehr mit einem spielen will.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_3VHVa9AP0ZM/SllE_G_Ps8I/AAAAAAAAALQ/qQMQ3tYhQ90/s1600-h/Picture+1.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 240px;" src="http://3.bp.blogspot.com/_3VHVa9AP0ZM/SllE_G_Ps8I/AAAAAAAAALQ/qQMQ3tYhQ90/s320/Picture+1.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5357389082732245954" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8144285405079538181-1985186295784185394?l=raichoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://raichoo.blogspot.com/feeds/1985186295784185394/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8144285405079538181&amp;postID=1985186295784185394' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/1985186295784185394'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/1985186295784185394'/><link rel='alternate' type='text/html' href='http://raichoo.blogspot.com/2009/07/spielt-nicht-mit-schmuddelkindern.html' title='&quot;Spielt nicht mit Schmuddelkindern!&quot;'/><author><name>Björn 'raichoo' Herzig</name><uri>https://profiles.google.com/102273886131939895778</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-KxzzpA_pbkc/AAAAAAAAAAI/AAAAAAAAARI/yHTIB2nrp8I/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_3VHVa9AP0ZM/SllE_G_Ps8I/AAAAAAAAALQ/qQMQ3tYhQ90/s72-c/Picture+1.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8144285405079538181.post-7093041488508510976</id><published>2009-06-28T06:18:00.000-07:00</published><updated>2010-04-17T00:59:54.333-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Zones'/><category scheme='http://www.blogger.com/atom/ns#' term='TOR'/><title type='text'>Elektronische Revolutionen: Mit TOR gegen Zensur</title><content type='html'>Gerade in den letzten Wochen macht vor allem ein Thema immer wieder die Runde: Zensur. Andere Länder leiden bereits unter ihr und unsere Regierung ist nun auch fröhlich dabei Stück für Stück eine solche Infrastruktur zu errichten und gleichzeitig aber Länder zu verurteilen die diese bereits haben.&lt;br /&gt;&lt;br /&gt;Des weiteren werden wir im Moment auch Zeuge eines Volksaufstandes wie wir ihn noch nie in der Geschichte der Menschheit erlebt haben. Die Bevölkerung des Iran erhebt sich gegen das Regime und nutzt das Internet als Medium der Kommunikation in die ganze Welt. Da gerade der Iran über Kontrolltechnologien verfügt die wir uns in unseren wüstesten Albträumen nicht wünschen würden brauchen diese Menschen einen Weg diese Sperren zu umgehen. Einer der prominentesten ist sicherlich &lt;a href="https://www.torproject.org/"&gt;The Onion Router&lt;/a&gt;, ein anonymisierendes Netzwerk welches es Menschen ermöglichet Zensur zu umgehen und Information aus oder einzuschleusen. Das schöne an TOR ist: jeder kann praktisch mitmachen und ich will hier mal 3 Methoden vorstellen wie das geht.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Relays&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;TOR besteht aus &lt;a href="http://torstatus.kgprog.com/"&gt;vielen Knoten die Daten untereinander weiterleiten&lt;/a&gt;. Die Verbindung zwischen diesen Knoten ist in TOR komplett verschlüsselt und lässt praktisch kaum Rückschlüsse auf Absender und Ziel zu (sicher ist dies mit einem hohen technischen Aufwand auch zu bewerkstelligen). Ein solches Relay ist relativ einfach zu konfigurieren und spendet dem Netzwerk Bandbreite. Wichtig ist hierbei das von einem Relay aus keine Verbindung aus dem TOR Netzwerk heraus aufgebaut werden kann (man hat also nicht zu befürchten das kriminelle Inhalte durch ein Relay aufgerufen werden).&lt;br /&gt;&lt;br /&gt;Eine Konfiguration für ein Relay wäre z.B. folgende:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;pre&gt;&lt;br /&gt;SocksPort 0&lt;br /&gt;DirPort 443&lt;br /&gt;ORPort 80&lt;br /&gt;ExitPolicy reject *:*&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Das ganze lässt sich einfach über &lt;code&gt;tor -f /pfad/zur/config&lt;/code&gt; starten. Man sollte allerdings sichergehen das DirPort und ORPort durch die Firewall erreichbar sind. (Protip: TOR als &lt;a href="http://raichoo.blogspot.com/2008/10/spa-mit-solaris-zones.html"&gt;Solaris Zone&lt;/a&gt; ;) ). Mehr Infos zu Relays findet man auch auf der &lt;a href="http://www.torproject.org/docs/tor-doc-relay.html.en"&gt;TOR Seite&lt;/a&gt;. Die ExitPolicy sichert das man von diesem Knoten aus das TOR Netzwerk nicht verlassen kann, diesen Eintrag sollte man auf keinen Fall weglassen wenn man sich nicht genau der Konsequenzen bewusst ist. Mehr dazu im Abschnitt über Exit Nodes.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Bridges&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Diese speziellen Relays werden "geheim" gehalten. Da Regierungen gerne mal Zugangspunkte zum TOR Netzwerk blockiert verlangt es nach Zugangspunkten die in keiner Liste auftauchen. Durch diese kann man dann anonym ins Netz kommen um z.B. brisantes Material aus Krisengebieten herauszuschleusen. Anhand eines Fingerprints kann man sich mit solch einer Bridge verbinden.&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;pre&gt;&lt;br /&gt;SocksPort 0&lt;br /&gt;ORPort 443&lt;br /&gt;BridgeRelay 1&lt;br /&gt;Exitpolicy reject *:*&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Es gibt unter anderem eine Initiative die sich dafür einsetzt &lt;a href="http://iansbrain.com/2009/06/15/tor-and-the-iranian-election/"&gt;TOR Bridges für den Iran bereitzustellen&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Exit Nodes (VORSICHT!)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Diese Dinger sind nicht ganz ohne. An einem Exit Node wird das TOR Netzwerk verlassen und es werden Verbindungen ins unverschlüsselte Netz aufgebaut. Hierbei kann es sich auch um strafbares Material handeln, wer also nicht umbedingt unangemeldeten Besuch von der Polizei haben möchte sollte sich absichern oder halt darüber im klaren sein was hier passiert. Um einen Exit Node einzurichten entfernt man lediglich die Exit Policy aus der Relay Konfiguration. &lt;font color="red"&gt;&lt;b&gt;Ich übernehme keine Verantwortung für entstehende Schäden. YOU HAVE BEEN WARNED!&lt;/b&gt;&lt;/font&gt;Auch wenn die Beschlagnahmung eines TOR Servers in der Regel nichts bringt da keine verwertbaren Daten anfallen, sollte man sich nicht umgedingt darauf verlassen das dies als Argument gilt die Maschine nicht mitzunehmen.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Relay oder Bridge? Was hilft am meisten und wann?&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Diese Frage habe ich mir zu Anfang auch gestellt. Bridges sind sehr wichtig, allerdings bringt es nicht viel dies vom heimischen  DSL Anschluss aus zu machen, da deutsche Provider innerhalb von 24 Stunden die Netzverbindung kappen. Hat man allerdings das Glück eine feste IP zu haben oder einen Anbieter ohne 24h-Disconnect sollte man sich überlegem eine Bridge aufzusetzen. Bridges fressen im allgemeinen recht wenig Bandbreite, Relays hingegen stehen eigentlich permanent unter Strom und verteilen Daten, es ist also nicht unklug den Transferrate etwas anzupassen wenn man nicht komplett auf seine Verbindung verzichten will. Dies geht über z.B. folgende Konfigurationseinträge:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;pre&gt;&lt;br /&gt;RelayBandwidthRate 50 KBytes  &lt;br /&gt;RelayBandwidthBurst 200 KBytes &lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;In meinen Augen ist TOR ein immer wichtiger werdendes Netzwerk das es Menschen ermöglicht sich über staatliche Willkür hinwegzusetzen und eventuell sogar Leben zu retten oder gar ganze Regierungen zu stürzen. TOR wird heute schon genutzt um die Chinesische Firewall zu umgehen und wird hoffentlich immer mehr Menschen die in Unterdrückung leben die Möglichkeit geben sich Gehör zu verschaffen.&lt;br /&gt;&lt;br /&gt;&lt;center&gt;&lt;embed id="VideoPlayback" src="http://video.google.com/googleplayer.swf?docid=-3163238297108270457&amp;hl=en&amp;fs=true" style="width:400px;height:326px" allowFullScreen="true" allowScriptAccess="always" type="application/x-shockwave-flash"&gt; &lt;/embed&gt;&lt;/center&gt;&lt;br /&gt;&lt;br /&gt;&lt;center&gt;&lt;embed src="http://xml.truveo.com/eb/i/21981370/a/c882232f9546522cd50fd128338ffb66/p/1" type="application/x-shockwave-flash" width=" 425" height=" 350" allowfullscreen="true" FlashVars="apiHost=api.sevenload.com"&gt;&lt;/embed&gt;&lt;div style="background-color:#315270; width:425px; height:14px;text-align:center;"&gt;&lt;a href="http://fr.truveo.com/" target="_blank" style="font-family:Arial; font-size:9px; font-weight:100; color:#C7D8E7;line-height:14px; text-decoration:none; letter-spacing:0.1em;"&gt;Find more videos like this on www.truveo.com.&lt;/a&gt;&lt;/div&gt;&lt;/center&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8144285405079538181-7093041488508510976?l=raichoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://raichoo.blogspot.com/feeds/7093041488508510976/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8144285405079538181&amp;postID=7093041488508510976' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/7093041488508510976'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/7093041488508510976'/><link rel='alternate' type='text/html' href='http://raichoo.blogspot.com/2009/06/elektronische-revolutionen-mit-tor.html' title='Elektronische Revolutionen: Mit TOR gegen Zensur'/><author><name>Björn 'raichoo' Herzig</name><uri>https://profiles.google.com/102273886131939895778</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-KxzzpA_pbkc/AAAAAAAAAAI/AAAAAAAAARI/yHTIB2nrp8I/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8144285405079538181.post-3923733407214064458</id><published>2009-06-16T09:54:00.000-07:00</published><updated>2010-04-17T00:58:35.291-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='MacOSX'/><category scheme='http://www.blogger.com/atom/ns#' term='FreeBSD'/><category scheme='http://www.blogger.com/atom/ns#' term='LLVM'/><title type='text'>LLVM: Neue Compiler braucht das Land!</title><content type='html'>In letzter Zeit macht die Low Level Virtual Machine immer mehr von sich Reden. Blöderweise ist der Name doch ein wenig verwirrend und man denkt schnell an die Java VM oder dergleichen. In Wirklichkeit handelt es sich um ein Compilerframework (und eine eigene Sprache) welches einem sehr interessante Möglichkeiten eröffnet. Apple verwendet LLVM unter anderem um &lt;a href="http://en.wikipedia.org/wiki/OpenCL"&gt;OpenCL&lt;/a&gt; zu realisieren.&lt;br /&gt;Was mich besonders an LLVM interessiert sind vor allem die Möglichkeiten zur Analyse von Fehlern die es bietet. Hier mal gcc und clang (ein C/C++/ObjC Frontend für LLVM) im Vergleich.&lt;br /&gt;&lt;code&gt;&lt;pre&gt;&lt;br /&gt;$ gcc-4.2 -fsyntax-only t.c&lt;br /&gt;t.c:7: error: invalid operands to binary + (have 'int' and 'struct A')&lt;br /&gt;$ clang -fsyntax-only t.c&lt;br /&gt;t.c:7:39: error: invalid operands to binary expression ('int' and 'struct A')&lt;br /&gt;return y + func(y ? ((SomeA.X + 40) + SomeA) / 42 + SomeA.X : SomeA.X);&lt;br /&gt;                     ~~~~~~~~~~~~~~ ^ ~~~~~&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;Clang nagelt den Fehler auf Zeile UND Spalte fest, nebenher verbraucht er zum kompilieren auch noch weniger Speicher und ist auch noch schneller. Ziemlich beeindruckend.&lt;br /&gt;&lt;br /&gt;LLVM wird sicherlich den Compilermarkt in der Opensource Welt nachhaltig verändern. So gibt es z.B. Ambitionen &lt;a href="http://wiki.freebsd.org/BuildingFreeBSDWithClang"&gt;FreeBSD komplett mit Clang anstelle von GCC zu übersetzen&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Auch die Rubyfraktion will von LLVM profitieren und so &lt;a href="http://www.macruby.org/blog/2009/03/28/experimental-branch.html"&gt;experimentiert das MacRuby-Projekt&lt;/a&gt; ebenfalls mit LLVM um Ruby auf dem Mac zu beschleunigen.&lt;br /&gt;&lt;br /&gt;Für alle die jetzt neugierig geworden sind gibt es hier einen interessanten Tech Talk zum Thema, genauso wie einen Podcast vom &lt;a href="http://chaosradio.ccc.de/cre114.html"&gt;Chaosradio Express&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;center&gt;&lt;embed id="VideoPlayback" src="http://video.google.com/googleplayer.swf?docid=1921156852099786640&amp;hl=en&amp;fs=true" style="width:400px;height:326px" allowFullScreen="true" allowScriptAccess="always" type="application/x-shockwave-flash"&gt; &lt;/embed&gt;&lt;/center&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8144285405079538181-3923733407214064458?l=raichoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://raichoo.blogspot.com/feeds/3923733407214064458/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8144285405079538181&amp;postID=3923733407214064458' title='2 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/3923733407214064458'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/3923733407214064458'/><link rel='alternate' type='text/html' href='http://raichoo.blogspot.com/2009/06/llvm-neue-compiler-braucht-das-land.html' title='LLVM: Neue Compiler braucht das Land!'/><author><name>Björn 'raichoo' Herzig</name><uri>https://profiles.google.com/102273886131939895778</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-KxzzpA_pbkc/AAAAAAAAAAI/AAAAAAAAARI/yHTIB2nrp8I/s512-c/photo.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8144285405079538181.post-5618310490342865827</id><published>2009-06-16T09:14:00.000-07:00</published><updated>2010-04-17T01:02:01.226-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Politik'/><title type='text'>Stoppschild für die SPD</title><content type='html'>Ich wollte eigentlich politischen Content auf diesem Blog außen vor lassen, aber die derzeitige politische Lage veranlasst mich dazu. Die SPD winkt das Zensurgesetz der CDU brav durch wie es sich schon angedeutet hat. Ich für meinen Teil sehe beide Parteien somit für diese Bundestagswahl als unwählbar an. Meine Stimme wird weder die Stasi CDU noch die Kohlekumpel und BILD-Leser SPD kriegen.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_3VHVa9AP0ZM/SjfE4JbZREI/AAAAAAAAAKQ/rpQD6KVBdYw/s1600-h/spd_stopp2.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 285px;" src="http://3.bp.blogspot.com/_3VHVa9AP0ZM/SjfE4JbZREI/AAAAAAAAAKQ/rpQD6KVBdYw/s320/spd_stopp2.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5347959551408292930" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8144285405079538181-5618310490342865827?l=raichoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://raichoo.blogspot.com/feeds/5618310490342865827/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8144285405079538181&amp;postID=5618310490342865827' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/5618310490342865827'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/5618310490342865827'/><link rel='alternate' type='text/html' href='http://raichoo.blogspot.com/2009/06/stoppschild-fur-die-spd.html' title='Stoppschild für die SPD'/><author><name>Björn 'raichoo' Herzig</name><uri>https://profiles.google.com/102273886131939895778</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-KxzzpA_pbkc/AAAAAAAAAAI/AAAAAAAAARI/yHTIB2nrp8I/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_3VHVa9AP0ZM/SjfE4JbZREI/AAAAAAAAAKQ/rpQD6KVBdYw/s72-c/spd_stopp2.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8144285405079538181.post-7183150086117172607</id><published>2009-06-15T11:54:00.000-07:00</published><updated>2010-04-17T00:59:07.151-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='D'/><category scheme='http://www.blogger.com/atom/ns#' term='LLVM'/><title type='text'>Vortrag: LDC - ein D Frontend für LLVM</title><content type='html'>Im Moment bin ich extrem auf der Suche nach einer modernen Sprache mit der sich ein elegantes Framework für das Programmieren von Applikationen realisieren lässt (schon frustrierend wie wenig der Markt da wirklich bietet, vor allem wenn es darum geht auch auf exotischeren Plattformen zu laufen). D hat einige interessante Ansätze die die Probleme vieler Sprachen löst. Mit LDC stehen jetzt auch die Chancen gut diese Sprache auf weitaus mehr Plattformen zu bringen als bisher, darum habe ich hier mal einen kleinen Vortrag verlinkt der das Projekt erklärt. Leider ist die Tonqualität ziemlich schlecht aber man kann es gerade noch so aushalten.&lt;br /&gt;&lt;br /&gt;&lt;center&gt;&lt;object width="400" height="295"&gt;&lt;param name="allowfullscreen" value="true" /&gt;&lt;param name="allowscriptaccess" value="always" /&gt;&lt;param name="movie" value="http://vimeo.com/moogaloop.swf?clip_id=3289106&amp;amp;server=vimeo.com&amp;amp;show_title=1&amp;amp;show_byline=1&amp;amp;show_portrait=0&amp;amp;color=&amp;amp;fullscreen=1" /&gt;&lt;embed src="http://vimeo.com/moogaloop.swf?clip_id=3289106&amp;amp;server=vimeo.com&amp;amp;show_title=1&amp;amp;show_byline=1&amp;amp;show_portrait=0&amp;amp;color=&amp;amp;fullscreen=1" type="application/x-shockwave-flash" allowfullscreen="true" allowscriptaccess="always" width="400" height="295"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;p&gt;&lt;a href="http://vimeo.com/3289106"&gt;LDC&lt;/a&gt; from &lt;a href="http://vimeo.com/user810587"&gt;Tom Stachowiak&lt;/a&gt; on &lt;a href="http://vimeo.com"&gt;Vimeo&lt;/a&gt;.&lt;/p&gt;&lt;/center&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8144285405079538181-7183150086117172607?l=raichoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://raichoo.blogspot.com/feeds/7183150086117172607/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8144285405079538181&amp;postID=7183150086117172607' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/7183150086117172607'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/7183150086117172607'/><link rel='alternate' type='text/html' href='http://raichoo.blogspot.com/2009/06/vortrag-ldc-ein-d-frontend-fur-llvm.html' title='Vortrag: LDC - ein D Frontend für LLVM'/><author><name>Björn 'raichoo' Herzig</name><uri>https://profiles.google.com/102273886131939895778</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-KxzzpA_pbkc/AAAAAAAAAAI/AAAAAAAAARI/yHTIB2nrp8I/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8144285405079538181.post-3629546722121658224</id><published>2009-06-10T05:54:00.001-07:00</published><updated>2009-06-10T08:39:16.511-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='MacOSX'/><title type='text'>Vortrag: Inside the Mac OS X Kernel</title><content type='html'>Diesen Vortrag wollte ich eigentlich schon vor lange Zeit mal verlinken, aber irgendwie habe ich das immer verschwitzt. Sollte sich jeder mal ansehen der sich für Kernel Designs interessiert. Vor allem die Mach IPC und IOKit sind wirklich einen Blick wert.&lt;br /&gt;&lt;br /&gt;&lt;center&gt;&lt;embed id="VideoPlayback" src="http://video.google.com/googleplayer.swf?docid=-8486570970228087945&amp;hl=en&amp;fs=true" style="width:400px;height:326px" allowFullScreen="true" allowScriptAccess="always" type="application/x-shockwave-flash"&gt; &lt;/embed&gt;&lt;/center&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8144285405079538181-3629546722121658224?l=raichoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://raichoo.blogspot.com/feeds/3629546722121658224/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8144285405079538181&amp;postID=3629546722121658224' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/3629546722121658224'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/3629546722121658224'/><link rel='alternate' type='text/html' href='http://raichoo.blogspot.com/2009/06/vortrag-inside-mac-os-x-kernel.html' title='Vortrag: Inside the Mac OS X Kernel'/><author><name>Björn 'raichoo' Herzig</name><uri>https://profiles.google.com/102273886131939895778</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-KxzzpA_pbkc/AAAAAAAAAAI/AAAAAAAAARI/yHTIB2nrp8I/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8144285405079538181.post-4139345367411132721</id><published>2009-05-21T20:13:00.000-07:00</published><updated>2009-05-21T20:14:27.485-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='DragonflyBSD'/><title type='text'>Vortrag: Threading in DragonflyBSD</title><content type='html'>&lt;center&gt;&lt;object width="425" height="344"&gt;&lt;param name="movie" value="http://www.youtube.com/v/c5E2pWTwxJE&amp;hl=de&amp;fs=1"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/c5E2pWTwxJE&amp;hl=de&amp;fs=1" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;/center&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8144285405079538181-4139345367411132721?l=raichoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://raichoo.blogspot.com/feeds/4139345367411132721/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8144285405079538181&amp;postID=4139345367411132721' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/4139345367411132721'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/4139345367411132721'/><link rel='alternate' type='text/html' href='http://raichoo.blogspot.com/2009/05/vortrag-threading-in-dragonflybsd.html' title='Vortrag: Threading in DragonflyBSD'/><author><name>Björn 'raichoo' Herzig</name><uri>https://profiles.google.com/102273886131939895778</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-KxzzpA_pbkc/AAAAAAAAAAI/AAAAAAAAARI/yHTIB2nrp8I/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8144285405079538181.post-3549163581939924254</id><published>2009-04-23T03:50:00.000-07:00</published><updated>2010-04-17T01:00:35.902-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='D'/><title type='text'>Programmierung: Ein kleiner Einblick in D</title><content type='html'>Jeder der sich schon mal mit C++ befasst hat kommt irgendwann mal an den Punkt an dem er denkt "Oh man geht das nicht auch einfacher?". Fakt ist: Kaum eine Sprache ist so schwer zu lernen und so aufwändig durch den Compiler zu kriegen wie diese, dazu kommen noch einige C Altlasten und vor allem der Preprozessor. Oft ertappt man sich dabei möglichst trickreich die Sprache aus den Angeln zu hebeln (mir fällt da spontan das sizeof Voodoo ein um zur Compilezeit herauszufinden ob ein Cast gemacht werden kann oder nicht). Viele dieser Tricks basieren auf ausgefuchsten C++-Templates und gerade die sorgen bei vielen Programmierern für spontanes "schreiend im Kreis rennen" (schon mal mit Typelists gearbeitet? :P). Hier springt &lt;a href="http://www.digitalmars.com/d/index.html"&gt;D von Digitalmars&lt;/a&gt; in die Bresche, oder versucht es zumindest. Ein paar Highlights möchte ich hier beleuchten.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Keine Rückwärtskompatibilität&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Was in C++ Anfangs noch Mittel zum Zweck war ist inzwischen zu einem unangenehmen Anhängsel geworden. Vielen geht schon beim Anblick eines const char* die Sause geschweige denn der ganze Mist den Arrays mit sich schleppen. Vieles davon bessert die STL schon lange nach (std::string und std::vector sei dank) ein wenig übel ist der Nachgeschmack dennoch... zumindest für mich ;). Besonders "schön" ist da vor allem der Preprozessor hat er doch keine Ahnung was es mit der Sprache auf sich hat und setzt nur fröhlich irgendwelche Markos oder Definitionen ein. Entscheidungen die zur Compilezeit getroffen werden gehen an im vorbei da er ja schon lange fertig ist wenn es zur Sache geht. Hier kommen dann bei C++ die Templates zum Schuss and genau dort wird es für viele kompliziert. D bietet hier ein eigenes Sprachmittel: &lt;span style="font-weight:bold;"&gt;static if&lt;/span&gt;.&lt;br /&gt;&lt;code&gt;&lt;pre&gt;&lt;br /&gt;import std.stdio;&lt;br /&gt;&lt;br /&gt;class A {}&lt;br /&gt;class B : A {}&lt;br /&gt;class C {}&lt;br /&gt;&lt;br /&gt;void main(string[] args) {&lt;br /&gt;    static if (is(B : A)) {&lt;br /&gt;        writefln("B erbt von A");&lt;br /&gt;    } else {&lt;br /&gt;        writefln("B erbt nicht von A");&lt;br /&gt;    }&lt;br /&gt;    static if (is(C : A)) {&lt;br /&gt;        writefln("C erbt von A");&lt;br /&gt;    } else {&lt;br /&gt;        writefln("C erbt nicht von A");&lt;br /&gt;    }   &lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;Ohne große Umwege lässt sich hier das Gewünschte ausdrücken. Ein Preprozessor würde hier versagen da er keine Ahnung von Sprachmitteln wie Vererbung hat, man wäre also auf C++-Template Voodoo angewiesen, hier ist schon alles in der Sprache drin.&lt;br /&gt;&lt;br /&gt;Besonders Templates wurden in D stark überarbeitet, da gerade hier sich Schwächen auftuen die zu sehr großen Problemen führen können. Das ganze Elend fängt schon bei der Syntax an. Da die Spitzen Klammern die in C++ verwendet werden auch irrtümlicherweise als größer oder kleiner-Operatoren angesehen werden können (in solchen Situationen muss man dem Compiler meist noch unter die Arme greifen). D benutzt hier eine etwas gewöhnungsbedürftige Syntax die allerdings diese Probleme umgeht da sie einen Operator verwendet der im Normalfall nur unär ist hier aber binär verwendet wird, nämlich den !-Operator.&lt;br /&gt;&lt;code&gt;&lt;pre&gt;&lt;br /&gt;import std.stdio;&lt;br /&gt;&lt;br /&gt;template Foo(T) {&lt;br /&gt;    T a = 666;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;void main(string[] args) {&lt;br /&gt;    alias Foo!(int) tmp;&lt;br /&gt;    writefln("%d",tmp.a);&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;Hier taucht auch gleichzeitig eine andere Besonderheit von D auf, das alias. Dieses Schlüsselwort macht eigentlich nichts anderes als das was wir von C/C++ kennen, denn im Gegensatz zu diesen Sprachen verfügt D über echte Typedefs die auch überladen können.&lt;br /&gt;&lt;code&gt;&lt;pre&gt;&lt;br /&gt;import std.stdio;&lt;br /&gt;&lt;br /&gt;typedef int bla;&lt;br /&gt;&lt;br /&gt;void test(int a) {&lt;br /&gt;    writefln("int: %d",a);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;void test(bla a) {&lt;br /&gt;    writefln("bla: %d",a);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;void main(string[] args) {&lt;br /&gt;    int a = 666;&lt;br /&gt;    bla b = 777;&lt;br /&gt;    test(a);&lt;br /&gt;    test(b);&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;Eine andere Kleinigkeit die bei unserem Template Beispiel aufgefallen ist, ist das es sich bei diesem Template weder um eine Template-Klasse noch um eine Template-Funktion handelt. Es ist einfach nur ein Template. Das bietet eine weitere Interessante Möglichkeit, nämlich &lt;span style="font-weight:bold;"&gt;Mixins&lt;/span&gt;.&lt;br /&gt;&lt;code&gt;&lt;pre&gt;&lt;br /&gt;import std.stdio;&lt;br /&gt;&lt;br /&gt;template Foo(T) {&lt;br /&gt;    void test() {&lt;br /&gt;        writefln("Foo.test");&lt;br /&gt;    }   &lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;class Test {&lt;br /&gt;    public {&lt;br /&gt;        mixin Foo!(int);&lt;br /&gt;    }   &lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;void main(string[] args) {&lt;br /&gt;    Test t = new Test;&lt;br /&gt;    t.test();&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;Ein nicht ganz so offensichtliches Feature ist hier der Garbage Collector und der Fakt das hier nicht mit Pointern (keine Sorge die gibt es auch noch) sondern mit Referenzen gearbeitet wird wenn eine Klasse instanziiert wird. Hier scheiden sich sicherlich die Geister denn was bei Systemprogrammierung durchaus Sinn macht, kann beim Programmieren von Applikationen schnell zur Katastrophe werden und in wirklich scheusslichen Speicherlecks enden (oder pro-aggressiven Einsätzen von auto_ptr, shared_ptr und Konsorten).&lt;br /&gt;&lt;br /&gt;Was auch sehr viel Spass macht ist das Wegfallen von Forward-Declarations. So geht z.B. folgendes:&lt;br /&gt;&lt;code&gt;&lt;pre&gt;&lt;br /&gt;import std.stdio;&lt;br /&gt;&lt;br /&gt;void foo() {&lt;br /&gt;    bar();&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;void bar() {&lt;br /&gt;    writefln("foobar");&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;void main(string[] args) {&lt;br /&gt;    foo();&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Kritikpunkte&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;D ist eine tolle Sprache und räumt mit einigen Sachen auf die bei C++ zu Verwirrung oder schlechtem Programmierstil führen auf. Dennoch ist die Unterstützung der Sprache noch mehr als dürftig da es im Endeffekt nur sehr wenige Compiler für sie gibt die im Grunde alle auf dem DMD von Digitalmars basieren. Auch fehlen mir einige In-Depth Einblicke die in für C++ zu Hauf gibt und gerade auf der Low-Level Seite von mir schmerzlich vermisst werden (bei Nachfrage wird man dann auch gerne mit der Standardantwort "read to code" abgefrühstückt). Auch ist die eine Aufspaltung der D Community durch 2 unterschiedliche "Standard"-Bibliotheken mehr als offensichtlich und auch nervig (Flamewars gibt es wirklich schon genug). Während ein Compiler &lt;a href="http://www.digitalmars.com/d/2.0/phobos/phobos.html"&gt;Phobos&lt;/a&gt; nutzt kommt der andere nur mit &lt;a href="http://www.dsource.org/projects/tango"&gt;Tango&lt;/a&gt; daher. Derzeit wird auch an D2.0 herumgeschustert und man kriegt langsam das Gefühl als werde auch diese Sprache immer überladener. Dennoch ist die Sprache so entworfen das einem nicht gleich pfundweise Fehlermeldungen um die Ohren geschleudert werden da gerade auf obskure veraltete Syntax verzichtet wurde. Für alle die aber etwas gesucht haben das so schnell wie C/C++ ist und mit viel vom Java/C# Komfort daherkommt ist diese Sprache sicherlich mal einen Blick wert. Java? Ja, D verzichtet unter anderem auf Multivererbung und setzt dafür auf Interfaces. Auch Schlüsselwörter wie final, abstract und synchronized sind oft einfach hilfreich wenn es darum geht schnell und leserlich das auszudrücken was man meint.&lt;br /&gt;&lt;br /&gt;Das hier sind nur ein paar sehr kleine Details von dem was D ausmacht und bei weitem noch nicht alle. Sollte Interesse bestehen kann ich gerne auch noch etwas auf Details eingehen (vor allem Closures dürften dein ein oder anderen sicher interessieren, das sprengt hier aber glaub ich etwas den Rahmen ^^).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8144285405079538181-3549163581939924254?l=raichoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://raichoo.blogspot.com/feeds/3549163581939924254/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8144285405079538181&amp;postID=3549163581939924254' title='2 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/3549163581939924254'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/3549163581939924254'/><link rel='alternate' type='text/html' href='http://raichoo.blogspot.com/2009/04/programmierung-ein-kleiner-einblick-in.html' title='Programmierung: Ein kleiner Einblick in D'/><author><name>Björn 'raichoo' Herzig</name><uri>https://profiles.google.com/102273886131939895778</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-KxzzpA_pbkc/AAAAAAAAAAI/AAAAAAAAARI/yHTIB2nrp8I/s512-c/photo.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8144285405079538181.post-1093777440526290082</id><published>2009-04-18T05:31:00.000-07:00</published><updated>2009-04-18T05:36:04.073-07:00</updated><title type='text'>Twitscher twitscher!</title><content type='html'>Aufgrund chronischem Spieltriebs hab ich mich einfach mal dazu entschlossen mich bei Twitter anzumelden. Da ich immer mal wieder Links finde die ich für mehr oder weniger für interessant erachte (und es irgendwie sinnlos ist jedesmal einen Blogartikel drüber zu schreiben) gibts die jetzt unter &lt;a href="http://twitter.com/raichoo"&gt;meinem neuen Twitteraccount&lt;/a&gt;. Follow me.... i know where they hide their cookies!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8144285405079538181-1093777440526290082?l=raichoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://raichoo.blogspot.com/feeds/1093777440526290082/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8144285405079538181&amp;postID=1093777440526290082' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/1093777440526290082'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/1093777440526290082'/><link rel='alternate' type='text/html' href='http://raichoo.blogspot.com/2009/04/twitscher-twitscher.html' title='Twitscher twitscher!'/><author><name>Björn 'raichoo' Herzig</name><uri>https://profiles.google.com/102273886131939895778</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-KxzzpA_pbkc/AAAAAAAAAAI/AAAAAAAAARI/yHTIB2nrp8I/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8144285405079538181.post-7695142221516501201</id><published>2009-03-25T09:37:00.000-07:00</published><updated>2010-04-17T00:59:41.934-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='C++'/><title type='text'>C++: ABI zur Laufzeit entwirren</title><content type='html'>Die C++ typeinfo ist ja immer so eine Sache. Einige Compiler entwirren die Namen, andere wieder nicht. G++ gehört zu den Compilern die das nicht von sich aus machen, aber man kann sich leicht Abhilfe schaffen.&lt;br /&gt;&lt;code&gt;&lt;pre&gt;&lt;br /&gt;#include &amp;lt;typeinfo&amp;gt;&lt;br /&gt;#include &amp;lt;iostream&amp;gt;&lt;br /&gt;#include &amp;lt;cxxabi.h&amp;gt;&lt;br /&gt;&lt;br /&gt;#define HAVE_CXA_DEMANGLE&lt;br /&gt;&lt;br /&gt;#ifdef HAVE_CXA_DEMANGLE&lt;br /&gt;const char* demangle(const char* name)&lt;br /&gt;{&lt;br /&gt;   char buf[1024];&lt;br /&gt;   unsigned int size = 1024;&lt;br /&gt;   int status;&lt;br /&gt;   char* res;&lt;br /&gt;   res = abi::__cxa_demangle(name,&lt;br /&gt;     buf,&lt;br /&gt;     &amp;size,&lt;br /&gt;     &amp;status);&lt;br /&gt;   return res;&lt;br /&gt;}&lt;br /&gt;#else&lt;br /&gt;const char* demangle(const char* name)&lt;br /&gt;{&lt;br /&gt;   return name;&lt;br /&gt;}&lt;br /&gt;#endif&lt;br /&gt;&lt;br /&gt;int main()&lt;br /&gt;{&lt;br /&gt;   std::cout &lt;&lt; typeid(std::cout).name();&lt;br /&gt;   std::cout &lt;&lt; std::endl;&lt;br /&gt;   std::cout &lt;&lt; ::demangle(typeid(std::cout).name());&lt;br /&gt;   std::cout &lt;&lt; std::endl;&lt;br /&gt;   return 0;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;/* Ausgabe :&lt;br /&gt;[raichoo@sparkster:~]&gt; ./a.out &lt;br /&gt;So&lt;br /&gt;std::ostream&lt;br /&gt;*/&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8144285405079538181-7695142221516501201?l=raichoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://raichoo.blogspot.com/feeds/7695142221516501201/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8144285405079538181&amp;postID=7695142221516501201' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/7695142221516501201'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/7695142221516501201'/><link rel='alternate' type='text/html' href='http://raichoo.blogspot.com/2009/03/c-abi-zur-laufzeit-entwirren.html' title='C++: ABI zur Laufzeit entwirren'/><author><name>Björn 'raichoo' Herzig</name><uri>https://profiles.google.com/102273886131939895778</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-KxzzpA_pbkc/AAAAAAAAAAI/AAAAAAAAARI/yHTIB2nrp8I/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8144285405079538181.post-9125854855656346399</id><published>2009-02-15T13:38:00.000-08:00</published><updated>2009-02-15T13:57:28.896-08:00</updated><title type='text'>Haiku: A blast from the past</title><content type='html'>Ich hab ja schon immer gerne mit Betriebssystemen der unterschiedlichsten Art rumgespielt und vor vielen Jahren bin ich auch mit BeOS in Berührung gekommen. Leider war die Liebe nicht von langer Dauer da Be irgendwann Geschichte war und damit auch dieses wunderbare Betriebssystem. Es war schon unglaublich was man damals aus einer Kiste an Performance rausholen konnte. Viele Systeme ächzen heute noch und dem was BeOS damals schon geleistet hat, und zwar auf weitaus schlechterer Hardware als heute. Umso mehr habe ich mich über das Projekt &lt;a href="http://www.haiku-os.org"&gt;Haiku&lt;/a&gt; gefreut das es sich zur Aufgabe gemacht hat ein freies BeOS zu entwickeln. Was es mir besonders angetan hat ist die reichhaltige API. Keine kilometerlangen Abhängigkeitslisten mehr Haiku bietet alles was man braucht in sogenannten &lt;a href="http://www.haiku-os.org/legacy-docs/bebook/SystemOverview.html"&gt;Kits&lt;/a&gt;. Alles ist sehr stark integriert und greift wunderbar ineinander. Vor allem der einheitlich Desktop hat seine Vorteile. Während Projekte wie KDE und Gnome darauf ausgelegt sind auf möglichst vielen unterschiedlichen Systemen zu laufen hat Haiku "nur" eine Oberfläche welche sämtliche Vorteile des darunterliegenden Systems nutzen kann. Dies ist bei anderen Desktop nicht ohne weiters mögliche da sie sonst ihre Portierbarkeit verlieren würden. Ein weiterer Vorteil ist das das starten von Applikationen einfach rasend schnell wird. Wer gerne mit Systemen herumspielt sollte auf jeden Fall einen Stop bei Haiku einlegen. ;)&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_3VHVa9AP0ZM/SZiPbW-EVAI/AAAAAAAAAJ4/cNvYCnCc4Zw/s1600-h/shot.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 200px;" src="http://4.bp.blogspot.com/_3VHVa9AP0ZM/SZiPbW-EVAI/AAAAAAAAAJ4/cNvYCnCc4Zw/s320/shot.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5303146261413909506" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8144285405079538181-9125854855656346399?l=raichoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://raichoo.blogspot.com/feeds/9125854855656346399/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8144285405079538181&amp;postID=9125854855656346399' title='1 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/9125854855656346399'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/9125854855656346399'/><link rel='alternate' type='text/html' href='http://raichoo.blogspot.com/2009/02/haiku-blast-from-past.html' title='Haiku: A blast from the past'/><author><name>Björn 'raichoo' Herzig</name><uri>https://profiles.google.com/102273886131939895778</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-KxzzpA_pbkc/AAAAAAAAAAI/AAAAAAAAARI/yHTIB2nrp8I/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_3VHVa9AP0ZM/SZiPbW-EVAI/AAAAAAAAAJ4/cNvYCnCc4Zw/s72-c/shot.png' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8144285405079538181.post-6294080592772028657</id><published>2009-01-09T12:45:00.000-08:00</published><updated>2009-01-09T12:56:14.164-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='OpenSolaris'/><title type='text'>Testphase für 2009.04 hat begonnen</title><content type='html'>Mit der Veröffentlichung von Build 105 für OpenSolaris geht es jetzt los mit der Entwicklung für den nächsten Release der Distribution, um auf das Developer Repository zuzugreifen genügt der folgende Befehl:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;pre&gt;&lt;br /&gt;$pfexec pkg set-authority -O http://pkg.opensolaris.org/dev opensolaris.org&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Mit Build 105 wird ZFS auf die neuste Version 14 gebracht (Vorsicht: ein Upgrade führt dazu das ältere Versionen und BEs von OpenSolaris nicht mehr auf die Daten zugreifen können!), des weiteren wird die NIC-Virtualisierung Crossbow eingeführt mit der es möglich ist komplette virtuelle Netzwerkkarten (inklusive eigener MAC-Addresse) zu erstellen.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8144285405079538181-6294080592772028657?l=raichoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://raichoo.blogspot.com/feeds/6294080592772028657/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8144285405079538181&amp;postID=6294080592772028657' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/6294080592772028657'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/6294080592772028657'/><link rel='alternate' type='text/html' href='http://raichoo.blogspot.com/2009/01/testphase-fr-200904-hat-begonnen.html' title='Testphase für 2009.04 hat begonnen'/><author><name>Björn 'raichoo' Herzig</name><uri>https://profiles.google.com/102273886131939895778</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-KxzzpA_pbkc/AAAAAAAAAAI/AAAAAAAAARI/yHTIB2nrp8I/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8144285405079538181.post-7986995827789797334</id><published>2008-12-21T15:18:00.001-08:00</published><updated>2008-12-21T15:21:08.449-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='OpenSolaris'/><title type='text'>Ruby 1.9.1 Preview2 selberbacken</title><content type='html'>Im Moment spiele ich mal wieder mit diversen Skriptsprachen herum von denen eine Ruby ist. Leider läßt sich der aktuelle Preview nur mit ein paar Umwegen unter OpenSolaris backen. Darum hier ein kleines Patch damit Vorgang durchläuft. Ich übernehme wie immer keine Verantwortung für eventuelle Probleme ^^.&lt;br /&gt;&lt;code&gt;&lt;pre&gt;&lt;br /&gt;--- ext/curses/curses.c Tue Nov 11 12:00:39 2008&lt;br /&gt;+++ ext/curses/curses.c Sun Dec 21 17:00:44 2008&lt;br /&gt;@@ -410,6 +410,9 @@&lt;br /&gt; static VALUE&lt;br /&gt; curses_getch(VALUE obj)&lt;br /&gt; {&lt;br /&gt;+#if defined(__sun)&lt;br /&gt;+ eucwidth_t wp;&lt;br /&gt;+#endif&lt;br /&gt;     int c;&lt;br /&gt; &lt;br /&gt;     rb_read_check(stdin);&lt;br /&gt;@@ -416,7 +419,12 @@&lt;br /&gt;     curses_stdscr();&lt;br /&gt;     c = getch();&lt;br /&gt;     if (c == EOF) return Qnil;&lt;br /&gt;+#if defined( __sun)&lt;br /&gt;+ getwidth(&amp;wp);&lt;br /&gt;+    if (ISPRINT(c, wp)) {&lt;br /&gt;+#else&lt;br /&gt;     if (ISPRINT(c)) {&lt;br /&gt;+#endif&lt;br /&gt;  char ch = (char)c;&lt;br /&gt; &lt;br /&gt;  return rb_locale_str_new(&amp;ch, 1);&lt;br /&gt;@@ -1105,12 +1113,20 @@&lt;br /&gt; {&lt;br /&gt;     struct windata *winp;&lt;br /&gt;     int c;&lt;br /&gt;+#if defined(__sun)&lt;br /&gt;+ eucwidth_t wp;&lt;br /&gt;+#endif&lt;br /&gt; &lt;br /&gt;     rb_read_check(stdin);&lt;br /&gt;     GetWINDOW(obj, winp);&lt;br /&gt;     c = wgetch(winp-&gt;window);&lt;br /&gt;     if (c == EOF) return Qnil;&lt;br /&gt;+#if defined(__sun)&lt;br /&gt;+ getwidth(&amp;wp);&lt;br /&gt;+    if (ISPRINT(c, wp)) {&lt;br /&gt;+#else&lt;br /&gt;     if (ISPRINT(c)) {&lt;br /&gt;+#endif&lt;br /&gt;  char ch = (char)c;&lt;br /&gt; &lt;br /&gt;  return rb_locale_str_new(&amp;ch, 1);&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8144285405079538181-7986995827789797334?l=raichoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://raichoo.blogspot.com/feeds/7986995827789797334/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8144285405079538181&amp;postID=7986995827789797334' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/7986995827789797334'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/7986995827789797334'/><link rel='alternate' type='text/html' href='http://raichoo.blogspot.com/2008/12/ruby-191-preview2-selberbacken.html' title='Ruby 1.9.1 Preview2 selberbacken'/><author><name>Björn 'raichoo' Herzig</name><uri>https://profiles.google.com/102273886131939895778</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-KxzzpA_pbkc/AAAAAAAAAAI/AAAAAAAAARI/yHTIB2nrp8I/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8144285405079538181.post-777978212297543963</id><published>2008-12-14T05:58:00.000-08:00</published><updated>2008-12-14T06:10:37.101-08:00</updated><title type='text'>Aktivismus: "The Yes Men"</title><content type='html'>Ich bin heute über einen sehr interessanten Link gestolpert der ausnahmsweise mal nichts mit Technik zu tun hat. Wirklich sehr sehenswert: &lt;a href="http://video.google.com/videoplay?docid=-338819014348247258&amp;q=free+trade"&gt;The Yes Men&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Schon krass was man unter dem Motiv der Gewinnmaximierung den Leuten alles verkaufen kann...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8144285405079538181-777978212297543963?l=raichoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://raichoo.blogspot.com/feeds/777978212297543963/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8144285405079538181&amp;postID=777978212297543963' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/777978212297543963'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/777978212297543963'/><link rel='alternate' type='text/html' href='http://raichoo.blogspot.com/2008/12/aktivismus-yes-men.html' title='Aktivismus: &quot;The Yes Men&quot;'/><author><name>Björn 'raichoo' Herzig</name><uri>https://profiles.google.com/102273886131939895778</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-KxzzpA_pbkc/AAAAAAAAAAI/AAAAAAAAARI/yHTIB2nrp8I/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8144285405079538181.post-8979758296313528543</id><published>2008-12-13T02:43:00.000-08:00</published><updated>2008-12-13T05:03:24.060-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='OpenSolaris'/><title type='text'>Nahtloses 64-Bit</title><content type='html'>Mir fallen immer wieder Fragen auf die sich auf die 64-Bit Fähigkeit von OpenSolaris beziehen. Wie z.B. "Wo krieg ich die 64-Bit ISO?" oder "Unterstützt Solaris das überhaupt?".&lt;br /&gt;Ja, Solaris baut sich je nach vorliegender Architektur passend zusammen (ein Vorteil der durch die hohe Modularisierung möglich ist), soll heißen: Die OpenSolaris Installations CD ist beides (bootet als LiveCD afaik aber nur im 32-bit Modus). Um herauszufinden ob die eigene Solarisinstallation auch 64-Bit unterstützt reichen folgende Befehle:&lt;br /&gt;&lt;code&gt;&lt;pre&gt;&lt;br /&gt;$ isainfo&lt;br /&gt;amd64 i386&lt;br /&gt;$ isainfo -vk&lt;br /&gt;64-bit amd64 kernel modules&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;Mein System unterstützt also i386 und amd64 und die Kernelkomponenten nutzen das 64-Bit Instruktionsset. Ich kann nahtlos 32 und 64-Bit Programme miteinander mischen ohne das ich irgendwas besonderes dafür tun muss (der Grund warum es auf 64-Bit Solaris Systemen auch schon seit Ewigkeiten die Möglichkeit gibt Flash zu nutzen), es läuft einfach.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8144285405079538181-8979758296313528543?l=raichoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://raichoo.blogspot.com/feeds/8979758296313528543/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8144285405079538181&amp;postID=8979758296313528543' title='1 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/8979758296313528543'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/8979758296313528543'/><link rel='alternate' type='text/html' href='http://raichoo.blogspot.com/2008/12/nahtloses-64-bit.html' title='Nahtloses 64-Bit'/><author><name>Björn 'raichoo' Herzig</name><uri>https://profiles.google.com/102273886131939895778</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-KxzzpA_pbkc/AAAAAAAAAAI/AAAAAAAAARI/yHTIB2nrp8I/s512-c/photo.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8144285405079538181.post-659307159671880319</id><published>2008-12-05T06:35:00.000-08:00</published><updated>2008-12-06T01:53:27.050-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='OpenSolaris'/><title type='text'>Amilo gone wild</title><content type='html'>Seit einigen Wochen schlage ich mich schon mit meinem alten Amilo Pi1505 und OpenSolaris herum. Irgendwann hat es sich dazu entschlossen sich im Kreis zu drehen sobald es größere Mengen an Daten geschrieben oder gelesen hat. Wer sich für ein Tagebuch dieser Schnitzeljagd quer durch den Quellcode interessiert kann das Ganze auf &lt;a href="http://defect.opensolaris.org/bz/show_bug.cgi?id=3690"&gt;defect.opensolaris.org&lt;/a&gt; nachlesen.&lt;br /&gt;Lange Rede, kurzer Unsinn. Der Hund lag in der NCQ begraben. MDB lieferte mir folgende Werte:&lt;br /&gt;&lt;code&gt;&lt;pre&gt;&lt;br /&gt;uint32_t ahciport_pending_tags = 0x1&lt;br /&gt;...&lt;br /&gt;struct sata_pkt *[32] ahciport_slot_pkts = [ 0, 0, 0, 0, 0, usw.&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;Dieser Zustand ist allerdings recht beknackt. ahciport_pending_tags sagt uns das ein Kommando in Slot 0 noch aussteht, Slot 0 zeigt aber auf 0 was wiederum heißt: Nichts steht aus. Und da beißt sich die Katze in den Schwanz und die ankommende Anfrage dreht sich immer im Kreis.&lt;br /&gt;Lösung dieses Problems ist es NCQ zu deaktivieren. Das geht über 2 Wege&lt;br /&gt;&lt;br /&gt;Der erste geht über MDB. Wir booten dazu OpenSolaris mit der Kerneloption -kd. Das versetzt uns beim Bootvorgang sofort in den Debugger. Hier setzen wir folgenden Breakpunkt und gehen wie folgt vor:&lt;br /&gt;&lt;code&gt;&lt;pre&gt;&lt;br /&gt;::bp ahci`ahci_attach&lt;br /&gt;::cont&lt;br /&gt;....&lt;br /&gt;sata`sata_func_enable/W 5&lt;br /&gt;::cont&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;Das deaktiviert NCQ und das Problem ist Geschichte.&lt;br /&gt;&lt;br /&gt;Jetzt hat man allerdings nicht wirklich Lust jedesmal solche Klimmzüge zu machen und für sowas ist die /etc/system da mit der wir bestimmte Kernelvariablen einfach selber setzen können ohne etwas neu zu kompilieren. Um das oben genannte festzuschreiben braucht man nicht mehr als folgende Zeile an die /etc/system anhängen:&lt;br /&gt;&lt;code&gt;&lt;pre&gt;&lt;br /&gt;set sata:sata_func_enable = 5&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Des weiteren mag diese Kiste wohl den Bootsplash und den HCI1394 Treiber nicht, darum sollte man im Textmode booten und die Bootoption -B disable-hci1394=true anhängen. So gibt dann auch endlich mein Sorgenkind Ruhe ;)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8144285405079538181-659307159671880319?l=raichoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://raichoo.blogspot.com/feeds/659307159671880319/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8144285405079538181&amp;postID=659307159671880319' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/659307159671880319'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/659307159671880319'/><link rel='alternate' type='text/html' href='http://raichoo.blogspot.com/2008/12/amilo-gone-wild.html' title='Amilo gone wild'/><author><name>Björn 'raichoo' Herzig</name><uri>https://profiles.google.com/102273886131939895778</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-KxzzpA_pbkc/AAAAAAAAAAI/AAAAAAAAARI/yHTIB2nrp8I/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8144285405079538181.post-4520152926091840861</id><published>2008-12-05T06:24:00.000-08:00</published><updated>2010-04-17T01:01:13.690-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='OpenSolaris'/><title type='text'>Wireless LAN auf dem Thinkpad SL500</title><content type='html'>Ich habe mir ja vor einiger Zeit ein Thinkpad SL500 zugelegt um es mit OpenSolaris zu bestücken, seltsamerweise wurde der WLAN Chip (Intel 5100 AGN) allerdings nicht erkannt obwohl der Treiber bereits seit einigen Wochen bereitsteht. Naja, so seltsam dann auch wieder nicht. Es fehlte einfach die Zuordnung zwischen ID und Treiber. Also erst mal herausfinden wie sich unser Chip zu erkennen gibt, dazu haben wir ja scanpci:&lt;br /&gt;&lt;code&gt;&lt;pre&gt;&lt;br /&gt;pci bus 0x0002 cardnum 0x00 function 0x00: vendor 0x8086 device 0x4237&lt;br /&gt; Intel Corporation PRO/Wireless 5100 AGN [Shiloh] Network Connection&lt;br /&gt; CardVendor 0x8086 card 0x1211 (Intel Corporation, Card unknown)&lt;br /&gt;  STATUS    0x0010  COMMAND 0x0046&lt;br /&gt;  CLASS     0x02 0x80 0x00  REVISION 0x00&lt;br /&gt;  BIST      0x00  HEADER 0x00  LATENCY 0x00  CACHE 0x08&lt;br /&gt;  BASE0     0x00000000fe1fe004  addr 0x00000000fe1fe000  MEM 64BIT&lt;br /&gt;  MAX_LAT   0x00  MIN_GNT 0x00  INT_PIN 0x01  INT_LINE 0x05&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;Jetzt nur noch die passenden Werte in die &lt;i&gt;/etc/driver_aliases&lt;/i&gt; übertragen.&lt;br /&gt;&lt;code&gt;&lt;pre&gt;&lt;br /&gt;# update_drv -a -i '"pciex8086,4237"' iwh&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;Viola, Wireless auf dem SL500 :)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8144285405079538181-4520152926091840861?l=raichoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://raichoo.blogspot.com/feeds/4520152926091840861/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8144285405079538181&amp;postID=4520152926091840861' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/4520152926091840861'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/4520152926091840861'/><link rel='alternate' type='text/html' href='http://raichoo.blogspot.com/2008/12/wireless-lan-auf-dem-thinkpad-sl500.html' title='Wireless LAN auf dem Thinkpad SL500'/><author><name>Björn 'raichoo' Herzig</name><uri>https://profiles.google.com/102273886131939895778</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-KxzzpA_pbkc/AAAAAAAAAAI/AAAAAAAAARI/yHTIB2nrp8I/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8144285405079538181.post-2843217979022217749</id><published>2008-12-04T14:48:00.000-08:00</published><updated>2008-12-04T14:53:08.179-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='OpenSolaris'/><title type='text'>OpenSolaris 2008.11: Interview und Präsentation</title><content type='html'>Hier sind zwei nicht ganz uninteressante Videos die ich auf dem Blog von &lt;a href="http://www.redmonk.com"&gt;Redmonk&lt;/a&gt; gefunden habe.&lt;br /&gt;&lt;br /&gt;&lt;center&gt;&lt;embed src="http://blip.tv/play/gdMH24sOh70s" type="application/x-shockwave-flash" width="422" height="257" allowscriptaccess="always" allowfullscreen="true"&gt;&lt;/embed&gt;&lt;br /&gt;&lt;br /&gt;&lt;embed src="http://blip.tv/play/gdMH26A4h70s" type="application/x-shockwave-flash" width="422" height="257" allowscriptaccess="always" allowfullscreen="true"&gt;&lt;/embed&gt;&lt;/center&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8144285405079538181-2843217979022217749?l=raichoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://raichoo.blogspot.com/feeds/2843217979022217749/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8144285405079538181&amp;postID=2843217979022217749' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/2843217979022217749'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/2843217979022217749'/><link rel='alternate' type='text/html' href='http://raichoo.blogspot.com/2008/12/opensolaris-200811-interview-und.html' title='OpenSolaris 2008.11: Interview und Präsentation'/><author><name>Björn 'raichoo' Herzig</name><uri>https://profiles.google.com/102273886131939895778</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-KxzzpA_pbkc/AAAAAAAAAAI/AAAAAAAAARI/yHTIB2nrp8I/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8144285405079538181.post-7599783916382447339</id><published>2008-12-04T03:45:00.001-08:00</published><updated>2008-12-04T03:49:37.606-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='OpenSolaris'/><title type='text'>Screencast: What's new in OpenSolaris 2008.11</title><content type='html'>Ein zwölfminütiger Screencast über einige der neuen Features die OpenSolaris 2008.11 zu bieten hat mit Schwerpunkt auf Desktopfunktionalitäten.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://webcast-west.sun.com/interactive/09B12437/index.html"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 221px;" src="http://2.bp.blogspot.com/_3VHVa9AP0ZM/STfC6t8WLNI/AAAAAAAAAJQ/6m_Nnbf6VcY/s320/screencast_200811.PNG" border="0" alt=""id="BLOGGER_PHOTO_ID_5275899802508733650" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8144285405079538181-7599783916382447339?l=raichoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://raichoo.blogspot.com/feeds/7599783916382447339/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8144285405079538181&amp;postID=7599783916382447339' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/7599783916382447339'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/7599783916382447339'/><link rel='alternate' type='text/html' href='http://raichoo.blogspot.com/2008/12/screencast-whats-new-in-opensolaris.html' title='Screencast: What&apos;s new in OpenSolaris 2008.11'/><author><name>Björn 'raichoo' Herzig</name><uri>https://profiles.google.com/102273886131939895778</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-KxzzpA_pbkc/AAAAAAAAAAI/AAAAAAAAARI/yHTIB2nrp8I/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_3VHVa9AP0ZM/STfC6t8WLNI/AAAAAAAAAJQ/6m_Nnbf6VcY/s72-c/screencast_200811.PNG' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8144285405079538181.post-1448254153103734693</id><published>2008-12-02T09:41:00.000-08:00</published><updated>2010-04-17T01:01:33.368-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ZFS'/><category scheme='http://www.blogger.com/atom/ns#' term='OpenSolaris'/><category scheme='http://www.blogger.com/atom/ns#' term='Dtrace'/><title type='text'>OpenSolaris 2008.11 erschienen</title><content type='html'>Nach über 6 Monaten Wartezeit ist OpenSolaris 2008.11 nun auf &lt;a href="http://www.opensolaris.com"&gt;www.opensolaris.com&lt;/a&gt; erhältlich und es hat sich eine ganze Menge verändert. Während der erste Release noch sehr rudimentär war hat sich diese Version dem Desktop sehr viel mehr angenähert. Aktuellere Software, mehr Treiber und vor allem sind große Lücken in der Liste der Applikationen gefüllt worden. Ein paar der Highlights werde ich hier auflisten, dennoch ist dies nur ein kleiner Teil von dem was sich wirklich alles getan hat. &lt;a href="http://www.opensolaris.com/learn/features/whats-new/200811/"&gt;Noch mehr neues&lt;/a&gt; hat Glynn Foster aufgelistet.&lt;br /&gt;&lt;br /&gt;Einführungen zu OpenSolaris Technologien gibt wie &lt;a href="http://raichoo.blogspot.com/2008/08/dtrace-workshop-teil-1-einfhrung.html"&gt;Dtrace&lt;/a&gt;, &lt;a href="http://raichoo.blogspot.com/2008/11/zfs-eine-einfhrung.html"&gt;ZFS&lt;/a&gt; und &lt;a href="http://raichoo.blogspot.com/2008/10/beadm-ich-bin-nicht-eins-ich-bin-viele.html"&gt;Beadm&lt;/a&gt; gibt es auf diesem Blog ebenfalls zu finden.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Gnome 2.24&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Mit dem neuen Release wurde jetzt auch Gnome auf den neusten Stand gebracht. Für den inzwischen typischen Solaris Look sorgt natürlich wieder das Nimbus Theme&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_3VHVa9AP0ZM/SS-m7e3X-SI/AAAAAAAAAIo/MragdtvDirc/s1600-h/Screenshot-1.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 200px;" src="http://2.bp.blogspot.com/_3VHVa9AP0ZM/SS-m7e3X-SI/AAAAAAAAAIo/MragdtvDirc/s320/Screenshot-1.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5273617229501954338" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Firefox 3 und Openoffice 3&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Ebenfalls mit von der Partie sind der neuste Firefox und die allerneuste Version von OpenOffice&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_3VHVa9AP0ZM/SS-nZqn-jMI/AAAAAAAAAIw/xX8-Ik5XvnY/s1600-h/Screenshot-2.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 200px;" src="http://2.bp.blogspot.com/_3VHVa9AP0ZM/SS-nZqn-jMI/AAAAAAAAAIw/xX8-Ik5XvnY/s320/Screenshot-2.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5273617748054674626" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_3VHVa9AP0ZM/SS-oIMS6SkI/AAAAAAAAAI4/lHlUBCd18b8/s1600-h/Screenshot-3.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 200px;" src="http://4.bp.blogspot.com/_3VHVa9AP0ZM/SS-oIMS6SkI/AAAAAAAAAI4/lHlUBCd18b8/s320/Screenshot-3.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5273618547367103042" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Timeslider&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Eines der Highlights ist sicherlich Timeslider. Im 15 Minuten Abstand werden Snapshots erstellt. Über den Tag verteilt werden diese dann jeweils stündlich archiviert, sowie täglich und wöchentlich. Wenn es zu eng auf der Platte wird räumt Timeslider einfach auf (Snapshots nehmen lediglich den Unterschied zwischen Filesystem und dem archiviertem Zustand an Blöcken in Anspruch). Um die Snapshots selber kümmern sich im Hintergrund diverse SMF Services, es wird also nicht nur der eingeloggte Benutzer versorgt sondern alle gewünschten Filesysteme (sehr praktisch für die beliebte Aufgabe gelöschte Dateien wiederherzustellen ;) )&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_3VHVa9AP0ZM/SS-l6kFmKFI/AAAAAAAAAIY/k1jFWvUrX7A/s1600-h/Screenshot-Time+Slider+Setup.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 294px; height: 320px;" src="http://2.bp.blogspot.com/_3VHVa9AP0ZM/SS-l6kFmKFI/AAAAAAAAAIY/k1jFWvUrX7A/s320/Screenshot-Time+Slider+Setup.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5273616114212284498" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_3VHVa9AP0ZM/SS-mFE5n1bI/AAAAAAAAAIg/ZjfFqB1or28/s1600-h/Screenshot-zfs-auto-snap:frequent-2008-11-28-08:30+-+File+Browser.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 222px;" src="http://1.bp.blogspot.com/_3VHVa9AP0ZM/SS-mFE5n1bI/AAAAAAAAAIg/ZjfFqB1or28/s320/Screenshot-zfs-auto-snap:frequent-2008-11-28-08:30+-+File+Browser.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5273616294819124658" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Packagemanager mit neuen Repositories&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Zu dem überarbeiteten Paketmanager kommen jetzt auch zusätzliche Repositories welche unter anderem Developer Releases, Sicherheitsupdates oder Community Pakete zur Verfügung stellen.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_3VHVa9AP0ZM/SS-rDi4CYVI/AAAAAAAAAJI/ePOwdf0pLeE/s1600-h/Screenshot-Package+Manager.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 263px;" src="http://2.bp.blogspot.com/_3VHVa9AP0ZM/SS-rDi4CYVI/AAAAAAAAAJI/ePOwdf0pLeE/s320/Screenshot-Package+Manager.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5273621766063939922" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Network Automagic&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Network Automagic wurde einem kompletten Facelift unterzogen. Auch wurde die Funktionalität erweitert. WLAN läßt sich nun genauso unkompliziert verwalten wie auch mehrere Netzwerkschnittstellen (was bei der alten Version nicht wirklich der Fall war).&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;SunStudio und Dtrace&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Mit SunStudio Express enthält OpenSolaris eine komplette Entwicklungsumgebung mit Netbeans und den Sun Compilern und Debuggern. Netbeans enthält jetzt ebenso eine grafische Oberfläche für Dtrace mit dem Namen D-Light. Dtrace selber hat über die letzten Monate ebenso einige Updates erhalten wie z.B. den IP-Provider zum tracen von Netzwerkstack Aktivitäten.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_3VHVa9AP0ZM/SS-pIF2jwmI/AAAAAAAAAJA/9aUXTQWQwIg/s1600-h/Screenshot-Sun+Studio.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 194px;" src="http://1.bp.blogspot.com/_3VHVa9AP0ZM/SS-pIF2jwmI/AAAAAAAAAJA/9aUXTQWQwIg/s320/Screenshot-Sun+Studio.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5273619645149200994" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;ZFS 13 mit L2ARC&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Auch ZFS ist in der Version 13 enthalten und unterstützt jetzt auch die L2ARC von OpenStorage die es einem unter anderem ermöglicht die Vorteile von SSD und HDD Platten zu vereinen indem einige wenige SSD Platten (oder auch nur eine) als Cache vor viele HDD Platten geschaltet werden. Somit kann man die Zugriffsgeschwindigkeit von SSD nutzen aber hat die Speichermasse von kostengünstigen HDD Platten.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Viele neue Treiber und Pakete&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Dazu sind viele neue Treiber gekommen, vor allem Intel Chipsätze jeder Art werden inzwischen sehr gut unterstützt. Gleiches gilt inzwischen für erste SD-Card Reader und auch einige Webcams. Sollte das dennoch nicht reichen gibt es zusätzliche freie Netzwerkkarten Treiber bei &lt;a href="http://homepage2.nifty.com/mrym3/taiyodo/eng/"&gt;Freenic&lt;/a&gt; und Audiotreiber bei &lt;a href="http://www.4front-tech.com/download.cgi"&gt;Open Sound&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Also, viel Spass ;)&lt;br /&gt;&lt;br /&gt;Newslinks: &lt;a href="http://www.golem.de/0812/63892.html"&gt;Golem&lt;/a&gt;, &lt;a href="http://www.heise.de/newsticker/OpenSolaris-2008-11-ist-fertig--/meldung/119745"&gt;Heise&lt;/a&gt;, &lt;a href="http://distrowatch.com/?newsid=05218"&gt;Distrowatch&lt;/a&gt;, &lt;a href="http://osnews.com/story/20603/OpenSolaris_2008_11_Released"&gt;OSNews&lt;/a&gt;, &lt;a href="http://computerseite-spezial.de/index.php/opensolaris/105-opensolaris-200811-einfuehrung.html"&gt;OpenSolaris 2008.11: Das neue "Sonnensystem"&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8144285405079538181-1448254153103734693?l=raichoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://raichoo.blogspot.com/feeds/1448254153103734693/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8144285405079538181&amp;postID=1448254153103734693' title='4 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/1448254153103734693'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/1448254153103734693'/><link rel='alternate' type='text/html' href='http://raichoo.blogspot.com/2008/11/was-gibts-neues-bei-opensolaris-200811.html' title='OpenSolaris 2008.11 erschienen'/><author><name>Björn 'raichoo' Herzig</name><uri>https://profiles.google.com/102273886131939895778</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-KxzzpA_pbkc/AAAAAAAAAAI/AAAAAAAAARI/yHTIB2nrp8I/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_3VHVa9AP0ZM/SS-m7e3X-SI/AAAAAAAAAIo/MragdtvDirc/s72-c/Screenshot-1.png' height='72' width='72'/><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8144285405079538181.post-2099616109041676787</id><published>2008-11-29T06:54:00.000-08:00</published><updated>2008-11-29T07:05:41.965-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='OpenSolaris'/><title type='text'>OpenSolaris in den HPC Top 500</title><content type='html'>Der erste OpenSolaris HPC ist in den Top 500 aufgetaucht und auf Platz &lt;a href="http://www.top500.org/system/9790"&gt;221&lt;/a&gt; eingezogen. Bei dem guten Stück handelt es sich um ein Fujitsu System der Japan Aerospace Exploration Agency. Mehr dazu auf dem &lt;a href="http://blogs.sun.com/sjie/entry/opensolaris_on_hpc_top_500"&gt;Sun HPC Blog&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8144285405079538181-2099616109041676787?l=raichoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://raichoo.blogspot.com/feeds/2099616109041676787/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8144285405079538181&amp;postID=2099616109041676787' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/2099616109041676787'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/2099616109041676787'/><link rel='alternate' type='text/html' href='http://raichoo.blogspot.com/2008/11/opensolaris-in-den-hpc-top-500.html' title='OpenSolaris in den HPC Top 500'/><author><name>Björn 'raichoo' Herzig</name><uri>https://profiles.google.com/102273886131939895778</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-KxzzpA_pbkc/AAAAAAAAAAI/AAAAAAAAARI/yHTIB2nrp8I/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8144285405079538181.post-5732181391116872618</id><published>2008-11-27T05:14:00.000-08:00</published><updated>2008-11-27T05:31:27.115-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='OpenSolaris'/><title type='text'>Solaris Cluster: Jetzt mit Indersicherung!</title><content type='html'>Gerade auf Youtube gesehen... einfach zu gut ^^&lt;br /&gt;&lt;br /&gt;&lt;center&gt;&lt;object width="425" height="344"&gt;&lt;param name="movie" value="http://www.youtube.com/v/0PkQMW0yd4o&amp;hl=en&amp;fs=1"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/0PkQMW0yd4o&amp;hl=en&amp;fs=1" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;/center&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8144285405079538181-5732181391116872618?l=raichoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://raichoo.blogspot.com/feeds/5732181391116872618/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8144285405079538181&amp;postID=5732181391116872618' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/5732181391116872618'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/5732181391116872618'/><link rel='alternate' type='text/html' href='http://raichoo.blogspot.com/2008/11/solaris-cluster-jetzt-mit.html' title='Solaris Cluster: Jetzt mit Indersicherung!'/><author><name>Björn 'raichoo' Herzig</name><uri>https://profiles.google.com/102273886131939895778</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-KxzzpA_pbkc/AAAAAAAAAAI/AAAAAAAAARI/yHTIB2nrp8I/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8144285405079538181.post-435811171902698759</id><published>2008-11-27T03:19:00.001-08:00</published><updated>2010-04-17T01:01:50.148-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='OpenSolaris'/><title type='text'>Compiz unter OpenSolaris</title><content type='html'>Und nun wieder mal was für die Kategorie "Cool aber nutzlos". Compiz ist nicht gerade ein Auswahlkriterium für mich wenn es um Betriebssysteme geht, aber es ist schon sehr hübsch anzuschauen. Darum habe ich mich mal hingesetzt und mein System etwas getrimmt.&lt;br /&gt;&lt;br /&gt;Als erstes erstellen wir einfach eine xorg.conf. Xorg macht das automatisch wenn man als root &lt;i&gt;Xorg -configure&lt;/i&gt; eingibt. Die erstellte config dann einfach nach /etc/X11/xorg.conf kopieren.&lt;br /&gt;&lt;br /&gt;Nun haben wir folgendes Problem: Diese config verwendet als voreingestellte Beschleunigung EXA. Das ist auf meinem Intel Chip mehr als lahm und alles andere als weich und flüssig. Ein anderes Problem ist das in der Xorg Version von OpenSolaris die OffscreenPixmap Funktion per default aktiv ist, das sorgt für teilweise richtig eklige Grafikfehler. Also tragen wir folgendes in die Device Section ein:&lt;br /&gt;&lt;code&gt;&lt;pre&gt;&lt;br /&gt;Option      "AccelMethod"           "XAA"&lt;br /&gt;Option      "XAANoOffscreenPixmaps" "true"&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;Ok, jetzt einfach den X-Server neu starten und Compiz unter den visuellen Effekten aktivieren. Und voila: Es wird prollig ;)&lt;br /&gt;&lt;br /&gt;&lt;center&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_3VHVa9AP0ZM/SS6E6L-NczI/AAAAAAAAAIQ/w9EfBH8xHMs/s1600-h/Screenshot.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 200px;" src="http://2.bp.blogspot.com/_3VHVa9AP0ZM/SS6E6L-NczI/AAAAAAAAAIQ/w9EfBH8xHMs/s320/Screenshot.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5273298348878426930" /&gt;&lt;/a&gt;&lt;/center&gt;&lt;br /&gt;Es könnte sein das man anstatt der Schatten am Panel große weiße Balken sieht. Die kann man aber loswerden indem man einfach die Schattengröße in den Compiz Einstellungen anpasst&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8144285405079538181-435811171902698759?l=raichoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://raichoo.blogspot.com/feeds/435811171902698759/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8144285405079538181&amp;postID=435811171902698759' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/435811171902698759'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/435811171902698759'/><link rel='alternate' type='text/html' href='http://raichoo.blogspot.com/2008/11/compiz-unter-opensolaris.html' title='Compiz unter OpenSolaris'/><author><name>Björn 'raichoo' Herzig</name><uri>https://profiles.google.com/102273886131939895778</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-KxzzpA_pbkc/AAAAAAAAAAI/AAAAAAAAARI/yHTIB2nrp8I/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_3VHVa9AP0ZM/SS6E6L-NczI/AAAAAAAAAIQ/w9EfBH8xHMs/s72-c/Screenshot.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8144285405079538181.post-4182383409013446141</id><published>2008-11-26T04:28:00.000-08:00</published><updated>2010-04-17T01:00:55.626-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ZFS'/><title type='text'>Uni Münster migriert zu ZFS</title><content type='html'>Nachdem wir neulich die Ankündigung bekommen haben das unsere Homeverzeichnisse an der Uni umziehen werden und wir in Zukunft einen gewaltigen Performanceboost kriegen, war ich doch mal neugierig was das zu bedeuten hat. Ein kleiner Blick auf unseren Fileserver hat mir folgendes gezeigt:&lt;br /&gt;&lt;code&gt;&lt;pre&gt;&lt;br /&gt;  pool: pool&lt;br /&gt; state: ONLINE&lt;br /&gt; scrub: none requested&lt;br /&gt;config:&lt;br /&gt;&lt;br /&gt;        NAME          STATE     READ WRITE CKSUM&lt;br /&gt;        pool          ONLINE       0     0     0&lt;br /&gt;          mirror      ONLINE       0     0     0&lt;br /&gt;            cxtxdxsx  ONLINE       0     0     0&lt;br /&gt;            cxtxdxsx  ONLINE       0     0     0&lt;br /&gt;&lt;br /&gt;errors: No known data errors&lt;br /&gt;&lt;br /&gt;  pool: pool2&lt;br /&gt; state: ONLINE&lt;br /&gt; scrub: none requested&lt;br /&gt;config:&lt;br /&gt;&lt;br /&gt;        NAME          STATE     READ WRITE CKSUM&lt;br /&gt;        pool2         ONLINE       0     0     0&lt;br /&gt;          raidz1      ONLINE       0     0     0&lt;br /&gt;            cxtxdxsx  ONLINE       0     0     0&lt;br /&gt;            cxtxdxsx  ONLINE       0     0     0&lt;br /&gt;            cxtxdxsx  ONLINE       0     0     0&lt;br /&gt;            cxtxdxsx  ONLINE       0     0     0&lt;br /&gt;            cxtxdxsx  ONLINE       0     0     0&lt;br /&gt;            cxtxdxsx  ONLINE       0     0     0&lt;br /&gt;            cxtxdxsx  ONLINE       0     0     0&lt;br /&gt;            cxtxdxsx  ONLINE       0     0     0&lt;br /&gt;          raidz1      ONLINE       0     0     0&lt;br /&gt;            cxtxdxsx  ONLINE       0     0     0&lt;br /&gt;            cxtxdxsx  ONLINE       0     0     0&lt;br /&gt;            cxtxdxsx  ONLINE       0     0     0&lt;br /&gt;            cxtxdxsx  ONLINE       0     0     0&lt;br /&gt;            cxtxdxsx  ONLINE       0     0     0&lt;br /&gt;            cxtxdxsx  ONLINE       0     0     0&lt;br /&gt;            cxtxdxsx  ONLINE       0     0     0&lt;br /&gt;            cxtxdxsx  ONLINE       0     0     0&lt;br /&gt;&lt;br /&gt;errors: No known data errors&lt;br /&gt;NAME              SIZE    USED   AVAIL    CAP  HEALTH     ALTROOT&lt;br /&gt;pool             1.02T    321G    719G    30%  ONLINE     /&lt;br /&gt;pool2            17.4T   1.59T   15.8T     9%  ONLINE     /&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;YAY!!!! Nuff said! :P (btw die Daten sind natürlich verfremdet ;)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8144285405079538181-4182383409013446141?l=raichoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://raichoo.blogspot.com/feeds/4182383409013446141/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8144285405079538181&amp;postID=4182383409013446141' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/4182383409013446141'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/4182383409013446141'/><link rel='alternate' type='text/html' href='http://raichoo.blogspot.com/2008/11/uni-mnster-migriert-auf-zfs.html' title='Uni Münster migriert zu ZFS'/><author><name>Björn 'raichoo' Herzig</name><uri>https://profiles.google.com/102273886131939895778</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-KxzzpA_pbkc/AAAAAAAAAAI/AAAAAAAAARI/yHTIB2nrp8I/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8144285405079538181.post-9114165499605785086</id><published>2008-11-24T05:05:00.000-08:00</published><updated>2008-11-24T05:09:34.179-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='OpenSolaris'/><title type='text'>OpenSolaris 2008.11 RC2 erschienen</title><content type='html'>Das ganze gibts auf &lt;a href="http://www.genunix.org"&gt;www.genunix.org&lt;/a&gt; zum Runterladen. Bugs bitte auf &lt;a href="http://defect.opensolaris.org"&gt;defect.opensolaris.org&lt;/a&gt; melden.&lt;br /&gt;&lt;br /&gt;Happy testing :)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8144285405079538181-9114165499605785086?l=raichoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://raichoo.blogspot.com/feeds/9114165499605785086/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8144285405079538181&amp;postID=9114165499605785086' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/9114165499605785086'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/9114165499605785086'/><link rel='alternate' type='text/html' href='http://raichoo.blogspot.com/2008/11/opensolaris-200811-rc2-erschienen.html' title='OpenSolaris 2008.11 RC2 erschienen'/><author><name>Björn 'raichoo' Herzig</name><uri>https://profiles.google.com/102273886131939895778</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-KxzzpA_pbkc/AAAAAAAAAAI/AAAAAAAAARI/yHTIB2nrp8I/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8144285405079538181.post-4359711653609670811</id><published>2008-11-10T13:08:00.000-08:00</published><updated>2010-04-17T01:01:13.692-07:00</updated><title type='text'>Papa's got a brandnew pigbag!</title><content type='html'>Nachdem sich bei mir geradezu ein Rechnermaßensterben zugetragen hat, habe ich mir endlich ein neues Notebook geleistet. Das Lenovo Thinkpad SL500 hochgerüstet auf 4GB RAM: Das perfekte OpenSolaris Notebook. Das einzige was derzeit nicht unterstützt wird ist der Intel 5100 Wlan Chip und für den gibt es bereits Treiber (muss wohl nur noch lernen auch meine Karte zu erkennen, Bugreport ist bereits verschickt und akzeptiert :) ). Ansonsten geht wirklich alles vom Fingerabdruckscanner (naja... als wenns was bringen würde) bis zur Webcam :).&lt;br /&gt;&lt;br /&gt;&lt;center&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_3VHVa9AP0ZM/SRikHqzxhoI/AAAAAAAAAII/VWCLAD8S8AA/s1600-h/desktop"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 200px;" src="http://2.bp.blogspot.com/_3VHVa9AP0ZM/SRikHqzxhoI/AAAAAAAAAII/VWCLAD8S8AA/s320/desktop" border="0" alt=""id="BLOGGER_PHOTO_ID_5267140215867278978" /&gt;&lt;/a&gt;&lt;/center&gt;&lt;br /&gt;&lt;br /&gt;Anmerkung: Ja, den Desktop gibts auch in deutsch. Ich hab meinen allerdings immer englisch, sieht einfach besser aus.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8144285405079538181-4359711653609670811?l=raichoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://raichoo.blogspot.com/feeds/4359711653609670811/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8144285405079538181&amp;postID=4359711653609670811' title='1 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/4359711653609670811'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/4359711653609670811'/><link rel='alternate' type='text/html' href='http://raichoo.blogspot.com/2008/11/papas-got-brandnew-pigbag.html' title='Papa&apos;s got a brandnew pigbag!'/><author><name>Björn 'raichoo' Herzig</name><uri>https://profiles.google.com/102273886131939895778</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-KxzzpA_pbkc/AAAAAAAAAAI/AAAAAAAAARI/yHTIB2nrp8I/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_3VHVa9AP0ZM/SRikHqzxhoI/AAAAAAAAAII/VWCLAD8S8AA/s72-c/desktop' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8144285405079538181.post-8421264493312475804</id><published>2008-11-05T14:31:00.001-08:00</published><updated>2008-11-05T14:39:20.494-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ZFS'/><title type='text'>Screencast: ZFS Selbstheilung</title><content type='html'>Wie ich schon in einem &lt;a href="http://raichoo.blogspot.com/2008/11/mythbusting-foofs-lvm-zfs.html"&gt;Artikel&lt;/a&gt; erwähnt habe, hat ZFS die Möglichkeit Fehler zu erkennen und diese auch selbst zu heilen. Für alle die das mal gerne in Aktion sehen wollen gibt es da einen interessanten &lt;a href="http://opensolaris.org/os/community/zfs/demos/selfheal/"&gt;Screencast&lt;/a&gt; ;). Man brauch auch nicht unbedingt einen Mirror dafür sondern kann einem ZFS sagen das es mehrere Kopien der Daten transparent angelegen soll (mit &lt;i&gt;zfs set copies=n myzfs&lt;/i&gt; erzeugt das Filesystem myzfs n Kopien der Daten und kann korrumpierte Daten in Notfall rekonstruieren).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8144285405079538181-8421264493312475804?l=raichoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://raichoo.blogspot.com/feeds/8421264493312475804/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8144285405079538181&amp;postID=8421264493312475804' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/8421264493312475804'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/8421264493312475804'/><link rel='alternate' type='text/html' href='http://raichoo.blogspot.com/2008/11/screencast-zfs-selbstheilung.html' title='Screencast: ZFS Selbstheilung'/><author><name>Björn 'raichoo' Herzig</name><uri>https://profiles.google.com/102273886131939895778</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-KxzzpA_pbkc/AAAAAAAAAAI/AAAAAAAAARI/yHTIB2nrp8I/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8144285405079538181.post-7264535365313163815</id><published>2008-11-05T05:10:00.000-08:00</published><updated>2008-11-05T05:18:48.777-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ZFS'/><title type='text'>Screencast: ZFS Basics</title><content type='html'>Passend zu meiner &lt;a href="http://raichoo.blogspot.com/2008/11/zfs-eine-einfhrung.html"&gt;Einführung in ZFS&lt;/a&gt; ist jetzt auch ein Screencast erschienen der ein paar der Funktionen von ZFS live zeigt. Immer wieder beeindruckend zu sehen wie schnell ZFS ist.&lt;br /&gt;&lt;br /&gt;&lt;center&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://webcast-west.sun.com/interactive/09A12416/index.html"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 170px;" src="http://1.bp.blogspot.com/_3VHVa9AP0ZM/SRGcpY3MNnI/AAAAAAAAAIA/8STRFTQ_v1g/s320/zfs_demo.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5265161674235328114" /&gt;&lt;/a&gt;&lt;/center&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8144285405079538181-7264535365313163815?l=raichoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://raichoo.blogspot.com/feeds/7264535365313163815/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8144285405079538181&amp;postID=7264535365313163815' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/7264535365313163815'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/7264535365313163815'/><link rel='alternate' type='text/html' href='http://raichoo.blogspot.com/2008/11/screencast-zfs-basics.html' title='Screencast: ZFS Basics'/><author><name>Björn 'raichoo' Herzig</name><uri>https://profiles.google.com/102273886131939895778</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-KxzzpA_pbkc/AAAAAAAAAAI/AAAAAAAAARI/yHTIB2nrp8I/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_3VHVa9AP0ZM/SRGcpY3MNnI/AAAAAAAAAIA/8STRFTQ_v1g/s72-c/zfs_demo.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8144285405079538181.post-1011176367376584367</id><published>2008-11-04T04:50:00.001-08:00</published><updated>2008-11-04T07:02:24.891-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ZFS'/><title type='text'>Mythbusting: $FOOFS + LVM = ZFS</title><content type='html'>Man hört es ja immer wieder wenn man ZFS erwähnt: "Das kann ich doch auch mit LVM machen!" oder "ZFS verletzt ja den ganzen Layergedanken, das gehört getrennt weils ja sonst total Bloatware ist". Damit möchte ich gerne mal in ein paar Punkten aufräumen, vor allem aber auch zeigen das diese Designentscheidung alles andere als willkürlich ist. Dazu werde ich 2 klassische ZFS Beispiele besprechen:  Selbstheilung und Intelligentes Prefetching&lt;br /&gt;&lt;br /&gt;Sehen wir uns erst einmal an wie ein Mirror auf herkömmliche Art und Weise angelegt ist:&lt;br /&gt;&lt;br&gt;&lt;br /&gt;&lt;center&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_3VHVa9AP0ZM/SRBaHfixVxI/AAAAAAAAAHg/qno4hcznl8s/s1600-h/lvm.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 176px; height: 320px;" src="http://1.bp.blogspot.com/_3VHVa9AP0ZM/SRBaHfixVxI/AAAAAAAAAHg/qno4hcznl8s/s320/lvm.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5264807049169032978" /&gt;&lt;/a&gt;&lt;/center&gt;&lt;br /&gt;Hier liegt eine klassische Trennung von Filesystem und Volumemanager vor. Das Filesystem hat keinerlei Ahnung das es auf einem Mirror arbeitet der Volumemanager liefert ihm einfach ein virtuelles Device und veranstaltet sein spiegeln unbemerkt vom Filesystem. Auf der anderen Seite kennt der Volumemanager sich aber auch nicht mit dem Filesystem aus, er arbeitet einfach nur mit abstrakten Daten die er wegschreibt und er nicht versteht da er keinerlei Bezug zum Filesystem hat.&lt;br /&gt;&lt;br /&gt;ZFS ist hier in 3 Schichten aufgeteilt:&lt;br /&gt;&lt;br&gt;&lt;br /&gt;&lt;center&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_3VHVa9AP0ZM/SRBjj31PmzI/AAAAAAAAAH4/F3ZjYeSATVU/s1600-h/zfsmir.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 148px; height: 320px;" src="http://1.bp.blogspot.com/_3VHVa9AP0ZM/SRBjj31PmzI/AAAAAAAAAH4/F3ZjYeSATVU/s320/zfsmir.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5264817432329952050" /&gt;&lt;/a&gt;&lt;/center&gt;&lt;br /&gt;Dem ZFS Posix Layer (ZPL) welcher die normale Posix API zur Verfügung stellt (open,close,read,write etc) darunter liegt direkt das ZFS welches einzelne Transaktionen (ZFS arbeitet NUR mit Transaktionen, dass heißt das das Filesystem nie in einen inkonsistenten Zustand kommt) an die Data Management Unit (DMU) weitergibt welche viele Transaktionen zu einer großen zusammenfasst und der Storage Pool Allocator (SPA) welcher Kenntnis von den Platten (die in unserem Beispiel gespiegelt sind) hat.&lt;br /&gt;&lt;br /&gt;Jetzt wollen wir als Beispiel auf einem Spiegel einen fehlerhaften Block haben welcher gelesen wird, sagen wir einfach mal es handelt sich hier um Metadaten welche durch äußere Einwirkungen (Erschütterung, Strahlung, statische Entladung etc) verändert wurden. Der Volumemanager hat hier keine Ahnung ob die Daten korrekt sind und reicht sie ans Filesystem weiter. Im schlimmsten Fall kommt es jetzt zu einer Kernelpanic im weniger schlimmen werden falsche Daten gelesen und die Applikation liefert falsche Ergebnisse oder stürzt ab. Da das Filesystem allerdings keinerlei Ahnung hat das es auf einem Mirror arbeitet kann es selbst wenn es bemerkt das die Daten falsch sind ja nicht wissen das evtl ein Mirror mit richtigen Daten existiert und keine korrekten Daten anfordern (da Volumemanager und Filesystem nun einmal voneinander getrennt sind).&lt;br /&gt;&lt;br /&gt;Wie macht ZFS das nun? Als Erstes räumt das Design von ZFS mit dem immer noch verbreiteten Glauben auf das Prüfsummen teuer sind. Bei den heuten Rechnergeschwindigkeiten ist die Berechnung einer solchen Summe zeitlich gesehen zu vernachlässigen. Dies macht sich ZFS zu nutze und sichert JEDEN Block mit einer Prüfsumme (default 256-bit). ZFS erkennt also immer ob ein Block immer noch in dem gleichen Zustand auf der Platte liegt wie es ihn geschrieben hat.&lt;br /&gt;Wir lesen nun den gleichen Block aus dem oberen Beispiel noch einmal. Durch die Prüfsumme erkennen wir das der Block falsch ist und da ZFS selber Kenntnis darüber hat das es auf einem Mirror arbeitet fordert es den gleichen Block von der anderen Platte erneut an. Dieser ist in unserem Beispiel korrekt worauf er an die Applikation weitergereicht wird während der andere fehlerhafte Block verworfen wird und mit dem korrekten von der anderen Platte automatisch überschrieben wird. Die Applikation merkt davon nicht das geringste. (Es ist sogar möglich eine der beiden Platte während eines Lese/Schreibvorgangs mit dd if=/dev/random zu überschreiben ohne das die Applikation fehlerhafte Daten zu sehen kriegt, gleichzeitig wird der Schaden den dd anrichtet transparent geheilt)&lt;br /&gt;&lt;br /&gt;&lt;center&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_3VHVa9AP0ZM/SRBd2H58ASI/AAAAAAAAAHw/NXorpzAi2ZI/s1600-h/fehler.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 247px;" src="http://3.bp.blogspot.com/_3VHVa9AP0ZM/SRBd2H58ASI/AAAAAAAAAHw/NXorpzAi2ZI/s320/fehler.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5264811148812484898" /&gt;&lt;/a&gt;&lt;/center&gt;&lt;br /&gt;&lt;br /&gt;Hat man nur eine Festplatte zu Verfügung kann man durch &lt;i&gt;zfs set copies=n filesystem&lt;/i&gt; veranlassen das alle Datenblöcke n-fach geschrieben werden. Tritt nun ein Fehler auf wird dieser genauso geheilt wie auf einem Mirror. Man kann so ein extra Filesystem für sehr sensible Daten absichern ohne mehrere Platten zur Verfügung zu haben (z.b. auf Notebooks).&lt;br /&gt;&lt;br /&gt;Ein anderes beliebtes Beispiel ist der intelligente Prefetchmechanismus. Nehmen wir folgendes an: Auf einem Filesystem liegt eine Videodatei die gleichzeitig von mehreren Benutzern gelesen wird. Alles in allem sind dies sequentielle Lesezugriffe, da alle diese User jedoch eine andere Stelle der Datei lesen kann man hier mit der herkömmlichen Aufteilung kein sequentielles Pattern erkennen, hier kann also kein Prefetch stattfinden da nicht erkannt wird welcher Block als nächstes gelesen wird. Da ZFS allerdings den Userkontext hat kann es erkennen das es sich hier um mehrere sequentielle Reads handelt und dementsprechend optimieren für normale Filesysteme + Volumemanager bleibt dies aufgrund des mangelnden Kontexts eine zufällige Leseabfolge.&lt;br /&gt; &lt;br /&gt;Dies sind nur ein paar Beispiele welche Vorteile das Zusammenlegen von Volumemanager und Filesystem hat, unter anderem kann man damit auch dynamische Stripes haben etc.&lt;br /&gt;&lt;br /&gt;ZFS räumt mit Annahmen auf die inzwischen 20 oder 30 Jahre alt sind, es ist komplett neu entwickelt worden mit Blick auf die Computerwelt wie sie heute ist, in der Storagekapazitäten gigantische Ausmaße annehmen und Fehler aufgrund von großen Datendurchsatz sehr leicht auftreten können und möglichst transparent repariert werden sollten. Unter anderem hat ZFS auch die on-disk Struktur stark vereinfacht (Metadaten,inodes welche hier znodes heissen, Daten etc werden gleich behandelt) oder Vorgänge wie formatieren und partitionieren abgeschafft (wer will heute schon 100TB formatieren und auf derartigen Speichermengen noch mit grow und shrink rumhantieren ;) ).&lt;br /&gt;&lt;br /&gt;Ergo: Myth BUSTED!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8144285405079538181-1011176367376584367?l=raichoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://raichoo.blogspot.com/feeds/1011176367376584367/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8144285405079538181&amp;postID=1011176367376584367' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/1011176367376584367'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/1011176367376584367'/><link rel='alternate' type='text/html' href='http://raichoo.blogspot.com/2008/11/mythbusting-foofs-lvm-zfs.html' title='Mythbusting: $FOOFS + LVM = ZFS'/><author><name>Björn 'raichoo' Herzig</name><uri>https://profiles.google.com/102273886131939895778</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-KxzzpA_pbkc/AAAAAAAAAAI/AAAAAAAAARI/yHTIB2nrp8I/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_3VHVa9AP0ZM/SRBaHfixVxI/AAAAAAAAAHg/qno4hcznl8s/s72-c/lvm.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8144285405079538181.post-4527617887446660117</id><published>2008-11-02T01:51:00.000-07:00</published><updated>2008-11-02T01:07:59.263-08:00</updated><title type='text'>Die CDDL ist nicht OpenSource?</title><content type='html'>Anscheinend gibt es immer noch Leute die meinen deratige Parolen schwingen zu müssen (über den Ton den man anderen Personen gegenüber da an den Tag legt will ich hier gar nicht reden). Dabei wiegen Links und andere Beweise wohl anscheinend weniger als "neeeeeeee, wenn ich das sage ist das so". Halten wir die Sache kurz, mit einem Auszug aus der &lt;a href="http://de.wikipedia.org/wiki/CDDL"&gt;Wikipedia&lt;/a&gt;:&lt;br&gt;&lt;br /&gt;&lt;i&gt;Die CDDL wurde am 1. Dezember 2004 der Open Source Initiative zur Abklärung zugesandt und Mitte Januar 2005 für Open-Source-kompatibel befunden. Die CDDL ist auch von der Free Software Foundation (FSF) als freie Lizenz anerkannt.&lt;/i&gt;&lt;br&gt;&lt;br /&gt;Und einem Link auf &lt;a href="http://www.opensource.org/licenses/cddl1.php"&gt;opensource.org&lt;/a&gt;.&lt;br&gt;&lt;br /&gt;Langsam nerven diese "heiligen Kriege"...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8144285405079538181-4527617887446660117?l=raichoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://raichoo.blogspot.com/feeds/4527617887446660117/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8144285405079538181&amp;postID=4527617887446660117' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/4527617887446660117'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/4527617887446660117'/><link rel='alternate' type='text/html' href='http://raichoo.blogspot.com/2008/11/die-cddl-ist-nicht-opensource.html' title='Die CDDL ist nicht OpenSource?'/><author><name>Björn 'raichoo' Herzig</name><uri>https://profiles.google.com/102273886131939895778</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-KxzzpA_pbkc/AAAAAAAAAAI/AAAAAAAAARI/yHTIB2nrp8I/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8144285405079538181.post-1977849625296758119</id><published>2008-11-01T07:57:00.000-07:00</published><updated>2008-11-01T10:08:05.666-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='MacOSX'/><category scheme='http://www.blogger.com/atom/ns#' term='ZFS'/><category scheme='http://www.blogger.com/atom/ns#' term='FreeBSD'/><category scheme='http://www.blogger.com/atom/ns#' term='Linux'/><category scheme='http://www.blogger.com/atom/ns#' term='OpenSolaris'/><title type='text'>ZFS: Eine Einführung</title><content type='html'>Krank sein nervt, aber wenn man im Bett liegt kann man sich mit ein paar Sachen befassen die man sonst eher selten macht. Ich hab die letzten Tage die ich mit Grippe im Bett gelegen hab einfach mal damit verbracht mich in einige ZFS Features einzuarbeiten und mir Gedanken darüber zu machen wie man sie in einem Blog packt. Damit auch die Linuxwelt etwas davon hat hab ich mich auch gleich noch darum gekümmert &lt;a href="http://raichoo.blogspot.com/2008/11/zfs-unter-ubuntu-intrepid-ibex.html"&gt;ZFS unter Ubuntu&lt;/a&gt; zum fliegen zu bringen.&lt;br /&gt;&lt;br /&gt;Naja lange Rede kurzer Unsinn.&lt;br /&gt;&lt;br /&gt;ZFS! Immer wieder hört man das es sich hierbei "nur" um ein Filesystem handelt. Ich will heute mal zeigen das das zwar stimmt, ZFS aber sehr viel mehr ist. Es ist praktisch ein Storage Werkzeugkoffer der fast alles abdeckt was einem in Sachen Storage so über den Weg laufen kann. Das Element mit dem alles anfängt ist der sogenannte &lt;i&gt;zpool&lt;/i&gt;. In einem zpool packen wir alles was wir an Storage so nutzen wollen: Festplatte, USB-Sticks, einfach nur Dateien und was weiß ich noch für Devices. Ich werde hier aufgrund eines notorischen Festplattenmangels einfach ganz normale Files nehmen die jeweils 100MB Größe haben.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;&lt;i&gt;ZPools&lt;/b&gt;&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;Als erstes werden wir einfach mal die einfachste Sorte von zpools anlegen, nämlich solche die nur aus einem Datenträger bestehen.&lt;br /&gt;&lt;code&gt;&lt;pre&gt;&lt;br /&gt;[root@itzkoatl:zfsdemo]&gt; zpool create tank $PWD/disk1 &lt;br /&gt;[root@itzkoatl:zfsdemo]&gt; zpool list&lt;br /&gt;NAME    SIZE   USED  AVAIL    CAP  HEALTH  ALTROOT&lt;br /&gt;tank   95.5M  73.5K  95.4M     0%  ONLINE  -&lt;br /&gt;[root@itzkoatl:zfsdemo]&gt; zpool status tank&lt;br /&gt;  pool: tank&lt;br /&gt; state: ONLINE&lt;br /&gt; scrub: none requested&lt;br /&gt;config:&lt;br /&gt;&lt;br /&gt; NAME                                  STATE     READ WRITE CKSUM&lt;br /&gt; tank                                  ONLINE       0     0     0&lt;br /&gt;   /export/home/raichoo/zfsdemo/disk1  ONLINE       0     0     0&lt;br /&gt;&lt;br /&gt;errors: No known data errors&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;Das wars eigentlich schon. Alleine durch die Eingabe von &lt;i&gt;zpool create tank $PWD/disk1&lt;/i&gt; haben wir einen neuen zpool erstellt. Kein formatieren, kein mounten. Das File wurde direkt mit einem ZFS Filesystem auf dem mountpunkt /tank angehängt. Das dauert nur wenige Sekunden.&lt;br /&gt;Was aber machen wenn man mehrere Festplatten hat und deren Platz in einem pool verwenden will?&lt;br /&gt;&lt;code&gt;&lt;pre&gt;&lt;br /&gt;[root@itzkoatl:zfsdemo]&gt; zpool add tank $PWD/disk2   &lt;br /&gt;[root@itzkoatl:zfsdemo]&gt; zpool status tank&lt;br /&gt;  pool: tank&lt;br /&gt; state: ONLINE&lt;br /&gt; scrub: none requested&lt;br /&gt;config:&lt;br /&gt;&lt;br /&gt; NAME                                  STATE     READ WRITE CKSUM&lt;br /&gt; tank                                  ONLINE       0     0     0&lt;br /&gt;   /export/home/raichoo/zfsdemo/disk1  ONLINE       0     0     0&lt;br /&gt;   /export/home/raichoo/zfsdemo/disk2  ONLINE       0     0     0&lt;br /&gt;&lt;br /&gt;errors: No known data errors&lt;br /&gt;[root@itzkoatl:zfsdemo]&gt; zpool list &lt;br /&gt;NAME    SIZE   USED  AVAIL    CAP  HEALTH  ALTROOT&lt;br /&gt;tank    191M  82.5K   191M     0%  ONLINE  -&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;Wir haben die neue Platte einfach durch add in den zpool eingefügt und wir &lt;i&gt;zpool list&lt;/i&gt; zeigt hat sich die Kapazität von tank verdoppelt.&lt;br /&gt;Wir können aber auch zpool mit RAID Fähigkeiten erstellen, dazu gibt es die subkommandos mirror, raidz und raidz2.&lt;br /&gt;&lt;code&gt;&lt;pre&gt;&lt;br /&gt;[root@itzkoatl:zfsdemo]&gt; zpool create tank mirror $PWD/disk1 $PWD/disk2&lt;br /&gt;[root@itzkoatl:zfsdemo]&gt; zpool status tank&lt;br /&gt;  pool: tank&lt;br /&gt; state: ONLINE&lt;br /&gt; scrub: none requested&lt;br /&gt;config:&lt;br /&gt;&lt;br /&gt; NAME                                    STATE     READ WRITE CKSUM&lt;br /&gt; tank                                    ONLINE       0     0     0&lt;br /&gt;   mirror                                ONLINE       0     0     0&lt;br /&gt;     /export/home/raichoo/zfsdemo/disk1  ONLINE       0     0     0&lt;br /&gt;     /export/home/raichoo/zfsdemo/disk2  ONLINE       0     0     0&lt;br /&gt;&lt;br /&gt;errors: No known data errors&lt;br /&gt;...&lt;br /&gt;[root@itzkoatl:zfsdemo]&gt; zpool create tank raidz2 $PWD/disk1 $PWD/disk2 $PWD/disk3 $PWD/disk4&lt;br /&gt;[root@itzkoatl:zfsdemo]&gt; zpool status tank                                    &lt;br /&gt;  pool: tank&lt;br /&gt; state: ONLINE&lt;br /&gt; scrub: none requested&lt;br /&gt;config:&lt;br /&gt;&lt;br /&gt; NAME                                    STATE     READ WRITE CKSUM&lt;br /&gt; tank                                    ONLINE       0     0     0&lt;br /&gt;   raidz2                                ONLINE       0     0     0&lt;br /&gt;     /export/home/raichoo/zfsdemo/disk1  ONLINE       0     0     0&lt;br /&gt;     /export/home/raichoo/zfsdemo/disk2  ONLINE       0     0     0&lt;br /&gt;     /export/home/raichoo/zfsdemo/disk3  ONLINE       0     0     0&lt;br /&gt;     /export/home/raichoo/zfsdemo/disk4  ONLINE       0     0     0&lt;br /&gt;&lt;br /&gt;errors: No known data errors&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;Man kann noch sehr viel mehr mit zpools anstellen, aber das reicht fürs erste ;).&lt;br /&gt;&lt;br /&gt;&lt;b&gt;&lt;i&gt;Filesysteme&lt;/i&gt;&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Das erste Filesystem haben wir ja schon mit dem Erstellen des zpools angelegt. Es trägt den Namen tank und ist unter /tank gemountet.&lt;br /&gt;&lt;code&gt;&lt;pre&gt;&lt;br /&gt;[root@itzkoatl:zfsdemo]&gt; zfs list&lt;br /&gt;NAME   USED  AVAIL  REFER  MOUNTPOINT&lt;br /&gt;tank  98.6K   158M  26.9K  /tank&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;Wir tun jetzt einfach mal so als würden wir eine Art home-Struktur anlegen wollen. Dazu legen wir ein separates home-Filesystem und ein Filesystem für jeden Benutzer an. ZFS Filesysteme sind in etwa vergleichbar mit dem was man unter herkömmlichen Filesystemen als Partitionen bezeichnet, nur das sie sich in ihrer Größe dem Inhalt anpassen. Ein ZFS Filesystem in dem also nichts liegt wird auch praktisch nichts an Plattenplatz belegen.&lt;br /&gt;&lt;code&gt;&lt;pre&gt;&lt;br /&gt;[root@itzkoatl:zfsdemo]&gt; zfs create tank/home&lt;br /&gt;[root@itzkoatl:zfsdemo]&gt; zfs create tank/user1&lt;br /&gt;[root@itzkoatl:zfsdemo]&gt; zfs create tank/user2&lt;br /&gt;[root@itzkoatl:zfsdemo]&gt; zfs create tank/user3&lt;br /&gt;[root@itzkoatl:zfsdemo]&gt; zfs list&lt;br /&gt;NAME         USED  AVAIL  REFER  MOUNTPOINT&lt;br /&gt;tank         247K   158M  34.4K  /tank&lt;br /&gt;tank/home   26.9K   158M  26.9K  /tank/home&lt;br /&gt;tank/user1  26.9K   158M  26.9K  /tank/user1&lt;br /&gt;tank/user2  26.9K   158M  26.9K  /tank/user2&lt;br /&gt;tank/user3  26.9K   158M  26.9K  /tank/user3&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;So wir haben unsere Filesysteme erstellt aber UPS! unsere User sind ja gar nicht an der richtigen Stelle gemountet, eigentlich gehören die ja nach /tank/home. Kein Problem, wir können den Mountpoint im Nachhinein einfach setzen&lt;br /&gt;&lt;code&gt;&lt;pre&gt;&lt;br /&gt;[root@itzkoatl:tank]&gt; zfs set mountpoint=/tank/home/user1 tank/user1&lt;br /&gt;[root@itzkoatl:tank]&gt; zfs rename tank/user1 tank/home/user1&lt;br /&gt;[root@itzkoatl:tank]&gt; zfs list&lt;br /&gt;NAME              USED  AVAIL  REFER  MOUNTPOINT&lt;br /&gt;tank              258K   158M  32.9K  /tank&lt;br /&gt;tank/home        55.3K   158M  28.4K  /tank/home&lt;br /&gt;tank/home/user1  26.9K   158M  26.9K  /tank/home/user1&lt;br /&gt;tank/user2       26.9K   158M  26.9K  /tank/user2&lt;br /&gt;tank/user3       26.9K   158M  26.9K  /tank/user3&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;Das rename ist eigentlich nicht nötig, ich habe es allerdings hier aus Schönheitsgründen mal gemacht ;). Durch das Umsetzen des Mountpoints wird das Filesystem von seinem alten Standort ausgehängt und am neuen Mountpoint eingehängt, alles automatisch.&lt;br /&gt;Wir räumen jetzt einfach mal die anderen Filesysteme weg und arbeiten nur noch mit user1 weiter.&lt;br /&gt;&lt;code&gt;&lt;pre&gt;&lt;br /&gt;[root@itzkoatl:tank]&gt; zfs destroy tank/user2&lt;br /&gt;[root@itzkoatl:tank]&gt; zfs destroy tank/user3&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;&lt;i&gt;Filesystem Attribute&lt;/b&gt;&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;Jetzt zu ein paar interessanten Attributen die man mit set und get setzen und auslesen kann. Ich werde nur ein paar davon zeigen weil es wirklich eine ganze Menge sind, aber ich halte diese für die praktischsten.&lt;br /&gt;&lt;br /&gt;&lt;i&gt;Reservation&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;Hiermit läßt sich Plattenplatz aus dem zpool reservieren. Dem Filesystem wird also eine bestimmte Menge Storage zugesichert, wie man unten sieht hat tank/home/user1 10MB mehr Speicher zur Verfügung als alle anderen Filesysteme.&lt;br /&gt;&lt;code&gt;&lt;pre&gt;&lt;br /&gt;[root@itzkoatl:tank]&gt; zfs set reservation=10m tank/home/user1&lt;br /&gt;[root@itzkoatl:tank]&gt; zfs list&lt;br /&gt;NAME               USED  AVAIL  REFER  MOUNTPOINT&lt;br /&gt;tank              10.2M   148M  28.4K  /tank&lt;br /&gt;tank/home         10.0M   148M  28.4K  /tank/home&lt;br /&gt;tank/home/user1   26.9K   158M  26.9K  /tank/home/user1&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;i&gt;Quotas&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;Was man reservieren kann, kann man aus begrenzen. Mit Quotas lassen sich Filesysteme klein halten.&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;pre&gt;&lt;br /&gt;[root@itzkoatl:tank]&gt; zfs set quota=10m tank/home/user1&lt;br /&gt;[root@itzkoatl:tank]&gt; zfs list                         &lt;br /&gt;NAME              USED  AVAIL  REFER  MOUNTPOINT&lt;br /&gt;tank             10.2M   148M  28.4K  /tank&lt;br /&gt;tank/home        10.0M   148M  28.4K  /tank/home&lt;br /&gt;tank/home/user1  26.9K  9.97M  26.9K  /tank/home/user1&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;i&gt;Compression&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;Der Name sagt es schon. Filesysteme lassen sich transparent komprimieren. Es gibt unterschiedliche Algorithmen wir nehmen hier gzip als Beispiel.&lt;br /&gt;&lt;code&gt;&lt;pre&gt;&lt;br /&gt;[root@itzkoatl:tank]&gt; zfs set compression=gzip tank/home/user1&lt;br /&gt;[root@itzkoatl:tank]&gt; zfs get compression tank/home/user1&lt;br /&gt;NAME             PROPERTY     VALUE            SOURCE&lt;br /&gt;tank/home/user1  compression  gzip             local&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;Hier sollte man daran denken das nur Dateien komprimiert werden die nachträglich im Filesystem erstellt werden. Auch zeigt ls nicht die komprimierte sondern die reale Größe der Datei an.&lt;br /&gt;&lt;br /&gt;&lt;i&gt;NFS&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;Besonders praktisch ist NFS Sharing. Ich werde hier nur die einfachste Form zeigen, aber anstatt &lt;i&gt;on&lt;/i&gt; lassen sich die normalen NFS Optionen für das Filesystem angeben. Unter Solaris wird hier alles automatisch eingerichtet und gestartet so das das eingeben einer einzige Zeile reicht um Filesysteme zu sharen (keine Ahnung wie das unter anderem Systemen ist).&lt;br /&gt;&lt;code&gt;&lt;pre&gt;&lt;br /&gt;[root@itzkoatl:tank]&gt; zfs set sharenfs=on tank/home/user1&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Das sind nur ein paar der vielen Attribute die ZFS bietet, alle zu zeigen würden den Rahmen sprengen ;)&lt;br /&gt;&lt;br /&gt;&lt;i&gt;&lt;b&gt;Snapshots&lt;/i&gt;&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Kommen wir zu einem meiner Lieblingsfeatures: Snapshots. Mit Snapshots lassen sich Filesysteme zu einem bestimmten Zeitpunkt einfrieren und auch wieder zurückspielen (und das innerhalb von ein paar Sekunden und ohne das es extra Plattenplatz belegt). Es ist ebenfalls jederzeit möglich in angelegt Snapshots reinzugucken. Wir werden jetzt einfach mal folgendes machen: Wie legen eine Datei mit dem Text "Das ist ein Test" an, danach erstellen wir einen Snapshot und werden die Datei verändern.&lt;br /&gt;&lt;code&gt;&lt;pre&gt;&lt;br /&gt;[root@itzkoatl:user1]&gt; echo "Das ist ein Test" &gt; text&lt;br /&gt;[root@itzkoatl:user1]&gt; ls&lt;br /&gt;text&lt;br /&gt;[root@itzkoatl:user1]&gt; cat text&lt;br /&gt;Das ist ein Test&lt;br /&gt;[root@itzkoatl:user1]&gt; zfs snapshot tank/home/user1@kleinertest&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;Ok wir haben den Zustand unseres Filesystems jetzt unter dem Snapshot mit dem Namen &lt;i&gt;kleinertest&lt;/i&gt; gesichert. Nun wollen wir unsere Datei mal kaputtmachen und alles wieder herstellen.&lt;br /&gt;&lt;code&gt;&lt;pre&gt;[root@itzkoatl:user1]&gt; echo "Ich mach alles kaputt!" &gt;| text &lt;br /&gt;[root@itzkoatl:user1]&gt; cat text &lt;br /&gt;Ich mach alles kaputt!&lt;br /&gt;[root@itzkoatl:user1]&gt; cat .zfs/snapshot/kleinertest/text &lt;br /&gt;Das ist ein Test&lt;br /&gt;[root@itzkoatl:user1]&gt; zfs rollback tank/home/user1@kleinertest&lt;br /&gt;[root@itzkoatl:user1]&gt; cat text                                &lt;br /&gt;Das ist ein Test&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;Wie man sieht existiert ein versteckter Ordner &lt;i&gt;.zfs&lt;/i&gt;, dieser wird nicht von ls -a angezeigt (Es sei denn man setzt ein bestimmtes Attribut) sondern praktisch on-the-fly erstellt wenn man explizit auf ihn zugreift. Mit &lt;i&gt;zfs rollback&lt;/i&gt; spulen wir das Filesystem wieder zu dem Zeitpunkt zurück an dem wir den Snapshot &lt;i&gt;kleinertest&lt;/i&gt; erstellt haben (der Snapshot selber existiert weiter). Snapshot sind nicht beschreibbar aber es lassen sich mit &lt;i&gt;zfs clone&lt;/i&gt; schreibbare Filesysteme aus einem Snapshot erstellen.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;&lt;i&gt;Serialisieren&lt;/i&gt;&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Ein Filesystem läßt sich in eine einzelne Datei ausgeben die sich dann verschicken läßt und woanders wieder in ein Filesystem umwandeln läßt (sehr praktisch für Backups). Dazu brauchen wir erst einmal einen Snapshot, dieser läßt sich mit &lt;i&gt;zfs send&lt;/i&gt; serialisieren und mit &lt;i&gt;zfs receive&lt;/i&gt; wieder "entpacken".&lt;br /&gt;&lt;code&gt;&lt;pre&gt;&lt;br /&gt;[root@itzkoatl:user1]&gt; zfs send tank/home/user1@kleinertest &gt; /tank/dump&lt;br /&gt;[root@itzkoatl:user1]&gt; ls -l /tank/dump&lt;br /&gt;-rw-r--r--   1 root     root       15680 Nov  1 17:29 /tank/dump&lt;br /&gt;[root@itzkoatl:user1]&gt; zfs receive tank/home/user2 &lt; /tank/dump&lt;br /&gt;[root@itzkoatl:user1]&gt; cat /tank/home/user2/text &lt;br /&gt;Das ist ein Test&lt;br /&gt;[root@itzkoatl:user1]&gt; zfs list&lt;br /&gt;NAME               USED  AVAIL  REFER  MOUNTPOINT&lt;br /&gt;tank              10.2M   148M  45.6K  /tank&lt;br /&gt;tank/home         10.1M   148M  31.4K  /tank/home&lt;br /&gt;tank/home/user1   29.1K  9.97M  29.1K  /tank/home/user1&lt;br /&gt;tank/home/user2   27.6K   148M  27.6K  /tank/home/user2&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;Wir haben also nun aus der dump-datei einfach ein neues Userverzeichnis erstellt welches den Zeitpunkt wiederspiegelt an dem wir &lt;i&gt;kleinertest&lt;/i&gt; erstellt haben. Snapshots lassen sich auch separat mit &lt;i&gt;zfs list -t snapshot&lt;/i&gt; anzeigen&lt;br /&gt;&lt;code&gt;&lt;pre&gt;&lt;br /&gt;[root@itzkoatl:user1]&gt; zfs list -t snapshot&lt;br /&gt;NAME                          USED  AVAIL  REFER  MOUNTPOINT&lt;br /&gt;tank/home/user1@kleinertest      0      -  29.1K  -&lt;br /&gt;tank/home/user2@kleinertest      0      -  27.6K  -&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;Wie man sieht waren in unserem dump sogar alle Snapshots des Filesystems erhalten (user2 hat ebenfalls einen Snapshot &lt;i&gt;kleinertest&lt;/i&gt;)&lt;br /&gt;&lt;br /&gt;&lt;i&gt;&lt;b&gt;Import und Export&lt;/b&gt;&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;Filesysteme müssen manchmal mobil sein, z.b. wenn sie auf USB-Sticks liegen. Hierzu kann man zpools einfach exportieren. Exportierte zpools sind ohne das man sie wieder importiert nicht benutzbar (sie werden auch automatisch ausgehängt etc). Steckt man z.b. einen USB-Stick mit einem zpool in das System ein, reicht unter Solaris ein &lt;i&gt;zpool import&lt;/i&gt; und alle exportierten Ports werden angezeigt. Ohne Paramter durchsucht dieser Befehl automatisch alle Datenträger nach exportierten zpools im /dev Filesystem.&lt;br /&gt;Da unsere disk Dateien jetzt aber keine echten Devices sind müssen wir den Ort an dem &lt;i&gt;zpool import&lt;/i&gt; suchen soll explizit angeben.&lt;br /&gt;&lt;code&gt;&lt;pre&gt;&lt;br /&gt;[root@itzkoatl:~]&gt; zpool export tank&lt;br /&gt;[root@itzkoatl:~]&gt; zpool import -d ./zfsdemo&lt;br /&gt;  pool: tank&lt;br /&gt;    id: 14691414290482700440&lt;br /&gt; state: ONLINE&lt;br /&gt;action: The pool can be imported using its name or numeric identifier.&lt;br /&gt;config:&lt;br /&gt;&lt;br /&gt; tank                                    ONLINE&lt;br /&gt;   raidz2                                ONLINE&lt;br /&gt;     /export/home/raichoo/zfsdemo/disk1  ONLINE&lt;br /&gt;     /export/home/raichoo/zfsdemo/disk2  ONLINE&lt;br /&gt;     /export/home/raichoo/zfsdemo/disk3  ONLINE&lt;br /&gt;     /export/home/raichoo/zfsdemo/disk4  ONLINE&lt;br /&gt;[root@itzkoatl:~]&gt; zpool import -d ./zfsdemo tank&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Das war ein kleiner aber recht umfangreicher Ausflug in die Welt von ZFS. Und vielen dürfte jetzt klar sein das ZFS mehr ist als nur Volumemanager und Filesystem in einem, es ist ein Storage Verwaltungstools. ZFS ist inzwischen neben Solaris auf FreeBSD, MacOSX und Linux (nur über FUSE) verfügbar. An weiteren Ports wird gearbeitet.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8144285405079538181-1977849625296758119?l=raichoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://raichoo.blogspot.com/feeds/1977849625296758119/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8144285405079538181&amp;postID=1977849625296758119' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/1977849625296758119'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/1977849625296758119'/><link rel='alternate' type='text/html' href='http://raichoo.blogspot.com/2008/11/zfs-eine-einfhrung.html' title='ZFS: Eine Einführung'/><author><name>Björn 'raichoo' Herzig</name><uri>https://profiles.google.com/102273886131939895778</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-KxzzpA_pbkc/AAAAAAAAAAI/AAAAAAAAARI/yHTIB2nrp8I/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8144285405079538181.post-866636406506949708</id><published>2008-11-01T06:22:00.001-07:00</published><updated>2008-11-01T06:51:26.817-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ZFS'/><category scheme='http://www.blogger.com/atom/ns#' term='Linux'/><title type='text'>ZFS unter Ubuntu Intrepid Ibex</title><content type='html'>ZFS und Linux ist ja leider ein Thema für sich, aber mit ein paar Handgriffen kann man es sich zumindest so zurechtbiegen das es unter FUSE im Userspace rennt. Auch wenn das nicht gerade die performanteste Lösung auf Erden ist kann man so wenigstens seine zpools unter Linux benutzen.&lt;br /&gt;&lt;br /&gt;Um die aktuelle Version 0.5.0 zu kompilieren muss man lediglich die folgenden Pakete nachinstallieren:&lt;br /&gt;&lt;b&gt;build-essential libfuse-dev libaio-dev zlib1g-dev scons&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Die aktuelle "ZFS on FUSE" Version findet man &lt;a href="https://developer.berlios.de/project/showfiles.php?group_id=6836"&gt;hier&lt;/a&gt;. Übersetzen und installieren läßt sich das ganze nachdem wir die oben genannten Pakete installiert haben:&lt;br /&gt;&lt;code&gt;&lt;pre&gt;&lt;br /&gt;raichoo@tensaiga:Projects$ tar xfvj zfs-fuse-0.5.0.tar.bz2&lt;br /&gt;...&lt;br /&gt;raichoo@tensaiga:Projects$ cd zfs-fuse-0.5.0/src&lt;br /&gt;raichoo@tensaiga:Projects$ scons&lt;br /&gt;...&lt;br /&gt;raichoo@tensaiga:Projects$ sudo scons install&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Mit &lt;b&gt;sudo zfs-fuse&lt;/b&gt; starten wir den Userspace Prozess der ZFS verwaltet.&lt;br /&gt;&lt;br /&gt;Leider schmeißt der Code sehr viele Warnings und es ist gleichzeitig das &lt;b&gt;-Werror&lt;/b&gt; Flag gesetzt welches ein kompilieren in diesem Fall unmöglich macht. Also entfernen wir dieses Flag aus der src/SConstruct aus dem CFLAGS Eintrage. Das ganze sieht dann so aus:&lt;br /&gt;&lt;code&gt;&lt;pre&gt;&lt;br /&gt;env['CCFLAGS'] = Split('-pipe -Wall -std=c99 -Wno-switch&lt;br /&gt;-Wno-unused -Wno-missing-braces -Wno-parentheses&lt;br /&gt;-Wno-uninitialized -fno-strict-aliasing -D_GNU_SOURCE&lt;br /&gt;-D_FILE_OFFSET_BITS=64 -D_REENTRANT &lt;br /&gt;-DTEXT_DOMAIN=\\"zfs-fuse\\" -DLINUX_AIO')&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;Ich weiß das ist unschön und gehört eigentlich verboten... vielleicht kennt jemand einen besseren Weg, ich würde mich sehr über Tipps freuen.&lt;br /&gt;&lt;br /&gt;&lt;center&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_3VHVa9AP0ZM/SQxeaK85T9I/AAAAAAAAAHY/a4sPzcZd58Y/s1600-h/zfs.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 214px;" src="http://4.bp.blogspot.com/_3VHVa9AP0ZM/SQxeaK85T9I/AAAAAAAAAHY/a4sPzcZd58Y/s320/zfs.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5263685868198645714" /&gt;&lt;/a&gt;&lt;/center&gt;&lt;br /&gt;&lt;br /&gt;Ich plane im Moment eine kleine ZFS Einführung an der jetzt hoffentlich auch die Linuxuser ihren Spaß haben werden.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8144285405079538181-866636406506949708?l=raichoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://raichoo.blogspot.com/feeds/866636406506949708/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8144285405079538181&amp;postID=866636406506949708' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/866636406506949708'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/866636406506949708'/><link rel='alternate' type='text/html' href='http://raichoo.blogspot.com/2008/11/zfs-unter-ubuntu-intrepid-ibex.html' title='ZFS unter Ubuntu Intrepid Ibex'/><author><name>Björn 'raichoo' Herzig</name><uri>https://profiles.google.com/102273886131939895778</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-KxzzpA_pbkc/AAAAAAAAAAI/AAAAAAAAARI/yHTIB2nrp8I/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_3VHVa9AP0ZM/SQxeaK85T9I/AAAAAAAAAHY/a4sPzcZd58Y/s72-c/zfs.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8144285405079538181.post-1194684266167471453</id><published>2008-10-26T06:50:00.001-07:00</published><updated>2008-10-26T08:43:53.999-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='OpenSolaris'/><title type='text'>Interview mit Ian Murdock</title><content type='html'>Ein interessantes Interview vom Linuxtag mit dem Gründer von Debian.&lt;br&gt;&lt;br&gt;&lt;br /&gt;&lt;center&gt;&lt;object width="425" height="344"&gt;&lt;param name="movie" value="http://www.youtube.com/v/kNZwBdfUdhc&amp;hl=en&amp;fs=1"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/kNZwBdfUdhc&amp;hl=en&amp;fs=1" type="application/x-shockwave-flash" allowfullscreen="true" width="425" height="344"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;/center&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8144285405079538181-1194684266167471453?l=raichoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://raichoo.blogspot.com/feeds/1194684266167471453/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8144285405079538181&amp;postID=1194684266167471453' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/1194684266167471453'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/1194684266167471453'/><link rel='alternate' type='text/html' href='http://raichoo.blogspot.com/2008/10/interview-mit-ian-murdock.html' title='Interview mit Ian Murdock'/><author><name>Björn 'raichoo' Herzig</name><uri>https://profiles.google.com/102273886131939895778</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-KxzzpA_pbkc/AAAAAAAAAAI/AAAAAAAAARI/yHTIB2nrp8I/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8144285405079538181.post-5808870947318306508</id><published>2008-10-26T05:50:00.000-07:00</published><updated>2008-10-26T08:43:34.862-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ZFS'/><category scheme='http://www.blogger.com/atom/ns#' term='OpenSolaris'/><title type='text'>Wie ZFS das Booten verändert</title><content type='html'>ZFS ändert nicht nur die Art und Weise wie wir mit Filesystemen umgehen (kein Partitionieren und Formatieren mehr etc.) sondern auch wie wir booten. Wie das alles technisch funktioniert und welche Möglichkeiten das eröffnet hat Lori Alt in einem &lt;a href="http://blogs.sun.com/storage/entry/zfs_boot_in_solaris_10"&gt;sehr sehenswerten Vortrag&lt;/a&gt; erläutert. Die Beispiele sind auf Solaris 10 bezogen. Unter der OpenSolaris Distro verwenden wir nicht die LU Tools sondern &lt;a href="http://raichoo.blogspot.com/2008/10/beadm-ich-bin-nicht-eins-ich-bin-viele.html"&gt;BEadm&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8144285405079538181-5808870947318306508?l=raichoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://raichoo.blogspot.com/feeds/5808870947318306508/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8144285405079538181&amp;postID=5808870947318306508' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/5808870947318306508'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/5808870947318306508'/><link rel='alternate' type='text/html' href='http://raichoo.blogspot.com/2008/10/wie-zfs-das-booten-verndert.html' title='Wie ZFS das Booten verändert'/><author><name>Björn 'raichoo' Herzig</name><uri>https://profiles.google.com/102273886131939895778</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-KxzzpA_pbkc/AAAAAAAAAAI/AAAAAAAAARI/yHTIB2nrp8I/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8144285405079538181.post-7257533125859465449</id><published>2008-10-26T03:55:00.000-07:00</published><updated>2008-10-26T08:43:04.691-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='OpenSolaris'/><title type='text'>Ein kleiner Preview auf 2008.11</title><content type='html'>Gman hat hier auf ein Video Review zum Thema OpenSolaris geantwortet und ein paar interessante Ankündigungen für 2008.11 gemacht. Besonders interessant finde ich den automatisierten Installer und den "Distribution Creator" mit dem man sich seine eigene Distro maßschneidern kann (Mit KDE4 Paketen könnte man sich dann eine KDE OpenSolaris Distro selberbacken ^^). Es bleibt also wie immer spannend.&lt;br /&gt;&lt;br /&gt;&lt;center&gt;&lt;object width="425" height="344"&gt;&lt;param name="movie" value="http://www.youtube.com/v/-xhEQ9KEfFA&amp;hl=en&amp;fs=1"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/-xhEQ9KEfFA&amp;hl=en&amp;fs=1" type="application/x-shockwave-flash" allowfullscreen="true" width="425" height="344"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;/center&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8144285405079538181-7257533125859465449?l=raichoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://raichoo.blogspot.com/feeds/7257533125859465449/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8144285405079538181&amp;postID=7257533125859465449' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/7257533125859465449'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/7257533125859465449'/><link rel='alternate' type='text/html' href='http://raichoo.blogspot.com/2008/10/ein-kleiner-preview-auf-200811.html' title='Ein kleiner Preview auf 2008.11'/><author><name>Björn 'raichoo' Herzig</name><uri>https://profiles.google.com/102273886131939895778</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-KxzzpA_pbkc/AAAAAAAAAAI/AAAAAAAAARI/yHTIB2nrp8I/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8144285405079538181.post-9122099134728645857</id><published>2008-10-25T07:19:00.000-07:00</published><updated>2008-10-25T07:36:40.598-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='OpenSolaris'/><title type='text'>Constantin Gonzalez zeigt wie's geht</title><content type='html'>Solaris hat ja immer den Ruf ziemlich benutzerunfreundlich gewesen zu sein, mit der OpenSolaris Distribution von Sun soll sich das jetzt ändern mit der derzeitigen Version 2008.05 hat sich zwar schon vieles verbessert aber sicherlich bleibt noch einiges zu tun (2008.11 welches gegen Ende November erscheint wird da allerdings sehr viel neues dazubringen ;).&lt;br /&gt;Für alle die einfach mal sehen wollen wie "schwer" es ist OpenSolaris zu installieren hier einfach mal ein kleiner Video Podcast von SunVision.tv&lt;br /&gt;&lt;br /&gt;&lt;center&gt;&lt;object width="425" height="344"&gt;&lt;param name="movie" value="http://www.youtube.com/v/CzOvNeutwIY&amp;hl=en&amp;fs=1"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/CzOvNeutwIY&amp;hl=en&amp;fs=1" type="application/x-shockwave-flash" allowfulscreen="true" width="425" height="344"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;/center&gt;&lt;br /&gt;&lt;br /&gt;Besonders praktisch ist das Device Utility welches gleich auf dem Desktop liegt und gleich anzeigt welche Geräte unterstützt werden (hat mir bei meiner Entscheidung welches Notebook ich kaufen will seeeeeeehr geholfen ^^). Sollte mit der aktuellen LiveCD einiges nicht klappen kann man auch einfach auf den aktuellen Build auf &lt;a href="http://www.genunix.org/"&gt;Genunix.org&lt;/a&gt; zurückgreifen (im Moment ist Build 99 aktuell). Diese Builds erscheinen meistens alle 2 Wochen und erhalten jedesmal jede Menge Bugfixes, neue Features und auch neue Treiber und lassen sich wie die normale OpenSolaris CD als LiveCD nutzen.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8144285405079538181-9122099134728645857?l=raichoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://raichoo.blogspot.com/feeds/9122099134728645857/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8144285405079538181&amp;postID=9122099134728645857' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/9122099134728645857'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/9122099134728645857'/><link rel='alternate' type='text/html' href='http://raichoo.blogspot.com/2008/10/constantin-gonzalez-zeigt-wies-geht.html' title='Constantin Gonzalez zeigt wie&apos;s geht'/><author><name>Björn 'raichoo' Herzig</name><uri>https://profiles.google.com/102273886131939895778</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-KxzzpA_pbkc/AAAAAAAAAAI/AAAAAAAAARI/yHTIB2nrp8I/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8144285405079538181.post-2889331064880436869</id><published>2008-10-25T04:32:00.000-07:00</published><updated>2010-04-17T01:04:37.208-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='OpenSolaris'/><title type='text'>OpenSolaris Usergroup Münster/Bielefeld/Osnabrück</title><content type='html'>Ich nehme hiermit einfach mal die Freiheit eine OpenSolaris Usergroup für den Bereich Münster, Bielefeld und Osnabrück auszurufen. Frei nach Jim's &lt;a href="http://blogs.sun.com/jimgris/entry/running_successful_opensolaris_user_groups"&gt;10 Punkte Plan für eine erfolgreiche Usergroup&lt;/a&gt; geht es erst einmal darum Interessenten zu finden und einen kleinen Stammtisch zu organisieren. Als Anlaufpunkt kann man sich gerne bei mir melden oder ihr schaut einfach in unserem Community Channel &lt;i&gt;#opensolaris-de&lt;/i&gt; auf Freenode vorbei. Jeder ist willkommen, egal ob Profi oder einfach nur Neugieriger. Alles ist noch offen für neue Ideen und Anregungen ;)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8144285405079538181-2889331064880436869?l=raichoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://raichoo.blogspot.com/feeds/2889331064880436869/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8144285405079538181&amp;postID=2889331064880436869' title='4 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/2889331064880436869'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/2889331064880436869'/><link rel='alternate' type='text/html' href='http://raichoo.blogspot.com/2008/10/opensolaris-usergroup.html' title='OpenSolaris Usergroup Münster/Bielefeld/Osnabrück'/><author><name>Björn 'raichoo' Herzig</name><uri>https://profiles.google.com/102273886131939895778</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-KxzzpA_pbkc/AAAAAAAAAAI/AAAAAAAAARI/yHTIB2nrp8I/s512-c/photo.jpg'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8144285405079538181.post-5424948415040427778</id><published>2008-10-24T13:10:00.000-07:00</published><updated>2008-10-24T13:31:46.045-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='OpenSolaris'/><title type='text'>"Less know Solaris Features" Handbuch zum Download</title><content type='html'>Für alle die sowas wie das FreeBSD Handbuch für Solaris suchen gibt es jetzt etwas interessantes auf &lt;a href="http://www.c0t0d0s0.org/pages/lksfbook.html"&gt;http://www.c0t0d0s0.org&lt;/a&gt;. Auch sonst ein durchaus lesenswerter Blog ;)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8144285405079538181-5424948415040427778?l=raichoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://raichoo.blogspot.com/feeds/5424948415040427778/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8144285405079538181&amp;postID=5424948415040427778' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/5424948415040427778'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/5424948415040427778'/><link rel='alternate' type='text/html' href='http://raichoo.blogspot.com/2008/10/less-know-solaris-features-handbuch-zum.html' title='&quot;Less know Solaris Features&quot; Handbuch zum Download'/><author><name>Björn 'raichoo' Herzig</name><uri>https://profiles.google.com/102273886131939895778</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-KxzzpA_pbkc/AAAAAAAAAAI/AAAAAAAAARI/yHTIB2nrp8I/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8144285405079538181.post-4909369487131009666</id><published>2008-10-17T23:57:00.000-07:00</published><updated>2008-10-18T00:23:13.956-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ZFS'/><category scheme='http://www.blogger.com/atom/ns#' term='Linux'/><title type='text'>ZFS für Linux kriegt ein Upgrade</title><content type='html'>Totgesagte leben länger heißt es ja so schön. So ist in dem ganzen Rummel um das Datenbank-Filesystem Btrfs und die neue ext Version wohl untergegangen das es schon im letzten Monat ein Upgrade für &lt;a href="http://zfs-on-fuse.blogspot.com/2008/09/zfs-fuse-050-released.html"&gt;ZFS on Fuse&lt;/a&gt;. Die neue Version unterstützt unter anderem ZFS Pools der Version 13 und beseitigt kritische Bugs. Das eröffnet die Möglichkeit ZFS Wechseldatenträger jetzt auf Mac OS X, FreeBSD, Linux und natürlich Solaris zu nutzen (wenn Windows jetzt noch ZFS kriegen würde könnte man endlich auf FAT verzichten... *träum*). Weitere Open Source Betriebssysteme wie NetBSD und DragonflyBSD arbeiten ebenfalls an einer Portierung. Natives ZFS unter Linux ist derzeit nicht möglich da die GPL das mischen mit Open Source Code der nicht unter GPL steht verbietet (bei Nvidia-Treibern scheint es zu gehen... ein Schelm wer Böses denkt ;) ).&lt;br /&gt;&lt;br /&gt;Mich persönlich würde interessieren wie hoch der Performanceverlust ist wenn man ein derartig komplexes Filesystem im Userspace laufen läßt. Falls Linux-user mit ZFS Erfahrung das lesen würde mich ein Feedback interessieren.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8144285405079538181-4909369487131009666?l=raichoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://raichoo.blogspot.com/feeds/4909369487131009666/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8144285405079538181&amp;postID=4909369487131009666' title='2 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/4909369487131009666'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/4909369487131009666'/><link rel='alternate' type='text/html' href='http://raichoo.blogspot.com/2008/10/zfs-fr-linux-kriegt-ein-upgrade.html' title='ZFS für Linux kriegt ein Upgrade'/><author><name>Björn 'raichoo' Herzig</name><uri>https://profiles.google.com/102273886131939895778</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-KxzzpA_pbkc/AAAAAAAAAAI/AAAAAAAAARI/yHTIB2nrp8I/s512-c/photo.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8144285405079538181.post-4800180024611806872</id><published>2008-10-17T13:59:00.000-07:00</published><updated>2008-10-17T15:28:59.946-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='OpenSolaris'/><category scheme='http://www.blogger.com/atom/ns#' term='Zones'/><title type='text'>Spaß mit Solaris-Zones</title><content type='html'>Zones werden immer wieder als eins von den Killer Features von Solaris genannt. Es handelt sich hierbei um eine Art leichtgewichtige Virtualisierung ähnlich den FreeBSD Jails, nur sehr viel mächtiger. Unter anderem ist es auch möglich sogenannte "branded zones", welche z.B. Linux virtualisieren, anzulegen.&lt;br /&gt;Ich werde heute erst einmal zeigen wie man eine Zone vom Typ ipkg anlegt, dies sind einfache Instanzen von Solaris. Sie laufen völlig abgeschottet vom Rest das Systems. In ihnen lassen sich separate Services fahren und man kann ihnen unter anderem eingeschränkte Ressourcen (z.b. eine einzelne CPU von einem SMP System) zuweisen.&lt;br /&gt;Ein Beispiel:&lt;i&gt; In einer Zone läuft ein Webserver auf den ein Angriff gelingt. Der Angreifer hat sich jetzt zwar Zugriff auf die Zone verschafft, kann aber nicht auf andere Services in anderen Zones zugreifen oder auf das Hauptsystem welches von der Zone aus nicht sichtbar ist. Eine DoS Attacke die z.b. versucht alle Ressourcen des Systems aufzubrauchen schlägt fehl da diese beschränkt sind.&lt;/i&gt;&lt;br /&gt;Um Zones anzulegen und zu verwalten greift man auf die Tools &lt;b&gt;zonecfg&lt;/b&gt; und &lt;b&gt;zoneadm&lt;/b&gt; zurück.&lt;br /&gt;Als erstes listen wir einfach mal alle Zonen auf die wir haben:&lt;br /&gt;&lt;code&gt;&lt;pre&gt;&lt;br /&gt;[root@itzkoatl:zones]&gt; zoneadm list -cv          &lt;br /&gt;  ID NAME             STATUS     PATH                           BRAND    IP    &lt;br /&gt;   0 global           running    /                              native   shared&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;&lt;b&gt;global&lt;/b&gt; steht für unser Hauptsystem. Die Option &lt;b&gt;-c&lt;/b&gt; zeigt uns Zonen an die im Status &lt;i&gt;configured&lt;/i&gt; sind, dazu aber später.&lt;br /&gt;Nun wollen wir unser System fit für Zones machen. Ich lege dazu einfach ein zusätzliches ZFS Filesystem im Ordner /export an. Dies geschieht einfach durch den Befehl &lt;i&gt; zfs create rpool/export/zones&lt;/i&gt;. (Zones brauchen anscheinend ein separates Filesystem auf dem sie angelegt werden).&lt;br /&gt;Originell wie wir sind legen wir jetzt eine Zone mit dem Namen "test" an:&lt;br /&gt;&lt;code&gt;&lt;pre&gt;&lt;br /&gt;[root@itzkoatl:~]&gt; zonecfg -z test&lt;br /&gt;test: No such zone configured&lt;br /&gt;Use 'create' to begin configuring a new zone.&lt;br /&gt;zonecfg:test&gt; create&lt;br /&gt;zonecfg:test&gt; set zonepath=/export/zones/test&lt;br /&gt;zonecfg:test&gt; verify&lt;br /&gt;zonecfg:test&gt; commit&lt;br /&gt;zonecfg:test&gt; exit&lt;br /&gt;[root@itzkoatl:~]&gt; zoneadm list -cv                      &lt;br /&gt;  ID NAME             STATUS     PATH                           BRAND    IP    &lt;br /&gt;   0 global           running    /                              native   shared&lt;br /&gt;   - test             configured /export/zones/test             ipkg     shared&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;Mit &lt;i&gt;create&lt;/i&gt; lege ich die Zone an, nun muss ich lediglich einen Pfad angeben in dem die Zone beherbergt werden soll (dafür haben wir ja gerade unser ZFS Filesystem errpool/export/zones erstellt). Mit &lt;i&gt;verify&lt;/i&gt; überprüfen wir ob auch alles ok ist und mit &lt;i&gt;commit&lt;/i&gt; legen wir dann die Konfiguration an (Für alle die es interessiert: die Konfiguration wird in /etc/zones/test.xml gespeichert).&lt;br /&gt;Unsere Zone befindet sich nun im Status &lt;i&gt;configured&lt;/i&gt;, das bedeutet das wir jetzt ein System in die Zone installieren können. Nachdem wir das System erfolgreich in die Zone installiert haben läßt sie sich wie ein separater Rechner booten und wir können uns mit zlogin einloggen.&lt;br /&gt;&lt;code&gt;&lt;pre&gt;&lt;br /&gt;[root@itzkoatl:~]&gt; zoneadm -z test install&lt;br /&gt;A ZFS file system has been created for this zone.&lt;br /&gt;  Authority: Using http://pkg.opensolaris.org:80/.&lt;br /&gt;      Image: Preparing at /export/zones/test/root ... done.&lt;br /&gt;      Cache: Using /var/pkg/download.&lt;br /&gt; Installing: (output follows)&lt;br /&gt;DOWNLOAD                                    PKGS       FILES     XFER (MB)&lt;br /&gt;Completed                                  52/52   7842/7842   75.32/75.32 &lt;br /&gt;&lt;br /&gt;PHASE                                        ACTIONS&lt;br /&gt;Install Phase                            12903/12903 &lt;br /&gt;PHASE                                          ITEMS&lt;br /&gt;Reading Existing Index                           9/9 &lt;br /&gt;Indexing Packages                              52/52 &lt;br /&gt;&lt;br /&gt;       Note: Man pages can be obtained by installing SUNWman&lt;br /&gt;Postinstall: Copying SMF seed repository ... done.&lt;br /&gt;Postinstall: Working around http://defect.opensolaris.org/bz/show_bug.cgi?id=741&lt;br /&gt;       Done: Installation completed in 268.109 seconds.&lt;br /&gt;&lt;br /&gt; Next Steps: Boot the zone, then log into the zone console&lt;br /&gt;             (zlogin -C) to complete the configuration process&lt;br /&gt;[root@itzkoatl:~]&gt; zoneadm -z test boot &lt;br /&gt;[root@itzkoatl:~]&gt; zlogin -C test&lt;br /&gt;[Connected to zone 'test' console]&lt;br /&gt;(hier hab ich noch mal ENTER drücken müssen)&lt;br /&gt;&lt;br /&gt;You did not enter a selection.&lt;br /&gt;What type of terminal are you using?&lt;br /&gt; 1) ANSI Standard CRT&lt;br /&gt; 2) DEC VT100&lt;br /&gt; 3) PC Console&lt;br /&gt; 4) Sun Command Tool&lt;br /&gt; 5) Sun Workstation&lt;br /&gt; 6) X Terminal Emulator (xterms)&lt;br /&gt; 7) Other&lt;br /&gt;Type the number of your choice and press Return: &lt;br /&gt;...&lt;br /&gt;test console login: root&lt;br /&gt;Password: &lt;br /&gt;Oct 17 14:53:45 test login: ROOT LOGIN /dev/console&lt;br /&gt;Sun Microsystems Inc.   SunOS 5.11      snv_99  November 2008&lt;br /&gt;root@test:~# &lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;Jetzt werden wir durch eine Installationsroutine geführt (Zum Fortfahren einfach ESC-2 drücken). Danach läuft eine virtualisierte Instanz von Solaris auf unserem System. Übrigens beim erstellen einer neuen Zone wird pkg eventuell einige Pakete herunterladen, dies geschieht aber nur einmal und zukünftige Zones werden sich die Pakete einfach aus dem Package-cache ziehen. &lt;br /&gt;&lt;br /&gt;Jetzt wollen wir als kleines i-Tüpfelchen noch eine virtuelle Netzwerkkarte hinzufügen und unserer Zone eine eigene IP geben ;)&lt;br /&gt;Dazu machen wir im Hostsystem folgendes:&lt;br /&gt;&lt;code&gt;&lt;pre&gt;&lt;br /&gt;[root@itzkoatl:export]&gt; zonecfg -z test&lt;br /&gt;zonecfg:test&gt; add net&lt;br /&gt;zonecfg:test:net&gt; set physical=rtls0&lt;br /&gt;zonecfg:test:net&gt; set address=192.168.1.111&lt;br /&gt;zonecfg:test:net&gt; end&lt;br /&gt;zonecfg:test&gt; verify&lt;br /&gt;zonecfg:test&gt; commit&lt;br /&gt;zonecfg:test&gt; exit&lt;br /&gt;[root@itzkoatl:export]&gt; zoneadm -z test reboot &lt;br /&gt;zone 'test': WARNING: rtls0:1: no matching subnet found in netmasks(4) for 192.168.1.111; using default of 255.255.255.0.&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;Wie man sieht sorgen Zones sogar für Abhilfe wenn man vergessen hat die Subnetzmaske einzugeben ;). (Für alle die mit rtls0 nichts anfangen können: das ist der Name der Netzwerkkarte, in diesem Fall eine Realtek)&lt;br /&gt;Unsere Zone ist jetzt im gesamten Netzwerk unter 192.168.1.111 erreichbar ;)&lt;br /&gt;&lt;br /&gt;Wozu kann man Zones denn jetzt alles missbrauchen? Mit "branded zones" kann man z.B. Linux Applikationen ausführen (dazu eventuell später mal), oder man kann einfach eine abgeschottete Zone für Entwicklung einrichten, warum nicht einfach jedem seiner Freunde eine eigene Zone auf eurem Solaris Server geben? ;)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8144285405079538181-4800180024611806872?l=raichoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://raichoo.blogspot.com/feeds/4800180024611806872/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8144285405079538181&amp;postID=4800180024611806872' title='3 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/4800180024611806872'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/4800180024611806872'/><link rel='alternate' type='text/html' href='http://raichoo.blogspot.com/2008/10/spa-mit-solaris-zones.html' title='Spaß mit Solaris-Zones'/><author><name>Björn 'raichoo' Herzig</name><uri>https://profiles.google.com/102273886131939895778</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-KxzzpA_pbkc/AAAAAAAAAAI/AAAAAAAAARI/yHTIB2nrp8I/s512-c/photo.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8144285405079538181.post-215520703836915011</id><published>2008-10-13T23:29:00.000-07:00</published><updated>2008-10-14T00:31:24.517-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='MacOSX'/><category scheme='http://www.blogger.com/atom/ns#' term='ZFS'/><category scheme='http://www.blogger.com/atom/ns#' term='OpenSolaris'/><title type='text'>OpenSolaris 2008.11 ermöglicht Zeitreisen</title><content type='html'>Jeder der sich schon mal einen Mac angesehen hat kennt vermutlich &lt;b&gt;Time Machine&lt;/b&gt;: das mitgelieferte Backup Tool von Apple. Ein ziemlich praktisches Feature, das in ähnlicher Form für den nächsten Release von OpenSolaris im November angekündigt ist. Das Ganze wird mit Hilfe von ZFS realisiert (schon mal ein großer Vorteil gegenüber Mac OS X welches IIRC rsync nutzt) und in Nautilus eingebettet, ein SMF Service sorgt im Hintergrund für regelmäßige Snapshots die sich dann per "Time Slider" durchforsten lassen.&lt;br /&gt;Ob es irgendwann auch ein funky Compiz Plugin geben wird das wie auf dem Mac einen Flug durch einen Zeittunnel realisiert bleibt wohl abzuwarten ^^.&lt;br /&gt;&lt;br /&gt;Mehr Informationen finden sich &lt;a href="http://blogs.sun.com/erwann/entry/zfs_on_the_desktop_zfs"&gt;hier&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Update&lt;/b&gt;: Mir wurde gerade gesagt das Mac OS X doch kein rysnc verwendet sondern "die FSEvent API" (was immer das ist ^^). Danke Okona ;)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8144285405079538181-215520703836915011?l=raichoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://raichoo.blogspot.com/feeds/215520703836915011/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8144285405079538181&amp;postID=215520703836915011' title='1 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/215520703836915011'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/215520703836915011'/><link rel='alternate' type='text/html' href='http://raichoo.blogspot.com/2008/10/opensolaris-200811-ermglicht-zeitreisen.html' title='OpenSolaris 2008.11 ermöglicht Zeitreisen'/><author><name>Björn 'raichoo' Herzig</name><uri>https://profiles.google.com/102273886131939895778</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-KxzzpA_pbkc/AAAAAAAAAAI/AAAAAAAAARI/yHTIB2nrp8I/s512-c/photo.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8144285405079538181.post-6080268390701074571</id><published>2008-10-13T12:41:00.000-07:00</published><updated>2008-10-13T12:52:21.088-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='OpenSolaris'/><title type='text'>OpenSolaris und Multimedia</title><content type='html'>Multimedia ist ja unter OpenSolaris anfangs eine ziemliche leidige Sache gewesen: kein mplayer, xine.... irgendwie konnte man nur sehr beschränkt out-of-the-box Multimediadateien abspielen. Im Paketkatalog fand man auch nicht wirklich Abhilfe. Inzwischen haben sich aber ein paar fleißige Japaner daran gemacht bewegte Bilder auch noch in die OpenSolaris Welt zu bringen. &lt;a href="http://www.lifewithsolaris.jp"&gt;Life with Solaris&lt;/a&gt; heißt das ganze und bietet mit ein paar Handgriffen alles das was man sich so wünscht. Einfach folgendes ausführen (mit root-Rechten versteht sich):&lt;br /&gt;&lt;code&gt;&lt;pre&gt;&lt;br /&gt;# pkg set-authority -O http://pkg.lifewithsolaris.jp:10000/ lifewithsolaris.jp&lt;br /&gt;# pkg refresh --full&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;Schon hat man Zugriff auf die Pakete von &lt;i&gt;Life with Solaris&lt;/i&gt;.&lt;br /&gt;Weitergehende Informationen finden sich &lt;a href="http://www.lifewithsolaris.jp/modules/packages/index.php?content_id=1"&gt;hier&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8144285405079538181-6080268390701074571?l=raichoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://raichoo.blogspot.com/feeds/6080268390701074571/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8144285405079538181&amp;postID=6080268390701074571' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/6080268390701074571'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/6080268390701074571'/><link rel='alternate' type='text/html' href='http://raichoo.blogspot.com/2008/10/opensolaris-und-multimedia.html' title='OpenSolaris und Multimedia'/><author><name>Björn 'raichoo' Herzig</name><uri>https://profiles.google.com/102273886131939895778</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-KxzzpA_pbkc/AAAAAAAAAAI/AAAAAAAAARI/yHTIB2nrp8I/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8144285405079538181.post-8244795910378113491</id><published>2008-10-09T04:14:00.000-07:00</published><updated>2008-10-09T05:14:47.089-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ZFS'/><category scheme='http://www.blogger.com/atom/ns#' term='OpenSolaris'/><title type='text'>BEadm: Ich bin nicht eins, ich bin viele</title><content type='html'>Ein Feature von OpenSolaris welches ich besonders liebe ist beadm, die Boot Environment Verwaltung. Hier mit kann man mehrere Instanzen des Systems auf seiner Platte installiert haben und benutzten. "Mooooment mal? Frisst das nicht unheimlich viel Plattenplatz wenn ich 3, 4 oder sogar mehr Versionen von OpenSolaris auf meiner Platte habe?" Genau das ist ja das schöne, NEIN! Unterschiedliche Bootumgebungen belegen nur Plattenplatz für die Unterschiede zwischen den Systemen, habe ich also nur kleine Änderungen vorgenommen belegt das System auch so gut wie keinen Plattenplatz. "Wie viele unterschiedliche Instanzen kann ich denn machen?" So viele wie man will! Ich selber habe immer noch eine Kopie des letzten Releases auf meiner Platte, auf meinem Notebook sogar noch eine Version von der frischen Installation welche ich im Notfall immer als eine Art "Rettungsversion" nutzen kann. Auf meinem Desktop sieht das ganze so aus:&lt;br /&gt;&lt;code&gt;&lt;pre&gt;&lt;br /&gt;[raichoo@itzkoatl:~]&gt; beadm list&lt;br /&gt;BE                Active Mountpoint Space  Policy Created          &lt;br /&gt;--                ------ ---------- -----  ------ -------          &lt;br /&gt;opensolaris_snv97 -      -          55.57M static 2008-09-12 15:44 &lt;br /&gt;opensolaris_snv98 NR     /          10.32G static 2008-09-19 07:25 &lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;Das sind also 2 Bootumgebungen. Wie man sieht belegt opensolaris_snv97 nur 55,57 MB an Plattenplatz obwohl es den KOMPLETTEN Zustand meines Systems (Anmerkung: Nur das System, mein Homefilesystem bleibt davon unberührt und kann auf jeder Instanz genutzt werden) vor dem letzten Upgrade repräsentiert. Diese Umgebung kann ich jetzt nach belieben vervielfältigen und damit weiterarbeiten oder einfach löschen wenn ich sie nicht mehr brauche. Was allerdings am wichtigsten ist: ich kann auf sie jederzeit zugreifen. Dies funktioniert fast genauso wie das händische mounten eines Datenträgers:&lt;br /&gt;&lt;code&gt;&lt;pre&gt;&lt;br /&gt;[raichoo@itzkoatl:~]&gt; su&lt;br /&gt;Password: &lt;br /&gt;[root@itzkoatl:~]&gt; mkdir /tmp/mountpoint&lt;br /&gt;[root@itzkoatl:~]&gt; beadm mount opensolaris_snv97 /tmp/mountpoint &lt;br /&gt;[root@itzkoatl:~]&gt; cd /tmp/mountpoint/&lt;br /&gt;[root@itzkoatl:mountpoint]&gt; ls&lt;br /&gt;a/                 etc/               mnt/               sbin/&lt;br /&gt;bin@               export/            net/               system/&lt;br /&gt;boot/              home/              opt/               tmp/&lt;br /&gt;bootcd_microroot/  kernel/            platform/          usr/&lt;br /&gt;cdrom/             lib/               proc/              var/&lt;br /&gt;COPYRIGHT          LICENSE            rmdisk/&lt;br /&gt;dev/               lost+found/        root/&lt;br /&gt;devices/           media/             rpool/&lt;br /&gt;[root@itzkoatl:mountpoint]&gt; cd&lt;br /&gt;[root@itzkoatl:~]&gt; beadm unmount opensolaris_snv97&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;Man beachte das es hier &lt;b&gt;unmount&lt;/b&gt; und nicht umount heißt ;)&lt;br /&gt;Das erstellen und zerstören einer Bootumgebung ist ebenso einfach:&lt;br /&gt;&lt;code&gt;&lt;pre&gt;&lt;br /&gt;[root@itzkoatl:~]&gt; beadm create donnerlutzi&lt;br /&gt;[root@itzkoatl:~]&gt; beadm list&lt;br /&gt;BE                Active Mountpoint Space  Policy Created          &lt;br /&gt;--                ------ ---------- -----  ------ -------          &lt;br /&gt;donnerlutzi       -      -          80.5K  static 2008-10-09 13:39 &lt;br /&gt;opensolaris_snv97 -      -          55.57M static 2008-09-12 15:44 &lt;br /&gt;opensolaris_snv98 NR     /          10.32G static 2008-09-19 07:25 &lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;Voila, das wars. Der Vorgang dauert satte 3 Sekunden und wie man sieht belegt donnerlutzi nur 80.5 KB an Plattenplatz. "Hmm... brauch ich da nicht noch einen Eintrag im Bootmanager damit ich in das System booten kann?" Nö, das macht beadm schon von ganz alleine ;)&lt;br /&gt;&lt;code&gt;&lt;pre&gt;&lt;br /&gt;[root@itzkoatl:~]&gt; cat /rpool/boot/grub/menu.lst&lt;br /&gt;...&lt;br /&gt;#============ End of LIBBE entry =============&lt;br /&gt;title donnerlutzi&lt;br /&gt;bootfs rpool/ROOT/donnerlutzi&lt;br /&gt;kernel$ /platform/i86pc/kernel/$ISADIR/unix -B $ZFS-BOOTFS&lt;br /&gt;module$ /platform/i86pc/$ISADIR/boot_archive&lt;br /&gt;#============ End of LIBBE entry =============&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;Will ich donnerlutzi zu meinem Standardsystem machen reicht ein beadm activate donnerlutzi und es wird ab dem nächsten Booten immer als erste Wahl in Grub angezeigt.&lt;br /&gt;Sehr praktisch ist das ich diese Bootumgebung auch separat aktualisieren oder komplett andere Software auf ihr installieren kann, da der Paketmanager damit umgehen kann (genauer genommen legt er sogar Sicherheitskopien meines Systems bei Updates an, so kann man immer wieder zurück wenn etwas schief geht. Dieses Verhalten kann man aber auch bei Bedarf umgehen).&lt;br /&gt;Will ich jetzt eine Bootumgebung separat aktualisieren geht das wie folgt:&lt;br /&gt;&lt;code&gt;&lt;pre&gt;&lt;br /&gt;[root@itzkoatl:~]&gt; beadm mount donnerlutzi /tmp/mountpoint &lt;br /&gt;[root@itzkoatl:~]&gt; pkg -R /tmp/mountpoint image-update&lt;br /&gt;...&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;Aber da ich eigentlich ganz zufrieden mit meinen 2 derzeitigen Systemen bin will ich donnerlutzi jetzt ganz gerne wieder loswerden:&lt;br /&gt;&lt;code&gt;&lt;pre&gt;&lt;br /&gt;[root@itzkoatl:~]&gt; beadm unmount donnerlutzi&lt;br /&gt;[root@itzkoatl:~]&gt; beadm destroy donnerlutzi&lt;br /&gt;Are you sure you want to destroy donnerlutzi? This action cannot be undone(y/[n]): y&lt;br /&gt;[root@itzkoatl:~]&gt; beadm list&lt;br /&gt;BE                Active Mountpoint Space  Policy Created          &lt;br /&gt;--                ------ ---------- -----  ------ -------          &lt;br /&gt;opensolaris_snv97 -      -          55.57M static 2008-09-12 15:44 &lt;br /&gt;opensolaris_snv98 NR     /          10.32G static 2008-09-19 07:25 &lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;"Wozu braucht man so etwas jetzt?" Der erste Punkt ist sicherlich das man sich so sehr gut absichern kann wenn man mal sein System total zerbastelt oder Software installiert die stark ins System eingreift. Man kann immer wieder zurück und das mit Hilfe von ein paar Handgriffen ohne zeitaufwendiges Zurückspielen des Systems durch ein herkömmliches Backup. Man kann auch gleichzeitig die stabile und die Entwicklerversion des Systems auf meiner Platte haben ohne das sich beide in die Quere kommen. So kann man vorher schon testen was neue Versionen bringen werden ohne auf sein stabiles System verzichten zu müssen oder irgendwelche LiveCDs zu benutzen auf denen das testen meist eh nur eingeschränkt funktioniert.&lt;br /&gt;&lt;br /&gt;"Wie funktioniert das ganze?" Beadm selbst ist in Python geschrieben und greift nur auf Möglichkeiten zurück die ZFS zur Verfügung stellt, also keine ekligen Hacks die irgendwelche großen Dumpdateien anlegen und dann irgendwie über 3 Ecken mounten, alles ist bereits sauber im System integriert. Beadm selber hat noch ein paar Funktionen die ich hier nicht erwähnt habe, ein Blick in die Manpage schafft hier aber Abhilfe.&lt;br /&gt;&lt;br /&gt;Na dann viel Spaß beim hemmungslosen Basteln! Jetzt ohne Angst das danach nichts mehr funktioniert :)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8144285405079538181-8244795910378113491?l=raichoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://raichoo.blogspot.com/feeds/8244795910378113491/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8144285405079538181&amp;postID=8244795910378113491' title='1 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/8244795910378113491'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/8244795910378113491'/><link rel='alternate' type='text/html' href='http://raichoo.blogspot.com/2008/10/beadm-ich-bin-nicht-eins-ich-bin-viele.html' title='BEadm: Ich bin nicht eins, ich bin viele'/><author><name>Björn 'raichoo' Herzig</name><uri>https://profiles.google.com/102273886131939895778</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-KxzzpA_pbkc/AAAAAAAAAAI/AAAAAAAAARI/yHTIB2nrp8I/s512-c/photo.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8144285405079538181.post-5611550304407781123</id><published>2008-10-09T04:00:00.000-07:00</published><updated>2008-10-09T04:11:21.150-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='OpenSolaris'/><title type='text'>AMP: Webentwicklungsumgebung für OpenSolaris</title><content type='html'>Für alle Web-Entwickler gibt es jetzt unter OpenSolaris eine umfangreiche Zusammenstellung an Entwicklungstools. Besonders interessant dürfte das zusammen mit Zones sein (einem Thema dem ich mich noch annehmen muss). Wie man AMP installiert und was es beinhaltet wird &lt;a href="http://developers.sun.com/developer/technicalArticles/opensolaris/webstack.html"&gt;hier&lt;/a&gt; ausführlich erklärt. Das zusammen  Dtrace (welches auch über PHP, JavaScript, Java, Python und Ruby tracing verfügt), ZFS und den bereits erwähnten Zones ergibt ein ziemliches Killerpaket.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8144285405079538181-5611550304407781123?l=raichoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://raichoo.blogspot.com/feeds/5611550304407781123/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8144285405079538181&amp;postID=5611550304407781123' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/5611550304407781123'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/5611550304407781123'/><link rel='alternate' type='text/html' href='http://raichoo.blogspot.com/2008/10/amp-webentwicklungsumgebung-fr.html' title='AMP: Webentwicklungsumgebung für OpenSolaris'/><author><name>Björn 'raichoo' Herzig</name><uri>https://profiles.google.com/102273886131939895778</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-KxzzpA_pbkc/AAAAAAAAAAI/AAAAAAAAARI/yHTIB2nrp8I/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8144285405079538181.post-5148869669502633196</id><published>2008-10-08T13:00:00.000-07:00</published><updated>2008-10-08T13:04:31.487-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ZFS'/><category scheme='http://www.blogger.com/atom/ns#' term='OpenSolaris'/><title type='text'>ZFS Screencast</title><content type='html'>Ich habe auf Youtube gerade einen ganz interessanten ZFS Screencast gefunden. Leider verhaut sich der Präsentator ständig mit den Kommandos, dennoch nicht uninteressant wenn man ZFS noch nie im Einsatz auf einer WIRKLICH großen Kiste gesehen hat ;)&lt;br /&gt;&lt;br /&gt;&lt;center&gt;&lt;object width="425" height="344"&gt;&lt;param name="movie" value="http://www.youtube.com/v/HPrzR5BPcJU&amp;hl=en&amp;fs=1"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/HPrzR5BPcJU&amp;hl=en&amp;fs=1" type="application/x-shockwave-flash" allowfullscreen="true" width="425" height="344"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;/center&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8144285405079538181-5148869669502633196?l=raichoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://raichoo.blogspot.com/feeds/5148869669502633196/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8144285405079538181&amp;postID=5148869669502633196' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/5148869669502633196'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/5148869669502633196'/><link rel='alternate' type='text/html' href='http://raichoo.blogspot.com/2008/10/zfs-screencast.html' title='ZFS Screencast'/><author><name>Björn 'raichoo' Herzig</name><uri>https://profiles.google.com/102273886131939895778</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-KxzzpA_pbkc/AAAAAAAAAAI/AAAAAAAAARI/yHTIB2nrp8I/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8144285405079538181.post-8657938779368257641</id><published>2008-10-04T06:04:00.000-07:00</published><updated>2010-04-17T01:02:45.647-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='OpenSolaris'/><title type='text'>Adrian de Groot: KDE4 on OpenSolaris</title><content type='html'>&lt;center&gt;&lt;object width="400" height="225"&gt; &lt;param name="allowfullscreen" value="true" /&gt; &lt;param name="allowscriptaccess" value="always" /&gt; &lt;param name="movie" value="http://vimeo.com/moogaloop.swf?clip_id=1128409&amp;amp;server=vimeo.com&amp;amp;show_title=1&amp;amp;show_byline=1&amp;amp;show_portrait=0&amp;amp;color=&amp;amp;fullscreen=1" /&gt; &lt;embed src="http://vimeo.com/moogaloop.swf?clip_id=1128409&amp;amp;server=vimeo.com&amp;amp;show_title=1&amp;amp;show_byline=1&amp;amp;show_portrait=0&amp;amp;color=&amp;amp;fullscreen=1" type="application/x-shockwave-flash" allowfullscreen="true" allowscriptaccess="always" width="400" height="225"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;br /&gt;&lt;a href="http://vimeo.com/1128409?pg=embed&amp;amp;sec=1128409"&gt;Adrian De Groot presents...KDE 4 on Open Solaris&lt;/a&gt; from &lt;a href="http://vimeo.com/user423727?pg=embed&amp;amp;sec=1128409"&gt;Phil Whitehouse&lt;/a&gt; on &lt;a href="http://vimeo.com?pg=embed&amp;amp;sec=1128409"&gt;Vimeo&lt;/a&gt;&lt;/center&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8144285405079538181-8657938779368257641?l=raichoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://raichoo.blogspot.com/feeds/8657938779368257641/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8144285405079538181&amp;postID=8657938779368257641' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/8657938779368257641'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/8657938779368257641'/><link rel='alternate' type='text/html' href='http://raichoo.blogspot.com/2008/10/adrian-de-groot-kde4-on-opensolaris.html' title='Adrian de Groot: KDE4 on OpenSolaris'/><author><name>Björn 'raichoo' Herzig</name><uri>https://profiles.google.com/102273886131939895778</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-KxzzpA_pbkc/AAAAAAAAAAI/AAAAAAAAARI/yHTIB2nrp8I/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8144285405079538181.post-8700524018129715149</id><published>2008-09-13T19:45:00.000-07:00</published><updated>2010-04-17T01:11:39.506-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ZSH'/><category scheme='http://www.blogger.com/atom/ns#' term='Debugging'/><category scheme='http://www.blogger.com/atom/ns#' term='Dtrace'/><title type='text'>ZSH Patch gegen fieses Memory Leak</title><content type='html'>Ich bin neulich auf einen unschönen Bug in ZSH gestoßen. Bei aktiviertem compinit wird bei jeder Vervollständigung ein Segment anonymer Speicher angelegt und nicht wieder richtig freigegeben. Ein kleines dtrace Skript hat das Problem entlarvt.&lt;br /&gt;&lt;code&gt;&lt;pre&gt;&lt;br /&gt;#!/usr/sbin/dtrace -s&lt;br /&gt;&lt;br /&gt;BEGIN&lt;br /&gt;{&lt;br /&gt; printf("\nTarget is : %d\nSegement is %X\n",$target, $1);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;syscall::mmap64:return&lt;br /&gt;/arg1 == $1 &amp;&amp; pid == $target/&lt;br /&gt;{&lt;br /&gt; printf("mmap returns: %x",arg1);&lt;br /&gt; self-&gt;triggered = 1;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;pid$target:zsh:dupstring:return&lt;br /&gt;/self-&gt;triggered == 1/&lt;br /&gt;{&lt;br /&gt; /*printf("Dupstring: %s",copyinstr(arg1));*/&lt;br /&gt; self-&gt;triggered = 0;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;syscall::mmap64:entry&lt;br /&gt;/pid == $target/&lt;br /&gt;{&lt;br /&gt; printf("mmap size: %d",arg1);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;syscall::munmap:entry&lt;br /&gt;/arg0 == $1 &amp;&amp; pid == $target/&lt;br /&gt;{&lt;br /&gt; printf("munmap size: %d\n",arg1);&lt;br /&gt; ustack();&lt;br /&gt; self-&gt;munmapping = 1;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;syscall::munmap:return&lt;br /&gt;/self-&gt;munmapping/&lt;br /&gt;{&lt;br /&gt; printf("Result of munmapping the segment in question was: %d",arg1);&lt;br /&gt; self-&gt;munmapping = 0;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;fbt::as_removeseg:entry&lt;br /&gt;/execname == "zsh" &amp;&amp; ((struct seg*)arg1)-&gt;s_base == (caddr_t)$1/&lt;br /&gt;{&lt;br /&gt; printf("\nGot removed");&lt;br /&gt; ustack();&lt;br /&gt; stack();&lt;br /&gt; exit(0);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;fbt::as_addseg:entry&lt;br /&gt;/execname == "zsh" &amp;&amp; ((struct seg*)arg1)-&gt;s_base == (caddr_t)$1/&lt;br /&gt;{&lt;br /&gt; printf("\nGot added");&lt;br /&gt; ustack();&lt;br /&gt; stack();&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;Danke an das ZSH-Team für das Überprüfen meines Patches.&lt;br /&gt;&lt;code&gt;&lt;pre&gt;&lt;br /&gt;Index: Src/mem.c&lt;br /&gt;===================================================================&lt;br /&gt;RCS file: /cvsroot/zsh/zsh/Src/mem.c,v&lt;br /&gt;retrieving revision 1.16&lt;br /&gt;diff -u -p -r1.16 mem.c&lt;br /&gt;--- Src/mem.c   17 May 2008 17:55:38 -0000      1.16&lt;br /&gt;+++ Src/mem.c   7 Sep 2008 09:23:32 -0000&lt;br /&gt;@@ -153,9 +153,9 @@ old_heaps(Heap old)&lt;br /&gt;        n = h-&gt;next;&lt;br /&gt;        DPUTS(h-&gt;sp, "BUG: old_heaps() with pushed heaps");&lt;br /&gt; #ifdef USE_MMAP&lt;br /&gt;-       munmap((void *) h, sizeof(*h));&lt;br /&gt;+       munmap((void *) h, h-&gt;size);&lt;br /&gt; #else&lt;br /&gt;-       zfree(h, sizeof(*h));&lt;br /&gt;+       zfree(h, HEAPSIZE);&lt;br /&gt; #endif&lt;br /&gt;     }&lt;br /&gt;     heaps = old;&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8144285405079538181-8700524018129715149?l=raichoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://raichoo.blogspot.com/feeds/8700524018129715149/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8144285405079538181&amp;postID=8700524018129715149' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/8700524018129715149'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/8700524018129715149'/><link rel='alternate' type='text/html' href='http://raichoo.blogspot.com/2008/09/zsh-patch-gegen-fieses-memory-leak.html' title='ZSH Patch gegen fieses Memory Leak'/><author><name>Björn 'raichoo' Herzig</name><uri>https://profiles.google.com/102273886131939895778</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-KxzzpA_pbkc/AAAAAAAAAAI/AAAAAAAAARI/yHTIB2nrp8I/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8144285405079538181.post-5494574861313410874</id><published>2008-09-13T19:01:00.000-07:00</published><updated>2008-09-13T20:58:37.160-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ZSH'/><category scheme='http://www.blogger.com/atom/ns#' term='OpenSolaris'/><title type='text'>ZSH: IPS Completion Skript</title><content type='html'>So ich hab mich mal hingesetzt und ein Vervollständigungsskript für IPS in der ZSH geschrieben. Das ganze ist noch relativ frisch und deswegen klappt vielleicht noch nicht alles so wie es soll, also gilt wie immer: PATCHES WELCOME ;)&lt;br /&gt;&lt;br /&gt;&lt;a href="http://docs.google.com/View?docID=dfdnr8dn_1f89hktdc&amp;revision=_latest"&gt;IPS Completion&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Um es zu nutzen: einfach als _pkg in /usr/share/zsh/site-functions speichern (compinit muss dafür aktiviert sein)&lt;br /&gt;&lt;br /&gt;Gegebenenfalls werde ich das Skript natürlich aktualisieren. Ich habe leider noch nicht rausbekommen wie man Google Docs verbieten kann die Einrückung einfach zu verschlucken, also sieht das ganze dementsprechend schrecklich aus. Ich hoffe mal das es trotzdem noch ohne Probleme funktionieren wird.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8144285405079538181-5494574861313410874?l=raichoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://raichoo.blogspot.com/feeds/5494574861313410874/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8144285405079538181&amp;postID=5494574861313410874' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/5494574861313410874'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/5494574861313410874'/><link rel='alternate' type='text/html' href='http://raichoo.blogspot.com/2008/09/zsh-ips-completion-skript.html' title='ZSH: IPS Completion Skript'/><author><name>Björn 'raichoo' Herzig</name><uri>https://profiles.google.com/102273886131939895778</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-KxzzpA_pbkc/AAAAAAAAAAI/AAAAAAAAARI/yHTIB2nrp8I/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8144285405079538181.post-198073051889800457</id><published>2008-08-24T19:12:00.000-07:00</published><updated>2010-04-17T01:12:03.308-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ZSH'/><category scheme='http://www.blogger.com/atom/ns#' term='Debugging'/><category scheme='http://www.blogger.com/atom/ns#' term='Dtrace'/><title type='text'>Dtrace im Kampfeinsatz: ZSH debuggen</title><content type='html'>Ich bin ja vor kurzem auf die wunderbare ZSH umgestiegen und leider Gottes habe ich den ein oder anderen Bug gefunden der ziemlich nervig ist. Es wurde mir verweigert selbst geschriebene Widgets an die &lt;b&gt;menuselect&lt;/b&gt; Keymap zu binden. Naja, was macht man da? Ganz einfach, Sourcecode besorgen und dtrace durchstarten lassen. Nach kurzer Zeit hatte ich das Problem eingekreist und konnte mich ohne Probleme auf den relevanten Teil konzentrieren ohne erst großartig den Code zu lesen. In einem Fenster hatte ich die zu debuggende Shell in der anderen lief dtrace und hat mir angezeigt was passiert während ich tippe.&lt;br /&gt;&lt;br /&gt;Hier sind ein paar Skripte die ich verwendet habe:&lt;br /&gt;&lt;br /&gt;Was passiert gerade im Z-Lineeditor:&lt;br /&gt;&lt;code&gt;&lt;pre&gt;&lt;br /&gt;#!/usr/sbin/dtrace -s&lt;br /&gt;&lt;br /&gt;#pragma D option flowindent&lt;br /&gt;&lt;br /&gt;pid$target:zle.so::entry,&lt;br /&gt;pid$target:zle.so::return&lt;br /&gt;{&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;Der Userstack Backtrace sobald &lt;code&gt;selectkeymap&lt;/code&gt; aufgerufen wird, inklusive der Information um welche Keymap es sich handelt:&lt;br /&gt;&lt;code&gt;&lt;pre&gt;&lt;br /&gt;#!/usr/sbin/dtrace -s&lt;br /&gt;&lt;br /&gt;pid$target:zle.so:selectkeymap:entry&lt;br /&gt;{&lt;br /&gt;        ustack();&lt;br /&gt;        printf("%s",copyinstr(arg0));&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;Und das ganze nochmal für &lt;code&gt;selectlocalmap&lt;/code&gt;:&lt;br /&gt;&lt;code&gt;&lt;pre&gt;&lt;br /&gt;#!/usr/sbin/dtrace -s&lt;br /&gt;&lt;br /&gt;pid$target:zle.so:selectlocalmap:entry&lt;br /&gt;/arg0 != 0/&lt;br /&gt;{&lt;br /&gt;    ustack();&lt;br /&gt;    printf("%p",arg0);&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Das ganze lief am Ende darauf hinaus das im aktuellen Source der Version 4.3.6 einfach die Zeile 2315 in der Datei complist.c von &lt;code&gt;selectlocalmap(mskeymap)&lt;/code&gt; in &lt;code&gt;selectkeymap("menuselect",1)&lt;/code&gt; geändert werden musste. Da das ganze ein ziemlicher Quickhack ist, übernehme ich aber für nichts die Garantie ;).&lt;br /&gt;&lt;br /&gt;Auf jeden Fall kann ich jetzt selbst geschriebene Widgets an die &lt;b&gt;menuselect&lt;/b&gt; Keymap binden und $KEYMAP wird beim Wechsel auch richtig gesetzt, alles ohne viel Aufwand oder einer Debugversion von ZSH :D. Mal sehen was Upstream dazu sagt.&lt;br /&gt;&lt;br /&gt;Ich sage dazu nur: DTRACE ROCKT!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8144285405079538181-198073051889800457?l=raichoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://raichoo.blogspot.com/feeds/198073051889800457/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8144285405079538181&amp;postID=198073051889800457' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/198073051889800457'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/198073051889800457'/><link rel='alternate' type='text/html' href='http://raichoo.blogspot.com/2008/08/dtrace-im-kampfeinsatz-zsh-debuggen.html' title='Dtrace im Kampfeinsatz: ZSH debuggen'/><author><name>Björn 'raichoo' Herzig</name><uri>https://profiles.google.com/102273886131939895778</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-KxzzpA_pbkc/AAAAAAAAAAI/AAAAAAAAARI/yHTIB2nrp8I/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8144285405079538181.post-7980843618071020172</id><published>2008-08-23T15:21:00.000-07:00</published><updated>2008-08-23T15:38:17.056-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='vi'/><category scheme='http://www.blogger.com/atom/ns#' term='ZSH'/><title type='text'>ZSH: vi-mode reloaded</title><content type='html'>Hmmmmm, vi Kommandos in der Shell. Sowas macht doch Spaß. Allerdings hab ich es gerne wenn mir der aktuelle Mode angezeigt und der Shellprompt ausgeblendet wird sobald ich im Kommando-Modus bin. Dafür hab ich meine .zshrc etwas erweitert. Allerdings gibt es ein kleines Problem: Der RPROMPT wird nur angepasst wenn die Shell mindestens ein Kommando ausgeführt hat. Mal sehen was die ZSH-Mailinglist dazu sagt.&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;pre&gt;&lt;br /&gt;zle-line-init zle-keymap-select()&lt;br /&gt;{&lt;br /&gt;    RPROMPT=${${KEYMAP/vicmd/-- COMMAND --}/main/}&lt;br /&gt;    PROMPT=${${KEYMAP/main/$SAVEDPROMPT}/vicmd/}&lt;br /&gt;    zle reset-prompt&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;zle -N zle-line-init&lt;br /&gt;zle -N zle-keymap-select&lt;br /&gt;&lt;br /&gt;setopt TRANSIENTRPROMPT&lt;br /&gt;&lt;br /&gt;bindkey -M vicmd "^M" down-line-or-history&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8144285405079538181-7980843618071020172?l=raichoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://raichoo.blogspot.com/feeds/7980843618071020172/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8144285405079538181&amp;postID=7980843618071020172' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/7980843618071020172'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/7980843618071020172'/><link rel='alternate' type='text/html' href='http://raichoo.blogspot.com/2008/08/zsh-vi-mode-reloaded.html' title='ZSH: vi-mode reloaded'/><author><name>Björn 'raichoo' Herzig</name><uri>https://profiles.google.com/102273886131939895778</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-KxzzpA_pbkc/AAAAAAAAAAI/AAAAAAAAARI/yHTIB2nrp8I/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8144285405079538181.post-518842793875292428</id><published>2008-08-21T19:25:00.000-07:00</published><updated>2008-08-22T15:59:16.131-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ZSH'/><title type='text'>ZSH: Fit for fun</title><content type='html'>Heute hab ich mich von der guten alten BASH verabschiedet und mein System auf ZSH umgestellt. Und da so eine mächtige Shell auch hübsch aussehen soll habe ich ihr auch gleich einen netten Look verpasst.&lt;br /&gt;&lt;br&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_3VHVa9AP0ZM/SK4kWNy4xsI/AAAAAAAAAGQ/57syj0RphyI/s1600-h/Screenshot-Terminal.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://1.bp.blogspot.com/_3VHVa9AP0ZM/SK4kWNy4xsI/AAAAAAAAAGQ/57syj0RphyI/s320/Screenshot-Terminal.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5237163380757284546" /&gt;&lt;/a&gt;&lt;br /&gt;Für alle die es interessiert, hier die .zshrc:&lt;br /&gt;&lt;code&gt;&lt;pre&gt;&lt;br /&gt;# Lines configured by zsh-newuser-install&lt;br /&gt;HISTSIZE=1000&lt;br /&gt;SAVEHIST=1000&lt;br /&gt;# End of lines configured by zsh-newuser-install&lt;br /&gt;PATH="/usr/bin:\&lt;br /&gt;/usr/X11/bin:\&lt;br /&gt;/usr/sbin:/sbin:\&lt;br /&gt;/opt/SunStudioExpress/bin:\&lt;br /&gt;/opt/netbeans-6.0/bin:\&lt;br /&gt;/opt/DTT/Bin:\&lt;br /&gt;/usr/sfw/bin:\&lt;br /&gt;/usr/gnu/bin"&lt;br /&gt;MANPATH="/usr/share/man:\&lt;br /&gt;/usr/X11/share/man:\&lt;br /&gt;/opt/SunStudioExpress/man:\&lt;br /&gt;/opt/DTT/Man:\&lt;br /&gt;/usr/sfw/share/man:\&lt;br /&gt;/usr/gnu/share/man"&lt;br /&gt;&lt;br /&gt;if ((EUID != 0));&lt;br /&gt;then&lt;br /&gt; PROMPT="[%{$(echo -n '\e[1;32m')%}%n\&lt;br /&gt;%{$(echo -n '\e[0;00m')%}@\&lt;br /&gt;%{$(echo -n '\e[0;33m')%}%m\&lt;br /&gt;%{$(echo -n '\e[0;00m')%}:\&lt;br /&gt;%{$(echo -n '\e[0;34m')%}%1~\&lt;br /&gt;%{$(echo -n '\e[0;00m')%}]\&lt;br /&gt;%{$(echo -n '\e[0;34m')%}&gt; \&lt;br /&gt;%{$(echo -n '\e[0;00m')%}"&lt;br /&gt; HISTFILE=~/.histfile&lt;br /&gt;else &lt;br /&gt;   PROMPT="[%{$(echo -n '\e[0;31m')%}%n\&lt;br /&gt;%{$(echo -n '\e[0;00m')%}@\&lt;br /&gt;%{$(echo -n '\e[0;33m')%}%m\&lt;br /&gt;%{$(echo -n '\e[0;00m')%}:\&lt;br /&gt;%{$(echo -n '\e[0;34m')%}%~\&lt;br /&gt;%{$(echo -n '\e[0;00m')%}]\&lt;br /&gt;%{$(echo -n '\e[0;31m')%}&gt; \&lt;br /&gt;%{$(echo -n '\e[0;00m')%}"&lt;br /&gt; HISTFILE="/root/.histfile"&lt;br /&gt;fi&lt;br /&gt;&lt;br /&gt;ls()&lt;br /&gt;{&lt;br /&gt; if [[ ${1[0,2]} != "-v" ]] &amp;&amp; [[ (${1[0,2]} != "-V") ]];&lt;br /&gt; then&lt;br /&gt;  /bin/dir $argv --color=always&lt;br /&gt; else&lt;br /&gt;  /bin/ls $argv&lt;br /&gt; fi&lt;br /&gt;}&lt;br /&gt;setopt HIST_IGNORE_DUPS&lt;br /&gt;setopt VI&lt;br /&gt;unsetopt flowcontrol&lt;br /&gt;&lt;br /&gt;bindkey "^[[3~" delete-char&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;Als kleine Besonderheit habe ich ls so umgestellt das es im Normalfall das GNU dir nimmt (weil das so schön bunt ist :P) und sobald ich die Option -v oder -V verwende das Solaris ls (weil das mit NFSv4 ACLs klarkommt welche ZFS-Standard sind)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8144285405079538181-518842793875292428?l=raichoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://raichoo.blogspot.com/feeds/518842793875292428/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8144285405079538181&amp;postID=518842793875292428' title='2 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/518842793875292428'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/518842793875292428'/><link rel='alternate' type='text/html' href='http://raichoo.blogspot.com/2008/08/zsh-fit-for-fun.html' title='ZSH: Fit for fun'/><author><name>Björn 'raichoo' Herzig</name><uri>https://profiles.google.com/102273886131939895778</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-KxzzpA_pbkc/AAAAAAAAAAI/AAAAAAAAARI/yHTIB2nrp8I/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_3VHVa9AP0ZM/SK4kWNy4xsI/AAAAAAAAAGQ/57syj0RphyI/s72-c/Screenshot-Terminal.png' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8144285405079538181.post-4883552916493542204</id><published>2008-08-20T14:19:00.000-07:00</published><updated>2008-08-20T16:26:20.351-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='OpenSolaris'/><category scheme='http://www.blogger.com/atom/ns#' term='Dtrace'/><title type='text'>Dtrace Workshop - Teil 4: Userspace tracen mit dem PID-Provider</title><content type='html'>Nachdem wir uns in den letzten drei Teilen eigentlich nur mit Kerneltracing befasst haben, wird es Zeit sich dem Userspace zu widmen. Hierfür liefert dtrace den PID-Provider mit dem wir jede Funktion innerhalb eines Prozesses genauso unter die Lupe nehmen können wie wir es auch schon beim Kernel gelernt haben. Diesen Provider werde ich jetzt anhand eines einfachen C-Programms vorstellen.&lt;br /&gt;&lt;code&gt;&lt;pre&gt;&lt;br /&gt;#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;&lt;br /&gt;void a(int i)&lt;br /&gt;{&lt;br /&gt;   printf("a\n");&lt;br /&gt;   return;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;void b(int i)&lt;br /&gt;{&lt;br /&gt;   printf("b\n");&lt;br /&gt;   a(3);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;void c(int i)&lt;br /&gt;{&lt;br /&gt;   printf("c\n");&lt;br /&gt;   b(2);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;int main()&lt;br /&gt;{&lt;br /&gt;   c(1);&lt;br /&gt;   return 0;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;Dieses Programm werden wir komplett ohne Debugsymbole übersetzen und &lt;b&gt;userspace&lt;/b&gt; nennen. Wir wollen jetzt mit dem PID-Provider sehen welche Funktionen innerhalb des Programms ausgeführt werden. Dazu schreiben wir ein einfaches D Skript.&lt;br /&gt;&lt;code&gt;&lt;pre&gt;&lt;br /&gt;#!/usr/sbin/dtrace -s&lt;br /&gt;&lt;br /&gt;#pragma D option flowindent&lt;br /&gt;&lt;br /&gt;pid$target:userspace::return,&lt;br /&gt;pid$target:userspace::entry&lt;br /&gt;{&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;Die Variable &lt;b&gt;$target&lt;/b&gt; bezieht sich auf das Programm das wir für dtrace als Ziel angeben. Dieses können wir mir der &lt;b&gt;-c&lt;/b&gt; Option für ein spezifisches Kommando, oder mit &lt;b&gt;-p&lt;/b&gt; für eine bestimmte PID angeben. Normal setzt sich der PID-Provider aus dem Wort &lt;b&gt;pid&lt;/b&gt; und einer PID zusammen (z.B. pid2342), mit der Zielvariablen ist unser Skript allerdings sehr viel dynamischer. Als Modul haben wir hier &lt;b&gt;userspace&lt;/b&gt; angegeben. Das ist der Name unseres Programms. Wir werden also nur Funktionen tracen die wir innerhalb unseres Programms definiert haben. Mit &lt;b&gt;dtrace -l -p pid&lt;i&gt;PID&lt;/i&gt;&lt;/b&gt; kann man sich übrigens alle tracebaren Funktionen eines bestimmten Prozesses ausgeben lassen (aber vorsicht, das ist meistens echt viel ;) ).&lt;br /&gt;&lt;code&gt;&lt;pre&gt;&lt;br /&gt;raichoo@itzkoatl:~/Projects# ./userspacetrace.d -c ./userspace&lt;br /&gt;dtrace: script './userspacetrace.d' matched 13 probes&lt;br /&gt;c&lt;br /&gt;b&lt;br /&gt;a&lt;br /&gt;CPU FUNCTION&lt;br /&gt;  0  -&gt; _start&lt;br /&gt;  0    -&gt; __fsr&lt;br /&gt;  0    &lt;- __fsr&lt;br /&gt;  0    -&gt; main&lt;br /&gt;  0      -&gt; c&lt;br /&gt;  0        -&gt; b&lt;br /&gt;  0          -&gt; a&lt;br /&gt;  0          &lt;- a&lt;br /&gt;  0        &lt;- b&lt;br /&gt;  0      &lt;- c&lt;br /&gt;  0    &lt;- main&lt;br /&gt;dtrace: pid 697 has exited&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;Jetzt würden wir aber gerne noch unsere printfs mittracen, dazu erweitern wir unser Skript einfach um die Tupel &lt;b&gt;pid$target:libc.so.1:printf:entry&lt;/b&gt; und &lt;b&gt;pid$target:libc.so.1:printf:return&lt;/b&gt; um die in libc.so.1 definierte &lt;i&gt;printf&lt;/i&gt; Funktion zu tracen (das geht auch für jede andere gelinkte lib). Wir erhalten nun folgende Ausgabe:&lt;br /&gt;&lt;code&gt;&lt;pre&gt;&lt;br /&gt;dtrace: script './userspacetrace.d' matched 15 probes&lt;br /&gt;c&lt;br /&gt;b&lt;br /&gt;a&lt;br /&gt;CPU FUNCTION&lt;br /&gt;  0  -&gt; _start&lt;br /&gt;  0    -&gt; __fsr&lt;br /&gt;  0    &lt;- __fsr&lt;br /&gt;  0    -&gt; main&lt;br /&gt;  0      -&gt; c&lt;br /&gt;  0        -&gt; printf&lt;br /&gt;  0        &lt;- printf&lt;br /&gt;  0        -&gt; b&lt;br /&gt;  0          -&gt; printf&lt;br /&gt;  0          &lt;- printf&lt;br /&gt;  0          -&gt; a&lt;br /&gt;  0            -&gt; printf&lt;br /&gt;  0            &lt;- printf&lt;br /&gt;  0          &lt;- a&lt;br /&gt;  0        &lt;- b&lt;br /&gt;  0      &lt;- c&lt;br /&gt;  0    &lt;- main&lt;br /&gt;dtrace: pid 714 has exited&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;Somit können wir jetzt jede Userspace Funktion tracen. Zum Abschluss will ich noch zeigen wie wir hier auch Probeargumente anwenden können:&lt;br /&gt;&lt;code&gt;&lt;pre&gt;&lt;br /&gt;#!/usr/sbin/dtrace -s&lt;br /&gt;&lt;br /&gt;#pragma D option flowindent&lt;br /&gt;&lt;br /&gt;pid$target:userspace::entry&lt;br /&gt;{&lt;br /&gt;   printf("Funktionsargument %d",arg0);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;pid$target:userspace::return,&lt;br /&gt;pid$target:libc.so.1:printf:return&lt;br /&gt;{&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;pid$target:libc.so.1:printf:entry&lt;br /&gt;{&lt;br /&gt;   printf("Funktionsargument %s",copyinstr(arg0));&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8144285405079538181-4883552916493542204?l=raichoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://raichoo.blogspot.com/feeds/4883552916493542204/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8144285405079538181&amp;postID=4883552916493542204' title='2 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/4883552916493542204'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/4883552916493542204'/><link rel='alternate' type='text/html' href='http://raichoo.blogspot.com/2008/08/dtrace-workshop-teil-4-userspace-tracen.html' title='Dtrace Workshop - Teil 4: Userspace tracen mit dem PID-Provider'/><author><name>Björn 'raichoo' Herzig</name><uri>https://profiles.google.com/102273886131939895778</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-KxzzpA_pbkc/AAAAAAAAAAI/AAAAAAAAARI/yHTIB2nrp8I/s512-c/photo.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8144285405079538181.post-6152868476997478386</id><published>2008-08-19T12:30:00.000-07:00</published><updated>2008-08-19T13:26:42.334-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='OpenSolaris'/><category scheme='http://www.blogger.com/atom/ns#' term='Dtrace'/><title type='text'>Dtrace Workshop - Teil 3: Der FBT-Provider und erste dtrace-Skripte</title><content type='html'>In &lt;a href="http://raichoo.blogspot.com/2008/08/dtrace-workshop-teil-1-einfhrung.html"&gt;Teil 1&lt;/a&gt; angekündigt und in &lt;a href="http://raichoo.blogspot.com/2008/08/dtrace-workshop-teil-2-probeargumente.html"&gt;Teil 2&lt;/a&gt; aufgeschoben will ich jetzt endlich zum FBT-Provider kommen. Hiermit kann man sich wie gesagt jede Funktion die es im Kernel gibt ausgeben lassen. Als Beispiel werden wir uns hier angucken was im Kernel passiert wenn wir bestimmte Systemcalls ausführen. Da unsere dtrace Anweisungen aber inzwischen immer komplexer werden, wird es langsam Zeit das wir uns damit befassen wie man dtrace Skripte schreibt.&lt;br /&gt;&lt;br /&gt;Wie bereits mehrmals gesagt wurde handelt es sich bei D um eine eigene Programmiersprache handelt welche sich an AWK und C anlehnt. D ist eventgesteuert, das heißt das bei bestimmten Ereignissen etwas ausgeführt wird und der Code nicht einfach durchlaufen wird. Als ersten sehen wir und mal ein einfaches dtrace Skript an. Wir greifen dabei auf eine der ersten Lektionen zurück die wir hatten, nämlich wie man sich anzeigen läßt welcher Prozess gerade welchen Systemcall ausführt.&lt;br /&gt;&lt;code&gt;&lt;pre&gt;&lt;br /&gt;#!/usr/sbin/dtrace -s&lt;br /&gt;&lt;br /&gt;syscall:::entry&lt;br /&gt;{&lt;br /&gt;   trace(execname);&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;Wir speichern das ganze unter syscall.d und machen es mit &lt;b&gt;chmod +x syscall.d&lt;/b&gt; ausführbar. Das Resultat sieht dann wie folgt aus:&lt;br /&gt;&lt;code&gt;&lt;pre&gt;&lt;br /&gt;raichoo@itzkoatl:~# ./syscall.d&lt;br /&gt;dtrace: script './syscall.d' matched 233 probes&lt;br /&gt;CPU     ID                    FUNCTION:NAME&lt;br /&gt;  0  68998                      ioctl:entry   dtrace&lt;br /&gt;  0  68998                      ioctl:entry   dtrace&lt;br /&gt;  0  69134                  sysconfig:entry   dtrace&lt;br /&gt;  0  69134                  sysconfig:entry   dtrace&lt;br /&gt;  0  69266                   schedctl:entry   dtrace&lt;br /&gt;  0  69068                  sigaction:entry   dtrace&lt;br /&gt;  0  69068                  sigaction:entry   dtrace&lt;br /&gt;  0  69068                  sigaction:entry   dtrace&lt;br /&gt;  0  69068                  sigaction:entry   dtrace&lt;br /&gt;...&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;Voila, schon haben wir unsere "Mühe" permanent in ein Skript gepackt, immer wieder abrufbar :).&lt;br /&gt;&lt;br /&gt;Wollen wir uns jetzt mal ein etwas komplexeres D Skript ansehen. Hier werden wir uns ansehen was beim mmap Syscall alles im Kernel passiert.&lt;br /&gt;&lt;code&gt;&lt;pre&gt;&lt;br /&gt;#!/usr/sbin/dtrace -s&lt;br /&gt;&lt;br /&gt;syscall::mmap:entry&lt;br /&gt;{&lt;br /&gt;   self-&gt;verfolgen = 1;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;fbt:::entry,&lt;br /&gt;fbt:::return&lt;br /&gt;/self-&gt;verfolgen/&lt;br /&gt;{&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;syscall::mmap:return&lt;br /&gt;{&lt;br /&gt;   self-&gt;verfolgen = 0;&lt;br /&gt;   exit(0);&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;Ok das ist jetzt etwas viel auf einmal. Besonders mysteriös ist hier die Zeile &lt;b&gt;self-&gt;verfolgen = 1&lt;/b&gt;. Hierbei handelt es sich um eine theadlokale Variable. Ruft ein Thread mmap auf wird verfolgen für diesen Thread auf 1 gesetzt, das wird wichtig wenn wir die Bedingung für unsere FBT Probes ansehen, diese wird nämlich nur ausgeführt wenn &lt;b&gt;self-&gt;verfolgen&lt;/b&gt; gesetzt ist. Erinnern wir uns: in &lt;a href="http://raichoo.blogspot.com/2008/08/dtrace-workshop-teil-1-einfhrung.html"&gt;Teil 1&lt;/a&gt; haben wir festgestellt das D Events wie folgt aufgebaut sind:&lt;br /&gt;&lt;code&gt;&lt;pre&gt;&lt;br /&gt;probe-tupel&lt;br /&gt;/Bedingung/&lt;br /&gt;{&lt;br /&gt;   Funktionskörper&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;Sobald der mmap Systemcall zurückkehrt (mit syscall::mmap:return) wird die Variabel auf 0 gesetzt und das Skript beendet. Gucken wir uns mal die Ausgabe dieses Skripts an:&lt;br /&gt;&lt;code&gt;&lt;pre&gt;&lt;br /&gt;raichoo@itzkoatl:~# ./mmap.d&lt;br /&gt;dtrace: script './mmap.d' matched 66380 probes&lt;br /&gt;CPU     ID                    FUNCTION:NAME&lt;br /&gt;  0  31880                    smmap32:entry&lt;br /&gt;  0  23175               smmap_common:entry&lt;br /&gt;  0  27816               as_rangelock:entry&lt;br /&gt;  0  27817              as_rangelock:return&lt;br /&gt;  0  23173                       zmap:entry&lt;br /&gt;  0  31698                choose_addr:entry&lt;br /&gt;  0  21835                   map_addr:entry&lt;br /&gt;...&lt;br /&gt;  0  29853                    as_map:return&lt;br /&gt;  0  23174                      zmap:return&lt;br /&gt;  0  29415             as_rangeunlock:entry&lt;br /&gt;  0  29952                  cv_signal:entry&lt;br /&gt;  0  29953                 cv_signal:return&lt;br /&gt;  0  29416            as_rangeunlock:return&lt;br /&gt;  0  23176              smmap_common:return&lt;br /&gt;  0  31881                   smmap32:return&lt;br /&gt;  0  69093                      mmap:return&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;Ok das ist ein ziemlicher Rattenschwanz (natürlich habe ich die Ausgabe hier gekürzt ;) )und leider auch sehr unübersichtlich, aber das alles passiert innerhalb eines mmap Syscalls im Kernel. Es wäre aber doch viel schöner wenn man die Ausgabe etwas einrücken könnte und damit besser lesbar. Das erreichen wir durch eine zusätzliche Zeile in unserem Skript.&lt;br /&gt;&lt;code&gt;&lt;pre&gt;&lt;br /&gt;#!/usr/sbin/dtrace -s&lt;br /&gt;&lt;br /&gt;#pragma D option flowindent&lt;br /&gt;&lt;br /&gt;syscall::mmap:entry&lt;br /&gt;{&lt;br /&gt;   self-&gt;verfolgen = 1;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;fbt:::entry,&lt;br /&gt;fbt:::return&lt;br /&gt;/self-&gt;verfolgen/&lt;br /&gt;{&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;syscall::mmap:return&lt;br /&gt;{&lt;br /&gt;   self-&gt;verfolgen = 0;&lt;br /&gt;   exit(0);&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;Durch die Anweisung &lt;b&gt;#pragma D option flowindent&lt;/b&gt; veranlassen wir dtrace unsere Ausgabe je nach entry oder return einzurücken und somit sehr viel lesbarer zu machen.&lt;br /&gt;Hier nochmal die gleiche Ausagebe mit flowindent:&lt;br /&gt;&lt;code&gt;&lt;pre&gt;&lt;br /&gt;raichoo@itzkoatl:~# ./mmap.d&lt;br /&gt;dtrace: script './mmap.d' matched 66380 probes&lt;br /&gt;CPU FUNCTION&lt;br /&gt;  0  -&gt; smmap32&lt;br /&gt;  0    -&gt; smmap_common&lt;br /&gt;  0      -&gt; as_rangelock&lt;br /&gt;  0      &lt;- as_rangelock&lt;br /&gt;  0      -&gt; zmap&lt;br /&gt;  0        -&gt; choose_addr&lt;br /&gt;  0          -&gt; map_addr&lt;br /&gt;...&lt;br /&gt;  0      &lt;- zmap&lt;br /&gt;  0      -&gt; as_rangeunlock&lt;br /&gt;  0        -&gt; cv_signal&lt;br /&gt;  0        &lt;- cv_signal&lt;br /&gt;  0      &lt;- as_rangeunlock&lt;br /&gt;  0    &lt;- smmap_common&lt;br /&gt;  0  &lt;- smmap32&lt;br /&gt;  0  &lt;= mmap&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;Jetzt kann man sicher sagen: "Ok... das sagt mir zwar jetzt welche Funktionen ausgeführt werden, aber was passiert denn jetzt genau". Stimmt, ohne Code sagt uns das jetzt recht wenig. Sun hat allerdings unter &lt;a href="http://src.opensolaris.org/source/"&gt;http://src.opensolaris.org/source/&lt;/a&gt; den gesamten veröffentlichen Code durchsuchbar gemacht. Wir brauchen uns also nur eine Funktion von Interesse aussuchen, ihren Namen unter &lt;b&gt;Definition&lt;/b&gt; eingeben und schon kriegen wir die Datei angegeben in der sie definiert ist und können sie uns auch online ansehen. Zugegeben ist das keine leichte Kost, aber das ist Kernelcode eigentlich fast nie. Hier kann man ihn aber live in Aktion sehen was das Verständnis um einiges erleichtert. :)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8144285405079538181-6152868476997478386?l=raichoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://raichoo.blogspot.com/feeds/6152868476997478386/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8144285405079538181&amp;postID=6152868476997478386' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/6152868476997478386'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/6152868476997478386'/><link rel='alternate' type='text/html' href='http://raichoo.blogspot.com/2008/08/dtrace-workshop-teil-3-der-fbt-provider.html' title='Dtrace Workshop - Teil 3: Der FBT-Provider und erste dtrace-Skripte'/><author><name>Björn 'raichoo' Herzig</name><uri>https://profiles.google.com/102273886131939895778</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-KxzzpA_pbkc/AAAAAAAAAAI/AAAAAAAAARI/yHTIB2nrp8I/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8144285405079538181.post-2275553431304358423</id><published>2008-08-18T05:35:00.000-07:00</published><updated>2008-08-18T08:43:53.469-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='OpenSolaris'/><title type='text'>Warum OpenSolaris?</title><content type='html'>Ich muss zugeben das mir diese Frage in den letzten Wochen ziemlich oft gestellt wurde, vor allem da man mich seit 12 Jahren eigentlich als überzeugten Linuxuser kannte. Zugegeben hat mich das ganze selbst ziemlich unerwartet getroffen, da ich OpenSolaris bis auf ZFS eigentlich als ziemlich uninteressant empfunden habe und teilweise sogar belächelt. Aber mit Betriebssystemen ist es manchmal wie mit Menschen: "Wenn man es erst einmal kennengelernt hat, ist es eigentlich richtig cool".&lt;br /&gt;&lt;br /&gt;&lt;i&gt;"Aber warum nicht Linux?"&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;, hört man aus der Linuxecke (bei den BSDler ist es oft ähnlich ^^). Die Frage ist sicherlich nicht ganz unberechtigt, verfügt Linux doch über sehr viel mehr Treiber und je nach Distribution derzeit noch über sehr viel mehr Pakete. Das mit den Treiber ist tatsächlich immer wieder ein Argument welches mir begegnet. Die Sache mit Treiber ist allerdings: Man braucht sie nur wenn man die Hardware hat. Und 99% der unterstützten Hardware besitze ich nun mal nicht und ich habe genauso wenig vor sie zu kaufen, also ist das Treiberargument hinfällig. Außerdem erinnere ich mich noch an eine Zeit als ich unter Linux weder Sound noch einen brauchbaren Browser hatte und trotzdem habe ich es benutzt weil es eben das gemacht hat was ich von ihm verlangt habe.&lt;br /&gt;Und genau das ist es was OpenSolaris jetzt für mich macht, derzeit allerdings noch mehr als Entwicklungsumgebung und noch nicht als mein Alltagsdesktop da es unter anderem noch an einer gewissen Multimediafähigkeit mangelt. Da OpenSolaris in dieser Form allerdings erst seit Mai existiert und es dafür schon eine sehr vollständige Figur macht, kann ich darüber ersteinmal hinwegsehen. Außerdem ist besagtes für den nächsten Release im November in Arbeit.&lt;br /&gt;&lt;br /&gt;&lt;i&gt;"Aber was macht OpenSolaris denn jetzt besser als Linux?"&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;Erstmal: Es handelt sich hier um persönliche Präferenzen. Ich kann hier noch soviel von Features schwärmen, aber letztendlich muss man diese Features auch nutzen. Hier einfach mal ein kleiner Einblick:&lt;br /&gt;&lt;br /&gt;&lt;b&gt;ZFS&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;In den letzten Monaten ist ZFS schon fast zum Buzzword geworden. Irgendwie redet jeder davon aber selten wird wirklich mal erklärt was ZFS eigentlich kann. Für alle Interessenten kann ist jedem Mal den &lt;a href="http://chaosradio.ccc.de/cre049.html"&gt;ZFS Podcast vom Chaosradio&lt;/a&gt; ans Herz legen. Ein besonders tolles Feature bei ZFS ist die Möglichkeit Snapshots von seinen Filesystemen anzulegen und damit sein System ähnlich wie bei modernen Versionskontrollsystemen zu verzweigen. Hier ein Beispiel von meinem System.&lt;br /&gt;&lt;code&gt;&lt;pre&gt;&lt;br /&gt;raichoo@itzkoatl:~$ beadm list&lt;br /&gt;&lt;br /&gt;BE                Active Active on Mountpoint Space&lt;br /&gt;Name                     reboot               Used&lt;br /&gt;----              ------ --------- ---------- -----&lt;br /&gt;opensolaris       no     no        -          14.58M&lt;br /&gt;opensolaris_snv95 yes    yes       /          6.40G&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;Es verfügt über 2 sogenannte Bootumgebungen. &lt;b&gt;opensolaris&lt;/b&gt; und &lt;b&gt;opensolaris_snv95&lt;/b&gt;. Auf der ersten liegt das Ursystem, mit anderen Worten die Version von OpenSolaris mit der ich installiert habe. Mit der Zeit kamen allerdings mehrere Updates und wie heißt es so schön: "Never change a winning Team". Also habe ich eine zusätzliche Bootumgebung mit dem Namen &lt;b&gt;opensolaris_snv95&lt;/b&gt; angelegt. Nachdem man diese erzeugt hat, besitzt man eine exakte Kopie seines Systems welche man dann separat updaten kann. Das ganze funktioniert so:&lt;br /&gt;&lt;code&gt;&lt;pre&gt;&lt;br /&gt;raichoo@itzkoatl:~# beadm create opensolaris_snv95&lt;br /&gt;raichoo@itzkoatl:~# mkdir /tmp/mein_neues_system&lt;br /&gt;raichoo@itzkoatl:~# beadm mount opensolaris_snv95 /tmp/mein_neues_system&lt;br /&gt;raichoo@itzkoatl:~# pkg -R /tmp/mein_neues_system image-update&lt;br /&gt;...&lt;br /&gt;raichoo@itzkoatl:~# beadm unmount opensolaris_snv95&lt;br /&gt;raichoo@itzkoatl:~# beadm activate opensolaris_snv95&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;Mit pkg habe ich die Kopie meines Systems auf den neusten Stand gebracht und mit activate habe ich dafür gesorgt das sie beim nächsten booten als Standard ausgewählt wird. Besonders praktisch ist hier das beadm auch schon grub eingerichtet hat und ich jetzt für jede Version einen Eintrag hat. Dazu kommt noch das die Kopie meines Systems nur den Unterschied zwischen beiden Systemen an Plattenplatz belegt. So kann man immer ohne Risiko an seinem System herumschrauben und mit einem Handgriff zurück. Aber ZFS kann noch mehr, unter anderem auch unglaublich mächtige Backupfunktionen, sehr komfortables NFS und Samba-Management, Raidfunktionen die weit über die Möglichkeit von traditionellem Hardwareraid hinausgehen, transparente Kompression und bald auch transparente Verschlüsselung, &lt;a href="http://www.youtube.com/watch?v=CN6iDzesEs0"&gt;Selbstheilung&lt;/a&gt; und alles läßt sich mit zwei Befehlen einfach und intuitiv aus der Konsole steuern. Wers nicht glaubt, hier die manpages zu &lt;a href="http://docs.sun.com/app/docs/doc/819-2240/zpool-1m?l=en&amp;q=manpages+prop_op&amp;a=view"&gt;zpool&lt;/a&gt; und &lt;a href="http://docs.sun.com/app/docs/doc/819-2240/zfs-1m?l=en&amp;q=manpages+prop_op&amp;a=view"&gt;zfs&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Dtrace und MDB&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Ich bin jemand der gerne versteht was in seinem System vorgeht. Das schließt Userspace Programme genauso ein wie Kernelspace Aktivitäten. Aus diesem Grund sammel ich auch Bücher die sich mit den jeweiligen Kerneln befassen. Zu Linux besitze ich das Buch "Understanding the Linux Kernel", und auch wenn es in vielerlei Hinsicht nicht uninteressant ist hat es einen gravierenden Nachteil: Ich kann so gut wie nichts davon live beobachten und mir bringt das Wissen um den Kernel und seine Funktionsweise relativ wenig, da nachdem er übersetzt ist er sich für mich in eine Blackbox verwandelt. Mit dtrace und dem Modular Debugger mdb kann ich jederzeit in den Kernel hineinsehen und nachvollziehen was passiert. Ich kann mein Wissen über den Kernel einsetzen um an die Informationen heranzukommen die ich brauche. Ein extremer Vorteil wenn man Probleme sucht, oder einfach nur verstehen will was eigentlich vor sich geht. Zu dtrace haben ich, wie einige vielleicht schon bemerkt haben, einen Workshop auf meinem Blog, eventuell werde ich das gleiche auch noch für mdb machen.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;IPS&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Über die Jahre gab es viele Paketsysteme und inzwischen sind die etablierten mehr oder weniger veraltet. Rpm soll überholt werden und apt ist für meinem Geschmack einfach zu kompliziert wenn es ums schnüren von Paketen geht. Ich will meine Software einfach nur übersetzen und dann freigeben können. Genau das macht IPS für mich. Ich muss mich nicht damit befassen Skripte zu schreiben um ein Paket zu erschaffen sondern kann meine Software einfach in mein eigenes Repository hochladen, das ganze ist in der Funktionalität wieder stark an moderne Versionskontrollsysteme angelehnt. Alles wunderbar ist &lt;a href="http://www.opensolaris.org/os/project/pkg/"&gt;dokumentiert&lt;/a&gt; auf der OpenSolaris Seite.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Dokumentation&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Womit wir auch gleich schon zum nächsten Punkt kommen. Als Developer hasst man es sie zu schreiben, als Anwender liebt man es sie zu haben. Dokumentation. Was mich bei praktisch allen Linux Distributionen immer gestört hat war der Mangel an aktueller tiefgreifender Dokumentation, die auch zugegebenermaßen bei den vielen Änderungen (ob nötig oder nicht sei mal dahingestellt) oft nicht auf dem neusten Stand ist oder teilweise einfach nur oberflächlich am Problem kratzt. Meistens provoziert ein sogenanntes Howto noch weitere Fragen die wieder dazu führen das man suchen muss. Das ganze artet oft in eine Art Schnitzeljagd im Netz aus, die nicht immer vom Erfolg gekrönt ist und gerade bei komplexen Fragen oft im Nichts endet.&lt;br /&gt;Zu Solaris gibt es allerdings einen zentralen Dokumentationsserver. &lt;a href="http://docs.sun.com"&gt;http://docs.sun.com&lt;/a&gt; wartet mit einem Berg an Büchern auf (ja, ganze Bücher keine Howtos)die alle frei zum herunterladen angeboten werden. Alles im handlichen PDF Format, sprengt das Angebot ohne Probleme die 10.000 Seiten Grenze (vermutlich sogar weit darüber hinaus). Alles wird verständlich mit Beispielen erklärt und sollte doch mal eine Frage auftauchen existiert meistens schon ein Link zum Buch das diese Frage klärt.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Stabile ABI&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Etwas vor dem sich Linux leider bis heute fürchtet oder ablehnt. Oft sind nach 2 oder 3 Versionen Treiber im Binärformat nicht mehr zu gebrauchen und man muss praktisch alles neu kompilieren. Nutzt man eine vorgefertigte Distribution hat man dieses Problem nicht, aber kommerzielle Anbieter schrecken davor zurück Treiber für Linux herzustellen da die Binärkompatibilität nicht gewährleistet ist. Auch wenn ich prinzipiell gegen sogenannte Blobs bin ist es für viele Anbieter ein Grund keine Treiber für Linux zu veröffentlichen, da der Wartungsaufwand in keinerlei Bezug zum Nutzen wäre. Unter Solaris 10 z.B. ist es allerdings immer noch möglich einen Netzwerktreiber zu laden der für Solaris 8 geschrieben wurde.&lt;br /&gt;&lt;br /&gt;Es gibt noch viele weitere Grunde wie das SMF System, Zones, die SunStudio Entwicklungsumgebung, die p*-Tools usw. Die mich dazu gebracht haben auf Solaris zu wechseln, aber auch hier gilt: Ein Feature ist nur dann sinnvoll wenn man es nutzt. Mir macht es auf jeden Fall das Leben ungeahnt leichter :)&lt;br /&gt;&lt;br /&gt;Wer jetzt neugierig ist kann sich auch einmal den Podcast von &lt;a href="http://www.audioads.de/files/9580/pofacs014.mp3"&gt;pofacs.de&lt;/a&gt; (eine allgemein sehr lohnenswerte Seite) zu OpenSolaris anhören.&lt;br /&gt;&lt;br /&gt;&lt;center&gt;&lt;a href="http://www.opensolaris.org"&gt;&lt;br /&gt;&lt;img border="0" style="margin: 8px;" alt="OpenSolaris: Innovation Matters" title="OpenSolaris: Innovation Matters" src="http://www.opensolaris.org/os/about/buttons/innomat_os_blk_125.gif"&gt;&lt;br /&gt;&lt;/a&gt;&lt;/center&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8144285405079538181-2275553431304358423?l=raichoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://raichoo.blogspot.com/feeds/2275553431304358423/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8144285405079538181&amp;postID=2275553431304358423' title='1 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/2275553431304358423'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/2275553431304358423'/><link rel='alternate' type='text/html' href='http://raichoo.blogspot.com/2008/08/warum-opensolaris.html' title='Warum OpenSolaris?'/><author><name>Björn 'raichoo' Herzig</name><uri>https://profiles.google.com/102273886131939895778</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-KxzzpA_pbkc/AAAAAAAAAAI/AAAAAAAAARI/yHTIB2nrp8I/s512-c/photo.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8144285405079538181.post-1869529186643647909</id><published>2008-08-17T12:23:00.001-07:00</published><updated>2008-08-20T14:10:20.057-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='OpenSolaris'/><category scheme='http://www.blogger.com/atom/ns#' term='Dtrace'/><title type='text'>Dtrace Workshop - Teil 2: Probeargumente und Aufzählungen</title><content type='html'>In &lt;a href="http://raichoo.blogspot.com/2008/08/dtrace-workshop-teil-1-einfhrung.html"&gt;Teil 1&lt;/a&gt; dieses Workshops haben wir uns mit grundlegenden Funktionen von dtrace befasst. Heute will ich mich mit Probeargumenten und Aufzählungen befassen.&lt;br /&gt;&lt;br /&gt;Wie ich letztes mal schon festgestellt habe, arbeitet man bei dtrace mit der Programmiersprache D. Diese Sprache verfügt unter anderem über Datentypen. Ein besonderer Datentyp ist die Aufzählung. Ich will hier mal in einem kleinen Beispiel zeigen wie das funktioniert indem ich dtrace Systemcalls aufzählen lasse.&lt;br /&gt;&lt;code&gt;&lt;pre&gt;&lt;br /&gt;raichoo@itzkoatl:~# dtrace -n 'syscall:::entry{@[probefunc] = count();}'&lt;br /&gt;dtrace: description 'syscall:::entry' matched 233 probes&lt;br /&gt;^C&lt;br /&gt;&lt;br /&gt;  fstat64                                                           1&lt;br /&gt;  mmap                                                              1&lt;br /&gt;  schedctl                                                          1&lt;br /&gt;  sigpending                                                        1&lt;br /&gt;  nanosleep                                                         2&lt;br /&gt;  stat64                                                            2&lt;br /&gt;  pset                                                              3&lt;br /&gt;  sysconfig                                                         3&lt;br /&gt;  c2audit                                                           4&lt;br /&gt;  dup                                                               4&lt;br /&gt;  fcntl                                                             4&lt;br /&gt;  open                                                              4&lt;br /&gt;  sigaction                                                         4&lt;br /&gt;  brk                                                               6&lt;br /&gt;  close                                                             8&lt;br /&gt;  gtime                                                            10&lt;br /&gt;  clock_gettime                                                    11&lt;br /&gt;  writev                                                           12&lt;br /&gt;  setcontext                                                       13&lt;br /&gt;  lwp_sigmask                                                      15&lt;br /&gt;  setitimer                                                        25&lt;br /&gt;  p_online                                                         32&lt;br /&gt;  portfs                                                           84&lt;br /&gt;  write                                                           133&lt;br /&gt;  getpid                                                          169&lt;br /&gt;  read                                                            171&lt;br /&gt;  doorfs                                                          252&lt;br /&gt;  lwp_park                                                        320&lt;br /&gt;  pollsys                                                         496&lt;br /&gt;  ioctl                                                           648&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Wollen wir mal der Aufzählung auseinandernehmen:&lt;br /&gt;Mit dem @ zeigen wir an das wir etwas aufzählen wollen. Was das genau ist geben wir in eckigen Klammern an, in diesem Fall ist das die Probefunktion. &lt;b&gt;probefunc&lt;/b&gt; ist eine vordefinierte Variable die uns sagt welche Probe "gefeuert" hat. Kommen wir nun zum &lt;b&gt;= count()&lt;/b&gt;. Dieser Teil sagt uns WIE wir aufzählen wollen. &lt;b&gt;count()&lt;/b&gt; zählt einfach nur wie oft ein Ereignis eingetreten ist. Später werden wir uns genauer unterschiedlichen Aufzählungsarten befassen.&lt;br /&gt;Als Anmerkung bleibt wohl noch zu sagen das dtrace während der Ausführung nichts ausgibt sondern erst wenn wir es mit Strg-C beenden.&lt;br /&gt;&lt;br /&gt;Als nächstes wollen wir uns zur Vertiefung noch einen dtrace-Aufruf ansehen der uns anzeigt welche Programme den mmap Systemcall aufrufen und wie oft.&lt;br /&gt;&lt;code&gt;&lt;pre&gt;&lt;br /&gt;raichoo@itzkoatl:~# dtrace -n 'syscall::mmap:entry{@[execname] = count();}'&lt;br /&gt;dtrace: description 'syscall::mmap:entry' matched 1 probe&lt;br /&gt;^C&lt;br /&gt;&lt;br /&gt;  dtrace                                                            1&lt;br /&gt;  hostname                                                         16&lt;br /&gt;  utmp_update                                                      16&lt;br /&gt;  bash                                                             33&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Hier zählen wir nicht nach &lt;b&gt;probefunc&lt;/b&gt; sondern nach &lt;b&gt;execname&lt;/b&gt; auf. Außerdem haben wir das Probetupel genauer spezifiziert.&lt;br /&gt;&lt;br /&gt;Wir wollen uns jetzt mal genauer angucken was ein Systemcall so macht. Als Beispiel nehme ich hier den &lt;b&gt;open&lt;/b&gt; Systemcall. Gucken wir uns die Funktionsdefinition in der dazugehörigen Manpage an:&lt;br /&gt;&lt;code&gt;&lt;pre&gt;&lt;br /&gt;int open(const char *path, int oflag, /* mode_t mode */);&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;Diese Informationen werden an den &lt;b&gt;open&lt;/b&gt; Syscall übergeben und wenn man ehrlich ist, würde man da eigentlich auch ganz gerne drankommen wenn man dtrace benutzt. Und das geht auch. Wir haben mit &lt;b&gt;execname&lt;/b&gt; und &lt;b&gt;probefunc&lt;/b&gt; bereits 2 vordefinierte Variablen kennengelernt, jetzt kommen die Variablen &lt;b&gt;arg0&lt;/b&gt; bis &lt;b&gt;arg9&lt;/b&gt; hinzu. Jede gibt uns Zugang zu einem Argument der jeweiligen Probe.&lt;br /&gt;Als Beisiel konstruieren wir hier mal einen dtrace Aufruf der uns anzeigt welche Dateien unser System gerade öffnet.&lt;br /&gt;&lt;code&gt;&lt;pre&gt;&lt;br /&gt;raichoo@itzkoatl:~# dtrace -n 'syscall::open:entry{printf("%s",copyinstr(arg0));}'&lt;br /&gt;dtrace: description 'syscall::open:entry' matched 1 probe&lt;br /&gt;CPU     ID                    FUNCTION:NAME&lt;br /&gt;  0  69268                       open:entry /export/home/raichoo/.icons/Neutral_Plus_Inv/cursors/xterm&lt;br /&gt;  0  69268                       open:entry /export/home/raichoo/.icons/Neutral_Plus_Inv/index.theme&lt;br /&gt;  0  69268                       open:entry /usr/share/icons/Neutral_Plus_Inv/cursors/xterm&lt;br /&gt;  0  69268                       open:entry /export/home/raichoo/.icons/Neutral_Plus_Inv/cursors/xterm&lt;br /&gt;  0  69268                       open:entry /export/home/raichoo/.icons/Neutral_Plus_Inv/index.theme&lt;br /&gt;  0  69268                       open:entry /usr/share/icons/Neutral_Plus_Inv/cursors/xterm&lt;br /&gt;  0  69268                       open:entry /export/home/raichoo/.icons/Neutral_Plus_Inv/cursors/xterm&lt;br /&gt;  0  69268                       open:entry /export/home/raichoo/.icons/Neutral_Plus_Inv/index.theme&lt;br /&gt;  0  69268                       open:entry /usr/share/icons/Neutral_Plus_Inv/cursors/xterm&lt;br /&gt;  0  69268                       open:entry /export/home/raichoo/.icons/Neutral_Plus_Inv/cursors/xterm&lt;br /&gt;  0  69268                       open:entry /export/home/raichoo/.icons/Neutral_Plus_Inv/index.theme&lt;br /&gt;  0  69268                       open:entry /usr/share/icons/Neutral_Plus_Inv/cursors/xterm&lt;br /&gt;  0  69268                       open:entry /export/home/raichoo/.icons/Neutral_Plus_Inv/cursors/xterm&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;Zu &lt;b&gt;printf&lt;/b&gt; werde ich hier nicht viel verlieren sondern auf die &lt;a href="http://docs.sun.com/app/docs/doc/819-2243/printf-3c?l=en&amp;q=open&amp;a=view"&gt;C Manpage&lt;/a&gt; verweisen, da sich die dtrace Funktion genauso verhält. Wir wollen und das erste Argument der Probe ansehen, wie wir oben schon gesehen haben ist das erste Argument &lt;b&gt;const char *path&lt;/b&gt; der Pfad der zur öffnenden Datei. Um dieses auszulesen benutzen wir das Probeargument arg0. Da wir uns in einem Systemcall befinden müssen wir die Informationen aus dem Kerneladressraum in den Userspaceaddressraum kopieren, dazu ist die &lt;b&gt;copyinstr()&lt;/b&gt; Funktion da.&lt;br /&gt;&lt;br /&gt;Eigentlich wollte ich noch etwas auf den FBT-Provider eingehen, aber ich glaube das ist erstmal genug Input für heute, also werde ich mir das für später aufbewahren.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8144285405079538181-1869529186643647909?l=raichoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://raichoo.blogspot.com/feeds/1869529186643647909/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8144285405079538181&amp;postID=1869529186643647909' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/1869529186643647909'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/1869529186643647909'/><link rel='alternate' type='text/html' href='http://raichoo.blogspot.com/2008/08/dtrace-workshop-teil-2-probeargumente.html' title='Dtrace Workshop - Teil 2: Probeargumente und Aufzählungen'/><author><name>Björn 'raichoo' Herzig</name><uri>https://profiles.google.com/102273886131939895778</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-KxzzpA_pbkc/AAAAAAAAAAI/AAAAAAAAARI/yHTIB2nrp8I/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8144285405079538181.post-5676513861878339502</id><published>2008-08-14T17:35:00.001-07:00</published><updated>2008-08-14T18:59:01.303-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='OpenSolaris'/><category scheme='http://www.blogger.com/atom/ns#' term='Dtrace'/><title type='text'>Dtrace Workshop - Teil 1: Einführung</title><content type='html'>Nachdem ich ja immer so viel von dtrace schwärme möchte ich den Menschen auch gerne mal dieses extrem praktische Tool nahe bringen. Das dieses Thema extrem umfangreich ist werde ich es in verschiedene Sektionen aufteilen und von Zeit zu Zeit immer mal wieder etwas dazu posten.&lt;br /&gt;&lt;br /&gt;Was ist dtrace überhaupt? Der beste Vergleich den ich kenne ist wie folgt:&lt;br /&gt;Stell dir vor du hast Probleme mit deinem Auto. Es macht komische Geräusche wenn du schnell fährst. Und nun stell dir vor du fährst auf die Autobahn, beschleunigst auf 200 Sachen und steigst gemütlich aus, öffnest die Motorhaube und baust die Kiste auseinander ohne das diese aufhört zu arbeiten. Du kannst dir jede Schraube jeden Schlauch und jedes noch so komplexe Teil ansehen und herausfinden wo es Probleme gibt. Genau das macht Dtrace mit deinem Betriebssystem und alle Programmen die darauf laufen.&lt;br /&gt;&lt;br /&gt;Jetzt kann man sicherlich sagen. Naja in meine Programme konnte ich aber schon immer mit einem Debugger reingucken. Klar konnte man das, aber nur in einzelne Prozesse. Dtrace ermöglicht systemweites Debuggen ohne das man das System in ein großes Performanceloch schmeißt wie das mit Tools wie strace und truss z.B. der Fall ist.&lt;br /&gt;&lt;br /&gt;Wie funktioniert das Ganze? Dtrace verfügt über sogenannte Provider, welche in der Lage sind das System zu "instrumentalisieren". Das heißt: Sie kennen Punkte im System an dem sie Messungen durchführen können.&lt;br /&gt;&lt;br /&gt;Listen wir erst mal unsere Messpunkte auf:&lt;br /&gt;&lt;code&gt;&lt;pre&gt;&lt;br /&gt;raichoo@itzkoatl:~# dtrace -l&lt;br /&gt;   ID   PROVIDER            MODULE                          FUNCTION NAME&lt;br /&gt;    1     dtrace                                                     BEGIN&lt;br /&gt;    2     dtrace                                                     END&lt;br /&gt;    3     dtrace                                                     ERROR&lt;br /&gt;    4        fbt              fcsm         fcsm_job_cache_destructor entry&lt;br /&gt;    5        fbt              fcsm         fcsm_job_cache_destructor return&lt;br /&gt;    6        fbt              fcsm        fcsm_job_cache_constructor entry&lt;br /&gt;    7        fbt              fcsm        fcsm_job_cache_constructor return&lt;br /&gt;    8        fbt              fcsm                      fcsm_display entry&lt;br /&gt;    9        fbt              fcsm                      fcsm_display return&lt;br /&gt;...&lt;br /&gt;69649   lockstat           genunix                   lock_clear_splx spin-release&lt;br /&gt;69650   lockstat           genunix                      CLOCK_UNLOCK spin-release&lt;br /&gt;69651   lockstat           genunix                          rw_enter rw-acquire&lt;br /&gt;69652   lockstat           genunix                          rw_enter rw-block&lt;br /&gt;69653   lockstat           genunix                           rw_exit rw-release&lt;br /&gt;69654   lockstat           genunix                       rw_tryenter rw-acquire&lt;br /&gt;69655   lockstat           genunix                     rw_tryupgrade rw-upgrade&lt;br /&gt;69656   lockstat           genunix                      rw_downgrade rw-downgrade&lt;br /&gt;69657   lockstat           genunix                       thread_lock thread-spin&lt;br /&gt;69658   lockstat           genunix                  thread_lock_high thread-spin&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;Ok, hier wurden wir gerade mit verdammt vielen Messpunkten oder auch Probes erschlagen. Wie man sieht ist jede Probe einem Provider, einem Modul, einer Funktion und einem Namen zugeordnet. Mit diesen Tupeln sind wir in der Lage jeden Messpunkt zu spezifizieren und damit anzusprechen. Gucken wir einfach mal wie viele Probes uns unser System so zur Verfügung stellt.&lt;br /&gt;&lt;code&gt;&lt;pre&gt;&lt;br /&gt;raichoo@itzkoatl:~# uname -a&lt;br /&gt;SunOS itzkoatl 5.11 snv_95 i86pc i386 i86pc&lt;br /&gt;raichoo@itzkoatl:~# dtrace -l | wc -l&lt;br /&gt;   69659&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;Alleine auf meinem System stehen mir fast 70.000 Probes zur Verfügung. Und das sind noch lange nicht alle, es gibt noch ein paar spezielle Provider (z.B. den PID-Provider und auch Provider für so ziemlich jedes Skriptsprache z.B. Python, Ruby, PHP, JavaScript und und und) die einem noch mehr Transparenz geben.&lt;br /&gt;&lt;br /&gt;Ok, jetzt da wir wissen das wir wirklich viel messen können wollen wir mal loslegen! Als Einführungsbeispiel will ich hier den Syscallprovider vorstellen. Dieser Provider weiß wie man Systemcalls instrumentalisiert. Systemcalls sind Funktionen bei deren Ausführung ein Programm ein Aufgabe an den Kernel abgibt z.B. öffne eine Datei, mappe mir etwas in den virtuellen Speicher, schicke ein Signal an einen anderen Prozess.&lt;br /&gt;&lt;br /&gt;Als erstes wollen wir erst mal jeden Syscall-Entry anzeigen lassen.&lt;br /&gt;&lt;code&gt;&lt;pre&gt;&lt;br /&gt;raichoo@itzkoatl:~# dtrace -n syscall:::entry&lt;br /&gt;...&lt;br /&gt;  0  69480                    pollsys:entry&lt;br /&gt;  0  69166                      write:entry&lt;br /&gt;  0  69450                lwp_sigmask:entry&lt;br /&gt;  0  69450                lwp_sigmask:entry&lt;br /&gt;  0  69164                       read:entry&lt;br /&gt;  0  69480                    pollsys:entry&lt;br /&gt;  0  69450                lwp_sigmask:entry&lt;br /&gt;  0  69450                lwp_sigmask:entry&lt;br /&gt;  0  69166                      write:entry&lt;br /&gt;  0  69480                    pollsys:entry&lt;br /&gt;  0  69166                      write:entry&lt;br /&gt;  0  69450                lwp_sigmask:entry&lt;br /&gt;  0  69450                lwp_sigmask:entry&lt;br /&gt;  0  69164                       read:entry&lt;br /&gt;  0  69480                    pollsys:entry&lt;br /&gt;  0  69450                lwp_sigmask:entry&lt;br /&gt;  0  69450                lwp_sigmask:entry&lt;br /&gt;  0  69166                      write:entry&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;Jetzt werden uns in Echtzeit alle Systemcall-Entrys auf dem System gezeigt ohne das das System ausgebremst wird. Diese Information ist allerdings eher unspannend. Wir wollen ja auch wissen WER das macht, also erweitern wir unser Kommando:&lt;br /&gt;&lt;code&gt;&lt;pre&gt;&lt;br /&gt;raichoo@itzkoatl:~# dtrace -n 'syscall:::entry{trace(execname);}'&lt;br /&gt;...&lt;br /&gt;  0  69258                      ioctl:entry   dtrace&lt;br /&gt;  0  69258                      ioctl:entry   dtrace&lt;br /&gt;  0  69258                      ioctl:entry   dtrace&lt;br /&gt;  0  69258                      ioctl:entry   dtrace&lt;br /&gt;  0  69258                      ioctl:entry   dtrace&lt;br /&gt;  0  69258                      ioctl:entry   dtrace&lt;br /&gt;  0  69258                      ioctl:entry   dtrace&lt;br /&gt;  0  69258                      ioctl:entry   dtrace&lt;br /&gt;  0  69258                      ioctl:entry   dtrace&lt;br /&gt;  0  69258                      ioctl:entry   dtrace&lt;br /&gt;  0  69352                       mmap:entry   dtrace&lt;br /&gt;  0  69286                   lwp_park:entry   dtrace&lt;br /&gt;  0  69450                lwp_sigmask:entry   sshd&lt;br /&gt;  0  69450                lwp_sigmask:entry   sshd&lt;br /&gt;  0  69164                       read:entry   sshd&lt;br /&gt;  0  69480                    pollsys:entry   sshd&lt;br /&gt;  0  69450                lwp_sigmask:entry   sshd&lt;br /&gt;  0  69450                lwp_sigmask:entry   sshd&lt;br /&gt;  0  69166                      write:entry   sshd&lt;br /&gt;  0  69480                    pollsys:entry   sshd&lt;br /&gt;  0  69450                lwp_sigmask:entry   sshd&lt;br /&gt;  0  69450                lwp_sigmask:entry   sshd&lt;br /&gt;  0  69164                       read:entry   sshd&lt;br /&gt;  0  69480                    pollsys:entry   sshd&lt;br /&gt;  0  69450                lwp_sigmask:entry   sshd&lt;br /&gt;  0  69450                lwp_sigmask:entry   sshd&lt;br /&gt;  0  69166                      write:entry   sshd&lt;br /&gt;  0  69480                    pollsys:entry   sshd&lt;br /&gt;  0  69330                 sigpending:entry   dtrace&lt;br /&gt;  0  69450                lwp_sigmask:entry   dtrace&lt;br /&gt;  0  69332                 setcontext:entry   dtrace&lt;br /&gt;  0  69166                      write:entry   dtrace&lt;br /&gt;  0  69450                lwp_sigmask:entry   sshd&lt;br /&gt;  0  69450                lwp_sigmask:entry   sshd&lt;br /&gt;  0  69164                       read:entry   sshd&lt;br /&gt;  0  69480                    pollsys:entry   sshd&lt;br /&gt;  0  69450                lwp_sigmask:entry   sshd&lt;br /&gt;  0  69450                lwp_sigmask:entry   sshd&lt;br /&gt;  0  69166                      write:entry   sshd&lt;br /&gt;  0  69480                    pollsys:entry   sshd&lt;br /&gt;  0  69258                      ioctl:entry   dtrace&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;Mit &lt;b&gt;trace(execname)&lt;/b&gt; geben wir an das wir uns für das Programm interessieren das den Systemcall tätigt. execname ist eine vordefinierte Variable von der es eine ganze Menge gibt.&lt;br /&gt;&lt;br /&gt;Aber was genau sehen wir da jetzt? Einige werden es sicher schon ahnen. Ich bin über SSH mit meinem Solarisrechner verbunden und alles was wir jetzt sehen sind die Systemcalls die das System braucht um all die Informationen für mich sichtbar zu machen. Wir gucken also dem System zu wie es uns sagt das es etwas sagt.&lt;br /&gt;&lt;br /&gt;Wollen wir also unsere "Observation" weiter einschränken. Wir können ein Bedingung angeben die uns nur in bestimmeten Fällen einen Messwert liefert. Das geht wie folgt.&lt;br /&gt;&lt;code&gt;&lt;pre&gt;&lt;br /&gt;raichoo@itzkoatl:~# dtrace -n 'syscall:::entry/execname == "gdm-binary"/{}'&lt;br /&gt;dtrace: description 'syscall:::entry' matched 233 probes&lt;br /&gt;CPU     ID                    FUNCTION:NAME&lt;br /&gt;  0  69164                       read:entry&lt;br /&gt;  0  69164                       read:entry&lt;br /&gt;  0  69164                       read:entry&lt;br /&gt;  0  69166                      write:entry&lt;br /&gt;  0  69412                      yield:entry&lt;br /&gt;  0  69164                       read:entry&lt;br /&gt;  0  69164                       read:entry&lt;br /&gt;  0  69486                    c2audit:entry&lt;br /&gt;  0  69368                      xstat:entry&lt;br /&gt;  0  69312                   readlink:entry&lt;br /&gt;  0  69486                    c2audit:entry&lt;br /&gt;  0  69450                lwp_sigmask:entry&lt;br /&gt;  0  69450                lwp_sigmask:entry&lt;br /&gt;  0  69450                lwp_sigmask:entry&lt;br /&gt;  0  69450                lwp_sigmask:entry&lt;br /&gt;  0  69356                     munmap:entry&lt;br /&gt;  0  69356                     munmap:entry&lt;br /&gt;...&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Hier werden uns nur Informationen ausgegeben wenn das ausführende Programm &lt;b&gt;gdm-binary&lt;/b&gt; ist.&lt;br /&gt;&lt;br /&gt;Unsere Abfrage ist also wie folgt aufgebaut:&lt;br /&gt;&lt;code&gt;&lt;pre&gt;&lt;br /&gt;dtrace -n probe-tupel&lt;br /&gt;/Bedingung/&lt;br /&gt;{&lt;br /&gt;    Funktionskörper&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;Wie man sieht stellt dtrace eine kleine Programmiersprache zur Verfügung. Diese Sprache hat den Namen D und ist stark mit AWK und C verwand.&lt;br /&gt;&lt;br /&gt;Das war nur ein &lt;b&gt;extrem&lt;/b&gt; kleiner Einblick in das was dtrace kann. Als nächstes werde ich mich mit Probe-Argumenten, dem FBT-Provider (welcher jede Funktion im Kernel tracen kann) und dtrace-Skripten befassen. Wer bis dahin nicht warten kann, kann sich auch den &lt;a href="http://video.google.com/videoplay?docid=-8002801113289007228&amp;ei=rCujSPH7BJOi2ALdhbW6Aw&amp;q=dtrace"&gt;Vortrag von Brian Cantrill&lt;/a&gt; über dtrace ansehen (SEHR SEHENSWERT!) oder einfach mal im &lt;a href="http://docs.sun.com/app/docs/doc/819-5488?a=load"&gt;Dtrace User's Guide&lt;/a&gt; schmöckern.&lt;br /&gt;&lt;br /&gt;Dtrace kann man auch auf der OpenSolaris LiveCD benutzen. Als Anmerkung gilt zu sagen das man root-Rechte braucht (oder bestimmte RBAC-Rechte auf einem Produktivsystem)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8144285405079538181-5676513861878339502?l=raichoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://raichoo.blogspot.com/feeds/5676513861878339502/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8144285405079538181&amp;postID=5676513861878339502' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/5676513861878339502'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/5676513861878339502'/><link rel='alternate' type='text/html' href='http://raichoo.blogspot.com/2008/08/dtrace-workshop-teil-1-einfhrung.html' title='Dtrace Workshop - Teil 1: Einführung'/><author><name>Björn 'raichoo' Herzig</name><uri>https://profiles.google.com/102273886131939895778</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-KxzzpA_pbkc/AAAAAAAAAAI/AAAAAAAAARI/yHTIB2nrp8I/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8144285405079538181.post-145590804237991335</id><published>2008-08-14T17:13:00.000-07:00</published><updated>2008-08-14T17:16:02.140-07:00</updated><title type='text'>Pimp my Blog</title><content type='html'>Nachdem es irgendwie recht defaultmässig auf meinem Blog zugegangen ist hab ich mir mal ein paar zusätzliche Einstellungen gegönnt im das gute Stück hier etwas persönlicher und auch übersichtlicher zu gestallten. :)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8144285405079538181-145590804237991335?l=raichoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://raichoo.blogspot.com/feeds/145590804237991335/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8144285405079538181&amp;postID=145590804237991335' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/145590804237991335'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/145590804237991335'/><link rel='alternate' type='text/html' href='http://raichoo.blogspot.com/2008/08/pimp-my-blog.html' title='Pimp my Blog'/><author><name>Björn 'raichoo' Herzig</name><uri>https://profiles.google.com/102273886131939895778</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-KxzzpA_pbkc/AAAAAAAAAAI/AAAAAAAAARI/yHTIB2nrp8I/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8144285405079538181.post-8174846515033541173</id><published>2008-08-04T03:38:00.000-07:00</published><updated>2008-08-04T16:21:52.350-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='vi'/><title type='text'>Der widerspenstigen Zähmung</title><content type='html'>Da vi/vim unter manchen Systemen die nervige Angewohnheit hat im Insert-Mode etwas eigensinnig mit den Pfeiltasten umzugehen, hier ein kleiner Patch um dem guten Stück Beine zu machen:&lt;br /&gt;&lt;br /&gt;Wir schreiben folgendes in unsere .exrc und .vimrc:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;pre&gt;set t_ku=[strg-v][pfeil-hoch]&lt;br /&gt;set t_kd=[strg-v][pfeil-runter]&lt;br /&gt;set t_kr=[strg-v][pfeil-rechts]&lt;br /&gt;set t_kl=[strg-v][pfeil-links]&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;(Anmerkung: Das was in den eckigen Klammern steht nicht abtippen sondern machen ;) )&lt;br /&gt;&lt;br /&gt;Um das ganze im Nachhinein noch etwas aufzupeppen kann man auch noch "set showmode" und "syntax on" hinzufügen um den aktuellen Mode anzeigen zu lassen und das Syntaxhighlighting zu aktivieren.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8144285405079538181-8174846515033541173?l=raichoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://raichoo.blogspot.com/feeds/8174846515033541173/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8144285405079538181&amp;postID=8174846515033541173' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/8174846515033541173'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/8174846515033541173'/><link rel='alternate' type='text/html' href='http://raichoo.blogspot.com/2008/08/der-widerspenstigen-zhmung.html' title='Der widerspenstigen Zähmung'/><author><name>Björn 'raichoo' Herzig</name><uri>https://profiles.google.com/102273886131939895778</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-KxzzpA_pbkc/AAAAAAAAAAI/AAAAAAAAARI/yHTIB2nrp8I/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8144285405079538181.post-3931175253800339127</id><published>2008-08-03T13:37:00.000-07:00</published><updated>2010-04-17T01:06:16.815-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='MacOSX'/><category scheme='http://www.blogger.com/atom/ns#' term='FreeBSD'/><category scheme='http://www.blogger.com/atom/ns#' term='Linux'/><category scheme='http://www.blogger.com/atom/ns#' term='OpenSolaris'/><category scheme='http://www.blogger.com/atom/ns#' term='Debugging'/><category scheme='http://www.blogger.com/atom/ns#' term='Dtrace'/><title type='text'>Dtrace überall</title><content type='html'>In den letzten Jahren hat dtrace, das dynamische Tracingtool von &lt;a href="http://www.opensolaris.org"&gt;OpenSolaris&lt;/a&gt;, für eine Menge aufsehen gesorgt und inzwischen findet es auf immer mehr Plattformen ein zuhause. Ports existieren bereits für Mac OS X und QNX. Derzeit werden auch vom &lt;a href="http://www.freebsd.org"&gt;FreeBSD&lt;/a&gt; (man munkelt auch über einen NetBSD Port) Team Anstrengungen unternommen es zu portieren und vor einigen Monaten wurde der erste Code in den CURRENT Zweig commited.&lt;br /&gt;Unter Linux gab es allerdings Probleme da die CDDL-Lizenz, unter der dtrace steht, nicht kompatibel zur GPL ist. Es wurden zwar mit systemtap Ansätze unternommen dtrace zu kopieren, doch ist es in keiner Weise vergleichbar da es unter anderem nicht in der Lage ist Userspace Prozesse zu tracen und die Stabilität des Systems beeinträchtigt da unter anderem das "Skripten" welches fast C ähnlich ist, völlig über das Ziel hinausschiesst und gefährlichen Code ermöglicht. Inzwischen ist das ftrace-Framework &lt;a href="http://lwn.net/Articles/291091/"&gt;im Gespräch&lt;/a&gt; welches aber im Gegensatz zu dtrace und systemtap nicht skriptbar ist und damit extrem an Flexibilität einbüßt. Alles in allem eher spärliche Aussichten. Für ein Licht am Ende des Tunnels sorgt &lt;a href="http://www.crisp.demon.co.uk/blog/index.html"&gt;Paul Fox&lt;/a&gt; der sich daran gemacht hat dtrace auf Linux zu portieren. Ob es letztendlich möglich sein wird Linux Distributionen mit dtrace auszuliefern kann ich derzeit leider nicht sagen (da mir der ganze Lizenzkram langsam eh zu undurchschaubar wird), aber es bleibt die Hoffnung das es wenigstens ein Patchset geben wird das dieses unglaublich mächtige Tool in die Linuxwelt bringen wird.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8144285405079538181-3931175253800339127?l=raichoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://raichoo.blogspot.com/feeds/3931175253800339127/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8144285405079538181&amp;postID=3931175253800339127' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/3931175253800339127'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/3931175253800339127'/><link rel='alternate' type='text/html' href='http://raichoo.blogspot.com/2008/08/dtrace-berall.html' title='Dtrace überall'/><author><name>Björn 'raichoo' Herzig</name><uri>https://profiles.google.com/102273886131939895778</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-KxzzpA_pbkc/AAAAAAAAAAI/AAAAAAAAARI/yHTIB2nrp8I/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8144285405079538181.post-5264745167405496361</id><published>2008-07-30T15:56:00.000-07:00</published><updated>2008-08-14T17:11:36.518-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='OpenSolaris'/><category scheme='http://www.blogger.com/atom/ns#' term='Debugging'/><title type='text'>Der Solaris Kerneldebugger: Ein Beispiel</title><content type='html'>Mein Notebook hat die unangenehme Angewohnheit das es unter Solaris gerne einen NMI produziert (Non Maskable Interrupts sind etwas unangenehme Zeitgenossen die z.b. bei Hardwarefehlern auftreten). Nach ein bisschen schmökern im Sourcecode von Solaris ist mir dann aufgefallen das es dort folgende Varibale im pcie Modul gibt:&lt;br /&gt;&lt;code&gt;&lt;pre&gt;uint32_t pcie_serr_disable_flag = 0;    /* Disable SERR */&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;In einem Kommentar wird erwähnt das bei aktiviertem SERR eventuell ein NMI entsteht (welcher aber nicht behandelt wird). Jetzt wollen wir den Inhalt dieser Variable also auf 1 haben damit SERR deaktiviert wird und wir den NMI los sind. Dazu nehmen wir den Kerneldebugger. Durch einfaches Anhängen von &lt;b&gt;-kd&lt;/b&gt; im Kerneleintrag von Grub landet man gleich zu Anfang am Debugprompt. Wir wollen jetzt zu dem Punkt springen an dem unser pcie Modul geladen wird, das erreichen wir indem wir dem Debugger sagen das es an diesem Punkt halten soll.&lt;br /&gt;&lt;code&gt;&lt;pre&gt;&lt;br /&gt;::bp pcie`_init&lt;br /&gt;::cont&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;Damit wird ein so genannter Breakpoint gesetzt. Wird dieser erreicht halten wir an und gelangen wieder an den Prompt. ::cont sagt dem Debugger einfach &lt;br /&gt;das das Programm weiterlaufen soll.&lt;br /&gt;&lt;br /&gt;Wir erreichen nun unseren Breakpoint. Jetzt können wir den Inhalt unserer Variable einfach mit&lt;br /&gt;&lt;code&gt;&lt;pre&gt;pcie_serr_disable_flag/W 1&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;auf 1 setzen und mit ::cont weiterbooten ohne das der NMI auftaucht.&lt;br /&gt;&lt;br /&gt;Praktische Sache oder? ;)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8144285405079538181-5264745167405496361?l=raichoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://raichoo.blogspot.com/feeds/5264745167405496361/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8144285405079538181&amp;postID=5264745167405496361' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/5264745167405496361'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/5264745167405496361'/><link rel='alternate' type='text/html' href='http://raichoo.blogspot.com/2008/07/der-solaris-kerneldebugger-ein-beispiel.html' title='Der Solaris Kerneldebugger: Ein Beispiel'/><author><name>Björn 'raichoo' Herzig</name><uri>https://profiles.google.com/102273886131939895778</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-KxzzpA_pbkc/AAAAAAAAAAI/AAAAAAAAARI/yHTIB2nrp8I/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8144285405079538181.post-5853565906209022144</id><published>2008-07-28T05:02:00.000-07:00</published><updated>2008-07-28T05:28:26.465-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Debugging'/><title type='text'>Spaß mit DLL-Injection</title><content type='html'>Heute will ich mich mal mit einer sehr interessanten Debug-Technik befassen: der DLL-Injektion.&lt;br /&gt;Jeder der schon mal in C++ oder ähnlichem gecodet hat kennt sicherlich das Konzept des Überladen von Funktionen. Die Frage ist jetzt: Kann man das ganze auch noch machen wenn ein Programm schon fertig gebacken ist? Otto würde jetzt sagen "Yiiiaaaaaaaaaah ih ih ih ih" *rumhüpf*&lt;br /&gt;&lt;br /&gt;Als Beispiel werde ich hier mal etwas fehlerhaften C-Code kompilieren und im Nachhinein die verantwortliche Funktion mit etwas harmlosen überladen.&lt;br /&gt;&lt;br /&gt;Hier erst mal unser fehlerhafter code&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;pre&gt;#include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;&lt;br /&gt;int main()&lt;br /&gt;{&lt;br /&gt;        char buffer[256];&lt;br /&gt;        vscanf("%s",buffer);&lt;br /&gt;        return 0;&lt;br /&gt;}&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Das Ganze segelt in einem herrlichen Segfault ab ^^. Ok, jetzt wollen wir einfach mal die Funktion vscanf mit etwas harmlosen "überschreiben". Dazu werden wir eine Dummy-lib schreiben und diese mit LD_PRELOAD dynamisch in unser Programm linken.&lt;br /&gt;&lt;br /&gt;Der Code für unser Lib sieht erst mal so aus:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;pre&gt;&lt;br /&gt;#include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;&lt;br /&gt;int vscanf(const char* format,va_list ap)&lt;br /&gt;{&lt;br /&gt;        printf("override\n");&lt;br /&gt;        return 0;&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Voila, wir haben die Zutaten. Jetzt wird es Zeit für das Rezept:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;pre&gt;&lt;br /&gt;[raichoo@tessaiga ~]$ gcc test.c -o karpott&lt;br /&gt;[raichoo@tessaiga ~]$ ./karpott&lt;br /&gt;test&lt;br /&gt;Segmentation fault: 11 (core dumped)&lt;br /&gt;[raichoo@tessaiga ~]$ gcc -shared -o override.so override.c&lt;br /&gt;[raichoo@tessaiga ~]$ LD_PRELOAD=./override.so ./karpott&lt;br /&gt;override&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Guten Appetit!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8144285405079538181-5853565906209022144?l=raichoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://raichoo.blogspot.com/feeds/5853565906209022144/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8144285405079538181&amp;postID=5853565906209022144' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/5853565906209022144'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/5853565906209022144'/><link rel='alternate' type='text/html' href='http://raichoo.blogspot.com/2008/07/spa-mit-dll-injection.html' title='Spaß mit DLL-Injection'/><author><name>Björn 'raichoo' Herzig</name><uri>https://profiles.google.com/102273886131939895778</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-KxzzpA_pbkc/AAAAAAAAAAI/AAAAAAAAARI/yHTIB2nrp8I/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8144285405079538181.post-3661502978885850069</id><published>2008-07-23T02:34:00.000-07:00</published><updated>2010-04-17T01:04:08.192-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='FreeBSD'/><title type='text'>KDE4 unter FreeBSD</title><content type='html'>Letzte Woche war es soweit: Für all die, denen kompilieren immer zu mühseelig ist, gibt es seit Donnerstag KDE4 Pakete für FreeBSD. Das Ganze dient derzeit noch zum testen, läuft aber bis auf einige Kleinigkeiten ziemlich rund. &lt;a href="http://miwi.bsdcrew.de/2008/07/17/freebsd-call-for-testing-kde4/"&gt;Die Porter rufen derzeit zur regen Bugjagd auf&lt;/a&gt; um KDE4 für FreeBSD fit zu machen.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp1.blogger.com/_3VHVa9AP0ZM/SIb8JGTVUSI/AAAAAAAAADg/dhArUD3HutY/s1600-h/kde4-freebsd.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://bp1.blogger.com/_3VHVa9AP0ZM/SIb8JGTVUSI/AAAAAAAAADg/dhArUD3HutY/s320/kde4-freebsd.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5226141650850763042" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Vielen Dank an Miwi fürs portieren und die Starthilfe ;)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8144285405079538181-3661502978885850069?l=raichoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://raichoo.blogspot.com/feeds/3661502978885850069/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8144285405079538181&amp;postID=3661502978885850069' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/3661502978885850069'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8144285405079538181/posts/default/3661502978885850069'/><link rel='alternate' type='text/html' href='http://raichoo.blogspot.com/2008/07/kde4-unter-freebsd.html' title='KDE4 unter FreeBSD'/><author><name>Björn 'raichoo' Herzig</name><uri>https://profiles.google.com/102273886131939895778</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-KxzzpA_pbkc/AAAAAAAAAAI/AAAAAAAAARI/yHTIB2nrp8I/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://bp1.blogger.com/_3VHVa9AP0ZM/SIb8JGTVUSI/AAAAAAAAADg/dhArUD3HutY/s72-c/kde4-freebsd.png' height='72' width='72'/><thr:total>0</thr:total></entry></feed>
