<?xml version="1.0" encoding="utf-8"?>
        <?xml-stylesheet type="text/css" href="http://blog.ngas.ch/styles/feed.css"?>
<rss version="2.0"
 xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
 xmlns:dc="http://purl.org/dc/elements/1.1/"
 xmlns:admin="http://webns.net/mvcb/"
 xmlns:atom="http://www.w3.org/2005/Atom"
>
<channel>
<title>Filed under: broken | Pas un Geek en tant que tel</title>
<atom:link href="http://blog.ngas.ch/archives/broken/index-rss.xml" rel="self" type="application/rss+xml" />
<link>http://blog.ngas.ch</link>
<description>No Geek As Such</description>
<dc:language>en-us</dc:language>
<dc:creator><a href=&quot;https://plus.google.com/114292582268779510325&quot;>Tonnerre Lombard</a></dc:creator>
<dc:date>2011-12-18T21:46:36+01:00</dc:date>
<admin:generatorAgent rdf:resource="http://nanoblogger.sourceforge.net" />

<item>
<link>http://blog.ngas.ch/archives/2011/08/15/frustration_with_the_thecus_n5200/index.html</link>
<guid isPermaLink="true">http://blog.ngas.ch/archives/2011/08/15/frustration_with_the_thecus_n5200/index.html</guid>
<title>Frustration with the Thecus N5200</title>
<dc:date>2011-08-15T01:23:47+01:00</dc:date>
<dc:creator><a href=&quot;https://plus.google.com/114292582268779510325&quot;>Tonnerre Lombard</a></dc:creator>
<dc:subject> broken, hardware</dc:subject>
<description><![CDATA[<p>
 After a recommendation from a friend, I recently bought myself a Thecus
 N5200 NAS for home use, to replace the sluggishly slow Netgear ReadyNAS.
 Along with it, I bought 5 2TB hard disks, which should be enough to give
 me 6TB or more of storage on my home directories.
</p>
<p>
 So I installed the hard disks and booted it up. I created a big RAID 6
 volume over all disks and then realized that it wasn't helping a lot
 because, while there was a menu option to enable NFS support in the
 first place, there was none whatsoever to export my new file system via
 NFS. Also, showmount confirmed that it wasn't exported.
</p>
<h4>Follow the manual</h4>
<p>
 As I couldn't find anything in the online help or the user manual about
 exporting file systems to NFS, I found
 <a href="http://wiki.chaostreff.ch/Thecus_n5200_Debian">Thecus N5200
  Debian</a> on the Chaoswiki and tried to follow the procedure outlined
 there. However, it turned out that my NAS was running a much more recent
 version of the Thecus supplied Linux distribution and couldn't install
 any of the mentioned packages. Also, Thecus itself doesn't seem to offer
 any SSH server.
</p>
<h4>Do It Yourself, maybe?</h4>
<p>
 So since the whole thing is just an i386 which runs Linux I decided to
 try and go in to fix things up myself. I installed Debian onto an SD card
 and tried in kvm whether it boots up fine and configures the system.
 Then I got myself an adapter from <a href="http://www.pcengines.ch/">PC
  Engines</a> to mount the SD card into the Thecus NAS and tried to boot
 it up.
</p>
<p>
 Well, so much for the theory. The system did something but there was no
 output on any of the two serial consoles, ever. Not even the firmware
 of the box write anything anywhere. The system is really hard to interact
 with. And while, in qemu, I get a serial console, it didn't work at all
 in the Thecus.
</p>
<p>
 And while the network card was configured and the firmware installed,
 nothing moved on that front either. According to
 <a href="http://wpkg.org/Running_Debian_on_Thecus_n5200">Running Debian
  on Thecus n5200</a> on wpkg, the only way to tell what the NAS is doing
 seems to be to solder a VGA adapter onto the mainboard and attach a
 monitor.
</p>
<h4>Picking up the pieces</h4>
<p>
 So to summarize, so far I wasted more than CHF 1'000.- and 10 TB of space.
 All I got in return is a brick which sits on the ground and can only
 share files with Windows boxes. Yes, I know, most systems can mount SMB
 shares, but that's really not an option.
</p>
<p>
 So I really wonder where this is going. What I'd love is a tiny box with
 space for 5 hard disks which can at least do 1 Gbit/s and can be
 integrated easily with my LDAP and Kerberos setup. In my world, this
 shouldn't be too much to ask.
</p>
<p>
 However, instead of this, vendors seem to throw very expensive closed
 systems at us which attempt to prevent us to customize them or to really
 interact with them in any way which the vendor wasn't planning for. I
 don't see the reason though.
</p>
<p>
 What's the loss for Thecus if I can easily install my own operating
 system, like I can with my ALIX? They aren't losing any money form this
 or anything. What's the cost of making everything output to the existing
 serial port? It's not like this is expensive to implement or anything.
 And the operating system used in the box suppports it just as well.
</p>
<p>
 So far I'm getting the feeling that I just found a new brick I can use
 as a door stopper. But I guess I'll try to do some more stuff with it
 before I loot the hard disks. Perhaps I should buy a regular Mini-ITX
 PC and use that.
</p>]]></description>

