Re: [nfs-utils PATCH] nfs4id: a tool to create and persist nfs4 client uniquifiers

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 




> On Feb 8, 2022, at 2:29 PM, Steve Dickson <steved@xxxxxxxxxx> wrote:
> 
> 
> 
> On 2/8/22 11:21 AM, Chuck Lever III wrote:
>>> On Feb 8, 2022, at 11:04 AM, Steve Dickson <steved@xxxxxxxxxx> wrote:
>>> 
>>> Hello,
>>> 
>>> On 2/4/22 7:56 AM, Benjamin Coddington wrote:
>>>> The nfs4id program will either create a new UUID from a random source or
>>>> derive it from /etc/machine-id, else it returns a UUID that has already
>>>> been written to /etc/nfs4-id.  This small, lightweight tool is suitable for
>>>> execution by systemd-udev in rules to populate the nfs4 client uniquifier.
>>>> Signed-off-by: Benjamin Coddington <bcodding@xxxxxxxxxx>
>>>> ---
>>>>  .gitignore               |   1 +
>>>>  configure.ac             |   4 +
>>>>  tools/Makefile.am        |   1 +
>>>>  tools/nfs4id/Makefile.am |   8 ++
>>>>  tools/nfs4id/nfs4id.c    | 184 +++++++++++++++++++++++++++++++++++++++
>>>>  tools/nfs4id/nfs4id.man  |  29 ++++++
>>>>  6 files changed, 227 insertions(+)
>>>>  create mode 100644 tools/nfs4id/Makefile.am
>>>>  create mode 100644 tools/nfs4id/nfs4id.c
>>>>  create mode 100644 tools/nfs4id/nfs4id.man
>>> Just a nit... naming convention... In the past
>>> we never put the protocol version in the name.
>>> Do a ls tools and utils directory and you
>>> see what I mean....
>>> 
>>> Would it be a problem to change the name from
>>> nfs4id to nfsid?
>> nfs4id is pretty generic, too.
>> Can we go with nfs-client-id ?
> I'm never been big with putting '-'
> in command names... nfscltid would
> be better IMHO... if we actually
> need the 'clt' in the name.

We have nfsidmap already. IMO we need some distinction
with user ID mapping tools... and some day we might
want to manage server IDs too (see EXCHANGE_ID).

nfsclientid then?


