diff options
author | Brian Behlendorf <[email protected]> | 2016-04-13 14:50:16 -0700 |
---|---|---|
committer | Brian Behlendorf <[email protected]> | 2016-04-25 11:13:09 -0700 |
commit | 5b4136bd499a892f65c86af8fd39fa21e05c9148 (patch) | |
tree | 4d5c98bcb02ec3de13683370be5e62fbe2046cd4 /lib/libzfs/libzfs_pool.c | |
parent | a5a370227eb0a3daf8992a38920d54eb3b7b3c25 (diff) |
Create unique partition labels
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 #4517
Diffstat (limited to 'lib/libzfs/libzfs_pool.c')
-rw-r--r-- | lib/libzfs/libzfs_pool.c | 28 |
1 files changed, 27 insertions, 1 deletions
diff --git a/lib/libzfs/libzfs_pool.c b/lib/libzfs/libzfs_pool.c index e7a9a0011..214c57ab4 100644 --- a/lib/libzfs/libzfs_pool.c +++ b/lib/libzfs/libzfs_pool.c @@ -4171,6 +4171,32 @@ zpool_label_disk_check(char *path) } /* + * 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. */ @@ -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; |