</item>
<item>
<link>http://blog.ngas.ch/archives/2010/09/01/the_debian_installation_of_doom/index.html</link>
<guid isPermaLink="true">http://blog.ngas.ch/archives/2010/09/01/the_debian_installation_of_doom/index.html</guid>
<title>The Debian Installation of Doom</title>
<dc:date>2010-09-01T02:33:57+01:00</dc:date>
<dc:creator>Tonnerre Lombard</dc:creator>
<dc:subject> broken, free_software</dc:subject>
<description><![CDATA[<p>
 For tonight I set myself a rather trivial task: install Debian on a remote server
 which I can only netboot grml on, and where I have no console access. I figured
 it wouldn't be too difficult. However, Debian figured that it would be best to
 throw any possible obstacle my way.
</p>
<p>
 I booted into grml, set up the partitions and file systems (/dev/md0 as /boot,
 /dev/md1 with lvm and the root file system). Then I mounted them in place and
 ran debootstrap. However, debootstrap said the configuration phase of the
 packages failed. So I chrooted into the system and ran <i>dpkg --configure -a</i>.
</p>
<p>
 Then, I figured that Debian prefers to leave the most important programs uninstalled,
 so I ran <i>apt-get install less bzip2 pax openssh-server sysklogd grub-pc
  linux-image-2.6.32-5-amd64</i>. However, grub-pc decided it doesn't want to
 install itself successfully. A manual run of grub-install fixed this glitch as
 well. Then I set up a root password, enabled root logins for now in the ssh
 configuration and configured /etc/fstab and /etc/network/interfaces. I added
 a netconsole to the grub configuration, just in case.
</p>
<p>
 Then I figured it was time to test the system, so I rebooted. However, I never saw
 the system come up. Also, the netconsole didn't log a thing. So I booted back into
 grml, installed kvm and tried to boot the system, only to find grub saying:
</p>
<p><code>
 error while parsing number
</code></p>
<p>
 So I fixed the device paths and re-ran update-grub2. Then the system booted but
 still didn't respond to ping, and had nothing on the netconsole. So I booted grml
 and saw that there was finally at least a dmesg.0 file. This file contained a
 number of hints:
</p>
<p><code>
 netconsole: eth0 doesn't exist, aborting.<br/>
 e100: eth0: e100_request_firmware: Failed to load firmware
 &quot;e100/dm101m_ucode.bin&quot;
</code></p>
<p>
 So I figured that apparently the Debianists no longer ship firmwares anymore. I found
 a package called linux-firmware in the non-free repository and installed it. Then
 I rebooted and received ping replies from the system, but ssh never came up, the
 connection remained refused. So I booted into grml and found all logs in the chroot
 to be empty:
</p>
<p><code>
 grml# ls -l &nbsp;<br/>
 -rw-r----- 1 root adm       0 Aug 31 23:20 /mnt/vms-planck--root/var/log/messages<br/>
 -rw-r----- 1 root adm       0 Aug 31 23:20 /mnt/vms-planck--root/var/log/syslog<br/>
 -rw-r----- 1 root adm       0 Aug 31 23:20 /mnt/vms-planck--root/var/log/daemon.log<br/>
 grml# 
</code></p>
<p>
 So I installed Dropbear and configured it to listen to port 2222, then rebooted. The
 system pinged, but ports 22 and 2222 remained refused. When running the system in kvm
 again, I discovered strange messsages though and found the root cause to be a popular
 debootstrap bug:
</p>
<p><code>
 grml# cat /sbin/start-stop-daemon<br/>
 #!/bin/sh<br/>
 echo<br/>
 echo "Warning: Fake start-stop-daemon called, doing nothing"<br/>
 grml#
</code></p>
<p>
 So I moved /sbin/start-stop-daemon.REAL back to /sbin/start-stop-daemon, but
 instead of typing reboot I accidentally typed poweroff, and now I have to wait for
 the hoster to flip the power switch of the server again before I can continue, so
 things will remain interesting.
</p>
<p>
 I guess being bitten by debootstrap, defaults, grub, netconsole, firmware and
 start-stop-daemon on the same day was a bit too much. Time to watch
 <i>V for Vendetta</i> and go to bed.
</p>
<p>
 <b>Update</b>: Note to those who didn't realize: no, I didn't watch the film, I
 just found it fitting.
</p>]]></description>

