<?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-759829123710334956</id><updated>2012-01-29T20:31:46.661+01:00</updated><category term='ruby'/><category term='aperture'/><category term='fsck'/><category term='zfs'/><category term='photography'/><category term='vmware'/><category term='shotwell'/><category term='smalltalk'/><category term='extfs'/><category term='nmap'/><category term='storage'/><category term='microwave'/><category term='monitoring'/><category term='wannabe-writer'/><category term='digikam'/><category term='puzzle'/><category term='lvm'/><category term='ports'/><category term='bash'/><category term='snapshot'/><category term='f-spot'/><category term='king cake'/><category term='zenoss'/><category term='filesystem'/><category term='text'/><category term='shell'/><category term='iphoto'/><category term='rails'/><category term='mathematics'/><category term='wish'/><category term='ascii-art'/><category term='vim'/><category term='fun'/><category term='tagging'/><category term='seaside'/><category term='btrfs'/><category term='newline'/><category term='whining'/><category term='san'/><title type='text'>Anselm's Blog</title><subtitle type='html'>All your base are belong to shell!</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://anselm-strauss.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/759829123710334956/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://anselm-strauss.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>anselm</name><uri>http://www.blogger.com/profile/12439016778981424132</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://3.bp.blogspot.com/_Yy4WDeOpVdM/TRo6zkow78I/AAAAAAAAAPk/r49QCStzciU/S220/anselm-strauss-posterized.png'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>15</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-759829123710334956.post-39582023485294908</id><published>2011-03-29T22:36:00.000+02:00</published><updated>2011-03-29T22:36:23.523+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='fun'/><category scheme='http://www.blogger.com/atom/ns#' term='wannabe-writer'/><title type='text'>ZZZzzz...</title><content type='html'>&lt;p&gt;I think I read this in a history book from the future, but I only remember vaguely, so it could as well be that I just made this up:&lt;/p&gt; &lt;p&gt;&lt;i&gt;"In the beginning of the 21st century society began to change in a way that human history had never seen before. Polyphasic sleep was widely adopted. The usual day-night life cycle as mankind knew it was virtually over. The words day and night were abandoned and people began to talk about phases instead. Even earth's orbit and rotation were altered in a staggering space mission in 2031. Certain people that could not adapt to this new form of life decided to go into winter sleep. But this was only a temporary solution. Many of them finally signed up for cryonic stasis, most of them with explicit demand to never wake them up again. Those people were also called monos (from monophasic sleep) or sloths."&lt;/i&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/759829123710334956-39582023485294908?l=anselm-strauss.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://anselm-strauss.blogspot.com/feeds/39582023485294908/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://anselm-strauss.blogspot.com/2011/03/zzzzzz.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/759829123710334956/posts/default/39582023485294908'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/759829123710334956/posts/default/39582023485294908'/><link rel='alternate' type='text/html' href='http://anselm-strauss.blogspot.com/2011/03/zzzzzz.html' title='ZZZzzz...'/><author><name>anselm</name><uri>http://www.blogger.com/profile/12439016778981424132</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://3.bp.blogspot.com/_Yy4WDeOpVdM/TRo6zkow78I/AAAAAAAAAPk/r49QCStzciU/S220/anselm-strauss-posterized.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-759829123710334956.post-1919568113780167616</id><published>2011-03-16T23:20:00.004+01:00</published><updated>2011-03-17T20:06:22.908+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='puzzle'/><title type='text'>About Puzzles</title><content type='html'>&lt;p&gt;When solving puzzles I often think the most frustrating thing is that there is very little theory about how to approach and efficiently solve them. Yet this is maybe why they are so interesting and allow one to be really creative. But sometimes I wish there had been more reasoning about the methodology of solving puzzles in my learning career than the sole perpetual advice that skill comes with practice.&lt;/p&gt;&lt;h3&gt;Understand the question, see the challenge&lt;/h3&gt;&lt;p&gt;I remember having spent a lot of time just figuring out what the heck this puzzle is asking for, in what direction the questions want me to go. This can of course be part of the puzzle itself, and maybe it is not that important after all to find the exact solution as fast as possible but rather just start thinking and go where you want to go. Only that degrees, school and partially also university are not always the right place for that.&lt;/p&gt;&lt;h3&gt;The image in the mirror&lt;/h3&gt;&lt;p&gt;A simple question I once heard and already asked some people is: &lt;em&gt;"Why is left and right flipped in the mirror?"&lt;/em&gt; I then sometimes get a lesson in optics, how the light is reflected, a schematic drawing and the final answer that this is why of course left and right is mirrored, &lt;em&gt;"You see?!"&lt;/em&gt;. To be fair the question is not that obviously asking for a puzzle, but to make it more clear I could ask &lt;em&gt;"Why of all things is it left and right? Why not top and bottom?"&lt;/em&gt; Then the puzzling question may become more obvious. I started to think about what two images are actually compared, that it is easier to not take myself as the subject to think with but somebody else I am looking at, once directly standing in front and once in the mirror. Then I thought about how I come from one image to the other and what needs to be changed to make top and bottom flip instead.&lt;/p&gt;&lt;p&gt;I found this example particularly interesting because at first it seems to ask for a simple technical explanation, but then when you see the actual implied challenge it gets much more puzzling.&lt;/p&gt;&lt;h3&gt;No need to solve what is not asked for&lt;/h3&gt;&lt;p&gt;Maybe not an advice I would give for trying to be creative, but unarguably efficiency is sometimes what is asked for.&lt;/p&gt;&lt;h3&gt;One glass of water and one glass of orange juice&lt;/h3&gt;&lt;p&gt;Assume both glasses a filled with the same amount. If you take one spoonful of the water glass, put it into the orange juice, mix it, take a spoonful of the mix and put it back into the water, will there be more orange juice in the water or more water in the orange juice or the same amount of each one in the other (disregarding density of the different fluids)? When I first started to solve this I made the mistake to actually starting to compute the fractions of each fluid in the other. While you may be able to solve it that way, remember that this is more than is asked for. The question is only if the parts are equal or in case not, which one is bigger.&lt;/p&gt;&lt;p&gt;There is actually a high level thought to easily solve this. If you take one spoonful from one glass to the other and then a spoonful of the same size again back, there must be the same total amount in each glass as before. Knowing that, if amount x is missing in the water glass because it is in the orange juice, the same amount of juice must be in the water glass, otherwise they would not have the same equal amount as they had before. Of course it can also be interesting to compute the actual fractions but it is a less efficient way to solve the original question.&lt;/p&gt;&lt;h3&gt;Ask the neighbors&lt;/h3&gt;&lt;p&gt;Sometimes a seeming detour can be a shortcut. It may be easier to compute something else, perhaps similar, and go on from there.&lt;/p&gt;&lt;h3&gt;Power set&lt;/h3&gt;&lt;p&gt;What is the sum of &lt;code&gt;2^0 + 2^1 + 2^2 + ... + 2^k&lt;/code&gt;? Not trivial to convert but in another representation it looks much simpler. This is of course the representation of a binary number with k digits each being 1. E.g. for k=4 it is 1111. To bring it into a simpler form the lots of 1 are bothering. Can this number be represented as a sum that has much less 1, maybe a fixed amount of 1, not depending on k? Well, 1111 is the same as 10000-1. And this form always has only two 1. So &lt;code&gt;sum[i=0, k, 2^i] = 2^(k+1)-1&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;The mathematical conversion for the interesting part would go something like this: &lt;code&gt;2^(k+1) = 2 * 2^k = 2^k + 2^k = 2^k + 2 * 2^(k-1) = 2^k + 2^(k-1) + 2^(k-1) = 2^k + 2^(k-1) + 2 * 2^(k-2) = ...&lt;/code&gt;.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/759829123710334956-1919568113780167616?l=anselm-strauss.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://anselm-strauss.blogspot.com/feeds/1919568113780167616/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://anselm-strauss.blogspot.com/2011/03/about-puzzles_16.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/759829123710334956/posts/default/1919568113780167616'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/759829123710334956/posts/default/1919568113780167616'/><link rel='alternate' type='text/html' href='http://anselm-strauss.blogspot.com/2011/03/about-puzzles_16.html' title='About Puzzles'/><author><name>anselm</name><uri>http://www.blogger.com/profile/12439016778981424132</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://3.bp.blogspot.com/_Yy4WDeOpVdM/TRo6zkow78I/AAAAAAAAAPk/r49QCStzciU/S220/anselm-strauss-posterized.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-759829123710334956.post-1566494626846614342</id><published>2011-02-26T18:18:00.002+01:00</published><updated>2011-02-28T10:44:47.742+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='puzzle'/><category scheme='http://www.blogger.com/atom/ns#' term='king cake'/><category scheme='http://www.blogger.com/atom/ns#' term='mathematics'/><title type='text'>Of King Cakes and Dices</title><content type='html'>&lt;p&gt;Last epiphany a &lt;a href="http://debern.blogspot.com"&gt;friend&lt;/a&gt; asked me the following puzzle: "You have &lt;code&gt;k&lt;/code&gt; king cakes and &lt;code&gt;p&lt;/code&gt; persons eating. Each person gets exactly one equal sized piece of each cake, and of course each cake has exactly one king in one piece. What is the probability that each person has picked at least one king?"&lt;/p&gt;&lt;h2&gt;Some facts&lt;/h2&gt;&lt;p&gt;&lt;ul&gt;&lt;li&gt;Since we are asking for each person to have at least one king, &lt;code&gt;k&lt;/code&gt; must be equal or bigger than &lt;code&gt;p&lt;/code&gt;.&lt;/li&gt;&lt;li&gt;Each cake is divided into &lt;code&gt;p&lt;/code&gt; equal sized pieces, because each person gets one piece of each cake.&lt;/li&gt;&lt;li&gt;The question "picking at least one king" is what makes the puzzle so difficult.&lt;/li&gt;&lt;/ul&gt;&lt;/p&gt;&lt;h2&gt;Abstraction&lt;/h2&gt;&lt;p&gt;The problem is equal to repeatedly throwing a dice. Each king has the same chance to be picked by any person. So you could throw a dice with &lt;code&gt;p&lt;/code&gt; surfaces for each king. You get a sequence of &lt;code&gt;k&lt;/code&gt; numbers, say &lt;code&gt;n(1)...n(k)&lt;/code&gt;, each with value &lt;code&gt;1..p&lt;/code&gt;. The interpretation of this is that person &lt;code&gt;n(i)&lt;/code&gt; has picked the king from the &lt;code&gt;i&lt;/code&gt;-th cake. So now we deal with possible combinations of &lt;code&gt;k&lt;/code&gt; digits, each having a value from &lt;code&gt;1..p&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;Since all persons and cakes are the same, each combination has the same probability.&lt;/p&gt;&lt;h2&gt;The question&lt;/h2&gt;&lt;p&gt;... is now how many combinations are there, where each &lt;code&gt;p&lt;/code&gt; is present at least once, meaning each person gets at least one king. The final probability is given by this value divided by the total number of combinations, which is &lt;code&gt;p^k&lt;/code&gt;. E.g. when &lt;code&gt;p=2, k=4&lt;/code&gt;, we have 4 bits and can represent &lt;code&gt;2^4 = 16&lt;/code&gt; different numbers.&lt;/p&gt;&lt;h2&gt;An example&lt;/h2&gt;&lt;p&gt;Choose &lt;code&gt;k=2, p=2&lt;/code&gt;. The combinations are:&lt;pre&gt;&lt;br /&gt;1 1&lt;br /&gt;1 2&lt;br /&gt;2 1&lt;br /&gt;2 2&lt;br /&gt;&lt;/pre&gt;The first and the last are not valid, both kings go to the same person and the other one gets none. So we have a probability of &lt;code&gt;2/4 = 50%&lt;/code&gt; that each person gets at least one king.&lt;/p&gt;&lt;p&gt;Choose &lt;code&gt;k=4, p=3&lt;/code&gt;. Then the list of combinations is:&lt;pre&gt;&lt;br /&gt;1 1 1 1&lt;br /&gt;1 1 1 2&lt;br /&gt;1 1 1 3&lt;br /&gt;1 1 2 1&lt;br /&gt;1 1 2 2&lt;br /&gt;...&lt;br /&gt;3 3 2 3&lt;br /&gt;3 3 3 1&lt;br /&gt;3 3 3 2&lt;br /&gt;3 3 3 3&lt;br /&gt;&lt;/pre&gt;A total of &lt;code&gt;3^4 = 81&lt;/code&gt; combinations. As you can see it gets more complicated to write down all possibilities, so we are looking for a more abstract approach.&lt;/p&gt;&lt;p&gt;You could either try to find a formula for all valid combinations directly by finding all that have each &lt;code&gt;p=1..3&lt;/code&gt; occurring at least once, or you compute the inverse, the invalid ones, which are all combinations that have at least one &lt;code&gt;p&lt;/code&gt; missing, and subtract it from the total count. An invalid combination would be &lt;code&gt;1 2 1 1&lt;/code&gt; since &lt;code&gt;3&lt;/code&gt; is not present which means person 3 gets no king. &lt;code&gt;1 2 3 x&lt;/code&gt; is valid for each &lt;code&gt;x&lt;/code&gt; since every &lt;code&gt;p&lt;/code&gt; is present.&lt;/p&gt;&lt;p&gt;I chose the second way. I found it easier to think with, but maybe the first works as well. The invalid combinations are those that either lack a &lt;code&gt;1&lt;/code&gt;, &lt;code&gt;2&lt;/code&gt; or &lt;code&gt;3&lt;/code&gt;, let us call them &lt;code&gt;m1, m2, m3&lt;/code&gt;. Each &lt;code&gt;m&lt;/code&gt; has &lt;code&gt;(3-1)^4 = 16&lt;/code&gt; combinations. We could sum them up if they were disjoint. For example, &lt;code&gt;3 3 3 3&lt;/code&gt; is counted twice, once in &lt;code&gt;m1&lt;/code&gt; and a second time in &lt;code&gt;m2&lt;/code&gt;. So we have to subtract again all combinations that we counted twice. That is, combinations which are in two of &lt;code&gt;m1, m2, m3&lt;/code&gt;. Let us call these possible sets &lt;code&gt;m12, m23, m13&lt;/code&gt;. E.g. &lt;code&gt;m12&lt;/code&gt; is missing &lt;code&gt;1&lt;/code&gt; and &lt;code&gt;2&lt;/code&gt;. There is actually only one combination for that: &lt;code&gt;3 3 3 3&lt;/code&gt;. &lt;code&gt;m12, m23, m13&lt;/code&gt; are disjoint, so we did not again count too much and are almost finished. The total amount of invalid combinations is then &lt;code&gt;m1 + m2 + m3 - m12 - m23 - m13 = 3*(3-1)^4-3*(3-2)^4 = 45&lt;/code&gt;. And the final probability is &lt;code&gt;(81-45)/81 = 36/81 = 4/9 ~ 44%&lt;/code&gt;.&lt;/p&gt;&lt;h2&gt;Generic solution&lt;/h2&gt;&lt;p&gt;The tricky part is to count &lt;code&gt;m1, m2, ... mX&lt;/code&gt;. Since they are not disjoint, you can not simple sum them up, but have to compute the union. For that you need to know all the possible intersections between the sets. But luckily mankind has &lt;a href="http://en.wikipedia.org/wiki/Inclusion%E2%80%93exclusion_principle"&gt;solved this before&lt;/a&gt; , and I could not explain it better. In short, to compute the union between a number of sets, you add all possible intersections between an odd number of the sets, and subtract all possible intersections between an even number of the sets. You also make use of combinatorics and the binomial coefficient. In our case &lt;code&gt;A1 &amp;cap; ... &amp;cap; An&lt;/code&gt; means all combinations that are missing all of the digits &lt;code&gt;1..i&lt;/code&gt;. There are &lt;code&gt;(p low n)&lt;/code&gt; such intersections and each counts &lt;code&gt;(p-n)^k&lt;/code&gt; elements. So our final formula is:&lt;pre&gt;&lt;br /&gt;sum((-1)^(n+1) * (p low n) * (p-n)^k), n=1..p&lt;br /&gt;&lt;/pre&gt;And this would be the nice graph for it if Mathematica did plot it:&lt;pre&gt;&lt;br /&gt;&lt;a href="http://www.wolframalpha.com/input/?i=plot+sum[power[-1%2Cn%2B1]*binomial[p%2Cn]*power[p-n%2Ck]%2C{n%2C1%2Cp}]%2C+p%3D1..10+and+k%3D1..10"&gt;plot sum[power[-1,n+1]*binomial[p,n]*power[p-n,k],{n,1,p}], p=1..10 and k=1..10&lt;/a&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/p&gt;&lt;p&gt;The final result is:&lt;pre&gt;&lt;br /&gt;(p^k - sum((-1)^(n+1) * (p low n) * (p-n)^k)) / p^k, n=1..p&lt;br /&gt;&lt;/pre&gt;&lt;/p&gt;&lt;h2&gt;A question for you&lt;/h2&gt;&lt;p&gt;Is it possible to construct a fair dice for all &lt;code&gt;n&lt;/code&gt;?&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/759829123710334956-1566494626846614342?l=anselm-strauss.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://anselm-strauss.blogspot.com/feeds/1566494626846614342/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://anselm-strauss.blogspot.com/2011/02/of-king-cakes-and-dices.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/759829123710334956/posts/default/1566494626846614342'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/759829123710334956/posts/default/1566494626846614342'/><link rel='alternate' type='text/html' href='http://anselm-strauss.blogspot.com/2011/02/of-king-cakes-and-dices.html' title='Of King Cakes and Dices'/><author><name>anselm</name><uri>http://www.blogger.com/profile/12439016778981424132</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://3.bp.blogspot.com/_Yy4WDeOpVdM/TRo6zkow78I/AAAAAAAAAPk/r49QCStzciU/S220/anselm-strauss-posterized.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-759829123710334956.post-6421713037558820425</id><published>2011-02-04T00:07:00.001+01:00</published><updated>2011-02-04T00:22:54.483+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='fun'/><category scheme='http://www.blogger.com/atom/ns#' term='microwave'/><title type='text'>The Microwave Trap</title><content type='html'>&lt;blockquote&gt;&lt;p&gt;&lt;em&gt;"Sometimes you have to shock your audience with something brilliantly primitive, only to be able to hit them really hard when you make your next creative punch."&lt;/em&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;&amp;ndash; From &lt;em&gt;Voices in your head&lt;/em&gt; by A. Strauss on February 3, 2011 &amp;ndash;&lt;/p&gt;&lt;p&gt;Maybe, but I think most people still just do it for gaining attention.&lt;/p&gt;&lt;p&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_Yy4WDeOpVdM/TUsujyoCEhI/AAAAAAAAAQg/IH24AQRKLZ4/s1600/microwave-trap.gif" imageanchor="1" style="margin-left:1em; margin-right:1em"&gt;&lt;img border="0" height="400" width="120" src="http://3.bp.blogspot.com/_Yy4WDeOpVdM/TUsujyoCEhI/AAAAAAAAAQg/IH24AQRKLZ4/s400/microwave-trap.gif" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/759829123710334956-6421713037558820425?l=anselm-strauss.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://anselm-strauss.blogspot.com/feeds/6421713037558820425/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://anselm-strauss.blogspot.com/2011/02/microwave-trap.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/759829123710334956/posts/default/6421713037558820425'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/759829123710334956/posts/default/6421713037558820425'/><link rel='alternate' type='text/html' href='http://anselm-strauss.blogspot.com/2011/02/microwave-trap.html' title='The Microwave Trap'/><author><name>anselm</name><uri>http://www.blogger.com/profile/12439016778981424132</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://3.bp.blogspot.com/_Yy4WDeOpVdM/TRo6zkow78I/AAAAAAAAAPk/r49QCStzciU/S220/anselm-strauss-posterized.png'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_Yy4WDeOpVdM/TUsujyoCEhI/AAAAAAAAAQg/IH24AQRKLZ4/s72-c/microwave-trap.gif' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-759829123710334956.post-3220405467589798035</id><published>2010-12-31T17:26:00.000+01:00</published><updated>2010-12-31T17:26:34.441+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='photography'/><category scheme='http://www.blogger.com/atom/ns#' term='tagging'/><category scheme='http://www.blogger.com/atom/ns#' term='digikam'/><category scheme='http://www.blogger.com/atom/ns#' term='iphoto'/><category scheme='http://www.blogger.com/atom/ns#' term='f-spot'/><category scheme='http://www.blogger.com/atom/ns#' term='shotwell'/><category scheme='http://www.blogger.com/atom/ns#' term='aperture'/><title type='text'>Tags used the wrong way</title><content type='html'>&lt;p&gt;In general I do not regret my switch from Mac OS X to FreeBSD/Linux. But when it comes to managing my pictures I have to say that I miss iPhoto and Aperture. And this not for the fancy features like face recognition or all the beautiful GUI stuff, but for a very basic one, and that is &lt;emph&gt;organizing pictures&lt;/emph&gt;.&lt;/p&gt;&lt;h3&gt;Low-level&lt;/h3&gt;&lt;p&gt;On Mac I started with &lt;a href="http://www.apple.com/ilife/iphoto"&gt;iPhoto&lt;/a&gt; and then switched to &lt;a href="http://www.apple.com/aperture"&gt;Aperture&lt;/a&gt;. Now I stay with &lt;a href="http://www.f-spot.org"&gt;F-Spot&lt;/a&gt;, I also looked at &lt;a href="http://www.digikam.com"&gt;Digikam&lt;/a&gt; and &lt;a href="http://www.yorba.org/shotwell"&gt;Shotwell&lt;/a&gt;, but I do not see any real advantages over F-Spot right now.&lt;/p&gt;&lt;p&gt;All programs allow you to either copy your pictures to an internal database or just reference them in your own filesystem layout. While the library format of iPhoto and Aperture is rather complicated and somewhat proprietary, the open-source programs do it a lot simpler. F-Spot and Shotwell just create a fixed folder structure by date for year, month and day to organize the pictures. In F-Spot you have a low level folder view, while in Shotwell you never see that structure directly. Digikam allows you to manage the folders from within the program and change the structure.&lt;/p&gt;&lt;p&gt;When it comes to metadata all programs in recent versions allow you to choose between storing tags, captions, and other data inside the original pictures or in their internal database. When switching between different photo management software storing the metadata inside the pictures is the only way to migrate. The internal formats are not compatible between programs.&lt;/p&gt;&lt;h3&gt;Tags are not enough&lt;/h3&gt;&lt;p&gt;Where iPhoto and Aperture allow you to create arbitrary folder structures with virtual albums and assign each picture to any number of albums, the other programs clearly lack some basic functionality. Shotwell has, like iPhoto, an event based primary organization of pictures. But each picture can only be in exactly one event. And the folder hierarchy has a fixed structure. Beyond that all open-source programs rely on the concept of tags to do further grouping of pictures.&lt;/p&gt;&lt;p&gt;So what is the problem with tags? Well, they are not intended for building hierarchies, but all open-source programs use them for exactly that. The tag field in the metadata is just a set of strings with no relations to each other. For example, if you create the tags &lt;code&gt;/Subject/Animals&lt;/code&gt; and &lt;code&gt;/Testing/Animals&lt;/code&gt; it will just assign the tag &lt;code&gt;Animals&lt;/code&gt; to the picture. Or maybe &lt;code&gt;Subject, Animals, Testing&lt;/code&gt; since it is not clear if parent tags should also be assigned. Parent tags and child tags can both be assigned, whereas for example in filesystems there is a distinction between folders for building the hierarchy and files that contain the actual content. In the case of tags, the hierarchy can not be rebuild from the tags, so it is stored in the internal data of the software and lost when only taking the picture metadata. Moreover you might get a conflict for using the same tag twice in different hierarchies because a tag without hierarchy can only exist once.&lt;/p&gt;&lt;p&gt;One could try and use a special encoding to store the full hierarchy of a tag, but since there is no standard for this I doubt it would really help. Shotwell currently abandons hierarchical tags completely, while F-Spot and Digikam try to implement them with some issues.&lt;/p&gt;&lt;h3&gt;Conclusion&lt;/h3&gt;&lt;p&gt;While this is an old hat for filesystems with symbolic/hard links, where everybody agrees that multiple different folder structures are needed to navigate to the same file, this does not seem to be solved in the world of photography management software. While Apple has a solid solution in my eyes, it is of course (again) their very own way, and not exportable. But part of the blame also goes to the lack of a meta data standard for this. The open-source world tries to rely on an open protocol and uses tags. But since tags are not really intended for the job some drawbacks and issues result.&lt;/p&gt;&lt;p&gt;The discussion on &lt;emph&gt;hierarchical tags&lt;/emph&gt; is on, may there be a solution soon!&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/759829123710334956-3220405467589798035?l=anselm-strauss.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://anselm-strauss.blogspot.com/feeds/3220405467589798035/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://anselm-strauss.blogspot.com/2010/12/tags-used-wrong-way.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/759829123710334956/posts/default/3220405467589798035'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/759829123710334956/posts/default/3220405467589798035'/><link rel='alternate' type='text/html' href='http://anselm-strauss.blogspot.com/2010/12/tags-used-wrong-way.html' title='Tags used the wrong way'/><author><name>anselm</name><uri>http://www.blogger.com/profile/12439016778981424132</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://3.bp.blogspot.com/_Yy4WDeOpVdM/TRo6zkow78I/AAAAAAAAAPk/r49QCStzciU/S220/anselm-strauss-posterized.png'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-759829123710334956.post-3791428793612746026</id><published>2010-10-28T19:13:00.001+02:00</published><updated>2010-10-30T13:23:37.309+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='bash'/><category scheme='http://www.blogger.com/atom/ns#' term='whining'/><category scheme='http://www.blogger.com/atom/ns#' term='shell'/><title type='text'>About those bash profiles</title><content type='html'>&lt;h3&gt;Which profile?&lt;/h3&gt;&lt;p&gt;It seems like a common fact to me that most people (including myself) get stuck when having to choose the right profile file in bash to add customizations. While there is actually a comprehensive manual that explains everything, I never found it clear enough, because I kept re-opening it reading the same sections over and over again. So once upon a time I took the courage trying to solve this quest. I started to hack and what came out is indeed not the simplest way of initializing a shell ...&lt;/p&gt;&lt;p&gt;My wish was actually simple. For each setting (like an environment variable or function definition) I wanted to be able to specify exactly for what type or types of shells it should be set. And additionally I wanted to set those settings either system-wide or per user.&lt;/p&gt;&lt;h3&gt;Shell types&lt;/h3&gt;&lt;p&gt;The type of a bash shell is determined by 3 boolean properties. A bash can be interactive, it can be a login shell and it can be a subshell of an existing one. The last property is not particularly interesting for now, I will use it later on when deciding whether a setting should be initialized only once or repeatedly for every subshell. This leaves us with 2 properties, that, if combined, give 4 different shell types:&lt;ol&gt;&lt;li&gt;Interactive login shell&lt;/li&gt;&lt;li&gt;Non-interactive login shell&lt;/li&gt;&lt;li&gt;Interactive shell&lt;/li&gt;&lt;li&gt;Non-interactive shell&lt;/li&gt;&lt;/ol&gt;To make it more clear, an example for each type:&lt;ol&gt;&lt;li&gt;&lt;code&gt;ssh localhost&lt;/code&gt;&lt;/li&gt;&lt;li&gt;&lt;code&gt;ssh localhost &amp;lt;command&amp;gt;&lt;/code&gt;&lt;/li&gt;&lt;li&gt;&lt;code&gt;bash&lt;/code&gt;&lt;/li&gt;&lt;li&gt;&lt;code&gt;bash -c &amp;lt;command&amp;gt;&lt;/code&gt;&lt;/li&gt;&lt;/ol&gt;A interactive login shell is what you get when you login with SSH on a remote host. From there you will mostly start subshells that are either interactive or not. If you give SSH a shell command as argument it will login, execute the command, and exit again, without giving you an interactive prompt. So that is a non-interactive login shell. Each type sources certain profile files upon initialization:&lt;ol&gt;&lt;li&gt;&lt;code&gt;/etc/profile, ~/.bash_profile&lt;/code&gt;&lt;/li&gt;&lt;li&gt;(same)&lt;/li&gt;&lt;li&gt;&lt;code&gt;~/.bashrc&lt;/code&gt;&lt;/li&gt;&lt;li&gt;File defined in &lt;code&gt;$BASH_ENV&lt;/code&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/p&gt;&lt;h3&gt;Initializing the shell&lt;/h3&gt;&lt;p&gt;I want to have a global system folder &lt;code&gt;/usr/local/etc/bash/profiles/&lt;/code&gt; and a per-user folder &lt;code&gt;~/.bash_profiles/&lt;/code&gt; where I can put profile files and bash will source them automatically. Per user settings should overwrite global ones and within each profile I can choose what shell type it will apply for. To do this I first configure &lt;code&gt;.bashrc&lt;/code&gt; and &lt;code&gt;.bash_profile&lt;/code&gt;. I simply set the variables &lt;code&gt;$BASH_LOGIN&lt;/code&gt; and &lt;code&gt;$BASH_INTERACTIVE&lt;/code&gt; to either true or false depending on the shell type.&lt;/p&gt;&lt;p&gt;For &lt;code&gt;.bashrc&lt;/code&gt; this is easy since it is only sourced by interactive shells that are not login shells:&lt;code&gt;&lt;pre&gt;&lt;br /&gt;BASH_INTERACTIVE=true&lt;br /&gt;BASH_LOGIN=false&lt;br /&gt;&lt;br /&gt;~/.bash/init&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;In &lt;code&gt;.bash_profile&lt;/code&gt; I have to distinguish between interactive and non-interactive login shells. This can be done by looking at &lt;code&gt;$-&lt;/code&gt;.&lt;code&gt;&lt;pre&gt;&lt;br /&gt;BASH_LOGIN=true&lt;br /&gt;&lt;br /&gt;if [[ $- = *i* ]]; then&lt;br /&gt;  BASH_INTERACTIVE=true&lt;br /&gt;else&lt;br /&gt;  BASH_INTERACTIVE=false&lt;br /&gt;fi&lt;br /&gt;&lt;br /&gt;. ~/.bash/init&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;/p&gt;&lt;p&gt;From both files I call a global initialization file that will look for profile files and source them. Inside each profile I can then choose if I want to apply the settings depending on &lt;code&gt;$BASH_LOGIN&lt;/code&gt; and &lt;code&gt;$BASH_INTERACTIVE&lt;/code&gt;. The common &lt;code&gt;init&lt;/code&gt; looks like this:&lt;code&gt;&lt;pre&gt;&lt;br /&gt;for profile in ~/.bash/profiles/* ~/.bash_profiles/*; do&lt;br /&gt;  if [ -f $profile ]; then&lt;br /&gt;    if [[ "$BASH_PROFILES" = "*$profile*" ]]; then&lt;br /&gt;      BASH_SOURCED=true&lt;br /&gt;    else&lt;br /&gt;      BASH_SOURCED=false&lt;br /&gt;    fi&lt;br /&gt;    . $profile &amp;&amp; \&lt;br /&gt;      export BASH_PROFILES="${BASH_PROFILES}${profile} "&lt;br /&gt;  fi&lt;br /&gt;done&lt;br /&gt;unset profile BASH_SOURCED&lt;br /&gt;&lt;br /&gt;BASH_ENV="~/.bash/bash_env"&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;There are two more things here to explain. First, I record successfully sourced profiles in &lt;code&gt;$BASH_PROFILES&lt;/code&gt; and set &lt;code&gt;$BASH_SOURCED&lt;/code&gt; to true if the profile has already been sourced. So optionally I can cause profiles to not get sourced again in a sub-shell. This is handy for exported variables that you do not want to overwrite if the user changed the value and exported it from an initial shell. Second, I set &lt;code&gt;$BASH_ENV&lt;/code&gt; globally in &lt;code&gt;init&lt;/code&gt;, so it is set for every shell. This is for non-interactive non-login shells. Unfortunately bash does not source any files for this type directly, but instead the file specified by this variable. In my case &lt;code&gt;bash_env&lt;/code&gt; looks simply like this:&lt;code&gt;&lt;pre&gt;&lt;br /&gt;BASH_LOGIN=false&lt;br /&gt;BASH_INTERACTIVE=false&lt;br /&gt;&lt;br /&gt;. ~/.bash/init&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;/p&gt;&lt;h3&gt;Logging out&lt;/h3&gt;&lt;p&gt;Here the process is much more simple. Bash does only source one file &lt;code&gt;.bash_logout&lt;/code&gt; and only if a login shell exits. Also, it does not make sense to setup anything on logout and the settings will not be passed on. So I simply check if it is a interactive shell and source profiles from a separate logout directory:&lt;code&gt;&lt;pre&gt;&lt;br /&gt;if [[ $- = *i* ]]; then&lt;br /&gt;  BASH_INTERACTIVE=true&lt;br /&gt;else&lt;br /&gt;  BASH_INTERACTIVE=false&lt;br /&gt;fi&lt;br /&gt;&lt;br /&gt;for profile in ~/.bash/profiles/logout/* \&lt;br /&gt;~/.bash_profiles/logout/*; do&lt;br /&gt;  if [ -f $profile ]; then&lt;br /&gt;    . $profile&lt;br /&gt;  fi&lt;br /&gt;done&lt;br /&gt;unset profile&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;/p&gt;&lt;h3&gt;Skeleton&lt;/h3&gt;&lt;p&gt;Finally I want to put these files into a global folder and only link from my user home to them. On my FreeBSD boxes I put them in &lt;code&gt;/usr/local/etc/bash/&lt;/code&gt; and create a set of skeleton symbolic links in &lt;code&gt;/usr/local/etc/bash/skel/&lt;/code&gt; that every user can copy to his home:&lt;code&gt;&lt;pre&gt;&lt;br /&gt;/usr/local/etc/bash/:&lt;br /&gt;&lt;br /&gt;bash_env&lt;br /&gt;bash_logout&lt;br /&gt;bash_profile&lt;br /&gt;bashrc&lt;br /&gt;init&lt;br /&gt;profiles&lt;br /&gt;skel&lt;br /&gt;&lt;br /&gt;/usr/local/etc/bash/skel/:&lt;br /&gt;&lt;br /&gt;.bash -&gt; /usr/local/etc/bash&lt;br /&gt;.bash_logout -&gt; .bash/bash_logout&lt;br /&gt;.bash_profile -&gt; .bash/bash_profile&lt;br /&gt;.bashrc -&gt; .bash/bashrc&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;/p&gt;&lt;h3&gt;Examples&lt;/h3&gt;&lt;p&gt;tmux is a text window manager similar to screen. I like to see any open sessions upon login, but do not want get the list on every sub shell I start or when the shell is not interactive. &lt;code&gt;/usr/local/etc/bash/profiles/tmux-list&lt;/code&gt;:&lt;code&gt;&lt;pre&gt;&lt;br /&gt;$BASH_INTERACTIVE || return 1&lt;br /&gt;$BASH_LOGIN || return 1&lt;br /&gt;&lt;br /&gt;if which -s tmux; then&lt;br /&gt;  echo "Open sessions:"&lt;br /&gt;  tmux list-sessions 2&gt; /dev/null || true&lt;br /&gt;fi&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;Environment variables usually only need to be set once at login when they are exported. &lt;code&gt;/usr/local/etc/bash/profiles/default-login&lt;/code&gt;:&lt;code&gt;&lt;pre&gt;&lt;br /&gt;$BASH_LOGIN || return 1&lt;br /&gt;$BASH_SOURCED &amp;&amp; return 1&lt;br /&gt;&lt;br /&gt;export PATH="$PATH:~/bin"&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;With functions and aliases it is different. Bash does not pass them to subshells, so they need to be sourced again and again. &lt;code&gt;/usr/local/etc/bash/profiles/alias-functions&lt;/code&gt;:&lt;code&gt;&lt;pre&gt;&lt;br /&gt;$BASH_INTERACTIVE || return 1&lt;br /&gt;&lt;br /&gt;function savealias() {&lt;br /&gt;  echo "!!! This command is aliased for safety reasons." &gt;&amp;2&lt;br /&gt;  echo "!!! If you are serious use `type -P $1`." &gt;&amp;2&lt;br /&gt;  return 1&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;function ask() {&lt;br /&gt;  echo -n "Enter 'y' to proceed: "&lt;br /&gt;  read answer&lt;br /&gt;  [ "$answer" = 'y' ] &amp;&amp; return 0&lt;br /&gt;  return 1&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;alias shutdown="savealias shutdown"&lt;br /&gt;alias halt="savealias halt"&lt;br /&gt;alias reboot="ask &amp;&amp; /sbin/shutdown -r now"&lt;br /&gt;alias init="savealias init"&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;/p&gt;&lt;h3&gt;Whining comment&lt;/h3&gt;&lt;p&gt;Maybe I should write a patch for bash entitled "Proper profile initialization", I just can not decide if I should call it a feature or bug report ...&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/759829123710334956-3791428793612746026?l=anselm-strauss.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://anselm-strauss.blogspot.com/feeds/3791428793612746026/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://anselm-strauss.blogspot.com/2010/10/about-those-bash-profiles.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/759829123710334956/posts/default/3791428793612746026'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/759829123710334956/posts/default/3791428793612746026'/><link rel='alternate' type='text/html' href='http://anselm-strauss.blogspot.com/2010/10/about-those-bash-profiles.html' title='About those bash profiles'/><author><name>anselm</name><uri>http://www.blogger.com/profile/12439016778981424132</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://3.bp.blogspot.com/_Yy4WDeOpVdM/TRo6zkow78I/AAAAAAAAAPk/r49QCStzciU/S220/anselm-strauss-posterized.png'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-759829123710334956.post-3024075848156266320</id><published>2010-09-24T16:52:00.000+02:00</published><updated>2010-09-24T16:52:57.225+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='wish'/><category scheme='http://www.blogger.com/atom/ns#' term='filesystem'/><category scheme='http://www.blogger.com/atom/ns#' term='zfs'/><category scheme='http://www.blogger.com/atom/ns#' term='lvm'/><title type='text'>ZFS Wishlist</title><content type='html'>&lt;h4&gt;Create a new data set from existing data online&lt;/h4&gt;&lt;p&gt;Often I start with one data set per pool and when the system evolves I create more and more data sets as needed. First I mount the new data set on a temporary path, move all data, then remove the old directory and remount the new data set to its designated path. The downside is that I can not really do this online, since a move does mostly not work for open files. Also the data must effectively be copied which can take some time.On a first thought it would be nice if there was one command that directly converts an existing folder into a new data set. On second thought, why does ZFS actually need to copy anything? Can it not just relink all znodes to the new data set? But I guess it has also something to do with the concept of mounting. How can you change an open file from one mount point to another ...&lt;/p&gt;&lt;h4&gt;Control over data allocation on vdevs&lt;/h4&gt;&lt;p&gt;This is something that I always liked in LVM, but somehow also made it more complicated and maybe more error prone compared to ZFS. In LVM you can exactly specify which physical extents are allocated to what logical volume. While in ZFS it is possible for example to replace single disks through the RAID algorithm or add vdevs to a pool, it automatically allocates extents to data sets and this can not be changed manually. And why should you have to make a new pool just to be able to control which data lies on what vdev? Having more that one pool always costs you some flexibility. Moving or splitting up data between pools always causes problems.A related topic is dynamically changing a RAID. One not so far reached example is to extend a mirror with additional disks to a RAIDZ for more capacity. Or to shrink a pool.Another interesting idea is the use of different tiers within a pool. There could for example be one vdev with large but slow SATA disks, and a second with small but fast SSDs. The database should lie on the fast tier, while the software repository mirror is better suited for the large capacity tier.&lt;/p&gt;&lt;h4&gt;Integration of additional layers&lt;/h4&gt;&lt;p&gt;One functionality that has always been present is the possibility to create a block device instead of a data set. It is basically a data set without the ZFS filesystem layer. The volume can then be formatted with an arbitrary filestem type. That is what is mostly done for swap.But no need to stop here. There are two examples where work is already underway. One is the integration of a database layer, so the database server directly uses ZFS. After all, is it really ideal to create a file in the filesystem (which also is a simple form of a database) and then in this file create a MySQL database, actually making a database within a database?The other example is network. In Lustre 3.0 it should be possible to use ZFS as backend. So speaking more clearly, the data you put on the network mount is distributed with Lustre to multiple servers that store it directly to their ZFS pool.&lt;/p&gt;&lt;h4&gt;Update data on properties change&lt;/h4&gt;&lt;p&gt;Like a defragmentation or RAID rebuild that runs in the background it would be nice to have the option to apply property changes to existing data. I am thinking of the case where a pool runs out of space. Then you enable compression for a data set, let it run in the background and with time some space gets free again.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/759829123710334956-3024075848156266320?l=anselm-strauss.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://anselm-strauss.blogspot.com/feeds/3024075848156266320/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://anselm-strauss.blogspot.com/2010/09/zfs-wishlist.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/759829123710334956/posts/default/3024075848156266320'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/759829123710334956/posts/default/3024075848156266320'/><link rel='alternate' type='text/html' href='http://anselm-strauss.blogspot.com/2010/09/zfs-wishlist.html' title='ZFS Wishlist'/><author><name>anselm</name><uri>http://www.blogger.com/profile/12439016778981424132</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://3.bp.blogspot.com/_Yy4WDeOpVdM/TRo6zkow78I/AAAAAAAAAPk/r49QCStzciU/S220/anselm-strauss-posterized.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-759829123710334956.post-4988524942223205826</id><published>2010-06-29T17:38:00.003+02:00</published><updated>2010-06-29T17:39:14.603+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='vim'/><category scheme='http://www.blogger.com/atom/ns#' term='text'/><category scheme='http://www.blogger.com/atom/ns#' term='newline'/><title type='text'>VIM's Hidden Newline</title><content type='html'>&lt;p&gt;At some point in your daily life with the ubiquitous development environment &lt;em&gt;VIM&lt;/em&gt;, you might face an advanced data structure called &lt;em&gt;text file&lt;/em&gt;, an integral part of an enterprise database system called &lt;em&gt;filesystem&lt;/em&gt;. And as you start to play with newlines you might wonder why the following is:&lt;pre&gt;&lt;br /&gt;$ vim vim-file&lt;br /&gt;$ echo -n "echo-line" &gt; echo-file&lt;br /&gt;$ cat echo-file vim-file&lt;br /&gt;echo-linevim-line&lt;br /&gt;$ cat vim-file echo-file&lt;br /&gt;vim-line&lt;br /&gt;echo-line$&lt;br /&gt;&lt;/pre&gt;&lt;code&gt;echo&lt;/code&gt; produces no newline as expected, but VIM does. Although the file just contains the content&lt;pre&gt;&lt;br /&gt;vim-line&lt;br /&gt;~&lt;br /&gt;&lt;/pre&gt;with no explicit newline, &lt;code&gt;cat&lt;/code&gt; still prints one. And indeed there is one as the hex dump shows:&lt;pre&gt;&lt;br /&gt;$ xxd vim &lt;br /&gt;0000000: 7669 6d0a                                vim.&lt;br /&gt;&lt;/pre&gt;The final dot after the characters &lt;code&gt;vim&lt;/code&gt; shows it. In my case it was not that obvious what files originated from VIM and which did not. Unfortunately you do not see a difference between the two files in &lt;code&gt;less&lt;/code&gt;, and VIM will only give a hint when the final newline is missing and automatically correct in when writing the file. But in the main display it is &lt;em&gt;hidden&lt;/em&gt;. &lt;/p&gt;&lt;p&gt;To avoid the final newline, VIM knows the &lt;code&gt;binary&lt;/code&gt; and &lt;code&gt;eol&lt;/code&gt; options that can be used together to prevent VIM from writing the final newline. But be advised that in general you are safer when using it in Unix text files.&lt;/p&gt;&lt;p&gt;Maybe one day we might get past these teething troubles and start spending our hacking time on some user-friendly systems. But since &lt;cite&gt;the computer revolution has not happened yet&lt;/cite&gt; I guess we just have to wait a little longer.&lt;/p&gt;&lt;p&gt;P.S. It is a shame I could not make any link to ZFS this time. So be it! For this post ...&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/759829123710334956-4988524942223205826?l=anselm-strauss.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://anselm-strauss.blogspot.com/feeds/4988524942223205826/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://anselm-strauss.blogspot.com/2010/06/vims-hidden-newline.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/759829123710334956/posts/default/4988524942223205826'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/759829123710334956/posts/default/4988524942223205826'/><link rel='alternate' type='text/html' href='http://anselm-strauss.blogspot.com/2010/06/vims-hidden-newline.html' title='VIM&apos;s Hidden Newline'/><author><name>anselm</name><uri>http://www.blogger.com/profile/12439016778981424132</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://3.bp.blogspot.com/_Yy4WDeOpVdM/TRo6zkow78I/AAAAAAAAAPk/r49QCStzciU/S220/anselm-strauss-posterized.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-759829123710334956.post-6307727960851558760</id><published>2010-06-24T20:41:00.000+02:00</published><updated>2010-06-24T20:41:28.733+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='zfs'/><category scheme='http://www.blogger.com/atom/ns#' term='lvm'/><category scheme='http://www.blogger.com/atom/ns#' term='vmware'/><category scheme='http://www.blogger.com/atom/ns#' term='storage'/><category scheme='http://www.blogger.com/atom/ns#' term='san'/><title type='text'>A Storage Nightmare</title><content type='html'>&lt;p&gt;Recently, I faced the following storage setup for a virtual server, and instantly I got a headache from it:&lt;ol&gt;&lt;li&gt;An enterprise storage system that abstracts almost everything presents a simple SCSI device with a virtual LUN on the SAN.&lt;/li&gt;&lt;li&gt;VMWare binds the LUN and formats it with VMFS, its proprietary cluster filesystem.&lt;/li&gt;&lt;li&gt;Inside the VMFS one VMDK file is created that uses all the space.&lt;/li&gt;&lt;li&gt;The VMDK file is attached as virtual disk to the guest system.&lt;/li&gt;&lt;li&gt;Inside Linux, the disk is partitioned into one primary partition, which is formatted as an LVM physical volume. It belongs to one volume group, from which multiple logical volumes are created.&lt;/li&gt;&lt;li&gt;The logical volumes are formatted with ext3.&lt;/li&gt;&lt;/ol&gt;To summarize this setup: The data from the application goes over 2 filesystem layers (ext3, VMFS) and 3 virtualization layers (LVM, VMWare, storage system) until it finally reaches the disk.&lt;/p&gt;&lt;p&gt;As if this wasn't enough to cause a headache, I further discovered some special setups:&lt;ul&gt;&lt;li&gt;Multiple LUNs are aggregated to one device in VMWare to work around the maximum size limit of the storage system.&lt;/li&gt;&lt;li&gt;The Linux LVM layer stripes a logical volume over multiple LUNs, which are directly passed through by VMWare from the SAN. Apparently the intention was to use LUNs from different RAID groups in the storage system for performance increase.&lt;/li&gt;&lt;/ul&gt;&lt;/p&gt;&lt;p&gt;Consider a simple question like "This filesystem is too slow, which volume in the storage system do we have to move to a faster tier?". To answer it you might get yourself into quite some typing: Look up the device of the filesystem's mount point, map the logical volume to the right volume group, look up the physical volume for it, remember its LUN, in VMWare map the LUN to the right virtual disk, identify the VMFS where the disk's VMDK file lies, and finally look up the LUN for the VMFS. &lt;em&gt;Oh my!&lt;/em&gt;&lt;/p&gt;&lt;p&gt;The different layers in this setup surely have their reasons. The storage system hides the fact that you actually have a lot of small disks instead of a huge pool. It gives you reliability and flexibility when migrating and expanding your data volumes. Without the VMWare layer you loose snapshot functionality. But then again, snapshots are also something you find in the LVM layer. As you do with logical volume management. It is somehow present in both, the storage system and LVM. This redundancy between layers and the missing integration between them leads to really bad understanding and probably also bad performance, but I would not want to have to debug the latter.&lt;/p&gt;&lt;/p&gt;Another fundamental problem in this respect is the block layer. There are such things like adding a SCSI device on a running system. But all dynamic functions that go beyond this are implemented in layers on top of that. Wouldn't it be nice to e.g. implement dynamic resizing in the block layer? You just resize the volume in the SAN and instantly the system sees more space and adds it to the filesystem. No manual work is needed like adding a new disk in VMWare or extending the volume group with a new physical volume and growing the logical volume.&lt;/p&gt;&lt;p&gt;ZFS got the integration of layers right. Inside a pool you do not have a static partitioning that allocates blocks to a filesystem in the first place. Resizing volumes is merely a matter of setting quotas and reservations that are totally dynamic. But besides working in the direction of applications and integrating network filesystems like Lustre and databases into ZFS, it is also interesting to go into the other direction of integrating and enhancing the block layer. One way would be to integrate it better with existing SCSI and Fibrechannel protocols to better cooperate with existing SAN solutions. Yet a more interesting way would be to eliminate the classic SAN and let ZFS do all the work. What ZFS currently lacks is fine grained control over how data is arranged on disks. E.g. the definition of different tiers with different speeds and moving filesystems dynamically between them. And then there are all the pretty things that come with storage networks: multipathing, replication, server based RAIDs, clustering, et cetera, et cetera.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/759829123710334956-6307727960851558760?l=anselm-strauss.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://anselm-strauss.blogspot.com/feeds/6307727960851558760/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://anselm-strauss.blogspot.com/2010/06/storage-nightmare.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/759829123710334956/posts/default/6307727960851558760'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/759829123710334956/posts/default/6307727960851558760'/><link rel='alternate' type='text/html' href='http://anselm-strauss.blogspot.com/2010/06/storage-nightmare.html' title='A Storage Nightmare'/><author><name>anselm</name><uri>http://www.blogger.com/profile/12439016778981424132</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://3.bp.blogspot.com/_Yy4WDeOpVdM/TRo6zkow78I/AAAAAAAAAPk/r49QCStzciU/S220/anselm-strauss-posterized.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-759829123710334956.post-5976054865864908663</id><published>2010-05-12T23:41:00.002+02:00</published><updated>2010-05-12T23:41:45.689+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='extfs'/><category scheme='http://www.blogger.com/atom/ns#' term='filesystem'/><category scheme='http://www.blogger.com/atom/ns#' term='zfs'/><category scheme='http://www.blogger.com/atom/ns#' term='fsck'/><category scheme='http://www.blogger.com/atom/ns#' term='snapshot'/><title type='text'>Checking Extfs Online</title><content type='html'>&lt;p&gt;For years extfs has been a reliable, stable and well performing filesystem. But there has always been a weak point it its design for operation on long-running servers with lots of data. It is what manifests as the &lt;em&gt;mount count&lt;/em&gt;, or more precisely, the inability to check the filesystem online.&lt;/p&gt;&lt;p&gt;This is a real problem for servers with high uptime demands. The usual way is to reboot the machine (in case the filesystem is vital for system operation) or remount the filesystem from time to time, and when the mount count reaches its limit the filesystem is checked. But not only the reboots and remounts interrupt the servers operation and raise the service downtime. Also, the filesystem check must be completed before the filesystem can be mounted again. With terabytes of data a check can take multiple hours or even days to complete, depending on your disk layout. And if this catches you in the wrong moment, e.g. when the server crashed and you need it back online fast, this can be a real pain. The alternative is to disable this behavior by setting the mount count to 0. In this case no automatic checks are done, but which honest system administrator would claim to be able to regularly check all filesystems on all servers by hand.&lt;/p&gt;&lt;p&gt;With the recent growing use of ext4 as standard filesystem in Linux distributions I asked myself if this shortcoming still exists today. Luckily things have changed for the better, and not first with the introduction of ext4 but with the inclusion of the VFS lock patches for the 2.6 series of kernels. Ext4 still can not do it on its own, but with the help of LVM there is a way. What is a simple &lt;code&gt;fsck_ufs -B&lt;/code&gt; for the BSD user, and where the ZFS user only smiles at you and asks "What, you only check once a month? I do it all the time, it is called &lt;em&gt;checksums.&lt;/em&gt;", is not that simple for the Linux user. The trick is to put the extfs on top of an LVM and use snapshots. The extfs and LVM code in the kernel need to play together, so when you make a snapshot everything is properly locked and consistent. Then you can run fsck on the snapshot, while the original copy of the filesystem continues its operation. If fsck reports success you simply discard the snapshot again, and know everything is fine.&lt;/p&gt;&lt;p&gt;The ugly thing is that LVM snapshots are a bit fragile. When you create the snapshot you must specify the size. It is the amount of space that is reserved to write the changes that happen since you made the snapshot. You have to properly estimate it depending on how long you will need the snapshot and how much data will be modified meanwhile. This might not be an easy task, even for a sysadmin. If the snapshot runs out of space you risk to loose data.&lt;/p&gt;&lt;p&gt;So, it is possible but truly not a very solid solution. I have never seen a distribution that implements this by default, though this seems to me to be a very essential task. So, how do &lt;em&gt;you&lt;/em&gt; manage to check all your ext filesystems on your enterprise Linux servers that have hundreds of days of uptime ...?&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/759829123710334956-5976054865864908663?l=anselm-strauss.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://anselm-strauss.blogspot.com/feeds/5976054865864908663/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://anselm-strauss.blogspot.com/2010/05/checking-extfs-online.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/759829123710334956/posts/default/5976054865864908663'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/759829123710334956/posts/default/5976054865864908663'/><link rel='alternate' type='text/html' href='http://anselm-strauss.blogspot.com/2010/05/checking-extfs-online.html' title='Checking Extfs Online'/><author><name>anselm</name><uri>http://www.blogger.com/profile/12439016778981424132</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://3.bp.blogspot.com/_Yy4WDeOpVdM/TRo6zkow78I/AAAAAAAAAPk/r49QCStzciU/S220/anselm-strauss-posterized.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-759829123710334956.post-882857398939190572</id><published>2010-05-02T14:40:00.000+02:00</published><updated>2010-05-02T14:40:18.034+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='zenoss'/><category scheme='http://www.blogger.com/atom/ns#' term='monitoring'/><title type='text'>Zenoss</title><content type='html'>&lt;p&gt;I've spent quite some time now working with Zenoss, and looking at the shiny &lt;a href="http://www.zenoss.com"&gt;Zenoss homepage&lt;/a&gt; with all it's praising catch phrases I felt like I had to do some critics here. Well, sadly I have mostly bad critics, which makes me think once more how poorly integrated monitoring today still is. I apologize for not pointing out the good things of Zenoss, but I'm sure you'll find plenty of that elsewhere on the net. The information here is based on Zenoss Enterprise version 2.4.&lt;/p&gt;&lt;h4&gt;Appliance&lt;/h4&gt;&lt;p&gt;Zenoss provides a stack installer that includes everything you need from OpenSSL to MySQL. This saves you from dependency problems and version mismatches, but has some odd consequences. Integrating Zenoss with the rest of your software can be a pain. It always wants to access or start the internal MySQL server, but you may already have your perfect MySQL cluster where you want to put the Zenoss event data. Also, you have to &lt;code&gt;su&lt;/code&gt; to the zenoss user whenever you do some work on Zenoss, otherwise you don't have the right profile for all the executables and libraries. When debugging you have to take care to always test with the Zenoss versions of the programs, in some cases they do not exactly match the behavior of the versions included in your system. &lt;/p&gt;&lt;p&gt;The stack installer does its work, but lacks real integration into the system. Upgrades and De-installation clearly need a lot of manual work that could be avoided with a real package like an RPM. The fact that today Zenoss still doesn't put any effort in proper packaging brings up the question if Zenoss' design really is the fundamental problem of proper system integration, and if not, why are they persisting that much on this strategy?&lt;/p&gt;&lt;h4&gt;Distribution&lt;/h4&gt;&lt;p&gt;Zenoss supports distributed collectors, so you can split the load over multiple servers. But it involves a lot of network setup. It demands multiple open ports for connections in different directions. Encrypting the traffic has to be done on ones own with SSL. This is especially a problem in large and insecure networks, as it might often be the case in environments you need that type of monitoring. Unfortunately, computation load is not the only thing that is distributed in Zenoss. Data is split over 3 different databases. The configuration is stored in ZEO (a Zope Object Database), events go to a MySQL database and performance data is stored in RRD files on the filesystem. Only the first two are centralized and need to be accessible by every collector. RRD files are distributed (yes, again!) over all collectors, each one provides the files for the hosts it monitors. And of course if you want to see nice graphs in the web interface you need to access all collectors, more specifically you need a way to access the RRD files on all collectors from the server that serves the web interface. &lt;/p&gt;&lt;p&gt;This architecture not only makes Zenoss very hard to setup, but also requires a lot of work when you migrate something or are looking for errors.&lt;/p&gt;&lt;h4&gt;Memory&lt;/h4&gt;&lt;p&gt;Zenoss starts various different daemons for a collector. Each one runs in its own Python VM, so at startup it can easily consume 50-100MB of memory without doing any work yet. Additionally some processes tend to consume much more memory under load, 300-500MB for a single process is no exception. Finally, Zenoss seems to be a not so bad friend of memory leaks. I often caught processes using up to 2GB memory and after a restart the were happy with a fourth of that memory before leaking again after another week of duty. Be prepared that restarting the Zenoss stack can take quite some time and result in some alert events or gaps in the graphs. The choice for a dynamic and interpreted language really shows some of its downside in this aspect.&lt;/p&gt;&lt;h4&gt;Extensibility&lt;/h4&gt;&lt;p&gt;This is one of Zenoss' strengths. Unfortunately the ways in which you can extend it are diverse and can lead to a small chaos. Zenpacks give you so much freedom you can pack any file or database object into them. But there is absolutely no control whether the installed data still matches what was in the zenpack. Also, it gets very difficult to track back what things were installed by which package. Installing, upgrading and versioning is completely up to you. And of course you need to install the zenpacks on each distributed collector individually, or sync them in the web interface which copies files over SSH and restarts everything, but you still have to do it for each collector.&lt;/p&gt;&lt;p&gt;There are a lot of methods to gather data in Zenoss, it even has its own syslog daemon you can stream to. But the integration of various methods lacks the care for details in the implementation. SSH commands very often report as an error, even when the check did not really fail but just the command timed out. This happens because there is no clean distinction between a failed state and an unknown state, like Nagios has it. Also, it occured to me that hundreds of OIDs reported as error just because there was a problem reading data from an SNMP agent.&lt;/p&gt;&lt;h4&gt;Behind the scenes&lt;/h4&gt;&lt;p&gt;Rather than having to define every item you want to monitor, Zenoss brings a lot of mechanisms that automatically gather data, and it finds out things all by itself. The consequences can be bad performance until you notice that periodic port scans are not such a good idea in a network where the majority of ports are silently blocked by default. The concept of modeling devices, so that you don't have to gather certain data every time you do a check, is in some cases overused. E.g. the size of a filesystem is modeled, but it's usage is not. So if you grow a filesystem you can get an error of e.g. 110% full, or -10% free, until some hours later the device is remodeled and the filesystem size is adapted to the grown value.&lt;/p&gt;&lt;h4&gt;Security&lt;/h4&gt;&lt;p&gt;A monitoring server can easily become a concern of security. It is a central device that can access data from all other devices. Whereas for certain monitoring methods the risk might be in acceptable range, there are others like SSH, where the shell access makes a lot of room for possible exploits and is difficult to restrict. The most important thing here is to handle stored passwords and keys in a secure way. But in Zenoss I found various ways to retrieve passwords as non root and also as non Zenoss admin. One way is to execute predefined commands on devices which gives you e.g. the clear text SNMP password in the output log. Another way is to browse the Zope management interface behind Zenoss, that gives you a low level access to the data. A lot of this is also an issue of access management. &lt;/p&gt;&lt;p&gt;As already mentioned, other weaknesses include Zenoss' need for the root SSH password (although this seems to have changed in new versions). It's needed to automatically update software and distribute configuration to all collectors. Another problem is the operation in untrusted networks. Most daemons make unencrypted connections, leaving it up to you to wrap everything with SSL tunnels.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/759829123710334956-882857398939190572?l=anselm-strauss.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://anselm-strauss.blogspot.com/feeds/882857398939190572/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://anselm-strauss.blogspot.com/2010/05/zenoss.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/759829123710334956/posts/default/882857398939190572'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/759829123710334956/posts/default/882857398939190572'/><link rel='alternate' type='text/html' href='http://anselm-strauss.blogspot.com/2010/05/zenoss.html' title='Zenoss'/><author><name>anselm</name><uri>http://www.blogger.com/profile/12439016778981424132</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://3.bp.blogspot.com/_Yy4WDeOpVdM/TRo6zkow78I/AAAAAAAAAPk/r49QCStzciU/S220/anselm-strauss-posterized.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-759829123710334956.post-8752646970812093813</id><published>2010-04-11T15:55:00.002+02:00</published><updated>2010-04-11T16:06:09.049+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='smalltalk'/><title type='text'>The Why of Smalltalk</title><content type='html'>&lt;p&gt;I began to learn Smalltalk in an academic way on university. So I first valued its technical qualities like easy syntax, homogenous design, dynamic behavior, etc. The first questions I faced were when somebody, who didn't know Smalltalk yet, asked me why it is so good and what's so special about it. Of course I couldn't resist and had to praise Smalltalk to the skies. It was not before such discussions, that I was also asked why Smalltalk isn't really popular if it is that good, and I started to be interested in the history of Smalltalk and where it's real applications are.Today, there are tons of new languages, most of them stating that they were among others influenced by Smalltalk, so the usual versus debates keep coming up.&lt;/p&gt;&lt;p&gt;Over at &lt;a href="http://stackoverflow.com/"&gt;stackoverflow&lt;/a&gt; they posed some of these very essential questions and collected a lot of interesting answers:&lt;ol&gt;&lt;li&gt;&lt;a href="http://stackoverflow.com/questions/1821266/what-is-so-special-about-smalltalk"&gt;What is so special about Smalltalk?&lt;/a&gt;&lt;ul&gt;&lt;li&gt;&lt;cite&gt;The Smalltalk way isn't to crash out on unexpected behaviour - it's to adapt.&lt;/cite&gt;&lt;/li&gt;&lt;li&gt;&lt;cite&gt;Today, Smalltalk isn't particularly important on its own - there are some people still using it to write stuff, but it's definitely not mainstream. Learning it will give you some insight in how and why OOP evolved, however.&lt;/cite&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://stackoverflow.com/questions/515061/where-do-you-use-smalltalk"&gt;Where do you use Smalltalk?&lt;/a&gt;&lt;ul&gt;&lt;li&gt;&lt;cite&gt;Smalltalk's strengths play into it's weaknesses. It's not the language (dynamic vs static typing will always be a discussion point) as much as the development/deployment environment.&lt;/cite&gt;&lt;/li&gt;&lt;li&gt;&lt;cite&gt;... Smalltalk allowed me to develop and debug this system as people used it. I did not need to restart the system to install new features and bug fixes. If a user process crashed, the debugger would open on my monitor and I could debug it live. The user's terminal would restart automatically.&lt;/cite&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://stackoverflow.com/questions/711140/why-isnt-smalltalk-popular"&gt;Why isn’t Smalltalk popular?&lt;/a&gt;&lt;ul&gt;&lt;li&gt;&lt;cite&gt;When Smalltalk was introduced, it was too far ahead of its time in terms of what kind of hardware it really needed.&lt;/cite&gt;&lt;/li&gt;&lt;li&gt;&lt;cite&gt;... IBM took a look at it and figured two things. First they didn't want to enter a marketing war with Sun that was clearly planning to spend a fortune on the Java brand. ... Anyhow, I don't mind that Smalltalk isn't popular. That makes it a secret weapon for me and I am really encouraged to see all the new development projects. Smalltalk is growing and advancing again and this is good because a lot of the best ideas in software (XP, unit testing, refactoring editors, coding assistants) all were developed in Smalltalk first and then filtered out to the rest of the world (generally in diluted forms).&lt;/cite&gt;&lt;/li&gt;&lt;li&gt;&lt;cite&gt;Most of the Smalltalkers that I've run into on the net try to say how Smalltalk is basically the best thing since sliced bread, and how awful every other language is.&lt;/cite&gt;&lt;/li&gt;&lt;li&gt;&lt;cite&gt;Any language where the expression 2 + 3 * 4 has the value 20 isn't going to be a commercial success.&lt;/cite&gt;&lt;/li&gt;&lt;li&gt;&lt;cite&gt;There was freedom. Smalltalk was about "take it all or leave it all". Java is a language, that can be used in different environments.&lt;/cite&gt;&lt;/li&gt;&lt;li&gt;&lt;cite&gt;Lack of Free implementations. At the time, it hadn't been demonstrated that a language needed a solid community-driven implementation to pick up mindshare; people still thought that selling software was a good way to make money.&lt;/cite&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://stackoverflow.com/questions/187380/why-use-ruby-instead-of-smalltalk"&gt;Why use Ruby instead of Smalltalk?&lt;/a&gt;&lt;ul&gt;&lt;li&gt;&lt;cite&gt;I think your question is somewhat missing the point. You shouldn't choose, you should learn them both!&lt;/cite&gt;&lt;/li&gt;&lt;li&gt;&lt;cite&gt;You answered the question in your first line: "Ruby is becoming popular".&lt;/cite&gt;&lt;/li&gt;&lt;li&gt;&lt;cite&gt;Over a year ago IBM dumped the language (their term is sunset). Also, take a look at the History. ParkPlace and Digitalk where the first major commercial players in the Smalltalk arena, they merged and then went out of business.&lt;/cite&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/759829123710334956-8752646970812093813?l=anselm-strauss.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://anselm-strauss.blogspot.com/feeds/8752646970812093813/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://anselm-strauss.blogspot.com/2010/04/why-of-smalltalk.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/759829123710334956/posts/default/8752646970812093813'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/759829123710334956/posts/default/8752646970812093813'/><link rel='alternate' type='text/html' href='http://anselm-strauss.blogspot.com/2010/04/why-of-smalltalk.html' title='The Why of Smalltalk'/><author><name>anselm</name><uri>http://www.blogger.com/profile/12439016778981424132</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://3.bp.blogspot.com/_Yy4WDeOpVdM/TRo6zkow78I/AAAAAAAAAPk/r49QCStzciU/S220/anselm-strauss-posterized.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-759829123710334956.post-7359177354929133618</id><published>2010-03-11T17:10:00.002+01:00</published><updated>2010-03-11T17:24:26.241+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='btrfs'/><category scheme='http://www.blogger.com/atom/ns#' term='filesystem'/><category scheme='http://www.blogger.com/atom/ns#' term='zfs'/><category scheme='http://www.blogger.com/atom/ns#' term='snapshot'/><title type='text'>When ZFS runs out of space</title><content type='html'>&lt;p&gt;I'm one of the hopefully not so few people anymore who proudly run ZFS on their servers. I even discovered the value of regular snapshots I'm doing with &lt;a href="http://www.freebsd.org/cgi/url.cgi?ports/sysutils/freebsd-snapshot/pkg-descr"&gt;freebsd-snapshot&lt;/a&gt;. A good thing to save you from some of your accidental &lt;code&gt;rm&lt;/code&gt; commands and evil destructive updates.&lt;/p&gt;&lt;p&gt;But there are also some issues to the whole snapshot story. Once you run out of space on a pool things can get a bit more complicated with all that snapshots around. There are two defining points to understand in such a situation:&lt;ul&gt;&lt;li&gt;Data in a pool can only be freed if it's not referenced any more by any snapshot, clone or data set&lt;/li&gt;&lt;li&gt;Snapshots are read-only&lt;/ul&gt;Thus, cleaning up space by removing files only helps if they are not referenced by a snapshot. But that's likely not the case if you are making multiple snapshots per day. And removing parts of a snapshot is not possible, you can only destroy the snapshot as a whole. So this comes down to painfully searching snapshots and files you don't need anymore and delete them manually. Alternatively you could convert snapshots into clones, which are again writable, and delete single files from them. But I don't think this is a very clean way, and it would surely break you snapshot cycle, leaving you with a bunch of clones you would have to cleanup later.&lt;/p&gt;&lt;p&gt;So, isn't there any better solution? Well, I currently don't see any with ZFS, maybe you know one ... But I can imagine something that would help a lot in such situations. &lt;em&gt;Writable snapshots&lt;/em&gt;, as &lt;a href="http://btrfs.wiki.kernel.org/index.php/Main_Page"&gt;BTRFS&lt;/a&gt; has it on its feature list. And on top of that, how cool would it be to have some snapshot-aware file utilities. I can already imagine the line on my command prompt: &lt;code&gt;rm --snapshot all ~/firefox*.core&lt;/code&gt; *flip* and there is the free space again ...&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/759829123710334956-7359177354929133618?l=anselm-strauss.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://anselm-strauss.blogspot.com/feeds/7359177354929133618/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://anselm-strauss.blogspot.com/2010/03/when-zfs-runs-out-of-space.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/759829123710334956/posts/default/7359177354929133618'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/759829123710334956/posts/default/7359177354929133618'/><link rel='alternate' type='text/html' href='http://anselm-strauss.blogspot.com/2010/03/when-zfs-runs-out-of-space.html' title='When ZFS runs out of space'/><author><name>anselm</name><uri>http://www.blogger.com/profile/12439016778981424132</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://3.bp.blogspot.com/_Yy4WDeOpVdM/TRo6zkow78I/AAAAAAAAAPk/r49QCStzciU/S220/anselm-strauss-posterized.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-759829123710334956.post-5985553385367267620</id><published>2010-03-07T00:41:00.003+01:00</published><updated>2010-03-22T14:12:33.685+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ports'/><category scheme='http://www.blogger.com/atom/ns#' term='nmap'/><category scheme='http://www.blogger.com/atom/ns#' term='ascii-art'/><title type='text'>While installing security/nmap</title><content type='html'>&lt;p&gt;Recently, when I did a &lt;code&gt;portinstall nmap&lt;/code&gt;, the build process surprised me with some pleasing ASCII art:&lt;pre&gt;            .       .                                                                           &lt;br /&gt;            \`-"'"-'/                                                                           &lt;br /&gt;             } 6 6 {                                                                            &lt;br /&gt;            ==. Y ,==                                                                           &lt;br /&gt;              /^^^\  .                                                                          &lt;br /&gt;             /     \  )  Ncat: A modern interpretation of classic Netcat                        &lt;br /&gt;            (  )-(  )/                                                                          &lt;br /&gt;            -""---""---   /                                                                     &lt;br /&gt;           /   Ncat    \_/                                                                      &lt;br /&gt;          (     ____                                                                            &lt;br /&gt;           \_.=|____E                                                                           &lt;br /&gt;Configuration complete.                                                                         &lt;br /&gt;   (  )   /\   _                 (                                                              &lt;br /&gt;    \ |  (  \ ( \.(               )                      _____                                  &lt;br /&gt;  \  \ \  `  `   ) \             (  ___                 / _   \                                 &lt;br /&gt; (_`    \+   . x  ( .\            \/   \____-----------/ (o)   \_                               &lt;br /&gt;- .-               \+  ;          (  O                           \____                          &lt;br /&gt;(__                +- .( -'.- &amp;lt;.   \_____________  `              \  /                          &lt;br /&gt;(_____            ._._: &amp;lt;_ - &amp;lt;- _- _  VVVVVVV VV V\                \/                           &lt;br /&gt;  .    /./.+-  . .- /  +--  - .    (--_AAAAAAA__A_/                |                            &lt;br /&gt;  (__ ' /x  / x _/ (                \______________//_              \_______                    &lt;br /&gt; , x / ( '  . / .  /                                  \___'          \     /                    &lt;br /&gt;    /  /  _/ /    +                                       |           \   /                     &lt;br /&gt;   '  (__/                                               /              \/                      &lt;br /&gt;                                                       /                  \                     &lt;br /&gt;             NMAP IS A POWERFUL TOOL -- USE CAREFULLY AND RESPONSIBLY                           &lt;br /&gt;&lt;/pre&gt;It surely makes all that compiling more fun.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/759829123710334956-5985553385367267620?l=anselm-strauss.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://anselm-strauss.blogspot.com/feeds/5985553385367267620/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://anselm-strauss.blogspot.com/2010/03/while-installing-securitynmap.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/759829123710334956/posts/default/5985553385367267620'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/759829123710334956/posts/default/5985553385367267620'/><link rel='alternate' type='text/html' href='http://anselm-strauss.blogspot.com/2010/03/while-installing-securitynmap.html' title='While installing security/nmap'/><author><name>anselm</name><uri>http://www.blogger.com/profile/12439016778981424132</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://3.bp.blogspot.com/_Yy4WDeOpVdM/TRo6zkow78I/AAAAAAAAAPk/r49QCStzciU/S220/anselm-strauss-posterized.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-759829123710334956.post-460929443749217122</id><published>2010-03-03T10:31:00.006+01:00</published><updated>2010-03-11T15:55:37.469+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='smalltalk'/><category scheme='http://www.blogger.com/atom/ns#' term='rails'/><category scheme='http://www.blogger.com/atom/ns#' term='seaside'/><title type='text'>Rails versus Seaside</title><content type='html'>&lt;p&gt;To start this blog, I'll simply make some propaganda for Smalltalk and &lt;a href="http://seaside.st/"&gt;Seaside&lt;/a&gt; by referencing an older but still very good &lt;a href="http://onsmalltalk.com/rails-vs-seaside"&gt;article&lt;/a&gt; from the &lt;a href="http://onsmalltalk.com/"&gt;On Smalltalk&lt;/a&gt; blog. &lt;em&gt;Are you still writing HTML? Oh, you are using embedded ruby code inside your HTML. So you are still doing it the old way then ...&lt;/em&gt;&lt;/p&gt;&lt;p&gt;The abstraction and consistency of your code that you get with Seaside and Smalltalk are still the very best I've seen so far. Simply turn your HTML code into Smalltalk, keeping it in the same environment as the remaining parts of your application and profit from all the other strengths Smalltalk offers you.&lt;/p&gt;&lt;p&gt;To be fair, nobody is perfect. Ever looked at how Seaside handles CSS?&lt;pre&gt;style&lt;br /&gt;  ^ '&lt;br /&gt;  #navigation {&lt;br /&gt;    padding: 5px;&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  #body {&lt;br /&gt;    margin: 5px;&lt;br /&gt;    padding: 5px;&lt;br /&gt;  }'&lt;br /&gt;&lt;/pre&gt;Well, surely that's &lt;em&gt;some kind&lt;/em&gt; of abstraction, transforming CSS code into a Smalltalk string literal. At least you can now use string composition and maybe regex replacing ... ;-)&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/759829123710334956-460929443749217122?l=anselm-strauss.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://anselm-strauss.blogspot.com/feeds/460929443749217122/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://anselm-strauss.blogspot.com/2010/03/rails-versus-seaside.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/759829123710334956/posts/default/460929443749217122'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/759829123710334956/posts/default/460929443749217122'/><link rel='alternate' type='text/html' href='http://anselm-strauss.blogspot.com/2010/03/rails-versus-seaside.html' title='Rails versus Seaside'/><author><name>anselm</name><uri>http://www.blogger.com/profile/12439016778981424132</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://3.bp.blogspot.com/_Yy4WDeOpVdM/TRo6zkow78I/AAAAAAAAAPk/r49QCStzciU/S220/anselm-strauss-posterized.png'/></author><thr:total>2</thr:total></entry></feed>
