talideon.com

Oysters are a fine thing, so are strawberries: but mashed together?

Entries for February 2007

February 2, 2007 at 12:05PM What should be done with eircom (and why ESB’s privatisation will fail)

Ever since eircom was privatised, I’ve had a bee in my bonnet about the way it was done.

To quote Mary Harney (and no, I’m not a PD), there’s only one thing worse than a public monopoly and that’s a private one. The single worst thing you can do in privatising a public company like eircom was is to privatise it wholesale.

When eircom was privatised, I was surprised that it wasn’t split into two companies, one to own and manage the network and another to handle the regular business of a telco.

For this arrangement to work properly, the network management company which would both manage and own the network would need to be a public company, a non-profit, or both, and the way it covered its expenses would need to be structured in such a way as to create a wider telecoms market. One method that I like is that any company would be allowed ongoing access to the network so long as it paid its dues to the network management company by (a) taking up network maintenance contracts in exchange for access, (b) taking up network expansion contracts in exchange for access, or (c) paying cold hard cash.

A regulator is not enough; a (proper) regulator is just a stick. You need a carrot too to encourage the market participants to play fair and to make it easy for new players to join.

The single best thing that could be done for the Irish telecoms market is for eircom to be split up upon such lines. Without doing so, the country’s progress will remain retarded by a powerful incumbent with no interest in giving up its dominant position.

Right now, the ESB, Ireland’s main electricity supplier, is being primed for privatisation. I don’t see it leading to a functioning market though: while EirGrid will manage the network, the ESB will still own the physical assets, creating yet another private monopoly.

Aside: I mentioned this on Irish Election back in October.

February 2, 2007 at 2:15PM Broadband!

With any luck, I should be getting online again soon. I put in an order with permaNET, who Niall says don’t completely completely suck. I’m going for the 2MB residential wireless, which should be just about sufficient. We’ll see.

And I’m well chuffed that the 0.5TB external HDD I ordered arrived for me at work today. It’s sweet!

February 5, 2007 at 2:18PM Getting a list of hostnames associated with a host.

I needed something for a shell script over the weekend to get a list the primary hostname and any aliases, all of them, I couldn’t think of any commands, and hostname doesn’t do quite what I wanted, so I knocked this out. It might be of use to somebody:

/*
 * hostnames.c
 * by Keith Gaughan (http://talideon.com/)
 *
 * Lists all the names associated with a given host (or the current one if
 * non is specified.
 *
 * Copyleft (k) Keith Gaughan, 2007.
 * All rights reversed. Do what you will with it, just don't come crying to
 * me if something bad happens.
 *
 * To compile, type: gcc -lc -Os -Wall -o hostnames hostnames.c
 * You might need an implementation of strlcpy().
 */

#include <stdio.h>
#include <unistd.h>
#include <netdb.h>
#include <string.h>

/* Sigh... */
#ifndef FALSE
#define FALSE 0
#define TRUE (!(FALSE))
#endif

static int quiet = FALSE;

static void echo(char* key, char* val) {
    if (quiet) {
        printf("%s\n", val);
    } else {
        printf("%s: %s\n", key, val);
    }
}

int main(int argc, char** argv) {
    char buf[250];
    struct hostent* h;
    char** aliases;
    int arg = 1;

    /* Check for quiet flag */
    if (argc > 1 && strcmp(argv[arg], "-q") == 0) {
        argc--;
        arg++;
        quiet = TRUE;
    }

    if (argc > 1) {
        /* Use the one passed in on the command line. */
        strlcpy(buf, argv[arg], sizeof buf);
    } else if (gethostname(buf, sizeof buf) != 0) {
        perror("Could not read host name");
        return 1;
    }

    h = gethostbyname(buf);
    if (h == NULL) {
        herror("Could not fetch host details");
        return 2;
    }
    echo("Official hostname", h->h_name);
    aliases = h->h_aliases;
    while (*aliases) {
        echo("Alias", *aliases);
        aliases++;
    }

    return 0;
}

Watch for the use of strlcpy(): you’ll need a copy, Linux boy.

February 6, 2007 at 11:20AM UMass Mounter: Part I

I’ve got a bit sick and tired of having to manually mount umass devices and frankly, neither HAL nor amd cut it for me, the former because it does an awful lot more than I really need and is only really usable within the confines of X, and the latter because it doesn’t really have the flexibility to deal with transient devices. Moreover, I don’t use GNOME or KDE and if you’re using HAL, you need an appropriate volume manager. Until somebody, possibly me, writes a volume manager that doesn’t depend on a particular desktop envirionment or that works with ROX (or ports ivman to FreeBSD), HAL is pretty much out of bounds.

I’ve been hunting for a decent way of dealing with the situation, but all I keep on running into are articles telling me to use amd. I did, however, stumble across one decent article which detailed how to use devd to detect a umass device being attached and detached. I was still left with a problem: how do I map the umass device reported to the appropriate SCSI device?

More digging around, and everyone I read was saying that the only way of getting it all to work was to do some awkward nonsense parsing the output from dmesg. That’s all well and fine if you don’t value your sanity, but I do.

I figured that seeing as umass devices end up being seen as SCSI devices by the rest of the world, the best thing to do would be to parse the output from camcontrol devlist -v, and what do you know, I was right. All the data I needed was there is a relatively mungeable format.

So to recap, we’re detecting the device being attached and detached, and we know which SCSI device we’re able to mount. Now all we need is somewhere to mount it.

/mnt is out of the question however because it’s only meant as a temporary mount point for use by the admin, however people might tend to abuse it. HAL does the right thing here by mounting everything under /media. In addition, we want to be able to mount multiple devices at once, so /mnt is dismissed for that reason too. The question arises, however, of what we’re going to call the mount points under /media.