</item>
<item>
<link>http://blog.ngas.ch/archives/2010/07/18/quotes_from_the_people_who_brought_you_php/index.html</link>
<guid isPermaLink="true">http://blog.ngas.ch/archives/2010/07/18/quotes_from_the_people_who_brought_you_php/index.html</guid>
<title>Quotes from the people who brought you PHP</title>
<dc:date>2010-07-18T16:27:43+01:00</dc:date>
<dc:creator>Tonnerre Lombard</dc:creator>
<dc:subject> programming, broken</dc:subject>
<description><![CDATA[<p>
 <a href="https://www.mirbsd.org/wlog-10.htm">Thorsten Glaser</a> from
 <a href="http://www.tarent.de/">Tarent</a> added a number of nice quotes
 from PHP developer
 <a href="http://en.wikipedia.org/wiki/Rasmus_Lerdorf">Rasmus Lerdorf</a>
 to the PHP source code of Evolvisforge, the gforge clone of his company:
</p>
<p><i>
 I have absolutely no idea how to write a programming language, I just
 kept adding the next logical step on the way.
</i></p>
<p>
 <a href="https://evolvis.org/scm/viewvc.php/trunk/gforge_base/evolvisforge/gforge/common/include/utils.php?root=evolvis&amp;r1=6547&amp;r2=6546&amp;pathrev=6547&amp;diff_format=u">gforge_base/evolvisforge/gforge/common/include/utils.php:1009</a>
</p>
<p><i>
 I was really, really bad at writing parsers. I still am really bad at
 writing parsers.
</i></p>
<p>
 <a href="https://evolvis.org/scm/viewvc.php/trunk/gforge_base/evolvisforge/gforge/common/include/minijson.php?revision=6547&amp;root=evolvis&amp;view=markup&amp;pathrev=6547">gforge_base/evolvisforge/gforge/common/include/minijson.php</a>
</p>
<p><i>
 I'm not a real programmer. I throw together things until it works
 then I move on. The real programmers will say &quot;yeah it works but
 you're leaking memory everywhere. Perhaps we should fix that.&quot; I'll
 just restart apache every 10 requests.
</i></p>
<p>
 <a href="https://evolvis.org/scm/viewvc.php/trunk/gforge_base/evolvisforge/gforge/www/pm/t_follow.php?revision=6547&amp;root=evolvis&amp;view=markup&amp;pathrev=6547">gforge_base/evolvisforge/gforge/www/pm/t_follow.php</a>
</p>
<p><i>
 We have things like protected properties. We have abstract methods.
 We have all this stuff that your computer science teacher told you
 you should be using. I don't care about this crap at all.
</i></p>
<p>
 <a href="https://evolvis.org/scm/viewvc.php/trunk/gforge_base/evolvisforge/gforge/www/pm/t_lookup.php?revision=6547&amp;root=evolvis&amp;view=markup&amp;pathrev=6547">gforge_base/evolvisforge/gforge/www/pm/t_lookup.php</a>
</p>
<p>
 I think people like Rasmus explain a lot about the poor design and the
 many implementation flaws of the PHP programming language.
</p>
<p>
 Thanks as well to <a href="http://www.slideshare.net/bsiegert">Benny
  Siegert</a> who provided the quotes.
</p>]]></description>

