title: OpenBSD's hotplugd rocks!
date: 2023-04-13 11:41
tags: OpenBSD hotplugd usb
summary: Setting up an automount script for OpenBSD is pretty easy.
---

My last post talked about how I broke my OpenBSD laptop by telling OpenBSD that
my usbstick was essential to the boot process, and then, when I booted the
laptop, I did not have that usb stick mounted. That caused some problems. I
since learned that the preferred way of automounting a usb stick under OpenBSD
is with `hotplugd`.

[hotplugd](https://man.openbsd.org/hotplugd) is OpenBSD&rsquo;s automounting functionality, and it&rsquo;s actually super simple
and easy. Just put your scripts at `/etc/hotplugd/attach` and
`/etc/hotplugd/detach`. And the man page gives you an example shell script, but
since I am not a big fan of `sh` (its syntax is confusing), I decided to write
my attach script in [GNU Guile](https://www.gnu.org/software/guile/). Writing that script made me want to write more
scripts in [scheme shell](https://scsh.net/), but I the last time I tried to install the scheme shell
on OpenBSD, it failed to compile.

Anyway, it is really easy to write your own script.  `hotplugd` will call your
script like so:

    attach <number> <label>

where `<number>` is one of the numbers in the table below and `<label>` is a
short descriptive string of the device.

    |---+------------------------------------|
    | 0 | generic, no special info           |
    |---+------------------------------------|
    | 1 | CPU (carries resource utilization) |
    |---+------------------------------------|
    | 2 | disk drive                         |
    |---+------------------------------------|
    | 3 | network interface                  |
    |---+------------------------------------|
    | 4 | tape device                        |
    |---+------------------------------------|
    | 5 | serial line interface              |
    |---+------------------------------------|

I am only really interested in `2` and `3`. Here is how I debbuged my attach
script, and you can easily do the same.

First find out what `sd` device your usb stick is.  Before you put in your usb
stick type in:

    sysctl hw.disknames

    hw.disknames=sd0:ec557d42f5cbfa41,sd1:5583d235b610c8a2

Now put in your usb stick and run the same command.

    sysctl hw.disknames

    hw.disknames=sd0:ec557d42f5cbfa41,sd1:5583d235b610c8a2,sd2:

So now I know that my usb stick is sd2.  Let&rsquo;s do a disklabel command on it:

    # disklabel sd2

    # /dev/rsd2c:
    type: SCSI
    disk: SCSI disk
    label: USB Flash Drive
    duid: 0000000000000000
    flags:
    bytes/sector: 512
    sectors/track: 63
    tracks/cylinder: 255
    sectors/cylinder: 16065
    cylinders: 1887
    total sectors: 30326784
    boundstart: 0
    boundend: 30326784
    
    16 partitions:
    #                size           offset  fstype [fsize bsize   cpg]
      c:            14.5G                0  unused
      i:            14.5G             2048   MSDOS

Notice from the output that this label is &ldquo;USB Flash Drive&rdquo;.  That is the label
that hotplugd will send to your attach script.

If you want a usb stick that is read-able/writeable accross all operating
systems, currently you will want to use the [vfat](https://wiki.archlinux.org/title/FAT) filesystem. That is what the
output above shows. The `fstype` of `MSDOS` is a vfat filesystem. This usb stick
is what I will use when I want to copy data between different OS-es (I do want
an [encrypted OpenBSD-specific usb stick](https://www.openbsd.org/faq/faq14.html#softraidCrypto) to store my gpg keys, but I have not yet
set that up). According to some of the smart people on the `#openbsd` irc
channel, if you have such a usb stick, then the `i` filesystem partition is the
one that you want to mount to read the data. And we see that above as well (`c`
is code for the whole drive. `/dev/rsd2c` is how you access the whole and raw
disk).

Ok, so now that you know what arguments that `hotplugd` will send your script,
go ahead and write your basic script. It probably won&rsquo;t be perfect, which is ok.
To test it, type in `su` in your terminal to get to root account, and then test
your script in the exact same way that OpenBSD will use your script (`#` means
that you are currently the root user):

    # ./attach 2 "USB Flash Drive"

You will probably get some weird errors, and that&rsquo;s ok. After you have run your
attach script, and it seemed to have no errors, verify that it properly mounted
with:

    mount

    /dev/sd1a on / type ffs (local, softdep)
    /dev/sd1k on /home type ffs (local, nodev, nosuid, softdep)
    /dev/sd1d on /tmp type ffs (local, nodev, nosuid, softdep)
    /dev/sd1f on /usr type ffs (local, nodev, softdep)
    /dev/sd1g on /usr/X11R6 type ffs (local, nodev, softdep)
    /dev/sd1h on /usr/local type ffs (local, nodev, wxallowed, softdep)
    /dev/sd1j on /usr/obj type ffs (local, nodev, nosuid, softdep)
    /dev/sd1i on /usr/src type ffs (local, nodev, nosuid, softdep)
    /dev/sd1e on /var type ffs (local, nodev, nosuid, softdep)
    /dev/sd2i on /mnt/usb type msdos (local, nodev, noexec)

And it look like I properly mounted my usb stick (the last line says it was).

One thing that users might find confusing is that OpenBSD passes in `2`, but
Guile accepted the `2` as a string.

My simple [attach script](https://notabug.org/jbranso/prog/src/master/gnu/guile/scripts/attach) works for me.  It will only auto mount vfat filesystems,
and I am pretty sure that weird things will happen if I plug in two usb sticks
at once, but it works.