> steved.
> 
>>> steved.
>>> 
>>>> diff --git a/.gitignore b/.gitignore
>>>> index c89d1cd2583d..a37964148dd8 100644
>>>> --- a/.gitignore
>>>> +++ b/.gitignore
>>>> @@ -61,6 +61,7 @@ utils/statd/statd
>>>>  tools/locktest/testlk
>>>>  tools/getiversion/getiversion
>>>>  tools/nfsconf/nfsconf
>>>> +tools/nfs4id/nfs4id
>>>>  support/export/mount.h
>>>>  support/export/mount_clnt.c
>>>>  support/export/mount_xdr.c
>>>> diff --git a/configure.ac b/configure.ac
>>>> index 50e9b321dcf3..93d0a902cfd8 100644
>>>> --- a/configure.ac
>>>> +++ b/configure.ac
>>>> @@ -355,6 +355,9 @@ if test "$enable_nfsv4" = yes; then
>>>>    dnl check for the keyutils libraries and headers
>>>>    AC_KEYUTILS
>>>>  +  dnl check for the libuuid library and headers
>>>> +  AC_LIBUUID
>>>> +
>>>>    dnl Check for sqlite3
>>>>    AC_SQLITE3_VERS
>>>>  @@ -740,6 +743,7 @@ AC_CONFIG_FILES([
>>>>  	tools/nfsdclnts/Makefile
>>>>  	tools/nfsconf/Makefile
>>>>  	tools/nfsdclddb/Makefile
>>>> +	tools/nfs4id/Makefile
>>>>  	utils/Makefile
>>>>  	utils/blkmapd/Makefile
>>>>  	utils/nfsdcld/Makefile
>>>> diff --git a/tools/Makefile.am b/tools/Makefile.am
>>>> index 9b4b0803db39..cc658f69bb32 100644
>>>> --- a/tools/Makefile.am
>>>> +++ b/tools/Makefile.am
>>>> @@ -7,6 +7,7 @@ OPTDIRS += rpcgen
>>>>  endif
>>>>    OPTDIRS += nfsconf
>>>> +OPTDIRS += nfs4id
>>>>    if CONFIG_NFSDCLD
>>>>  OPTDIRS += nfsdclddb
>>>> diff --git a/tools/nfs4id/Makefile.am b/tools/nfs4id/Makefile.am
>>>> new file mode 100644
>>>> index 000000000000..d1e60a35a510
>>>> --- /dev/null
>>>> +++ b/tools/nfs4id/Makefile.am
>>>> @@ -0,0 +1,8 @@
>>>> +## Process this file with automake to produce Makefile.in
>>>> +
>>>> +man8_MANS	= nfs4id.man
>>>> +
>>>> +bin_PROGRAMS = nfs4id
>>>> +
>>>> +nfs4id_SOURCES = nfs4id.c
>>>> +nfs4id_LDADD = $(LIBUUID)
>>>> diff --git a/tools/nfs4id/nfs4id.c b/tools/nfs4id/nfs4id.c
>>>> new file mode 100644
>>>> index 000000000000..dbb807ae21f3
>>>> --- /dev/null
>>>> +++ b/tools/nfs4id/nfs4id.c
>>>> @@ -0,0 +1,184 @@
>>>> +/*
>>>> + * nfs4id.c -- create and persist uniquifiers for nfs4 clients
>>>> + *
>>>> + * Copyright (C) 2022  Red Hat, Benjamin Coddington <bcodding@xxxxxxxxxx>
>>>> + *
>>>> + * This program is free software; you can redistribute it and/or
>>>> + * modify it under the terms of the GNU General Public License
>>>> + * as published by the Free Software Foundation; either version 2
>>>> + * of the License, or (at your option) any later version.
>>>> + *
>>>> + * This program is distributed in the hope that it will be useful,
>>>> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
>>>> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
>>>> + * GNU General Public License for more details.
>>>> + *
>>>> + * You should have received a copy of the GNU General Public License
>>>> + * along with this program; if not, write to the Free Software
>>>> + * Foundation, Inc., 51 Franklin Street, Fifth Floor,
>>>> + * Boston, MA 02110-1301, USA.
>>>> + */
>>>> +
>>>> +#include <stdio.h>
>>>> +#include <stdarg.h>
>>>> +#include <getopt.h>
>>>> +#include <string.h>
>>>> +#include <errno.h>
>>>> +#include <stdlib.h>
>>>> +#include <fcntl.h>
>>>> +#include <unistd.h>
>>>> +#include <uuid/uuid.h>
>>>> +
>>>> +#define NFS4IDFILE "/etc/nfs4-id"
>>>> +
>>>> +UUID_DEFINE(nfs4_clientid_uuid_template,
>>>> +	0xa2, 0x25, 0x68, 0xb2, 0x7a, 0x5f, 0x49, 0x90,
>>>> +	0x8f, 0x98, 0xc5, 0xf0, 0x67, 0x78, 0xcc, 0xf1);
>>>> +
>>>> +static char *prog;
>>>> +static char *source = NULL;
>>>> +static char nfs4_id[64];
>>>> +static int force = 0;
>>>> +
>>>> +static void usage(void)
>>>> +{
>>>> +	fprintf(stderr, "usage: %s [-f|--force] [machine]\n", prog);
>>>> +}
>>>> +
>>>> +static void fatal(const char *fmt, ...)
>>>> +{
>>>> +	int err = errno;
>>>> +	va_list args;
>>>> +	char fatal_msg[256] = "fatal: ";
>>>> +
>>>> +	va_start(args, fmt);
>>>> +	vsnprintf(&fatal_msg[7], 255, fmt, args);
>>>> +	if (err)
>>>> +		fprintf(stderr, "%s: %s\n", fatal_msg, strerror(err));
>>>> +	else
>>>> +		fprintf(stderr, "%s\n", fatal_msg);
>>>> +	exit(-1);
>>>> +}
>>>> +
>>>> +static int read_nfs4_id(void)
>>>> +{
>>>> +	int fd;
>>>> +
>>>> +	fd = open(NFS4IDFILE, O_RDONLY);
>>>> +	if (fd < 0)
>>>> +		return fd;
>>>> +	read(fd, nfs4_id, 64);
>>>> +	close(fd);
>>>> +	return 0;
>>>> +}
>>>> +
>>>> +static void write_nfs4_id(void)
>>>> +{
>>>> +	int fd;
>>>> +
>>>> +	fd = open(NFS4IDFILE, O_RDWR|O_TRUNC|O_CREAT, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
>>>> +	if (fd < 0)
>>>> +		fatal("could not write id to " NFS4IDFILE);
>>>> +	write(fd, nfs4_id, 37);
>>>> +}
>>>> +
>>>> +static void print_nfs4_id(void)
>>>> +{
>>>> +	fprintf(stdout, "%s", nfs4_id);
>>>> +}
>>>> +	
>>>> +static void check_or_make_id(void)
>>>> +{
>>>> +	int ret;
>>>> +	uuid_t nfs4id_uuid;
>>>> +
>>>> +	ret = read_nfs4_id();
>>>> +	if (ret != 0) {
>>>> +		if (errno != ENOENT )
>>>> +			fatal("reading file " NFS4IDFILE);
>>>> +		uuid_generate_random(nfs4id_uuid);
>>>> +		uuid_unparse(nfs4id_uuid, nfs4_id);
>>>> +		nfs4_id[36] = '\n';
>>>> +		nfs4_id[37] = '\0';
>>>> +		write_nfs4_id();
>>>> +	}
>>>> +	print_nfs4_id();	
>>>> +}
>>>> +
>>>> +static void check_or_make_id_from_machine(void)
>>>> +{
>>>> +	int fd, ret;
>>>> +	char machineid[32];
>>>> +	uuid_t nfs4id_uuid;
>>>> +
>>>> +	ret = read_nfs4_id();
>>>> +	if (ret != 0) {
>>>> +		if (errno != ENOENT )
>>>> +			fatal("reading file " NFS4IDFILE);
>>>> +
>>>> +		fd = open("/etc/machine-id", O_RDONLY);
>>>> +		if (fd < 0)
>>>> +			fatal("unable to read /etc/machine-id");
>>>> +
>>>> +		read(fd, machineid, 32);
>>>> +		close(fd);
>>>> +
>>>> +		uuid_generate_sha1(nfs4id_uuid, nfs4_clientid_uuid_template, machineid, 32);
>>>> +		uuid_unparse(nfs4id_uuid, nfs4_id);
>>>> +		nfs4_id[36] = '\n';
>>>> +		nfs4_id[37] = '\0';
>>>> +		write_nfs4_id();
>>>> +	}
>>>> +	print_nfs4_id();
>>>> +}
>>>> +
>>>> +int main(int argc, char **argv)
>>>> +{
>>>> +	prog = argv[0];
>>>> +
>>>> +	while (1) {
>>>> +		int opt;
>>>> +		int option_index = 0;
>>>> +		static struct option long_options[] = {
>>>> +			{"force",	no_argument,	0, 'f' },
>>>> +			{0,			0,				0, 0 }
>>>> +		};
>>>> +
>>>> +		errno = 0;
>>>> +		opt = getopt_long(argc, argv, ":f", long_options, &option_index);
>>>> +		if (opt == -1)
>>>> +			break;
>>>> +
>>>> +		switch (opt) {
>>>> +		case 'f':
>>>> +			force = 1;
>>>> +			break;
>>>> +		case '?':
>>>> +			usage();
>>>> +			fatal("unexpected arg \"%s\"", argv[optind - 1]);
>>>> +			break;
>>>> +		}
>>>> +	}
>>>> +
>>>> +	argc -= optind;
>>>> +
>>>> +	if (argc > 1) {
>>>> +		usage();
>>>> +		fatal("Too many arguments");
>>>> +	}
>>>> +
>>>> +	if (argc)
>>>> +		source = argv[optind++];
>>>> +
>>>> +	if (force)
>>>> +		unlink(NFS4IDFILE);
>>>> +
>>>> +	if (!source)
>>>> +		check_or_make_id();
>>>> +	else if (strcmp(source, "machine") == 0)
>>>> +		check_or_make_id_from_machine();
>>>> +	else {
>>>> +		usage();
>>>> +		fatal("unrecognized source %s\n", source);
>>>> +	}
>>>> +}
>>>> diff --git a/tools/nfs4id/nfs4id.man b/tools/nfs4id/nfs4id.man
>>>> new file mode 100644
>>>> index 000000000000..358f836468a2
>>>> --- /dev/null
>>>> +++ b/tools/nfs4id/nfs4id.man
>>>> @@ -0,0 +1,29 @@
>>>> +.\"
>>>> +.\" nfs4id(8)
>>>> +.\"
>>>> +.TH nfs4id 8 "3 Feb 2022"
>>>> +.SH NAME
>>>> +nfs4id \- Generate or return nfs4 client id uniqueifiers
>>>> +.SH SYNOPSIS
>>>> +.B nfs4id [ -f | --force ] [<source>]
>>>> +
>>>> +.SH DESCRIPTION
>>>> +The
>>>> +.B nfs4id
>>>> +command provides a simple utility to help NFS Version 4 clients use unique
>>>> +and persistent client id values.  The command checks for the existence of a
>>>> +file /etc/nfs4-id and returns the first 64 chars read from that file.  If
>>>> +the file is not found, a UUID is generated from the specified source and
>>>> +written to the file and returned.
>>>> +.SH OPTIONS
>>>> +.TP
>>>> +.BR \-f, \-\-force
>>>> +Overwrite the existing /etc/nfs4-id with a UUID generated from <source>.
>>>> +.SH Sources
>>>> +If <source> is not specified, nfs4id will generate a new random UUID.
>>>> +
>>>> +If <source> is "machine", nfs4id will generate a deterministic UUID value
>>>> +derived from a sha1 hash of the contents of /etc/machine-id and a static
>>>> +key.
>>>> +.SH SEE ALSO
>>>> +.BR machine-id (5)
>> --
>> Chuck Lever
> 

--
Chuck Lever







[Index of Archives]     [Linux Filesystem Development]     [Linux USB Development]     [Linux Media Development]     [Video for Linux]     [Linux NILFS]     [Linux Audio Users]     [Yosemite Info]     [Linux SCSI]

  Powered by Linux