</item>
<item>
<link>http://blog.ngas.ch/archives/2010/05/24/putting_the_fun_in_funionfs/index.html</link>
<guid isPermaLink="true">http://blog.ngas.ch/archives/2010/05/24/putting_the_fun_in_funionfs/index.html</guid>
<title>Putting the fun in funionfs</title>
<dc:date>2010-05-24T20:56:27+01:00</dc:date>
<dc:creator>Tonnerre Lombard</dc:creator>
<dc:subject> broken</dc:subject>
<description><![CDATA[<p>
 Since a lot of the world still evolves around PHP, and a friend of mine
 asked me to host a PHP based blog, I was confronted with a typical PHP
 application which, like all typical PHP applications, enjoys heavily
 writing to its installation directory and keeping its own configuration
 there.
</p>
<p>
 Being the automation freak I am, I rolled an RPM package of the PHP
 application which installs it into <i>/usr/share</i>. Then, a Puppet
 rule creates an Apache vhost in <i>/home/www</i> and union mounts the
 shared installation into <i>htdocs</i>, with a vhost subdirectory named
 <i>confdata</i> as read-write layer.
</p>
<p>
 It turned out I had better used NetBSD for the task. The only unionfs
 implementation available in CentOS 5.5 is fuse based and called
 <i>funionfs</i>. However, funionfs doesn't support SElinux contexts,
 so everything ends up in the context <i>fusefs_t</i>, leaving it
 inaccessible to Apache. A small SElinux module fixed that:
</p>
<p><code>
module serendipity 1.0;<br/>
<br/>
require {<br/>
&nbsp;&nbsp;&nbsp;&nbsp;type httpd_t;<br/>
&nbsp;&nbsp;&nbsp;&nbsp;type fusefs_t;<br/>
&nbsp;&nbsp;&nbsp;&nbsp;class lnk_file read;<br/>
&nbsp;&nbsp;&nbsp;&nbsp;class dir { read write remove_name getattr create search add_name };<br/>
&nbsp;&nbsp;&nbsp;&nbsp;class file { read write getattr create setattr rename };<br/>
}<br/>
<br/>
#============= httpd_t ==============<br/>
allow httpd_t fusefs_t:dir { read write remove_name getattr create search add_name };<br/>
allow httpd_t fusefs_t:file { read write getattr create setattr rename };<br/>
allow httpd_t fusefs_t:lnk_file read;
</code></p>
<p>
 This might not be the most secure solution but nothing other than Apache
 runs on this VM anyway, so I didn't care enough. It's still better than
 turning off SElinux entirely.
</p>
<p>
 In order to allow the software to access the database, I had to flip another
 SElinux switch:
</p>
<p><code>
 httpd_can_network_connect_db --&gt; on
</code></p>
<p>
 Now things almost worked. However, installing templates via the web
 interface does not, so I went on to investigate:
</p>
<p><code>
 % cd /home/www/s9y.zrh.internetputzen.com/htdocs/templates<br/>
 % mkdir test<br/>
 mkdir: cannot create directory `test': No such file or directory<br/>
 % ls -ld test<br/>
 ls: test: No such file or directory<br/>
 % touch test<br/>
 touch: setting times of `test': File exists<br/>
 % ls -ld test<br/>
 -rw-r--r-- 1 root root 0 May 24 20:49 test<br/>
 % rm test
</code></p>
<p>
 It's impossible to create directories in the funionfs. Apparently it's
 some kind of bug. Creating the template in <i>confdir</i> worked but
 it means the web interface is not working.
</p>
<p>
 Looking forward to <i>aufs2</i> in later versions of CentOS.
</p>]]></description>

