Blame fedfs/fedfs-map-nfs4.c

Packit Service 590e6c
/*
Packit Service 590e6c
 * Copyright 2011 Oracle.  All rights reserved.
Packit Service 590e6c
 *
Packit Service 590e6c
 * This file is part of fedfs-utils.
Packit Service 590e6c
 *
Packit Service 590e6c
 * fedfs-utils is free software; you can redistribute it and/or modify
Packit Service 590e6c
 * it under the terms of the GNU General Public License version 2.0 as
Packit Service 590e6c
 * published by the Free Software Foundation.
Packit Service 590e6c
 *
Packit Service 590e6c
 * fedfs-utils is distributed in the hope that it will be useful, but
Packit Service 590e6c
 * WITHOUT ANY WARRANTY; without even the implied warranty of
Packit Service 590e6c
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Packit Service 590e6c
 * GNU General Public License version 2.0 for more details.
Packit Service 590e6c
 *
Packit Service 590e6c
 * You should have received a copy of the GNU General Public License
Packit Service 590e6c
 * version 2.0 along with fedfs-utils.  If not, see:
Packit Service 590e6c
 *
Packit Service 590e6c
 *	http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
Packit Service 590e6c
 */
Packit Service 590e6c
Packit Service 590e6c
#ifdef HAVE_CONFIG_H
Packit Service 590e6c
#include <config.h>
Packit Service 590e6c
#endif
Packit Service 590e6c
Packit Service 590e6c
#include <sys/types.h>
Packit Service 590e6c
#include <sys/stat.h>
Packit Service 590e6c
#include <sys/socket.h>
Packit Service 590e6c
#include <sys/mount.h>
Packit Service 590e6c
#include <sys/wait.h>
Packit Service 590e6c
Packit Service 590e6c
#include <stdbool.h>
Packit Service 590e6c
#include <string.h>
Packit Service 590e6c
#include <stdlib.h>
Packit Service 590e6c
#include <unistd.h>
Packit Service 590e6c
#include <stdio.h>
Packit Service 590e6c
#include <libgen.h>
Packit Service 590e6c
#include <errno.h>
Packit Service 590e6c
#include <getopt.h>
Packit Service 590e6c
#include <locale.h>
Packit Service 590e6c
#include <netdb.h>
Packit Service 590e6c
#include <langinfo.h>
Packit Service 590e6c
Packit Service 590e6c
#include "fedfs-nls.h"
Packit Service 590e6c
#include "fedfs-token.h"
Packit Service 590e6c
#include "fedfs-getsrvinfo.h"
Packit Service 590e6c
#include "fedfs-gpl-boiler.h"
Packit Service 590e6c
Packit Service 590e6c
/**
Packit Service 590e6c
 * Name of SRV record containing NFSv4 FedFS root
Packit Service 590e6c
 */
Packit Service 590e6c
#define FEDFS_NFS_DOMAINROOT	"_nfs-domainroot._tcp"
Packit Service 590e6c
Packit Service 590e6c
/**
Packit Service 590e6c
 * Export pathname of NFSv4 FedFS root
Packit Service 590e6c
 */
Packit Service 590e6c
#define FEDFS_NFS_EXPORTPATH	"/.domainroot"
Packit Service 590e6c
Packit Service 590e6c
static char *progname;
Packit Service 590e6c
Packit Service 590e6c
/**
Packit Service 590e6c
 * Display usage message
Packit Service 590e6c
 */
Packit Service 590e6c
static void
Packit Service 590e6c
fedfs_map_usage(void)
Packit Service 590e6c
{
Packit Service 590e6c
	printf(_("\nUsage: %s [domain]\n\n"), progname);
Packit Service 590e6c
Packit Service 590e6c
	printf("%s", fedfs_gpl_boilerplate);
Packit Service 590e6c
}
Packit Service 590e6c
Packit Service 590e6c
/**
Packit Service 590e6c
 * Construct an NFSv4 map entry for "domainname" with one server
Packit Service 590e6c
 *
Packit Service 590e6c
 * @param si single-entry list of SRV records
Packit Service 590e6c
 * @param domainname NUL-terminated UTF-8 string containing name of FedFS domain
Packit Service 590e6c
 * @return command exit status
Packit Service 590e6c
 */
Packit Service 590e6c
static int fedfs_map_nfs4_oneserver(struct srvinfo *si, const char *domainname)
Packit Service 590e6c
{
Packit Service 590e6c
	printf("-fstype=nfs,vers=4,fg");
Packit Service 590e6c
	if (si->si_port != 2049)
Packit Service 590e6c
		printf(",port=%u", si->si_port);
Packit Service 590e6c
	printf(" %s:%s/%s\n", si->si_target, FEDFS_NFS_EXPORTPATH, domainname);
Packit Service 590e6c
	return 0;
Packit Service 590e6c
}
Packit Service 590e6c
Packit Service 590e6c
/**
Packit Service 590e6c
 * Construct an NFSv4 map entry for "domainname" with multiple servers
Packit Service 590e6c
 *
Packit Service 590e6c
 * @param si list of SRV records for requested FedFS domain
Packit Service 590e6c
 * @param domainname NUL-terminated UTF-8 string containing name of FedFS domain
Packit Service 590e6c
 * @return command exit status
Packit Service 590e6c
 */
