February 21, 2010

How I bricked my iTunes Server

for a while...

As soon as it was available in Germany I bought a Sheeva Plug Computer (ca. EUR 100) and a 1 TB Imation external USB disk (ca. EUR 100). My plan was to use this a fileserver, mainly as a DAAP iTunes Music server.

The Imation disk is great. It's covered with an absorber material, and I only hear it when I put my ear on it. It's also supposed to use very little energy.
The Sheeva Plug is not so great. The USB connections have too little friction, so it is extremely easy to lose the connection. I already had to format the USB disk twice, because it became unusable, when the USB cabled didn't connect properly any more... Also I think, it could be a little smaller. It's quite a beefy plug.

There are a lot of guides out there, that cover what to do with the Sheeva, once you get it. For a fileserver like mine, you only need three packages: avahi-daemon for Zeroconf, mt-daapd for Daap/iTunes and samba for filesharing. I also wanted netatalk for completeness sake.

I just want to write down a few notes, that I didn't see covered elsewhere on the web. There are a lot of good guides out there.

  • netatalk - gave me some weird address family errors, but when I turned off the ATALKD daemon and just use AFPD daemon (see /etc/defult/netatalk/. It worked OK. I don't really use AFP now, I use samba, it seems so much faster.
  • hostname - append a .local to the name you come up with. Zeroconf will then be able to properly resolve it.
  • fstab - try to replace as much as possible of the /var hierarchy with tmpfs mounts. You will lose persistent logs, but that should reduce writes to the flash memory of the plug.
As a final buff, I wanted to mount the root file system as read only. Truely an idiotic maneuvre in planning in execution, but here's what I did, no kidding...
  1. Edited /etc/fstab to read rootfs / rootfs ro 00 instead of rootfs / rootfs rw 0 0, hoping that this would just work
  2. Rebooted
  3. Checked with mount that it worked, it didn't (rootfs on / type rootfs (rw))
  4. Decided to revert /etc/fstab to avoid confusion later in life
  5. Noticed about three times in a row that saving the changed file didn't work.
  6. Examined fstab file permissions and my user id (root)
  7. Failed to see any reason, why it shouldn't work.
  8. Abandoned this problem and tried to figure out some other aesthetic problem in the boot process
  9. Figured out that I needed strings for that
  10. Tried apt-get install strings, knowing that it wouldn't work, which it didn't. Dimly rememberd something about "bin-utils"...
  11. Gave up on this, but noticed a warning that apt-get gave about not being able to use a read-only /var/lib/dpkg/lock.
  12. Figured, that probably /var/lib/dpkg was missing and needed creation
  13. Noticed, that this wasn't the case.
  14. Experienced a rare moment, that I wouldn't call lucid, but nevertheless had a somewhat dim-but-brighter-than-pitch-black quality. The root filesystem was indeed mounted read only, and mount had lied to me!
  15. Moaned as I realized, that to install anything on the root file system I had to edit fstab and reboot. But everything on the root file system is read only now.
  16. Dealt with the pain, by writing this blog entry
  17. Rememberd the remount option mount -o remount,rw / ;)

January 12, 2010

A mysterious and largely unknown gcc builtin function

#include <stdio.h>

main()
{
   int  x;

   // \\\\\\\\\\\  ///////////// 
   // ||    POWERFUL MAGIC    ||
   // //////////   \\\\\\\\\\\\\
   x = __powerful_magic__( 1848);
   printf( "%d\n", x);

   return( 0);
}

Continue reading "A mysterious and largely unknown gcc builtin function" »

January 6, 2010

deprecation, deprecation, deprecation - Part 2

So out of curiosity I figured I'd like to check the deprecation statistics.

Here's the unix command I used to get the statistics. I am collecting recursive all the header files inside an SDK directory, unique them by filename (which is a bug, but better than not doing it) and check for the AVAILABLE...BUT..DEPRECATED string. Then I massage the output a little, so I can easily put it in a table:

( for i in `find /Developer/SDKs/MacOSX10.4u.sdk/ -name "*.h" -print` ; do file=`basename $i`; echo "$file" "$i"; done | awk '{ files[ $1] = $2 } END { for ( x in files) print files[ x] }' | xargs egrep -H "AVAILABLE_MAC_OS_X_VERSION_10_._AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_." ) | egrep -v "#define|#ifdef|#ifndef|\ \*\ .*AVA" | sed 's/.*\(AVAILABLE_.*_10_.\).*/\1/' | sort | uniq -c | sed 's/AVAILABLE_MAC_OS_X_VERSION_10_\(.*\)_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_\(.*\)/\1 \2/'

which exposes that the JavaVM.framework is apparently broken in the 10.6 SDK, but who uses Java anyway ;)
egrep: /Developer/SDKs/MacOSX10.6.sdk//System/Library/Frameworks/JavaVM.framework/Versions/A/Headers/jvmdi.h: No such file or directory
egrep: /Developer/SDKs/MacOSX10.6.sdk//System/Library/Frameworks/JavaVM.framework/Versions/A/Headers/jvmpi.h: No such file or directory

Anway here are the results:

Mac OS X Deprecation Chart

How to read this chart. On the left side is the released version. The bars show the number of symbols deprecated of previous OS X versions. So for example the top entry 10.1, shows that it deprecates less than 10 function from 10.0. Then 10.3 deprecates a few symbols from 10.0 and 10.2 and so on. Further interpretation of the data is left to the reader.

What is kind of interesting is to compare the raw numbers for the various SDKs. I checked 10.4.u.sdk, 10.5.sdk and 10.6.sdk. The horizontal axis has the version that deprecates, the vertical axis has the version that suffers deprecation:

10.4u.sdk10.110.210.310.410.510.6
10.02531111982
10.11324
10.220
10.312
10.4
10.5
10.5.sdk10.110.210.310.410.510.6
10.026381107682
10.113737
10.292219
10.31432
10.47
10.5
10.6.sdk10.110.210.310.410.510.6
10.02537108264097
10.111832
10.2921123
10.31819106
10.4713
10.58
Some quick observations:
  • 10.4u.sdk seems to be broken, as it has deprecations from 10.5 already
  • since deprecations seem to disappear over time, this could mean, that either symbols were really removed, or that some symbols were wrongly deprecated

The methodology used here isn't perfect, because I am not checking all headers. But I hate scrapping the whole entry ;)

deprecation, deprecation, deprecation - Part 1

The initial grievance for this posting is this warning:
foo.m:17: warning: 'NSLookupSymbolInImage' is deprecated 
(declared at /Developer/SDKs/MacOSX10.5.sdk/usr/include/mach-o/dyld.h:182)
When I look into the header I find this:
/*
 * The following dyld API's are deprecated as of Mac OS X 10.5.  They are either  
 * no longer necessary or are superceeded by dlopen and friends in .
 * dlopen/dlsym/dlclose have been available since Mac OS X 10.3 and work with 
 * dylibs and bundles.  
 *
 *    NSAddImage                           -> dlopen
 *    NSLookupSymbolInImage                -> dlsym
 *    NSCreateObjectFileImageFromFile      -> dlopen
 *    NSDestroyObjectFileImage             -> dlclose
 *    NSLinkModule                         -> not needed when dlopen used
 *    NSUnLinkModule                       -> not needed when dlclose used
 *    NSLookupSymbolInModule               -> dlsym
 *    _dyld_image_containing_address       -> dladdr
 *    NSLinkEditError                      -> dlerror
 *
 */
and
extern NSSymbol NSLookupSymbolInModule(NSModule module, const char* symbolName)
AVAILABLE_MAC_OS_X_VERSION_10_1_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_5;
So it appeared in 10.1 and it's plug gets pulled in 10.5. Short lived API, I would say.

What bothers me, that one of the ideas behind Foundation is, that it should isolate me from the OS layer and abstract to a common denominator, that remains stable. Yet here, the Foundation functions are deprecated and I am suposed to use dyld directly, although Foundation still could (and probably does) do the work using dyld.

I don't get this.