MFhead@r324482

This commit is contained in:
Enji Cooper 2017-10-10 06:26:12 +00:00
commit 50896984cd
527 changed files with 102219 additions and 45488 deletions

View File

@ -435,7 +435,7 @@ worlds: .PHONY
.if make(universe) || make(universe_kernels) || make(tinderbox) || make(targets)
TARGETS?=amd64 arm arm64 i386 mips powerpc riscv sparc64
_UNIVERSE_TARGETS= ${TARGETS}
TARGET_ARCHES_arm?= arm armeb armv6
TARGET_ARCHES_arm?= arm armeb armv6 armv7
TARGET_ARCHES_arm64?= aarch64
TARGET_ARCHES_mips?= mipsel mips mips64el mips64 mipsn32 mipselhf mipshf mips64elhf mips64hf
TARGET_ARCHES_powerpc?= powerpc powerpc64 powerpcspe

View File

@ -398,6 +398,7 @@ KNOWN_ARCHES?= aarch64/arm64 \
arm \
armeb/arm \
armv6/arm \
armv7/arm \
i386 \
mips \
mipsel/mips \
@ -615,7 +616,7 @@ BFLAGS+= -B${CROSS_BINUTILS_PREFIX}
BFLAGS+= -B${WORLDTMP}/usr/bin
.endif
.if ${TARGET} == "arm"
.if ${TARGET_ARCH:Marmv6*} != "" && ${TARGET_CPUTYPE:M*soft*} == ""
.if ${TARGET_ARCH:Marmv[67]*} != "" && ${TARGET_CPUTYPE:M*soft*} == ""
TARGET_ABI= gnueabihf
.else
TARGET_ABI= gnueabi
@ -651,7 +652,7 @@ XCFLAGS+= ${BFLAGS}
${TARGET_ARCH} == "powerpc64" || ${TARGET_ARCH:Mmips64*} != "")
LIBCOMPAT= 32
.include "Makefile.libcompat"
.elif ${MK_LIBSOFT} != "no" && ${TARGET_ARCH} == "armv6"
.elif ${MK_LIBSOFT} != "no" && ${TARGET_ARCH:Marmv[67]*} != ""
LIBCOMPAT= SOFT
.include "Makefile.libcompat"
.endif
@ -1360,6 +1361,10 @@ BUILDKERNELS+= ${_kernel}
.if empty(INSTALLKERNEL) && !defined(NO_INSTALLKERNEL)
INSTALLKERNEL= ${_kernel}
.endif
.else
.if make(buildkernel)
.error Missing KERNCONF ${KERNCONFDIR}/${_kernel}
.endif
.endif
.endfor

View File

@ -59,10 +59,10 @@ LIB32WMAKEFLAGS+= -DCOMPAT_32BIT
# -------------------------------------------------------------------
# soft-fp world
.if ${TARGET_ARCH} == "armv6"
.if ${TARGET_ARCH:Marmv[67]*} != ""
LIBSOFTCFLAGS= -DCOMPAT_SOFTFP
LIBSOFTCPUFLAGS= -mfloat-abi=softfp
LIBSOFTWMAKEENV= CPUTYPE=soft MACHINE=arm MACHINE_ARCH=armv6
LIBSOFTWMAKEENV= CPUTYPE=soft MACHINE=arm MACHINE_ARCH=${TARGET_ARCH}
LIBSOFTWMAKEFLAGS= -DCOMPAT_SOFTFP
.endif

View File

@ -38,6 +38,23 @@
# xargs -n1 | sort | uniq -d;
# done
# 20161010: Remove libstand
OLD_FILES+=usr/lib/libstand.a
OLD_FILES+=usr/lib/libstand_p.a
OLD_FILES+=usr/include/stand.h
OLD_FILES+=usr/share/man/man3/libstand.3
# 20171003: remove RCMDS
OLD_FILES+=bin/rcp
OLD_FILES+=rescue/rcp
OLD_FILES+=usr/bin/rlogin
OLD_FILES+=usr/bin/rsh
OLD_FILES+=usr/libexec/rlogind
OLD_FILES+=usr/libexec/rshd
OLD_FILES+=usr/share/man/man1/rcp.1.gz
OLD_FILES+=usr/share/man/man1/rlogin.1.gz
OLD_FILES+=usr/share/man/man1/rsh.1.gz
OLD_FILES+=usr/share/man/man8/rlogind.8.gz
OLD_FILES+=usr/share/man/man8/rshd.8.gz
# 20170927: crshared
OLD_FILES+=usr/share/man/man9/crshared.9.gz
# 20170927: procctl

View File

