Printable Singularity Chess

2014-04-08 23:58 - General

Some short while back, I discovered Singularity Chess. A chess variant where the board has been warped by a singularity (i.e. black hole), thus all of the "squares" are actually rounded, causing moves to be warped around curves where they would normally move in straight lines.

It seemed interesting, but I couldn't try it out for myself effectively. I couldn't find anything to download online to make it easier. So I decided to make one. I grabbed the first image of the board, then rotated and perspective corrected it to be a more perfect shot from directly above. (I assumed the four visible corners were originally rectangular for this step.) Then I started measuring the dimensions of the image I produced.

The result is the SVG image singularity-chess-v1.xml. It looks just like the beautiful wooden board from the original post, but it should be cheap and easy to print out, to try the game with a lower barrier to entry. It is intended to fit onto 11x17" paper, but letter (8.5x11") would work in a pinch, if you have small pieces.

Peanut Butter Brownies

2014-03-07 20:26 - General

Peanut butter brownies. I made some peanut butter brownies. Yum. Place smells great. Now I just have to wait for them to cool down!


Gran Turismo 6: All Stars

2014-02-19 22:53 - Gaming

Gran Turismo 6: All stars!

I got Gran Turismo 6 for Xmas, and have been playing it since, about seven weeks. I just got the last of 573 stars (first place in all of the career mode races). And I've done most (but certainly not all) of the optional mission races. Either way, I think it's time to call this game done. Phew. Some of those stars were tough to get, especially the last two dozen.

I Know 79% Of the English Language

2014-01-30 16:37 - General

I just found a scientific Vocabulary Test online. I scored 79% (detected 86% of actual words, failed on 7% of non-words). Which is "a high level for a native speaker".

UDF For Portable Storage

2014-01-04 12:54 - Tech

I swear I looked into this a few years ago, and decided not to. But I did again recently. Most USB storage devices are used with FAT32, which is unpleasant for a variety of reasons. I found one page with a great summary of why both FAT32 is awful and UDF is better. It's from this year, and new to me. I also found another page with more technical detail and a complicated Perl script to do the formatting, with some tricks to improve interoperability. It's older. I probably saw it before.

I think this boils down to the fact that Windows XP cannot write to UDF. Back the last time I looked into this, I figure I cared about that too much to switch. Nowadays though I interact mostly with Windows 7, plus some Mac and Linux. I've tried it out, and so far it is absolutely the case that it "just works" and very pleasantly. I have a couple 2GB thumb drives and a 1TB external disk both formatted to UDF now, and they're working quite well across all three platforms.

Installing Gentoo Into a LUKS-Encrypted ZFS Root

2013-12-31 14:31 - Linux

This is a continuation of my earlier explorations booting from a LUKS encrypted disk. This time, I'm booting Gentoo Linux from a LUKS encrypted ZFS volume. I won't go into why in detail (others do that at length elsewhere), but I do like the checksumming and snapshotting that ZFS provides. I'm still re-working my backup system to function through ZFS snapshots, but my progress so far is already great.

I've now done this procedure twice for real (my server at home, and the remote server in my Mom's basement to serve as the off-site backup). And of course, I learned and tweaked as I was doing so. I took notes, and I'm doing it a third time in a virtual machine to make sure I got all the details right. The first time I figured out booting from LUKS it was really helpful, even just for me to refer to again later. You'll best start with my Gentoo minimal install LiveCD patched with ZFS support. Any bootable 64-bit ZFS enabled media will do, but that's easy and familiar if you've done Gentoo before. Note however that this is a simple cookbook style reference, not a tutorial. If you don't already know ZFS, you'd do very well to read up on it. I have a collection of links at the end for lots more detail.

Work through the Gentoo Handbook until section four. My disk scheme is: three 2TB disks in a RAIDZ1 pool, with LUKS encryption underneath. They're all the same model and thus the same size. Additionally another small disk to hold the (unencrypted) boot. I started testing with a plain old USB flash drive, and later switched to a Compact Flash to IDE adapter as a cheap/small/low power fake SSD. So in my case sda, sdb, and sdc are the main three drives, while sdd is the (USB) boot drive. Setting them up looks like:

(A quick note on the examples before this first one: The shell prompts are colored red, the inputs I type are colored green, and the rest is the output. Your output will likely differ in small details; I'm trusting you to be intelligent enough to figure that out if you're following this as a guide. But I find archiving the output still makes it easier to follow along. Your inputs may differ as well, be careful to make sure you are referencing (e.g.) the proper disk!)

livecd ~ # fdisk /dev/sdd
Welcome to fdisk (util-linux 2.22.2).

Changes will remain in memory only, until you decide to write them.
Be careful before using the write command.

Device does not contain a recognized partition table
Building a new DOS disklabel with disk identifier 0x14d61137.

Command (m for help): p

Disk /dev/sdd: 1073 MB, 1073741824 bytes, 2097152 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x14d61137

   Device Boot      Start         End      Blocks   Id  System

Command (m for help): n
Partition type:
   p   primary (0 primary, 0 extended, 4 free)
   e   extended
Select (default p):
Using default response p
Partition number (1-4, default 1):
Using default value 1
First sector (2048-2097151, default 2048):
Using default value 2048
Last sector, +sectors or +size{K,M,G} (2048-2097151, default 2097151):
Using default value 2097151
Partition 1 of type Linux and of size 1023 MiB is set

Command (m for help): w
The partition table has been altered!

Calling ioctl() to re-read partition table.
Syncing disks.
livecd ~ # mkfs.ext2 /dev/sdd1
mke2fs 1.42.7 (21-Jan-2013)
Filesystem label=
OS type: Linux
Block size=4096 (log=2)
Fragment size=4096 (log=2)
Stride=0 blocks, Stripe width=0 blocks
65536 inodes, 261888 blocks
13094 blocks (5.00%) reserved for the super user
First data block=0
Maximum filesystem blocks=268435456
8 block groups
32768 blocks per group, 32768 fragments per group
8192 inodes per group
Superblock backups stored on blocks:
        32768, 98304, 163840, 229376

Allocating group tables: done
Writing inode tables: done
Writing superblocks and filesystem accounting information: done

A note here on encryption passphrases. I've elected to use the same passphrase on all three disks. Later, I set it up so that I only have to type this passphrase once upon boot to unlock all three. I suggest you do the same. Also note: yes, I am encrypting the entire raw disk here, on purpose. ZFS does not need partitions, just a block device to store its data. The boot disk is partitioned however, to give GRUB room to install.

livecd ~ # cryptsetup luksFormat /dev/sda

WARNING!
========
This will overwrite data on /dev/sda irrevocably.

Are you sure? (Type uppercase yes): YES
Enter passphrase:
Verify passphrase:
livecd ~ # cryptsetup luksFormat /dev/sdb

WARNING!
========
This will overwrite data on /dev/sdb irrevocably.

Are you sure? (Type uppercase yes): YES
Enter passphrase:
Verify passphrase:
livecd ~ # cryptsetup luksFormat /dev/sdb

WARNING!
========
This will overwrite data on /dev/sdb irrevocably.

Are you sure? (Type uppercase yes): YES
Enter passphrase:
Verify passphrase:
livecd ~ # cryptsetup luksOpen /dev/sda crypt1
Enter passphrase for /dev/sda:
livecd ~ # cryptsetup luksOpen /dev/sdb crypt2
Enter passphrase for /dev/sdb:
livecd ~ # cryptsetup luksOpen /dev/sdc crypt3
Enter passphrase for /dev/sdc:

So now we have three encrypted disks called crypt1, crypt2, and crypt3. We can set up a zpool with them, and data sets within that pool.

livecd ~ # zpool create -m none -o ashift=12 -o cachefile= -O atime=off -O compression=lz4 -O xattr=sa -R /mnt/gentoo rpool raidz1 crypt1 crypt2 crypt3

This complicated command will:

-m none
Not mount this pool.
-o ashift=12
Set the block size. (Check an e.g. fdisk -l /dev/sda. Mine says Sector size (logical/physical): 512 bytes / 4096 bytes, which shows that the disk's physical sectors are 4k. The ashift=12 means sector sizes of 212, or 4k. If your sectors are 512 bytes, you should omit this.
-o cachefile=
Not create a cachefile. These can speed up the zpool import (i.e. "mount") phase. With just three vdevs in the pool, I find this unnecessary, and skipping the complication is better.
-O atime=off
Not record access times.
-O compression=lz4
Turn on compression. This is a good idea. Modern processors tend to have more spare resources than modern disks. This compression algorithm specifically is lightweight, but acheives nice ratios on appropriate content.
-O xattr=sa
Store extended attributes in inodes rather than hidden files. Which is supposed to make Samba more performant.
-R /mnt/gentoo
Sets the "altroot", i.e. the temporary alternative mount point. This value is appropriate for the Handbook driven install process.
rpool
The name of the pool.
raidz1
The type of the pool.
crypt1 crypt2 crypt3
The devices making up this pool; ZFS can find them just by these short names (which are unlikely to otherwise exist) and their brevity will make other output easier to read.

And in good Unix tradition, produces no output upon success. Now to create the datasets within the pool. ZFS datasets are heirarchical. I've created two top level data sets: root and tmp. The first gets regular snapshots (via zfs-auto-snapshot), which get replicated off site. The latter does not, because it contains only files that are easy to replace (linux kernel source, portage) or are not worth backing up (large scratch files, media archives).

livecd ~ # zfs create -o mountpoint=/ rpool/root
livecd ~ # zfs create -o mountpoint=/var -o devices=off -o exec=off -o setuid=off rpool/root/var
livecd ~ # zfs create -o mountpoint=/home/user rpool/root/home/user
livecd ~ # zfs create -o mountpoint=none rpool/tmp
livecd ~ # zfs create -o mountpoint=/tmp -o devices=off -o exec=off -o setuid=off rpool/tmp/root
livecd ~ # zfs create -o mountpoint=/home/user/tmp -o devices=off -o exec=off -o setuid=off rpool/tmp/user
livecd ~ # zfs create -o mountpoint=/usr/src rpool/tmp/linux-src
livecd ~ # zfs create -o mountpoint=/usr/portage rpool/tmp/portage
livecd ~ # zfs create -o mountpoint=/var/tmp rpool/tmp/var

Note that ZFS will auto-mount these data sets at the given mount points (relative to the altroot specified at zpool creation). Fill in the actual name for "user". Also optionally (but recommended) set up swap.

livecd ~ # zfs create -o sync=always -o primarycache=metadata -o secondarycache=none -o volblocksize=4K -V 1G rpool/swap
livecd ~ # mkswap -f /dev/zvol/rpool/swap
Setting up swapspace version 1, size = 1048572 KiB
no label, UUID=c072e84f-08bc-4fbb-9e65-0c1ba83a85bc
livecd ~ # swapon /dev/zvol/rpool/swap

Continue with section 4.f (mounting) of the handbook, but remember that the ZFS data sets are already mounted.

livecd ~ # mkdir /mnt/gentoo/boot
livecd ~ # mount /dev/sdd1 /mnt/gentoo/boot
livecd ~ # chmod 1777 /mnt/gentoo/tmp
livecd ~ # cd /mnt/gentoo

We're doing a standard Gentoo install now, from section 5.

At section 7a, use genkernel. We'll need to use a custom linuxrc in order to luksOpen all three of our encrypted drives at the right point (before it tries to mount our ZFS root). We must also build a valid kernel before we can (build and) install the ZFS kernel modules. So:

(chroot) livecd ~ # echo "sys-kernel/genkernel cryptsetup" >> /etc/portage/package.use
(chroot) livecd ~ # echo "sys-fs/lvm2 -thin" >> /etc/portage/package.use
(chroot) livecd ~ # emerge -va genkernel gentoo-sources

These are the packages that would be merged, in order:
...
(chroot) livecd ~ # genkernel --makeopts=-j6 bzImage
(chroot) livecd ~ # cat >> /etc/portage/package.accept_keywords
# required by zfs (argument)
=sys-fs/zfs-0.6.2-r3 ~amd64
# required by sys-fs/zfs-kmod-0.6.2-r3
# required by sys-fs/zfs-0.6.2-r3
# required by zfs (argument)
=sys-kernel/spl-0.6.2-r2 ~amd64
# required by sys-fs/zfs-0.6.2-r3
# required by zfs (argument)
=sys-fs/zfs-kmod-0.6.2-r3 ~amd64
^D
(chroot) livecd ~ # emerge -va zfs

These are the packages that would be merged, in order:
...
(chroot) livecd ~ # rc-update add zfs boot
(chroot) livecd ~ # cp /usr/share/genkernel/defaults/linuxrc /root/linuxrc.orig
(chroot) livecd ~ # cp /usr/share/genkernel/defaults/linuxrc /root/linuxrc
(chroot) livecd ~ # vi /root/linuxrc

Find the line that says just startVolumes. Immediately before that, add:

CRYPT_NUM=0
luks_open() {
  DISK="$1"
  PASSPHRASE="$2"
  cryptsetup isLuks "$DISK" || return
  CRYPT_NUM=$(( CRYPT_NUM + 1))
  good_msg "Opening $DISK as crypt${CRYPT_NUM} ..."
  echo "$PASSPHRASE" | cryptsetup luksOpen "$DISK" crypt$CRYPT_NUM
  test_success "luksOpen $DISK"
}
echo -n "Please enter LUKS passphrase: "
read -s PASSPHRASE
echo
for D in /dev/sd?; do
  luks_open "$D" "$PASSPHRASE"
done
unset CRYPT_NUM D PASSPHRASE

The result is that the three encrypted disks will be unlocked immediately before the ZFS pool is imported. This technique does unfortunately read in the LUKS passphrase in a shell script, and echo it (via the command line) into cryptsetup. Putting sensitive data like a passphrase onto the command line like this is normally a big security no-no. I'm comfortable with this simply because it exists only inside the initramfs; any attacker capable of monitoring closely enough to catch the passphrase at this point (by its presence on the command line) can mount a simpler and equally effective attack. If you're uncomfortable with that, you can simply omit the reading and echoing of $PASSPHRASE (and thus be forced to type it three times instead).

Now, be sure to call genkernel like:

(chroot) livecd ~ # genkernel --makeopts=-j6 --no-clean --menuconfig --luks --zfs --linuxrc=/root/linuxrc --callback="emerge @module-rebuild" all

Some of these flags can instead be permanently set via /etc/genkernel.conf but not (as far as I know) the --zfs nor --linuxrc flags, both of which are critical. The rebuild callback is probably only necessary this first time.

Continue with the handbook. The fstab should be empty besides /boot and swap. In section 10, be sure to pick legacy grub. (I had trouble with grub2 failing with a segmentation fault while trying to probe the ZFS system. Even though it shouldn't need to do that at all.) The file /boot/grub/grub.conf should contain a section like:

title Gentoo Linux
root (hd0,0)
kernel /boot/kernel dozfs=force real_root=ZFS=rpool/root
initrd /boot/initramfs

Make sure that /boot/kernel and /boot/initramfs actually exist (symlinks are nice), or edit to match the correct actually installed file. Unfortunately we really do need to dozfs=force. Linux seems unable to cleanly export (i.e. unmount) the root file system partition. Forcing the import is the only way I know to make things work. The file /boot/grub/device.map should contain only one line:

(hd3)    /dev/sdd

Otherwise it will try to search all the other (LUKS encrypted) drives for partitions, and get confused. (Note that the whitespace is a tab character.) Then install GRUB:

(chroot) livecd ~ # cat /proc/mounts | grep -v rootfs > /etc/mtab
(chroot) livecd ~ # grub-install /dev/sdd
Installation finished. No error reported.
This is the contents of the device map /boot/grub/device.map.
Check if this is correct or not. If any of the lines is incorrect,
fix it and re-run the script `grub-install'.

(hd3)    /dev/sdd

Carefully note the confusing grub disk references. The grub config is used early during the boot process, while the BIOS has mapped the USB drive containing /boot to the first (i.e. (hd0)) visible device. Once the kernel has booted, it picks a different order for things, and will put the SATA drives first (sda, sdb, sdc) and later enumerate the USB drive (sdd). Since we're running the grub-install command under a booted kernel, the same (hd0,0) that we referenced in the config is now (hd3) under a running system.

Continue from handbook section 10.e. Done!

Appendix: Recovery

Should you ever need to reboot during installation, or later boot from the livecd for recovery, it would go something like this:

livecd ~ # rmmod floppy
livecd ~ # cryptsetup luksOpen /dev/sda crypt1
livecd ~ # cryptsetup luksOpen /dev/sdb crypt2
livecd ~ # cryptsetup luksOpen /dev/sdc crypt3
livecd ~ # zpool import -fR /mnt/gentoo rpool
livecd ~ # mount /dev/sdd1 /mnt/gentoo/boot
livecd ~ # mount -t proc none /mnt/gentoo/proc
livecd ~ # mount --rbind /dev /mnt/gentoo/dev
livecd ~ # mount --rbind /sys /mnt/gentoo/sys
livecd ~ # chroot /mnt/gentoo /bin/bash

The floppy module seems to get auto-loaded even though the machine has no floppy drive, and this causes zpool import to hang while trying to check if it should open a vdev on fd0. So first remove it. The luksOpen lines unlock the encrypted volumes, then we mount all the other required paths and chroot into it.

Appendix: Links

I relied on a number of existing sources to figure out how to do this. Most of this information came from Gentoo Hardened ZFS rootfs with dm-crypt/luks 0.6.2 which is quite similar to this article. I added some more details from the Funtoo wiki's ZFS Install Guide and the Gentoo wiki's ZFS page.

Steering Wheel Jig v2.0

2013-12-24 12:17 - Gaming

The first bit of planning, measuring the side of the coffee table. The second bit of planning, using trigonometry to figure out the measurements I didn Figuring out how to assemble the removable portion. Figuring out how to join the angled platform onto the end of the jig.

The final assembled steering wheel jig. Detail view of the platform. Detail view of the joint.

I'm anticipating a gift of Gran Turismo 6 tomorrow. Back when I was playing Gran Turismo 5 I got a steering wheel controller and made a jig to clamp it onto a chair at just the right height. I learned pretty quickly how uncomfortable sitting on a bare wooden chair gets while driving. So for a while I've had the inkling of a plan to build something better.

The idea was to take the existing comfy couch I have, plus the coffee table sitting in front of it. The jig now hangs back towards me from the coffee table, rather than forward from underneath the chair. I did this briefly while the demo was out with my existing set up, and I learned two things: putting it at the right height for driving makes it very hard to get in and out of the couch (plus blocks the TV for normal watching) and the existing jig was too short to reach, I had to awkwardly move the table closer.

So I started by taking measurements of the table. And how far away the couch is normally. I brought only that with me when I came to New Jersey to visit my mom for the holidays, where plenty of materials and tools are available. Then I realized I had to do some trigonometry to figure out the measurements that actually matter. Which gave me around 54" total length and 24" across the width of the table, minimum. I decided that I wanted to address the obstruction that it caused somehow. At first I figured the easiest thing would be hinges to lift it out of the way easily, but worried about the strength of that. So I ended up with a simple "knuckle" joint that detaches.

The final product is a length of two by four that will get clamped to the legs of the table, ending in the joint. The other half contains the platform, angled to remain flat as installed, which slots into that joint with a retaining pin. Besides a bit of the total length and angles I actually did most of the measurements by eye, and I'm quite pleased with how it all turns out. I might end up needing to add a support brace under the knuckle, if it all ends up too heavy for the table to counter balance (the jig itself is right around 10 pounds, total). But that should be easy enough to take care of later, and the old jig will provide plenty of raw material.

Building a Gentoo Minimal LiveCD with ZFS support

2013-12-18 21:51 - Linux

I've used Gentoo Linux on my servers for some time. A few years back I learned how to set up encryption via LUKS over the whole root partition. Now I'm trying to use ZFS as my root file system and keep LUKS for encryption. The first thing I needed was a bootable install environment with support for both ZFS and LUKS. The only one I could find was the Gentoo LiveDVD, but that's over a year old. I've tried using it in tests, and it causes the whole machine to hang quite often.

I found an old repository that claimed to provide straightforward instructions to build a regular Gentoo install CD with ZFS support. But it was even older than the live DVD. So old that I couldn't get it to build correctly. This pointed me towards the Gentoo Catalyst build system, however. I found the source for Gentoo releng, where the catalyst tool which makes the Gentoo installation media is developed. And I updated it to support ZFS. I've made those changes available, so you should be able to:

# cd /root
# git clone https://github.com/arantius/gentoo-releng.git releng
# cd releng
# git checkout -t origin/zfs
# mkdir -p /var/tmp/catalyst/builds/default
# wget ... -O /var/tmp/catalyst/builds/default/stage3-amd64-latest.tar.bz2
# catalyst -s latest
# catalyst -v -f releng/releases/weekly/specs/amd64/installcd-stage1.spec
# catalyst -v -f releng/releases/weekly/specs/amd64/installcd-stage2-minimal.spec

Customizing of course that wget line, maybe even using links interactively. Just make sure the stage3 snapshot ends up at exactly that path. Also note that you really must put these files at /root/releng, as they contain hard coded references to that absolute path. If you don't already have a working Gentoo instance, this will work perfectly fine in a virtual machine. I actually built the ISO I'm using now from within a virtualboxes.org image for Gentoo. For me, stage 1 took just under 2 hours, and stage 2 about half an hour. An ISO image should now be located in /var/tmp/catalyst/builds/default/.

Finally, I'm making the fully built ISO image I created available for download. See this salient note on licensing. Download gentoo-install-amd64-minimal-20131205.zfs.iso; MD5 6b70a2109b323c077c458c72dcf09c83; SHA1 f36d8454da1ab4c889615085bb97d2070e2d99d0.

Gentoo Boot via YUMI

2013-12-07 19:15 - Linux

In pursuit of other things, I recently figured out how to get the Gentoo live media to work with YUMI, a tool to put multiple boot media onto a single bootable USB drive. It supports a wide range of tools natively, but not any of the bootable Gentoo media. It does have a "Try Unlisted ISO" option. These appear at first not to work with Gentoo media. They just need some tweaking.

First let me mention in passing the tool Rufus, which will format, and optionally install a single bootable media, USB drives. It's really nice, but I want to use YUMI to install multiple bootable tools onto one drive.

The first thing you'll need is the bootable ISO images to start with. I've been working with the amd64 64-bit bootable media recently. The Gentoo LiveDVD named livedvd-amd64-multilib-20121221.iso, and the Gentoo minimal LiveCD named install-amd64-minimal-20131010.iso. (The minimal LiveCD is small and fast. The LiveDVD is the only bootable linux media I currently know of with both LUKS and ZFS support.)

First open YUMI. Let it properly FAT format this USB drive and set it bootable. Then pick "Try Unlisted ISO (via SYSLINUX)" as the distribution to install, pick the right ISO, and let it go. When I do this, I'm left with E:\multiboot\install-amd64-minimal-20131010 filled with the files that the ISO contained. Some of these files assume they are at the root of the drive, but YUMI has changed this. That's what we need to fix, to make it work again.

Within this directory that YUMI put the LiveCD in, find the isolinux directory, and the isolinux.cfg file there. There should be two lines looking something like:

  append root=/dev/ram0 init=/linuxrc  dokeymap looptype=squashfs loop=/image.squashfs  cdroot initrd=gentoo.igz vga=791

We need to fix the loop= parameter, to point to that file's location within the USB drive. I edited that line to look like:

  append root=/dev/ram0 init=/linuxrc  dokeymap looptype=squashfs loop=/multiboot/install-amd64-minimal-20131010/image.squashfs  cdroot initrd=gentoo.igz vga=791

Plus the same changes to the gentoo-nofb entry. Finally, we need to move the (empty) livecd file up to the top of the USB drive. This is how the Gentoo LiveCD boot system validates that it has found the drive it expects. As far as I can tell, it will only look in the root.

At this point you can follow the same steps for the LiveDVD. Which like I said has ZFS support, and also is a full/graphical live linux environment.