Skip to content

Commit

Permalink
Create unique partition labels
Browse files Browse the repository at this point in the history
When partitioning a device a name may be specified for each partition.
Internally zfs doesn't use this partition name for anything so it
has always just been set to "zfs".

However this isn't optimal because udev will create symlinks using
this name in /dev/disk/by-partlabel/.  If the name isn't unique
then all the links cannot be created.

Therefore a random 64-bit value has been added to the partition
label, i.e "zfs-1234567890abcdef".  Additional information could
be encoded here but since partitions may be reused that might
result in confusion and it was decided against.

Signed-off-by: Brian Behlendorf <[email protected]>
Signed-off-by: Tony Hutter <[email protected]>
Signed-off-by: Richard Laager <[email protected]>
Closes openzfs#4517
  • Loading branch information
behlendorf authored and ryao committed Jun 7, 2016
1 parent f817f0a commit 182bc62
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 1 deletion.
1 change: 1 addition & 0 deletions cmd/zpool/zpool_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -6055,6 +6055,7 @@ main(int argc, char **argv)

(void) setlocale(LC_ALL, "");
(void) textdomain(TEXT_DOMAIN);
srand(time(NULL));

dprintf_setup(&argc, argv);

Expand Down
28 changes: 27 additions & 1 deletion lib/libzfs/libzfs_pool.c
Original file line number Diff line number Diff line change
Expand Up @@ -4170,6 +4170,32 @@ zpool_label_disk_check(char *path)
return (0);
}

/*
* Generate a unique partition name for the ZFS member. Partitions must
* have unique names to ensure udev will be able to create symlinks under
* /dev/disk/by-partlabel/ for all pool members. The partition names are
* of the form <pool>-<unique-id>.
*/
static void
zpool_label_name(char *label_name, int label_size)
{
uint64_t id = 0;
int fd;

fd = open("/dev/urandom", O_RDONLY);
if (fd > 0) {
if (read(fd, &id, sizeof (id)) != sizeof (id))
id = 0;

close(fd);
}

if (id == 0)
id = (((uint64_t)rand()) << 32) | (uint64_t)rand();

snprintf(label_name, label_size, "zfs-%016llx", (u_longlong_t) id);
}

/*
* Label an individual disk. The name provided is the short name,
* stripped of any leading /dev path.
Expand Down Expand Up @@ -4260,7 +4286,7 @@ zpool_label_disk(libzfs_handle_t *hdl, zpool_handle_t *zhp, char *name)
* can get, in the absence of V_OTHER.
*/
vtoc->efi_parts[0].p_tag = V_USR;
(void) strcpy(vtoc->efi_parts[0].p_name, "zfs");
zpool_label_name(vtoc->efi_parts[0].p_name, EFI_PART_NAME_LEN);

vtoc->efi_parts[8].p_start = slice_size + start_block;
vtoc->efi_parts[8].p_size = resv;
Expand Down

0 comments on commit 182bc62

Please sign in to comment.