@ -51,6 +51,23 @@ NOTE TO PEOPLE WHO THINK THAT FreeBSD 12.x IS SLOW:
****************************** SPECIAL WARNING: ******************************
20171010:
libstand has turned into a private library for sys/boot use only.
It is no longer supported as a public interface outside of sys/boot.
20171005:
The arm port has split armv6 into armv6 and armv7. armv7 is now
a valid TARGET_ARCH/MACHINE_ARCH setting. If you have an armv7 system
and are running a kernel from before r324363, you will need to add
MACHINE_ARCH=armv7 to 'make buildworld' to do a native build.
20171003:
When building multiple kernels using KERNCONF, non-existent KERNCONF
files will produce an error and buildkernel will fail. Previously
missing KERNCONF files silently failed giving no indication as to
why, only to subsequently discover during installkernel that the
desired kernel was never built in the first place.
20170912:
The default serial number format for CTL LUNs has changed. This will
affect users who use /dev/diskid/* device nodes, or whose FibreChannel

View File

@ -40,7 +40,6 @@ SUBDIR= cat \
test \
uuidgen
SUBDIR.${MK_RCMDS}+= rcp
SUBDIR.${MK_SENDMAIL}+= rmail
SUBDIR.${MK_TCSH}+= csh
SUBDIR.${MK_TESTS}+= tests

View File

@ -199,7 +199,8 @@ static VAR var[] = {
{"tdaddr", "TDADDR", NULL, "thread-address", 0, kvar, KOFF(ki_tdaddr),
KPTR, "lx", 0},
{"tdev", "TDEV", NULL, "terminal-device", 0, tdev, 0, CHAR, NULL, 0},
{"tdnam", "TDNAM", NULL, "terminal-device-name", LJUST, tdnam, 0, CHAR,
{"tdnam", "", "tdname", NULL, 0, NULL, 0, CHAR, NULL, 0},
{"tdname", "TDNAME", NULL, "thread-name", LJUST, tdnam, 0, CHAR,
NULL, 0},
{"time", "TIME", NULL, "cpu-time", USER, cputime, 0, CHAR, NULL, 0},
{"tpgid", "TPGID", NULL, "terminal-process-gid", 0, kvar,

View File

@ -29,7 +29,7 @@
.\" @(#)ps.1 8.3 (Berkeley) 4/18/94
.\" $FreeBSD$
.\"
.Dd September 7, 2017
.Dd October 9, 2017
.Dt PS 1
.Os
.Sh NAME
@ -675,6 +675,8 @@ saved UID from a setuid executable
accumulated system CPU time
.It Cm tdaddr
thread address
.It Cm tdname
thread name
.It Cm tdev
control terminal device number
.It Cm time

View File

@ -523,7 +523,11 @@ main(int argc, char *argv[])
*/
nentries = -1;
kp = kvm_getprocs(kd, what, flag, &nentries);
if ((kp == NULL && nentries > 0) || (kp != NULL && nentries < 0))
/*
* Ignore ESRCH to preserve behaviour of "ps -p nonexistent-pid"
* not reporting an error.
*/
if ((kp == NULL && errno != ESRCH) || (kp != NULL && nentries < 0))
xo_errx(1, "%s", kvm_geterr(kd));
nkept = 0;
if (nentries > 0) {

View File

@ -1,19 +0,0 @@
# @(#)Makefile 8.1 (Berkeley) 7/19/93
# $FreeBSD$
.include <src.opts.mk>
PACKAGE=rcmds
PROG= rcp
SRCS= rcp.c util.c
CFLAGS+=-DBINDIR=${BINDIR}
PACKAGE=rcmds
BINOWN= root
BINMODE=4555
HAS_TESTS=
SUBDIR.${MK_TESTS}+= tests
.include <bsd.prog.mk>

View File

@ -1,18 +0,0 @@
# $FreeBSD$
# Autogenerated - do NOT edit!
DIRDEPS = \
gnu/lib/csu \
gnu/lib/libgcc \
include \
include/xlocale \
lib/${CSU_DIR} \
lib/libc \
lib/libcompiler_rt \
.include <dirdeps.mk>
.if ${DEP_RELDIR} == ${_DEP_RELDIR}
# local dependencies - needed for -jN in clean tree
.endif

View File

@ -1,47 +0,0 @@
/*-
* Copyright (c) 1992, 1993
* The Regents of the University of California. All rights reserved.
*
* 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.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
*
* @(#)extern.h 8.1 (Berkeley) 5/31/93
* $FreeBSD$
*/
typedef struct {
size_t cnt;
char *buf;
} BUF;
extern int iamremote;
BUF *allocbuf(BUF *, int, int);
char *colon(char *);
void lostconn(int);
void nospace(void);
int okname(char *);
void run_err(const char *, ...) __printflike(1, 2);
int susystem(char *, int);
void verifydir(char *);

View File

@ -1,160 +0,0 @@
.\"-
.\" Copyright (c) 1983, 1990, 1993
.\" The Regents of the University of California. All rights reserved.
.\"
.\" 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.
.\" 3. Neither the name of the University nor the names of its contributors
.\" may be used to endorse or promote products derived from this software
.\" without specific prior written permission.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
.\"
.\" @(#)rcp.1 8.1 (Berkeley) 5/31/93
.\" $FreeBSD$
.\"
.Dd July 3, 2017
.Dt RCP 1
.Os
.Sh NAME
.Nm rcp
.Nd remote file copy
.Sh SYNOPSIS
.Nm
.Op Fl 46p
.Ar file1 file2
.Nm
.Op Fl 46pr
.Ar
.Ar directory
.Sh DEPRECATION NOTICE
.Nm
is deprecated and will be removed from future versions of the
.Fx
base system.
If
.Nm
is still required, it can be installed from ports or packages
(net/bsdrcmds).
.Sh DESCRIPTION
The
.Nm
utility copies files between machines.
Each
.Ar file
or
.Ar directory
argument is either a remote file name of the
form
.Dq ruser@rhost:path ,
or a local file name (containing no
.Ql :\&
characters,
or a
.Ql /
before any
.Ql :\& Ns
s).
.Pp
The following options are available:
.Bl -tag -width indent
.It Fl 4
Use IPv4 addresses only.
.It Fl 6
Use IPv6 addresses only.
.It Fl p
Cause
.Nm
to attempt to preserve (duplicate) in its copies the modification
times and modes of the source files, ignoring the
.Xr umask 2 .
By default, the mode and owner of
.Ar file2
are preserved if it already existed; otherwise the mode of the source file
modified by the
.Xr umask 2
on the destination host is used.
.It Fl r
If any of the source files are directories,
.Nm
copies each subtree rooted at that name; in this case
the destination must be a directory.
.El
.Pp
If
.Ar path
is not a full path name, it is interpreted relative to
the login directory of the specified user
.Ar ruser
on
.Ar rhost ,
or your current user name if no other remote user name is specified.
A
.Ar path
on a remote host may be quoted (using
.Ql \e ,
.Ql \&" ,
or
.Ql \(aa )
so that the metacharacters are interpreted remotely.
.Pp
The
.Nm
utility does not prompt for passwords; it performs remote execution
via
.Xr rsh 1 ,
and requires the same authorization.
.Pp
The
.Nm
utility handles third party copies, where neither source nor target files
are on the current machine.
.Sh SEE ALSO
.Xr cp 1 ,
.Xr ftp 1 ,
.Xr rlogin 1 ,
.Xr rsh 1 ,
.Xr hosts.equiv 5
.Sh HISTORY
The
.Nm
command appeared in
.Bx 4.2 .
The version of
.Nm
described here
has been reimplemented with Kerberos in
.Bx 4.3 Reno .
.Sh BUGS
Does not detect all cases where the target of a copy might
be a file in cases where only a directory should be legal.
.Pp
Is confused by any output generated by commands in a
.Pa .login ,
.Pa .profile ,
or
.Pa .cshrc
file on the remote host.
.Pp
The destination user and hostname may have to be specified as
.Dq rhost.ruser
when the destination machine is running the
.Bx 4.2
version of
.Nm .

View File

@ -1,791 +0,0 @@
/*-
* Copyright (c) 1983, 1990, 1992, 1993
* The Regents of the University of California. All rights reserved.
* Copyright (c) 2002 Networks Associates Technology, Inc.
* All rights reserved.
*
* Portions of this software were developed for the FreeBSD Project by
* ThinkSec AS and NAI Labs, the Security Research Division of Network
* Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035
* ("CBOSS"), as part of the DARPA CHATS research program.
*
* 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.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
*/
#if 0
#ifndef lint
static char const copyright[] =
"@(#) Copyright (c) 1983, 1990, 1992, 1993\n\
The Regents of the University of California. All rights reserved.\n";
#endif /* not lint */
#ifndef lint
static char sccsid[] = "@(#)rcp.c 8.2 (Berkeley) 4/2/94";
#endif /* not lint */
#endif
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/in_systm.h>
#include <netinet/ip.h>
#include <ctype.h>
#include <dirent.h>
#include <err.h>
#include <errno.h>
#include <fcntl.h>
#include <limits.h>
#include <netdb.h>
#include <paths.h>
#include <pwd.h>
#include <signal.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "extern.h"
#define OPTIONS "46dfprt"
static struct passwd *pwd;
static u_short port;
static uid_t userid;
static int errs, rem;
int iamremote;
static int pflag, iamrecursive, targetshouldbedirectory;
static int family = PF_UNSPEC;
static int argc_copy;
static const char **argv_copy;
static char period[] = ".";
#define CMDNEEDS 64
static char cmd[CMDNEEDS]; /* must hold "rcp -r -p -d\0" */
int response(void);
void rsource(char *, struct stat *);
void sink(int, char *[]);
void source(int, char *[]);
void tolocal(int, char *[]);
void toremote(char *, int, char *[]);
void usage(void);
int
main(int argc, char *argv[])
{
struct servent *sp;
int ch, fflag, i, tflag;
char *targ;
/*
* Prepare for execing ourselves.
*/
argc_copy = argc + 1;
argv_copy = malloc((argc_copy + 1) * sizeof(*argv_copy));
if (argv_copy == NULL)
err(1, "malloc");
argv_copy[0] = argv[0];
argv_copy[1] = "-K";
for (i = 1; i < argc; ++i) {
argv_copy[i + 1] = strdup(argv[i]);
if (argv_copy[i + 1] == NULL)
errx(1, "strdup: out of memory");
}
argv_copy[argc + 1] = NULL;
fflag = tflag = 0;
while ((ch = getopt(argc, argv, OPTIONS)) != -1)
switch(ch) { /* User-visible flags. */
case '4':
family = PF_INET;
break;
case '6':
family = PF_INET6;
break;
case 'p':
pflag = 1;
break;
case 'r':
iamrecursive = 1;
break;
/* Server options. */
case 'd':
targetshouldbedirectory = 1;
break;
case 'f': /* "from" */
iamremote = 1;
fflag = 1;
break;
case 't': /* "to" */
iamremote = 1;
tflag = 1;
break;
case '?':
default:
usage();
}
argc -= optind;
argv += optind;
sp = getservbyname("shell", "tcp");
if (sp == NULL)
errx(1, "shell/tcp: unknown service");
port = sp->s_port;
if ((pwd = getpwuid(userid = getuid())) == NULL)
errx(1, "unknown user %d", (int)userid);
rem = STDIN_FILENO; /* XXX */
if (fflag) { /* Follow "protocol", send data. */
(void)response();
(void)setuid(userid);
source(argc, argv);
exit(errs);
}
if (tflag) { /* Receive data. */
(void)setuid(userid);
sink(argc, argv);
exit(errs);
}
if (argc < 2)
usage();
if (argc > 2)
targetshouldbedirectory = 1;
rem = -1;
/* Command to be executed on remote system using "rsh". */
(void)snprintf(cmd, sizeof(cmd), "rcp%s%s%s",
iamrecursive ? " -r" : "", pflag ? " -p" : "",
targetshouldbedirectory ? " -d" : "");
(void)signal(SIGPIPE, lostconn);
if ((targ = colon(argv[argc - 1]))) /* Dest is remote host. */
toremote(targ, argc, argv);
else {
tolocal(argc, argv); /* Dest is local host. */
if (targetshouldbedirectory)
verifydir(argv[argc - 1]);
}
exit(errs);
}
void
toremote(char *targ, int argc, char *argv[])
{
int i, tos;
char *bp, *host, *src, *suser, *thost, *tuser;
*targ++ = 0;
if (*targ == 0)
targ = period;
if ((thost = strchr(argv[argc - 1], '@'))) {
/* user@host */
*thost++ = 0;
tuser = argv[argc - 1];
if (*tuser == '\0')
tuser = NULL;
else if (!okname(tuser))
exit(1);
} else {
thost = argv[argc - 1];
tuser = NULL;
}
for (i = 0; i < argc - 1; i++) {
src = colon(argv[i]);
if (src) { /* remote to remote */
*src++ = 0;
if (*src == 0)
src = period;
host = strchr(argv[i], '@');
if (host) {
*host++ = 0;
suser = argv[i];
if (*suser == '\0')
suser = pwd->pw_name;
else if (!okname(suser)) {
++errs;
continue;
}
if (asprintf(&bp,
"%s %s -l %s -n %s %s '%s%s%s:%s'",
_PATH_RSH, host, suser, cmd, src,
tuser ? tuser : "", tuser ? "@" : "",
thost, targ) == -1)
err(1, "asprintf");
} else
if (asprintf(&bp,
"exec %s %s -n %s %s '%s%s%s:%s'",
_PATH_RSH, argv[i], cmd, src,
tuser ? tuser : "", tuser ? "@" : "",
thost, targ) == -1)
err(1, "asprintf");
(void)susystem(bp, userid);
(void)free(bp);
} else { /* local to remote */
if (rem == -1) {
if (asprintf(&bp, "%s -t %s", cmd, targ)
== -1)
err(1, "asprintf");
host = thost;
rem = rcmd_af(&host, port,
pwd->pw_name,
tuser ? tuser : pwd->pw_name,
bp, 0, family);
if (rem < 0)
exit(1);
if (family == PF_INET) {
tos = IPTOS_THROUGHPUT;
if (setsockopt(rem, IPPROTO_IP, IP_TOS,
&tos, sizeof(int)) < 0)
warn("TOS (ignored)");
}
if (response() < 0)
exit(1);
(void)free(bp);
(void)setuid(userid);
}
source(1, argv+i);
}
}
}
void
tolocal(int argc, char *argv[])
{
int i, len, tos;
char *bp, *host, *src, *suser;
for (i = 0; i < argc - 1; i++) {
if (!(src = colon(argv[i]))) { /* Local to local. */
len = strlen(_PATH_CP) + strlen(argv[i]) +
strlen(argv[argc - 1]) + 20;
if (!(bp = malloc(len)))
err(1, "malloc");
(void)snprintf(bp, len, "exec %s%s%s %s %s", _PATH_CP,
iamrecursive ? " -PR" : "", pflag ? " -p" : "",
argv[i], argv[argc - 1]);
if (susystem(bp, userid))
++errs;
(void)free(bp);
continue;
}
*src++ = 0;
if (*src == 0)
src = period;
if ((host = strchr(argv[i], '@')) == NULL) {
host = argv[i];
suser = pwd->pw_name;
} else {
*host++ = 0;
suser = argv[i];
if (*suser == '\0')
suser = pwd->pw_name;
else if (!okname(suser)) {
++errs;
continue;
}
}
len = strlen(src) + CMDNEEDS + 20;
if ((bp = malloc(len)) == NULL)
err(1, "malloc");
(void)snprintf(bp, len, "%s -f %s", cmd, src);
rem = rcmd_af(&host, port, pwd->pw_name, suser, bp, 0,
family);
(void)free(bp);
if (rem < 0) {
++errs;
continue;
}
(void)seteuid(userid);
if (family == PF_INET) {
tos = IPTOS_THROUGHPUT;
if (setsockopt(rem, IPPROTO_IP, IP_TOS, &tos,
sizeof(int)) < 0)
warn("TOS (ignored)");
}
sink(1, argv + argc - 1);
(void)seteuid(0);
(void)close(rem);
rem = -1;
}
}
void
source(int argc, char *argv[])
{
struct stat stb;
static BUF buffer;
BUF *bp;
off_t i;
int amt, fd, haderr, indx, result;
char *last, *name, buf[BUFSIZ];
for (indx = 0; indx < argc; ++indx) {
name = argv[indx];
if ((fd = open(name, O_RDONLY, 0)) < 0)
goto syserr;
if (fstat(fd, &stb)) {
syserr: run_err("%s: %s", name, strerror(errno));
goto next;
}
switch (stb.st_mode & S_IFMT) {
case S_IFREG:
break;
case S_IFDIR:
if (iamrecursive) {
rsource(name, &stb);
goto next;
}
/* FALLTHROUGH */
default:
run_err("%s: not a regular file", name);
goto next;
}
if ((last = strrchr(name, '/')) == NULL)
last = name;
else
++last;
if (pflag) {
/*
* Make it compatible with possible future
* versions expecting microseconds.
*/
(void)snprintf(buf, sizeof(buf), "T%ld 0 %ld 0\n",
(long)stb.st_mtim.tv_sec,
(long)stb.st_atim.tv_sec);
(void)write(rem, buf, strlen(buf));
if (response() < 0)
goto next;
}
#define MODEMASK (S_ISUID|S_ISGID|S_ISTXT|S_IRWXU|S_IRWXG|S_IRWXO)
(void)snprintf(buf, sizeof(buf), "C%04o %jd %s\n",
stb.st_mode & MODEMASK, (intmax_t)stb.st_size, last);
(void)write(rem, buf, strlen(buf));
if (response() < 0)
goto next;
if ((bp = allocbuf(&buffer, fd, BUFSIZ)) == NULL) {
next: if (fd >= 0)
(void)close(fd);
continue;
}
/* Keep writing after an error so that we stay sync'd up. */
for (haderr = i = 0; i < stb.st_size; i += bp->cnt) {
amt = bp->cnt;
if (i + amt > stb.st_size)
amt = stb.st_size - i;
if (!haderr) {
result = read(fd, bp->buf, amt);
if (result != amt)
haderr = result >= 0 ? EIO : errno;
}
if (haderr)
(void)write(rem, bp->buf, amt);
else {
result = write(rem, bp->buf, amt);
if (result != amt)
haderr = result >= 0 ? EIO : errno;
}
}
if (close(fd) && !haderr)
haderr = errno;
if (!haderr)
(void)write(rem, "", 1);
else
run_err("%s: %s", name, strerror(haderr));
(void)response();
}
}
void
rsource(char *name, struct stat *statp)
{
DIR *dirp;
struct dirent *dp;
char *last, *vect[1], path[PATH_MAX];
if (!(dirp = opendir(name))) {
run_err("%s: %s", name, strerror(errno));
return;
}
last = strrchr(name, '/');
if (last == NULL)
last = name;
else
last++;
if (pflag) {
(void)snprintf(path, sizeof(path), "T%ld 0 %ld 0\n",
(long)statp->st_mtim.tv_sec,
(long)statp->st_atim.tv_sec);
(void)write(rem, path, strlen(path));
if (response() < 0) {
closedir(dirp);
return;
}
}
(void)snprintf(path, sizeof(path),
"D%04o %d %s\n", statp->st_mode & MODEMASK, 0, last);
(void)write(rem, path, strlen(path));
if (response() < 0) {
closedir(dirp);
return;
}
while ((dp = readdir(dirp))) {
if (dp->d_ino == 0)
continue;
if (!strcmp(dp->d_name, ".") || !strcmp(dp->d_name, ".."))
continue;
if (strlen(name) + 1 + strlen(dp->d_name) >= sizeof(path)) {
run_err("%s/%s: name too long", name, dp->d_name);
continue;
}
(void)snprintf(path, sizeof(path), "%s/%s", name, dp->d_name);
vect[0] = path;
source(1, vect);
}
(void)closedir(dirp);
(void)write(rem, "E\n", 2);
(void)response();
}
void
sink(int argc, char *argv[])
{
static BUF buffer;
struct stat stb;
struct timeval tv[2];
enum { YES, NO, DISPLAYED } wrerr;
BUF *bp;
off_t i, j, size;
int amt, exists, first, mask, mode, ofd, omode;
size_t count;
int setimes, targisdir, wrerrno = 0;
char ch, *cp, *np, *targ, *vect[1], buf[BUFSIZ], path[PATH_MAX];
const char *why;
#define atime tv[0]
#define mtime tv[1]
#define SCREWUP(str) { why = str; goto screwup; }
setimes = targisdir = 0;
mask = umask(0);
if (!pflag)
(void)umask(mask);
if (argc != 1) {
run_err("ambiguous target");
exit(1);
}
targ = *argv;
if (targetshouldbedirectory)
verifydir(targ);
(void)write(rem, "", 1);
if (stat(targ, &stb) == 0 && S_ISDIR(stb.st_mode))
targisdir = 1;
for (first = 1;; first = 0) {
cp = buf;
if (read(rem, cp, 1) <= 0)
return;
if (*cp++ == '\n')
SCREWUP("unexpected <newline>");
do {
if (read(rem, &ch, sizeof(ch)) != sizeof(ch))
SCREWUP("lost connection");
*cp++ = ch;
} while (cp < &buf[BUFSIZ - 1] && ch != '\n');
*cp = 0;
if (buf[0] == '\01' || buf[0] == '\02') {
if (iamremote == 0)
(void)write(STDERR_FILENO,
buf + 1, strlen(buf + 1));
if (buf[0] == '\02')
exit(1);
++errs;
continue;
}
if (buf[0] == 'E') {
(void)write(rem, "", 1);
return;
}
if (ch == '\n')
*--cp = 0;
cp = buf;
if (*cp == 'T') {
setimes++;
cp++;
mtime.tv_sec = strtol(cp, &cp, 10);
if (!cp || *cp++ != ' ')
SCREWUP("mtime.sec not delimited");
mtime.tv_usec = strtol(cp, &cp, 10);
if (!cp || *cp++ != ' ')
SCREWUP("mtime.usec not delimited");
atime.tv_sec = strtol(cp, &cp, 10);
if (!cp || *cp++ != ' ')
SCREWUP("atime.sec not delimited");
atime.tv_usec = strtol(cp, &cp, 10);
if (!cp || *cp++ != '\0')
SCREWUP("atime.usec not delimited");
(void)write(rem, "", 1);
continue;
}
if (*cp != 'C' && *cp != 'D') {
/*
* Check for the case "rcp remote:foo\* local:bar".
* In this case, the line "No match." can be returned
* by the shell before the rcp command on the remote is
* executed so the ^Aerror_message convention isn't
* followed.
*/
if (first) {
run_err("%s", cp);
exit(1);
}
SCREWUP("expected control record");
}
mode = 0;
for (++cp; cp < buf + 5; cp++) {
if (*cp < '0' || *cp > '7')
SCREWUP("bad mode");
mode = (mode << 3) | (*cp - '0');
}
if (*cp++ != ' ')
SCREWUP("mode not delimited");
for (size = 0; isdigit(*cp);)
size = size * 10 + (*cp++ - '0');
if (*cp++ != ' ')
SCREWUP("size not delimited");
if (targisdir) {
if (strlen(targ) + (*targ ? 1 : 0) + strlen(cp)
>= sizeof(path)) {
run_err("%s%s%s: name too long", targ,
*targ ? "/" : "", cp);
exit(1);
}
(void)snprintf(path, sizeof(path), "%s%s%s", targ,
*targ ? "/" : "", cp);
np = path;
} else
np = targ;
exists = stat(np, &stb) == 0;
if (buf[0] == 'D') {
int mod_flag = pflag;
if (exists) {
if (!S_ISDIR(stb.st_mode)) {
errno = ENOTDIR;
goto bad;
}
if (pflag)
(void)chmod(np, mode);
} else {
/* Handle copying from a read-only directory */
mod_flag = 1;
if (mkdir(np, mode | S_IRWXU) < 0)
goto bad;
}
vect[0] = np;
sink(1, vect);
if (setimes) {
setimes = 0;
if (utimes(np, tv) < 0)
run_err("%s: set times: %s",
np, strerror(errno));
}
if (mod_flag)
(void)chmod(np, mode);
continue;
}
omode = mode;
mode |= S_IWRITE;
if ((ofd = open(np, O_WRONLY|O_CREAT, mode)) < 0) {
bad: run_err("%s: %s", np, strerror(errno));
continue;
}
(void)write(rem, "", 1);
if ((bp = allocbuf(&buffer, ofd, BUFSIZ)) == NULL) {
(void)close(ofd);
continue;
}
cp = bp->buf;
wrerr = NO;
for (count = i = 0; i < size; i += BUFSIZ) {
amt = BUFSIZ;
if (i + amt > size)
amt = size - i;
count += amt;
do {
j = read(rem, cp, amt);
if (j <= 0) {
run_err("%s", j ? strerror(errno) :
"dropped connection");
exit(1);
}
amt -= j;
cp += j;
} while (amt > 0);
if (count == bp->cnt) {
/* Keep reading so we stay sync'd up. */
if (wrerr == NO) {
j = write(ofd, bp->buf, count);
if (j != (off_t)count) {
wrerr = YES;
wrerrno = j >= 0 ? EIO : errno;
}
}
count = 0;
cp = bp->buf;
}
}
if (count != 0 && wrerr == NO &&
(j = write(ofd, bp->buf, count)) != (off_t)count) {
wrerr = YES;
wrerrno = j >= 0 ? EIO : errno;
}
if (ftruncate(ofd, size)) {
run_err("%s: truncate: %s", np, strerror(errno));
wrerr = DISPLAYED;
}
if (pflag) {
if (exists || omode != mode)
if (fchmod(ofd, omode))
run_err("%s: set mode: %s",
np, strerror(errno));
} else {
if (!exists && omode != mode)
if (fchmod(ofd, omode & ~mask))
run_err("%s: set mode: %s",
np, strerror(errno));
}
(void)close(ofd);
(void)response();
if (setimes && wrerr == NO) {
setimes = 0;
if (utimes(np, tv) < 0) {
run_err("%s: set times: %s",
np, strerror(errno));
wrerr = DISPLAYED;
}
}
switch(wrerr) {
case YES:
run_err("%s: %s", np, strerror(wrerrno));
break;
case NO:
(void)write(rem, "", 1);
break;
case DISPLAYED:
break;
}
}
screwup:
run_err("protocol error: %s", why);
exit(1);
}
int
response(void)
{
char ch, *cp, resp, rbuf[BUFSIZ];
if (read(rem, &resp, sizeof(resp)) != sizeof(resp))
lostconn(0);
cp = rbuf;
switch(resp) {
case 0: /* ok */
return (0);
default:
*cp++ = resp;
/* FALLTHROUGH */
case 1: /* error, followed by error msg */
case 2: /* fatal error, "" */
do {
if (read(rem, &ch, sizeof(ch)) != sizeof(ch))
lostconn(0);
*cp++ = ch;
} while (cp < &rbuf[BUFSIZ] && ch != '\n');
if (!iamremote)
(void)write(STDERR_FILENO, rbuf, cp - rbuf);
++errs;
if (resp == 1)
return (-1);
exit(1);
}
/* NOTREACHED */
}
void
usage(void)
{
(void)fprintf(stderr, "%s\n%s\n",
"usage: rcp [-46p] file1 file2",
" rcp [-46pr] file ... directory");
exit(1);
}
#include <stdarg.h>
void
run_err(const char *fmt, ...)
{
static FILE *fp;
va_list ap;
++errs;
if (fp == NULL && !(fp = fdopen(rem, "w")))
return;
(void)fprintf(fp, "%c", 0x01);
(void)fprintf(fp, "rcp: ");
va_start(ap, fmt);
(void)vfprintf(fp, fmt, ap);
va_end(ap);
(void)fprintf(fp, "\n");
(void)fflush(fp);
if (!iamremote) {
va_start(ap, fmt);
vwarnx(fmt, ap);
va_end(ap);
}
}

View File

@ -1,5 +0,0 @@
# $FreeBSD$
ATF_TESTS_SH+= rcp_test
.include <bsd.test.mk>

View File

@ -1,60 +0,0 @@
#
# Copyright 2017 Shivansh Rai
# All rights reserved.
#
# 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$
#
usage_output='usage: rcp'
atf_test_case invalid_usage
invalid_usage_head()
{
atf_set "descr" "Verify that an invalid usage with a supported option produces a valid error message"
}
invalid_usage_body()
{
atf_check -s not-exit:0 -e match:"$usage_output" rcp -4
atf_check -s not-exit:0 -e match:"$usage_output" rcp -6
atf_check -s not-exit:0 -e match:"$usage_output" rcp -p
atf_check -s not-exit:0 -e match:"$usage_output" rcp -r
}
atf_test_case no_arguments
no_arguments_head()
{
atf_set "descr" "Verify that rcp(1) fails and generates a valid usage message when no arguments are supplied"
}
no_arguments_body()
{
atf_check -s not-exit:0 -e match:"$usage_output" rcp
}
atf_init_test_cases()
{
atf_add_test_case invalid_usage
atf_add_test_case no_arguments
}

View File

@ -1,159 +0,0 @@
/*-
* Copyright (c) 1992, 1993
* The Regents of the University of California. All rights reserved.
*
* 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.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
*/
#ifndef lint
#if 0
static const char sccsid[] = "@(#)util.c 8.2 (Berkeley) 4/2/94";
#endif
#endif /* not lint */
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <ctype.h>
#include <err.h>
#include <errno.h>
#include <paths.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "extern.h"
char *
colon(char *cp)
{
if (*cp == ':') /* Leading colon is part of file name. */
return (0);
for (; *cp; ++cp) {
if (*cp == ':')
return (cp);
if (*cp == '/')
return (0);
}
return (0);
}
void
verifydir(char *cp)
{
struct stat stb;
if (!stat(cp, &stb)) {
if (S_ISDIR(stb.st_mode))
return;
errno = ENOTDIR;
}
run_err("%s: %s", cp, strerror(errno));
exit(1);
}
int
okname(char *cp0)
{
int c;
char *cp;
cp = cp0;
do {
c = *cp;
if (c & 0200)
goto bad;
if (!isalpha(c) && !isdigit(c) && c != '_' && c != '-' && c != '.')
goto bad;
} while (*++cp);
return (1);
bad: warnx("%s: invalid user name", cp0);
return (0);
}
int
susystem(char *s, int userid)
{
sig_t istat, qstat;
int status;
pid_t pid;
pid = vfork();
switch (pid) {
case -1:
return (127);
case 0:
(void)setuid(userid);
execl(_PATH_BSHELL, "sh", "-c", s, (char *)NULL);
_exit(127);
}
istat = signal(SIGINT, SIG_IGN);
qstat = signal(SIGQUIT, SIG_IGN);
if (waitpid(pid, &status, 0) < 0)
status = -1;
(void)signal(SIGINT, istat);
(void)signal(SIGQUIT, qstat);
return (status);
}
BUF *
allocbuf(BUF *bp, int fd, int blksize)
{
struct stat stb;
size_t size;
if (fstat(fd, &stb) < 0) {
run_err("fstat: %s", strerror(errno));
return (0);
}
size = roundup(stb.st_blksize, blksize);
if (size == 0)
size = blksize;
if (bp->cnt >= size)
return (bp);
if ((bp->buf = realloc(bp->buf, size)) == NULL) {
bp->cnt = 0;
run_err("%s", strerror(errno));
return (0);
}
bp->cnt = size;
return (bp);
}
void
lostconn(int signo __unused)
{
if (!iamremote)
warnx("lost connection");
exit(1);
}

View File

@ -1,6 +1,3 @@
'\" te
.\" Copyright (c) 2012, Martin Matuska <mm@FreeBSD.org>.
.\" All Rights Reserved.
.\"
.\" This file and its contents are supplied under the terms of the
.\" Common Development and Distribution License ("CDDL"), version 1.0.
@ -13,71 +10,75 @@
.\"
.\"
.\" Copyright 2012, Richard Lowe.
.\" Copyright (c) 2012, Marcelo Araujo <araujo@FreeBSD.org>.
.\" Copyright (c) 2012, 2014 by Delphix. All rights reserved.
.\" All Rights Reserved.
.\" Copyright (c) 2012, 2017 by Delphix. All rights reserved.
.\" Copyright 2017 Nexenta Systems, Inc.
.\"
.\" $FreeBSD$
.\"
.Dd July 26, 2014
.Dd October 06, 2017
.Dt ZDB 8
.Os
.Sh NAME
.Nm zdb
.Nd Display zpool debugging and consistency information
.Nd display zpool debugging and consistency information
.Sh SYNOPSIS
.Nm
.Op Fl CumdibcsDvhLMXFPA
.Op Fl e Op Fl p Ar path...
.Op Fl t Ar txg
.Op Fl U Ar cache
.Op Fl AbcdDFGhiLMPsvX
.Op Fl e Oo Fl V Oc Op Fl p Ar path ...
.Op Fl I Ar inflight I/Os
.Op Fl x Ar dumpdir
.Ar poolname
.Op Ar object ...
.Nm
.Op Fl divPA
.Op Fl e Op Fl p Ar path...
.Op Fl U Ar cache
.Ar dataset
.Op Ar object ...
.Nm
.Fl m Op Fl MLXFPA
.Oo Fl o Ar var Ns = Ns Ar value Oc Ns ...
.Op Fl t Ar txg
.Op Fl e Op Fl p Ar path...
.Op Fl U Ar cache
.Ar poolname
.Op Fl x Ar dumpdir
.Op Ar poolname Op Ar object ...
.Nm
.Fl R Op Fl A
.Op Fl e Op Fl p Ar path...
.Op Fl AdiPv
.Op Fl e Oo Fl V Oc Op Fl p Ar path ...
.Op Fl U Ar cache
.Ar poolname
.Ar poolname
.Ar vdev Ns : Ns Ar offset Ns : Ns Ar size Ns Op Ns : Ns Ar flags
.Nm
.Fl S
.Op Fl AP
.Op Fl e Op Fl p Ar path...
.Op Fl U Ar cache
.Ar poolname
.Ar poolname
.Nm
.Fl l
.Op Fl uA
.Ar device
.Ar dataset Op Ar object ...
.Nm
.Fl C
.Op Fl A
.Op Fl U Ar cache
.Nm
.Fl E
.Op Fl A
.Ar word0 Ns \&: Ns Ar word1 Ns :...: Ns Ar word15
.Nm
.Fl l
.Op Fl Aqu
.Ar device
.Nm
.Fl m
.Op Fl AFLPX
.Op Fl e Oo Fl V Oc Op Fl p Ar path ...
.Op Fl t Ar txg
.Op Fl U Ar cache
.Ar poolname Op Ar vdev Op Ar metaslab ...
.Nm
.Fl O
.Ar dataset path
.Nm
.Fl R
.Op Fl A
.Op Fl e Oo Fl V Oc Op Fl p Ar path ...
.Op Fl U Ar cache
.Ar poolname vdev Ns \&: Ns Ar offset Ns \&: Ns Ar size Ns Op : Ns Ar flags
.Nm
.Fl S
.Op Fl AP
.Op Fl e Oo Fl V Oc Op Fl p Ar path ...
.Op Fl U Ar cache
.Ar poolname
.Sh DESCRIPTION
The
.Nm
utility displays information about a ZFS pool useful for debugging and
performs some amount of consistency checking.
It is a not a general purpose tool and options (and facilities) may change.
utility displays information about a ZFS pool useful for debugging and performs
some amount of consistency checking.
It is a not a general purpose tool and options
.Pq and facilities
may change.
This is neither a
.Xr fsck 8
nor a
nor an
.Xr fsdb 8
utility.
.Pp
@ -89,73 +90,96 @@ internals is assumed.
If the
.Ar dataset
argument does not contain any
.Sy /
.Qq Sy /
or
.Sy @
.Qq Sy @
characters, it is interpreted as a pool name.
The root dataset can be specified as
.Pa pool Ns Sy /
(pool name followed by a slash).
.Ar pool Ns /
.Pq pool name followed by a slash .
.Pp
When operating on an imported and active pool it is possible, though unlikely,
that zdb may interpret inconsistent pool data and behave erratically.
.Sh OPTIONS
Display options:
.Bl -tag -width indent
.Bl -tag -width Ds
.It Fl b
Display statistics regarding the number, size (logical, physical and
allocated) and deduplication of blocks.
Display statistics regarding the number, size
.Pq logical, physical and allocated
and deduplication of blocks.
.It Fl c
Verify the checksum of all metadata blocks while printing block statistics
(see
.Fl b Ns ).
.Po see
.Fl b
.Pc .
.Pp
If specified multiple times, verify the checksums of all blocks.
.It Fl C
Display information about the configuration. If specified with no other
options, instead display information about the cache file
.Po Pa /etc/zfs/zpool.cache Pc .
Display information about the configuration.
If specified with no other options, instead display information about the cache
file
.Pq Pa /boot/zfs/zpool.cache .
To specify the cache file to display, see
.Fl U
.Fl U .
.Pp
If specified multiple times, and a pool name is also specified display both
the cached configuration and the on-disk configuration.
If specified multiple times, and a pool name is also specified display both the
cached configuration and the on-disk configuration.
If specified multiple times with
.Fl e
also display the configuration that would be used were the pool to be
imported.
also display the configuration that would be used were the pool to be imported.
.It Fl d
Display information about datasets. Specified once, displays basic dataset
information: ID, create transaction, size, and object count.
Display information about datasets.
Specified once, displays basic dataset information: ID, create transaction,
size, and object count.
.Pp
If specified multiple times provides greater and greater verbosity.
.Pp
If object IDs are specified, display information about those specific objects only.
If object IDs are specified, display information about those specific objects
only.
.It Fl D
Display deduplication statistics, including the deduplication ratio (dedup),
compression ratio (compress), inflation due to the zfs copies property
(copies), and an overall effective ratio (dedup * compress / copies).
.Pp
If specified twice, display a histogram of deduplication statistics, showing
the allocated (physically present on disk) and referenced (logically
referenced in the pool) block counts and sizes by reference count.
.Pp
If specified a third time, display the statistics independently for each deduplication table.
.Pp
If specified a fourth time, dump the contents of the deduplication tables describing duplicate blocks.
.Pp
If specified a fifth time, also dump the contents of the deduplication tables describing unique blocks.
Display deduplication statistics, including the deduplication ratio
.Pq Sy dedup ,
compression ratio
.Pq Sy compress ,
inflation due to the zfs copies property
.Pq Sy copies ,
and an overall effective ratio
.Pq Sy dedup No * Sy compress No / Sy copies .
.It Fl DD
Display a histogram of deduplication statistics, showing the allocated
.Pq physically present on disk
and referenced
.Pq logically referenced in the pool
block counts and sizes by reference count.
.It Fl DDD
Display the statistics independently for each deduplication table.
.It Fl DDDD
Dump the contents of the deduplication tables describing duplicate blocks.
.It Fl DDDDD
Also dump the contents of the deduplication tables describing unique blocks.
.It Fl E Ar word0 Ns \&: Ns Ar word1 Ns :...: Ns Ar word15
Decode and display block from an embedded block pointer specified by the
.Ar word
arguments.
.It Fl h
Display pool history similar to
.Cm zpool history ,
.Nm zpool Cm history ,
but include internal changes, transaction, and dataset information.
.It Fl i
Display information about intent log (ZIL) entries relating to each
dataset.
If specified multiple times, display counts of each intent log transaction
type.
Display information about intent log
.Pq ZIL
entries relating to each dataset.
If specified multiple times, display counts of each intent log transaction type.
.It Fl l Ar device
Display the vdev labels from the specified device.
Read the vdev labels from the specified device.
.Nm Fl l
will return 0 if valid label was found, 1 if error occurred, and 2 if no valid
labels were found.
.Pp
If the
.Fl q
option is also specified, don't print the labels.
.Pp
If the
.Fl u
option is also specified, also display the uberblocks on this device.
@ -166,36 +190,55 @@ By default,
verifies that all non-free blocks are referenced, which can be very expensive.
.It Fl m
Display the offset, spacemap, and free space of each metaslab.
When specified twice, also display information about the on-disk free
space histogram associated with each metaslab. When specified three time,
display the maximum contiguous free space, the in-core free space histogram,
and the percentage of free space in each space map. When specified
four times display every spacemap record.
.It Fl mm
Also display information about the on-disk free space histogram associated with
each metaslab.
.It Fl mmm
Display the maximum contiguous free space, the in-core free space histogram, and
the percentage of free space in each space map.
.It Fl mmmm
Display every spacemap record.
.It Fl M
Display the offset, spacemap, and free space of each metaslab.
When specified twice, also display information about the maximum contiguous
free space and the percentage of free space in each space map.
When specified three times display every spacemap record.
.It Fl MM
Also display information about the maximum contiguous free space and the
percentage of free space in each space map.
.It Fl MMM
Display every spacemap record.
.It Fl O Ar dataset path
Look up the specified
.Ar path
inside of the
.Ar dataset
and display its metadata and indirect blocks.
Specified
.Ar path
must be relative to the root of
.Ar dataset .
This option can be combined with
.Fl v
for increasing verbosity.
.It Xo
.Fl R Ar poolname
.Ar vdev Ns : Ns Ar offset Ns : Ns Ar size Ns Op Ns : Ns Ar flags
.Fl R Ar poolname vdev Ns \&: Ns Ar offset Ns \&: Ns Ar size Ns Op : Ns Ar flags
.Xc
Read and display a block from the specified device. By default the block is
displayed as a hex dump, but see the description of the
.Fl r
Read and display a block from the specified device.
By default the block is displayed as a hex dump, but see the description of the
.Sy r
flag, below.
.Pp
The block is specified in terms of a colon-separated tuple
.Ar vdev
(an integer vdev identifier)
.Pq an integer vdev identifier
.Ar offset
(the offset within the vdev)
.Pq the offset within the vdev
.Ar size
(the size of the block to read) and, optionally,
.Pq the size of the block to read
and, optionally,
.Ar flags
(a set of flags, described below).
.Bl -tag -width indent
.It Sy b offset
.Pq a set of flags, described below .
.Pp
.Bl -tag -compact -width "b offset"
.It Sy b Ar offset
Print block pointer
.It Sy d
Decompress the block
@ -210,19 +253,20 @@ Dump raw uninterpreted block data
.El
.It Fl s
Report statistics on
.Nm Ns 's
.Nm zdb
I/O.
Display operation counts, bandwidth, and error counts of I/O to the pool from
.Nm .
.It Fl S
Simulate the effects of deduplication, constructing a DDT and then display
that DDT as with \fB-DD\fR.
that DDT as with
.Fl DD .
.It Fl u
Display the current uberblock.
.El
.Pp
Other options:
.Bl -tag -width indent
.Bl -tag -width Ds
.It Fl A
Do not abort should any assertion fail.
.It Fl AA
@ -230,28 +274,41 @@ Enable panic recovery, certain errors which would otherwise be fatal are
demoted to warnings.
.It Fl AAA
Do not abort if asserts fail and also enable panic recovery.
.It Fl e Op Fl p Ar path...
.It Fl e Op Fl p Ar path ...
Operate on an exported pool, not present in
.Pa /etc/zfs/zpool.cache .
.Pa /boot/zfs/zpool.cache .
The
.Fl p
flag specifies the path under which devices are to be searched.
.It Fl x Ar dumpdir
All blocks accessed will be copied to files in the specified directory.
The blocks will be placed in sparse files whose name is the same as
that of the file or device read. zdb can be then run on the generated files.
that of the file or device read.
.Nm
can be then run on the generated files.
Note that the
.Fl bbc
flags are sufficient to access (and thus copy)
flags are sufficient to access
.Pq and thus copy
all metadata on the pool.
.It Fl F
Attempt to make an unreadable pool readable by trying progressively older
transactions.
.It Fl G
Dump the contents of the zfs_dbgmsg buffer before exiting
.Nm .
zfs_dbgmsg is a buffer used by ZFS to dump advanced debug information.
.It Fl I Ar inflight I/Os
Limit the number of outstanding checksum I/Os to the specified value.
The default value is 200. This option affects the performance of the
The default value is 200.
This option affects the performance of the
.Fl c
option.
.It Fl o Ar var Ns = Ns Ar value ...
Set the given global libzpool variable to the provided value.
The value must be an unsigned 32-bit integer.
Currently only little-endian systems are supported to avoid accidentally setting
the high 32 bits of 64-bit variables.
.It Fl P
Print numbers in an unscaled form more amenable to parsing, eg. 1000000 rather
than 1M.
@ -269,9 +326,14 @@ Use a cache file other than
.It Fl v
Enable verbosity.
Specify multiple times for increased verbosity.
.It Fl V
Attempt verbatim import.
This mimics the behavior of the kernel when loading a pool from a cachefile.
Only usable with
.Fl e .
.It Fl X
Attempt
.Ql extreme
.Qq extreme
transaction rewind, that is attempt the same recovery as
.Fl F
but read transactions otherwise deemed too old.
@ -283,46 +345,58 @@ option, with more occurrences enabling more verbosity.
If no options are specified, all information about the named pool will be
displayed at default verbosity.
.Sh EXAMPLES
.Bl -tag -width 0n
.It Sy Example 1 Display the configuration of imported pool 'rpool'
.Bd -literal -offset 2n
.Li # Ic zdb -C rpool
.Bl -tag -width Ds
.It Xo
.Sy Example 1
Display the configuration of imported pool
.Pa rpool
.Xc
.Bd -literal
# zdb -C rpool
MOS Configuration:
version: 28
name: 'rpool'
...
.Ed
.It Sy Example 2 Display basic dataset information about 'rpool'
.Bd -literal -offset 2n
.Li # Ic zdb -d rpool
.It Xo
.Sy Example 2
Display basic dataset information about
.Pa rpool
.Xc
.Bd -literal
# zdb -d rpool
Dataset mos [META], ID 0, cr_txg 4, 26.9M, 1051 objects
Dataset rpool/swap [ZVOL], ID 59, cr_txg 356, 486M, 2 objects
...
.Ed
.It Xo Sy Example 3 Display basic information about object 0 in
.Sy 'rpool/export/home'
.It Xo
.Sy Example 3
Display basic information about object 0 in
.Pa rpool/export/home
.Xc
.Bd -literal -offset 2n
.Li # Ic zdb -d rpool/export/home 0
.Bd -literal
# zdb -d rpool/export/home 0
Dataset rpool/export/home [ZPL], ID 137, cr_txg 1546, 32K, 8 objects
Object lvl iblk dblk dsize lsize %full type
0 7 16K 16K 15.0K 16K 25.00 DMU dnode
.Ed
.It Xo Sy Example 4 Display the predicted effect of enabling deduplication on
.Sy 'rpool'
.It Xo
.Sy Example 4
Display the predicted effect of enabling deduplication on
.Pa rpool
.Xc
.Bd -literal -offset 2n
.Li # Ic zdb -S rpool
.Bd -literal
# zdb -S rpool
Simulated DDT histogram:
bucket allocated referenced
______ ______________________________ ______________________________
refcnt blocks LSIZE PSIZE DSIZE blocks LSIZE PSIZE DSIZE
------ ------ ----- ----- ----- ------ ----- ----- -----
1 694K 27.1G 15.0G 15.0G 694K 27.1G 15.0G 15.0G
2 35.0K 1.33G 699M 699M 74.7K 2.79G 1.45G 1.45G
bucket allocated referenced
______ ______________________________ ______________________________
refcnt blocks LSIZE PSIZE DSIZE blocks LSIZE PSIZE DSIZE
------ ------ ----- ----- ----- ------ ----- ----- -----
1 694K 27.1G 15.0G 15.0G 694K 27.1G 15.0G 15.0G
2 35.0K 1.33G 699M 699M 74.7K 2.79G 1.45G 1.45G
...
dedup = 1.11, compress = 1.80, copies = 1.00, dedup * compress / copies = 2.00
.Ed
@ -330,22 +404,3 @@ dedup = 1.11, compress = 1.80, copies = 1.00, dedup * compress / copies = 2.00
.Sh SEE ALSO
.Xr zfs 8 ,
.Xr zpool 8
.Sh AUTHORS
This manual page is a
.Xr mdoc 7
reimplementation of the
.Tn illumos
manual page
.Em zdb(1M) ,
modified and customized for
.Fx
and licensed under the
Common Development and Distribution License
.Pq Tn CDDL .
.Pp
The
.Xr mdoc 7
implementation of this manual page was initially written by
.An Martin Matuska Aq mm@FreeBSD.org
and
.An Marcelo Araujo Aq araujo@FreeBSD.org .

View File

@ -23,6 +23,7 @@
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2011, 2016 by Delphix. All rights reserved.
* Copyright (c) 2014 Integros [integros.com]
* Copyright 2017 Nexenta Systems, Inc.
*/
#include <stdio.h>
@ -60,6 +61,7 @@
#include <sys/ddt.h>
#include <sys/zfeature.h>
#include <sys/abd.h>
#include <sys/blkptr.h>
#include <zfs_comutil.h>
#undef verify
#include <libzfs.h>
@ -120,18 +122,24 @@ static void
usage(void)
{
(void) fprintf(stderr,
"Usage: %s [-CumMdibcsDvhLXFPAG] [-t txg] [-e [-p path...]] "
"[-U config] [-I inflight I/Os] [-x dumpdir] poolname [object...]\n"
" %s [-divPA] [-e -p path...] [-U config] dataset "
"[object...]\n"
" %s -mM [-LXFPA] [-t txg] [-e [-p path...]] [-U config] "
"poolname [vdev [metaslab...]]\n"
" %s -R [-A] [-e [-p path...]] poolname "
"vdev:offset:size[:flags]\n"
" %s -S [-PA] [-e [-p path...]] [-U config] poolname\n"
" %s -l [-uA] device\n"
" %s -C [-A] [-U config]\n\n",
cmdname, cmdname, cmdname, cmdname, cmdname, cmdname, cmdname);
"Usage:\t%s [-AbcdDFGhiLMPsvX] [-e [-V] [-p <path> ...]] "
"[-I <inflight I/Os>]\n"
"\t\t[-o <var>=<value>]... [-t <txg>] [-U <cache>] [-x <dumpdir>]\n"
"\t\t[<poolname> [<object> ...]]\n"
"\t%s [-AdiPv] [-e [-V] [-p <path> ...]] [-U <cache>] <dataset> "
"[<object> ...]\n"
"\t%s -C [-A] [-U <cache>]\n"
"\t%s -l [-Aqu] <device>\n"
"\t%s -m [-AFLPX] [-e [-V] [-p <path> ...]] [-t <txg>] "
"[-U <cache>]\n\t\t<poolname> [<vdev> [<metaslab> ...]]\n"
"\t%s -O <dataset> <path>\n"
"\t%s -R [-A] [-e [-V] [-p <path> ...]] [-U <cache>]\n"
"\t\t<poolname> <vdev>:<offset>:<size>[:<flags>]\n"
"\t%s -E [-A] word0:word1:...:word15\n"
"\t%s -S [-AP] [-e [-V] [-p <path> ...]] [-U <cache>] "
"<poolname>\n\n",
cmdname, cmdname, cmdname, cmdname, cmdname, cmdname, cmdname,
cmdname, cmdname);
(void) fprintf(stderr, " Dataset name must include at least one "
"separator character '/' or '@'\n");
@ -140,49 +148,57 @@ usage(void)
(void) fprintf(stderr, " If object numbers are specified, only "
"those objects are dumped\n\n");
(void) fprintf(stderr, " Options to control amount of output:\n");
(void) fprintf(stderr, " -u uberblock\n");
(void) fprintf(stderr, " -d dataset(s)\n");
(void) fprintf(stderr, " -i intent logs\n");
(void) fprintf(stderr, " -C config (or cachefile if alone)\n");
(void) fprintf(stderr, " -h pool history\n");
(void) fprintf(stderr, " -b block statistics\n");
(void) fprintf(stderr, " -m metaslabs\n");
(void) fprintf(stderr, " -M metaslab groups\n");
(void) fprintf(stderr, " -c checksum all metadata (twice for "
"all data) blocks\n");
(void) fprintf(stderr, " -s report stats on zdb's I/O\n");
(void) fprintf(stderr, " -C config (or cachefile if alone)\n");
(void) fprintf(stderr, " -d dataset(s)\n");
(void) fprintf(stderr, " -D dedup statistics\n");
(void) fprintf(stderr, " -S simulate dedup to measure effect\n");
(void) fprintf(stderr, " -v verbose (applies to all others)\n");
(void) fprintf(stderr, " -l dump label contents\n");
(void) fprintf(stderr, " -E decode and display block from an "
"embedded block pointer\n");
(void) fprintf(stderr, " -h pool history\n");
(void) fprintf(stderr, " -i intent logs\n");
(void) fprintf(stderr, " -l read label contents\n");
(void) fprintf(stderr, " -L disable leak tracking (do not "
"load spacemaps)\n");
(void) fprintf(stderr, " -m metaslabs\n");
(void) fprintf(stderr, " -M metaslab groups\n");
(void) fprintf(stderr, " -O perform object lookups by path\n");
(void) fprintf(stderr, " -R read and display block from a "
"device\n\n");
"device\n");
(void) fprintf(stderr, " -s report stats on zdb's I/O\n");
(void) fprintf(stderr, " -S simulate dedup to measure effect\n");
(void) fprintf(stderr, " -v verbose (applies to all "
"others)\n\n");
(void) fprintf(stderr, " Below options are intended for use "
"with other options:\n");
(void) fprintf(stderr, " -A ignore assertions (-A), enable "
"panic recovery (-AA) or both (-AAA)\n");
(void) fprintf(stderr, " -F attempt automatic rewind within "
"safe range of transaction groups\n");
(void) fprintf(stderr, " -U <cachefile_path> -- use alternate "
"cachefile\n");
(void) fprintf(stderr, " -X attempt extreme rewind (does not "
"work with dataset)\n");
(void) fprintf(stderr, " -e pool is exported/destroyed/"
"has altroot/not in a cachefile\n");
(void) fprintf(stderr, " -p <path> -- use one or more with "
"-e to specify path to vdev dir\n");
(void) fprintf(stderr, " -x <dumpdir> -- "
"dump all read blocks into specified directory\n");
(void) fprintf(stderr, " -P print numbers in parseable form\n");
(void) fprintf(stderr, " -t <txg> -- highest txg to use when "
"searching for uberblocks\n");
(void) fprintf(stderr, " -F attempt automatic rewind within "
"safe range of transaction groups\n");
(void) fprintf(stderr, " -G dump zfs_dbgmsg buffer before "
"exiting\n");
(void) fprintf(stderr, " -I <number of inflight I/Os> -- "
"specify the maximum number of "
"checksumming I/Os [default is 200]\n");
(void) fprintf(stderr, " -G dump zfs_dbgmsg buffer before "
"exiting\n");
(void) fprintf(stderr, " -o <variable>=<value> set global "
"variable to an unsigned 32-bit integer value\n");
(void) fprintf(stderr, " -p <path> -- use one or more with "
"-e to specify path to vdev dir\n");
(void) fprintf(stderr, " -P print numbers in parseable form\n");
(void) fprintf(stderr, " -q don't print label contents\n");
(void) fprintf(stderr, " -t <txg> -- highest txg to use when "
"searching for uberblocks\n");
(void) fprintf(stderr, " -u uberblock\n");
(void) fprintf(stderr, " -U <cachefile_path> -- use alternate "
"cachefile\n");
(void) fprintf(stderr, " -V do verbatim import\n");
(void) fprintf(stderr, " -x <dumpdir> -- "
"dump all read blocks into specified directory\n");
(void) fprintf(stderr, " -X attempt extreme rewind (does not "
"work with dataset)\n\n");
(void) fprintf(stderr, "Specify an option more than once (e.g. -bb) "
"to make only that option verbose\n");
(void) fprintf(stderr, "Default is to dump everything non-verbosely\n");
@ -1582,8 +1598,9 @@ dump_deadlist(dsl_deadlist_t *dl)
dle = AVL_NEXT(&dl->dl_tree, dle)) {
if (dump_opt['d'] >= 5) {
char buf[128];
(void) snprintf(buf, sizeof (buf), "mintxg %llu -> "
"obj %llu", (longlong_t)dle->dle_mintxg,
(void) snprintf(buf, sizeof (buf),
"mintxg %llu -> obj %llu",
(longlong_t)dle->dle_mintxg,
(longlong_t)dle->dle_bpobj.bpo_object);
dump_full_bpobj(&dle->dle_bpobj, buf, 0);
} else {
@ -1597,8 +1614,55 @@ dump_deadlist(dsl_deadlist_t *dl)
static avl_tree_t idx_tree;
static avl_tree_t domain_tree;
static boolean_t fuid_table_loaded;
static boolean_t sa_loaded;
sa_attr_type_t *sa_attr_table;
static objset_t *sa_os = NULL;
static sa_attr_type_t *sa_attr_table = NULL;
static int
open_objset(const char *path, dmu_objset_type_t type, void *tag, objset_t **osp)
{
int err;
uint64_t sa_attrs = 0;
uint64_t version = 0;
VERIFY3P(sa_os, ==, NULL);
err = dmu_objset_own(path, type, B_TRUE, tag, osp);
if (err != 0) {
(void) fprintf(stderr, "failed to own dataset '%s': %s\n", path,
strerror(err));
return (err);
}
if (dmu_objset_type(*osp) == DMU_OST_ZFS) {
(void) zap_lookup(*osp, MASTER_NODE_OBJ, ZPL_VERSION_STR,
8, 1, &version);
if (version >= ZPL_VERSION_SA) {
(void) zap_lookup(*osp, MASTER_NODE_OBJ, ZFS_SA_ATTRS,
8, 1, &sa_attrs);
}
err = sa_setup(*osp, sa_attrs, zfs_attr_table, ZPL_END,
&sa_attr_table);
if (err != 0) {
(void) fprintf(stderr, "sa_setup failed: %s\n",
strerror(err));
dmu_objset_disown(*osp, tag);
*osp = NULL;
}
}
sa_os = *osp;
return (0);
}
static void
close_objset(objset_t *os, void *tag)
{
VERIFY3P(os, ==, sa_os);
if (os->os_sa != NULL)
sa_tear_down(os);
dmu_objset_disown(os, tag);
sa_attr_table = NULL;
sa_os = NULL;
}
static void
fuid_table_destroy()
@ -1670,25 +1734,7 @@ dump_znode(objset_t *os, uint64_t object, void *data, size_t size)
int idx = 0;
int error;
if (!sa_loaded) {
uint64_t sa_attrs = 0;
uint64_t version;
VERIFY(zap_lookup(os, MASTER_NODE_OBJ, ZPL_VERSION_STR,
8, 1, &version) == 0);
if (version >= ZPL_VERSION_SA) {
VERIFY(zap_lookup(os, MASTER_NODE_OBJ, ZFS_SA_ATTRS,
8, 1, &sa_attrs) == 0);
}
if ((error = sa_setup(os, sa_attrs, zfs_attr_table,
ZPL_END, &sa_attr_table)) != 0) {
(void) printf("sa_setup failed errno %d, can't "
"display znode contents\n", error);
return;
}
sa_loaded = B_TRUE;
}
VERIFY3P(os, ==, sa_os);
if (sa_handle_get(os, object, NULL, SA_HDL_PRIVATE, &hdl)) {
(void) printf("Failed to get handle for SA znode\n");
return;
@ -2156,44 +2202,154 @@ dump_label_uberblocks(vdev_label_t *lbl, uint64_t ashift)
}
}
static void
static char curpath[PATH_MAX];
/*
* Iterate through the path components, recursively passing
* current one's obj and remaining path until we find the obj
* for the last one.
*/
static int
dump_path_impl(objset_t *os, uint64_t obj, char *name)
{
int err;
int header = 1;
uint64_t child_obj;
char *s;
dmu_buf_t *db;
dmu_object_info_t doi;
if ((s = strchr(name, '/')) != NULL)
*s = '\0';
err = zap_lookup(os, obj, name, 8, 1, &child_obj);
(void) strlcat(curpath, name, sizeof (curpath));
if (err != 0) {
(void) fprintf(stderr, "failed to lookup %s: %s\n",
curpath, strerror(err));
return (err);
}
child_obj = ZFS_DIRENT_OBJ(child_obj);
err = sa_buf_hold(os, child_obj, FTAG, &db);
if (err != 0) {
(void) fprintf(stderr,
"failed to get SA dbuf for obj %llu: %s\n",
(u_longlong_t)child_obj, strerror(err));
return (EINVAL);
}
dmu_object_info_from_db(db, &doi);
sa_buf_rele(db, FTAG);
if (doi.doi_bonus_type != DMU_OT_SA &&
doi.doi_bonus_type != DMU_OT_ZNODE) {
(void) fprintf(stderr, "invalid bonus type %d for obj %llu\n",
doi.doi_bonus_type, (u_longlong_t)child_obj);
return (EINVAL);
}
if (dump_opt['v'] > 6) {
(void) printf("obj=%llu %s type=%d bonustype=%d\n",
(u_longlong_t)child_obj, curpath, doi.doi_type,
doi.doi_bonus_type);
}
(void) strlcat(curpath, "/", sizeof (curpath));
switch (doi.doi_type) {
case DMU_OT_DIRECTORY_CONTENTS:
if (s != NULL && *(s + 1) != '\0')
return (dump_path_impl(os, child_obj, s + 1));
/*FALLTHROUGH*/
case DMU_OT_PLAIN_FILE_CONTENTS:
dump_object(os, child_obj, dump_opt['v'], &header);
return (0);
default:
(void) fprintf(stderr, "object %llu has non-file/directory "
"type %d\n", (u_longlong_t)obj, doi.doi_type);
break;
}
return (EINVAL);
}
/*
* Dump the blocks for the object specified by path inside the dataset.
*/
static int
dump_path(char *ds, char *path)
{
int err;
objset_t *os;
uint64_t root_obj;
err = open_objset(ds, DMU_OST_ZFS, FTAG, &os);
if (err != 0)
return (err);
err = zap_lookup(os, MASTER_NODE_OBJ, ZFS_ROOT_OBJ, 8, 1, &root_obj);
if (err != 0) {
(void) fprintf(stderr, "can't lookup root znode: %s\n",
strerror(err));
dmu_objset_disown(os, FTAG);
return (EINVAL);
}
(void) snprintf(curpath, sizeof (curpath), "dataset=%s path=/", ds);
err = dump_path_impl(os, root_obj, path);
close_objset(os, FTAG);
return (err);
}
static int
dump_label(const char *dev)
{
int fd;
vdev_label_t label;
char *path, *buf = label.vl_vdev_phys.vp_nvlist;
char path[MAXPATHLEN];
char *buf = label.vl_vdev_phys.vp_nvlist;
size_t buflen = sizeof (label.vl_vdev_phys.vp_nvlist);
struct stat64 statbuf;
uint64_t psize, ashift;
int len = strlen(dev) + 1;
boolean_t label_found = B_FALSE;
if (strncmp(dev, ZFS_DISK_ROOTD, strlen(ZFS_DISK_ROOTD)) == 0) {
len++;
path = malloc(len);
(void) snprintf(path, len, "%s%s", ZFS_RDISK_ROOTD,
dev + strlen(ZFS_DISK_ROOTD));
} else {
path = strdup(dev);
(void) strlcpy(path, dev, sizeof (path));
if (dev[0] == '/') {
if (strncmp(dev, ZFS_DISK_ROOTD,
strlen(ZFS_DISK_ROOTD)) == 0) {
(void) snprintf(path, sizeof (path), "%s%s",
ZFS_RDISK_ROOTD, dev + strlen(ZFS_DISK_ROOTD));
}
} else if (stat64(path, &statbuf) != 0) {
char *s;
(void) snprintf(path, sizeof (path), "%s%s", ZFS_RDISK_ROOTD,
dev);
if (((s = strrchr(dev, 's')) == NULL &&
(s = strchr(dev, 'p')) == NULL) ||
!isdigit(*(s + 1)))
(void) strlcat(path, "s0", sizeof (path));
}
if ((fd = open64(path, O_RDONLY)) < 0) {
(void) printf("cannot open '%s': %s\n", path, strerror(errno));
free(path);
(void) fprintf(stderr, "cannot open '%s': %s\n", path,
strerror(errno));
exit(1);
}
if (fstat64(fd, &statbuf) != 0) {
(void) printf("failed to stat '%s': %s\n", path,
(void) fprintf(stderr, "failed to stat '%s': %s\n", path,
strerror(errno));
free(path);
(void) close(fd);
exit(1);
}
if (S_ISBLK(statbuf.st_mode)) {
(void) printf("cannot use '%s': character device required\n",
path);
free(path);
(void) fprintf(stderr,
"cannot use '%s': character device required\n", path);
(void) close(fd);
exit(1);
}
@ -2204,36 +2360,43 @@ dump_label(const char *dev)
for (int l = 0; l < VDEV_LABELS; l++) {
nvlist_t *config = NULL;
(void) printf("--------------------------------------------\n");
(void) printf("LABEL %d\n", l);
(void) printf("--------------------------------------------\n");
if (!dump_opt['q']) {
(void) printf("------------------------------------\n");
(void) printf("LABEL %d\n", l);
(void) printf("------------------------------------\n");
}
if (pread64(fd, &label, sizeof (label),
vdev_label_offset(psize, l, 0)) != sizeof (label)) {
(void) printf("failed to read label %d\n", l);
if (!dump_opt['q'])
(void) printf("failed to read label %d\n", l);
continue;
}
if (nvlist_unpack(buf, buflen, &config, 0) != 0) {
(void) printf("failed to unpack label %d\n", l);
if (!dump_opt['q'])
(void) printf("failed to unpack label %d\n", l);
ashift = SPA_MINBLOCKSHIFT;
} else {
nvlist_t *vdev_tree = NULL;
dump_nvlist(config, 4);
if (!dump_opt['q'])
dump_nvlist(config, 4);
if ((nvlist_lookup_nvlist(config,
ZPOOL_CONFIG_VDEV_TREE, &vdev_tree) != 0) ||
(nvlist_lookup_uint64(vdev_tree,
ZPOOL_CONFIG_ASHIFT, &ashift) != 0))
ashift = SPA_MINBLOCKSHIFT;
nvlist_free(config);
label_found = B_TRUE;
}
if (dump_opt['u'])
dump_label_uberblocks(&label, ashift);
}
free(path);
(void) close(fd);
return (label_found ? 0 : 2);
}
static uint64_t dataset_feature_count[SPA_FEATURES];
@ -2245,11 +2408,9 @@ dump_one_dir(const char *dsname, void *arg)
int error;
objset_t *os;
error = dmu_objset_own(dsname, DMU_OST_ANY, B_TRUE, FTAG, &os);
if (error) {
(void) printf("Could not open %s, error %d\n", dsname, error);
error = open_objset(dsname, DMU_OST_ANY, FTAG, &os);
if (error != 0)
return (0);
}
for (spa_feature_t f = 0; f < SPA_FEATURES; f++) {
if (!dmu_objset_ds(os)->ds_feature_inuse[f])
@ -2260,9 +2421,8 @@ dump_one_dir(const char *dsname, void *arg)
}
dump_dir(os);
dmu_objset_disown(os, FTAG);
close_objset(os, FTAG);
fuid_table_destroy();
sa_loaded = B_FALSE;
return (0);
}
@ -3497,6 +3657,33 @@ zdb_read_block(char *thing, spa_t *spa)
free(dup);
}
static void
zdb_embedded_block(char *thing)
{
blkptr_t bp = { 0 };
unsigned long long *words = (void *)&bp;
char buf[SPA_MAXBLOCKSIZE];
int err;
err = sscanf(thing, "%llx:%llx:%llx:%llx:%llx:%llx:%llx:%llx:"
"%llx:%llx:%llx:%llx:%llx:%llx:%llx:%llx",
words + 0, words + 1, words + 2, words + 3,
words + 4, words + 5, words + 6, words + 7,
words + 8, words + 9, words + 10, words + 11,
words + 12, words + 13, words + 14, words + 15);
if (err != 16) {
(void) printf("invalid input format\n");
exit(1);
}
ASSERT3U(BPE_GET_LSIZE(&bp), <=, SPA_MAXBLOCKSIZE);
err = decode_embedded_bp(&bp, buf, BPE_GET_LSIZE(&bp));
if (err != 0) {
(void) printf("decode failed: %u\n", err);
exit(1);
}
zdb_dump_block_raw(buf, BPE_GET_LSIZE(&bp), 0);
}
static boolean_t
pool_match(nvlist_t *cfg, char *tgt)
{
@ -3595,6 +3782,7 @@ main(int argc, char **argv)
char *target;
nvlist_t *policy = NULL;
uint64_t max_txg = UINT64_MAX;
int flags = ZFS_IMPORT_MISSING_LOG;
int rewind = ZPOOL_NEVER_REWIND;
char *spa_config_path_env;
boolean_t target_is_spa = B_TRUE;
@ -3614,34 +3802,38 @@ main(int argc, char **argv)
spa_config_path = spa_config_path_env;
while ((c = getopt(argc, argv,
"bcdhilmMI:suCDRSAFLXx:evp:t:U:PG")) != -1) {
"AbcCdDeEFGhiI:lLmMo:Op:PqRsSt:uU:vVx:X")) != -1) {
switch (c) {
case 'b':
case 'c':
case 'C':
case 'd':
case 'D':
case 'E':
case 'G':
case 'h':
case 'i':
case 'l':
case 'm':
case 's':
case 'u':
case 'C':
case 'D':
case 'M':
case 'O':
case 'R':
case 's':
case 'S':
case 'G':
case 'u':
dump_opt[c]++;
dump_all = 0;
break;
case 'A':
case 'e':
case 'F':
case 'L':
case 'X':
case 'e':
case 'P':
case 'q':
case 'X':
dump_opt[c]++;
break;
/* NB: Sort single match options below. */
case 'I':
max_inflight = strtoull(optarg, NULL, 0);
if (max_inflight == 0) {
@ -3651,6 +3843,11 @@ main(int argc, char **argv)
usage();
}
break;
case 'o':
error = set_global_var(optarg);
if (error != 0)
usage();
break;
case 'p':
if (searchdirs == NULL) {
searchdirs = umem_alloc(sizeof (char *),
@ -3676,10 +3873,19 @@ main(int argc, char **argv)
break;
case 'U':
spa_config_path = optarg;
if (spa_config_path[0] != '/') {
(void) fprintf(stderr,
"cachefile must be an absolute path "
"(i.e. start with a slash)\n");
usage();
}
break;
case 'v':
verbose++;
break;
case 'V':
flags = ZFS_IMPORT_VERBATIM;
break;
case 'x':
vn_dumpdir = optarg;
break;
@ -3721,7 +3927,7 @@ main(int argc, char **argv)
verbose = MAX(verbose, 1);
for (c = 0; c < 256; c++) {
if (dump_all && !strchr("elAFLRSXP", c))
if (dump_all && strchr("AeEFlLOPRSX", c) == NULL)
dump_opt[c] = 1;
if (dump_opt[c])
dump_opt[c] += verbose;
@ -3735,6 +3941,14 @@ main(int argc, char **argv)
if (argc < 2 && dump_opt['R'])
usage();
if (dump_opt['E']) {
if (argc != 1)
usage();
zdb_embedded_block(argv[0]);
return (0);
}
if (argc < 1) {
if (!dump_opt['e'] && dump_opt['C']) {
dump_cachefile(spa_config_path);
@ -3743,9 +3957,14 @@ main(int argc, char **argv)
usage();
}
if (dump_opt['l']) {
dump_label(argv[0]);
return (0);
if (dump_opt['l'])
return (dump_label(argv[0]));
if (dump_opt['O']) {
if (argc != 2)
usage();
dump_opt['v'] = verbose + 3;
return (dump_path(argv[0], argv[1]));
}
if (dump_opt['X'] || dump_opt['F'])
@ -3775,11 +3994,7 @@ main(int argc, char **argv)
fatal("can't open '%s': %s",
target, strerror(ENOMEM));
}
if ((error = spa_import(name, cfg, NULL,
ZFS_IMPORT_MISSING_LOG)) != 0) {
error = spa_import(name, cfg, NULL,
ZFS_IMPORT_VERBATIM);
}
error = spa_import(name, cfg, NULL, flags);
}
}
@ -3822,8 +4037,7 @@ main(int argc, char **argv)
}
}
} else {
error = dmu_objset_own(target, DMU_OST_ANY,
B_TRUE, FTAG, &os);
error = open_objset(target, DMU_OST_ANY, FTAG, &os);
}
}
nvlist_free(policy);
@ -3866,10 +4080,12 @@ main(int argc, char **argv)
zdb_read_block(argv[i], spa);
}
(os != NULL) ? dmu_objset_disown(os, FTAG) : spa_close(spa, FTAG);
if (os != NULL)
close_objset(os, FTAG);
else
spa_close(spa, FTAG);
fuid_table_destroy();
sa_loaded = B_FALSE;
dump_debug_buffer();

