o Provide a private definition for UUIDs (mkimg_uuid_t) because

UUIDs are not portable.
 o  Move mkimg_uuid() to a new file and merge both gpt_uuid_enc()
    and vhd_uuid_enc() into a single mkimg_uuid_enc() that lives
    in the same file.
 o  Move the OS-specific implementation of generating a UUID to
    osdep_uuidgen() and provide the implementations for FreeBSD,
    macOS and Linux.
 o  Expect the partitioning scheme headers to be found by having
    a search to the directory in which the headers live. This
    avoids conflicts on non-FreeBSD machines.
This commit is contained in:
Marcel Moolenaar 2016-10-18 01:55:07 +00:00
parent e7c08366e7
commit 4299711473
12 changed files with 168 additions and 81 deletions

View File

@ -3,15 +3,15 @@
.include <src.opts.mk>
PROG= mkimg
SRCS= format.c image.c mkimg.c scheme.c
SRCS= format.c image.c mkimg.c scheme.c uuid.c
MAN= mkimg.1
MKIMG_VERSION=20151211
MKIMG_VERSION=20161016
mkimg.o: Makefile
CFLAGS+=-DMKIMG_VERSION=${MKIMG_VERSION}
CFLAGS+=-DSPARSE_WRITE
CFLAGS+=-I${.CURDIR:H:H}/sys
CFLAGS+=-I${SRCTOP}/sys/sys/disk
# List of formats to support
SRCS+= \

View File

@ -33,7 +33,7 @@ __FBSDID("$FreeBSD$");
#include <string.h>
#include <unistd.h>
#include <sys/disk/apm.h>
#include <apm.h>
#include "endian.h"
#include "image.h"

View File

@ -33,7 +33,7 @@ __FBSDID("$FreeBSD$");
#include <string.h>
#include <unistd.h>
#include <sys/disk/bsd.h>
#include <bsd.h>
#include "endian.h"
#include "image.h"

View File

@ -33,7 +33,7 @@ __FBSDID("$FreeBSD$");
#include <string.h>
#include <unistd.h>
#include <sys/disk/mbr.h>
#include <mbr.h>
#include "endian.h"
#include "image.h"

View File