Again, HAL, or more likely gnome-volume-manager, gets this right by using the volume labels as the names of the mount points. But there’s no trivial way under FreeBSD, or any *nix as best I know, to look this information up---it simply hasn’t been all that useful, at least not till now.

HAL might not be all that useful to me by itself, but I can always steal ideas from it, so I dug around the FreeBSD specific code to figure out how exactly it was managing to figure out the volume labels. I discovered it was using libvolume_id to dig out the data and I set about putting together a small wrapper around the library called volumeinfo to allow the umassaction script I’ll be coding up tomorrow---it responds to attach and detatch events---to figure out what it should call the mount point it’ll be creating. Here’s the code:

/*
 * volumeinfo.c
 * by Keith Gaughan (http://talideon.com/)
 *
 * A wrapper around libvolume_id for getting information about a volume
 * designated by a given special file.
 *
 * To compile (on FreeBSD), use:
 *
 *     gcc -Wall -Os -DNDEBUG \
 *         -I/usr/local/include/ -L/usr/local/lib/ -lvolume_id
 *         -o volumeinfo volumeinfo.c
 *     strip volumeinfo
 *
 * You will, of course, need libvolume_id.
 *
 * Copyright (c) Keith Gaughan, 2007.
 *
 * I'd like to put this under a BSD-style license, but because libvolume_id
 * is covered by the GPL and not a more reasonable license like the LGPL, I
 * guess this is, by extension, covered by the GPL. So until such time as I
 * know for certain...
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.     See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307     USA
 */

#include <assert.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <sys/disk.h>
#include <libvolume_id.h>

void write_pair(const char* name, const char* value) {
    assert(name != NULL);
    assert(value != NULL);

    if (strlen(value) > 0) {
        printf("%s: %s\n", name, value);
    }
}

struct volume_id* probe_node(const char* node) {
    struct volume_id* vid;
    off_t media_size;

    assert(node != NULL);

    vid = volume_id_open_node(node);
    if (vid) {
        ioctl(vid->fd, DIOCGMEDIASIZE, &media_size);
        if (volume_id_probe_all(vid, 0, media_size) != 0) {
            volume_id_close(vid);
            vid = NULL;
        }
    }

    return vid;
}

int main(int argc, char** argv) {
    struct volume_id* vid;

    if (argc < 2) {
        fprintf(stderr, "usage: volumeinfo special\n");
        return 1;
    }

    vid = probe_node(argv[1]);
    if (!vid) {
        fprintf(stderr, "error: Could not probe device\n");
        return 2;
    }

    write_pair("label", vid->label);
    write_pair("uuid", vid->uuid);
    write_pair("usage", vid->usage);
    write_pair("type", vid->type);
    write_pair("type-version", vid->type_version);

    volume_id_close(vid);

    return 0;
}

Pretty simple. As a fallback, I’ll be using the drive UUID if there’s no appropriate label available.

So the remaining problems are responding to the mount and unmount events, adding and removing entries from /etc/fstab to that mount is able to mount the device properly, setting the appropriate permissions and ownership on the mount point to allow the user to mount the thing at all, and finally, cleaning up after the device is detatched. And did I mention that my external HDD takes a fair while to spin up and that the thumb drive I have has two partitions, one of which thinks it’s a CD-ROM drive? But that’s all for tomorrow.

Update: Tweaked volumeinfo to give more info.

Update (2007-03-09): I may or may not pick up this project again, but since I decided to finally give GNOME a go, even if it means giving up ROX and using the utterly awful Nautilus (kids, if you want to see how a spatial file manager should work, see ROX-Filer), HAL’s been working well enough for me to put the project on hold. It still sucks though.

February 12, 2007 at 2:09PM Is it wrong to vote for myself?

IrishElection.com is up for Best Designed Blog in the Irish Blog Awards. Holy crap! Now, seeing as I’m the person who did the design, it’s be really wrong for me to go and vote for it... [smile]

And vote for Kaz too, while you’re at it. And Michele[1].

[1] Not that there’s even the slightest chance of getting a pay rise for that...

February 18, 2007 at 1:05AM Anything that uses a threaded libxml2 in the FreeBSD ports is horribly broken

It appears there’s a number of rather important ports that don’t do enough checking on what the build configuration they should use should be.

I’ve spent, on and off, a good chunk of today trying to figure out why some of my ports--the likes of GNOME 2 and PHP 5--weren’t building correctly. This was driving me demented. I was convinced that I was going something utterly retarded--a not entirely unlikely situation--when I was installing them.

Eventually I figured out what the problem was. I had WITH_THREADS=yes in my make.conf file because I need it for various reasons for various ports I’ve installed. When WITH_THREADS=yes, it appears that various ports doen’t bother to dereference the PTHREAD_LIBS variable in the command-line arguments for the compiler even when WITH_THREADS=yes is on. Smack, smack, smack, smack!

So, note to self: don’t set WITH_THREADS in make.conf; instead have it passed to make by portinstall. It’s a pain, but it’s safer and avoids retardedness.

To know if you’re having this problem yourself, check the autoconf log (config.log, IIRC) that portinstall will tell you about when the ./configure stage of the build fails. It’s a wee bit annoying that it doesn’t just tell you that the aclocal file for libxml2 doesn’t include a check for this and an actual diagnostic error when it fails. Anyway, you should find something like this:

/usr/local/lib/libxml2.so: undefined reference to `pthread_equal'

If you do, you’ve got a threaded libxml2 library and a port that uses it but is too dumb to check if it needs to link to pthreads or not.