View File

@ -0,0 +1,536 @@
.\" This file and its contents are supplied under the terms of the
.\" Common Development and Distribution License ("CDDL"), version 1.0.
.\" You may only use this file in accordance with the terms of version
.\" 1.0 of the CDDL.
.\"
.\" A full copy of the text of the CDDL should have accompanied this
.\" source. A copy of the CDDL is also available via the Internet at
.\" http://www.illumos.org/license/CDDL.
.\"
.\"
.\" Copyright (c) 2016, 2017 by Delphix. All rights reserved.
.\"
.Dd October 02, 2017
.Dt ZFS-PROGRAM 1M
.Os
.Sh NAME
.Nm zfs program
.Nd executes ZFS channel programs
.Sh SYNOPSIS
.Cm zfs program
.Op Fl t Ar instruction-limit
.Op Fl m Ar memory-limit
.Ar pool
.Ar script
.\".Op Ar optional arguments to channel program
.Sh DESCRIPTION
The ZFS channel program interface allows ZFS administrative operations to be
run programmatically as a Lua script.
The entire script is executed atomically, with no other administrative
operations taking effect concurrently.
A library of ZFS calls is made available to channel program scripts.
Channel programs may only be run with root privileges.
.Pp
A modified version of the Lua 5.2 interpreter is used to run channel program
scripts.
The Lua 5.2 manual can be found at:
.Bd -centered -offset indent
.Lk http://www.lua.org/manual/5.2/
.Ed
.Pp
The channel program given by
.Ar script
will be run on
.Ar pool ,
and any attempts to access or modify other pools will cause an error.
.Sh OPTIONS
.Bl -tag -width "-t"
.It Fl t Ar instruction-limit
Execution time limit, in number of Lua instructions to execute.
If a channel program executes more than the specified number of instructions,
it will be stopped and an error will be returned.
The default limit is 10 million instructions, and it can be set to a maximum of
100 million instructions.
.It Fl m Ar memory-limit
Memory limit, in bytes.
If a channel program attempts to allocate more memory than the given limit, it
will be stopped and an error returned.
The default memory limit is 10 MB, and can be set to a maximum of 100 MB.
.El
.Pp
All remaining argument strings will be passed directly to the Lua script as
described in the
.Sx LUA INTERFACE
section below.
.Sh LUA INTERFACE
A channel program can be invoked either from the command line, or via a library
call to
.Fn lzc_channel_program .
.Ss Arguments
Arguments passed to the channel program are converted to a Lua table.
If invoked from the command line, extra arguments to the Lua script will be
accessible as an array stored in the argument table with the key 'argv':
.Bd -literal -offset indent
args = ...
argv = args["argv"]
-- argv == {1="arg1", 2="arg2", ...}
.Ed
.Pp
If invoked from the libZFS interface, an arbitrary argument list can be
passed to the channel program, which is accessible via the same
"..." syntax in Lua:
.Bd -literal -offset indent
args = ...
-- args == {"foo"="bar", "baz"={...}, ...}
.Ed
.Pp
Note that because Lua arrays are 1-indexed, arrays passed to Lua from the
libZFS interface will have their indices incremented by 1.
That is, the element
in
.Va arr[0]
in a C array passed to a channel program will be stored in
.Va arr[1]
when accessed from Lua.
.Ss Return Values
Lua return statements take the form:
.Bd -literal -offset indent
return ret0, ret1, ret2, ...
.Ed
.Pp
Return statements returning multiple values are permitted internally in a
channel program script, but attempting to return more than one value from the
top level of the channel program is not permitted and will throw an error.
However, tables containing multiple values can still be returned.
If invoked from the command line, a return statement:
.Bd -literal -offset indent
a = {foo="bar", baz=2}
return a
.Ed
.Pp
Will be output formatted as:
.Bd -literal -offset indent
Channel program fully executed with return value:
return:
baz: 2
foo: 'bar'
.Ed
.Ss Fatal Errors
If the channel program encounters a fatal error while running, a non-zero exit
status will be returned.
If more information about the error is available, a singleton list will be
returned detailing the error:
.Bd -literal -offset indent
error: "error string, including Lua stack trace"
.Ed
.Pp
If a fatal error is returned, the channel program may have not executed at all,
may have partially executed, or may have fully executed but failed to pass a
return value back to userland.
.Pp
If the channel program exhausts an instruction or memory limit, a fatal error
will be generated and the program will be stopped, leaving the program partially
executed.
No attempt is made to reverse or undo any operations already performed.
Note that because both the instruction count and amount of memory used by a
channel program are deterministic when run against the same inputs and
filesystem state, as long as a channel program has run successfully once, you
can guarantee that it will finish successfully against a similar size system.
.Pp
If a channel program attempts to return too large a value, the program will
fully execute but exit with a nonzero status code and no return value.
.Pp
.Em Note:
ZFS API functions do not generate Fatal Errors when correctly invoked, they
return an error code and the channel program continues executing.
See the
.Sx ZFS API
section below for function-specific details on error return codes.
.Ss Lua to C Value Conversion
When invoking a channel program via the libZFS interface, it is necessary to
translate arguments and return values from Lua values to their C equivalents,
and vice-versa.
.Pp
There is a correspondence between nvlist values in C and Lua tables.
A Lua table which is returned from the channel program will be recursively
converted to an nvlist, with table values converted to their natural
equivalents:
.Bd -literal -offset indent
string -> string
number -> int64
boolean -> boolean_value
nil -> boolean (no value)
table -> nvlist
.Ed
.Pp
Likewise, table keys are replaced by string equivalents as follows:
.Bd -literal -offset indent
string -> no change
number -> signed decimal string ("%lld")
boolean -> "true" | "false"
.Ed
.Pp
Any collision of table key strings (for example, the string "true" and a
true boolean value) will cause a fatal error.
.Pp
Lua numbers are represented internally as signed 64-bit integers.
.Sh LUA STANDARD LIBRARY
The following Lua built-in base library functions are available:
.Bd -literal -offset indent
assert rawlen
collectgarbage rawget
error rawset
getmetatable select
ipairs setmetatable
next tonumber
pairs tostring
rawequal type
.Ed
.Pp
All functions in the
.Em coroutine ,
.Em string ,
and
.Em table
built-in submodules are also available.
A complete list and documentation of these modules is available in the Lua
manual.
.Pp
The following functions base library functions have been disabled and are
not available for use in channel programs:
.Bd -literal -offset indent
dofile
loadfile
load
pcall
print
xpcall
.Ed
.Sh ZFS API
.Ss Function Arguments
Each API function takes a fixed set of required positional arguments and
optional keyword arguments.
For example, the destroy function takes a single positional string argument
(the name of the dataset to destroy) and an optional "defer" keyword boolean
argument.
When using parentheses to specify the arguments to a Lua function, only
positional arguments can be used:
.Bd -literal -offset indent
zfs.sync.destroy("rpool@snap")
.Ed
.Pp
To use keyword arguments, functions must be called with a single argument that
is a Lua table containing entries mapping integers to positional arguments and
strings to keyword arguments:
.Bd -literal -offset indent
zfs.sync.destroy({1="rpool@snap", defer=true})
.Ed
.Pp
The Lua language allows curly braces to be used in place of parenthesis as
syntactic sugar for this calling convention:
.Bd -literal -offset indent
zfs.sync.snapshot{"rpool@snap", defer=true}
.Ed
.Ss Function Return Values
If an API function succeeds, it returns 0.
If it fails, it returns an error code and the channel program continues
executing.
API functions do not generate Fatal Errors except in the case of an
unrecoverable internal file system error.
.Pp
In addition to returning an error code, some functions also return extra
details describing what caused the error.
This extra description is given as a second return value, and will always be a
Lua table, or Nil if no error details were returned.
Different keys will exist in the error details table depending on the function
and error case.
Any such function may be called expecting a single return value:
.Bd -literal -offset indent
errno = zfs.sync.promote(dataset)
.Ed
.Pp
Or, the error details can be retrieved:
.Bd -literal -offset indent
errno, details = zfs.sync.promote(dataset)
if (errno == EEXIST) then
assert(details ~= Nil)
list_of_conflicting_snapshots = details
end
.Ed
.Pp
The following global aliases for API function error return codes are defined
for use in channel programs:
.Bd -literal -offset indent
EPERM ECHILD ENODEV ENOSPC
ENOENT EAGAIN ENOTDIR ESPIPE
ESRCH ENOMEM EISDIR EROFS
EINTR EACCES EINVAL EMLINK
EIO EFAULT ENFILE EPIPE
ENXIO ENOTBLK EMFILE EDOM
E2BIG EBUSY ENOTTY ERANGE
ENOEXEC EEXIST ETXTBSY EDQUOT
EBADF EXDEV EFBIG
.Ed
.Ss API Functions
For detailed descriptions of the exact behavior of any zfs administrative
operations, see the main
.Xr zfs 1
manual page.
.Bl -tag -width "xx"
.It Em zfs.debug(msg)
Record a debug message in the zfs_dbgmsg log.
A log of these messages can be printed via mdb's "::zfs_dbgmsg" command, or
can be monitored live by running:
.Bd -literal -offset indent
dtrace -n 'zfs-dbgmsg{trace(stringof(arg0))}'
.Ed
.Pp
msg (string)
.Bd -ragged -compact -offset "xxxx"
Debug message to be printed.
.Ed
.It Em zfs.exists(dataset)
Returns true if the given dataset exists, or false if it doesn't.
A fatal error will be thrown if the dataset is not in the target pool.
That is, in a channel program running on rpool,
zfs.exists("rpool/nonexistent_fs") returns false, but
zfs.exists("somepool/fs_that_may_exist") will error.
.Pp
dataset (string)
.Bd -ragged -compact -offset "xxxx"
Dataset to check for existence.
Must be in the target pool.
.Ed
.It Em zfs.get_prop(dataset, property)
Returns two values.
First, a string, number or table containing the property value for the given
dataset.
Second, a string containing the source of the property (i.e. the name of the
dataset in which it was set or nil if it is readonly).
Throws a Lua error if the dataset is invalid or the property doesn't exist.
Note that Lua only supports int64 number types whereas ZFS number properties
are uint64.
This means very large values (like guid) may wrap around and appear negative.
.Pp
dataset (string)
.Bd -ragged -compact -offset "xxxx"
Filesystem or snapshot path to retrieve properties from.
.Ed
.Pp
property (string)
.Bd -ragged -compact -offset "xxxx"
Name of property to retrieve.
All filesystem, snapshot and volume properties are supported except
for 'mounted' and 'iscsioptions.'
Also supports the 'written@snap' and 'written#bookmark' properties and
the '<user|group><quota|used>@id' properties, though the id must be in numeric
form.
.Ed
.El
.Bl -tag -width "xx"
.It Sy zfs.sync submodule
The sync submodule contains functions that modify the on-disk state.
They are executed in "syncing context".
.Pp
The available sync submodule functions are as follows:
.Bl -tag -width "xx"
.It Em zfs.sync.destroy(dataset, [defer=true|false])
Destroy the given dataset.
Returns 0 on successful destroy, or a nonzero error code if the dataset could
not be destroyed (for example, if the dataset has any active children or
clones).
.Pp
dataset (string)
.Bd -ragged -compact -offset "xxxx"
Filesystem or snapshot to be destroyed.
.Ed
.Pp
[optional] defer (boolean)
.Bd -ragged -compact -offset "xxxx"
Valid only for destroying snapshots.
If set to true, and the snapshot has holds or clones, allows the snapshot to be
marked for deferred deletion rather than failing.
.Ed
.It Em zfs.sync.promote(dataset)
Promote the given clone to a filesystem.
Returns 0 on successful promotion, or a nonzero error code otherwise.
If EEXIST is returned, the second return value will be an array of the clone's
snapshots whose names collide with snapshots of the parent filesystem.
.Pp
dataset (string)
.Bd -ragged -compact -offset "xxxx"
Clone to be promoted.
.Ed
.It Em zfs.sync.rollback(filesystem)
Rollback to the previous snapshot for a dataset.
Returns 0 on successful rollback, or a nonzero error code otherwise.
Rollbacks can be performed on filesystems or zvols, but not on snapshots
or mounted datasets.
EBUSY is returned in the case where the filesystem is mounted.
.Pp
filesystem (string)
.Bd -ragged -compact -offset "xxxx"
Filesystem to rollback.
.Ed
.It Em zfs.sync.snapshot(dataset)
Create a snapshot of a filesystem.
Returns 0 if the snapshot was successfully created,
and a nonzero error code otherwise.
.Pp
Note: Taking a snapshot will fail on any pool older than legacy version 27.
To enable taking snapshots from ZCP scripts, the pool must be upgraded.
.Pp
dataset (string)
.Bd -ragged -compact -offset "xxxx"
Name of snapshot to create.
.Ed
.El
.It Sy zfs.check submodule
For each function in the zfs.sync submodule, there is a corresponding zfs.check
function which performs a "dry run" of the same operation.
Each takes the same arguments as its zfs.sync counterpart and returns 0 if the
operation would succeed, or a non-zero error code if it would fail, along with
any other error details.
That is, each has the same behavior as the corresponding sync function except
for actually executing the requested change.
For example,
.Em zfs.check.destroy("fs")
returns 0 if
.Em zfs.sync.destroy("fs")
would successfully destroy the dataset.
.Pp
The available zfs.check functions are:
.Bl -tag -width "xx"
.It Em zfs.check.destroy(dataset, [defer=true|false])
.It Em zfs.check.promote(dataset)
.It Em zfs.check.rollback(filesystem)
.It Em zfs.check.snapshot(dataset)
.El
.It Sy zfs.list submodule
The zfs.list submodule provides functions for iterating over datasets and
properties.
Rather than returning tables, these functions act as Lua iterators, and are
generally used as follows:
.Bd -literal -offset indent
for child in zfs.list.children("rpool") do
...
end
.Ed
.Pp
The available zfs.list functions are:
.Bl -tag -width "xx"
.It Em zfs.list.clones(snapshot)
Iterate through all clones of the given snapshot.
.Pp
snapshot (string)
.Bd -ragged -compact -offset "xxxx"
Must be a valid snapshot path in the current pool.
.Ed
.It Em zfs.list.snapshots(dataset)
Iterate through all snapshots of the given dataset.
Each snapshot is returned as a string containing the full dataset name, e.g.
"pool/fs@snap".
.Pp
dataset (string)
.Bd -ragged -compact -offset "xxxx"
Must be a valid filesystem or volume.
.Ed
.It Em zfs.list.children(dataset)
Iterate through all direct children of the given dataset.
Each child is returned as a string containing the full dataset name, e.g.
"pool/fs/child".
.Pp
dataset (string)
.Bd -ragged -compact -offset "xxxx"
Must be a valid filesystem or volume.
.Ed
.It Em zfs.list.properties(dataset)
Iterate through all user properties for the given dataset.
.Pp
dataset (string)
.Bd -ragged -compact -offset "xxxx"
Must be a valid filesystem, snapshot, or volume.
.Ed
.It Em zfs.list.system_properties(dataset)
Returns an array of strings, the names of the valid system (non-user defined)
properties for the given dataset.
Throws a Lua error if the dataset is invalid.
.Pp
dataset (string)
.Bd -ragged -compact -offset "xxxx"
Must be a valid filesystem, snapshot or volume.
.Ed
.El
.El
.Sh EXAMPLES
.Ss Example 1
The following channel program recursively destroys a filesystem and all its
snapshots and children in a naive manner.
Note that this does not involve any error handling or reporting.
.Bd -literal -offset indent
function destroy_recursive(root)
for child in zfs.list.children(root) do
destroy_recursive(child)
end
for snap in zfs.list.snapshots(root) do
zfs.sync.destroy(snap)
end
zfs.sync.destroy(root)
end
destroy_recursive("pool/somefs")
.Ed
.Ss Example 2
A more verbose and robust version of the same channel program, which
properly detects and reports errors, and also takes the dataset to destroy
as a command line argument, would be as follows:
.Bd -literal -offset indent
succeeded = {}
failed = {}
function destroy_recursive(root)
for child in zfs.list.children(root) do
destroy_recursive(child)
end
for snap in zfs.list.snapshots(root) do
err = zfs.sync.destroy(snap)
if (err ~= 0) then
failed[snap] = err
else
succeeded[snap] = err
end
end
err = zfs.sync.destroy(root)
if (err ~= 0) then
failed[root] = err
else
succeeded[root] = err
end
end
args = ...
argv = args["argv"]
destroy_recursive(argv[1])
results = {}
results["succeeded"] = succeeded
results["failed"] = failed
return results
.Ed
.Ss Example 3
The following function performs a forced promote operation by attempting to
promote the given clone and destroying any conflicting snapshots.
.Bd -literal -offset indent
function force_promote(ds)
errno, details = zfs.check.promote(ds)
if (errno == EEXIST) then
assert(details ~= Nil)
for i, snap in ipairs(details) do
zfs.sync.destroy(ds .. "@" .. snap)
end
elseif (errno ~= 0) then
return errno
end
return zfs.sync.promote(ds)
end
.Ed