Packit Service 590e6c
static int fedfs_map_nfs4_replicas(struct srvinfo *si, const char *domainname)
Packit Service 590e6c
{
Packit Service 590e6c
	struct srvinfo *cur;
Packit Service 590e6c
	unsigned short port;
Packit Service 590e6c
	_Bool comma;
Packit Service 590e6c
Packit Service 590e6c
	/*
Packit Service 590e6c
	 * Unfortunately our automounter can't handle a list of
Packit Service 590e6c
	 * replicas where the various servers live on different
Packit Service 590e6c
	 * ports from one another.
Packit Service 590e6c
	 */
Packit Service 590e6c
	port = si->si_port;
Packit Service 590e6c
	for (cur = si; cur != NULL; cur = cur->si_next)
Packit Service 590e6c
		if (cur->si_port != port) {
Packit Service 590e6c
			fprintf(stderr, _("%s: Replicas on different ports not supported\n"),
Packit Service 590e6c
				progname);
Packit Service 590e6c
			return 1;
Packit Service 590e6c
		}
Packit Service 590e6c
Packit Service 590e6c
	if (port != 2049)
Packit Service 590e6c
		printf("-fstype=nfs,vers=4,fg,port=%u ", port);
Packit Service 590e6c
	else
Packit Service 590e6c
		printf("-fstype=nfs,vers=4,fg ");
Packit Service 590e6c
Packit Service 590e6c
	/*
Packit Service 590e6c
	 * Note that the export path is required to be indentical
Packit Service 590e6c
	 * for all domain root servers for this domain.
Packit Service 590e6c
	 */
Packit Service 590e6c
	for (comma = false, cur = si; cur != NULL; cur = cur->si_next) {
Packit Service 590e6c
		if (comma)
Packit Service 590e6c
			printf(",");
Packit Service 590e6c
		printf("%s(%u)", cur->si_target, cur->si_weight);
Packit Service 590e6c
		comma = true;
Packit Service 590e6c
	}
Packit Service 590e6c
	printf(":%s/%s\n", FEDFS_NFS_EXPORTPATH, domainname);
Packit Service 590e6c
Packit Service 590e6c
	return 0;
Packit Service 590e6c
}
Packit Service 590e6c
Packit Service 590e6c
/**
Packit Service 590e6c
 * Construct an NFSv4 map entry for "domainname"
Packit Service 590e6c
 *
Packit Service 590e6c
 * @param domainname NUL-terminated UTF-8 string containing name of FedFS domain
Packit Service 590e6c
 * @return command exit status
Packit Service 590e6c
 */
Packit Service 590e6c
static int fedfs_map_nfs4(const char *domainname)
Packit Service 590e6c
{
Packit Service 590e6c
	struct srvinfo *cur, *si = NULL;
Packit Service 590e6c
	unsigned int count;
Packit Service 590e6c
	int error, result;
Packit Service 590e6c
Packit Service 590e6c
	result = 1;
Packit Service 590e6c
	error = getsrvinfo(FEDFS_NFS_DOMAINROOT, domainname, &si);
Packit Service 590e6c
	switch (error) {
Packit Service 590e6c
	case ESI_SUCCESS:
Packit Service 590e6c
		break;
Packit Service 590e6c
	case ESI_NONAME:
Packit Service 590e6c
		fprintf(stderr, _("%s: Domain name %s not found\n"),
Packit Service 590e6c
			progname, domainname);
Packit Service 590e6c
		goto out;
Packit Service 590e6c
	case ESI_SERVICE:
Packit Service 590e6c
		fprintf(stderr, _("%s: No FedFS domain root available for %s\n"),
Packit Service 590e6c
			progname, domainname);
Packit Service 590e6c
		goto out;
Packit Service 590e6c
	default:
Packit Service 590e6c
		fprintf(stderr, _("%s: Failed to resolve %s: %s\n"),
Packit Service 590e6c
			progname, domainname, gsi_strerror(error));
Packit Service 590e6c
		goto out;
Packit Service 590e6c
	}
Packit Service 590e6c
Packit Service 590e6c
	for (count = 0, cur = si; cur != NULL; cur = cur->si_next)
Packit Service 590e6c
		count++;
Packit Service 590e6c
	if (count == 1)
Packit Service 590e6c
		result = fedfs_map_nfs4_oneserver(si, domainname);
Packit Service 590e6c
	else
Packit Service 590e6c
		result = fedfs_map_nfs4_replicas(si, domainname);
Packit Service 590e6c
Packit Service 590e6c
out:
Packit Service 590e6c
	freesrvinfo(si);
Packit Service 590e6c
	return result;
Packit Service 590e6c
}
Packit Service 590e6c
Packit Service 590e6c
/**
Packit Service 590e6c
 * Program entry point
Packit Service 590e6c
 *
Packit Service 590e6c
 * @param argc count of command line arguments
Packit Service 590e6c
 * @param argv array of NUL-terminated C strings containing command line arguments
Packit Service 590e6c
 * @return program exit status
Packit Service 590e6c
 */
Packit Service 590e6c
int main(int argc, char *argv[])
Packit Service 590e6c
{
Packit Service 590e6c
	(void)setlocale(LC_ALL, "");
Packit Service 590e6c
Packit Service 590e6c
	progname = basename(argv[0]);
Packit Service 590e6c
Packit Service 590e6c
	if (argc != 2) {
Packit Service 590e6c
		fedfs_map_usage();
Packit Service 590e6c
		return 1;
Packit Service 590e6c
	}
Packit Service 590e6c
Packit Service 590e6c
	if (strcmp(progname, "fedfs-map-nfs4") == 0)
Packit Service 590e6c
		return fedfs_map_nfs4(argv[1]);
Packit Service 590e6c
#ifdef EXAMPLE
Packit Service 590e6c
	/* CIFS support might plug in here */
Packit Service 590e6c
	else if (strcmp(progname, "fedfs-map-cifs") == 0)
Packit Service 590e6c
		return fedfs_map_cifs(argv[1]);
Packit Service 590e6c
#endif
Packit Service 590e6c
Packit Service 590e6c
	fprintf(stderr, _("%s: Unsupported file system type\n"), progname);
Packit Service 590e6c
	return 1;
Packit Service 590e6c
}