</item>
<item>
<link>http://blog.ngas.ch/archives/2008/11/30/mysql_5_1_few_new_features_but_many_new_bugs/index.html</link>
<guid isPermaLink="true">http://blog.ngas.ch/archives/2008/11/30/mysql_5_1_few_new_features_but_many_new_bugs/index.html</guid>
<title>MySQL 5.1: few new features, but many new bugs</title>
<dc:date>2008-11-30T00:34:45+01:00</dc:date>
<dc:creator>Tonnerre Lombard</dc:creator>
<dc:subject> broken, programming</dc:subject>
<description><![CDATA[<p>
 As <a href="http://monty-says.blogspot.com/">Monty</a>, who is apparently
 working at MySQL, wrote yesterday in his blog, there appears to be a
 rahter large number of quite devastating bugs left in MySQL 5.1 at the
 time of its release, many of which would have been declared release
 critical by open source projects.
</p>
<p>
 In <a href="http://monty-says.blogspot.com/2008/11/oops-we-did-it-again-mysql-51-released.html"><i>Oops, we did it again</i></a>,
 <i>Monty</i> names a number of these bugs and outlines variety of bad
 management decisions which have lead to the current situation, and which
 apparently have lead to similar situations in the past.
</p>
<p>
 To me, it does not really come as a surprise. As you may or may not know,
 I have been following the MySQL company, community and products for years,
 and haven't seen too many different types of releases so far. In any case,
 I strongly support the suggestion of <i>Monty</i> and also strictly
 recommend staying with MySQL 5.0 for now &mash; or to migrate to
 <a href="http://www.postgresql.org/">PostgreSQL</i>, if possible.
</p>]]></description>

</item>
<item>
<link>http://blog.ngas.ch/archives/2008/11/26/mysql_build_system_command_line_wildness/index.html</link>
<guid isPermaLink="true">http://blog.ngas.ch/archives/2008/11/26/mysql_build_system_command_line_wildness/index.html</guid>
<title>MySQL build system command line wildness</title>
<dc:date>2008-11-26T12:31:18+01:00</dc:date>
<dc:creator>Tonnerre Lombard</dc:creator>
<dc:subject> broken, programming</dc:subject>
<description><![CDATA[<p>
 Only seconds ago, the MySQL build system produced a ton of compiler command
 lines like this one:
</p>
<p><code>
 gcc -shared  -Wl,--whole-archive ndbapi/.libs/libndbapi.a common/transporter/.libs/libtransporter.a common/debugger/.libs/libtrace.a common/debugger/signaldata/.libs/libsignaldataprint.a mgmapi/.libs/libmgmapi.a common/mgmcommon/.libs/libmgmsrvcommon.a common/logger/.libs/liblogger.a common/portlib/.libs/libportlib.a common/util/.libs/libgeneral.a -Wl,--no-whole-archive  -lpthread -lpthread -lpthread -lpthread -lpthread -lpthread -lpthread -lpthread -lpthread -lpthread -lpthread -lpthread -lpthread -lpthread -lpthread -lpthread -lpthread -lpthread -lpthread -lpthread -lpthread -lpthread -lpthread -lpthread -lpthread -lpthread -lpthread -lpthread -lpthread -lpthread -lpthread -lpthread -lpthread -lpthread -lpthread -lpthread -lpthread -lcrypt -lnsl -lm -lpthread  -Wl,-soname -Wl,libndbclient.so.0 -o .libs/libndbclient.so.0.0.0
</code></p>
<p>
 It seems that it really desperately wants to link against libpthread.
</p>]]></description>