View File

@ -286,6 +286,12 @@
.Ar snapshot
.Op Ar snapshot Ns | Ns Ar filesystem
.Nm
.Cm program
.Op Fl t Ar timeout
.Op Fl m Ar memory_limit
.Ar pool script
.Op Ar arg1 No ...
.Nm
.Cm jail
.Ar jailid Ns | Ns Ar jailname filesystem
.Nm
@ -3287,6 +3293,48 @@ Display the path's inode change time as the first column of output.
.El
.It Xo
.Nm
.Cm program
.Op Fl t Ar timeout
.Op Fl m Ar memory_limit
.Ar pool script
.Op Ar arg1 No ...
.Xc
.Pp
Executes
.Ar script
as a ZFS channel program on
.Ar pool .
The ZFS channel
program interface allows ZFS administrative operations to be run
programmatically via a Lua script.
The entire script is executed atomically, with no other administrative
operations taking effect concurrently.
A library of ZFS calls is made available to channel program scripts.
Channel programs may only be run with root privileges.
.Pp
For full documentation of the ZFS channel program interface, see the manual
page for
.Xr zfs-program 8 .
.Bl -tag -width indent
.It Fl t Ar timeout
Execution time limit, in milliseconds.
If a channel program executes for longer than the provided timeout, it will
be stopped and an error will be returned.
The default timeout is 1000 ms, and can be set to a maximum of 10000 ms.
.It Fl m Ar memory-limit
Memory limit, in bytes.
If a channel program attempts to allocate more memory than the given limit,
it will be stopped and an error returned.
The default memory limit is 10 MB, and can be set to a maximum of 100 MB.
.Pp
All remaining argument strings are passed directly to the channel program as
arguments.
See
.Xr zfs-program 8
for more information.
.El
.It Xo
.Nm
.Cm jail
.Ar jailid filesystem
.Xc

View File

