From owner-svn-src-projects@freebsd.org Fri Jun 16 23:29:44 2017 Return-Path: Delivered-To: svn-src-projects@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 3461AD8B349 for ; Fri, 16 Jun 2017 23:29:44 +0000 (UTC) (envelope-from rmacklem@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id EE0F873C96; Fri, 16 Jun 2017 23:29:43 +0000 (UTC) (envelope-from rmacklem@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id v5GNThwa021285; Fri, 16 Jun 2017 23:29:43 GMT (envelope-from rmacklem@FreeBSD.org) Received: (from rmacklem@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id v5GNThiT021284; Fri, 16 Jun 2017 23:29:43 GMT (envelope-from rmacklem@FreeBSD.org) Message-Id: <201706162329.v5GNThiT021284@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: rmacklem set sender to rmacklem@FreeBSD.org using -f From: Rick Macklem Date: Fri, 16 Jun 2017 23:29:43 +0000 (UTC) To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r320037 - projects/pnfs-planb-server/usr.bin/pnfsdsfile X-SVN-Group: projects MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-projects@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: "SVN commit messages for the src " projects" tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 16 Jun 2017 23:29:44 -0000 Author: rmacklem Date: Fri Jun 16 23:29:42 2017 New Revision: 320037 URL: https://svnweb.freebsd.org/changeset/base/320037 Log: Add an option to pnfsdsfile so that a sysadmin can replace the IP# for a DS. (This should be avoided, but just in case it has to be done...) Modified: projects/pnfs-planb-server/usr.bin/pnfsdsfile/pnfsdsfile.c Modified: projects/pnfs-planb-server/usr.bin/pnfsdsfile/pnfsdsfile.c ============================================================================== --- projects/pnfs-planb-server/usr.bin/pnfsdsfile/pnfsdsfile.c Fri Jun 16 23:27:10 2017 (r320036) +++ projects/pnfs-planb-server/usr.bin/pnfsdsfile/pnfsdsfile.c Fri Jun 16 23:29:42 2017 (r320037) @@ -45,6 +45,7 @@ __FBSDID("$FreeBSD$"); static void usage(void); static struct option longopts[] = { + { "changeds", required_argument, NULL, 'c' }, { "quiet", no_argument, NULL, 'q' }, { "ds", required_argument, NULL, 's' }, { "zerofh", no_argument, NULL, 'z' }, @@ -60,18 +61,35 @@ static struct option longopts[] = { int main(int argc, char *argv[]) { - struct addrinfo *res, *ad; + struct addrinfo *res, *ad, *newres; struct sockaddr_in *sin, *adsin; struct sockaddr_in6 *sin6, *adsin6; - char hostn[NI_MAXHOST + 1]; + char hostn[2 * NI_MAXHOST + 2], *cp; struct pnfsdsfile dsfile; int ch, quiet, zerofh; + in_port_t tport; zerofh = 0; quiet = 0; res = NULL; - while ((ch = getopt_long(argc, argv, "qs:z", longopts, NULL)) != -1) { + newres = NULL; + while ((ch = getopt_long(argc, argv, "c:qs:z", longopts, NULL)) != -1) { switch (ch) { + case 'c': + /* Replace the first DS server with the second one. */ + if (zerofh != 0) + errx(1, "-c and -z are mutually exclusive\n"); + strlcpy(hostn, optarg, 2 * NI_MAXHOST + 2); + cp = strchr(hostn, ','); + if (cp == NULL) + errx(1, "Bad -c argument %s\n", hostn); + *cp = '\0'; + if (getaddrinfo(hostn, NULL, NULL, &res) != 0) + errx(1, "Can't get IP# for %s\n", hostn); + *cp++ = ','; + if (getaddrinfo(cp, NULL, NULL, &newres) != 0) + errx(1, "Can't get IP# for %s\n", cp); + break; case 'q': quiet = 1; break; @@ -81,6 +99,8 @@ main(int argc, char *argv[]) errx(1, "Can't get IP# for %s\n", optarg); break; case 'z': + if (newres != NULL) + errx(1, "-c and -z are mutually exclusive\n"); zerofh = 1; break; default: @@ -129,6 +149,61 @@ main(int argc, char *argv[]) } if (res == NULL || ad != NULL) { memset(&dsfile.dsf_fh, 0, sizeof(dsfile.dsf_fh)); + if (extattr_set_file(*argv, EXTATTR_NAMESPACE_SYSTEM, + "pnfsd.dsfile", &dsfile, sizeof(dsfile)) != + sizeof(dsfile)) + err(1, "Can't set pnfsd.dsfile\n"); + } + } + + /* Do the -c option to replace the DS host address. */ + if (newres != NULL) { + if (geteuid() != 0) + errx(1, "Must be root/su to replace the host addr\n"); + + /* + * Check that the old host address matches. + */ + sin = &dsfile.dsf_sin; + sin6 = &dsfile.dsf_sin6; + ad = res; + while (ad != NULL) { + adsin = (struct sockaddr_in *)ad->ai_addr; + adsin6 = (struct sockaddr_in6 *)ad->ai_addr; + if (adsin->sin_family == sin->sin_family) { + if (sin->sin_family == AF_INET && + sin->sin_addr.s_addr == + adsin->sin_addr.s_addr) + break; + else if (sin->sin_family == AF_INET6 && + IN6_ARE_ADDR_EQUAL(&sin6->sin6_addr, + &adsin6->sin6_addr)) + break; + } + ad = ad->ai_next; + } + if (ad != NULL) { + if (sin->sin_family == AF_INET) + tport = sin->sin_port; + else + tport = sin6->sin6_port; + /* + * We have a match, so replace it with the first + * AF_INET or AF_INET6 address in the newres list. + */ + while (newres->ai_addr->sa_family != AF_INET && + newres->ai_addr->sa_family != AF_INET6) { + newres = newres->ai_next; + if (newres == NULL) + errx(1, "Hostname %s has no IP#\n", cp); + } + if (newres->ai_addr->sa_family == AF_INET) { + memcpy(sin, newres->ai_addr, sizeof(*sin)); + sin->sin_port = tport; + } else if (newres->ai_addr->sa_family == AF_INET6) { + memcpy(sin6, newres->ai_addr, sizeof(*sin6)); + sin6->sin6_port = tport; + } if (extattr_set_file(*argv, EXTATTR_NAMESPACE_SYSTEM, "pnfsd.dsfile", &dsfile, sizeof(dsfile)) != sizeof(dsfile))