[PATCH] mkswap: generate UUID

Rob Landley rob at landley.net
Thu Jun 18 21:58:53 UTC 2009


On Thursday 18 June 2009 10:47:56 Colin Watson wrote:
> Many modern Linux installers use UUIDs rather than device names to
> identify devices. This works better if mkswap sets a UUID.
>
> Signed-off-by: Colin Watson <cjwatson at ubuntu.com>
> ---
>  Makefile                            |    1 +
>  e2fsprogs/old_e2fsprogs/uuid/Kbuild |    1 +
>  util-linux/Kbuild                   |    2 ++
>  util-linux/mkswap.c                 |   13 +++++++++++++
>  4 files changed, 17 insertions(+), 0 deletions(-)
>
> diff --git a/Makefile b/Makefile
> index ffa6948..633711a 100644
> --- a/Makefile
> +++ b/Makefile
> @@ -451,6 +451,7 @@ libs-y		:= \
>  		coreutils/libcoreutils/ \
>  		debianutils/ \
>  		e2fsprogs/ \
> +		e2fsprogs/old_e2fsprogs/uuid/ \
>  		editors/ \
>  		findutils/ \
>  		init/ \

AAAAHHH!!!!!  KILL IT WITH FIRE!

Here's the uuid creation function I wrote for toybox a couple years back, 
after reading more standards documents than are strictly healthy to see what I 
could get away with _not_ doing:

// According to http://www.opengroup.org/onlinepubs/9629399/apdxa.htm
// we should generate a uuid structure by reading a clock with 100 nanosecond
// precision, normalizing it to the start of the gregorian calendar in 1582,
// and looking up our eth0 mac address.
//
// On the other hand, we have 128 bits to come up with a unique identifier, of
// which 6 have a defined value.  /dev/urandom it is.

static void create_uuid(char *uuid)
{
	// Read 128 random bits
	int fd = xopen("/dev/urandom", O_RDONLY);
	xreadall(fd, uuid, 16);
	close(fd);

	// Claim to be a DCE format UUID.
	uuid[6] = (uuid[6] & 0x0F) | 0x40;
	uuid[8] = (uuid[8] & 0x3F) | 0x80;

	// rfc2518 section 6.4.1 suggests if we're not using a macaddr, we should
	// set bit 1 of the node ID, which is the mac multicast bit.  This means we
	// should never collide with anybody actually using a macaddr.
	uuid[11] = uuid[11] | 128;
}

> +static void mkswap_generate_uuid(void *buf)
> +{
> +	uuid_t uuid_dat;
> +	char uuid_string[37];
> +
> +	uuid_generate(uuid_dat);
> +	memcpy(buf, uuid_dat, sizeof(uuid_dat));
> +	uuid_unparse(uuid_dat, uuid_string);

And here's a totally untested, off the top of my head guess at a uuid_unparse() 
that may have endianness issues but should at least be internally consistent.  
Probably has at least one major thinko, haven't even tried compiling it, but 
you get the idea:

void uuid_unparse(char *in, char *out)
{
	int i=0, fields[4,6,8,10,16], ipos=0, opos=0;

	for (;;) {
		opos += sprintf(out+opos, "%02x", in[ipos++]);

		if (ipos > fields[i]) {
			if (i++) {
				if (i==5) break;
				out[pos++]='-';
			}
		}
	}
}

Please please please please please don't resurrect bits of old_e2fsprogs.  
Rewriting it from scratch, fine.  Using it out of the old_ directory: ew.

Rob
-- 
Latency is more important than throughput. It's that simple. - Linus Torvalds


More information about the busybox mailing list