@ -21,7 +21,7 @@
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2011, 2015 by Delphix. All rights reserved.
* Copyright (c) 2011, 2016 by Delphix. All rights reserved.
* Copyright 2012 Milan Jurik. All rights reserved.
* Copyright (c) 2012, Joyent, Inc. All rights reserved.
* Copyright (c) 2011-2012 Pawel Jakub Dawidek. All rights reserved.
@ -51,6 +51,7 @@
#include <grp.h>
#include <pwd.h>
#include <signal.h>
#include <sys/debug.h>
#include <sys/list.h>
#include <sys/mntent.h>
#include <sys/mnttab.h>
@ -111,6 +112,7 @@ static int zfs_do_diff(int argc, char **argv);
static int zfs_do_jail(int argc, char **argv);
static int zfs_do_unjail(int argc, char **argv);
static int zfs_do_bookmark(int argc, char **argv);
static int zfs_do_channel_program(int argc, char **argv);
/*
* Enable a reasonable set of defaults for libumem debugging on DEBUG builds.
@ -160,6 +162,7 @@ typedef enum {
HELP_RELEASE,
HELP_DIFF,
HELP_BOOKMARK,
HELP_CHANNEL_PROGRAM,
} zfs_help_t;
typedef struct zfs_command {
@ -187,6 +190,7 @@ static zfs_command_t command_table[] = {
{ "promote", zfs_do_promote, HELP_PROMOTE },
{ "rename", zfs_do_rename, HELP_RENAME },
{ "bookmark", zfs_do_bookmark, HELP_BOOKMARK },
{ "program", zfs_do_channel_program, HELP_CHANNEL_PROGRAM },
{ NULL },
{ "list", zfs_do_list, HELP_LIST },
{ NULL },
@ -340,6 +344,10 @@ get_usage(zfs_help_t idx)
"[snapshot|filesystem]\n"));
case HELP_BOOKMARK:
return (gettext("\tbookmark <snapshot> <bookmark>\n"));
case HELP_CHANNEL_PROGRAM:
return (gettext("\tprogram [-t <instruction limit>] "
"[-m <memory limit (b)>] <pool> <program file> "
"[lua args...]\n"));
}
abort();
@ -368,6 +376,18 @@ safe_malloc(size_t size)
return (data);
}
void *
safe_realloc(void *data, size_t size)
{
void *newp;
if ((newp = realloc(data, size)) == NULL) {
free(data);
nomem();
}
return (newp);
}
static char *
safe_strdup(char *str)
{
@ -7101,6 +7121,194 @@ zfs_do_bookmark(int argc, char **argv)
return (-1);
}
static int
zfs_do_channel_program(int argc, char **argv)
{
int ret, fd;
char c;
char *progbuf, *filename, *poolname;
size_t progsize, progread;
nvlist_t *outnvl;
uint64_t instrlimit = ZCP_DEFAULT_INSTRLIMIT;
uint64_t memlimit = ZCP_DEFAULT_MEMLIMIT;
zpool_handle_t *zhp;
/* check options */
while (-1 !=
(c = getopt(argc, argv, "t:(instr-limit)m:(memory-limit)"))) {
switch (c) {
case 't':
case 'm': {
uint64_t arg;
char *endp;
errno = 0;
arg = strtoull(optarg, &endp, 0);
if (errno != 0 || *endp != '\0') {
(void) fprintf(stderr, gettext(
"invalid argument "
"'%s': expected integer\n"), optarg);
goto usage;
}
if (c == 't') {
if (arg > ZCP_MAX_INSTRLIMIT || arg == 0) {
(void) fprintf(stderr, gettext(
"Invalid instruction limit: "
"%s\n"), optarg);
return (1);
} else {
instrlimit = arg;
}
} else {
ASSERT3U(c, ==, 'm');
if (arg > ZCP_MAX_MEMLIMIT || arg == 0) {
(void) fprintf(stderr, gettext(
"Invalid memory limit: "
"%s\n"), optarg);
return (1);
} else {
memlimit = arg;
}
}
break;
}
case '?':
(void) fprintf(stderr, gettext("invalid option '%c'\n"),
optopt);
goto usage;
}
}
argc -= optind;
argv += optind;
if (argc < 2) {
(void) fprintf(stderr,
gettext("invalid number of arguments\n"));
goto usage;
}
poolname = argv[0];
filename = argv[1];
if (strcmp(filename, "-") == 0) {
fd = 0;
filename = "standard input";
} else if ((fd = open(filename, O_RDONLY)) < 0) {
(void) fprintf(stderr, gettext("cannot open '%s': %s\n"),
filename, strerror(errno));
return (1);
}
if ((zhp = zpool_open(g_zfs, poolname)) == NULL) {
(void) fprintf(stderr, gettext("cannot open pool '%s'"),
poolname);
return (1);
}
zpool_close(zhp);
/*
* Read in the channel program, expanding the program buffer as
* necessary.
*/
progread = 0;
progsize = 1024;
progbuf = safe_malloc(progsize);
do {
ret = read(fd, progbuf + progread, progsize - progread);
progread += ret;
if (progread == progsize && ret > 0) {
progsize *= 2;
progbuf = safe_realloc(progbuf, progsize);
}
} while (ret > 0);
if (fd != 0)
(void) close(fd);
if (ret < 0) {
free(progbuf);
(void) fprintf(stderr,
gettext("cannot read '%s': %s\n"),
filename, strerror(errno));
return (1);
}
progbuf[progread] = '\0';
/*
* Any remaining arguments are passed as arguments to the lua script as
* a string array:
* {
* "argv" -> [ "arg 1", ... "arg n" ],
* }
*/
nvlist_t *argnvl = fnvlist_alloc();
fnvlist_add_string_array(argnvl, ZCP_ARG_CLIARGV, argv + 2, argc - 2);
ret = lzc_channel_program(poolname, progbuf, instrlimit, memlimit,
argnvl, &outnvl);
if (ret != 0) {
/*
* On error, report the error message handed back by lua if one
* exists. Otherwise, generate an appropriate error message,
* falling back on strerror() for an unexpected return code.
*/
char *errstring = NULL;
if (nvlist_exists(outnvl, ZCP_RET_ERROR)) {
(void) nvlist_lookup_string(outnvl,
ZCP_RET_ERROR, &errstring);
if (errstring == NULL)
errstring = strerror(ret);
} else {
switch (ret) {
case EINVAL:
errstring =
"Invalid instruction or memory limit.";
break;
case ENOMEM:
errstring = "Return value too large.";
break;
case ENOSPC:
errstring = "Memory limit exhausted.";
break;
#ifdef illumos
case ETIME:
#else
case ETIMEDOUT:
#endif
errstring = "Timed out.";
break;
case EPERM:
errstring = "Permission denied. Channel "
"programs must be run as root.";
break;
default:
errstring = strerror(ret);
}
}
(void) fprintf(stderr,
gettext("Channel program execution failed:\n%s\n"),
errstring);
} else {
(void) printf("Channel program fully executed ");
if (nvlist_empty(outnvl)) {
(void) printf("with no return value.\n");
} else {
(void) printf("with return value:\n");
dump_nvlist(outnvl, 4);
}
}
free(progbuf);
fnvlist_free(outnvl);
fnvlist_free(argnvl);
return (ret != 0);
usage:
usage(B_FALSE);
return (-1);
}
int
main(int argc, char **argv)
{

View File

@ -21,7 +21,7 @@
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2011, 2015 by Delphix. All rights reserved.
* Copyright (c) 2011, 2016 by Delphix. All rights reserved.
* Copyright (c) 2012 by Frederik Wessels. All rights reserved.
* Copyright (c) 2012 Martin Matuska <mm@FreeBSD.org>. All rights reserved.
* Copyright (c) 2013 by Prasad Joshi (sTec). All rights reserved.
@ -5254,6 +5254,11 @@ get_history_one(zpool_handle_t *zhp, void *data)
dump_nvlist(fnvlist_lookup_nvlist(rec,
ZPOOL_HIST_OUTPUT_NVL), 8);
}
if (nvlist_exists(rec, ZPOOL_HIST_ERRNO)) {
(void) printf(" errno: %lld\n",
fnvlist_lookup_int64(rec,
ZPOOL_HIST_ERRNO));
}
} else {
if (!cb->internal)
continue;

View File

@ -583,6 +583,8 @@ usage(boolean_t requested)
"\t[-F freezeloops (default: %llu)] max loops in spa_freeze()\n"
"\t[-P passtime (default: %llu sec)] time per pass\n"
"\t[-B alt_ztest (default: <none>)] alternate ztest path\n"
"\t[-o variable=value] ... set global variable to an unsigned\n"
"\t 32-bit integer value\n"
"\t[-h] (print help)\n"
"",
zo->zo_pool,
@ -618,7 +620,7 @@ process_options(int argc, char **argv)
bcopy(&ztest_opts_defaults, zo, sizeof (*zo));
while ((opt = getopt(argc, argv,
"v:s:a:m:r:R:d:t:g:i:k:p:f:VET:P:hF:B:")) != EOF) {
"v:s:a:m:r:R:d:t:g:i:k:p:f:VET:P:hF:B:o:")) != EOF) {
value = 0;
switch (opt) {
case 'v':
@ -705,6 +707,10 @@ process_options(int argc, char **argv)
case 'B':
(void) strlcpy(altdir, optarg, sizeof (altdir));
break;
case 'o':
if (set_global_var(optarg) != 0)
usage(B_FALSE);
break;
case 'h':
usage(B_TRUE);
break;

View File

@ -434,7 +434,7 @@ dt_dis(const dtrace_difo_t *dp, FILE *fp)
ulong_t i = 0;
char type[DT_TYPE_NAMELEN];
(void) fprintf(fp, "\nDIFO 0x%p returns %s\n", (void *)dp,
(void) fprintf(fp, "\nDIFO %p returns %s\n", (void *)dp,
dt_dis_typestr(&dp->dtdo_rtype, type, sizeof (type)));
(void) fprintf(fp, "%-3s %-8s %s\n",

View File

@ -377,7 +377,7 @@ dt_print_array(ctf_id_t base, ulong_t off, dt_printarg_t *pap)
ctf_id_t rtype;
if (ctf_array_info(ctfp, base, &car) == CTF_ERR) {
(void) fprintf(fp, "0x%p", (void *)addr);
(void) fprintf(fp, "%p", (void *)addr);
return;
}

View File

@ -22,7 +22,7 @@
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2013, Joyent, Inc. All rights reserved.
* Copyright (c) 2011, 2015 by Delphix. All rights reserved.
* Copyright (c) 2011, 2016 by Delphix. All rights reserved.
* Copyright (c) 2012 DEY Storage Systems, Inc. All rights reserved.
* Copyright (c) 2011-2012 Pawel Jakub Dawidek. All rights reserved.
* Copyright (c) 2013 Martin Matuska. All rights reserved.
@ -2166,6 +2166,7 @@ get_numeric_property(zfs_handle_t *zhp, zfs_prop_t prop, zprop_source_t *src,
if (zfs_prop_readonly(prop) &&
*source != NULL && (*source)[0] == '\0') {
*source = NULL;
return (-1);
}
break;
@ -2354,6 +2355,74 @@ zfs_get_clones_nvl(zfs_handle_t *zhp)
return (value);
}
/*
* Accepts a property and value and checks that the value
* matches the one found by the channel program. If they are
* not equal, print both of them.
*/
void
zcp_check(zfs_handle_t *zhp, zfs_prop_t prop, uint64_t intval,
const char *strval)
{
if (!zhp->zfs_hdl->libzfs_prop_debug)
return;
int error;
char *poolname = zhp->zpool_hdl->zpool_name;
const char *program =
"args = ...\n"
"ds = args['dataset']\n"
"prop = args['property']\n"
"value, setpoint = zfs.get_prop(ds, prop)\n"
"return {value=value, setpoint=setpoint}\n";
nvlist_t *outnvl;
nvlist_t *retnvl;
nvlist_t *argnvl = fnvlist_alloc();
fnvlist_add_string(argnvl, "dataset", zhp->zfs_name);
fnvlist_add_string(argnvl, "property", zfs_prop_to_name(prop));
error = lzc_channel_program(poolname, program,
10 * 1000 * 1000, 10 * 1024 * 1024, argnvl, &outnvl);
if (error == 0) {
retnvl = fnvlist_lookup_nvlist(outnvl, "return");
if (zfs_prop_get_type(prop) == PROP_TYPE_NUMBER) {
int64_t ans;
error = nvlist_lookup_int64(retnvl, "value", &ans);
if (error != 0) {
(void) fprintf(stderr, "zcp check error: %u\n",
error);
return;
}
if (ans != intval) {
(void) fprintf(stderr,
"%s: zfs found %lld, but zcp found %lld\n",
zfs_prop_to_name(prop),
(longlong_t)intval, (longlong_t)ans);
}
} else {
char *str_ans;
error = nvlist_lookup_string(retnvl, "value", &str_ans);
if (error != 0) {
(void) fprintf(stderr, "zcp check error: %u\n",
error);
return;
}
if (strcmp(strval, str_ans) != 0) {
(void) fprintf(stderr,
"%s: zfs found %s, but zcp found %s\n",
zfs_prop_to_name(prop),
strval, str_ans);
}
}
} else {
(void) fprintf(stderr,
"zcp check failed, channel program error: %u\n", error);
}
nvlist_free(argnvl);
nvlist_free(outnvl);
}
/*
* Retrieve a property from the given object. If 'literal' is specified, then
* numbers are left as exact values. Otherwise, numbers are converted to a
@ -2400,6 +2469,7 @@ zfs_prop_get(zfs_handle_t *zhp, zfs_prop_t prop, char *propbuf, size_t proplen,
&t) == 0)
(void) snprintf(propbuf, proplen, "%llu", val);
}
zcp_check(zhp, prop, val, NULL);
break;
case ZFS_PROP_MOUNTPOINT:
@ -2468,7 +2538,7 @@ zfs_prop_get(zfs_handle_t *zhp, zfs_prop_t prop, char *propbuf, size_t proplen,
/* 'legacy' or 'none' */
(void) strlcpy(propbuf, str, proplen);
}
zcp_check(zhp, prop, NULL, propbuf);
break;
case ZFS_PROP_ORIGIN:
@ -2476,6 +2546,7 @@ zfs_prop_get(zfs_handle_t *zhp, zfs_prop_t prop, char *propbuf, size_t proplen,
if (str == NULL)
return (-1);
(void) strlcpy(propbuf, str, proplen);
zcp_check(zhp, prop, NULL, str);
break;
case ZFS_PROP_CLONES:
@ -2490,7 +2561,6 @@ zfs_prop_get(zfs_handle_t *zhp, zfs_prop_t prop, char *propbuf, size_t proplen,
if (get_numeric_property(zhp, prop, src, &source, &val) != 0)
return (-1);
/*
* If quota or reservation is 0, we translate this into 'none'
* (unless literal is set), and indicate that it's the default
@ -2509,6 +2579,7 @@ zfs_prop_get(zfs_handle_t *zhp, zfs_prop_t prop, char *propbuf, size_t proplen,
else
zfs_nicenum(val, propbuf, proplen);
}
zcp_check(zhp, prop, val, NULL);
break;
case ZFS_PROP_FILESYSTEM_LIMIT:
@ -2533,6 +2604,8 @@ zfs_prop_get(zfs_handle_t *zhp, zfs_prop_t prop, char *propbuf, size_t proplen,
} else {
zfs_nicenum(val, propbuf, proplen);
}
zcp_check(zhp, prop, val, NULL);
break;
case ZFS_PROP_REFRATIO:
@ -2542,6 +2615,7 @@ zfs_prop_get(zfs_handle_t *zhp, zfs_prop_t prop, char *propbuf, size_t proplen,
(void) snprintf(propbuf, proplen, "%llu.%02llux",
(u_longlong_t)(val / 100),
(u_longlong_t)(val % 100));
zcp_check(zhp, prop, val, NULL);
break;
case ZFS_PROP_TYPE:
@ -2562,6 +2636,7 @@ zfs_prop_get(zfs_handle_t *zhp, zfs_prop_t prop, char *propbuf, size_t proplen,
abort();
}
(void) snprintf(propbuf, proplen, "%s", str);
zcp_check(zhp, prop, NULL, propbuf);
break;
case ZFS_PROP_MOUNTED:
@ -2587,6 +2662,7 @@ zfs_prop_get(zfs_handle_t *zhp, zfs_prop_t prop, char *propbuf, size_t proplen,
* consumers.
*/
(void) strlcpy(propbuf, zhp->zfs_name, proplen);
zcp_check(zhp, prop, NULL, propbuf);
break;
case ZFS_PROP_MLSLABEL:
@ -2640,26 +2716,33 @@ zfs_prop_get(zfs_handle_t *zhp, zfs_prop_t prop, char *propbuf, size_t proplen,
if (get_numeric_property(zhp, prop, src, &source, &val) != 0)
return (-1);
(void) snprintf(propbuf, proplen, "%llu", (u_longlong_t)val);
zcp_check(zhp, prop, val, NULL);
break;
default:
switch (zfs_prop_get_type(prop)) {
case PROP_TYPE_NUMBER:
if (get_numeric_property(zhp, prop, src,
&source, &val) != 0)
&source, &val) != 0) {
return (-1);
if (literal)
}
if (literal) {
(void) snprintf(propbuf, proplen, "%llu",
(u_longlong_t)val);
else
} else {
zfs_nicenum(val, propbuf, proplen);
}
zcp_check(zhp, prop, val, NULL);
break;
case PROP_TYPE_STRING:
str = getprop_string(zhp, prop, &source);
if (str == NULL)
return (-1);
(void) strlcpy(propbuf, str, proplen);
zcp_check(zhp, prop, NULL, str);
break;
case PROP_TYPE_INDEX:
@ -2668,7 +2751,9 @@ zfs_prop_get(zfs_handle_t *zhp, zfs_prop_t prop, char *propbuf, size_t proplen,
return (-1);
if (zfs_prop_index_to_string(prop, val, &strval) != 0)
return (-1);
(void) strlcpy(propbuf, strval, proplen);
zcp_check(zhp, prop, NULL, strval);
break;
default:

View File

@ -55,15 +55,6 @@
#define ZDIFF_REMOVED '-'
#define ZDIFF_RENAMED 'R'
static boolean_t
do_name_cmp(const char *fpath, const char *tpath)
{
char *fname, *tname;
fname = strrchr(fpath, '/') + 1;
tname = strrchr(tpath, '/') + 1;
return (strcmp(fname, tname) == 0);
}
typedef struct differ_info {
zfs_handle_t *zhp;
char *fromsnap;
@ -262,7 +253,6 @@ static int
write_inuse_diffs_one(FILE *fp, differ_info_t *di, uint64_t dobj)
{
struct zfs_stat fsb, tsb;
boolean_t same_name;
mode_t fmode, tmode;
char fobjname[MAXPATHLEN], tobjname[MAXPATHLEN];
int fobjerr, tobjerr;
@ -323,7 +313,6 @@ write_inuse_diffs_one(FILE *fp, differ_info_t *di, uint64_t dobj)
if (fmode != tmode && fsb.zs_gen == tsb.zs_gen)
tsb.zs_gen++; /* Force a generational difference */
same_name = do_name_cmp(fobjname, tobjname);
/* Simple modification or no change */
if (fsb.zs_gen == tsb.zs_gen) {
@ -334,7 +323,7 @@ write_inuse_diffs_one(FILE *fp, differ_info_t *di, uint64_t dobj)
if (change) {
print_link_change(fp, di, change,
change > 0 ? fobjname : tobjname, &tsb);
} else if (same_name) {
} else if (strcmp(fobjname, tobjname) == 0) {
print_file(fp, di, ZDIFF_MODIFIED, fobjname, &tsb);
} else {
print_rename(fp, di, fobjname, tobjname, &tsb);

View File

@ -79,6 +79,7 @@ struct libzfs_handle {
libzfs_fru_t **libzfs_fru_hash;
libzfs_fru_t *libzfs_fru_list;
char libzfs_chassis_id[256];
boolean_t libzfs_prop_debug;
};
#define ZFSSHARE_MISS 0x01 /* Didn't find entry in cache */

View File

@ -2295,6 +2295,7 @@ vdev_get_physpaths(nvlist_t *nv, char *physpath, size_t phypath_size,
return (ret);
}
} else if (strcmp(type, VDEV_TYPE_MIRROR) == 0 ||
strcmp(type, VDEV_TYPE_RAIDZ) == 0 ||
strcmp(type, VDEV_TYPE_REPLACING) == 0 ||
(is_spare = (strcmp(type, VDEV_TYPE_SPARE) == 0))) {
nvlist_t **child;

View File

@ -3212,7 +3212,12 @@ zfs_receive_one(libzfs_handle_t *hdl, int infd, const char *tosnap,
/*
* Determine the name of the origin snapshot, store in zc_string.
*/
if (drrb->drr_flags & DRR_FLAG_CLONE) {
if (originsnap) {
(void) strncpy(zc.zc_string, originsnap, sizeof (zc.zc_string));
if (flags->verbose)
(void) printf("using provided clone origin %s\n",
zc.zc_string);
} else if (drrb->drr_flags & DRR_FLAG_CLONE) {
if (guid_to_name(hdl, zc.zc_value,
drrb->drr_fromguid, B_FALSE, zc.zc_string) != 0) {
zcmd_free_nvlists(&zc);
@ -3223,11 +3228,6 @@ zfs_receive_one(libzfs_handle_t *hdl, int infd, const char *tosnap,
}
if (flags->verbose)
(void) printf("found clone origin %s\n", zc.zc_string);
} else if (originsnap) {
(void) strncpy(zc.zc_string, originsnap, sizeof (zc.zc_string));
if (flags->verbose)
(void) printf("using provided clone origin %s\n",
zc.zc_string);
}
boolean_t resuming = DMU_GET_FEATUREFLAGS(drrb->drr_versioninfo) &

View File

@ -678,6 +678,10 @@ libzfs_init(void)
zpool_feature_init();
libzfs_mnttab_init(hdl);
if (getenv("ZFS_PROP_DEBUG") != NULL) {
hdl->libzfs_prop_debug = B_TRUE;
}
return (hdl);
}

View File

@ -20,7 +20,7 @@
*/
/*
* Copyright (c) 2012, 2014 by Delphix. All rights reserved.
* Copyright (c) 2012, 2017 by Delphix. All rights reserved.
* Copyright (c) 2013 Steven Hartland. All rights reserved.
* Copyright (c) 2014 Integros [integros.com]
* Copyright 2017 RackTop Systems.
@ -160,7 +160,12 @@ lzc_ioctl(zfs_ioc_t ioc, const char *name,
if (resultp != NULL) {
*resultp = NULL;
zc.zc_nvlist_dst_size = MAX(size * 2, 128 * 1024);
if (ioc == ZFS_IOC_CHANNEL_PROGRAM) {
zc.zc_nvlist_dst_size = fnvlist_lookup_uint64(source,
ZCP_ARG_MEMLIMIT);
} else {
zc.zc_nvlist_dst_size = MAX(size * 2, 128 * 1024);
}
zc.zc_nvlist_dst = (uint64_t)(uintptr_t)
malloc(zc.zc_nvlist_dst_size);
#ifdef illumos
@ -174,7 +179,15 @@ lzc_ioctl(zfs_ioc_t ioc, const char *name,
}
while (ioctl(g_fd, ioc, &zc) != 0) {
if (errno == ENOMEM && resultp != NULL) {
/*
* If ioctl exited with ENOMEM, we retry the ioctl after
* increasing the size of the destination nvlist.
*
* Channel programs that exit with ENOMEM ran over the
* lua memory sandbox; they should not be retried.
*/
if (errno == ENOMEM && resultp != NULL &&
ioc != ZFS_IOC_CHANNEL_PROGRAM) {
free((void *)(uintptr_t)zc.zc_nvlist_dst);
zc.zc_nvlist_dst_size *= 2;
zc.zc_nvlist_dst = (uint64_t)(uintptr_t)
@ -904,3 +917,54 @@ lzc_destroy_bookmarks(nvlist_t *bmarks, nvlist_t **errlist)
return (error);
}
/*
* Executes a channel program.
*
* If this function returns 0 the channel program was successfully loaded and
* ran without failing. Note that individual commands the channel program ran
* may have failed and the channel program is responsible for reporting such
* errors through outnvl if they are important.
*
* This method may also return:
*
* EINVAL The program contains syntax errors, or an invalid memory or time
* limit was given. No part of the channel program was executed.
* If caused by syntax errors, 'outnvl' contains information about the
* errors.
*
* EDOM The program was executed, but encountered a runtime error, such as
* calling a function with incorrect arguments, invoking the error()
* function directly, failing an assert() command, etc. Some portion
* of the channel program may have executed and committed changes.
* Information about the failure can be found in 'outnvl'.
*
* ENOMEM The program fully executed, but the output buffer was not large
* enough to store the returned value. No output is returned through
* 'outnvl'.
*
* ENOSPC The program was terminated because it exceeded its memory usage
* limit. Some portion of the channel program may have executed and
* committed changes to disk. No output is returned through 'outnvl'.
*
* ETIMEDOUT The program was terminated because it exceeded its Lua instruction
* limit. Some portion of the channel program may have executed and
* committed changes to disk. No output is returned through 'outnvl'.
*/
int
lzc_channel_program(const char *pool, const char *program, uint64_t instrlimit,
uint64_t memlimit, nvlist_t *argnvl, nvlist_t **outnvl)
{
int error;
nvlist_t *args;
args = fnvlist_alloc();
fnvlist_add_string(args, ZCP_ARG_PROGRAM, program);
fnvlist_add_nvlist(args, ZCP_ARG_ARGLIST, argnvl);
fnvlist_add_uint64(args, ZCP_ARG_INSTRLIMIT, instrlimit);
fnvlist_add_uint64(args, ZCP_ARG_MEMLIMIT, memlimit);
error = lzc_ioctl(ZFS_IOC_CHANNEL_PROGRAM, pool, args, outnvl);
fnvlist_free(args);
return (error);
}

View File

@ -20,7 +20,7 @@
*/
/*
* Copyright (c) 2012, 2014 by Delphix. All rights reserved.
* Copyright (c) 2012, 2016 by Delphix. All rights reserved.
* Copyright (c) 2013 by Martin Matuska <mm@FreeBSD.org>. All rights reserved.
* Copyright 2017 RackTop Systems.
*/
@ -86,6 +86,9 @@ boolean_t lzc_exists(const char *);
int lzc_rollback(const char *, char *, int);
int lzc_rollback_to(const char *, const char *);
int lzc_channel_program(const char *, const char *, uint64_t, uint64_t,
nvlist_t *, nvlist_t **);
#ifdef __cplusplus
}
#endif

View File

@ -738,6 +738,7 @@ vpanic(const char *fmt, va_list adx)
char buf[512];
(void) vsnprintf(buf, 512, fmt, adx);
assfail(buf, NULL, 0);
abort(); /* necessary to make vpanic meet noreturn requirements */
}
void

View File

@ -20,7 +20,7 @@
*/
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2015 by Delphix. All rights reserved.
* Copyright (c) 2012, 2016 by Delphix. All rights reserved.
* Copyright (c) 2012, Joyent, Inc. All rights reserved.
*/
/*
@ -66,6 +66,7 @@ extern "C" {
#include <fsshare.h>
#include <pthread.h>
#include <sched.h>
#include <setjmp.h>
#include <sys/debug.h>
#include <sys/note.h>
#include <sys/types.h>
@ -126,8 +127,8 @@ extern void dprintf_setup(int *argc, char **argv);
extern void cmn_err(int, const char *, ...);
extern void vcmn_err(int, const char *, __va_list);
extern void panic(const char *, ...);
extern void vpanic(const char *, __va_list);
extern void panic(const char *, ...) __NORETURN;
extern void vpanic(const char *, __va_list) __NORETURN;
#define fm_panic panic
@ -349,6 +350,7 @@ extern void cv_broadcast(kcondvar_t *cv);
#define KM_SLEEP UMEM_NOFAIL
#define KM_PUSHPAGE KM_SLEEP
#define KM_NOSLEEP UMEM_DEFAULT
#define KM_NORMALPRI 0 /* not needed with UMEM_DEFAULT */
#define KMC_NODEBUG UMC_NODEBUG
#define KMC_NOTOUCH 0 /* not needed for userland caches */
#define KM_NODEBUG 0
@ -581,6 +583,7 @@ extern void kernel_fini(void);
struct spa;
extern void nicenum(uint64_t num, char *buf);
extern void show_pool_stats(struct spa *);
extern int set_global_var(char *arg);
typedef struct callb_cpr {
kmutex_t *cc_lockp;

View File

@ -20,6 +20,7 @@
*/
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2016 by Delphix. All rights reserved.
*/
#include <assert.h>
@ -31,6 +32,7 @@
#include <sys/spa.h>
#include <sys/fs/zfs.h>
#include <sys/refcount.h>
#include <dlfcn.h>
/*
* Routines needed by more than one client of libzpool.
@ -153,3 +155,58 @@ show_pool_stats(spa_t *spa)
nvlist_free(config);
}
/*
* Sets given global variable in libzpool to given unsigned 32-bit value.
* arg: "<variable>=<value>"
*/
int
set_global_var(char *arg)
{
void *zpoolhdl;
char *varname = arg, *varval;
u_longlong_t val;
#ifndef _LITTLE_ENDIAN
/*
* On big endian systems changing a 64-bit variable would set the high
* 32 bits instead of the low 32 bits, which could cause unexpected
* results.
*/
fprintf(stderr, "Setting global variables is only supported on "
"little-endian systems\n", varname);
return (ENOTSUP);
#endif
if ((varval = strchr(arg, '=')) != NULL) {
*varval = '\0';
varval++;
val = strtoull(varval, NULL, 0);
if (val > UINT32_MAX) {
fprintf(stderr, "Value for global variable '%s' must "
"be a 32-bit unsigned integer\n", varname);
return (EOVERFLOW);
}
} else {
return (EINVAL);
}
zpoolhdl = dlopen("libzpool.so", RTLD_LAZY);
if (zpoolhdl != NULL) {
uint32_t *var;
var = dlsym(zpoolhdl, varname);
if (var == NULL) {
fprintf(stderr, "Global variable '%s' does not exist "
"in libzpool.so\n", varname);
return (EINVAL);
}
*var = (uint32_t)val;
dlclose(zpoolhdl);
} else {
fprintf(stderr, "Failed to open libzpool.so to set global "
"variable\n");
return (EIO);
}
return (0);
}

View File

@ -4,6 +4,8 @@
# ZFS_COMMON_SRCS
.PATH: ${SRCTOP}/sys/cddl/contrib/opensolaris/uts/common/fs/zfs
# LUA_SRCS
.PATH: ${SRCTOP}/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/lua
# ZFS_SHARED_SRCS
.PATH: ${SRCTOP}/sys/cddl/contrib/opensolaris/common/zfs
# KERNEL_SRCS
@ -28,11 +30,12 @@ LIB= zpool
ZFS_COMMON_SRCS= ${ZFS_COMMON_OBJS:C/.o$/.c/} trim_map.c
ZFS_SHARED_SRCS= ${ZFS_SHARED_OBJS:C/.o$/.c/}
LUA_SRCS= ${LUA_OBJS:C/.o$/.c/}
KERNEL_SRCS= kernel.c taskq.c util.c
LIST_SRCS= list.c
UNICODE_SRCS= u8_textprep.c
SRCS= ${ZFS_COMMON_SRCS} ${ZFS_SHARED_SRCS} \
SRCS= ${ZFS_COMMON_SRCS} ${ZFS_SHARED_SRCS} ${LUA_SRCS} \
${KERNEL_SRCS} ${LIST_SRCS} ${ATOMIC_SRCS} \
${UNICODE_SRCS}
@ -43,6 +46,7 @@ CFLAGS+= -I${SRCTOP}/cddl/compat/opensolaris/lib/libumem
CFLAGS+= -I${SRCTOP}/cddl/contrib/opensolaris/lib/libzpool/common
CFLAGS+= -I${SRCTOP}/sys/cddl/contrib/opensolaris/uts/common/sys
CFLAGS+= -I${SRCTOP}/sys/cddl/contrib/opensolaris/uts/common/fs/zfs
CFLAGS+= -I${SRCTOP}/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/lua
CFLAGS+= -I${SRCTOP}/sys/cddl/contrib/opensolaris/common/zfs
CFLAGS+= -I${SRCTOP}/sys/cddl/contrib/opensolaris/uts/common
CFLAGS+= -I${SRCTOP}/cddl/contrib/opensolaris/head

View File

@ -3,7 +3,7 @@
.PATH: ${SRCTOP}/cddl/contrib/opensolaris/cmd/zfs
PROG= zfs
MAN= zfs.8
MAN= zfs.8 zfs-program.8
SRCS= zfs_main.c zfs_iter.c
WARNS?= 0

View File

@ -15,7 +15,7 @@
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
VERSION = 1.14.2
VERSION = 1.14.3
# === LIST OF FILES ====================================================

View File

@ -2,6 +2,21 @@ $Id: NEWS,v 1.26 2017/07/28 14:57:56 schwarze Exp $
This file lists the most important changes in the mandoc.bsd.lv distribution.
Changes in version 1.14.3, released on August 5, 2017
--- BUG FIXES ---
* man(7): Do not crash with out-of-bounds read access to a constant
array if .sp or a blank line immediately precedes .SS or .SH.
* mdoc(7): Do not crash with out-of-bounds read access to a constant
array if .sp or a blank line precede the first .Sh macro.
* tbl(7): Ignore explicitly specified negative column widths rather than
wrapping around to huge numbers and risking memory exhaustion.
* man(1): No longer use names that only occur in the SYNOPSIS section.
Gets rid of some surprising behaviour and bogus warnings.
--- THANKS TO ---
Leah Neukirchen (Void Linux), Markus Waldeck (Debian),
Peter Bui (nd.edu), and Yuri Pankov (illumos) for bug reports.
Changes in version 1.14.2, released on July 28, 2017
--- MAJOR NEW FEATURES ---

View File

@ -1,4 +1,4 @@
/* $Id: man_term.c,v 1.208 2017/06/25 11:42:02 schwarze Exp $ */
/* $Id: man_term.c,v 1.209 2017/07/31 15:19:06 schwarze Exp $ */
/*
* Copyright (c) 2008-2012 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2010-2015, 2017 Ingo Schwarze <schwarze@openbsd.org>
@ -673,7 +673,7 @@ pre_SS(DECL_ARGS)
do {
n = n->prev;
} while (n != NULL && n->tok != TOKEN_NONE &&
} while (n != NULL && n->tok >= MAN_TH &&
termacts[n->tok].flags & MAN_NOTEXT);
if (n == NULL || (n->tok == MAN_SS && n->body->child == NULL))
break;
@ -735,7 +735,7 @@ pre_SH(DECL_ARGS)
do {
n = n->prev;
} while (n != NULL && n->tok != TOKEN_NONE &&
} while (n != NULL && n->tok >= MAN_TH &&
termacts[n->tok].flags & MAN_NOTEXT);
if (n == NULL || (n->tok == MAN_SH && n->body->child == NULL))
break;

View File

@ -1,4 +1,4 @@
/* $OpenBSD: mansearch.c,v 1.50 2016/07/09 15:23:36 schwarze Exp $ */
/* $Id: mansearch.c,v 1.76 2017/08/02 13:29:04 schwarze Exp $ */
/*
* Copyright (c) 2012 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2013-2017 Ingo Schwarze <schwarze@openbsd.org>
@ -171,7 +171,9 @@ mansearch(const struct mansearch *search,
page = dbm_page_get(rp->page);
if (lstmatch(search->sec, page->sect) == 0 ||
lstmatch(search->arch, page->arch) == 0)
lstmatch(search->arch, page->arch) == 0 ||
(search->argmode == ARG_NAME &&
rp->bits <= (int32_t)(NAME_SYN & NAME_MASK)))
continue;
if (res == NULL) {
@ -452,14 +454,28 @@ lstlen(const char *cp, size_t sep)
{
size_t sz;
for (sz = 0;; sz++) {
if (cp[0] == '\0') {
if (cp[1] == '\0')
break;
sz += sep - 1;
} else if (cp[0] < ' ')
sz--;
cp++;
for (sz = 0; *cp != '\0'; cp++) {
/* Skip names appearing only in the SYNOPSIS. */
if (*cp <= (char)(NAME_SYN & NAME_MASK)) {
while (*cp != '\0')
cp++;
continue;
}
/* Skip name class markers. */
if (*cp < ' ')
cp++;
/* Print a separator before each but the first string. */
if (sz)
sz += sep;
/* Copy one string. */
while (*cp != '\0') {
sz++;
cp++;
}
}
return sz;
}
@ -471,19 +487,34 @@ lstlen(const char *cp, size_t sep)
static void
lstcat(char *buf, size_t *i, const char *cp, const char *sep)
{
const char *s;
const char *s;
size_t i_start;
for (;;) {
if (cp[0] == '\0') {
if (cp[1] == '\0')
break;
for (i_start = *i; *cp != '\0'; cp++) {
/* Skip names appearing only in the SYNOPSIS. */
if (*cp <= (char)(NAME_SYN & NAME_MASK)) {
while (*cp != '\0')
cp++;
continue;
}
/* Skip name class markers. */
if (*cp < ' ')
cp++;
/* Print a separator before each but the first string. */
if (*i > i_start) {
s = sep;
while (*s != '\0')
buf[(*i)++] = *s++;
} else if (cp[0] >= ' ')
buf[(*i)++] = cp[0];
cp++;
}
/* Copy one string. */
while (*cp != '\0')
buf[(*i)++] = *cp++;
}
}
/*

View File

@ -1,4 +1,4 @@
/* $Id: mdoc_validate.c,v 1.350 2017/07/20 12:54:02 schwarze Exp $ */
/* $Id: mdoc_validate.c,v 1.352 2017/08/02 13:29:04 schwarze Exp $ */
/*
* Copyright (c) 2008-2012 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2010-2017 Ingo Schwarze <schwarze@openbsd.org>
@ -1137,8 +1137,6 @@ post_fname(POST_ARGS)
if ( ! (cp[0] == '\0' || (cp[0] == '(' && cp[1] == '*')))
mandoc_msg(MANDOCERR_FN_PAREN, mdoc->parse,
n->line, n->pos + pos, n->string);
if (n->sec == SEC_SYNOPSIS && mdoc->meta.msec != NULL)
mandoc_xr_add(mdoc->meta.msec, n->string, -1, -1);
}
static void
@ -1205,9 +1203,8 @@ post_nm(POST_ARGS)
n = mdoc->last;
if ((n->sec == SEC_NAME || n->sec == SEC_SYNOPSIS) &&
n->child != NULL && n->child->type == ROFFT_TEXT &&
mdoc->meta.msec != NULL)
if (n->sec == SEC_NAME && n->child != NULL &&
n->child->type == ROFFT_TEXT && mdoc->meta.msec != NULL)
mandoc_xr_add(mdoc->meta.msec, n->child->string, -1, -1);
if (n->last != NULL &&
@ -1931,7 +1928,7 @@ post_root(POST_ARGS)
/* Check that we begin with a proper `Sh'. */
n = mdoc->first->child;
while (n != NULL && n->tok != TOKEN_NONE &&
while (n != NULL && n->tok >= MDOC_Dd &&
mdoc_macros[n->tok].flags & MDOC_PROLOGUE)
n = n->next;

View File

@ -1,4 +1,4 @@
/* $Id: tbl_html.c,v 1.22 2017/06/12 20:14:18 schwarze Exp $ */
/* $Id: tbl_html.c,v 1.23 2017/07/31 16:14:10 schwarze Exp $ */
/*
* Copyright (c) 2011 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2014, 2015, 2017 Ingo Schwarze <schwarze@openbsd.org>
@ -49,6 +49,9 @@ html_tbl_strlen(const char *p, void *arg)
static size_t
html_tbl_sulen(const struct roffsu *su, void *arg)
{
if (su->scale < 0.0)
return 0;
switch (su->unit) {
case SCALE_FS: /* 2^16 basic units */
return su->scale * 65536.0 / 24.0;

View File

@ -1,4 +1,4 @@
/* $Id: tbl_term.c,v 1.56 2017/07/08 13:43:15 schwarze Exp $ */
/* $Id: tbl_term.c,v 1.57 2017/07/31 16:14:10 schwarze Exp $ */
/*
* Copyright (c) 2009, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2011,2012,2014,2015,2017 Ingo Schwarze <schwarze@openbsd.org>
@ -51,7 +51,10 @@ static void tbl_word(struct termp *, const struct tbl_dat *);
static size_t
term_tbl_sulen(const struct roffsu *su, void *arg)
{
return term_hen((const struct termp *)arg, su);
int i;
i = term_hen((const struct termp *)arg, su);
return i > 0 ? i : 0;
}
static size_t

View File

@ -26,10 +26,10 @@
#include "config.h"
#endif
#ifdef WITH_CASPER
#ifdef HAVE_CASPER
#include <libcasper.h>
#include <casper/cap_dns.h>
#endif /* WITH_CASPER */
#endif /* HAVE_CASPER */
#include <netdissect-stdinc.h>
@ -202,7 +202,7 @@ intoa(uint32_t addr)
static uint32_t f_netmask;
static uint32_t f_localnet;
#ifdef WITH_CASPER
#ifdef HAVE_CASPER
extern cap_channel_t *capdns;
#endif
@ -250,7 +250,7 @@ getname(netdissect_options *ndo, const u_char *ap)
*/
if (!ndo->ndo_nflag &&
(addr & f_netmask) == f_localnet) {
#ifdef WITH_CASPER
#ifdef HAVE_CASPER
if (capdns != NULL) {
hp = cap_gethostbyaddr(capdns, (char *)&addr, 4,
AF_INET);
@ -311,7 +311,7 @@ getname6(netdissect_options *ndo, const u_char *ap)
* Do not print names if -n was given.
*/
if (!ndo->ndo_nflag) {
#ifdef WITH_CASPER
#ifdef HAVE_CASPER
if (capdns != NULL) {
hp = cap_gethostbyaddr(capdns, (char *)&addr,
sizeof(addr), AF_INET6);

View File

@ -82,10 +82,10 @@ The Regents of the University of California. All rights reserved.\n";
#include <sys/ioccom.h>
#include <net/bpf.h>
#include <libgen.h>
#ifdef WITH_CASPER
#ifdef HAVE_CASPER
#include <libcasper.h>
#include <casper/cap_dns.h>
#endif /* WITH_CASPER */
#endif /* HAVE_CASPER */
#endif /* HAVE_CAPSICUM */
#include <pcap.h>
#include <signal.h>
@ -176,7 +176,7 @@ static int infoprint;
char *program_name;
#ifdef WITH_CASPER
#ifdef HAVE_CASPER
cap_channel_t *capdns;
#endif
@ -730,7 +730,7 @@ get_next_file(FILE *VFile, char *ptr)
return ret;
}
#ifdef WITH_CASPER
#ifdef HAVE_CASPER
static cap_channel_t *
capdns_setup(void)
{
@ -757,7 +757,7 @@ capdns_setup(void)
return (capdnsloc);
}
#endif /* WITH_CASPER */
#endif /* HAVE_CASPER */
#ifdef HAVE_PCAP_SET_TSTAMP_PRECISION
static int
@ -1839,10 +1839,10 @@ main(int argc, char **argv)
exit_tcpdump(0);
}
#ifdef WITH_CASPER
#ifdef HAVE_CASPER
if (!ndo->ndo_nflag)
capdns = capdns_setup();
#endif /* WITH_CASPER */
#endif /* HAVE_CASPER */
init_print(ndo, localnet, netmask, timezone_offset);
@ -2066,11 +2066,11 @@ main(int argc, char **argv)
#ifdef HAVE_CAPSICUM
cansandbox = (VFileName == NULL && zflag == NULL);
#ifdef WITH_CASPER
#ifdef HAVE_CASPER
cansandbox = (cansandbox && (ndo->ndo_nflag || capdns != NULL));
#else
cansandbox = (cansandbox && ndo->ndo_nflag);
#endif /* WITH_CASPER */
#endif /* HAVE_CASPER */
if (cansandbox && cap_enter() < 0 && errno != ENOSYS)
error("unable to enter the capability mode");
#endif /* HAVE_CAPSICUM */

View File

@ -5,73 +5,73 @@
notify 10 {
match "system" "ZFS";
match "type" "fs.zfs.checksum";
action "logger -p kern.warn -t ZFS 'checksum mismatch, zpool=$pool path=$vdev_path offset=$zio_offset size=$zio_size'";
action "logger -p local7.warn -t ZFS 'checksum mismatch, zpool=$pool path=$vdev_path offset=$zio_offset size=$zio_size'";
};
notify 10 {
match "system" "ZFS";
match "type" "fs.zfs.io";
action "logger -p kern.warn -t ZFS 'vdev I/O failure, zpool=$pool path=$vdev_path offset=$zio_offset size=$zio_size error=$zio_err'";
action "logger -p local7.warn -t ZFS 'vdev I/O failure, zpool=$pool path=$vdev_path offset=$zio_offset size=$zio_size error=$zio_err'";
};
notify 10 {
match "system" "ZFS";
match "type" "fs.zfs.data";
action "logger -p kern.warn -t ZFS 'pool I/O failure, zpool=$pool error=$zio_err'";
action "logger -p local7.warn -t ZFS 'pool I/O failure, zpool=$pool error=$zio_err'";
};
notify 10 {
match "system" "ZFS";
match "type" "fs.zfs.zpool";
action "logger -p kern.err -t ZFS 'failed to load zpool $pool'";
action "logger -p local7.err -t ZFS 'failed to load zpool $pool'";
};
notify 10 {
match "system" "ZFS";
match "type" "fs.zfs.vdev\..*";
action "logger -p kern.err -t ZFS 'vdev problem, zpool=$pool path=$vdev_path type=$type'";
action "logger -p local7.err -t ZFS 'vdev problem, zpool=$pool path=$vdev_path type=$type'";
};
notify 10 {
match "system" "ZFS";
match "type" "fs.zfs.io_failure";
action "logger -p kern.alert -t ZFS 'catastrophic pool I/O failure, zpool=$pool'";
action "logger -p local7.alert -t ZFS 'catastrophic pool I/O failure, zpool=$pool'";
};
notify 10 {
match "system" "ZFS";
match "type" "fs.zfs.probe_failure";
action "logger -p kern.err -t ZFS 'vdev probe failure, zpool=$pool path=$vdev_path'";
action "logger -p local7.err -t ZFS 'vdev probe failure, zpool=$pool path=$vdev_path'";
};
notify 10 {
match "system" "ZFS";
match "type" "fs.zfs.log_replay";
action "logger -p kern.err -t ZFS 'pool log replay failure, zpool=$pool'";
action "logger -p local7.err -t ZFS 'pool log replay failure, zpool=$pool'";
};
notify 10 {
match "system" "ZFS";
match "type" "fs.zfs.config_cache_write";
action "logger -p kern.warn -t ZFS 'failed to write zpool.cache, zpool=$pool'";
action "logger -p local7.warn -t ZFS 'failed to write zpool.cache, zpool=$pool'";
};
notify 10 {
match "system" "ZFS";
match "type" "resource.fs.zfs.removed";
action "logger -p kern.notice -t ZFS 'vdev is removed, pool_guid=$pool_guid vdev_guid=$vdev_guid'";
action "logger -p local7.notice -t ZFS 'vdev is removed, pool_guid=$pool_guid vdev_guid=$vdev_guid'";
};
notify 10 {
match "system" "ZFS";
match "type" "resource.fs.zfs.autoreplace";
action "logger -p kern.info -t ZFS 'autoreplace is configured for vdev, pool_guid=$pool_guid vdev_guid=$vdev_guid'";
action "logger -p local7.info -t ZFS 'autoreplace is configured for vdev, pool_guid=$pool_guid vdev_guid=$vdev_guid'";
};
notify 10 {
match "system" "ZFS";
match "type" "resource.fs.zfs.statechange";
action "logger -p kern.notice -t ZFS 'vdev state changed, pool_guid=$pool_guid vdev_guid=$vdev_guid'";
action "logger -p local7.notice -t ZFS 'vdev state changed, pool_guid=$pool_guid vdev_guid=$vdev_guid'";
};

View File

@ -12,10 +12,10 @@
#ssh stream tcp6 nowait root /usr/sbin/sshd sshd -i -6
#telnet stream tcp nowait root /usr/libexec/telnetd telnetd
#telnet stream tcp6 nowait root /usr/libexec/telnetd telnetd
#shell stream tcp nowait root /usr/libexec/rshd rshd
#shell stream tcp6 nowait root /usr/libexec/rshd rshd
#login stream tcp nowait root /usr/libexec/rlogind rlogind
#login stream tcp6 nowait root /usr/libexec/rlogind rlogind
#shell stream tcp nowait root /usr/local/sbin/rshd rshd
#shell stream tcp6 nowait root /usr/local/sbin/rshd rshd
#login stream tcp nowait root /usr/local/sbin/rlogind rlogind
#login stream tcp6 nowait root /usr/local/sbin/rlogind rlogind
#finger stream tcp nowait/3/10 nobody /usr/libexec/fingerd fingerd -k -s
#finger stream tcp6 nowait/3/10 nobody /usr/libexec/fingerd fingerd -k -s
#

View File

@ -34,8 +34,6 @@
..
pwait
..
rcp
..
rmdir
..
sh
@ -478,6 +476,10 @@
..
netinet
..
netpfil
pf
..
..
opencrypto
..
pjdfstest

View File

@ -35,14 +35,6 @@ FTPMODE= ${FILESMODE}
LINKS= ${FILESDIR}/ftpd ${FILESDIR}/ftp
.endif
.if ${MK_RCMDS} != "no"
FILESGROUPS+= RCMDS
RCMDS+= rsh
RCMDSPACKAGE+= rcmds
RCMDSDIR= ${FILESDIR}
RCMDSMODE= ${FILESMODE}
.endif
.if ${MK_TELNET} != "no"
FILESGROUPS+= TELNET
TELNET+= telnetd

View File

@ -1,18 +0,0 @@
#
# $FreeBSD$
#
# PAM configuration for the "rsh" service
#
# auth
auth required pam_rhosts.so no_warn
# account
account required pam_nologin.so
account required pam_unix.so
# session
session required pam_permit.so
# password
password required pam_deny.so

View File

@ -46,9 +46,12 @@ SRCS+= app.c \
# DEO: why not used?
#SRCS+= itbl-ops.c
.if ${TARGET_ARCH} == "armv6" || ${TARGET_ARCH} == "armv6eb"
.if ${TARGET_ARCH:Marmv6*} != ""
CFLAGS+= -DCPU_DEFAULT=ARM_ARCH_V6K
.endif
.if ${TARGET_ARCH:Marmv7*} != ""
CFLAGS+= -DCPU_DEFAULT=ARM_ARCH_V7A
.endif
.if ${TARGET_CPUARCH} == "mips"
SRCS+= itbl-ops.c itbl-parse.y itbl-lex.l

View File

@ -34,9 +34,12 @@ CFLAGS+= -DTARGET_ARM_EABI
.if ${TARGET_ARCH:Marm*eb} != ""
CFLAGS += -DTARGET_ENDIAN_DEFAULT=MASK_BIG_END
.endif
.if ${TARGET_ARCH} == "armv6" || ${TARGET_ARCH} == "armv6eb"
.if ${TARGET_ARCH:Marmv6*} != ""
CFLAGS += -DFREEBSD_ARCH_armv6
.endif
.if ${TARGET_ARCH:Marmv7*} != ""
CFLAGS += -DFREEBSD_ARCH_armv7
.endif
.if ${TARGET_CPUARCH} == "mips"
.if ${TARGET_ARCH:Mmips*el*} != ""

View File

@ -75,7 +75,6 @@ SUBDIR= ${SUBDIR_BOOTSTRAP} \
libsbuf \
libsmb \
libsqlite3 \
libstand \
libstdbuf \
libstdthreads \
libsysdecode \

View File

@ -20,10 +20,10 @@ CFLAGS+= -D__STDC_CONSTANT_MACROS
TARGET_ARCH?= ${MACHINE_ARCH}
BUILD_ARCH?= ${MACHINE_ARCH}
# Armv6 uses hard float abi, unless the CPUTYPE has soft in it.
# Armv6 and armv7 uses hard float abi, unless the CPUTYPE has soft in it.
# arm (for armv4 and armv5 CPUs) always uses the soft float ABI.
# For all other targets, we stick with 'unknown'.
.if ${TARGET_ARCH:Marmv6*} && (!defined(CPUTYPE) || ${CPUTYPE:M*soft*} == "")
.if ${TARGET_ARCH:Marmv[67]*} && (!defined(CPUTYPE) || ${CPUTYPE:M*soft*} == "")
TARGET_ABI= -gnueabihf
.elif ${TARGET_ARCH:Marm*}
TARGET_ABI= -gnueabi

View File

@ -110,7 +110,7 @@ NOASM=
.include "${LIBC_SRCTOP}/uuid/Makefile.inc"
.include "${LIBC_SRCTOP}/xdr/Makefile.inc"
.if (${LIBC_ARCH} == "arm" && \
(${MACHINE_ARCH:Marmv6*} == "" || (defined(CPUTYPE) && ${CPUTYPE:M*soft*}))) || \
(${MACHINE_ARCH:Marmv[67]*} == "" || (defined(CPUTYPE) && ${CPUTYPE:M*soft*}))) || \
(${LIBC_ARCH} == "mips" && ${MACHINE_ARCH:Mmips*hf} == "") || \
(${LIBC_ARCH} == "riscv" && ${MACHINE_ARCH:Mriscv*sf} != "")
.include "${LIBC_SRCTOP}/softfloat/Makefile.inc"

View File

@ -11,7 +11,7 @@ SYM_MAPS+=${LIBC_SRCTOP}/arm/Symbol.map
.include "${LIBC_SRCTOP}/arm/aeabi/Makefile.inc"
.if ${MACHINE_ARCH:Marmv6*} && (!defined(CPUTYPE) || ${CPUTYPE:M*soft*} == "")
.if ${MACHINE_ARCH:Marmv[67]*} && (!defined(CPUTYPE) || ${CPUTYPE:M*soft*} == "")
SYM_MAPS+=${LIBC_SRCTOP}/arm/Symbol_vfp.map
.endif

View File

@ -5,14 +5,14 @@
SRCS+= aeabi_atexit.c \
aeabi_unwind_cpp.c \
aeabi_unwind_exidx.c
.if (${MACHINE_ARCH:Marmv6*} && defined(CPUTYPE) && ${CPUTYPE:M*soft*} != "") || \
${MACHINE_ARCH:Marmv6*} == ""
.if (${MACHINE_ARCH:Marmv[67]*} && defined(CPUTYPE) && ${CPUTYPE:M*soft*} != "") || \
${MACHINE_ARCH:Marmv[67]*} == ""
SRCS+= aeabi_asm_double.S \
aeabi_asm_float.S \
aeabi_double.c \
aeabi_float.c
.endif
.if ${MACHINE_ARCH:Marmv6*} && (!defined(CPUTYPE) || ${CPUTYPE:M*soft*} == "")
.if ${MACHINE_ARCH:Marmv[67]*} && (!defined(CPUTYPE) || ${CPUTYPE:M*soft*} == "")
SRCS+= aeabi_vfp_double.S \
aeabi_vfp_float.S
.endif

View File

@ -7,7 +7,7 @@ SRCS+= _ctx_start.S _setjmp.S _set_tp.c alloca.S fabs.c \
arm_initfini.c \
trivial-getcontextx.c
.if ${MACHINE_ARCH:Marmv6*} && (!defined(CPUTYPE) || ${CPUTYPE:M*soft*} == "")
.if ${MACHINE_ARCH:Marmv[67]*} && (!defined(CPUTYPE) || ${CPUTYPE:M*soft*} == "")
SRCS+= fpgetmask_vfp.c fpgetround_vfp.c fpgetsticky_vfp.c fpsetmask_vfp.c \
fpsetround_vfp.c fpsetsticky_vfp.c
.endif

View File

@ -160,9 +160,6 @@ __libc_allocate_tls(void *oldtcb, size_t tcbsize, size_t tcbalign __unused)
if (tls_init_size > 0)
memcpy((void*)dtv[2], tls_init, tls_init_size);
if (tls_static_space > tls_init_size)
memset((void*)(dtv[2] + tls_init_size), 0,
tls_static_space - tls_init_size);
}
return(tcb);

View File

@ -28,7 +28,7 @@
.\" From: @(#)gethostbyname.3 8.4 (Berkeley) 5/25/95
.\" $FreeBSD$
.\"
.Dd May 12, 2006
.Dd October 4, 2017
.Dt GETHOSTBYNAME 3
.Os
.Sh NAME
@ -189,19 +189,20 @@ function
may be used to request the use of a connected
.Tn TCP
socket for queries.
Queries will by default use
.Tn UDP
datagrams.
If the
.Fa stayopen
flag is non-zero,
this sets the option to send all queries to the name server using
flag is non-zero, a
.Tn TCP
and to retain the connection after each call to
connection to the name server will be used.
It will remain open after calls to
.Fn gethostbyname ,
.Fn gethostbyname2
or
.Fn gethostbyaddr .
Otherwise, queries are performed using
.Tn UDP
datagrams.
.Fn gethostbyaddr
have completed.
.Pp
The
.Fn endhostent

View File

@ -124,7 +124,7 @@ SYM_MAPS+= ${LIBC_SRCTOP}/sys/Symbol.map
CLEANFILES+= ${SASM} ${SPSEUDO}
.if ${MACHINE_CPUARCH} == "amd64" || ${MACHINE_CPUARCH} == "i386" || \
${MACHINE_CPUARCH} == "powerpc" || ${MACHINE_ARCH:Marmv6*}
${MACHINE_CPUARCH} == "powerpc" || ${MACHINE_ARCH:Marmv[67]*}
NOTE_GNU_STACK='\t.section .note.GNU-stack,"",%%progbits\n'
.else
NOTE_GNU_STACK=''

View File

@ -28,7 +28,7 @@
.\" @(#)recv.2 8.3 (Berkeley) 2/21/94
.\" $FreeBSD$
.\"
.Dd February 3, 2017
.Dd October 3, 2017
.Dt RECV 2
.Os
.Sh NAME
@ -230,7 +230,7 @@ Here
.Fa msg_name
and
.Fa msg_namelen
specify the destination address if the socket is unconnected;
specify the source address if the socket is unconnected;
.Fa msg_name
may be given as a null pointer if no names are desired or required.
The

View File

@ -50,7 +50,8 @@ caph_limit_stream(int fd, int flags)
cap_rights_t rights;
unsigned long cmds[] = { TIOCGETA, TIOCGWINSZ, FIODTYPE };
cap_rights_init(&rights, CAP_FCNTL, CAP_FSTAT, CAP_IOCTL, CAP_SEEK);
cap_rights_init(&rights, CAP_EVENT, CAP_FCNTL, CAP_FSTAT,
CAP_IOCTL, CAP_SEEK);
if ((flags & CAPH_READ) != 0)
cap_rights_set(&rights, CAP_READ);

View File

@ -204,7 +204,7 @@ SRCF+= stdatomic
.endif
.for file in ${SRCF}
.if ${MACHINE_ARCH:Marmv6*} && (!defined(CPUTYPE) || ${CPUTYPE:M*soft*} == "") \
.if ${MACHINE_ARCH:Marmv[67]*} && (!defined(CPUTYPE) || ${CPUTYPE:M*soft*} == "") \
&& exists(${CRTSRC}/${CRTARCH}/${file}vfp.S)
SRCS+= ${file}vfp.S
. elif exists(${CRTSRC}/${CRTARCH}/${file}.S)

View File

@ -25,7 +25,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
.Dd June 6, 2014
.Dd October 5, 2017
.Dt CUSE 3
.Os
.Sh NAME
@ -292,6 +292,7 @@ enum {
CUSE_ERR_SIGNAL
CUSE_ERR_OTHER
CUSE_ERR_NOT_LOADED
CUSE_ERR_NO_DEVICE
CUSE_POLL_NONE
CUSE_POLL_READ

View File

@ -48,10 +48,12 @@ __FBSDID("$FreeBSD$");
#include <sys/stat.h>
#include <sys/vnode.h>
#include <sys/socket.h>
#define _WANT_SOCKET
#include <sys/socketvar.h>
#include <sys/domain.h>
#include <sys/protosw.h>
#include <sys/un.h>
#define _WANT_UNPCB
#include <sys/unpcb.h>
#include <sys/sysctl.h>
#include <sys/tty.h>
@ -580,6 +582,10 @@ procstat_getfiles_kvm(struct procstat *procstat, struct kinfo_proc *kp, int mmap
type = PS_FST_TYPE_SHM;
data = file.f_data;
break;
case DTYPE_PROCDESC:
type = PS_FST_TYPE_PROCDESC;
data = file.f_data;
break;
default:
continue;
}
@ -663,6 +669,7 @@ kinfo_type2fst(int kftype)
int kf_type;
int fst_type;
} kftypes2fst[] = {
{ KF_TYPE_PROCDESC, PS_FST_TYPE_PROCDESC },
{ KF_TYPE_CRYPTO, PS_FST_TYPE_CRYPTO },
{ KF_TYPE_FIFO, PS_FST_TYPE_FIFO },
{ KF_TYPE_KQUEUE, PS_FST_TYPE_KQUEUE },

View File

@ -68,6 +68,7 @@
#define PS_FST_TYPE_SEM 10
#define PS_FST_TYPE_UNKNOWN 11
#define PS_FST_TYPE_NONE 12
#define PS_FST_TYPE_PROCDESC 13
/*
* Special descriptor numbers.

View File

@ -719,6 +719,8 @@ extern char *_usrstack __hidden;
extern int _libthr_debug;
extern int _thread_event_mask;
extern struct pthread *_thread_last_event;
/* Used in symbol lookup of libthread_db */
extern struct pthread_key _thread_keytable[];
/* List of all threads: */
extern pthreadlist _thread_list;

View File

@ -42,7 +42,8 @@ __FBSDID("$FreeBSD$");
#include "thr_private.h"
static struct pthread_key _thread_keytable[PTHREAD_KEYS_MAX];
/* Used in symbol lookup of libthread_db */
struct pthread_key _thread_keytable[PTHREAD_KEYS_MAX];
__weak_reference(_pthread_key_create, pthread_key_create);
__weak_reference(_pthread_key_delete, pthread_key_delete);

View File

@ -3,7 +3,7 @@
LDBL_PREC = 53
SYM_MAPS += ${.CURDIR}/arm/Symbol.map
.if ${MACHINE_ARCH:Marmv6*} && defined(CPUTYPE) && ${CPUTYPE:M*soft*} != ""
.if ${MACHINE_ARCH:Marmv[67]*} && defined(CPUTYPE) && ${CPUTYPE:M*soft*} != ""
ARCH_SRCS = fenv-softfp.c fenv-vfp.c
.endif

View File

@ -79,11 +79,6 @@ _rtld-elf= rtld-elf
SUBDIR+= rbootd
.endif
.if ${MK_RCMDS} != "no"
_rlogind= rlogind
_rshd= rshd
.endif
.if ${MK_SENDMAIL} != "no"
_mail.local= mail.local
_smrsh= smrsh

View File

@ -430,6 +430,10 @@ main(int argc, char *argv[], char **envp)
}
}
/* handle filesize limit gracefully */
sa.sa_handler = SIG_IGN;
(void)sigaction(SIGXFSZ, &sa, NULL);
if (daemon_mode) {
int *ctl_sock, fd, maxfd = -1, nfds, i;
fd_set defreadfds, readfds;
@ -1196,14 +1200,14 @@ end_login(void)
#endif
(void) seteuid(0);
if (logged_in && dowtmp)
ftpd_logwtmp(wtmpid, NULL, NULL);
pw = NULL;
#ifdef LOGIN_CAP
setusercontext(NULL, getpwuid(0), 0, LOGIN_SETALL & ~(LOGIN_SETLOGIN |
LOGIN_SETUSER | LOGIN_SETGROUP | LOGIN_SETPATH |
LOGIN_SETENV));
#endif
if (logged_in && dowtmp)
ftpd_logwtmp(wtmpid, NULL, NULL);
pw = NULL;
#ifdef USE_PAM
if (pamh) {
if ((e = pam_setcred(pamh, PAM_DELETE_CRED)) != PAM_SUCCESS)
@ -1478,7 +1482,7 @@ pass(char *passwd)
}
}
setusercontext(lc, pw, 0, LOGIN_SETALL &
~(LOGIN_SETUSER | LOGIN_SETPATH | LOGIN_SETENV));
~(LOGIN_SETRESOURCES | LOGIN_SETUSER | LOGIN_SETPATH | LOGIN_SETENV));
#else
setlogin(pw->pw_name);
(void) initgroups(pw->pw_name, pw->pw_gid);
@ -1520,6 +1524,10 @@ pass(char *passwd)
(struct sockaddr *)&his_addr);
logged_in = 1;
#ifdef LOGIN_CAP
setusercontext(lc, pw, 0, LOGIN_SETRESOURCES);
#endif
if (guest && stats && statfd < 0)
#ifdef VIRTUAL_HOSTING
statfd = open(thishost->statfile, O_WRONLY|O_APPEND);
@ -2770,6 +2778,11 @@ dologout(int status)
if (logged_in && dowtmp) {
(void) seteuid(0);
#ifdef LOGIN_CAP
setusercontext(NULL, getpwuid(0), 0, LOGIN_SETALL & ~(LOGIN_SETLOGIN |
LOGIN_SETUSER | LOGIN_SETGROUP | LOGIN_SETPATH |
LOGIN_SETENV));
#endif
ftpd_logwtmp(wtmpid, NULL, NULL);
}
/* beware of flushing buffers after a SIGPIPE */

View File

@ -1,23 +0,0 @@
# @(#)Makefile 8.1 (Berkeley) 6/4/93
# $FreeBSD$
.include <src.opts.mk>
PACKAGE=rcmds
PROG= rlogind
MAN= rlogind.8
PACKAGE=rcmds
LIBADD= util
WARNS?= 2
.if ${MK_INET6_SUPPORT} != "no"
CFLAGS+= -DINET6
.endif
.if ${MK_BLACKLIST_SUPPORT} != "no"
CFLAGS+= -DUSE_BLACKLIST -I${SRCTOP}/contrib/blacklist/include
LIBADD+= blacklist
LDFLAGS+=-L${LIBBLACKLISTDIR}
.endif
.include <bsd.prog.mk>

View File

@ -1,22 +0,0 @@
# $FreeBSD$
# Autogenerated - do NOT edit!
DIRDEPS = \
gnu/lib/csu \
gnu/lib/libgcc \
include \
include/arpa \
include/xlocale \
lib/${CSU_DIR} \
lib/libblacklist \
lib/libc \
lib/libcompiler_rt \
lib/libthr \
lib/libutil \
.include <dirdeps.mk>
.if ${DEP_RELDIR} == ${_DEP_RELDIR}
# local dependencies - needed for -jN in clean tree
.endif

View File

@ -1,202 +0,0 @@
.\" Copyright (c) 1983, 1989, 1991, 1993
.\" The Regents of the University of California. All rights reserved.
.\"
.\" 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.
.\" 3. Neither the name of the University nor the names of its contributors
.\" may be used to endorse or promote products derived from this software
.\" without specific prior written permission.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
.\"
.\" @(#)rlogind.8 8.1 (Berkeley) 6/4/93
.\" $FreeBSD$
.\"
.Dd July 3, 2017
.Dt RLOGIND 8
.Os
.Sh NAME
.Nm rlogind
.Nd remote login server
.Sh SYNOPSIS
.Nm
.Op Fl Daln
.Sh DEPRECATION NOTICE
.Nm
is deprecated and will be removed from future versions of the
.Fx
base system.
If
.Nm
is still required, it can be installed from ports or packages
(net/bsdrcmds).
.Sh DESCRIPTION
The
.Nm
utility is the server for the
.Xr rlogin 1
program.
The server provides a remote login facility
with authentication based on privileged port numbers from trusted hosts.
.Pp
Options supported by
.Nm :
.Bl -tag -width indent
.It Fl D
Set TCP_NODELAY socket option.
This improves responsiveness at the expense of
some additional network traffic.
.It Fl a
Ask hostname for verification.
.It Fl l
Prevent any authentication based on the user's
.Dq Pa .rhosts
file, unless the user is logging in as the superuser.
.It Fl n
Disable keep-alive messages.
.El
.Pp
The
.Nm
utility listens for service requests at the port indicated in
the
.Dq login
service specification; see
.Xr services 5 .
When a service request is received the following protocol
is initiated:
.Bl -enum
.It
The server checks the client's source port.
If the port is not in the range 512-1023, the server
aborts the connection.
.It
The server checks the client's source address
and requests the corresponding host name (see
.Xr gethostbyaddr 3 ,
.Xr hosts 5
and
.Xr named 8 ) .
If the hostname cannot be determined,
the dot-notation representation of the host address is used.
If the hostname is in the same domain as the server (according to
the last two components of the domain name),
or if the
.Fl a
option is given,
the addresses for the hostname are requested,
verifying that the name and address correspond.
Normal authentication is bypassed if the address verification fails.
.El
.Pp
Once the source port and address have been checked,
.Nm
proceeds with the authentication process described in
.Xr rshd 8 .
It then allocates a pseudo terminal (see
.Xr pty 4 ) ,
and manipulates file descriptors so that the slave
half of the pseudo terminal becomes the
.Em stdin ,
.Em stdout ,
and
.Em stderr
for a login process.
The login process is an instance of the
.Xr login 1
program, invoked with the
.Fl f
option if authentication has succeeded.
If automatic authentication fails, the user is
prompted to log in as if on a standard terminal line.
.Pp
The parent of the login process manipulates the master side of
the pseudo terminal, operating as an intermediary
between the login process and the client instance of the
.Xr rlogin 1
program.
In normal operation, the packet protocol described
in
.Xr pty 4
is invoked to provide
.Ql ^S/^Q
type facilities and propagate
interrupt signals to the remote programs.
The login process
propagates the client terminal's baud rate and terminal type,
as found in the environment variable,
.Ev TERM ;
see
.Xr environ 7 .
The screen or window size of the terminal is requested from the client,
and window size changes from the client are propagated to the pseudo terminal.
.Pp
Transport-level keepalive messages are enabled unless the
.Fl n
option is present.
The use of keepalive messages allows sessions to be timed out
if the client crashes or becomes unreachable.
.Sh FILES
.Bl -tag -width /etc/hostsxxxxxxxx -compact
.It Pa /etc/hosts
.It Pa /etc/hosts.equiv
.It Ev $HOME Ns Pa /.rhosts
.It Pa /var/run/nologin
.El
.Sh DIAGNOSTICS
All initial diagnostic messages are indicated
by a leading byte with a value of 1,
after which any network connections are closed.
If there are no errors before
.Xr login 1
is invoked, a null byte is returned as in indication of success.
.Bl -tag -width Ds
.It Sy Try again.
A
.Xr fork 2
by the server failed.
.El
.Sh SEE ALSO
.Xr login 1 ,
.Xr ruserok 3 ,
.Xr hosts 5 ,
.Xr hosts.equiv 5 ,
.Xr login.conf 5 ,
.Xr nologin 5 ,
.Xr services 5 ,
.Xr rshd 8
.Sh HISTORY
The
.Nm
utility appeared in
.Bx 4.2 .
.Pp
IPv6 support was added by WIDE/KAME project.
.Sh BUGS
The authentication procedure used here assumes the integrity
of each client machine and the connecting medium.
This is
insecure, but is useful in an
.Dq open
environment.
.Pp
A facility to allow all data exchanges to be encrypted should be
present.
.Pp
A more extensible protocol should be used.

View File

@ -1,583 +0,0 @@
/*-
* Copyright (c) 1983, 1988, 1989, 1993
* The Regents of the University of California. All rights reserved.
* Copyright (c) 2002 Networks Associates Technology, Inc.
* All rights reserved.
*
* Portions of this software were developed for the FreeBSD Project by
* ThinkSec AS and NAI Labs, the Security Research Division of Network
* Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035
* ("CBOSS"), as part of the DARPA CHATS research program.
*
* 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.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
*/
#if 0
#ifndef lint
static const char copyright[] =
"@(#) Copyright (c) 1983, 1988, 1989, 1993\n\
The Regents of the University of California. All rights reserved.\n";
#endif /* not lint */
#ifndef lint
static const char sccsid[] = "@(#)rlogind.c 8.1 (Berkeley) 6/4/93";
#endif /* not lint */
#endif
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
/*
* remote login server:
* \0
* remuser\0
* locuser\0
* terminal_type/speed\0
* data
*/
#define FD_SETSIZE 16 /* don't need many bits for select */
#include <sys/types.h>
#include <sys/param.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <signal.h>
#include <termios.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/in_systm.h>
#include <netinet/ip.h>
#include <netinet/tcp.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <errno.h>
#include <libutil.h>
#include <paths.h>
#include <poll.h>
#include <pwd.h>
#include <syslog.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#ifdef USE_BLACKLIST
#include <blacklist.h>
#endif
#ifndef TIOCPKT_WINDOW
#define TIOCPKT_WINDOW 0x80
#endif
#define ARGSTR "Daln"
char *env[2];
#define NMAX 30
char lusername[NMAX+1], rusername[NMAX+1];
static char term[64] = "TERM=";
#define ENVSIZE (sizeof("TERM=")-1) /* skip null for concatenation */
int keepalive = 1;
int check_all = 0;
int no_delay;
struct passwd *pwd;
union sockunion {
struct sockinet {
u_char si_len;
u_char si_family;
u_short si_port;
} su_si;
struct sockaddr_in su_sin;
struct sockaddr_in6 su_sin6;
};
#define su_len su_si.si_len
#define su_family su_si.si_family
#define su_port su_si.si_port
void doit(int, union sockunion *);
int control(int, char *, int);
void protocol(int, int);
void cleanup(int);
void fatal(int, char *, int);
int do_rlogin(union sockunion *);
void getstr(char *, int, char *);
void setup_term(int);
int do_krb_login(struct sockaddr_in *);
void usage(void);
int
main(int argc, char *argv[])
{
extern int __check_rhosts_file;
union sockunion from;
socklen_t fromlen;
int ch, on;
openlog("rlogind", LOG_PID | LOG_CONS, LOG_AUTH);
opterr = 0;
while ((ch = getopt(argc, argv, ARGSTR)) != -1)
switch (ch) {
case 'D':
no_delay = 1;
break;
case 'a':
check_all = 1;
break;
case 'l':
__check_rhosts_file = 0;
break;
case 'n':
keepalive = 0;
break;
case '?':
default:
usage();
break;
}
argc -= optind;
argv += optind;
fromlen = sizeof (from);
if (getpeername(0, (struct sockaddr *)&from, &fromlen) < 0) {
syslog(LOG_ERR,"Can't get peer name of remote host: %m");
fatal(STDERR_FILENO, "Can't get peer name of remote host", 1);
}
on = 1;
if (keepalive &&
setsockopt(0, SOL_SOCKET, SO_KEEPALIVE, &on, sizeof (on)) < 0)
syslog(LOG_WARNING, "setsockopt (SO_KEEPALIVE): %m");
if (no_delay &&
setsockopt(0, IPPROTO_TCP, TCP_NODELAY, &on, sizeof(on)) < 0)
syslog(LOG_WARNING, "setsockopt (TCP_NODELAY): %m");
if (from.su_family == AF_INET)
{
on = IPTOS_LOWDELAY;
if (setsockopt(0, IPPROTO_IP, IP_TOS, (char *)&on, sizeof(int)) < 0)
syslog(LOG_WARNING, "setsockopt (IP_TOS): %m");
}
doit(0, &from);
return 0;
}
int child;
int netf;
char line[MAXPATHLEN];
int confirmed;
struct winsize win = { 0, 0, 0, 0 };
void
doit(int f, union sockunion *fromp)
{
int master, pid, on = 1;
int authenticated = 0;
char hostname[2 * MAXHOSTNAMELEN + 1];
char nameinfo[2 * INET6_ADDRSTRLEN + 1];
char c;
alarm(60);
read(f, &c, 1);
if (c != 0)
exit(1);
alarm(0);
realhostname_sa(hostname, sizeof(hostname) - 1,
(struct sockaddr *)fromp, fromp->su_len);
/* error check ? */
fromp->su_port = ntohs((u_short)fromp->su_port);
hostname[sizeof(hostname) - 1] = '\0';
{
if ((fromp->su_family != AF_INET
#ifdef INET6
&& fromp->su_family != AF_INET6
#endif
) ||
fromp->su_port >= IPPORT_RESERVED ||
fromp->su_port < IPPORT_RESERVED/2) {
getnameinfo((struct sockaddr *)fromp,
fromp->su_len,
nameinfo, sizeof(nameinfo), NULL, 0,
NI_NUMERICHOST);
/* error check ? */
syslog(LOG_NOTICE, "Connection from %s on illegal port",
nameinfo);
#ifdef USE_BLACKLIST
blacklist(1, STDIN_FILENO, "illegal port");
#endif
fatal(f, "Permission denied", 0);
}
#ifdef IP_OPTIONS
if (fromp->su_family == AF_INET)
{
u_char optbuf[BUFSIZ/3];
socklen_t optsize = sizeof(optbuf);
int ipproto, i;
struct protoent *ip;
if ((ip = getprotobyname("ip")) != NULL)
ipproto = ip->p_proto;
else
ipproto = IPPROTO_IP;
if (getsockopt(0, ipproto, IP_OPTIONS, (char *)optbuf,
&optsize) == 0 && optsize != 0) {
for (i = 0; i < optsize; ) {
u_char c = optbuf[i];
if (c == IPOPT_LSRR || c == IPOPT_SSRR) {
syslog(LOG_NOTICE,
"Connection refused from %s with IP option %s",
inet_ntoa(fromp->su_sin.sin_addr),
c == IPOPT_LSRR ? "LSRR" : "SSRR");
#ifdef USE_BLACKLIST
blacklist(1, STDIN_FILENO, "source routing present");
#endif
exit(1);
}
if (c == IPOPT_EOL)
break;
i += (c == IPOPT_NOP) ? 1 : optbuf[i+1];
}
}
}
#endif
if (do_rlogin(fromp) == 0)
authenticated++;
}
if (confirmed == 0) {
write(f, "", 1);
confirmed = 1; /* we sent the null! */
}
netf = f;
pid = forkpty(&master, line, NULL, &win);
if (pid < 0) {
if (errno == ENOENT)
fatal(f, "Out of ptys", 0);
else
fatal(f, "Forkpty", 1);
}
if (pid == 0) {
if (f > 2) /* f should always be 0, but... */
(void) close(f);
setup_term(0);
if (*lusername=='-') {
syslog(LOG_ERR, "tried to pass user \"%s\" to login",
lusername);
#ifdef USE_BLACKLIST
blacklist(1, STDIN_FILENO, "invalid user");
#endif
fatal(STDERR_FILENO, "invalid user", 0);
}
#ifdef USE_BLACKLIST
blacklist(0, STDIN_FILENO, "success");
#endif
if (authenticated) {
execl(_PATH_LOGIN, "login", "-p",
"-h", hostname, "-f", lusername, (char *)NULL);
} else
execl(_PATH_LOGIN, "login", "-p",
"-h", hostname, lusername, (char *)NULL);
fatal(STDERR_FILENO, _PATH_LOGIN, 1);
/*NOTREACHED*/
}
ioctl(f, FIONBIO, &on);
ioctl(master, FIONBIO, &on);
ioctl(master, TIOCPKT, &on);
signal(SIGCHLD, cleanup);
protocol(f, master);
signal(SIGCHLD, SIG_IGN);
cleanup(0);
}
char magic[2] = { 0377, 0377 };
char oobdata[] = {TIOCPKT_WINDOW};
/*
* Handle a "control" request (signaled by magic being present)
* in the data stream. For now, we are only willing to handle
* window size changes.
*/
int
control(int pty, char *cp, int n)
{
struct winsize w;
if (n < 4 + (int)sizeof(w) || cp[2] != 's' || cp[3] != 's')
return (0);
oobdata[0] &= ~TIOCPKT_WINDOW; /* we know he heard */
bcopy(cp+4, (char *)&w, sizeof(w));
w.ws_row = ntohs(w.ws_row);
w.ws_col = ntohs(w.ws_col);
w.ws_xpixel = ntohs(w.ws_xpixel);
w.ws_ypixel = ntohs(w.ws_ypixel);
(void)ioctl(pty, TIOCSWINSZ, &w);
return (4+sizeof (w));
}
/*
* rlogin "protocol" machine.
*/
void
protocol(int f, int p)
{
char pibuf[1024+1], fibuf[1024], *pbp = NULL, *fbp = NULL;
int pcc = 0, fcc = 0;
int cc, nfd, n;
char cntl;
/*
* Must ignore SIGTTOU, otherwise we'll stop
* when we try and set slave pty's window shape
* (our controlling tty is the master pty).
*/
(void) signal(SIGTTOU, SIG_IGN);
send(f, oobdata, 1, MSG_OOB); /* indicate new rlogin */
if (f > p)
nfd = f + 1;
else
nfd = p + 1;
for (;;) {
struct pollfd set[2];
set[0].fd = p;
set[0].events = POLLPRI;
set[1].fd = f;
set[1].events = 0;
if (fcc)
set[0].events |= POLLOUT;
else
set[1].events |= POLLIN;
if (pcc >= 0) {
if (pcc)
set[1].events |= POLLOUT;
else
set[0].events |= POLLIN;
}
if ((n = poll(set, 2, INFTIM)) < 0) {
if (errno == EINTR)
continue;
fatal(f, "poll", 1);
}
if (n == 0) {
/* shouldn't happen... */
sleep(5);
continue;
}
#define pkcontrol(c) ((c)&(TIOCPKT_FLUSHWRITE|TIOCPKT_NOSTOP|TIOCPKT_DOSTOP))
if (set[0].revents & POLLPRI) {
cc = read(p, &cntl, 1);
if (cc == 1 && pkcontrol(cntl)) {
cntl |= oobdata[0];
send(f, &cntl, 1, MSG_OOB);
if (cntl & TIOCPKT_FLUSHWRITE)
pcc = 0;
}
}
if (set[1].revents & POLLIN) {
fcc = read(f, fibuf, sizeof(fibuf));
if (fcc < 0 && errno == EWOULDBLOCK)
fcc = 0;
else {
char *cp;
int left, n;
if (fcc <= 0)
break;
fbp = fibuf;
top:
for (cp = fibuf; cp < fibuf+fcc-1; cp++)
if (cp[0] == magic[0] &&
cp[1] == magic[1]) {
left = fcc - (cp-fibuf);
n = control(p, cp, left);
if (n) {
left -= n;
if (left > 0)
bcopy(cp+n, cp, left);
fcc -= n;
goto top; /* n^2 */
}
}
}
}
if (set[0].revents & POLLOUT && fcc > 0) {
cc = write(p, fbp, fcc);
if (cc > 0) {
fcc -= cc;
fbp += cc;
}
}
if (set[0].revents & POLLIN) {
pcc = read(p, pibuf, sizeof (pibuf));
pbp = pibuf;
if (pcc < 0 && errno == EWOULDBLOCK)
pcc = 0;
else if (pcc <= 0)
break;
else if (pibuf[0] == 0) {
pbp++, pcc--;
} else {
if (pkcontrol(pibuf[0])) {
pibuf[0] |= oobdata[0];
send(f, &pibuf[0], 1, MSG_OOB);
}
pcc = 0;
}
}
if (set[1].revents & POLLOUT && pcc > 0) {
cc = write(f, pbp, pcc);
if (cc > 0) {
pcc -= cc;
pbp += cc;
}
}
}
}
void
cleanup(int signo __unused)
{
shutdown(netf, SHUT_RDWR);
exit(1);
}
void
fatal(int f, char *msg, int syserr)
{
int len;
char buf[BUFSIZ], *bp = buf;
/*
* Prepend binary one to message if we haven't sent
* the magic null as confirmation.
*/
if (!confirmed)
*bp++ = '\01'; /* error indicator */
if (syserr)
len = snprintf(bp, sizeof(buf), "rlogind: %s: %s.\r\n",
msg, strerror(errno));
else
len = snprintf(bp, sizeof(buf), "rlogind: %s.\r\n", msg);
if (len < 0)
len = 0;
(void) write(f, buf, bp + len - buf);
exit(1);
}
int
do_rlogin(union sockunion *dest)
{
getstr(rusername, sizeof(rusername), "remuser too long");
getstr(lusername, sizeof(lusername), "locuser too long");
getstr(term+ENVSIZE, sizeof(term)-ENVSIZE, "Terminal type too long");
pwd = getpwnam(lusername);
if (pwd == NULL)
return (-1);
/* XXX why don't we syslog() failure? */
return (iruserok_sa(dest, dest->su_len, pwd->pw_uid == 0, rusername,
lusername));
}
void
getstr(char *buf, int cnt, char *errmsg)
{
char c;
do {
if (read(STDIN_FILENO, &c, 1) != 1)
exit(1);
if (--cnt < 0) {
#ifdef USE_BLACKLIST
blacklist(1, STDIN_FILENO, "buffer overflow");
#endif
fatal(STDOUT_FILENO, errmsg, 0);
}
*buf++ = c;
} while (c != 0);
}
extern char **environ;
void
setup_term(int fd)
{
char *cp;
char *speed;
struct termios tt, def;
cp = strchr(term + ENVSIZE, '/');
#ifndef notyet
tcgetattr(fd, &tt);
if (cp) {
*cp++ = '\0';
speed = cp;
cp = strchr(speed, '/');
if (cp)
*cp++ = '\0';
cfsetspeed(&tt, atoi(speed));
}
cfmakesane(&def);
tt.c_iflag = def.c_iflag;
tt.c_oflag = def.c_oflag;
tt.c_lflag = def.c_lflag;
tcsetattr(fd, TCSAFLUSH, &tt);
#else
if (cp) {
*cp++ = '\0';
speed = cp;
cp = strchr(speed, '/');
if (cp)
*cp++ = '\0';
tcgetattr(fd, &tt);
cfsetspeed(&tt, atoi(speed));
tcsetattr(fd, TCSAFLUSH, &tt);
}
#endif
env[0] = term;
env[1] = 0;
environ = env;
}
void
usage(void)
{
syslog(LOG_ERR, "usage: rlogind [-" ARGSTR "]");
}

View File

@ -1,24 +0,0 @@
# From: @(#)Makefile 8.1 (Berkeley) 6/4/93
# $FreeBSD$
PACKAGE=rcmds
.include <src.opts.mk>
PROG= rshd
MAN= rshd.8
PACKAGE=rcmds
WARNS?= 3
WFORMAT=0
LIBADD= util pam
.if ${MK_BLACKLIST_SUPPORT} != "no"
CFLAGS+= -DUSE_BLACKLIST -I${SRCTOP}/contrib/blacklist/include
LIBADD+= blacklist
LDFLAGS+=-L${LIBBLACKLISTDIR}
.endif
.include <bsd.prog.mk>

View File

@ -1,23 +0,0 @@
# $FreeBSD$
# Autogenerated - do NOT edit!
DIRDEPS = \
gnu/lib/csu \
gnu/lib/libgcc \
include \
include/arpa \
include/xlocale \
lib/${CSU_DIR} \
lib/libblacklist \
lib/libc \
lib/libcompiler_rt \
lib/libpam/libpam \
lib/libthr \
lib/libutil \
.include <dirdeps.mk>
.if ${DEP_RELDIR} == ${_DEP_RELDIR}
# local dependencies - needed for -jN in clean tree
.endif

View File

@ -1,277 +0,0 @@
.\" Copyright (c) 1983, 1989, 1991, 1993
.\" The Regents of the University of California. All rights reserved.
.\"
.\" 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.
.\" 3. Neither the name of the University nor the names of its contributors
.\" may be used to endorse or promote products derived from this software
.\" without specific prior written permission.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
.\"
.\" @(#)rshd.8 8.1 (Berkeley) 6/4/93
.\" $FreeBSD$
.\"
.Dd July 3, 2017
.Dt RSHD 8
.Os
.Sh NAME
.Nm rshd
.Nd remote shell server
.Sh SYNOPSIS
.Nm
.Op Fl aDLln
.Sh DEPRECATION NOTICE
.Nm
is deprecated and will be removed from future versions of the
.Fx
base system.
If
.Nm
is still required, it can be installed from ports or packages
(net/bsdrcmds).
.Sh DESCRIPTION
The
.Nm
utility
is the server for the
.Xr rcmd 3
routine and, consequently, for the
.Xr rsh 1
utility.
The server provides remote execution facilities
with authentication based on privileged port numbers from trusted hosts.
.Pp
The
.Nm
utility listens for service requests at the port indicated in
the
.Dq cmd
service specification; see
.Xr services 5 .
When a service request is received the following protocol
is initiated:
.Bl -enum
.It
The server checks the client's source port.
If the port is not in the range 512-1023, the server
aborts the connection.
.It
The server reads characters from the socket up
to a
.Tn NUL
(`\e0') byte.
The resultant string is
interpreted as an
.Tn ASCII
number, base 10.
.It
If the number received in step 2 is non-zero,
it is interpreted as the port number of a secondary
stream to be used for the
.Em stderr .
A second connection is then created to the specified
port on the client's machine.
The source port of this
second connection is also in the range 512-1023.
.It
The server checks the client's source address
and requests the corresponding host name (see
.Xr gethostbyaddr 3 ,
.Xr hosts 5
and
.Xr named 8 ) .
If the hostname cannot be determined or the hostname and address do
not match after verification,
the dot-notation representation of the host address is used.
.It
A null terminated user name of at most 16 characters
is retrieved on the initial socket.
This user name
is interpreted as the user identity on the
.Em client Ns 's
machine.
.It
A null terminated user name of at most 16 characters
is retrieved on the initial socket.
This user name
is interpreted as a user identity to use on the
.Em server Ns 's
machine.
.It
A null terminated command to be passed to a
shell is retrieved on the initial socket.
The length of
the command is limited by the upper bound on the size of
the system's argument list.
.It
The
.Nm
utility then validates the user using
.Xr ruserok 3 ,
which uses the file
.Pa /etc/hosts.equiv
and the
.Pa .rhosts
file found in the user's home directory.
The
.Fl l
option prevents
.Xr ruserok 3
from doing any validation based on the user's
.Pa .rhosts
file,
unless the user is the superuser.
.It
A
.Tn NUL
byte is returned on the initial socket
and the command line is passed to the normal login
shell of the user.
The
shell inherits the network connections established
by
.Nm .
.El
.Pp
The options are as follows:
.Bl -tag -width indent
.It Fl a
This flag is ignored, and is present for compatibility purposes.
.It Fl D
Sets the TCP_NODELAY socket option, which improves the performance
of small back-to-back writes at the expense of additional network
traffic.
.It Fl L
Causes all successful accesses to be logged to
.Xr syslogd 8
as
.Li auth.info
messages.
.It Fl l
Do not use the user's
.Pa .rhosts
file for authentication, unless the user is the superuser.
.It Fl n
Turn off transport level keepalive messages.
This will prevent sessions
from timing out if the client crashes or becomes unreachable.
.El
.Sh FILES
.Bl -tag -width /var/run/nologin -compact
.It Pa /etc/hosts
.It Pa /etc/hosts.equiv
.It Pa /etc/login.conf
.It Ev $HOME Ns Pa /.rhosts
.Pp
.It Pa /etc/pam.conf
.Nm
uses
.Pa /etc/pam.conf
entries with service name
.Dq rsh .
Authentication modules requiring passwords (such as
.Nm pam_unix )
are not supported.
.El
.Sh DIAGNOSTICS
Except for the last one listed below,
all diagnostic messages
are returned on the initial socket,
after which any network connections are closed.
An error is indicated by a leading byte with a value of
1 (0 is returned in step 10 above upon successful completion
of all the steps prior to the execution of the login shell).
.Bl -tag -width indent
.It Sy Locuser too long.
The name of the user on the client's machine is
longer than 16 characters.
.It Sy Ruser too long.
The name of the user on the remote machine is
longer than 16 characters.
.It Sy Command too long.
The command line passed exceeds the size of the argument
list (as configured into the system).
.It Sy Login incorrect.
No password file entry for the user name existed
or the authentication procedure described above failed.
.It Sy Remote directory.
The
.Xr chdir 2
function to the home directory failed.
.It Sy Logins not available right now.
The
.Xr rsh 1
utility was attempted outside the allowed hours defined in
.Pa /etc/login.conf
for the local user's login class.
.It Sy Can't make pipe.
The pipe needed for the
.Em stderr ,
was not created.
.It Sy Can't fork; try again.
A
.Xr fork 2
by the server failed.
.It Sy <shellname>: ...
The user's login shell could not be started.
This message is returned
on the connection associated with the
.Em stderr ,
and is not preceded by a flag byte.
.El
.Sh SEE ALSO
.Xr rlogin 1 ,
.Xr rsh 1 ,
.Xr gethostbyaddr 3 ,
.Xr rcmd 3 ,
.Xr ruserok 3 ,
.Xr hosts 5 ,
.Xr hosts.equiv 5 ,
.Xr login.conf 5 ,
.Xr services 5 ,
.Xr named 8 ,
.Xr rlogind 8 ,
.Xr syslogd 8
.Sh HISTORY
IPv6 support was added by WIDE/KAME project.
.Sh BUGS
The authentication procedure used here assumes the integrity
of each client machine and the connecting medium.
This is
insecure, but is useful in an
.Dq open
environment.
.Pp
A facility to allow all data exchanges to be encrypted should be
present.
.Pp
Post-PAM,
.Fx
also needs the following patch applied besides properly configuring
.Pa .rhosts :
.Bd -literal -offset indent
--- etc/pam.d/rsh.orig Wed Dec 17 14:36:20 2003
+++ etc/pam.d/rsh Wed Dec 17 14:30:43 2003
@@ -9 +9 @@
-auth required pam_rhosts.so no_warn
+auth required pam_rhosts.so no_warn allow_root
.Ed
.Pp
A more extensible protocol (such as Telnet) should be used.

View File

@ -1,617 +0,0 @@
/*-
* Copyright (c) 1988, 1989, 1992, 1993, 1994
* The Regents of the University of California. All rights reserved.
* Copyright (c) 2002 Networks Associates Technology, Inc.
* All rights reserved.
*
* Portions of this software were developed for the FreeBSD Project by
* ThinkSec AS and NAI Labs, the Security Research Division of Network
* Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035
* ("CBOSS"), as part of the DARPA CHATS research program.
*
* 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.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
*/
#ifndef lint
static const char copyright[] =
"@(#) Copyright (c) 1988, 1989, 1992, 1993, 1994\n\
The Regents of the University of California. All rights reserved.\n";
#endif /* not lint */
#ifndef lint
#if 0
static const char sccsid[] = "@(#)rshd.c 8.2 (Berkeley) 4/6/94";
#endif
#endif /* not lint */
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
/*
* remote shell server:
* [port]\0
* ruser\0
* luser\0
* command\0
* data
*/
#include <sys/param.h>
#include <sys/ioctl.h>
#include <sys/time.h>
#include <sys/socket.h>
#include <netinet/in_systm.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <netinet/tcp.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <err.h>
#include <errno.h>
#include <fcntl.h>
#include <libutil.h>
#include <paths.h>
#include <pwd.h>
#include <signal.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <syslog.h>
#include <unistd.h>
#include <login_cap.h>
#include <security/pam_appl.h>
#include <security/openpam.h>
#include <sys/wait.h>
#ifdef USE_BLACKLIST
#include <blacklist.h>
#endif
static struct pam_conv pamc = { openpam_nullconv, NULL };
static pam_handle_t *pamh;
static int pam_err;
#define PAM_END { \
if ((pam_err = pam_setcred(pamh, PAM_DELETE_CRED)) != PAM_SUCCESS) \
syslog(LOG_ERR|LOG_AUTH, "pam_setcred(): %s", pam_strerror(pamh, pam_err)); \
if ((pam_err = pam_close_session(pamh,0)) != PAM_SUCCESS) \
syslog(LOG_ERR|LOG_AUTH, "pam_close_session(): %s", pam_strerror(pamh, pam_err)); \
if ((pam_err = pam_end(pamh, pam_err)) != PAM_SUCCESS) \
syslog(LOG_ERR|LOG_AUTH, "pam_end(): %s", pam_strerror(pamh, pam_err)); \
}
int keepalive = 1;
int log_success; /* If TRUE, log all successful accesses */
int sent_null;
int no_delay;
void doit(struct sockaddr *);
static void rshd_errx(int, const char *, ...) __printf0like(2, 3);
void getstr(char *, int, const char *);
int local_domain(char *);
char *topdomain(char *);
void usage(void);
char slash[] = "/";
char bshell[] = _PATH_BSHELL;
#define OPTIONS "aDLln"
int
main(int argc, char *argv[])
{
extern int __check_rhosts_file;
struct linger linger;
socklen_t fromlen;
int ch, on = 1;
struct sockaddr_storage from;
openlog("rshd", LOG_PID, LOG_DAEMON);
opterr = 0;
while ((ch = getopt(argc, argv, OPTIONS)) != -1)
switch (ch) {
case 'a':
/* ignored for compatibility */
break;
case 'l':
__check_rhosts_file = 0;
break;
case 'n':
keepalive = 0;
break;
case 'D':
no_delay = 1;
break;
case 'L':
log_success = 1;
break;
case '?':
default:
usage();
break;
}
argc -= optind;
argv += optind;
fromlen = sizeof (from);
if (getpeername(0, (struct sockaddr *)&from, &fromlen) < 0) {
syslog(LOG_ERR, "getpeername: %m");
exit(1);
}
if (keepalive &&
setsockopt(0, SOL_SOCKET, SO_KEEPALIVE, (char *)&on,
sizeof(on)) < 0)
syslog(LOG_WARNING, "setsockopt (SO_KEEPALIVE): %m");
linger.l_onoff = 1;
linger.l_linger = 60; /* XXX */
if (setsockopt(0, SOL_SOCKET, SO_LINGER, (char *)&linger,
sizeof (linger)) < 0)
syslog(LOG_WARNING, "setsockopt (SO_LINGER): %m");
if (no_delay &&
setsockopt(0, IPPROTO_TCP, TCP_NODELAY, &on, sizeof(on)) < 0)
syslog(LOG_WARNING, "setsockopt (TCP_NODELAY): %m");
doit((struct sockaddr *)&from);
/* NOTREACHED */
return(0);
}
extern char **environ;
void
doit(struct sockaddr *fromp)
{
extern char *__rcmd_errstr; /* syslog hook from libc/net/rcmd.c. */
struct passwd *pwd;
u_short port;
fd_set ready, readfrom;
int cc, nfd, pv[2], pid, s;
int one = 1;
const char *cp, *errorstr;
char sig, buf[BUFSIZ];
char *cmdbuf, luser[16], ruser[16];
char rhost[2 * MAXHOSTNAMELEN + 1];
char numericname[INET6_ADDRSTRLEN];
int af, srcport;
int maxcmdlen;
login_cap_t *lc;
maxcmdlen = (int)sysconf(_SC_ARG_MAX);
if (maxcmdlen <= 0 || (cmdbuf = malloc(maxcmdlen)) == NULL)
exit(1);
(void) signal(SIGINT, SIG_DFL);
(void) signal(SIGQUIT, SIG_DFL);
(void) signal(SIGTERM, SIG_DFL);
af = fromp->sa_family;
srcport = ntohs(*((in_port_t *)&fromp->sa_data));
if (af == AF_INET) {
inet_ntop(af, &((struct sockaddr_in *)fromp)->sin_addr,
numericname, sizeof numericname);
} else if (af == AF_INET6) {
inet_ntop(af, &((struct sockaddr_in6 *)fromp)->sin6_addr,
numericname, sizeof numericname);
} else {
syslog(LOG_ERR, "malformed \"from\" address (af %d)", af);
exit(1);
}
#ifdef IP_OPTIONS
if (af == AF_INET) {
u_char optbuf[BUFSIZ/3];
socklen_t optsize = sizeof(optbuf), ipproto, i;
struct protoent *ip;
if ((ip = getprotobyname("ip")) != NULL)
ipproto = ip->p_proto;
else
ipproto = IPPROTO_IP;
if (!getsockopt(0, ipproto, IP_OPTIONS, optbuf, &optsize) &&
optsize != 0) {
for (i = 0; i < optsize; ) {
u_char c = optbuf[i];
if (c == IPOPT_LSRR || c == IPOPT_SSRR) {
syslog(LOG_NOTICE,
"connection refused from %s with IP option %s",
numericname,
c == IPOPT_LSRR ? "LSRR" : "SSRR");
exit(1);
}
if (c == IPOPT_EOL)
break;
i += (c == IPOPT_NOP) ? 1 : optbuf[i+1];
}
}
}
#endif
if (srcport >= IPPORT_RESERVED ||
srcport < IPPORT_RESERVED/2) {
syslog(LOG_NOTICE|LOG_AUTH,
"connection from %s on illegal port %u",
numericname,
srcport);
#ifdef USE_BLACKLIST
blacklist(1, STDIN_FILENO, "illegal port");
#endif
exit(1);
}
(void) alarm(60);
port = 0;
s = 0; /* not set or used if port == 0 */
for (;;) {
char c;
if ((cc = read(STDIN_FILENO, &c, 1)) != 1) {
if (cc < 0)
syslog(LOG_NOTICE, "read: %m");
shutdown(0, SHUT_RDWR);
exit(1);
}
if (c == 0)
break;
port = port * 10 + c - '0';
}
(void) alarm(0);
if (port != 0) {
int lport = IPPORT_RESERVED - 1;
s = rresvport_af(&lport, af);
if (s < 0) {
syslog(LOG_ERR, "can't get stderr port: %m");
exit(1);
}
if (port >= IPPORT_RESERVED ||
port < IPPORT_RESERVED/2) {
syslog(LOG_NOTICE|LOG_AUTH,
"2nd socket from %s on unreserved port %u",
numericname,
port);
#ifdef USE_BLACKLIST
blacklist(1, STDIN_FILENO, "unreserved port");
#endif
exit(1);
}
*((in_port_t *)&fromp->sa_data) = htons(port);
if (connect(s, fromp, fromp->sa_len) < 0) {
syslog(LOG_INFO, "connect second port %d: %m", port);
exit(1);
}
}
errorstr = NULL;
realhostname_sa(rhost, sizeof(rhost) - 1, fromp, fromp->sa_len);
rhost[sizeof(rhost) - 1] = '\0';
/* XXX truncation! */
(void) alarm(60);
getstr(ruser, sizeof(ruser), "ruser");
getstr(luser, sizeof(luser), "luser");
getstr(cmdbuf, maxcmdlen, "command");
(void) alarm(0);
pam_err = pam_start("rsh", luser, &pamc, &pamh);
if (pam_err != PAM_SUCCESS) {
syslog(LOG_ERR|LOG_AUTH, "pam_start(): %s",
pam_strerror(pamh, pam_err));
#ifdef USE_BLACKLIST
blacklist(1, STDIN_FILENO, "login incorrect");
#endif
rshd_errx(1, "Login incorrect.");
}
if ((pam_err = pam_set_item(pamh, PAM_RUSER, ruser)) != PAM_SUCCESS ||
(pam_err = pam_set_item(pamh, PAM_RHOST, rhost)) != PAM_SUCCESS) {
syslog(LOG_ERR|LOG_AUTH, "pam_set_item(): %s",
pam_strerror(pamh, pam_err));
#ifdef USE_BLACKLIST
blacklist(1, STDIN_FILENO, "login incorrect");
#endif
rshd_errx(1, "Login incorrect.");
}
pam_err = pam_authenticate(pamh, 0);
if (pam_err == PAM_SUCCESS) {
if ((pam_err = pam_get_user(pamh, &cp, NULL)) == PAM_SUCCESS) {
strlcpy(luser, cp, sizeof(luser));
/* XXX truncation! */
}
pam_err = pam_acct_mgmt(pamh, 0);
}
if (pam_err != PAM_SUCCESS) {
syslog(LOG_INFO|LOG_AUTH,
"%s@%s as %s: permission denied (%s). cmd='%.80s'",
ruser, rhost, luser, pam_strerror(pamh, pam_err), cmdbuf);
#ifdef USE_BLACKLIST
blacklist(1, STDIN_FILENO, "permission denied");
#endif
rshd_errx(1, "Login incorrect.");
}
setpwent();
pwd = getpwnam(luser);
if (pwd == NULL) {
syslog(LOG_INFO|LOG_AUTH,
"%s@%s as %s: unknown login. cmd='%.80s'",
ruser, rhost, luser, cmdbuf);
#ifdef USE_BLACKLIST
blacklist(1, STDIN_FILENO, "unknown login");
#endif
if (errorstr == NULL)
errorstr = "Login incorrect.";
rshd_errx(1, errorstr, rhost);
}
lc = login_getpwclass(pwd);
if (pwd->pw_uid)
auth_checknologin(lc);
if (chdir(pwd->pw_dir) < 0) {
if (chdir("/") < 0 ||
login_getcapbool(lc, "requirehome", !!pwd->pw_uid)) {
syslog(LOG_INFO|LOG_AUTH,
"%s@%s as %s: no home directory. cmd='%.80s'",
ruser, rhost, luser, cmdbuf);
rshd_errx(0, "No remote home directory.");
}
pwd->pw_dir = slash;
}
if (lc != NULL && fromp->sa_family == AF_INET) { /*XXX*/
char remote_ip[MAXHOSTNAMELEN];
strlcpy(remote_ip, numericname, sizeof(remote_ip));
/* XXX truncation! */
if (!auth_hostok(lc, rhost, remote_ip)) {
syslog(LOG_INFO|LOG_AUTH,
"%s@%s as %s: permission denied (%s). cmd='%.80s'",
ruser, rhost, luser, __rcmd_errstr,
cmdbuf);
#ifdef USE_BLACKLIST
blacklist(1, STDIN_FILENO, "permission denied");
#endif
rshd_errx(1, "Login incorrect.");
}
if (!auth_timeok(lc, time(NULL)))
rshd_errx(1, "Logins not available right now");
}
/*
* PAM modules might add supplementary groups in
* pam_setcred(), so initialize them first.
* But we need to open the session as root.
*/
if (setusercontext(lc, pwd, pwd->pw_uid, LOGIN_SETGROUP) != 0) {
syslog(LOG_ERR, "setusercontext: %m");
exit(1);
}
if ((pam_err = pam_open_session(pamh, 0)) != PAM_SUCCESS) {
syslog(LOG_ERR, "pam_open_session: %s", pam_strerror(pamh, pam_err));
} else if ((pam_err = pam_setcred(pamh, PAM_ESTABLISH_CRED)) != PAM_SUCCESS) {
syslog(LOG_ERR, "pam_setcred: %s", pam_strerror(pamh, pam_err));
}
(void) write(STDERR_FILENO, "\0", 1);
sent_null = 1;
if (port) {
if (pipe(pv) < 0)
rshd_errx(1, "Can't make pipe.");
pid = fork();
if (pid == -1)
rshd_errx(1, "Can't fork; try again.");
if (pid) {
(void) close(0);
(void) close(1);
(void) close(2);
(void) close(pv[1]);
FD_ZERO(&readfrom);
FD_SET(s, &readfrom);
FD_SET(pv[0], &readfrom);
if (pv[0] > s)
nfd = pv[0];
else
nfd = s;
ioctl(pv[0], FIONBIO, (char *)&one);
/* should set s nbio! */
nfd++;
do {
ready = readfrom;
if (select(nfd, &ready, (fd_set *)0,
(fd_set *)0, (struct timeval *)0) < 0)
break;
if (FD_ISSET(s, &ready)) {
int ret;
ret = read(s, &sig, 1);
if (ret <= 0)
FD_CLR(s, &readfrom);
else
killpg(pid, sig);
}
if (FD_ISSET(pv[0], &ready)) {
errno = 0;
cc = read(pv[0], buf, sizeof(buf));
if (cc <= 0) {
shutdown(s, SHUT_RDWR);
FD_CLR(pv[0], &readfrom);
} else {
(void)write(s, buf, cc);
}
}
} while (FD_ISSET(s, &readfrom) ||
FD_ISSET(pv[0], &readfrom));
PAM_END;
exit(0);
}
(void) close(s);
(void) close(pv[0]);
dup2(pv[1], 2);
close(pv[1]);
}
else {
pid = fork();
if (pid == -1)
rshd_errx(1, "Can't fork; try again.");
if (pid) {
/* Parent. */
while (wait(NULL) > 0 || errno == EINTR)
/* nothing */ ;
PAM_END;
exit(0);
}
}
#ifdef USE_BLACKLIST
blacklist(0, STDIN_FILENO, "success");
#endif
closefrom(3);
if (setsid() == -1)
syslog(LOG_ERR, "setsid() failed: %m");
if (setlogin(pwd->pw_name) < 0)
syslog(LOG_ERR, "setlogin() failed: %m");
if (*pwd->pw_shell == '\0')
pwd->pw_shell = bshell;
(void) pam_setenv(pamh, "HOME", pwd->pw_dir, 1);
(void) pam_setenv(pamh, "SHELL", pwd->pw_shell, 1);
(void) pam_setenv(pamh, "USER", pwd->pw_name, 1);
(void) pam_setenv(pamh, "PATH", _PATH_DEFPATH, 1);
environ = pam_getenvlist(pamh);
(void) pam_end(pamh, pam_err);
cp = strrchr(pwd->pw_shell, '/');
if (cp)
cp++;
else
cp = pwd->pw_shell;
if (setusercontext(lc, pwd, pwd->pw_uid,
LOGIN_SETALL & ~LOGIN_SETGROUP) < 0) {
syslog(LOG_ERR, "setusercontext(): %m");
exit(1);
}
login_close(lc);
endpwent();
if (log_success || pwd->pw_uid == 0) {
syslog(LOG_INFO|LOG_AUTH, "%s@%s as %s: cmd='%.80s'",
ruser, rhost, luser, cmdbuf);
}
execl(pwd->pw_shell, cp, "-c", cmdbuf, (char *)NULL);
err(1, "%s", pwd->pw_shell);
exit(1);
}
/*
* Report error to client. Note: can't be used until second socket has
* connected to client, or older clients will hang waiting for that
* connection first.
*/
static void
rshd_errx(int errcode, const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
if (sent_null == 0)
write(STDERR_FILENO, "\1", 1);
verrx(errcode, fmt, ap);
/* NOTREACHED */
}
void
getstr(char *buf, int cnt, const char *error)
{
char c;
do {
if (read(STDIN_FILENO, &c, 1) != 1)
exit(1);
*buf++ = c;
if (--cnt == 0) {
#ifdef USE_BLACKLIST
blacklist(1, STDIN_FILENO, "buffer overflow");
#endif
rshd_errx(1, "%s too long", error);
}
} while (c != 0);
}
/*
* Check whether host h is in our local domain,
* defined as sharing the last two components of the domain part,
* or the entire domain part if the local domain has only one component.
* If either name is unqualified (contains no '.'),
* assume that the host is local, as it will be
* interpreted as such.
*/
int
local_domain(char *h)
{
char localhost[MAXHOSTNAMELEN];
char *p1, *p2;
localhost[0] = 0;
(void) gethostname(localhost, sizeof(localhost) - 1);
localhost[sizeof(localhost) - 1] = '\0';
/* XXX truncation! */
p1 = topdomain(localhost);
p2 = topdomain(h);
if (p1 == NULL || p2 == NULL || !strcasecmp(p1, p2))
return (1);
return (0);
}
char *
topdomain(char *h)
{
char *p, *maybe = NULL;
int dots = 0;
for (p = h + strlen(h); p >= h; p--) {
if (*p == '.') {
if (++dots == 2)
return (p);
maybe = p;
}
}
return (maybe);
}
void
usage(void)
{
syslog(LOG_ERR, "usage: rshd [-%s]", OPTIONS);
exit(2);
}

View File

@ -161,14 +161,18 @@ ports.txz:
${XZ_CMD} > ${.OBJDIR}/ports.txz
reldoc:
cd ${.CURDIR}/doc && ${MAKE} all install clean 'FORMATS=html txt' \
cd ${DOCDIR}/en_US.ISO8859-1/htdocs/releases/${REVISION}R && \
${MAKE} all install clean 'FORMATS=html txt' \
INSTALL_COMPRESSED='' URLS_ABSOLUTE=YES DOCDIR=${.OBJDIR}/rdoc
mkdir -p reldoc
.for i in hardware readme relnotes errata
ln -f rdoc/${RELNOTES_LANG}/${i}/article.txt reldoc/${i:tu}.TXT
ln -f rdoc/${RELNOTES_LANG}/${i}/article.html reldoc/${i:tu}.HTM
ln -f ${DOCDIR}/${RELNOTES_LANG}/htdocs/releases/${REVISION}R/${i}/${i:tl}.txt \
reldoc/${i:tu}.TXT
ln -f ${DOCDIR}/${RELNOTES_LANG}/htdocs/releases/${REVISION}R/${i}/${i:tl}.html \
reldoc/${i:tu}.HTM
.endfor
cp rdoc/${RELNOTES_LANG}/readme/docbook.css reldoc
cp ${DOCDIR}/${RELNOTES_LANG}/htdocs/releases/${REVISION}R/readme/docbook.css \
reldoc
disc1: packagesystem
# Install system

View File

@ -57,7 +57,7 @@ TLD?= ${FTPDIR}/releases
.endif
.if defined(EMBEDDED) && !empty(EMBEDDED)
. if ${TARGET:Marm*} != "" && (${TARGET_ARCH} == "armv6" || ${TARGET_ARCH} == "aarch64")
. if ${TARGET:Marm*} != "" && (${TARGET_ARCH:Marmv[67]} != "" || ${TARGET_ARCH} == "aarch64")
. if !defined(BOARDNAME) && empty(BOARDNAME)
BOARDNAME:= ${KERNCONF}
. else

View File

@ -5,11 +5,11 @@
EMBEDDEDBUILD=1
EMBEDDED_TARGET="arm"
EMBEDDED_TARGET_ARCH="armv6"
EMBEDDED_TARGET_ARCH="armv7"
EMBEDDEDPORTS="sysutils/u-boot-bananapi"
KERNEL="GENERIC"
WORLD_FLAGS="${WORLD_FLAGS} UBLDR_LOADADDR=0x42000000"
IMAGE_SIZE="1536M"
IMAGE_SIZE="2560M"
PART_SCHEME="MBR"
FAT_SIZE="32m -b 1m"
FAT_TYPE="16"

View File

@ -5,16 +5,17 @@
EMBEDDEDBUILD=1
EMBEDDED_TARGET="arm"
EMBEDDED_TARGET_ARCH="armv6"
EMBEDDED_TARGET_ARCH="armv7"
EMBEDDEDPORTS="sysutils/u-boot-beaglebone"
KERNEL="BEAGLEBONE"
KERNEL="GENERIC"
WORLD_FLAGS="${WORLD_FLAGS} UBLDR_LOADADDR=0x88000000"
IMAGE_SIZE="1536M"
IMAGE_SIZE="2560M"
PART_SCHEME="MBR"
FAT_SIZE="2m"
FAT_TYPE="12"
MD_ARGS="-x 63 -y 255"
NODOC=1
export BOARDNAME="BEAGLEBONE"
arm_install_uboot() {
UBOOT_DIR="/usr/local/share/u-boot/u-boot-beaglebone"

View File

@ -5,16 +5,17 @@
EMBEDDEDBUILD=1
EMBEDDED_TARGET="arm"
EMBEDDED_TARGET_ARCH="armv6"
EMBEDDED_TARGET_ARCH="armv7"
EMBEDDEDPORTS="sysutils/u-boot-cubieboard"
KERNEL="ALLWINNER_UP"
KERNEL="GENERIC"
WORLD_FLAGS="${WORLD_FLAGS} UBLDR_LOADADDR=0x42000000"
IMAGE_SIZE="1536M"
IMAGE_SIZE="2560M"
PART_SCHEME="MBR"
FAT_SIZE="32m -b 1m"
FAT_TYPE="16"
MD_ARGS="-x 63 -y 255"
NODOC=1
export BOARDNAME="CUBIEBOARD"
arm_install_uboot() {
UBOOT_DIR="/usr/local/share/u-boot/u-boot-cubieboard"

View File

@ -5,11 +5,11 @@
EMBEDDEDBUILD=1
EMBEDDED_TARGET="arm"
EMBEDDED_TARGET_ARCH="armv6"
EMBEDDED_TARGET_ARCH="armv7"
EMBEDDEDPORTS="sysutils/u-boot-cubieboard2"
KERNEL="GENERIC"
WORLD_FLAGS="${WORLD_FLAGS} UBLDR_LOADADDR=0x42000000"
IMAGE_SIZE="1536M"
IMAGE_SIZE="2560M"
PART_SCHEME="MBR"
FAT_SIZE="32m -b 1m"
FAT_TYPE="16"

View File

@ -5,11 +5,11 @@
EMBEDDEDBUILD=1
EMBEDDED_TARGET="arm"
EMBEDDED_TARGET_ARCH="armv6"
EMBEDDED_TARGET_ARCH="armv7"
EMBEDDEDPORTS="sysutils/u-boot-cubox-hummingboard"
KERNEL="IMX6"
WORLD_FLAGS="${WORLD_FLAGS} UBLDR_LOADADDR=0x12000000"
IMAGE_SIZE="1536M"
IMAGE_SIZE="2560M"
PART_SCHEME="MBR"
FAT_SIZE="50m -b 16384"
FAT_TYPE="16"

View File

@ -9,7 +9,7 @@ EMBEDDED_TARGET_ARCH="armv6"
EMBEDDEDPORTS="sysutils/u-boot-duovero"
KERNEL="GUMSTIX"
WORLD_FLAGS="${WORLD_FLAGS} UBLDR_LOADADDR=0x88000000"
IMAGE_SIZE="1536M"
IMAGE_SIZE="2560M"
PART_SCHEME="MBR"
FAT_SIZE="2m"
FAT_TYPE="12"

View File

@ -5,16 +5,17 @@
EMBEDDEDBUILD=1
EMBEDDED_TARGET="arm"
EMBEDDED_TARGET_ARCH="armv6"
EMBEDDED_TARGET_ARCH="armv7"
EMBEDDEDPORTS="sysutils/u-boot-pandaboard"
KERNEL="PANDABOARD"
KERNEL="GENERIC"
WORLD_FLAGS="${WORLD_FLAGS} UBLDR_LOADADDR=0x88000000"
IMAGE_SIZE="1536M"
IMAGE_SIZE="2560M"
PART_SCHEME="MBR"
FAT_SIZE="2m"
FAT_TYPE="12"
MD_ARGS="-x 63 -y 255"
NODOC=1
export BOARDNAME="PANDABOARD"
arm_install_uboot() {
UBOOT_DIR="/usr/local/share/u-boot/u-boot-pandaboard"

View File

@ -9,7 +9,7 @@ EMBEDDED_TARGET_ARCH="armv6"
EMBEDDEDPORTS="sysutils/u-boot-rpi"
KERNEL="RPI-B"
WORLD_FLAGS="${WORLD_FLAGS} UBLDR_LOADADDR=0x2000000"
IMAGE_SIZE="1536M"
IMAGE_SIZE="2560M"
PART_SCHEME="MBR"
FAT_SIZE="17m"
FAT_TYPE="16"

View File

@ -5,11 +5,11 @@
EMBEDDEDBUILD=1
EMBEDDED_TARGET="arm"
EMBEDDED_TARGET_ARCH="armv6"
EMBEDDED_TARGET_ARCH="armv7"
EMBEDDEDPORTS="sysutils/u-boot-rpi2"
KERNEL="GENERIC"
WORLD_FLAGS="${WORLD_FLAGS} UBLDR_LOADADDR=0x2000000"
IMAGE_SIZE="1536M"
IMAGE_SIZE="2560M"
PART_SCHEME="MBR"
FAT_SIZE="50m"
FAT_TYPE="16"

View File

@ -5,7 +5,7 @@
EMBEDDEDBUILD=1
EMBEDDED_TARGET="arm"
EMBEDDED_TARGET_ARCH="armv6"
EMBEDDED_TARGET_ARCH="armv7"
EMBEDDEDPORTS="sysutils/u-boot-wandboard"
KERNEL="IMX6"
WORLD_FLAGS="${WORLD_FLAGS} UBLDR_LOADADDR=0x12000000"

View File

@ -1,38 +0,0 @@
# $FreeBSD$
#
# The user can override the default language to build and install
# with the RELNOTES_LANG variable.
#
.if defined(RELNOTES_LANG) && !empty(RELNOTES_LANG)
SUBDIR+= ${RELNOTES_LANG}
.else
SUBDIR+= en_US.ISO8859-1
.endif
SUBDIR+= share/xml
RELN_ROOT?= ${.CURDIR}
.if exists(/usr/local/bin/svn)
SVN?= /usr/local/bin/svn
.elif exists(/usr/bin/svn)
SVN?= /usr/bin/svn
.else
SVN?= /usr/bin/svnlite
.endif
SVNFLAGS?= -r HEAD
update:
.if !exists(${SVN})
@echo "--------------------------------------------------------------"
@echo ">>> Updating ${RELN_ROOT} requires ${SVN}."
@echo "--------------------------------------------------------------"
@exit 1
.endif
@echo "--------------------------------------------------------------"
@echo ">>> Updating ${.CURDIR}"
@echo "--------------------------------------------------------------"
@(cd ${.CURDIR} && ${SVN} update ${SVNFLAGS})
.include "${RELN_ROOT}/share/mk/doc.relnotes.mk"
.include "${DOC_PREFIX}/share/mk/doc.subdir.mk"

View File

@ -1,127 +0,0 @@
-*- text -*-
RELNOTESng README
Bruce A. Mah <bmah@freebsd.org>
$FreeBSD$
This is the top-level directory for RELNOTESng, a re-write of
FreeBSD's *.TXT documentation files. They have been converted to
DocBook, and versions of the documents can be now be built for various
supported architectures. The output files can be rendered in any
format supported by the FreeBSD Documentation Project (for example,
ASCII text, PDF, PS, HTML).
RELNOTESng requires that the FreeBSD doc/ sources are installed; it
leverages off of much of the DocProj build infrastructure, including
DocBook extensions and stylesheets. If the doc/ sources are not
installed in /usr/src, their location should be specified with the
DOC_PREFIX Makefile variable. RELNOTESng also requires the DocProj
build tools, which can easily be installed with the textproc/docproj
port in the Ports Collection.
Notable files and directories:
share/mk/doc.relnotes.mk
Common Makefile definitions for RELNOTESng. These definitions
mostly accommodate the fact that we're building DocProj-like
documents outside the doc/ tree.
share/xml/catalog
Main SGML catalog for all language-neutral (and default EN)
stylesheet and entity files. Can be overridden if needed for
translations.
share/xml/default.dsl
All documents build with this file as a stylesheet. All it
does is to make it possible to use the document catalogs to
locate the "real" stylesheet by reference, rather than having
to specify it by pathname.
share/xml/release.dsl
Language-neutral stylesheet. This stylesheet supports
the arch= attribute on (all?) DocBook elements; elements with
an arch= attribute are only included in the output if their
value is equal to the value of the &arch; entity. In the
future, arch= could be a list of possible &arch; entity values
that match, such as "i386,sparc64".
share/xml/release.ent
Release information. Need to update the entry definitions in
this file when rolling new revisions; these should take effect
in all documents.
en_US.ISO8859-1/share/xml/release.dsl
Language-dependent stylesheet for en, but also the default for
translations if they don't override the settings here. This
stylesheet sets the email footer at the bottom of HTML pages,
as well as a few other parameters. If necessary for
translations, this file can be overridden with
*/share/xml/release.dsl and */share/xml/catalog.
*/relnotes/common/
Directory for multi-architecture release notes files.
*/relnotes/*/
Directories for architecture-specific release notes files.
*/hardware/common/
Directory for multi-architecture hardware notes files.
*/hardware/*/
Directories for architecture-specific hardware notes files.
*/installation/common/
Directory for multi-architecture installation notes files.
Note that the FreeBSD DocProj build infrastructure does
not handle documents (or subdirectories) named "install"
well, so we call our document "installation" and do
a hack when it gets installed into a distribution to fix
this up.
*/installation/*/
Directories for architecture-specific release notes files.
*/errata/
Directory for errata document.
*/readme/
Directory for (introductory) document.
If building the release notes "standalone" (in other words, not part
of a release), it may be necessary (depending on the relative
locations of the checked-out src/ and doc/ directories) to set the
DOC_PREFIX Makefile variable to point to the top directory of the doc/
tree. For example:
% make DOC_PREFIX=/usr/doc all
All definition of the "current" version of FreeBSD is contained in the
share/xml/release.ent file; release engineers should peruse the
contents of this file carefully when doing version number bumps.
When creating content for the architecture-dependent files, authors
should use the arch= attribute to elements that are specific to a
particular machine architecture. The value of this attribute should
be a single word that indicates for which architecture the current
element will be included. For example:
<para arch="sparc64">SPARC64-specific text</para>
The currently-supported architectures are amd64, arm, i386,
powerpc and sparc64. An element may appear for multiple architectures
by specifying a comma-separated list of architectures
(i.e. arch="sparc64,amd64").
When creating a translation, make a new directory under this
directory with a language code (paralleling the DocProj directory
structure). If necessary, new language-dependent HTML footers can be
generated by making a new language-dependent
${LANG}/share/xml/release.dsl, a ${LANG}/share/xml/catalog that
points to it, and a new definition in the Makefiles that adds
${LANG}/share/xml/catalog to EXTRA_CATALOGS. Except for the Makefile
changes, this is the same procedure that is used for creating a new
translation for DocProj files.
RELNOTESng is now enabled by default in the FreeBSD release-build
process. It can be disabled by setting NODOC=YES when building a
release (note that this is the same variable that disables DocProj
documentation builds).
Release builders can set which language gets built with the
RELNOTES_LANG variable; note that this is different from the
DOC_LANG variable because (at least initially) most languages
will have localized DocProj files but not localized release notes.
The default language, if none is specified, is en_US.ISO8859-1.

View File

@ -1,16 +0,0 @@
# $FreeBSD$
RELN_ROOT?= ${.CURDIR}/..
SUBDIR = relnotes
SUBDIR+= hardware
SUBDIR+= readme
SUBDIR+= errata
COMPAT_SYMLINK = en
LANGCODE=en_US.ISO8859-1
_LANGCODE=en_US.ISO8859-1
.include "${RELN_ROOT}/share/mk/doc.relnotes.mk"
.include "${DOC_PREFIX}/share/mk/doc.project.mk"

View File

@ -1,19 +0,0 @@
# $FreeBSD$
RELN_ROOT?= ${.CURDIR}/../..
.ifdef NO_LANGCODE_IN_DESTDIR
DESTDIR?= ${DOCDIR}/errata
.else
DESTDIR?= ${DOCDIR}/en_US.ISO8859-1/errata
.endif
DOC?= article
FORMATS?= html
INSTALL_COMPRESSED?= gz
INSTALL_ONLY_COMPRESSED?=
# SGML content
SRCS+= article.xml
.include "${RELN_ROOT}/share/mk/doc.relnotes.mk"
.include "${DOC_PREFIX}/share/mk/doc.project.mk"

View File

@ -1,100 +0,0 @@
<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE article PUBLIC "-//FreeBSD//DTD DocBook XML V5.0-Based Extension//EN"
"http://www.FreeBSD.org/XML/share/xml/freebsd50.dtd" [
<!ENTITY % release PUBLIC "-//FreeBSD//ENTITIES Release Specification//EN"
"http://www.FreeBSD.org/release/XML/release.ent">
%release;
<!ENTITY security SYSTEM "../../share/xml/security.xml">
<!ENTITY errata SYSTEM "../../share/xml/errata.xml">
]>
<article xmlns="http://docbook.org/ns/docbook"
xmlns:xlink="http://www.w3.org/1999/xlink"
version="5.0">
<info>
<title>&os; &release; Errata </title>
<author><orgname>The &os; Project</orgname></author>
<pubdate>$FreeBSD$</pubdate>
<copyright>
<year>2015</year>
<holder role="mailto:doc@FreeBSD.org">The &os; Documentation Project</holder>
</copyright>
<legalnotice xml:id="trademarks" role="trademarks">
&tm-attrib.freebsd;
&tm-attrib.intel;
&tm-attrib.sparc;
&tm-attrib.general;
</legalnotice>
<abstract>
<para>This document lists errata items for &os; &release;,
containing significant information discovered after the release
or too late in the release cycle to be otherwise included in the
release documentation.
This information includes security advisories, as well as news
relating to the software or documentation that could affect its
operation or usability. An up-to-date version of this document
should always be consulted before installing this version of
&os;.</para>
<para>This errata document for &os; &release;
will be maintained until the release of &os; &release.next;.</para>
</abstract>
</info>
<sect1 xml:id="intro">
<title>Introduction</title>
<para>This errata document contains <quote>late-breaking news</quote>
about &os; &release;
Before installing this version, it is important to consult this
document to learn about any post-release discoveries or problems
that may already have been found and fixed.</para>
<para>Any version of this errata document actually distributed
with the release (for example, on a CDROM distribution) will be
out of date by definition, but other copies are kept updated on
the Internet and should be consulted as the <quote>current
errata</quote> for this release. These other copies of the
errata are located at
<link xlink:href="https://www.FreeBSD.org/releases/" />,
plus any sites
which keep up-to-date mirrors of this location.</para>
<para>Source and binary snapshots of &os; &release.branch; also
contain up-to-date copies of this document (as of the time of
the snapshot).</para>
<para>For a list of all &os; CERT security advisories, see
<link xlink:href="https://www.FreeBSD.org/security/"/>.</para>
</sect1>
<sect1 xml:id="security">
<title>Security Advisories</title>
&security;
</sect1>
<sect1 xml:id="errata">
<title>Errata Notices</title>
&errata;
</sect1>
<sect1 xml:id="open-issues">
<title>Open Issues</title>
<para>No open issues.</para>
</sect1>
<sect1 xml:id="late-news">
<title>Late-Breaking News</title>
<para>No news.</para>
</sect1>
</article>

Some files were not shown because too many files have changed in this diff Show More