FreeBSD cross compiling or “Thanks Captain Obvious…”

It would be nice to manage my fleet of FreeBSD machines from one place. But I’ve diversified from i386 only to i386 and amd64 as I start doing more and more stuff with virtual machines; single purpose servers and less power usage for-the-win. The question comes up, do I need build-i386.vindaloo.com and build-amd64.vindaloo.com — Nope:

# env TARGET=i386 MAKEOBJDIRPREFIX=/usr/obj/i386 make buildworld...

NFS – Old habits die hard

Old habits and myths die hard. Conventional wisdom asserts that UDP is better because it has lower overhead; then conventional wisdom suggests that you tune the buffer sizes to improve performance. On the face of things that would seem to work but once the the write size exceeds the max packet size, NFS delivers the packet by using multiple packets. Sending multiple packets triggers the issue because dropping just one UDP packet means the whole buffer must be resent. Contrast with TCP: yes the packet header is larger so less data can be sent and yes the receiving side has to ack each packet. But: with TCP if a packet gets dropped, only that packet needs to be resent; with a modern TCP stack the kernel will constantly adjust the window size to make the best use the available bandwidth. In other words NFS over tcp will automatically tune the buffer sizes for the current conditions.

MySQL lovefest

Great, just discovered how easy it is to break things with mysql views and stored functions. It turns out that to create a view after a dump, mysql must create table temporarily for each view, then one by one drop the tables and create views in their place.  This presents two potential problems. 1. It’s possible to have a view with more columns than you have in a table. 2. Views can use stored functions to modify results but stored functions aren’t a part of the mysql dump process until after the view have been defined.

The solution to the problem may be: Create the database, Create all the stored procedures and functions, create the tables and views from mysqldump –no-data. Reload all the data. It’s not. It looks like the only way to do this is to use information schema to make a list of tables to dump. Follow this up with routines, and then follow this up with views.

bash / ksh / pdksh

Fo my new job I’ve decided to try not to be so old and crotchety and use bash without complaining rather the just changing my shell to pdksh. Today I needed to process options in a shell function which I’ve done in ksh before. It turns out that you have to preface your option processing with OPTIND=1 if you are in a function. Dunno why but I’ll find it out.

py2exe + anydbm error

So, I tried something simple yesterday adding a call to anydbm to a python program that I plan to distribute on windows with py2exe. Doing so I ran into this error:

ImportError: no dbm clone found; tried ['dbhash', 'gdbm', 'dbm',  'dumbdbm']

Turns out that the way py2exe works though it misses the dependency that anydbm has on a db module. The moral of the story is that if you want to use anydbm and py2exe you need to do something like:


import anydbm, dbhash

f = anydbm.open("dbname.db", "c")
...

Vinyl

As I write this I’m listening to Squeeze’s Argybargy which I ripped from vinyl to MP3 a while ago. After doing this with a couple of albums, Argybargy, The Pretenders Learning to Crawl, I’m really happy with the results. Vinyl ripped to MP3 sounds very good. In some cases better than CD. It’s been a good experiment but wonder if I couldn’t make things even better by upgrading my equipment. I’m using an old technics direct drive turntable with a grado cartridge and a reasonably good Denon integrated amp. I wonder how much better it would be if I upgraded to a low end Music Hall Turntable like an MMF 2.1 or a Rega RP-1 and exchanged the Denon for the Adcom Pre-Amp that’s filling in for my broken A/V amp downstairs. On the other hand I wonder how much I would use a new turntable.

Finally sat down with sqlalchemy…

I’ve been meaning to sit down and play with sqlalchemy for a while now. As an old person though my needs are a little different. Most people use the ORM model to relieve themselves of the burden of dealing with SQL database engines. This is all fine and dandy if you have the luxury of using an SQL database solely as a repository for data with permanence. However, SQL databases can do much more than that. In this vein the sqlalchemy tutorials don’t tell you much about database introspection, that is figuring out what the layout of a table is from the information available in the database. Introspection is very important to me because I frequently create tables (and contraints and triggers etc) on the database. I also have a frequent need to an SQL feature called views but that’s a story for a different day. I came up with this code:

#! /usr/bin/env python

''' ============================================================================================
Program: sqla.py -- A test of sqlalchemy's ability to introspect tables from a database.
============================================================================================ '''

from sqlalchemy import *
from sqlalchemy.orm import *

metadata = MetaData("mysql://scott:tiger@mysql.example.com/test")

workEntryMeta = Table('work_entry', metadata,
                      Column('work_entry_id', Integer, primary_key=True),
                      autoload=True, )

class WorkEntry(object):
    pass

def sqlToStr(c):
    if c is None:
        return "NULL"
    else:
        return str(c)

mapper(WorkEntry, workEntryMeta)

session = create_session()
q = session.query(WorkEntry)
entries = q.all()

headers = None
for e in entries:
    if headers is None:
        headers = [ c for c in e.__dict__.keys() if c[0] <> '_' ]
        print headers
        print "\t".join(headers)

    d = [ sqlToStr(e.__dict__[c]) for c in headers ]
    print "\t".join(d)

This creates an ORM object for the table work_entry in the current python program and grabs all the rows from the database printing each one as it goes.

iPad first impressions.

Well, my iPad showed up and I’m trying to touch type on it. I guess that I can say that so far I like it and I see a lot of potential for it. At the same time it works quite well with a keyboard. I think that for developers of the device a keyboard is going to be required kit.

Apple/Batteries

My biggest problem with the latest MacBooks is Apples insistence on selling them without user serviceable batteries. To me that means that the battery life is what it is and you can’t do anything about it. I own an older MacBook Pro with the replaceable battery. And I have a pair of batteries for the machine. What a pain in the neck it is to have two batteries. The webs advice on battery storage is to keep Li-Ion batteries in a cool place at about 40% charge. Also, under no circumstances let your battery discharge to nothing. I have two batteries because I don’t want to be stuck on a trans-continental flight with no laptop but more and more airplanes have empower and a trans-continental length flight is only 5 hours of laptop time when you add it up. The new Apples advertise a 7 hour battery life. Mine does slightly better than 5 on each battery depending on the workload. So in the past few trips I’ve never gone on to the second battery. Given all these things the Empower to Magsafe charger is probably a better investment than a second battery.