Index: head/usr.sbin/Makefile =================================================================== --- head/usr.sbin/Makefile (revision 335235) +++ head/usr.sbin/Makefile (revision 335236) @@ -1,224 +1,225 @@ # From: @(#)Makefile 5.20 (Berkeley) 6/12/93 # $FreeBSD$ .include SUBDIR= adduser \ arp \ binmiscctl \ camdd \ cdcontrol \ chkgrp \ chown \ chroot \ ckdist \ clear_locks \ crashinfo \ cron \ ctladm \ ctld \ daemon \ dconschat \ devctl \ devinfo \ diskinfo \ dumpcis \ etcupdate \ extattr \ extattrctl \ fifolog \ fstyp \ fwcontrol \ getfmac \ getpmac \ gstat \ i2c \ ifmcstat \ iostat \ iovctl \ kldxref \ mailwrapper \ makefs \ memcontrol \ mergemaster \ mfiutil \ mixer \ mlxcontrol \ mountd \ mount_smbfs \ mpsutil \ mptutil \ mtest \ newsyslog \ nfscbd \ nfsd \ nfsdumpstate \ nfsrevoke \ nfsuserd \ nmtree \ nologin \ pciconf \ periodic \ + pnfsdscopymr \ pnfsdsfile \ pnfsdskill \ powerd \ prometheus_sysctl_exporter \ pstat \ pw \ pwd_mkdb \ quot \ rarpd \ rmt \ rpcbind \ rpc.lockd \ rpc.statd \ rpc.umntall \ rtprio \ rwhod \ service \ services_mkdb \ sesutil \ setfib \ setfmac \ setpmac \ smbmsg \ snapinfo \ spray \ syslogd \ sysrc \ tcpdrop \ tcpdump \ traceroute \ trpt \ tzsetup \ uefisign \ ugidfw \ vigr \ vipw \ wake \ watch \ watchdogd \ zic \ zonectl # NB: keep these sorted by MK_* knobs SUBDIR.${MK_ACCT}+= accton SUBDIR.${MK_ACCT}+= sa SUBDIR.${MK_AMD}+= amd SUBDIR.${MK_AUDIT}+= audit SUBDIR.${MK_AUDIT}+= auditd .if ${MK_OPENSSL} != "no" SUBDIR.${MK_AUDIT}+= auditdistd .endif SUBDIR.${MK_AUDIT}+= auditreduce SUBDIR.${MK_AUDIT}+= praudit SUBDIR.${MK_AUTHPF}+= authpf SUBDIR.${MK_AUTOFS}+= autofs SUBDIR.${MK_BLACKLIST}+= blacklistctl SUBDIR.${MK_BLACKLIST}+= blacklistd SUBDIR.${MK_BLUETOOTH}+= bluetooth SUBDIR.${MK_BOOTPARAMD}+= bootparamd SUBDIR.${MK_BSDINSTALL}+= bsdinstall SUBDIR.${MK_BSNMP}+= bsnmpd SUBDIR.${MK_CTM}+= ctm SUBDIR.${MK_CXGBETOOL}+= cxgbetool SUBDIR.${MK_DIALOG}+= bsdconfig SUBDIR.${MK_EFI}+= efivar efidp efibootmgr SUBDIR.${MK_FLOPPY}+= fdcontrol SUBDIR.${MK_FLOPPY}+= fdformat SUBDIR.${MK_FLOPPY}+= fdread SUBDIR.${MK_FLOPPY}+= fdwrite SUBDIR.${MK_FMTREE}+= fmtree SUBDIR.${MK_FREEBSD_UPDATE}+= freebsd-update SUBDIR.${MK_GSSAPI}+= gssd SUBDIR.${MK_GPIO}+= gpioctl SUBDIR.${MK_INET6}+= ip6addrctl SUBDIR.${MK_INET6}+= mld6query SUBDIR.${MK_INET6}+= ndp SUBDIR.${MK_INET6}+= rip6query SUBDIR.${MK_INET6}+= route6d SUBDIR.${MK_INET6}+= rrenumd SUBDIR.${MK_INET6}+= rtadvctl SUBDIR.${MK_INET6}+= rtadvd SUBDIR.${MK_INET6}+= rtsold SUBDIR.${MK_INET6}+= traceroute6 SUBDIR.${MK_INETD}+= inetd SUBDIR.${MK_IPFW}+= ipfwpcap SUBDIR.${MK_ISCSI}+= iscsid SUBDIR.${MK_JAIL}+= jail SUBDIR.${MK_JAIL}+= jexec SUBDIR.${MK_JAIL}+= jls # XXX MK_SYSCONS SUBDIR.${MK_LEGACY_CONSOLE}+= kbdcontrol SUBDIR.${MK_LEGACY_CONSOLE}+= kbdmap SUBDIR.${MK_LEGACY_CONSOLE}+= moused SUBDIR.${MK_LEGACY_CONSOLE}+= vidcontrol .if ${MK_LIBTHR} != "no" || ${MK_LIBPTHREAD} != "no" SUBDIR.${MK_PPP}+= pppctl SUBDIR.${MK_NS_CACHING}+= nscd .endif SUBDIR.${MK_LPR}+= lpr SUBDIR.${MK_MAN_UTILS}+= manctl SUBDIR.${MK_MLX5TOOL}+= mlx5tool SUBDIR.${MK_NAND}+= nandsim SUBDIR.${MK_NAND}+= nandtool SUBDIR.${MK_NETGRAPH}+= flowctl SUBDIR.${MK_NETGRAPH}+= ngctl SUBDIR.${MK_NETGRAPH}+= nghook SUBDIR.${MK_NIS}+= rpc.yppasswdd SUBDIR.${MK_NIS}+= rpc.ypupdated SUBDIR.${MK_NIS}+= rpc.ypxfrd SUBDIR.${MK_NIS}+= ypbind SUBDIR.${MK_NIS}+= ypldap SUBDIR.${MK_NIS}+= yp_mkdb SUBDIR.${MK_NIS}+= yppoll SUBDIR.${MK_NIS}+= yppush SUBDIR.${MK_NIS}+= ypserv SUBDIR.${MK_NIS}+= ypset SUBDIR.${MK_NTP}+= ntp SUBDIR.${MK_OPENSSL}+= keyserv SUBDIR.${MK_PC_SYSINSTALL}+= pc-sysinstall SUBDIR.${MK_PF}+= ftp-proxy SUBDIR.${MK_PKGBOOTSTRAP}+= pkg .if (${COMPILER_TYPE} == "clang" || (${COMPILER_TYPE} == "gcc" && ${COMPILER_VERSION} >= 60100 && ${MACHINE_CPUARCH} != "riscv")) SUBDIR.${MK_PMC}+= pmc SUBDIR.${MK_PMC}+= pmcannotate SUBDIR.${MK_PMC}+= pmccontrol SUBDIR.${MK_PMC}+= pmcstat .endif SUBDIR.${MK_PMC}+= pmcstudy SUBDIR.${MK_PORTSNAP}+= portsnap SUBDIR.${MK_PPP}+= ppp SUBDIR.${MK_QUOTAS}+= edquota SUBDIR.${MK_QUOTAS}+= quotaon SUBDIR.${MK_QUOTAS}+= repquota SUBDIR.${MK_SENDMAIL}+= editmap SUBDIR.${MK_SENDMAIL}+= mailstats SUBDIR.${MK_SENDMAIL}+= makemap SUBDIR.${MK_SENDMAIL}+= praliases SUBDIR.${MK_SENDMAIL}+= sendmail SUBDIR.${MK_TCP_WRAPPERS}+= tcpdchk SUBDIR.${MK_TCP_WRAPPERS}+= tcpdmatch SUBDIR.${MK_TIMED}+= timed SUBDIR.${MK_TOOLCHAIN}+= config SUBDIR.${MK_TOOLCHAIN}+= crunch SUBDIR.${MK_UNBOUND}+= unbound SUBDIR.${MK_USB}+= uathload SUBDIR.${MK_USB}+= uhsoctl SUBDIR.${MK_USB}+= usbconfig SUBDIR.${MK_USB}+= usbdump SUBDIR.${MK_UTMPX}+= ac SUBDIR.${MK_UTMPX}+= lastlogin SUBDIR.${MK_UTMPX}+= utx SUBDIR.${MK_WIRELESS}+= ancontrol SUBDIR.${MK_WIRELESS}+= wlandebug SUBDIR.${MK_WIRELESS}+= wpa SUBDIR.${MK_TESTS}+= tests .include SUBDIR_PARALLEL= .include Index: head/usr.sbin/pnfsdscopymr/Makefile =================================================================== --- head/usr.sbin/pnfsdscopymr/Makefile (nonexistent) +++ head/usr.sbin/pnfsdscopymr/Makefile (revision 335236) @@ -0,0 +1,6 @@ +# $FreeBSD$ + +PROG= pnfsdscopymr +MAN= pnfsdscopymr.8 + +.include Property changes on: head/usr.sbin/pnfsdscopymr/Makefile ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Index: head/usr.sbin/pnfsdscopymr/pnfsdscopymr.8 =================================================================== --- head/usr.sbin/pnfsdscopymr/pnfsdscopymr.8 (nonexistent) +++ head/usr.sbin/pnfsdscopymr/pnfsdscopymr.8 (revision 335236) @@ -0,0 +1,99 @@ +.\" Copyright (c) 2018 Rick Macklem +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $FreeBSD$ +.\" +.Dd June 2, 2018 +.Dt PNFSDSCOPYMR 8 +.Os +.Sh NAME +.Nm pnfsdscopymr +.Nd +copy or move a data storage file for a MDS file to a different DS +.Sh SYNOPSIS +.Nm +.Op Fl r Ar mounted-on-DS-dir +.Op Fl m Ar source-mounted-on-DS-dir destination-mounted-on-DS-dir +.Ar mdsfile +.Sh DESCRIPTION +The +.Nm +command copies a data storage file for an MDS file from one DS to another DS. +It is normally used to recover data files onto a repaired DS, but can also +be used to manually migrate a data storage file from one DS to a different one. +By default, the command will copy the data storage file for +.Dq mdsfile +to one of the other DSs to create a mirror of it. +This might be done if the file was created before mirroring was enabled on +the pNFS service and now needs to be mirrored. +.Pp +The following options are available: +.Bl -tag -width Ds +.It Fl r Ar mounted-on-DS-dir +This option indicates that the data storage file should be created on the DS +that is mounted on the directory +.Dq mounted-on-DS-dir . +It will only do the copy if there is an entry in the pnfsd.dsfile extended +attribute that has an IP address of 0.0.0.0. +See +.Xr pnfsdsfile 1 +for how to do this. +This is normally done for all regular files via +.Xr find 1 +in order to recover the data +storage files onto a repaired DS. +.It Fl m Ar source-mounted-on-DS-dir destination-mounted-on-DS-dir +This option indicates that the data storage file is to be migrated from +the source DS mounted on the diectory +.Dq source-mounted-on-DS-dir +to the DS mounted on the directory +.Dq destination-mounted-on-DS-dir . +In this case, the data storage file will be removed from the source DS +when the copy is completed. +.El +If the copy/migration is already done, the command will simply exit(0), +so that it can safely be used on all regular files in the exported directory +tree on the MDS. +.Pp +This command must be run on the MDS and a typical usage would be as an +argument for +.Xr find 1 +for all regular files. +.sp +For example, if the repaired DS is mounted on /data3 and files previously +stored on the repaired DS have had the DS's IP address set to 0.0.0.0: +.br +# cd +.br +# find . -type f -exec pnfsdscopymr -r /data3 {} \\; +.Sh SEE ALSO +.Xr find 1 , +.Xr nfsv4 4 , +.Xr pnfs 4 , +.Xr nfsd 8 , +.Xr pnfsdsfile 8 , +.Xr pnfsdskill 8 +.Sh HISTORY +The +.Nm +command appeared in FreeBSD12. Property changes on: head/usr.sbin/pnfsdscopymr/pnfsdscopymr.8 ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Index: head/usr.sbin/pnfsdscopymr/pnfsdscopymr.c =================================================================== --- head/usr.sbin/pnfsdscopymr/pnfsdscopymr.c (nonexistent) +++ head/usr.sbin/pnfsdscopymr/pnfsdscopymr.c (revision 335236) @@ -0,0 +1,311 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * + * Copyright (c) 2017 Rick Macklem + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +static void usage(void); + +static struct option longopts[] = { + { "migrate", required_argument, NULL, 'm' }, + { "mirror", required_argument, NULL, 'r' }, + { NULL, 0, NULL, 0 } +}; + +/* + * This program creates a copy of the file's (first argument) data on the + * new/recovering DS mirror. If the file is already on the new/recovering + * DS, it will simply exit(0). + */ +int +main(int argc, char *argv[]) +{ + struct nfsd_pnfsd_args pnfsdarg; + struct pnfsdsfile dsfile[NFSDEV_MAXMIRRORS]; + struct stat sb; + struct statfs sf; + struct addrinfo hints, *res, *nres; + struct sockaddr_in sin; + struct sockaddr_in6 sin6; + ssize_t xattrsize, xattrsize2; + size_t mirlen; + int ch, fnd, fndzero, i, migrateit, mirrorcnt, mirrorit, ret; + int mirrorlevel; + char host[MNAMELEN + NI_MAXHOST + 2], *cp; + + if (geteuid() != 0) + errx(1, "Must be run as root/su"); + + mirrorit = migrateit = 0; + pnfsdarg.dspath = pnfsdarg.curdspath = NULL; + while ((ch = getopt_long(argc, argv, "m:r:", longopts, NULL)) != -1) { + switch (ch) { + case 'm': + /* Migrate the file from the second DS to the first. */ + if (mirrorit != 0) + errx(1, "-r and -m are mutually exclusive"); + migrateit = 1; + pnfsdarg.curdspath = optarg; + break; + case 'r': + /* Mirror the file on the specified DS. */ + if (migrateit != 0) + errx(1, "-r and -m are mutually exclusive"); + mirrorit = 1; + pnfsdarg.dspath = optarg; + break; + default: + usage(); + } + } + argc -= optind; + argv += optind; + if (migrateit != 0) { + if (argc != 2) + usage(); + pnfsdarg.dspath = *argv++; + } else if (argc != 1) + usage(); + + /* Get the pNFS service's mirror level. */ + mirlen = sizeof(mirrorlevel); + ret = sysctlbyname("vfs.nfs.pnfsmirror", &mirrorlevel, &mirlen, + NULL, 0); + if (ret < 0) + errx(1, "Can't get vfs.nfs.pnfsmirror"); + + if (pnfsdarg.dspath != NULL && pnfsdarg.curdspath != NULL && + strcmp(pnfsdarg.dspath, pnfsdarg.curdspath) == 0) + errx(1, "Can't migrate to same server"); + + /* + * The host address and directory where the data storage file is + * located is in the extended attribute "pnfsd.dsfile". + */ + xattrsize = extattr_get_file(*argv, EXTATTR_NAMESPACE_SYSTEM, + "pnfsd.dsfile", dsfile, sizeof(dsfile)); + mirrorcnt = xattrsize / sizeof(struct pnfsdsfile); + xattrsize2 = mirrorcnt * sizeof(struct pnfsdsfile); + if (mirrorcnt < 1 || xattrsize != xattrsize2) + errx(1, "Can't get extattr pnfsd.dsfile for %s", *argv); + + /* See if there is a 0.0.0.0 entry. */ + fndzero = 0; + for (i = 0; i < mirrorcnt; i++) { + if (dsfile[i].dsf_sin.sin_family == AF_INET && + dsfile[i].dsf_sin.sin_addr.s_addr == 0) + fndzero = 1; + } + + /* If already mirrored for default case, just exit(0); */ + if (mirrorit == 0 && migrateit == 0 && (mirrorlevel < 2 || + (fndzero == 0 && mirrorcnt >= mirrorlevel) || + (fndzero != 0 && mirrorcnt > mirrorlevel))) + exit(0); + + /* For the "-r" case, there must be a 0.0.0.0 entry. */ + if (mirrorit != 0 && (fndzero == 0 || mirrorlevel < 2 || + mirrorcnt < 2 || mirrorcnt > mirrorlevel)) + exit(0); + + /* For pnfsdarg.dspath set, if it is already in list, just exit(0); */ + if (pnfsdarg.dspath != NULL) { + /* Check the dspath to see that it's an NFS mount. */ + if (stat(pnfsdarg.dspath, &sb) < 0) + errx(1, "Can't stat %s", pnfsdarg.dspath); + if (!S_ISDIR(sb.st_mode)) + errx(1, "%s is not a directory", pnfsdarg.dspath); + if (statfs(pnfsdarg.dspath, &sf) < 0) + errx(1, "Can't fsstat %s", pnfsdarg.dspath); + if (strcmp(sf.f_fstypename, "nfs") != 0) + errx(1, "%s is not an NFS mount", pnfsdarg.dspath); + if (strcmp(sf.f_mntonname, pnfsdarg.dspath) != 0) + errx(1, "%s is not the mounted-on dir for the new DS", + pnfsdarg.dspath); + + /* + * Check the IP address of the NFS server against the entrie(s) + * in the extended attribute. + */ + strlcpy(host, sf.f_mntfromname, sizeof(host)); + cp = strchr(host, ':'); + if (cp == NULL) + errx(1, "No : in mount %s", host); + *cp = '\0'; + memset(&hints, 0, sizeof(hints)); + hints.ai_family = PF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + if (getaddrinfo(host, NULL, &hints, &res) != 0) + errx(1, "Can't get address for %s", host); + for (i = 0; i < mirrorcnt; i++) { + nres = res; + while (nres != NULL) { + if (dsfile[i].dsf_sin.sin_family == + nres->ai_family) { + /* + * If there is already an entry for this + * DS, just exit(0), since copying isn't + * required. + */ + if (nres->ai_family == AF_INET && + nres->ai_addrlen >= sizeof(sin)) { + memcpy(&sin, nres->ai_addr, + sizeof(sin)); + if (sin.sin_addr.s_addr == + dsfile[i].dsf_sin.sin_addr.s_addr) + exit(0); + } else if (nres->ai_family == + AF_INET6 && nres->ai_addrlen >= + sizeof(sin6)) { + memcpy(&sin6, nres->ai_addr, + sizeof(sin6)); + if (IN6_ARE_ADDR_EQUAL(&sin6.sin6_addr, + &dsfile[i].dsf_sin6.sin6_addr)) + exit(0); + } + } + nres = nres->ai_next; + } + } + freeaddrinfo(res); + } + + /* For "-m", the pnfsdarg.curdspath must be in the list. */ + if (pnfsdarg.curdspath != NULL) { + /* Check pnfsdarg.curdspath to see that it's an NFS mount. */ + if (stat(pnfsdarg.curdspath, &sb) < 0) + errx(1, "Can't stat %s", pnfsdarg.curdspath); + if (!S_ISDIR(sb.st_mode)) + errx(1, "%s is not a directory", pnfsdarg.curdspath); + if (statfs(pnfsdarg.curdspath, &sf) < 0) + errx(1, "Can't fsstat %s", pnfsdarg.curdspath); + if (strcmp(sf.f_fstypename, "nfs") != 0) + errx(1, "%s is not an NFS mount", pnfsdarg.curdspath); + if (strcmp(sf.f_mntonname, pnfsdarg.curdspath) != 0) + errx(1, "%s is not the mounted-on dir of the cur DS", + pnfsdarg.curdspath); + + /* + * Check the IP address of the NFS server against the entrie(s) + * in the extended attribute. + */ + strlcpy(host, sf.f_mntfromname, sizeof(host)); + cp = strchr(host, ':'); + if (cp == NULL) + errx(1, "No : in mount %s", host); + *cp = '\0'; + memset(&hints, 0, sizeof(hints)); + hints.ai_family = PF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + if (getaddrinfo(host, NULL, &hints, &res) != 0) + errx(1, "Can't get address for %s", host); + fnd = 0; + for (i = 0; i < mirrorcnt && fnd == 0; i++) { + nres = res; + while (nres != NULL) { + if (dsfile[i].dsf_sin.sin_family == + nres->ai_family) { + /* + * Note if the entry is found. + */ + if (nres->ai_family == AF_INET && + nres->ai_addrlen >= sizeof(sin)) { + memcpy(&sin, nres->ai_addr, + sizeof(sin)); + if (sin.sin_addr.s_addr == + dsfile[i].dsf_sin.sin_addr.s_addr) { + fnd = 1; + break; + } + } else if (nres->ai_family == + AF_INET6 && nres->ai_addrlen >= + sizeof(sin6)) { + memcpy(&sin6, nres->ai_addr, + sizeof(sin6)); + if (IN6_ARE_ADDR_EQUAL(&sin6.sin6_addr, + &dsfile[i].dsf_sin6.sin6_addr)) { + fnd = 1; + break; + } + } + } + nres = nres->ai_next; + } + } + freeaddrinfo(res); + /* + * If not found just exit(0), since it is not on the + * source DS. + */ + if (fnd == 0) + exit(0); + } + + /* Do the copy via the nfssvc() syscall. */ + pnfsdarg.op = PNFSDOP_COPYMR; + pnfsdarg.mdspath = *argv; + ret = nfssvc(NFSSVC_PNFSDS, &pnfsdarg); + if (ret < 0 && errno != EEXIST) + err(1, "Copymr failed args %s, %s", argv[1], argv[2]); + exit(0); +} + +static void +usage(void) +{ + + fprintf(stderr, "pnfsdscopymr [-r recovered-DS-mounted-on-path] " + "[-m soure-DS-mounted-on-path destination-DS-mounted-on-path] " + "mds-filename"); + exit(1); +} + Property changes on: head/usr.sbin/pnfsdscopymr/pnfsdscopymr.c ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property