@ -33,26 +33,25 @@ __FBSDID("$FreeBSD$");
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <uuid.h>
#include <sys/disk/gpt.h>
#include <sys/disk/mbr.h>
#include <gpt.h>
#include <mbr.h>
#include "endian.h"
#include "image.h"
#include "mkimg.h"
#include "scheme.h"
static uuid_t gpt_uuid_efi = GPT_ENT_TYPE_EFI;
static uuid_t gpt_uuid_freebsd = GPT_ENT_TYPE_FREEBSD;
static uuid_t gpt_uuid_freebsd_boot = GPT_ENT_TYPE_FREEBSD_BOOT;
static uuid_t gpt_uuid_freebsd_nandfs = GPT_ENT_TYPE_FREEBSD_NANDFS;
static uuid_t gpt_uuid_freebsd_swap = GPT_ENT_TYPE_FREEBSD_SWAP;
static uuid_t gpt_uuid_freebsd_ufs = GPT_ENT_TYPE_FREEBSD_UFS;
static uuid_t gpt_uuid_freebsd_vinum = GPT_ENT_TYPE_FREEBSD_VINUM;
static uuid_t gpt_uuid_freebsd_zfs = GPT_ENT_TYPE_FREEBSD_ZFS;
static uuid_t gpt_uuid_mbr = GPT_ENT_TYPE_MBR;
static uuid_t gpt_uuid_ms_basic_data = GPT_ENT_TYPE_MS_BASIC_DATA;
static mkimg_uuid_t gpt_uuid_efi = GPT_ENT_TYPE_EFI;
static mkimg_uuid_t gpt_uuid_freebsd = GPT_ENT_TYPE_FREEBSD;
static mkimg_uuid_t gpt_uuid_freebsd_boot = GPT_ENT_TYPE_FREEBSD_BOOT;
static mkimg_uuid_t gpt_uuid_freebsd_nandfs = GPT_ENT_TYPE_FREEBSD_NANDFS;
static mkimg_uuid_t gpt_uuid_freebsd_swap = GPT_ENT_TYPE_FREEBSD_SWAP;
static mkimg_uuid_t gpt_uuid_freebsd_ufs = GPT_ENT_TYPE_FREEBSD_UFS;
static mkimg_uuid_t gpt_uuid_freebsd_vinum = GPT_ENT_TYPE_FREEBSD_VINUM;
static mkimg_uuid_t gpt_uuid_freebsd_zfs = GPT_ENT_TYPE_FREEBSD_ZFS;
static mkimg_uuid_t gpt_uuid_mbr = GPT_ENT_TYPE_MBR;
static mkimg_uuid_t gpt_uuid_ms_basic_data = GPT_ENT_TYPE_MS_BASIC_DATA;
static struct mkimg_alias gpt_aliases[] = {
{ ALIAS_EFI, ALIAS_PTR2TYPE(&gpt_uuid_efi) },
@ -126,21 +125,6 @@ crc32(const void *buf, size_t sz)
return (crc ^ ~0U);
}
static void
gpt_uuid_enc(void *buf, const uuid_t *uuid)
{
uint8_t *p = buf;
int i;
le32enc(p, uuid->time_low);
le16enc(p + 4, uuid->time_mid);
le16enc(p + 6, uuid->time_hi_and_version);
p[8] = uuid->clock_seq_hi_and_reserved;
p[9] = uuid->clock_seq_low;
for (i = 0; i < _UUID_NODE_LEN; i++)
p[10 + i] = uuid->node[i];
}
static u_int
gpt_tblsz(void)
{
@ -194,7 +178,7 @@ gpt_write_pmbr(lba_t blks, void *bootcode)
static struct gpt_ent *
gpt_mktbl(u_int tblsz)
{
uuid_t uuid;
mkimg_uuid_t uuid;
struct gpt_ent *tbl, *ent;
struct part *part;
int c, idx;
@ -205,9 +189,9 @@ gpt_mktbl(u_int tblsz)
TAILQ_FOREACH(part, &partlist, link) {
ent = tbl + part->index;
gpt_uuid_enc(&ent->ent_type, ALIAS_TYPE2PTR(part->type));
mkimg_uuid_enc(&ent->ent_type, ALIAS_TYPE2PTR(part->type));
mkimg_uuid(&uuid);
gpt_uuid_enc(&ent->ent_uuid, &uuid);
mkimg_uuid_enc(&ent->ent_uuid, &uuid);
le64enc(&ent->ent_lba_start, part->block);
le64enc(&ent->ent_lba_end, part->block + part->size - 1);
if (part->label != NULL) {
@ -238,7 +222,7 @@ gpt_write_hdr(struct gpt_hdr *hdr, uint64_t self, uint64_t alt, uint64_t tbl)
static int
gpt_write(lba_t imgsz, void *bootcode)
{
uuid_t uuid;
mkimg_uuid_t uuid;
struct gpt_ent *tbl;
struct gpt_hdr *hdr;
uint32_t crc;
@ -275,7 +259,7 @@ gpt_write(lba_t imgsz, void *bootcode)
le64enc(&hdr->hdr_lba_start, 2 + tblsz);
le64enc(&hdr->hdr_lba_end, imgsz - tblsz - 2);
mkimg_uuid(&uuid);
gpt_uuid_enc(&hdr->hdr_uuid, &uuid);
mkimg_uuid_enc(&hdr->hdr_uuid, &uuid);
le32enc(&hdr->hdr_entries, nparts);
le32enc(&hdr->hdr_entsz, sizeof(struct gpt_ent));
crc = crc32(tbl, nparts * sizeof(struct gpt_ent));

View File

@ -33,7 +33,7 @@ __FBSDID("$FreeBSD$");
#include <string.h>
#include <unistd.h>
#include <sys/disk/mbr.h>
#include <mbr.h>
#include "endian.h"
#include "image.h"

View File

@ -28,7 +28,6 @@
__FBSDID("$FreeBSD$");
#include <sys/stat.h>
#include <sys/uuid.h>
#include <errno.h>
#include <err.h>
#include <fcntl.h>
@ -374,22 +373,6 @@ mkimg_chs(lba_t lba, u_int maxcyl, u_int *cylp, u_int *hdp, u_int *secp)
*secp = sec;
}
void
mkimg_uuid(struct uuid *uuid)
{
static uint8_t gen[sizeof(struct uuid)];
u_int i;
if (!unit_testing) {
uuidgen(uuid, 1);
return;
}
for (i = 0; i < sizeof(gen); i++)
gen[i]++;
memcpy(uuid, gen, sizeof(uuid_t));
}
static int
capacity_resize(lba_t end)
{

View File

@ -30,6 +30,7 @@
#define _MKIMG_MKIMG_H_
#include <sys/queue.h>
#include <sys/types.h>
struct part {
TAILQ_ENTRY(part) link;
@ -89,7 +90,17 @@ ssize_t sparse_write(int, const void *, size_t);
void mkimg_chs(lba_t, u_int, u_int *, u_int *, u_int *);
struct uuid;
void mkimg_uuid(struct uuid *);
struct mkimg_uuid {
uint32_t time_low;
uint16_t time_mid;
uint16_t time_hi_and_version;
uint8_t clock_seq_hi_and_reserved;
uint8_t clock_seq_low;
uint8_t node[6];
};
typedef struct mkimg_uuid mkimg_uuid_t;
void mkimg_uuid(mkimg_uuid_t *);
void mkimg_uuid_enc(void *, const mkimg_uuid_t *);
#endif /* _MKIMG_MKIMG_H_ */

View File

@ -33,7 +33,7 @@ __FBSDID("$FreeBSD$");
#include <string.h>
#include <unistd.h>
#include <sys/disk/pc98.h>
#include <pc98.h>
#include "endian.h"
#include "image.h"

125
usr.bin/mkimg/uuid.c Normal file
View File

@ -0,0 +1,125 @@
/*-
* Copyright (c) 2016 Marcel Moolenaar
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include "endian.h"
#include "image.h"
#include "mkimg.h"
static void osdep_uuidgen(mkimg_uuid_t *);
#ifdef __APPLE__
#include <uuid/uuid.h>
static void
osdep_uuidgen(mkimg_uuid_t *uuid)
{
uuid_generate_time((void *)uuid);
}
#endif /* __APPLE__ */
#ifdef __FreeBSD__
#include <sys/uuid.h>
static void
osdep_uuidgen(mkimg_uuid_t *uuid)
{
uuidgen((void *)uuid, 1);
}
#endif /* __FreeBSD__ */
#ifdef __linux__
#include <stdlib.h>
#include <time.h>
static void
osdep_uuidgen(mkimg_uuid_t *uuid)
{
struct timespec tp;
uint64_t time = 0x01B21DD213814000LL;
u_int i;
uint16_t seq;
if (clock_gettime(CLOCK_REALTIME, &tp) == -1)
abort();
time += (uint64_t)tp.tv_sec * 10000000LL;
time += tp.tv_nsec / 100;
uuid->time_low = (uint32_t)time;
uuid->time_mid = (uint16_t)(time >> 32);
uuid->time_hi_and_version = (uint16_t)(time >> 48) & 0xfff;
uuid->time_hi_and_version |= 1 << 12;
seq = random();
uuid->clock_seq_hi_and_reserved = (uint8_t)(seq >> 8) & 0x3f;
uuid->clock_seq_low = (uint8_t)seq;
for (i = 0; i < 6; i++)
uuid->node[i] = (uint8_t)random();
uuid->node[0] |= 0x01;
}
#endif /* __linux__ */
void
mkimg_uuid(mkimg_uuid_t *uuid)
{
static uint8_t gen[sizeof(mkimg_uuid_t)];
u_int i;
if (!unit_testing) {
osdep_uuidgen(uuid);
return;
}
for (i = 0; i < sizeof(gen); i++)
gen[i]++;
memcpy(uuid, gen, sizeof(*uuid));
}
void
mkimg_uuid_enc(void *buf, const mkimg_uuid_t *uuid)
{
uint8_t *p = buf;
u_int i;
le32enc(p, uuid->time_low);
le16enc(p + 4, uuid->time_mid);
le16enc(p + 6, uuid->time_hi_and_version);
p[8] = uuid->clock_seq_hi_and_reserved;
p[9] = uuid->clock_seq_low;
for (i = 0; i < 6; i++)
p[10 + i] = uuid->node[i];
}

View File

@ -33,7 +33,6 @@ __FBSDID("$FreeBSD$");
#include <string.h>
#include <time.h>
#include <unistd.h>
#include <uuid.h>
#include "endian.h"
#include "image.h"
@ -92,7 +91,7 @@ struct vhd_footer {
#define VHD_DISK_TYPE_DYNAMIC 3
#define VHD_DISK_TYPE_DIFF 4
uint32_t checksum;
uuid_t id;
mkimg_uuid_t id;
uint8_t saved_state;
uint8_t _reserved[427];
};
@ -200,26 +199,11 @@ vhd_timestamp(void)
return (0x01234567);
}
static void
vhd_uuid_enc(void *buf, const uuid_t *uuid)
{
uint8_t *p = buf;
int i;
be32enc(p, uuid->time_low);
be16enc(p + 4, uuid->time_mid);
be16enc(p + 6, uuid->time_hi_and_version);
p[8] = uuid->clock_seq_hi_and_reserved;
p[9] = uuid->clock_seq_low;
for (i = 0; i < _UUID_NODE_LEN; i++)
p[10 + i] = uuid->node[i];
}
static void
vhd_make_footer(struct vhd_footer *footer, uint64_t image_size,
uint32_t disk_type, uint64_t data_offset)
{
uuid_t id;
mkimg_uuid_t id;
memset(footer, 0, sizeof(*footer));
be64enc(&footer->cookie, VHD_FOOTER_COOKIE);
@ -236,7 +220,7 @@ vhd_make_footer(struct vhd_footer *footer, uint64_t image_size,
be16enc(&footer->geometry.cylinders, footer->geometry.cylinders);
be32enc(&footer->disk_type, disk_type);
mkimg_uuid(&id);
vhd_uuid_enc(&footer->id, &id);
mkimg_uuid_enc(&footer->id, &id);
be32enc(&footer->checksum, vhd_checksum(footer, sizeof(*footer)));
}
@ -261,7 +245,7 @@ struct vhd_dyn_header {
uint32_t max_entries;
uint32_t block_size;
uint32_t checksum;
uuid_t parent_id;
mkimg_uuid_t parent_id;
uint32_t parent_timestamp;
char _reserved1[4];
uint16_t parent_name[256]; /* UTF-16 */

View File

@ -34,7 +34,7 @@ __FBSDID("$FreeBSD$");
#include <string.h>
#include <unistd.h>
#include <sys/disk/vtoc.h>
#include <vtoc.h>
#include "endian.h"
#include "image.h"