</item>
<item>
<link>http://blog.ngas.ch/archives/2008/11/25/your_daily_pot_of_mysql_insanity_threading/index.html</link>
<guid isPermaLink="true">http://blog.ngas.ch/archives/2008/11/25/your_daily_pot_of_mysql_insanity_threading/index.html</guid>
<title>Your daily pot of MySQL insanity: Threading</title>
<dc:date>2008-11-25T18:34:20+01:00</dc:date>
<dc:creator>Tonnerre Lombard</dc:creator>
<dc:subject> broken, programming</dc:subject>
<description><![CDATA[<p>
 I really know I shouldn't look into MySQL source code, but since there are
 customers who really entrust their data to this piece of software, I
 sometimes have to.
</p>
<p>
 The task today: Updating PHP on Etch to version 5.2.6. Sounds easy, right?
 Wrong. Because after you put up with disabling all the new security
 extension which prevent the worst PHP scripts you've ever seen from
 running, and after fiddling half a day with weird compile time detection
 scripts which don't work in a uniform way, i.e. discover different
 environments under different circumstances, thus leaving you with a
 PHP which is in a constant debate with itself where its extension
 directory really is, &hellip;
</p>
<p>
 &hellip;you finally come to the point where you have a working PHP package
 which waits infinitely on a futex on exit. A command as simple as
 <i>php -v</i> hangs indefinitely.
</p>
<p>
 Following the code path further up, there is <i>main()</i>,
 <i>php_module_shutdown()</i>, <i>zend_shutdown()</i> (Why this stack order?!),
 <i>zend_hash_graceful_reverse_destroy()</i>, <i>zend_hash_apply_deleter()</i>,
 <i>module_destructor()</i>, <i>zm_shutdown_mysql()</i> (Argh, there's our
 other worst offender), <i>mysql_server_end()</i>, <i>my_end()</i>,
 <i>my_thread_global_end()</i>, <i>pthread_cond_destroy()</i>, &hellip;
</p>
<p>
 Digging through the code a bit, and digging through the glibc code some
 more, it becomes clear that this is indeed one of the good old
 <i>pthread_exit()</i> NPTL bugs from older glibc days. For once, it seems
 that Debian has also shipped beta software to the world. At least it
 wasn't some important system component, only the libc.
</p>
<p>
 Looking around some more, I stumbled over the
 <a href="http://bugs.php.net/bug.php?id=42625">PHP bug #42625</a>. It is
 not very helpful, though, it only proclaims:
</p>
<p><pre>
 Problem will solve itself when you rename /lib/tls to
 /lib/tls.go.fuck.yourself
</pre></p>
<p>
 Thanks for the suggestion, dear PHP people, but I have to get some work
 done first. Of course the above workaround does its job, but it is
 simply not what you would like to see in your server environment. And
 I don't mean the name.
</p>
<p>
 So I dug out a different patch for <i>mysql</i> which adds code to detect
 whether or not the glibc NPTL is in use. In fact, it gets the check
 entirely wrong by checking if the OS is Linux, while the bug is certain
 to appear on other operating systems running glibc as well. In that
 precise moment, though, I couldn't have cared less.
</p>
<p>
 Digging through the related header files, some more horrid things turned
 up which made it perfectly clear that I should not have gone there. One
 comment was rather odd:
</p>
<p><code>
 /*Irena: compiler does not like this: */<br/>
 /*#define my_pthread_getprio(pthread_t thread_id) pthread_dummy(0) */
</code></p>
<p>
 Yeah, Irena, I can imagine perfeclty well why the compiler didn't like
 that. After all, typed arguments aren't really supported in preprocessor
 macros. It can be hacked in using tricks, but they will always be
 tricks. However, now that you found out that the compiler doesn't like
 it, why commit it?
</p>
<p>
 Only a number of lines further, there is some code to handle a nonexistent
 errno:
</p>
<p><code>
 #ifndef ESRCH<br/>
 /* Define it to something */<br/>
 #define ESRCH 1<br/>
 #endif
</code></p>
<p>
 Maybe it is not the best idea after all to define <i>ESRCH</i> to <i>EPERM</i>.
</p>
<p>
 Then finally I am at the code I want to modify, but there is some oddity
 as well (there's always one more oddity). The added thread types for the
 header file are not flags or anything, they just enumerate types of
 libraries. However, no enum is used. That's ok, but the numbering is
 slightly odd:
</p>
<p><code>
 #define THD_LIB_OTHER   1<br/>
 #define THD_LIB_NPTL    2<br/>
 #define THD_LIB_LT      4<br/>
</code></p>
<p>
 Why bitwise numbering if it is not a flag? Or can a threading library be
 LT and OTHER at a time?
</p>
<p>
 Of course, that's all not dangerous, but it gives a very odd impression
 &hellip;
</p>]]></description>

</item>
<item>
<link>http://blog.ngas.ch/archives/2008/11/04/sqlalchemy_with_ancient_methods_against_modern_it/index.html</link>
<guid isPermaLink="true">http://blog.ngas.ch/archives/2008/11/04/sqlalchemy_with_ancient_methods_against_modern_it/index.html</guid>
<title>SQLAlchemy: With ancient methods against modern IT</title>
<dc:date>2008-11-04T09:32:18+01:00</dc:date>
<dc:creator>Tonnerre Lombard</dc:creator>
<dc:subject> broken, programming</dc:subject>
<description><![CDATA[<p>
 There is a small number of projects the Python developers are especially
 proud of: <a href="http://www.zope.org/">Zope</a> and
 <a href="http://www.sqlalchemy.org/">SQLAlchemy</a>.
</p>
<p>
 The fact that the Python core team deliberately keeps breaking compatibility
 for Zope is probably bad enough, but at least SQLAlchemy appears to work
 well enough with the various versions. Well, but how does it work?
</p>
<p>
 The answer is: bizarre.
</p>
<h2>Never trust the database to get sequences right!</h2>
<p>
 The first thing I discovered was with PostgreSQL and sequences. Some tables
 use sequences for creating their primary key, which is then going to be a
 64-bit integer. This is done automatically by either not naming the primary
 key column on insert, or by using the keyword <i>DEFAULT</i>.
</p>
<p>
 Looking through the debug output, however, items like these can be spotted:
</p>
<p><code>
 2008-11-04 09:26:24,258 INFO sqlalchemy.engine.base.Engine.0x..d0 select nextval('data_from_box_id_seq')
</code></p>
<p>
 This is wrong on a number of levels. At this point, SQLalchemy manually
 queries the next value returned by the sequence for the <i>id</i> column.
 This value is consequently used in the <i>insert</i> statement for the
 <i>id</i> column. This breaks the atomicity of the <i>insert</i>
 statement &mdash; rather than letting PostgreSQL handle things internally
 as it's supposed to, the insert statement is artificially split into two
 statements. Of course, this also means that two SQL operations are
 performed, which almost doubles the network overhead (especially over
 encrypted connections).
</p>
<p>
 The most likely reason why this is done is to have the row ID of the
 newly inserted row for use in the client side object representation.
 However, PostgreSQL has two much better mechanisms achieving the same:
 Firstly, the ID can be queried using the <i>last_insert_id</i> operation,
 or, even better, everything can be handled in one statement by using
 the <i>RETURNING</i> keyword:
</p>
<p><code>
 INSERT INTO data_from_box VALUES (DEFAULT, something, else) RETURNING id;
</code></p>
<h2>Prepared statements are for the weak and timid</h2>
<p>
 An even more bizarre affection manifests itself in the support for MySQL.
 Rather than to make use of the prepared statements, which are mandated
 by the API specification, SQLAlchemy attempts to reproduce prepared
 statements in the SQLAlchemy code, and to naturalize SQL statements
 manually. Then, the resulting statement is <i>PREPARE</i>d and
 <i>EXECUTE</i>d.
</p>
<p>
 This of course constitutes a duplication of functionality, and more than
 this, the SQLAlchemy users are now prone to SQLAlchemy prepared statement
 naturalization bugs which cannot really occurr in SQL prepared statements
 (because they are never synchronized into a string but used as-is).
</p>
<p>
 Overall, it is very hard to say what the SQLAlchemy developers had in mind,
 but it seems clear that it was nothing useful.
</p>]]></description>

</item>
<item>
<link>http://blog.ngas.ch/archives/2008/10/29/iterating_hot_air/index.html</link>
<guid isPermaLink="true">http://blog.ngas.ch/archives/2008/10/29/iterating_hot_air/index.html</guid>
<title>Iterating hot air</title>
<dc:date>2008-10-29T13:45:42+01:00</dc:date>
<dc:creator>Tonnerre Lombard</dc:creator>
<dc:subject> broken, programming</dc:subject>
<description><![CDATA[<p>
 Python allows to create iterators through the builtin function
 <i>iter</i>. This function has two ways of being called:
</p>
<ul>
 <li><b>iter</b>(<i>collection</i>) -> <i>iterator</i></li>
 <li><b>iter</b>(<i>callable</i>, <i>sentinel</i>) -> <i>iterator</i></li>
</ul>
<p>
 The first call is rather unproblematic for sure. It calls a class method,
 it gets its object and that's it.
</p>
<p>
 The second variant is however utterly useless. The callable is not called
 with any object &mdash; in fact, the call to <i>iter</i> does not even
 know what object is being iterated. This requires the programmer to
 store the state externally in some kind of global variable, or not to
 have any state at all. The latter would render the iterator rather pointless,
 since a crucial part of the purpose of an iterator is to externalize
 the state.
</p>]]></description>

</item>
<item>
<link>http://blog.ngas.ch/archives/2008/10/27/integer_is_an_int_but_be_aware_that_its_not/index.html</link>
<guid isPermaLink="true">http://blog.ngas.ch/archives/2008/10/27/integer_is_an_int_but_be_aware_that_its_not/index.html</guid>
<title>Integer() is an int, but be aware that it's not</title>
<dc:date>2008-10-27T11:16:54+01:00</dc:date>
<dc:creator>Tonnerre Lombard</dc:creator>
<dc:subject> broken, programming</dc:subject>
<description><![CDATA[<p>
 In Python's <a href="http://pyasn1.sourceforge.net/">external ASN.1 toolkit</a>
 features a special type, Integer(), which can be written to or fetched from
 an ASN.1 structure transparently. The resulting object, despite being an
 instance of <i>pyasn1.Integer</i>, behaves like any other integer: all
 operations can be applied as one would apply them to an integer.
</p>
<p>
 All operations? Not quite! A single function parameter is holding out,
 strong as ever, against the integer compatibility. Life is not easy for
 the programmers attempting to make use of the resulting objects.
</p>
<p>
 In fact it's quite funny: the problem is with the function <i>pow</i>.
 As the documentation says:
</p>
<p><code>
 In [1]: pow.__doc__<br/>
 Out[1]: 'pow(x, y[, z]) -> number\n\nWith two arguments, equivalent to x**y.  With three arguments,\nequivalent to (x**y) % z, but may be more efficient (e.g. for longs).'
</code></p>
<p>
 Since crypto wants speed, and ASN.1 is frequently used in crypto, we now
 try to combine pyasn1 and
 <a href="http://www.amk.ca/python/code/crypto.html">the amk crypto
  toolkit</a>, since Python itself does not contain any crypto. We use the
 DSA sign function, which basically only calls pow() for us. This is where
 we get bitten. The reason is simple and astonishing:
</p>
<p><code>
 In [2]: i = pyasn1.type.univ.Integer(23)<br/>
 In [3]: pow(i, 23)<br/>
 Out[3]: Integer('20880467999847912034355032910567')<br/>
 In [4]: pow(23, i)<br/>
 Out[4]: Integer('20880467999847912034355032910567')<br/>
 In [5]: pow(23, 23, i)<br/>
 ---------------------------------------------------------------------------<br/>
 TypeError                                 Traceback (most recent call last)<br/>
<br/>
 /home/tonnerre/&lt;ipython console&gt; in &lt;module&gt;()<br/>
<br/>
 TypeError: unsupported operand type(s) for pow(): 'int', 'int', 'instance'<br/>
<br/>
 In [6]: 
</code></p>
<p>
 Astonishingly, the Integer instance is allowed as the first and second
 argument to <i>pow()</i>, but not as the third one. More astonishingly,
 all of them are supposed to be ints. Even more weirdly, if pow is called
 with 3 pyasn1 Integer()s, the error message is still the same: the first
 two Integer()s are said to be int, the last one remains an instance.
</p>]]></description>

</item>
</channel>
</rss>

