integrate from head@185615

This commit is contained in:
Dag-Erling Smørgrav 2008-12-04 18:48:08 +00:00
commit e57c2b130f
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/projects/quota64/; revision=185617
2611 changed files with 410075 additions and 272053 deletions

View file

@ -15,10 +15,10 @@ are met:
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 AUTHOR AND CONTRIBUTORS ``AS IS'' AND
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 AUTHOR OR CONTRIBUTORS BE LIABLE
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)

View file

@ -267,6 +267,10 @@ make: .PHONY
${MMAKE} all && \
${MMAKE} install DESTDIR=${MAKEPATH} BINDIR=
tinderbox:
cd ${.CURDIR} && \
DOING_TINDERBOX=YES ${MAKE} ${JFLAG} universe
#
# universe
#
@ -274,14 +278,24 @@ make: .PHONY
# with a reasonable chance of success, regardless of how old your
# existing system is.
#
.if make(universe)
.if make(universe) || make(tinderbox)
TARGETS?=amd64 arm i386 ia64 pc98 powerpc sparc64 sun4v
.if defined(DOING_TINDERBOX)
FAILFILE=tinderbox.failed
MAKEFAIL=tee -a ${FAILFILE}
.else
MAKEFAIL=cat
.endif
universe: universe_prologue
universe_prologue:
@echo "--------------------------------------------------------------"
@echo ">>> make universe started on ${STARTTIME}"
@echo "--------------------------------------------------------------"
.if defined(DOING_TINDERBOX)
rm -f ${FAILFILE}
.endif
.for target in ${TARGETS}
KERNCONFS!= cd ${.CURDIR}/sys/${target}/conf && \
find [A-Z]*[A-Z] -type f -maxdepth 0 \
@ -292,22 +306,28 @@ universe: universe_${target}
universe_${target}:
.if !defined(MAKE_JUST_KERNELS)
@echo ">> ${target} started on `LC_ALL=C date`"
-cd ${.CURDIR} && ${MAKE} ${JFLAG} buildworld \
@(cd ${.CURDIR} && env __MAKE_CONF=/dev/null \
${MAKE} ${JFLAG} buildworld \
TARGET=${target} \
__MAKE_CONF=/dev/null \
> _.${target}.buildworld 2>&1
> _.${target}.buildworld 2>&1 || \
(echo "${target} world failed," \
"check _.${target}.buildworld for details" | ${MAKEFAIL}))
@echo ">> ${target} buildworld completed on `LC_ALL=C date`"
.endif
.if exists(${.CURDIR}/sys/${target}/conf/NOTES)
-cd ${.CURDIR}/sys/${target}/conf && ${MAKE} LINT \
> ${.CURDIR}/_.${target}.makeLINT 2>&1
@(cd ${.CURDIR}/sys/${target}/conf && env __MAKE_CONF=/dev/null \
${MAKE} LINT > ${.CURDIR}/_.${target}.makeLINT 2>&1 || \
(echo "${target} 'make LINT' failed," \
"check _.${target}.makeLINT for details"| ${MAKEFAIL}))
.endif
.for kernel in ${KERNCONFS}
-cd ${.CURDIR} && ${MAKE} ${JFLAG} buildkernel \
@(cd ${.CURDIR} && env __MAKE_CONF=/dev/null \
${MAKE} ${JFLAG} buildkernel \
TARGET=${target} \
KERNCONF=${kernel} \
__MAKE_CONF=/dev/null \
> _.${target}.${kernel} 2>&1
> _.${target}.${kernel} 2>&1 || \
(echo "${target} ${kernel} kernel failed," \
"check _.${target}.${kernel} for details"| ${MAKEFAIL}))
.endfor
@echo ">> ${target} completed on `LC_ALL=C date`"
.endfor
@ -317,4 +337,11 @@ universe_epilogue:
@echo ">>> make universe completed on `LC_ALL=C date`"
@echo " (started ${STARTTIME})"
@echo "--------------------------------------------------------------"
.if defined(DOING_TINDERBOX)
@if [ -e ${FAILFILE} ] ; then \
echo "Tinderbox failed:" ;\
cat ${FAILFILE} ;\
exit 1 ;\
fi
.endif
.endif

View file

@ -505,6 +505,9 @@ distribute32 install32:
cd ${.CURDIR}/gnu/lib; ${LIB32IMAKE} ${.TARGET:S/32$//}
.if ${MK_CRYPT} != "no"
cd ${.CURDIR}/secure/lib; ${LIB32IMAKE} ${.TARGET:S/32$//}
.endif
.if ${MK_KERBEROS} != "no"
cd ${.CURDIR}/kerberos5/lib; ${LIB32IMAKE} ${.TARGET:S/32$//}
.endif
cd ${.CURDIR}/libexec/rtld-elf; \
PROG=ld-elf32.so.1 ${LIB32IMAKE} ${.TARGET:S/32$//}

View file

@ -14,6 +14,11 @@
# The file is partitioned: OLD_FILES first, then OLD_LIBS and OLD_DIRS last.
#
# 20081123: vfs_mountedon.9 removed
OLD_FILES+=usr/share/man/man9/vfs_mountedon.9.gz
# 20081023: FREE.9 and MALLOC.9 removed
OLD_FILES+=usr/share/man/man9/FREE.9.gz
OLD_FILES+=usr/share/man/man9/MALLOC.9.gz
# 20080928: removal of inaccurate device_ids(9) manual page
OLD_FILES+=usr/share/man/man9/device_ids.9.gz
OLD_FILES+=usr/share/man/man9/major.9.gz

View file

@ -22,6 +22,38 @@ NOTE TO PEOPLE WHO THINK THAT FreeBSD 8.x IS SLOW:
to maximize performance. (To disable malloc debugging, run
ln -s aj /etc/malloc.conf.)
20081130:
__FreeBSD_version 800057 marks the switchover from the
binary ath hal to source code. Users must add the line:
options AH_SUPPORT_AR5416
to their kernel config files when specifying:
device ath_hal
The ath_hal module no longer exists; the code is now compiled
together with the driver in the ath module. It is now
possible to tailor chip support (i.e. reduce the set of chips
and thereby the code size); consult ath_hal(4) for details.
20081121:
__FreeBSD_version 800054 adds memory barriers to
<machine/atomic.h>, new interfaces to ifnet to facilitate
multiple hardware transmit queues for cards that support
them, and a lock-less ring-buffer implementation to
enable drivers to more efficiently manage queueing of
packets.
20081117:
A new version of ZFS (version 13) has been merged to -HEAD.
This version has zpool attribute "listsnapshots" off by
default, which means "zfs list" does not show snapshots,
and is the same as Solaris behavior.
20081028:
dummynet(4) ABI has changed. ipfw(8) needs to be recompiled.
20081009:
The uhci, ohci, ehci and slhci USB Host controller drivers have
been put into separate modules. If you load the usb module

View file

@ -77,6 +77,17 @@ static void raw_cat(int);
static int udom_open(const char *path, int flags);
#endif
/* Memory strategy threshold, in pages: if physmem is larger then this, use a
* large buffer */
#define PHYSPAGES_THRESHOLD (32*1024)
/* Maximum buffer size in bytes - do not allow it to grow larger than this */
#define BUFSIZE_MAX (2*1024*1024)
/* Small (default) buffer size in bytes. It's inefficient for this to be
* smaller than MAXPHYS */
#define BUFSIZE_SMALL (MAXPHYS)
int
main(int argc, char *argv[])
{
@ -247,9 +258,17 @@ raw_cat(int rfd)
if (buf == NULL) {
if (fstat(wfd, &sbuf))
err(1, "%s", filename);
bsize = MAX(sbuf.st_blksize, 1024);
if (S_ISREG(sbuf.st_mode)) {
/* If there's plenty of RAM, use a large copy buffer */
if (sysconf(_SC_PHYS_PAGES) > PHYSPAGES_THRESHOLD)
bsize = MIN(BUFSIZE_MAX, MAXPHYS*8);
else
bsize = BUFSIZE_SMALL;
} else
bsize = MAX(sbuf.st_blksize,
(blksize_t)sysconf(_SC_PAGESIZE));
if ((buf = malloc(bsize)) == NULL)
err(1, "buffer");
err(1, "malloc() failure of IO buffer");
}
while ((nr = read(rfd, buf, bsize)) > 0)
for (off = 0; nr; nr -= nw, off += nw)

View file

@ -69,7 +69,7 @@ static const char *bits_to_string(ces_status_flags, const char *);
static void find_element(char *, uint16_t *, uint16_t *);
static struct changer_element_status *get_element_status
(unsigned int, unsigned int);
(unsigned int, unsigned int, int);
static int do_move(const char *, int, char **);
static int do_exchange(const char *, int, char **);
@ -969,7 +969,8 @@ do_return(const char *cname, int argc, char **argv)
++argv; --argc;
/* Get the status */
ces = get_element_status((unsigned int)type, (unsigned int)element);
ces = get_element_status((unsigned int)type, (unsigned int)element,
CHET_VT == type);
if (NULL == ces)
errx(1, "%s: null element status pointer", cname);
@ -1004,7 +1005,7 @@ do_return(const char *cname, int argc, char **argv)
* should free() it when done.
*/
static struct changer_element_status *
get_element_status(unsigned int type, unsigned int element)
get_element_status(unsigned int type, unsigned int element, int use_voltags)
{
struct changer_element_status_request cesr;
struct changer_element_status *ces;
@ -1020,7 +1021,8 @@ get_element_status(unsigned int type, unsigned int element)
cesr.cesr_element_type = (uint16_t)type;
cesr.cesr_element_base = (uint16_t)element;
cesr.cesr_element_count = 1; /* Only this one element */
cesr.cesr_flags |= CESR_VOLTAGS; /* Grab voltags as well */
if (use_voltags)
cesr.cesr_flags |= CESR_VOLTAGS; /* Grab voltags as well */
cesr.cesr_element_status = ces;
if (ioctl(changer_fd, CHIOGSTATUS, (char *)&cesr) == -1) {

View file

@ -57,10 +57,22 @@ __FBSDID("$FreeBSD$");
#define cp_pct(x, y) ((y == 0) ? 0 : (int)(100.0 * (x) / (y)))
/* Memory strategy threshold, in pages: if physmem is larger then this, use a
* large buffer */
#define PHYSPAGES_THRESHOLD (32*1024)
/* Maximum buffer size in bytes - do not allow it to grow larger than this */
#define BUFSIZE_MAX (2*1024*1024)
/* Small (default) buffer size in bytes. It's inefficient for this to be
* smaller than MAXPHYS */
#define BUFSIZE_SMALL (MAXPHYS)
int
copy_file(const FTSENT *entp, int dne)
{
static char buf[MAXBSIZE];
static char *buf = NULL;
static size_t bufsize;
struct stat *fs;
ssize_t wcount;
size_t wresid;
@ -137,47 +149,60 @@ copy_file(const FTSENT *entp, int dne)
* Mmap and write if less than 8M (the limit is so we don't totally
* trash memory on big files. This is really a minor hack, but it
* wins some CPU back.
* Some filesystems, such as smbnetfs, don't support mmap,
* so this is a best-effort attempt.
*/
#ifdef VM_AND_BUFFER_CACHE_SYNCHRONIZED
if (S_ISREG(fs->st_mode) && fs->st_size > 0 &&
fs->st_size <= 8 * 1048576) {
if ((p = mmap(NULL, (size_t)fs->st_size, PROT_READ,
MAP_SHARED, from_fd, (off_t)0)) == MAP_FAILED) {
fs->st_size <= 8 * 1024 * 1024 &&
(p = mmap(NULL, (size_t)fs->st_size, PROT_READ,
MAP_SHARED, from_fd, (off_t)0)) != MAP_FAILED) {
wtotal = 0;
for (bufp = p, wresid = fs->st_size; ;
bufp += wcount, wresid -= (size_t)wcount) {
wcount = write(to_fd, bufp, wresid);
if (wcount <= 0)
break;
wtotal += wcount;
if (info) {
info = 0;
(void)fprintf(stderr,
"%s -> %s %3d%%\n",
entp->fts_path, to.p_path,
cp_pct(wtotal, fs->st_size));
}
if (wcount >= (ssize_t)wresid)
break;
}
if (wcount != (ssize_t)wresid) {
warn("%s", to.p_path);
rval = 1;
}
/* Some systems don't unmap on close(2). */
if (munmap(p, fs->st_size) < 0) {
warn("%s", entp->fts_path);
rval = 1;
} else {
wtotal = 0;
for (bufp = p, wresid = fs->st_size; ;
bufp += wcount, wresid -= (size_t)wcount) {
wcount = write(to_fd, bufp, wresid);
if (wcount <= 0)
break;
wtotal += wcount;
if (info) {
info = 0;
(void)fprintf(stderr,
"%s -> %s %3d%%\n",
entp->fts_path, to.p_path,
cp_pct(wtotal, fs->st_size));
}
if (wcount >= (ssize_t)wresid)
break;
}
if (wcount != (ssize_t)wresid) {
warn("%s", to.p_path);
rval = 1;
}
/* Some systems don't unmap on close(2). */
if (munmap(p, fs->st_size) < 0) {
warn("%s", entp->fts_path);
rval = 1;
}
}
} else
#endif
{
if (buf == NULL) {
/*
* Note that buf and bufsize are static. If
* malloc() fails, it will fail at the start
* and not copy only some files.
*/
if (sysconf(_SC_PHYS_PAGES) >
PHYSPAGES_THRESHOLD)
bufsize = MIN(BUFSIZE_MAX, MAXPHYS * 8);
else
bufsize = BUFSIZE_SMALL;
buf = malloc(bufsize);
if (buf == NULL)
err(1, "Not enough memory");
}
wtotal = 0;
while ((rcount = read(from_fd, buf, MAXBSIZE)) > 0) {
while ((rcount = read(from_fd, buf, bufsize)) > 0) {
for (bufp = buf, wresid = rcount; ;
bufp += wcount, wresid -= wcount) {
wcount = write(to_fd, bufp, wresid);

View file

@ -29,7 +29,7 @@
.\" @(#)df.1 8.3 (Berkeley) 5/8/95
.\" $FreeBSD$
.\"
.Dd April 22, 2004
.Dd November 23, 2008
.Dt DF 1
.Os
.Sh NAME
@ -38,7 +38,7 @@
.Sh SYNOPSIS
.Nm
.Op Fl b | g | H | h | k | m | P
.Op Fl aciln
.Op Fl acilnT
.Op Fl t Ar type
.Op Ar file | filesystem ...
.Sh DESCRIPTION
@ -140,6 +140,8 @@ The
.Xr lsvfs 1
command can be used to find out the types of file systems
that are available on the system.
.It Fl T
Include file system type.
.El
.Sh ENVIRONMENT
.Bl -tag -width BLOCKSIZE

View file

@ -68,6 +68,7 @@ __FBSDID("$FreeBSD$");
/* Maximum widths of various fields. */
struct maxwidths {
int mntfrom;
int fstype;
int total;
int used;
int avail;
@ -93,7 +94,7 @@ imax(int a, int b)
return (a > b ? a : b);
}
static int aflag = 0, cflag, hflag, iflag, kflag, lflag = 0, nflag;
static int aflag = 0, cflag, hflag, iflag, kflag, lflag = 0, nflag, Tflag;
static struct ufs_args mdev;
int
@ -115,7 +116,7 @@ main(int argc, char *argv[])
totalbuf.f_bsize = DEV_BSIZE;
strlcpy(totalbuf.f_mntfromname, "total", MNAMELEN);
vfslist = NULL;
while ((ch = getopt(argc, argv, "abcgHhiklmnPt:")) != -1)
while ((ch = getopt(argc, argv, "abcgHhiklmnPt:T")) != -1)
switch (ch) {
case 'a':
aflag = 1;
@ -176,6 +177,9 @@ main(int argc, char *argv[])
fstype = optarg;
vfslist = makevfslist(optarg);
break;
case 'T':
Tflag = 1;
break;
case '?':
default:
usage();
@ -391,6 +395,7 @@ prtstat(struct statfs *sfsp, struct maxwidths *mwp)
if (++timesthrough == 1) {
mwp->mntfrom = imax(mwp->mntfrom, (int)strlen("Filesystem"));
mwp->fstype = imax(mwp->fstype, (int)strlen("Type"));
if (hflag) {
header = " Size";
mwp->total = mwp->used = mwp->avail =
@ -402,8 +407,10 @@ prtstat(struct statfs *sfsp, struct maxwidths *mwp)
mwp->used = imax(mwp->used, (int)strlen("Used"));
mwp->avail = imax(mwp->avail, (int)strlen("Avail"));
(void)printf("%-*s %-*s %*s %*s Capacity",
mwp->mntfrom, "Filesystem", mwp->total, header,
(void)printf("%-*s", mwp->mntfrom, "Filesystem");
if (Tflag)
(void)printf(" %-*s", mwp->fstype, "Type");
(void)printf(" %-*s %*s %*s Capacity", mwp->total, header,
mwp->used, "Used", mwp->avail, "Avail");
if (iflag) {
mwp->iused = imax(mwp->iused, (int)strlen(" iused"));
@ -414,6 +421,8 @@ prtstat(struct statfs *sfsp, struct maxwidths *mwp)
(void)printf(" Mounted on\n");
}
(void)printf("%-*s", mwp->mntfrom, sfsp->f_mntfromname);
if (Tflag)
(void)printf(" %-*s", mwp->fstype, sfsp->f_fstypename);
used = sfsp->f_blocks - sfsp->f_bfree;
availblks = sfsp->f_bavail + used;
if (hflag) {
@ -468,6 +477,7 @@ update_maxwidths(struct maxwidths *mwp, const struct statfs *sfsp)
getbsize(&dummy, &blocksize);
mwp->mntfrom = imax(mwp->mntfrom, (int)strlen(sfsp->f_mntfromname));
mwp->fstype = imax(mwp->fstype, (int)strlen(sfsp->f_fstypename));
mwp->total = imax(mwp->total, int64width(
fsbtoblk((int64_t)sfsp->f_blocks, sfsp->f_bsize, blocksize)));
mwp->used = imax(mwp->used,
@ -505,7 +515,7 @@ usage(void)
{
(void)fprintf(stderr,
"usage: df [-b | -g | -H | -h | -k | -m | -P] [-aciln] [-t type] [file | filesystem ...]\n");
"usage: df [-b | -g | -H | -h | -k | -m | -P] [-acilnT] [-t type] [file | filesystem ...]\n");
exit(EX_USAGE);
}

View file

@ -196,9 +196,8 @@ tdnam(KINFO *k, VARENT *ve)
v = ve->var;
if (showthreads && k->ki_p->ki_numthreads > 1)
(void)printf("%-*s", v->width, k->ki_p->ki_ocomm);
else
(void)printf("%-*s", v->width, " " );
else
(void)printf("%-*s", v->width, " ");
}
void

View file

@ -789,6 +789,4 @@ run_err(const char *fmt, ...)
vwarnx(fmt, ap);
va_end(ap);
}
va_end(ap);
}

View file

@ -791,6 +791,7 @@ evalcommand(union node *cmd, int flags, struct backcmd *backcmd)
for (sp = varlist.list ; sp ; sp = sp->next)
mklocal(sp->text);
funcnest++;
exitstatus = oexitstatus;
if (flags & EV_TESTED)
evaltree(cmdentry.u.func, EV_TESTED);
else

View file

@ -728,9 +728,6 @@ typecmd_impl(int argc, char **argv, int cmd)
extern char *const parsekwd[];
for (i = 1; i < argc; i++) {
if (cmd != TYPECMD_SMALLV)
out1str(argv[i]);
/* First look at the keywords */
for (pp = (char **)parsekwd; *pp; pp++)
if (**pp == *argv[i] && equal(*pp, argv[i]))
@ -740,7 +737,7 @@ typecmd_impl(int argc, char **argv, int cmd)
if (cmd == TYPECMD_SMALLV)
out1fmt("%s\n", argv[i]);
else
out1str(" is a shell keyword\n");
out1fmt("%s is a shell keyword\n", argv[i]);
continue;
}
@ -749,7 +746,8 @@ typecmd_impl(int argc, char **argv, int cmd)
if (cmd == TYPECMD_SMALLV)
out1fmt("alias %s='%s'\n", argv[i], ap->val);
else
out1fmt(" is an alias for %s\n", ap->val);
out1fmt("%s is an alias for %s\n", argv[i],
ap->val);
continue;
}
@ -775,7 +773,7 @@ typecmd_impl(int argc, char **argv, int cmd)
if (cmd == TYPECMD_SMALLV)
out1fmt("%s\n", name);
else
out1fmt(" is%s %s\n",
out1fmt("%s is%s %s\n", argv[i],
(cmdp && cmd == TYPECMD_TYPE) ?
" a tracked alias for" : "",
name);
@ -784,11 +782,12 @@ typecmd_impl(int argc, char **argv, int cmd)
if (cmd == TYPECMD_SMALLV)
out1fmt("%s\n", argv[i]);
else
out1fmt(" is %s\n", argv[i]);
out1fmt("%s is %s\n", argv[i],
argv[i]);
} else {
if (cmd != TYPECMD_SMALLV)
out1fmt(": %s\n",
strerror(errno));
outfmt(out2, "%s: %s\n",
argv[i], strerror(errno));
error |= 127;
}
}
@ -798,19 +797,19 @@ typecmd_impl(int argc, char **argv, int cmd)
if (cmd == TYPECMD_SMALLV)
out1fmt("%s\n", argv[i]);
else
out1str(" is a shell function\n");
out1fmt("%s is a shell function\n", argv[i]);
break;
case CMDBUILTIN:
if (cmd == TYPECMD_SMALLV)
out1fmt("%s\n", argv[i]);
else
out1str(" is a shell builtin\n");
out1fmt("%s is a shell builtin\n", argv[i]);
break;
default:
if (cmd != TYPECMD_SMALLV)
out1str(": not found\n");
outfmt(out2, "%s: not found\n", argv[i]);
error |= 127;
break;
}

View file

@ -4,3 +4,5 @@ OPENSOLARIS_USR_DISTDIR= ${.CURDIR}/../../../cddl/contrib/opensolaris
OPENSOLARIS_SYS_DISTDIR= ${.CURDIR}/../../../sys/cddl/contrib/opensolaris
IGNORE_PRAGMA= YES
CFLAGS+= -DNEED_SOLARIS_BOOLEAN

View file

@ -0,0 +1,36 @@
/*-
* Copyright (c) 2007 Pawel Jakub Dawidek <pjd@FreeBSD.org>
* 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 AUTHORS 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 AUTHORS 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$
*/
#ifndef _OPENSOLARIS_LIBSHARE_H_
#define _OPENSOLARIS_LIBSHARE_H_
#define SA_OK 0
#define SA_INIT_CONTROL_API 0
#endif /* !_OPENSOLARIS_LIBSHARE_H_ */

View file

@ -9,6 +9,8 @@
#define MNTTAB _PATH_DEVNULL
#define MNT_LINE_MAX 1024
#define umount2(p, f) unmount(p, f)
struct mnttab {
char *mnt_special;
char *mnt_mountp;

View file

@ -94,11 +94,7 @@ int
devid_get(int fd, ddi_devid_t *retdevid)
{
if (ioctl(fd, DIOCGIDENT, retdevid->devid) == -1)
return (errno);
if (retdevid->devid[0] == '\0')
return (ENOENT);
return (0);
return (ENOENT);
}
int

View file

@ -37,6 +37,8 @@ __FBSDID("$FreeBSD$");
#include <sys/mntent.h>
#include <sys/mnttab.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
static char *
mntopt(char **p)

View file

@ -35,9 +35,10 @@ __FBSDID("$FreeBSD$");
#include <sys/mount.h>
#include <sys/uio.h>
#include <sys/mntent.h>
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <string.h>
static void
build_iovec(struct iovec **iov, int *iovlen, const char *name, void *val,
@ -86,7 +87,7 @@ zmount(const char *spec, const char *dir, int mflag, char *fstype,
assert(optlen > 0);
optstr = strdup(optptr);
assert(optptr != NULL);
assert(optstr != NULL);
iov = NULL;
iovlen = 0;

View file

@ -32,7 +32,7 @@
#include <sys/sysctl.h>
#include <sys/zone.h>
int
zoneid_t
getzoneid(void)
{
size_t size;
@ -42,5 +42,5 @@ getzoneid(void)
size = sizeof(jailid);
if (sysctlbyname("security.jail.jailed", &jailid, &size, NULL, 0) == -1)
assert(!"No security.jail.jailed sysctl!");
return (jailid);
return ((zoneid_t)jailid);
}

View file

@ -1576,7 +1576,7 @@ main(int argc, char *argv[])
if ((v = make_argv(optarg)) == NULL)
fatal("failed to allocate memory");
P = dtrace_proc_create(g_dtp, v[0], v);
P = dtrace_proc_create(g_dtp, v[0], v, NULL, NULL);
if (P == NULL)
dfatal(NULL); /* dtrace_errmsg() only */

View file

@ -23,7 +23,7 @@
# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
#ident "%Z%%M% %I% %E% SMI"
# ident "%Z%%M% %I% %E% SMI"
# Exception list: names tests that are bypassed when running in Java
# mode (relative to /opt/SUNWdtrt/tst)
@ -49,6 +49,7 @@ common/usdt/tst.dlclose2.ksh
common/usdt/tst.dlclose3.ksh
common/usdt/tst.eliminate.ksh
common/usdt/tst.enabled.ksh
common/usdt/tst.enabled2.ksh
common/usdt/tst.entryreturn.ksh
common/usdt/tst.fork.ksh
common/usdt/tst.header.ksh

View file

@ -28,13 +28,17 @@ zdb \- ZFS debugger
.fi
.SH DESCRIPTION
.sp
.LP
The \fBzdb\fR command is used by support engineers to diagnose failures and gather statistics. Since the \fBZFS\fR file system is always consistent on disk and is self-repairing, \fBzdb\fR should only be run under the direction by a support engineer.
.sp
.LP
If no arguments are specified, \fBzdb\fR, performs basic consistency checks on the pool and associated datasets, and report any problems detected.
.sp
.LP
Any options supported by this command are internal to Sun and subject to change at any time.
.SH EXIT STATUS
.sp
.LP
The following exit values are returned:
.sp
@ -71,6 +75,7 @@ Invalid command line options were specified.
.RE
.SH ATTRIBUTES
.sp
.LP
See \fBattributes\fR(5) for descriptions of the following attributes:
.sp
@ -89,5 +94,6 @@ Interface StabilityUnstable
.TE
.SH SEE ALSO
.sp
.LP
\fBzfs\fR(1M), \fBzpool\fR(1M), \fBattributes\fR(5)

File diff suppressed because it is too large Load diff

View file

@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
* Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@ -233,19 +233,26 @@ typedef struct zil_rec_info {
} zil_rec_info_t;
static zil_rec_info_t zil_rec_info[TX_MAX_TYPE] = {
{ NULL, "Total " },
{ zil_prt_rec_create, "TX_CREATE " },
{ zil_prt_rec_create, "TX_MKDIR " },
{ zil_prt_rec_create, "TX_MKXATTR " },
{ zil_prt_rec_create, "TX_SYMLINK " },
{ zil_prt_rec_remove, "TX_REMOVE " },
{ zil_prt_rec_remove, "TX_RMDIR " },
{ zil_prt_rec_link, "TX_LINK " },
{ zil_prt_rec_rename, "TX_RENAME " },
{ zil_prt_rec_write, "TX_WRITE " },
{ zil_prt_rec_truncate, "TX_TRUNCATE" },
{ zil_prt_rec_setattr, "TX_SETATTR " },
{ zil_prt_rec_acl, "TX_ACL " },
{ NULL, "Total " },
{ zil_prt_rec_create, "TX_CREATE " },
{ zil_prt_rec_create, "TX_MKDIR " },
{ zil_prt_rec_create, "TX_MKXATTR " },
{ zil_prt_rec_create, "TX_SYMLINK " },
{ zil_prt_rec_remove, "TX_REMOVE " },
{ zil_prt_rec_remove, "TX_RMDIR " },
{ zil_prt_rec_link, "TX_LINK " },
{ zil_prt_rec_rename, "TX_RENAME " },
{ zil_prt_rec_write, "TX_WRITE " },
{ zil_prt_rec_truncate, "TX_TRUNCATE " },
{ zil_prt_rec_setattr, "TX_SETATTR " },
{ zil_prt_rec_acl, "TX_ACL_V0 " },
{ zil_prt_rec_acl, "TX_ACL_ACL " },
{ zil_prt_rec_create, "TX_CREATE_ACL " },
{ zil_prt_rec_create, "TX_CREATE_ATTR " },
{ zil_prt_rec_create, "TX_CREATE_ACL_ATTR " },
{ zil_prt_rec_create, "TX_MKDIR_ACL " },
{ zil_prt_rec_create, "TX_MKDIR_ATTR " },
{ zil_prt_rec_create, "TX_MKDIR_ACL_ATTR " },
};
/* ARGSUSED */
@ -255,12 +262,14 @@ print_log_record(zilog_t *zilog, lr_t *lr, void *arg, uint64_t claim_txg)
int txtype;
int verbose = MAX(dump_opt['d'], dump_opt['i']);
/* reduce size of txtype to strip off TX_CI bit */
txtype = lr->lrc_txtype;
ASSERT(txtype != 0 && (uint_t)txtype < TX_MAX_TYPE);
ASSERT(lr->lrc_txg);
(void) printf("\t\t%s len %6llu, txg %llu, seq %llu\n",
(void) printf("\t\t%s%s len %6llu, txg %llu, seq %llu\n",
(lr->lrc_txtype & TX_CI) ? "CI-" : "",
zil_rec_info[txtype].zri_name,
(u_longlong_t)lr->lrc_reclen,
(u_longlong_t)lr->lrc_txg,

File diff suppressed because it is too large Load diff

View file

@ -19,12 +19,10 @@
* CDDL HEADER END
*/
/*
* Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
#include <libintl.h>
#include <libuutil.h>
#include <stddef.h>
@ -56,28 +54,43 @@ typedef struct zfs_node {
typedef struct callback_data {
uu_avl_t *cb_avl;
int cb_recurse;
int cb_flags;
zfs_type_t cb_types;
zfs_sort_column_t *cb_sortcol;
zfs_proplist_t **cb_proplist;
zprop_list_t **cb_proplist;
} callback_data_t;
uu_avl_pool_t *avl_pool;
/*
* Called for each dataset. If the object the object is of an appropriate type,
* Include snaps if they were requested or if this a zfs list where types
* were not specified and the "listsnapshots" property is set on this pool.
*/
static int
zfs_include_snapshots(zfs_handle_t *zhp, callback_data_t *cb)
{
zpool_handle_t *zph;
if ((cb->cb_flags & ZFS_ITER_PROP_LISTSNAPS) == 0)
return (cb->cb_types & ZFS_TYPE_SNAPSHOT);
zph = zfs_get_pool_handle(zhp);
return (zpool_get_prop_int(zph, ZPOOL_PROP_LISTSNAPS, NULL));
}
/*
* Called for each dataset. If the object is of an appropriate type,
* add it to the avl tree and recurse over any children as necessary.
*/
int
static int
zfs_callback(zfs_handle_t *zhp, void *data)
{
callback_data_t *cb = data;
int dontclose = 0;
int include_snaps = zfs_include_snapshots(zhp, cb);
/*
* If this object is of the appropriate type, add it to the AVL tree.
*/
if (zfs_get_type(zhp) & cb->cb_types) {
if ((zfs_get_type(zhp) & cb->cb_types) ||
((zfs_get_type(zhp) == ZFS_TYPE_SNAPSHOT) && include_snaps)) {
uu_avl_index_t idx;
zfs_node_t *node = safe_malloc(sizeof (zfs_node_t));
@ -100,10 +113,12 @@ zfs_callback(zfs_handle_t *zhp, void *data)
/*
* Recurse if necessary.
*/
if (cb->cb_recurse && (zfs_get_type(zhp) == ZFS_TYPE_FILESYSTEM ||
(zfs_get_type(zhp) == ZFS_TYPE_VOLUME && (cb->cb_types &
ZFS_TYPE_SNAPSHOT))))
(void) zfs_iter_children(zhp, zfs_callback, data);
if (cb->cb_flags & ZFS_ITER_RECURSE) {
if (zfs_get_type(zhp) == ZFS_TYPE_FILESYSTEM)
(void) zfs_iter_filesystems(zhp, zfs_callback, data);
if ((zfs_get_type(zhp) != ZFS_TYPE_SNAPSHOT) && include_snaps)
(void) zfs_iter_snapshots(zhp, zfs_callback, data);
}
if (!dontclose)
zfs_close(zhp);
@ -118,7 +133,7 @@ zfs_add_sort_column(zfs_sort_column_t **sc, const char *name,
zfs_sort_column_t *col;
zfs_prop_t prop;
if ((prop = zfs_name_to_prop(name)) == ZFS_PROP_INVAL &&
if ((prop = zfs_name_to_prop(name)) == ZPROP_INVAL &&
!zfs_prop_user(name))
return (-1);
@ -126,7 +141,7 @@ zfs_add_sort_column(zfs_sort_column_t **sc, const char *name,
col->sc_prop = prop;
col->sc_reverse = reverse;
if (prop == ZFS_PROP_INVAL) {
if (prop == ZPROP_INVAL) {
col->sc_user_prop = safe_malloc(strlen(name) + 1);
(void) strcpy(col->sc_user_prop, name);
}
@ -243,7 +258,7 @@ zfs_sort(const void *larg, const void *rarg, void *data)
* Otherwise, we compare 'lnum' and 'rnum'.
*/
lstr = rstr = NULL;
if (psc->sc_prop == ZFS_PROP_INVAL) {
if (psc->sc_prop == ZPROP_INVAL) {
nvlist_t *luser, *ruser;
nvlist_t *lval, *rval;
@ -257,10 +272,10 @@ zfs_sort(const void *larg, const void *rarg, void *data)
if (lvalid)
verify(nvlist_lookup_string(lval,
ZFS_PROP_VALUE, &lstr) == 0);
ZPROP_VALUE, &lstr) == 0);
if (rvalid)
verify(nvlist_lookup_string(rval,
ZFS_PROP_VALUE, &rstr) == 0);
ZPROP_VALUE, &rstr) == 0);
} else if (zfs_prop_is_string(psc->sc_prop)) {
lvalid = (zfs_prop_get(l, psc->sc_prop, lbuf,
@ -293,7 +308,7 @@ zfs_sort(const void *larg, const void *rarg, void *data)
if (lstr)
ret = strcmp(lstr, rstr);
if (lnum < rnum)
else if (lnum < rnum)
ret = -1;
else if (lnum > rnum)
ret = 1;
@ -309,9 +324,9 @@ zfs_sort(const void *larg, const void *rarg, void *data)
}
int
zfs_for_each(int argc, char **argv, boolean_t recurse, zfs_type_t types,
zfs_sort_column_t *sortcol, zfs_proplist_t **proplist, zfs_iter_f callback,
void *data, boolean_t args_can_be_paths)
zfs_for_each(int argc, char **argv, int flags, zfs_type_t types,
zfs_sort_column_t *sortcol, zprop_list_t **proplist,
zfs_iter_f callback, void *data)
{
callback_data_t cb;
int ret = 0;
@ -328,7 +343,7 @@ zfs_for_each(int argc, char **argv, boolean_t recurse, zfs_type_t types,
}
cb.cb_sortcol = sortcol;
cb.cb_recurse = recurse;
cb.cb_flags = flags;
cb.cb_proplist = proplist;
cb.cb_types = types;
if ((cb.cb_avl = uu_avl_create(avl_pool, NULL, UU_DEFAULT)) == NULL) {
@ -341,7 +356,7 @@ zfs_for_each(int argc, char **argv, boolean_t recurse, zfs_type_t types,
/*
* If given no arguments, iterate over all datasets.
*/
cb.cb_recurse = 1;
cb.cb_flags |= ZFS_ITER_RECURSE;
ret = zfs_iter_root(g_zfs, zfs_callback, &cb);
} else {
int i;
@ -354,14 +369,14 @@ zfs_for_each(int argc, char **argv, boolean_t recurse, zfs_type_t types,
* can take volumes as well.
*/
argtype = types;
if (recurse) {
if (flags & ZFS_ITER_RECURSE) {
argtype |= ZFS_TYPE_FILESYSTEM;
if (types & ZFS_TYPE_SNAPSHOT)
argtype |= ZFS_TYPE_VOLUME;
}
for (i = 0; i < argc; i++) {
if (args_can_be_paths) {
if (flags & ZFS_ITER_ARGS_CAN_BE_PATHS) {
zhp = zfs_path_to_zhandle(g_zfs, argv[i],
argtype);
} else {

View file

@ -19,15 +19,13 @@
* CDDL HEADER END
*/
/*
* Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#ifndef ZFS_ITER_H
#define ZFS_ITER_H
#pragma ident "%Z%%M% %I% %E% SMI"
#ifdef __cplusplus
extern "C" {
#endif
@ -40,8 +38,12 @@ typedef struct zfs_sort_column {
boolean_t sc_reverse;
} zfs_sort_column_t;
int zfs_for_each(int, char **, boolean_t, zfs_type_t, zfs_sort_column_t *,
zfs_proplist_t **, zfs_iter_f, void *, boolean_t);
#define ZFS_ITER_RECURSE (1 << 0)
#define ZFS_ITER_ARGS_CAN_BE_PATHS (1 << 1)
#define ZFS_ITER_PROP_LISTSNAPS (1 << 2)
int zfs_for_each(int, char **, int options, zfs_type_t,
zfs_sort_column_t *, zprop_list_t **, zfs_iter_f, void *);
int zfs_add_sort_column(zfs_sort_column_t **, const char *, boolean_t);
void zfs_free_sort_columns(zfs_sort_column_t *);

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,460 @@
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#include <libzfs.h>
#undef verify /* both libzfs.h and zfs_context.h want to define this */
#include <sys/zfs_context.h>
#include <errno.h>
#include <fcntl.h>
#include <stdarg.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <strings.h>
#include <sys/file.h>
#include <sys/mntent.h>
#include <sys/mnttab.h>
#include <sys/param.h>
#include <sys/stat.h>
#include <sys/dmu.h>
#include <sys/dmu_objset.h>
#include <sys/dnode.h>
#include <sys/vdev_impl.h>
#include "zinject.h"
#include <assert.h>
#define verify assert
extern void kernel_init(int);
extern void kernel_fini(void);
static int debug;
static void
ziprintf(const char *fmt, ...)
{
va_list ap;
if (!debug)
return;
va_start(ap, fmt);
(void) vprintf(fmt, ap);
va_end(ap);
}
/*
* Given a full path to a file, translate into a dataset name and a relative
* path within the dataset. 'dataset' must be at least MAXNAMELEN characters,
* and 'relpath' must be at least MAXPATHLEN characters. We also pass a stat64
* buffer, which we need later to get the object ID.
*/
static int
parse_pathname(const char *fullpath, char *dataset, char *relpath,
struct stat64 *statbuf)
{
struct statfs sfs;
const char *rel;
if (fullpath[0] != '/') {
(void) fprintf(stderr, "invalid object '%s': must be full "
"path\n", fullpath);
usage();
return (-1);
}
if (strlen(fullpath) >= MAXPATHLEN) {
(void) fprintf(stderr, "invalid object; pathname too long\n");
return (-1);
}
if (stat64(fullpath, statbuf) != 0) {
(void) fprintf(stderr, "cannot open '%s': %s\n",
fullpath, strerror(errno));
return (-1);
}
if (statfs(fullpath, &sfs) == -1) {
(void) fprintf(stderr, "cannot find mountpoint for '%s': %s\n",
fullpath, strerror(errno));
return (-1);
}
if (strcmp(sfs.f_fstypename, MNTTYPE_ZFS) != 0) {
(void) fprintf(stderr, "invalid path '%s': not a ZFS "
"filesystem\n", fullpath);
return (-1);
}
if (strncmp(fullpath, sfs.f_mntonname, strlen(sfs.f_mntonname)) != 0) {
(void) fprintf(stderr, "invalid path '%s': mountpoint "
"doesn't match path\n", fullpath);
return (-1);
}
(void) strcpy(dataset, sfs.f_mntfromname);
rel = fullpath + strlen(sfs.f_mntonname);
if (rel[0] == '/')
rel++;
(void) strcpy(relpath, rel);
return (0);
}
/*
* Convert from a (dataset, path) pair into a (objset, object) pair. Note that
* we grab the object number from the inode number, since looking this up via
* libzpool is a real pain.
*/
/* ARGSUSED */
static int
object_from_path(const char *dataset, const char *path, struct stat64 *statbuf,
zinject_record_t *record)
{
objset_t *os;
int err;
/*
* Before doing any libzpool operations, call sync() to ensure that the
* on-disk state is consistent with the in-core state.
*/
sync();
if ((err = dmu_objset_open(dataset, DMU_OST_ZFS,
DS_MODE_USER | DS_MODE_READONLY, &os)) != 0) {
(void) fprintf(stderr, "cannot open dataset '%s': %s\n",
dataset, strerror(err));
return (-1);
}
record->zi_objset = dmu_objset_id(os);
record->zi_object = statbuf->st_ino;
dmu_objset_close(os);
return (0);
}
/*
* Calculate the real range based on the type, level, and range given.
*/
static int
calculate_range(const char *dataset, err_type_t type, int level, char *range,
zinject_record_t *record)
{
objset_t *os = NULL;
dnode_t *dn = NULL;
int err;
int ret = -1;
/*
* Determine the numeric range from the string.
*/
if (range == NULL) {
/*
* If range is unspecified, set the range to [0,-1], which
* indicates that the whole object should be treated as an
* error.
*/
record->zi_start = 0;
record->zi_end = -1ULL;
} else {
char *end;
/* XXX add support for suffixes */
record->zi_start = strtoull(range, &end, 10);
if (*end == '\0')
record->zi_end = record->zi_start + 1;
else if (*end == ',')
record->zi_end = strtoull(end + 1, &end, 10);
if (*end != '\0') {
(void) fprintf(stderr, "invalid range '%s': must be "
"a numeric range of the form 'start[,end]'\n",
range);
goto out;
}
}
switch (type) {
case TYPE_DATA:
break;
case TYPE_DNODE:
/*
* If this is a request to inject faults into the dnode, then we
* must translate the current (objset,object) pair into an
* offset within the metadnode for the objset. Specifying any
* kind of range with type 'dnode' is illegal.
*/
if (range != NULL) {
(void) fprintf(stderr, "range cannot be specified when "
"type is 'dnode'\n");
goto out;
}
record->zi_start = record->zi_object * sizeof (dnode_phys_t);
record->zi_end = record->zi_start + sizeof (dnode_phys_t);
record->zi_object = 0;
break;
}
/*
* Get the dnode associated with object, so we can calculate the block
* size.
*/
if ((err = dmu_objset_open(dataset, DMU_OST_ANY,
DS_MODE_USER | DS_MODE_READONLY, &os)) != 0) {
(void) fprintf(stderr, "cannot open dataset '%s': %s\n",
dataset, strerror(err));
goto out;
}
if (record->zi_object == 0) {
dn = os->os->os_meta_dnode;
} else {
err = dnode_hold(os->os, record->zi_object, FTAG, &dn);
if (err != 0) {
(void) fprintf(stderr, "failed to hold dnode "
"for object %llu\n",
(u_longlong_t)record->zi_object);
goto out;
}
}
ziprintf("data shift: %d\n", (int)dn->dn_datablkshift);
ziprintf(" ind shift: %d\n", (int)dn->dn_indblkshift);
/*
* Translate range into block IDs.
*/
if (record->zi_start != 0 || record->zi_end != -1ULL) {
record->zi_start >>= dn->dn_datablkshift;
record->zi_end >>= dn->dn_datablkshift;
}
/*
* Check level, and then translate level 0 blkids into ranges
* appropriate for level of indirection.
*/
record->zi_level = level;
if (level > 0) {
ziprintf("level 0 blkid range: [%llu, %llu]\n",
record->zi_start, record->zi_end);
if (level >= dn->dn_nlevels) {
(void) fprintf(stderr, "level %d exceeds max level "
"of object (%d)\n", level, dn->dn_nlevels - 1);
goto out;
}
if (record->zi_start != 0 || record->zi_end != 0) {
int shift = dn->dn_indblkshift - SPA_BLKPTRSHIFT;
for (; level > 0; level--) {
record->zi_start >>= shift;
record->zi_end >>= shift;
}
}
}
ret = 0;
out:
if (dn) {
if (dn != os->os->os_meta_dnode)
dnode_rele(dn, FTAG);
}
if (os)
dmu_objset_close(os);
return (ret);
}
int
translate_record(err_type_t type, const char *object, const char *range,
int level, zinject_record_t *record, char *poolname, char *dataset)
{
char path[MAXPATHLEN];
char *slash;
struct stat64 statbuf;
int ret = -1;
kernel_init(FREAD);
debug = (getenv("ZINJECT_DEBUG") != NULL);
ziprintf("translating: %s\n", object);
if (MOS_TYPE(type)) {
/*
* MOS objects are treated specially.
*/
switch (type) {
case TYPE_MOS:
record->zi_type = 0;
break;
case TYPE_MOSDIR:
record->zi_type = DMU_OT_OBJECT_DIRECTORY;
break;
case TYPE_METASLAB:
record->zi_type = DMU_OT_OBJECT_ARRAY;
break;
case TYPE_CONFIG:
record->zi_type = DMU_OT_PACKED_NVLIST;
break;
case TYPE_BPLIST:
record->zi_type = DMU_OT_BPLIST;
break;
case TYPE_SPACEMAP:
record->zi_type = DMU_OT_SPACE_MAP;
break;
case TYPE_ERRLOG:
record->zi_type = DMU_OT_ERROR_LOG;
break;
}
dataset[0] = '\0';
(void) strcpy(poolname, object);
return (0);
}
/*
* Convert a full path into a (dataset, file) pair.
*/
if (parse_pathname(object, dataset, path, &statbuf) != 0)
goto err;
ziprintf(" dataset: %s\n", dataset);
ziprintf(" path: %s\n", path);
/*
* Convert (dataset, file) into (objset, object)
*/
if (object_from_path(dataset, path, &statbuf, record) != 0)
goto err;
ziprintf("raw objset: %llu\n", record->zi_objset);
ziprintf("raw object: %llu\n", record->zi_object);
/*
* For the given object, calculate the real (type, level, range)
*/
if (calculate_range(dataset, type, level, (char *)range, record) != 0)
goto err;
ziprintf(" objset: %llu\n", record->zi_objset);
ziprintf(" object: %llu\n", record->zi_object);
if (record->zi_start == 0 &&
record->zi_end == -1ULL)
ziprintf(" range: all\n");
else
ziprintf(" range: [%llu, %llu]\n", record->zi_start,
record->zi_end);
/*
* Copy the pool name
*/
(void) strcpy(poolname, dataset);
if ((slash = strchr(poolname, '/')) != NULL)
*slash = '\0';
ret = 0;
err:
kernel_fini();
return (ret);
}
int
translate_raw(const char *str, zinject_record_t *record)
{
/*
* A raw bookmark of the form objset:object:level:blkid, where each
* number is a hexidecimal value.
*/
if (sscanf(str, "%llx:%llx:%x:%llx", (u_longlong_t *)&record->zi_objset,
(u_longlong_t *)&record->zi_object, &record->zi_level,
(u_longlong_t *)&record->zi_start) != 4) {
(void) fprintf(stderr, "bad raw spec '%s': must be of the form "
"'objset:object:level:blkid'\n", str);
return (-1);
}
record->zi_end = record->zi_start;
return (0);
}
int
translate_device(const char *pool, const char *device, err_type_t label_type,
zinject_record_t *record)
{
char *end;
zpool_handle_t *zhp;
nvlist_t *tgt;
boolean_t isspare, iscache;
/*
* Given a device name or GUID, create an appropriate injection record
* with zi_guid set.
*/
if ((zhp = zpool_open(g_zfs, pool)) == NULL)
return (-1);
record->zi_guid = strtoull(device, &end, 16);
if (record->zi_guid == 0 || *end != '\0') {
tgt = zpool_find_vdev(zhp, device, &isspare, &iscache, NULL);
if (tgt == NULL) {
(void) fprintf(stderr, "cannot find device '%s' in "
"pool '%s'\n", device, pool);
return (-1);
}
verify(nvlist_lookup_uint64(tgt, ZPOOL_CONFIG_GUID,
&record->zi_guid) == 0);
}
switch (label_type) {
case TYPE_LABEL_UBERBLOCK:
record->zi_start = offsetof(vdev_label_t, vl_uberblock[0]);
record->zi_end = record->zi_start + VDEV_UBERBLOCK_RING - 1;
break;
case TYPE_LABEL_NVLIST:
record->zi_start = offsetof(vdev_label_t, vl_vdev_phys);
record->zi_end = record->zi_start + VDEV_PHYS_SIZE - 1;
break;
}
return (0);
}

View file

@ -0,0 +1,770 @@
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
/*
* ZFS Fault Injector
*
* This userland component takes a set of options and uses libzpool to translate
* from a user-visible object type and name to an internal representation.
* There are two basic types of faults: device faults and data faults.
*
*
* DEVICE FAULTS
*
* Errors can be injected into a particular vdev using the '-d' option. This
* option takes a path or vdev GUID to uniquely identify the device within a
* pool. There are two types of errors that can be injected, EIO and ENXIO,
* that can be controlled through the '-e' option. The default is ENXIO. For
* EIO failures, any attempt to read data from the device will return EIO, but
* subsequent attempt to reopen the device will succeed. For ENXIO failures,
* any attempt to read from the device will return EIO, but any attempt to
* reopen the device will also return ENXIO.
* For label faults, the -L option must be specified. This allows faults
* to be injected into either the nvlist or uberblock region of all the labels
* for the specified device.
*
* This form of the command looks like:
*
* zinject -d device [-e errno] [-L <uber | nvlist>] pool
*
*
* DATA FAULTS
*
* We begin with a tuple of the form:
*
* <type,level,range,object>
*
* type A string describing the type of data to target. Each type
* implicitly describes how to interpret 'object'. Currently,
* the following values are supported:
*
* data User data for a file
* dnode Dnode for a file or directory
*
* The following MOS objects are special. Instead of injecting
* errors on a particular object or blkid, we inject errors across
* all objects of the given type.
*
* mos Any data in the MOS
* mosdir object directory
* config pool configuration
* bplist blkptr list
* spacemap spacemap
* metaslab metaslab
* errlog persistent error log
*
* level Object level. Defaults to '0', not applicable to all types. If
* a range is given, this corresponds to the indirect block
* corresponding to the specific range.
*
* range A numerical range [start,end) within the object. Defaults to
* the full size of the file.
*
* object A string describing the logical location of the object. For
* files and directories (currently the only supported types),
* this is the path of the object on disk.
*
* This is translated, via libzpool, into the following internal representation:
*
* <type,objset,object,level,range>
*
* These types should be self-explanatory. This tuple is then passed to the
* kernel via a special ioctl() to initiate fault injection for the given
* object. Note that 'type' is not strictly necessary for fault injection, but
* is used when translating existing faults into a human-readable string.
*
*
* The command itself takes one of the forms:
*
* zinject
* zinject <-a | -u pool>
* zinject -c <id|all>
* zinject [-q] <-t type> [-f freq] [-u] [-a] [-m] [-e errno] [-l level]
* [-r range] <object>
* zinject [-f freq] [-a] [-m] [-u] -b objset:object:level:start:end pool
*
* With no arguments, the command prints all currently registered injection
* handlers, with their numeric identifiers.
*
* The '-c' option will clear the given handler, or all handlers if 'all' is
* specified.
*
* The '-e' option takes a string describing the errno to simulate. This must
* be either 'io' or 'checksum'. In most cases this will result in the same
* behavior, but RAID-Z will produce a different set of ereports for this
* situation.
*
* The '-a', '-u', and '-m' flags toggle internal flush behavior. If '-a' is
* specified, then the ARC cache is flushed appropriately. If '-u' is
* specified, then the underlying SPA is unloaded. Either of these flags can be
* specified independently of any other handlers. The '-m' flag automatically
* does an unmount and remount of the underlying dataset to aid in flushing the
* cache.
*
* The '-f' flag controls the frequency of errors injected, expressed as a
* integer percentage between 1 and 100. The default is 100.
*
* The this form is responsible for actually injecting the handler into the
* framework. It takes the arguments described above, translates them to the
* internal tuple using libzpool, and then issues an ioctl() to register the
* handler.
*
* The final form can target a specific bookmark, regardless of whether a
* human-readable interface has been designed. It allows developers to specify
* a particular block by number.
*/
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <strings.h>
#include <unistd.h>
#include <sys/fs/zfs.h>
#include <sys/mount.h>
#include <libzfs.h>
#undef verify /* both libzfs.h and zfs_context.h want to define this */
#include "zinject.h"
libzfs_handle_t *g_zfs;
int zfs_fd;
#ifndef ECKSUM
#define ECKSUM EBADE
#endif
static const char *errtable[TYPE_INVAL] = {
"data",
"dnode",
"mos",
"mosdir",
"metaslab",
"config",
"bplist",
"spacemap",
"errlog",
"uber",
"nvlist"
};
static err_type_t
name_to_type(const char *arg)
{
int i;
for (i = 0; i < TYPE_INVAL; i++)
if (strcmp(errtable[i], arg) == 0)
return (i);
return (TYPE_INVAL);
}
static const char *
type_to_name(uint64_t type)
{
switch (type) {
case DMU_OT_OBJECT_DIRECTORY:
return ("mosdir");
case DMU_OT_OBJECT_ARRAY:
return ("metaslab");
case DMU_OT_PACKED_NVLIST:
return ("config");
case DMU_OT_BPLIST:
return ("bplist");
case DMU_OT_SPACE_MAP:
return ("spacemap");
case DMU_OT_ERROR_LOG:
return ("errlog");
default:
return ("-");
}
}
/*
* Print usage message.
*/
void
usage(void)
{
(void) printf(
"usage:\n"
"\n"
"\tzinject\n"
"\n"
"\t\tList all active injection records.\n"
"\n"
"\tzinject -c <id|all>\n"
"\n"
"\t\tClear the particular record (if given a numeric ID), or\n"
"\t\tall records if 'all' is specificed.\n"
"\n"
"\tzinject -d device [-e errno] [-L <nvlist|uber>] pool\n"
"\t\tInject a fault into a particular device or the device's\n"
"\t\tlabel. Label injection can either be 'nvlist' or 'uber'.\n"
"\t\t'errno' can either be 'nxio' (the default) or 'io'.\n"
"\n"
"\tzinject -b objset:object:level:blkid pool\n"
"\n"
"\t\tInject an error into pool 'pool' with the numeric bookmark\n"
"\t\tspecified by the remaining tuple. Each number is in\n"
"\t\thexidecimal, and only one block can be specified.\n"
"\n"
"\tzinject [-q] <-t type> [-e errno] [-l level] [-r range]\n"
"\t [-a] [-m] [-u] [-f freq] <object>\n"
"\n"
"\t\tInject an error into the object specified by the '-t' option\n"
"\t\tand the object descriptor. The 'object' parameter is\n"
"\t\tinterperted depending on the '-t' option.\n"
"\n"
"\t\t-q\tQuiet mode. Only print out the handler number added.\n"
"\t\t-e\tInject a specific error. Must be either 'io' or\n"
"\t\t\t'checksum'. Default is 'io'.\n"
"\t\t-l\tInject error at a particular block level. Default is "
"0.\n"
"\t\t-m\tAutomatically remount underlying filesystem.\n"
"\t\t-r\tInject error over a particular logical range of an\n"
"\t\t\tobject. Will be translated to the appropriate blkid\n"
"\t\t\trange according to the object's properties.\n"
"\t\t-a\tFlush the ARC cache. Can be specified without any\n"
"\t\t\tassociated object.\n"
"\t\t-u\tUnload the associated pool. Can be specified with only\n"
"\t\t\ta pool object.\n"
"\t\t-f\tOnly inject errors a fraction of the time. Expressed as\n"
"\t\t\ta percentage between 1 and 100.\n"
"\n"
"\t-t data\t\tInject an error into the plain file contents of a\n"
"\t\t\tfile. The object must be specified as a complete path\n"
"\t\t\tto a file on a ZFS filesystem.\n"
"\n"
"\t-t dnode\tInject an error into the metadnode in the block\n"
"\t\t\tcorresponding to the dnode for a file or directory. The\n"
"\t\t\t'-r' option is incompatible with this mode. The object\n"
"\t\t\tis specified as a complete path to a file or directory\n"
"\t\t\ton a ZFS filesystem.\n"
"\n"
"\t-t <mos>\tInject errors into the MOS for objects of the given\n"
"\t\t\ttype. Valid types are: mos, mosdir, config, bplist,\n"
"\t\t\tspacemap, metaslab, errlog. The only valid <object> is\n"
"\t\t\tthe poolname.\n");
}
static int
iter_handlers(int (*func)(int, const char *, zinject_record_t *, void *),
void *data)
{
zfs_cmd_t zc;
int ret;
zc.zc_guid = 0;
while (ioctl(zfs_fd, ZFS_IOC_INJECT_LIST_NEXT, &zc) == 0)
if ((ret = func((int)zc.zc_guid, zc.zc_name,
&zc.zc_inject_record, data)) != 0)
return (ret);
return (0);
}
static int
print_data_handler(int id, const char *pool, zinject_record_t *record,
void *data)
{
int *count = data;
if (record->zi_guid != 0)
return (0);
if (*count == 0) {
(void) printf("%3s %-15s %-6s %-6s %-8s %3s %-15s\n",
"ID", "POOL", "OBJSET", "OBJECT", "TYPE", "LVL", "RANGE");
(void) printf("--- --------------- ------ "
"------ -------- --- ---------------\n");
}
*count += 1;
(void) printf("%3d %-15s %-6llu %-6llu %-8s %3d ", id, pool,
(u_longlong_t)record->zi_objset, (u_longlong_t)record->zi_object,
type_to_name(record->zi_type), record->zi_level);
if (record->zi_start == 0 &&
record->zi_end == -1ULL)
(void) printf("all\n");
else
(void) printf("[%llu, %llu]\n", (u_longlong_t)record->zi_start,
(u_longlong_t)record->zi_end);
return (0);
}
static int
print_device_handler(int id, const char *pool, zinject_record_t *record,
void *data)
{
int *count = data;
if (record->zi_guid == 0)
return (0);
if (*count == 0) {
(void) printf("%3s %-15s %s\n", "ID", "POOL", "GUID");
(void) printf("--- --------------- ----------------\n");
}
*count += 1;
(void) printf("%3d %-15s %llx\n", id, pool,
(u_longlong_t)record->zi_guid);
return (0);
}
/*
* Print all registered error handlers. Returns the number of handlers
* registered.
*/
static int
print_all_handlers(void)
{
int count = 0;
(void) iter_handlers(print_device_handler, &count);
(void) printf("\n");
count = 0;
(void) iter_handlers(print_data_handler, &count);
return (count);
}
/* ARGSUSED */
static int
cancel_one_handler(int id, const char *pool, zinject_record_t *record,
void *data)
{
zfs_cmd_t zc;
zc.zc_guid = (uint64_t)id;
if (ioctl(zfs_fd, ZFS_IOC_CLEAR_FAULT, &zc) != 0) {
(void) fprintf(stderr, "failed to remove handler %d: %s\n",
id, strerror(errno));
return (1);
}
return (0);
}
/*
* Remove all fault injection handlers.
*/
static int
cancel_all_handlers(void)
{
int ret = iter_handlers(cancel_one_handler, NULL);
(void) printf("removed all registered handlers\n");
return (ret);
}
/*
* Remove a specific fault injection handler.
*/
static int
cancel_handler(int id)
{
zfs_cmd_t zc;
zc.zc_guid = (uint64_t)id;
if (ioctl(zfs_fd, ZFS_IOC_CLEAR_FAULT, &zc) != 0) {
(void) fprintf(stderr, "failed to remove handler %d: %s\n",
id, strerror(errno));
return (1);
}
(void) printf("removed handler %d\n", id);
return (0);
}
/*
* Register a new fault injection handler.
*/
static int
register_handler(const char *pool, int flags, zinject_record_t *record,
int quiet)
{
zfs_cmd_t zc;
(void) strcpy(zc.zc_name, pool);
zc.zc_inject_record = *record;
zc.zc_guid = flags;
if (ioctl(zfs_fd, ZFS_IOC_INJECT_FAULT, &zc) != 0) {
(void) fprintf(stderr, "failed to add handler: %s\n",
strerror(errno));
return (1);
}
if (flags & ZINJECT_NULL)
return (0);
if (quiet) {
(void) printf("%llu\n", (u_longlong_t)zc.zc_guid);
} else {
(void) printf("Added handler %llu with the following "
"properties:\n", (u_longlong_t)zc.zc_guid);
(void) printf(" pool: %s\n", pool);
if (record->zi_guid) {
(void) printf(" vdev: %llx\n",
(u_longlong_t)record->zi_guid);
} else {
(void) printf("objset: %llu\n",
(u_longlong_t)record->zi_objset);
(void) printf("object: %llu\n",
(u_longlong_t)record->zi_object);
(void) printf(" type: %llu\n",
(u_longlong_t)record->zi_type);
(void) printf(" level: %d\n", record->zi_level);
if (record->zi_start == 0 &&
record->zi_end == -1ULL)
(void) printf(" range: all\n");
else
(void) printf(" range: [%llu, %llu)\n",
(u_longlong_t)record->zi_start,
(u_longlong_t)record->zi_end);
}
}
return (0);
}
int
main(int argc, char **argv)
{
int c;
char *range = NULL;
char *cancel = NULL;
char *end;
char *raw = NULL;
char *device = NULL;
int level = 0;
int quiet = 0;
int error = 0;
int domount = 0;
err_type_t type = TYPE_INVAL;
err_type_t label = TYPE_INVAL;
zinject_record_t record = { 0 };
char pool[MAXNAMELEN];
char dataset[MAXNAMELEN];
zfs_handle_t *zhp;
int ret;
int flags = 0;
if ((g_zfs = libzfs_init()) == NULL) {
(void) fprintf(stderr, "internal error: failed to "
"initialize ZFS library\n");
return (1);
}
libzfs_print_on_error(g_zfs, B_TRUE);
if ((zfs_fd = open(ZFS_DEV, O_RDWR)) < 0) {
(void) fprintf(stderr, "failed to open ZFS device\n");
return (1);
}
if (argc == 1) {
/*
* No arguments. Print the available handlers. If there are no
* available handlers, direct the user to '-h' for help
* information.
*/
if (print_all_handlers() == 0) {
(void) printf("No handlers registered.\n");
(void) printf("Run 'zinject -h' for usage "
"information.\n");
}
return (0);
}
while ((c = getopt(argc, argv, ":ab:d:f:qhc:t:l:mr:e:uL:")) != -1) {
switch (c) {
case 'a':
flags |= ZINJECT_FLUSH_ARC;
break;
case 'b':
raw = optarg;
break;
case 'c':
cancel = optarg;
break;
case 'd':
device = optarg;
break;
case 'e':
if (strcasecmp(optarg, "io") == 0) {
error = EIO;
} else if (strcasecmp(optarg, "checksum") == 0) {
error = ECKSUM;
} else if (strcasecmp(optarg, "nxio") == 0) {
error = ENXIO;
} else {
(void) fprintf(stderr, "invalid error type "
"'%s': must be 'io', 'checksum' or "
"'nxio'\n", optarg);
usage();
return (1);
}
break;
case 'f':
record.zi_freq = atoi(optarg);
if (record.zi_freq < 1 || record.zi_freq > 100) {
(void) fprintf(stderr, "frequency range must "
"be in the range (0, 100]\n");
return (1);
}
break;
case 'h':
usage();
return (0);
case 'l':
level = (int)strtol(optarg, &end, 10);
if (*end != '\0') {
(void) fprintf(stderr, "invalid level '%s': "
"must be an integer\n", optarg);
usage();
return (1);
}
break;
case 'm':
domount = 1;
break;
case 'q':
quiet = 1;
break;
case 'r':
range = optarg;
break;
case 't':
if ((type = name_to_type(optarg)) == TYPE_INVAL &&
!MOS_TYPE(type)) {
(void) fprintf(stderr, "invalid type '%s'\n",
optarg);
usage();
return (1);
}
break;
case 'u':
flags |= ZINJECT_UNLOAD_SPA;
break;
case 'L':
if ((label = name_to_type(optarg)) == TYPE_INVAL &&
!LABEL_TYPE(type)) {
(void) fprintf(stderr, "invalid label type "
"'%s'\n", optarg);
usage();
return (1);
}
break;
case ':':
(void) fprintf(stderr, "option -%c requires an "
"operand\n", optopt);
usage();
return (1);
case '?':
(void) fprintf(stderr, "invalid option '%c'\n",
optopt);
usage();
return (2);
}
}
argc -= optind;
argv += optind;
if (cancel != NULL) {
/*
* '-c' is invalid with any other options.
*/
if (raw != NULL || range != NULL || type != TYPE_INVAL ||
level != 0) {
(void) fprintf(stderr, "cancel (-c) incompatible with "
"any other options\n");
usage();
return (2);
}
if (argc != 0) {
(void) fprintf(stderr, "extraneous argument to '-c'\n");
usage();
return (2);
}
if (strcmp(cancel, "all") == 0) {
return (cancel_all_handlers());
} else {
int id = (int)strtol(cancel, &end, 10);
if (*end != '\0') {
(void) fprintf(stderr, "invalid handle id '%s':"
" must be an integer or 'all'\n", cancel);
usage();
return (1);
}
return (cancel_handler(id));
}
}
if (device != NULL) {
/*
* Device (-d) injection uses a completely different mechanism
* for doing injection, so handle it separately here.
*/
if (raw != NULL || range != NULL || type != TYPE_INVAL ||
level != 0) {
(void) fprintf(stderr, "device (-d) incompatible with "
"data error injection\n");
usage();
return (2);
}
if (argc != 1) {
(void) fprintf(stderr, "device (-d) injection requires "
"a single pool name\n");
usage();
return (2);
}
(void) strcpy(pool, argv[0]);
dataset[0] = '\0';
if (error == ECKSUM) {
(void) fprintf(stderr, "device error type must be "
"'io' or 'nxio'\n");
return (1);
}
if (translate_device(pool, device, label, &record) != 0)
return (1);
if (!error)
error = ENXIO;
} else if (raw != NULL) {
if (range != NULL || type != TYPE_INVAL || level != 0) {
(void) fprintf(stderr, "raw (-b) format with "
"any other options\n");
usage();
return (2);
}
if (argc != 1) {
(void) fprintf(stderr, "raw (-b) format expects a "
"single pool name\n");
usage();
return (2);
}
(void) strcpy(pool, argv[0]);
dataset[0] = '\0';
if (error == ENXIO) {
(void) fprintf(stderr, "data error type must be "
"'checksum' or 'io'\n");
return (1);
}
if (translate_raw(raw, &record) != 0)
return (1);
if (!error)
error = EIO;
} else if (type == TYPE_INVAL) {
if (flags == 0) {
(void) fprintf(stderr, "at least one of '-b', '-d', "
"'-t', '-a', or '-u' must be specified\n");
usage();
return (2);
}
if (argc == 1 && (flags & ZINJECT_UNLOAD_SPA)) {
(void) strcpy(pool, argv[0]);
dataset[0] = '\0';
} else if (argc != 0) {
(void) fprintf(stderr, "extraneous argument for "
"'-f'\n");
usage();
return (2);
}
flags |= ZINJECT_NULL;
} else {
if (argc != 1) {
(void) fprintf(stderr, "missing object\n");
usage();
return (2);
}
if (error == ENXIO) {
(void) fprintf(stderr, "data error type must be "
"'checksum' or 'io'\n");
return (1);
}
if (translate_record(type, argv[0], range, level, &record, pool,
dataset) != 0)
return (1);
if (!error)
error = EIO;
}
/*
* If this is pool-wide metadata, unmount everything. The ioctl() will
* unload the pool, so that we trigger spa-wide reopen of metadata next
* time we access the pool.
*/
if (dataset[0] != '\0' && domount) {
if ((zhp = zfs_open(g_zfs, dataset, ZFS_TYPE_DATASET)) == NULL)
return (1);
if (zfs_unmount(zhp, NULL, 0) != 0)
return (1);
}
record.zi_error = error;
ret = register_handler(pool, flags, &record, quiet);
if (dataset[0] != '\0' && domount)
ret = (zfs_mount(zhp, NULL, 0) != 0);
libzfs_fini(g_zfs);
return (ret);
}

View file

@ -0,0 +1,71 @@
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#ifndef _ZINJECT_H
#define _ZINJECT_H
#pragma ident "%Z%%M% %I% %E% SMI"
#include <sys/zfs_ioctl.h>
#ifdef __cplusplus
extern "C" {
#endif
typedef enum {
TYPE_DATA, /* plain file contents */
TYPE_DNODE, /* metadnode contents */
TYPE_MOS, /* all MOS data */
TYPE_MOSDIR, /* MOS object directory */
TYPE_METASLAB, /* metaslab objects */
TYPE_CONFIG, /* MOS config */
TYPE_BPLIST, /* block pointer list */
TYPE_SPACEMAP, /* space map objects */
TYPE_ERRLOG, /* persistent error log */
TYPE_LABEL_UBERBLOCK, /* label specific uberblock */
TYPE_LABEL_NVLIST, /* label specific nvlist */
TYPE_INVAL
} err_type_t;
#define MOS_TYPE(t) \
((t) >= TYPE_MOS && (t) < TYPE_LABEL_UBERBLOCK)
#define LABEL_TYPE(t) \
((t) >= TYPE_LABEL_UBERBLOCK && (t) < TYPE_INVAL)
int translate_record(err_type_t type, const char *object, const char *range,
int level, zinject_record_t *record, char *poolname, char *dataset);
int translate_raw(const char *raw, zinject_record_t *record);
int translate_device(const char *pool, const char *device,
err_type_t label_type, zinject_record_t *record);
void usage(void);
extern libzfs_handle_t *g_zfs;
#ifdef __cplusplus
}
#endif
#endif /* _ZINJECT_H */

File diff suppressed because it is too large Load diff

View file

@ -53,6 +53,7 @@ struct zpool_list {
boolean_t zl_findall;
uu_avl_t *zl_avl;
uu_avl_pool_t *zl_pool;
zprop_list_t **zl_proplist;
};
/* ARGSUSED */
@ -81,6 +82,12 @@ add_pool(zpool_handle_t *zhp, void *data)
node->zn_handle = zhp;
uu_avl_node_init(node, &node->zn_avlnode, zlp->zl_pool);
if (uu_avl_find(zlp->zl_avl, node, NULL, &idx) == NULL) {
if (zlp->zl_proplist &&
zpool_expand_proplist(zhp, zlp->zl_proplist) != 0) {
zpool_close(zhp);
free(node);
return (-1);
}
uu_avl_insert(zlp->zl_avl, node, idx);
} else {
zpool_close(zhp);
@ -98,7 +105,7 @@ add_pool(zpool_handle_t *zhp, void *data)
* line.
*/
zpool_list_t *
pool_list_get(int argc, char **argv, zpool_proplist_t **proplist, int *err)
pool_list_get(int argc, char **argv, zprop_list_t **proplist, int *err)
{
zpool_list_t *zlp;
@ -114,6 +121,8 @@ pool_list_get(int argc, char **argv, zpool_proplist_t **proplist, int *err)
UU_DEFAULT)) == NULL)
zpool_no_memory();
zlp->zl_proplist = proplist;
if (argc == 0) {
(void) zpool_iter(g_zfs, add_pool, zlp);
zlp->zl_findall = B_TRUE;
@ -123,13 +132,12 @@ pool_list_get(int argc, char **argv, zpool_proplist_t **proplist, int *err)
for (i = 0; i < argc; i++) {
zpool_handle_t *zhp;
if ((zhp = zpool_open_canfail(g_zfs,
argv[i])) != NULL && add_pool(zhp, zlp) == 0) {
if (proplist &&
zpool_expand_proplist(zhp, proplist) != 0)
if (zhp = zpool_open_canfail(g_zfs, argv[i])) {
if (add_pool(zhp, zlp) != 0)
*err = B_TRUE;
} else
} else {
*err = B_TRUE;
}
}
}
@ -228,7 +236,7 @@ pool_list_count(zpool_list_t *zlp)
*/
int
for_each_pool(int argc, char **argv, boolean_t unavail,
zpool_proplist_t **proplist, zpool_iter_f func, void *data)
zprop_list_t **proplist, zpool_iter_f func, void *data)
{
zpool_list_t *list;
int ret = 0;

File diff suppressed because it is too large Load diff

View file

@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
* Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@ -77,3 +77,28 @@ zpool_no_memory(void)
gettext("internal error: out of memory\n"));
exit(1);
}
/*
* Return the number of logs in supplied nvlist
*/
uint_t
num_logs(nvlist_t *nv)
{
uint_t nlogs = 0;
uint_t c, children;
nvlist_t **child;
if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
&child, &children) != 0)
return (0);
for (c = 0; c < children; c++) {
uint64_t is_log = B_FALSE;
(void) nvlist_lookup_uint64(child[c], ZPOOL_CONFIG_IS_LOG,
&is_log);
if (is_log)
nlogs++;
}
return (nlogs);
}

View file

@ -19,15 +19,13 @@
* CDDL HEADER END
*/
/*
* Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#ifndef ZPOOL_UTIL_H
#define ZPOOL_UTIL_H
#pragma ident "%Z%%M% %I% %E% SMI"
#include <libnvpair.h>
#include <libzfs.h>
@ -41,22 +39,24 @@ extern "C" {
void *safe_malloc(size_t);
char *safe_strdup(const char *);
void zpool_no_memory(void);
uint_t num_logs(nvlist_t *nv);
/*
* Virtual device functions
*/
nvlist_t *make_root_vdev(nvlist_t *poolconfig, int force, int check_rep,
boolean_t isreplace, int argc, char **argv);
nvlist_t *make_root_vdev(zpool_handle_t *zhp, int force, int check_rep,
boolean_t isreplace, boolean_t dryrun, int argc, char **argv);
/*
* Pool list functions
*/
int for_each_pool(int, char **, boolean_t unavail, zpool_proplist_t **,
int for_each_pool(int, char **, boolean_t unavail, zprop_list_t **,
zpool_iter_f, void *);
typedef struct zpool_list zpool_list_t;
zpool_list_t *pool_list_get(int, char **, zpool_proplist_t **, int *);
zpool_list_t *pool_list_get(int, char **, zprop_list_t **, int *);
void pool_list_update(zpool_list_t *);
int pool_list_iter(zpool_list_t *, int unavail, zpool_iter_f, void *);
void pool_list_free(zpool_list_t *);

View file

@ -20,12 +20,10 @@
*/
/*
* Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
/*
* Functions to convert between a list of vdevs and an nvlist representing the
* configuration. Each entry in the list can be one of:
@ -48,8 +46,8 @@
* Hot spares are a special case, and passed down as an array of disk vdevs, at
* the same level as the root of the vdev tree.
*
* The only function exported by this file is 'get_vdev_spec'. The function
* performs several passes:
* The only function exported by this file is 'make_root_vdev'. The
* function performs several passes:
*
* 1. Construct the vdev specification. Performs syntax validation and
* makes sure each device is valid.
@ -59,6 +57,7 @@
* 3. Check for replication errors if the 'force' flag is not specified.
* validates that the replication level is consistent across the
* entire pool.
* 4. Call libzfs to label any whole disks with an EFI label.
*/
#include <assert.h>
@ -76,8 +75,6 @@
#include <sys/mntent.h>
#include <libgeom.h>
#include <libzfs.h>
#include "zpool_util.h"
/*
@ -111,53 +108,105 @@ vdev_error(const char *fmt, ...)
}
/*
* Validate a GEOM provider.
* Check that a file is valid. All we can do in this case is check that it's
* not in use by another pool, and not in use by swap.
*/
static int
check_file(const char *file, boolean_t force, boolean_t isspare)
{
char *name;
int fd;
int ret = 0;
int err;
pool_state_t state;
boolean_t inuse;
#if 0
if (dm_inuse_swap(file, &err)) {
if (err)
libdiskmgt_error(err);
else
vdev_error(gettext("%s is currently used by swap. "
"Please see swap(1M).\n"), file);
return (-1);
}
#endif
if ((fd = open(file, O_RDONLY)) < 0)
return (0);
if (zpool_in_use(g_zfs, fd, &state, &name, &inuse) == 0 && inuse) {
const char *desc;
switch (state) {
case POOL_STATE_ACTIVE:
desc = gettext("active");
break;
case POOL_STATE_EXPORTED:
desc = gettext("exported");
break;
case POOL_STATE_POTENTIALLY_ACTIVE:
desc = gettext("potentially active");
break;
default:
desc = gettext("unknown");
break;
}
/*
* Allow hot spares to be shared between pools.
*/
if (state == POOL_STATE_SPARE && isspare)
return (0);
if (state == POOL_STATE_ACTIVE ||
state == POOL_STATE_SPARE || !force) {
switch (state) {
case POOL_STATE_SPARE:
vdev_error(gettext("%s is reserved as a hot "
"spare for pool %s\n"), file, name);
break;
default:
vdev_error(gettext("%s is part of %s pool "
"'%s'\n"), file, desc, name);
break;
}
ret = -1;
}
free(name);
}
(void) close(fd);
return (ret);
}
static int
check_provider(const char *name, boolean_t force, boolean_t isspare)
{
struct gmesh mesh;
struct gclass *mp;
struct ggeom *gp;
struct gprovider *pp;
int rv;
char path[MAXPATHLEN];
/* XXX: What to do with isspare? */
if (strncmp(name, _PATH_DEV, sizeof(_PATH_DEV) - 1) != 0)
snprintf(path, sizeof(path), "%s%s", _PATH_DEV, name);
else
strlcpy(path, name, sizeof(path));
if (strncmp(name, _PATH_DEV, sizeof(_PATH_DEV) - 1) == 0)
name += sizeof(_PATH_DEV) - 1;
rv = geom_gettree(&mesh);
assert(rv == 0);
pp = NULL;
LIST_FOREACH(mp, &mesh.lg_class, lg_class) {
LIST_FOREACH(gp, &mp->lg_geom, lg_geom) {
LIST_FOREACH(pp, &gp->lg_provider, lg_provider) {
if (strcmp(pp->lg_name, name) == 0)
goto out;
}
}
}
out:
rv = -1;
if (pp == NULL)
vdev_error("no such provider %s\n", name);
else {
int acr, acw, ace;
VERIFY(sscanf(pp->lg_mode, "r%dw%de%d", &acr, &acw, &ace) == 3);
if (acw == 0 && ace == 0)
rv = 0;
else
vdev_error("%s is in use (%s)\n", name, pp->lg_mode);
}
geom_deletetree(&mesh);
return (rv);
return (check_file(path, force, isspare));
}
/*
* By "whole disk" we mean an entire physical disk (something we can
* label, toggle the write cache on, etc.) as opposed to the full
* capacity of a pseudo-device such as lofi or did. We act as if we
* are labeling the disk, which should be a pretty good test of whether
* it's a viable device or not. Returns B_TRUE if it is and B_FALSE if
* it isn't.
*/
static boolean_t
is_provider(const char *name)
is_whole_disk(const char *name)
{
int fd;
@ -167,8 +216,8 @@ is_provider(const char *name)
return (B_TRUE);
}
return (B_FALSE);
}
/*
* Create a leaf vdev. Determine if this is a GEOM provider.
* Valid forms for a leaf vdev are:
@ -176,25 +225,81 @@ is_provider(const char *name)
* /dev/xxx Complete path to a GEOM provider
* xxx Shorthand for /dev/xxx
*/
nvlist_t *
make_leaf_vdev(const char *arg)
static nvlist_t *
make_leaf_vdev(const char *arg, uint64_t is_log)
{
char ident[DISK_IDENT_SIZE], path[MAXPATHLEN];
char path[MAXPATHLEN];
struct stat64 statbuf;
nvlist_t *vdev = NULL;
char *type = NULL;
boolean_t wholedisk = B_FALSE;
if (strncmp(arg, _PATH_DEV, sizeof(_PATH_DEV) - 1) == 0)
strlcpy(path, arg, sizeof (path));
else
snprintf(path, sizeof (path), "%s%s", _PATH_DEV, arg);
/*
* Determine what type of vdev this is, and put the full path into
* 'path'. We detect whether this is a device of file afterwards by
* checking the st_mode of the file.
*/
if (arg[0] == '/') {
/*
* Complete device or file path. Exact type is determined by
* examining the file descriptor afterwards.
*/
wholedisk = is_whole_disk(arg);
if (!wholedisk && (stat64(arg, &statbuf) != 0)) {
(void) fprintf(stderr,
gettext("cannot open '%s': %s\n"),
arg, strerror(errno));
return (NULL);
}
if (is_provider(path))
(void) strlcpy(path, arg, sizeof (path));
} else {
/*
* This may be a short path for a device, or it could be total
* gibberish. Check to see if it's a known device in
* /dev/dsk/. As part of this check, see if we've been given a
* an entire disk (minus the slice number).
*/
if (strncmp(arg, _PATH_DEV, sizeof(_PATH_DEV) - 1) == 0)
strlcpy(path, arg, sizeof (path));
else
snprintf(path, sizeof (path), "%s%s", _PATH_DEV, arg);
wholedisk = is_whole_disk(path);
if (!wholedisk && (stat64(path, &statbuf) != 0)) {
/*
* If we got ENOENT, then the user gave us
* gibberish, so try to direct them with a
* reasonable error message. Otherwise,
* regurgitate strerror() since it's the best we
* can do.
*/
if (errno == ENOENT) {
(void) fprintf(stderr,
gettext("cannot open '%s': no such "
"GEOM provider\n"), arg);
(void) fprintf(stderr,
gettext("must be a full path or "
"shorthand device name\n"));
return (NULL);
} else {
(void) fprintf(stderr,
gettext("cannot open '%s': %s\n"),
path, strerror(errno));
return (NULL);
}
}
}
/*
* Determine whether this is a device or a file.
*/
if (wholedisk) {
type = VDEV_TYPE_DISK;
else {
} else if (S_ISREG(statbuf.st_mode)) {
type = VDEV_TYPE_FILE;
} else {
(void) fprintf(stderr, gettext("cannot use '%s': must be a "
"GEOM provider\n"), path);
"GEOM provider or regular file\n"), path);
return (NULL);
}
@ -206,6 +311,7 @@ make_leaf_vdev(const char *arg)
verify(nvlist_alloc(&vdev, NV_UNIQUE_NAME, 0) == 0);
verify(nvlist_add_string(vdev, ZPOOL_CONFIG_PATH, path) == 0);
verify(nvlist_add_string(vdev, ZPOOL_CONFIG_TYPE, type) == 0);
verify(nvlist_add_uint64(vdev, ZPOOL_CONFIG_IS_LOG, is_log) == 0);
if (strcmp(type, VDEV_TYPE_DISK) == 0)
verify(nvlist_add_uint64(vdev, ZPOOL_CONFIG_WHOLE_DISK,
(uint64_t)B_FALSE) == 0);
@ -267,12 +373,14 @@ typedef struct replication_level {
uint64_t zprl_parity;
} replication_level_t;
#define ZPOOL_FUZZ (16 * 1024 * 1024)
/*
* Given a list of toplevel vdevs, return the current replication level. If
* the config is inconsistent, then NULL is returned. If 'fatal' is set, then
* an error message will be displayed for each self-inconsistent vdev.
*/
replication_level_t *
static replication_level_t *
get_replication(nvlist_t *nvroot, boolean_t fatal)
{
nvlist_t **top;
@ -291,10 +399,20 @@ get_replication(nvlist_t *nvroot, boolean_t fatal)
lastrep.zprl_type = NULL;
for (t = 0; t < toplevels; t++) {
uint64_t is_log = B_FALSE;
nv = top[t];
verify(nvlist_lookup_string(nv, ZPOOL_CONFIG_TYPE, &type) == 0);
/*
* For separate logs we ignore the top level vdev replication
* constraints.
*/
(void) nvlist_lookup_uint64(nv, ZPOOL_CONFIG_IS_LOG, &is_log);
if (is_log)
continue;
verify(nvlist_lookup_string(nv, ZPOOL_CONFIG_TYPE,
&type) == 0);
if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
&child, &children) != 0) {
/*
@ -328,7 +446,7 @@ get_replication(nvlist_t *nvroot, boolean_t fatal)
}
/*
* The 'dontreport' variable indicatest that we've
* The 'dontreport' variable indicates that we've
* already reported an error for this spec, so don't
* bother doing it again.
*/
@ -349,7 +467,7 @@ get_replication(nvlist_t *nvroot, boolean_t fatal)
ZPOOL_CONFIG_TYPE, &childtype) == 0);
/*
* If this is a a replacing or spare vdev, then
* If this is a replacing or spare vdev, then
* get the real first child of the vdev.
*/
if (strcmp(childtype,
@ -409,22 +527,30 @@ get_replication(nvlist_t *nvroot, boolean_t fatal)
*/
if ((fd = open(path, O_RDONLY)) >= 0) {
err = fstat64(fd, &statbuf);
if (err == 0 &&
S_ISCHR(statbuf.st_mode)) {
err = ioctl(fd, DIOCGMEDIASIZE,
&statbuf.st_size);
}
(void) close(fd);
} else {
err = stat64(path, &statbuf);
}
if (err != 0 || statbuf.st_size == 0)
continue;
size = statbuf.st_size;
/*
* Also check the size of each device. If they
* differ, then report an error.
* Also make sure that devices and
* slices have a consistent size. If
* they differ by a significant amount
* (~16MB) then report an error.
*/
if (!dontreport && vdev_size != -1ULL &&
size != vdev_size) {
if (!dontreport &&
(vdev_size != -1ULL &&
(labs(size - vdev_size) >
ZPOOL_FUZZ))) {
if (ret != NULL)
free(ret);
ret = NULL;
@ -506,9 +632,11 @@ get_replication(nvlist_t *nvroot, boolean_t fatal)
* has a consistent replication level, then we ignore any errors. Otherwise,
* report any difference between the two.
*/
int
static int
check_replication(nvlist_t *config, nvlist_t *newroot)
{
nvlist_t **child;
uint_t children;
replication_level_t *current = NULL, *new;
int ret;
@ -524,6 +652,23 @@ check_replication(nvlist_t *config, nvlist_t *newroot)
if ((current = get_replication(nvroot, B_FALSE)) == NULL)
return (0);
}
/*
* for spares there may be no children, and therefore no
* replication level to check
*/
if ((nvlist_lookup_nvlist_array(newroot, ZPOOL_CONFIG_CHILDREN,
&child, &children) != 0) || (children == 0)) {
free(current);
return (0);
}
/*
* If all we have is logs then there's no replication level to check.
*/
if (num_logs(newroot) == children) {
free(current);
return (0);
}
/*
* Get the replication level of the new vdev spec, reporting any
@ -621,7 +766,7 @@ is_spare(nvlist_t *config, const char *path)
* Go through and find any devices that are in use. We rely on libdiskmgt for
* the majority of this task.
*/
int
static int
check_in_use(nvlist_t *config, nvlist_t *nv, int force, int isreplacing,
int isspare)
{
@ -653,6 +798,9 @@ check_in_use(nvlist_t *config, nvlist_t *nv, int force, int isreplacing,
if (strcmp(type, VDEV_TYPE_DISK) == 0)
ret = check_provider(path, force, isspare);
if (strcmp(type, VDEV_TYPE_FILE) == 0)
ret = check_file(path, force, isspare);
return (ret);
}
@ -668,10 +816,17 @@ check_in_use(nvlist_t *config, nvlist_t *nv, int force, int isreplacing,
isreplacing, B_TRUE)) != 0)
return (ret);
if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_L2CACHE,
&child, &children) == 0)
for (c = 0; c < children; c++)
if ((ret = check_in_use(config, child[c], force,
isreplacing, B_FALSE)) != 0)
return (ret);
return (0);
}
const char *
static const char *
is_grouping(const char *type, int *mindev)
{
if (strcmp(type, "raidz") == 0 || strcmp(type, "raidz1") == 0) {
@ -698,6 +853,18 @@ is_grouping(const char *type, int *mindev)
return (VDEV_TYPE_SPARE);
}
if (strcmp(type, "log") == 0) {
if (mindev != NULL)
*mindev = 1;
return (VDEV_TYPE_LOG);
}
if (strcmp(type, "cache") == 0) {
if (mindev != NULL)
*mindev = 1;
return (VDEV_TYPE_L2CACHE);
}
return (NULL);
}
@ -710,14 +877,21 @@ is_grouping(const char *type, int *mindev)
nvlist_t *
construct_spec(int argc, char **argv)
{
nvlist_t *nvroot, *nv, **top, **spares;
int t, toplevels, mindev, nspares;
nvlist_t *nvroot, *nv, **top, **spares, **l2cache;
int t, toplevels, mindev, nspares, nlogs, nl2cache;
const char *type;
uint64_t is_log;
boolean_t seen_logs;
top = NULL;
toplevels = 0;
spares = NULL;
l2cache = NULL;
nspares = 0;
nlogs = 0;
nl2cache = 0;
is_log = B_FALSE;
seen_logs = B_FALSE;
while (argc > 0) {
nv = NULL;
@ -730,12 +904,56 @@ construct_spec(int argc, char **argv)
nvlist_t **child = NULL;
int c, children = 0;
if (strcmp(type, VDEV_TYPE_SPARE) == 0 &&
spares != NULL) {
(void) fprintf(stderr, gettext("invalid vdev "
"specification: 'spare' can be "
"specified only once\n"));
return (NULL);
if (strcmp(type, VDEV_TYPE_SPARE) == 0) {
if (spares != NULL) {
(void) fprintf(stderr,
gettext("invalid vdev "
"specification: 'spare' can be "
"specified only once\n"));
return (NULL);
}
is_log = B_FALSE;
}
if (strcmp(type, VDEV_TYPE_LOG) == 0) {
if (seen_logs) {
(void) fprintf(stderr,
gettext("invalid vdev "
"specification: 'log' can be "
"specified only once\n"));
return (NULL);
}
seen_logs = B_TRUE;
is_log = B_TRUE;
argc--;
argv++;
/*
* A log is not a real grouping device.
* We just set is_log and continue.
*/
continue;
}
if (strcmp(type, VDEV_TYPE_L2CACHE) == 0) {
if (l2cache != NULL) {
(void) fprintf(stderr,
gettext("invalid vdev "
"specification: 'cache' can be "
"specified only once\n"));
return (NULL);
}
is_log = B_FALSE;
}
if (is_log) {
if (strcmp(type, VDEV_TYPE_MIRROR) != 0) {
(void) fprintf(stderr,
gettext("invalid vdev "
"specification: unsupported 'log' "
"device: %s\n"), type);
return (NULL);
}
nlogs++;
}
for (c = 1; c < argc; c++) {
@ -746,7 +964,8 @@ construct_spec(int argc, char **argv)
children * sizeof (nvlist_t *));
if (child == NULL)
zpool_no_memory();
if ((nv = make_leaf_vdev(argv[c])) == NULL)
if ((nv = make_leaf_vdev(argv[c], B_FALSE))
== NULL)
return (NULL);
child[children - 1] = nv;
}
@ -765,11 +984,17 @@ construct_spec(int argc, char **argv)
spares = child;
nspares = children;
continue;
} else if (strcmp(type, VDEV_TYPE_L2CACHE) == 0) {
l2cache = child;
nl2cache = children;
continue;
} else {
verify(nvlist_alloc(&nv, NV_UNIQUE_NAME,
0) == 0);
verify(nvlist_add_string(nv, ZPOOL_CONFIG_TYPE,
type) == 0);
verify(nvlist_add_uint64(nv,
ZPOOL_CONFIG_IS_LOG, is_log) == 0);
if (strcmp(type, VDEV_TYPE_RAIDZ) == 0) {
verify(nvlist_add_uint64(nv,
ZPOOL_CONFIG_NPARITY,
@ -788,8 +1013,10 @@ construct_spec(int argc, char **argv)
* We have a device. Pass off to make_leaf_vdev() to
* construct the appropriate nvlist describing the vdev.
*/
if ((nv = make_leaf_vdev(argv[0])) == NULL)
if ((nv = make_leaf_vdev(argv[0], is_log)) == NULL)
return (NULL);
if (is_log)
nlogs++;
argc--;
argv++;
}
@ -801,13 +1028,19 @@ construct_spec(int argc, char **argv)
top[toplevels - 1] = nv;
}
if (toplevels == 0 && nspares == 0) {
if (toplevels == 0 && nspares == 0 && nl2cache == 0) {
(void) fprintf(stderr, gettext("invalid vdev "
"specification: at least one toplevel vdev must be "
"specified\n"));
return (NULL);
}
if (seen_logs && nlogs == 0) {
(void) fprintf(stderr, gettext("invalid vdev specification: "
"log requires at least 1 device\n"));
return (NULL);
}
/*
* Finally, create nvroot and add all top-level vdevs to it.
*/
@ -819,18 +1052,26 @@ construct_spec(int argc, char **argv)
if (nspares != 0)
verify(nvlist_add_nvlist_array(nvroot, ZPOOL_CONFIG_SPARES,
spares, nspares) == 0);
if (nl2cache != 0)
verify(nvlist_add_nvlist_array(nvroot, ZPOOL_CONFIG_L2CACHE,
l2cache, nl2cache) == 0);
for (t = 0; t < toplevels; t++)
nvlist_free(top[t]);
for (t = 0; t < nspares; t++)
nvlist_free(spares[t]);
for (t = 0; t < nl2cache; t++)
nvlist_free(l2cache[t]);
if (spares)
free(spares);
if (l2cache)
free(l2cache);
free(top);
return (nvroot);
}
/*
* Get and validate the contents of the given vdev specification. This ensures
* that the nvlist returned is well-formed, that all the devices exist, and that
@ -842,11 +1083,11 @@ construct_spec(int argc, char **argv)
* added, even if they appear in use.
*/
nvlist_t *
make_root_vdev(nvlist_t *poolconfig, int force, int check_rep,
boolean_t isreplacing, int argc, char **argv)
make_root_vdev(zpool_handle_t *zhp, int force, int check_rep,
boolean_t isreplacing, boolean_t dryrun, int argc, char **argv)
{
nvlist_t *newroot;
nvlist_t *poolconfig = NULL;
is_force = force;
/*
@ -857,6 +1098,9 @@ make_root_vdev(nvlist_t *poolconfig, int force, int check_rep,
if ((newroot = construct_spec(argc, argv)) == NULL)
return (NULL);
if (zhp && ((poolconfig = zpool_get_config(zhp, NULL)) == NULL))
return (NULL);
/*
* Validate each device to make sure that its not shared with another
* subsystem. We do this even if 'force' is set, because there are some

File diff suppressed because it is too large Load diff

View file

@ -39,7 +39,7 @@ extern "C" {
#if defined(__STDC__)
#if __STDC_VERSION__ - 0 >= 199901L
extern void __assert_c99(const char *, const char *, int, const char *);
extern void __assert(const char *, const char *, int);
#else
extern void __assert(const char *, const char *, int);
#endif /* __STDC_VERSION__ - 0 >= 199901L */
@ -70,8 +70,7 @@ extern void _assert();
#if defined(__STDC__)
#if __STDC_VERSION__ - 0 >= 199901L
#define assert(EX) (void)((EX) || \
(__assert_c99(#EX, __FILE__, __LINE__, __func__), 0))
#define assert(EX) (void)((EX) || (__assert(#EX, __FILE__, __LINE__), 0))
#else
#define assert(EX) (void)((EX) || (__assert(#EX, __FILE__, __LINE__), 0))
#endif /* __STDC_VERSION__ - 0 >= 199901L */

View file

@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (the "License"). You may not use this file except in compliance
* with the License.
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@ -20,11 +19,10 @@
* CDDL HEADER END
*/
/*
* Copyright 2005 Sun Microsystems, Inc. All rights reserved.
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/* Libintl is a library of advanced internationalization functions. */
#ifndef _LIBINTL_H
#define _LIBINTL_H
@ -63,6 +61,9 @@ typedef long wchar_t;
#define TEXTDOMAINMAX 256
#define __GNU_GETTEXT_SUPPORTED_REVISION(m) \
((((m) == 0) || ((m) == 1)) ? 1 : -1)
#ifdef __STDC__
extern char *dcgettext(const char *, const char *, const int);
extern char *dgettext(const char *, const char *);

View file

@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (the "License"). You may not use this file except in compliance
* with the License.
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@ -19,8 +18,9 @@
*
* CDDL HEADER END
*/
/*
* Copyright 2003 Sun Microsystems, Inc. All rights reserved.
* Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@ -81,12 +81,12 @@ typedef lwp_cond_t cond_t;
* Because we have to deal with C++, we cannot redefine this one as that one.
*/
typedef struct _rwlock {
int32_t readers; /* -1 == writer else # of readers */
int32_t readers; /* rwstate word */
uint16_t type;
uint16_t magic;
mutex_t mutex; /* used to indicate ownership */
cond_t readercv; /* unused */
cond_t writercv; /* unused */
mutex_t mutex; /* used with process-shared rwlocks */
cond_t readercv; /* used only to indicate ownership */
cond_t writercv; /* used only to indicate ownership */
} rwlock_t;
#ifdef __STDC__
@ -111,6 +111,7 @@ int cond_signal(cond_t *);
int cond_broadcast(cond_t *);
int mutex_init(mutex_t *, int, void *);
int mutex_destroy(mutex_t *);
int mutex_consistent(mutex_t *);
int mutex_lock(mutex_t *);
int mutex_trylock(mutex_t *);
int mutex_unlock(mutex_t *);
@ -152,6 +153,7 @@ int cond_signal();
int cond_broadcast();
int mutex_init();
int mutex_destroy();
int mutex_consistent();
int mutex_lock();
int mutex_trylock();
int mutex_unlock();

View file

@ -30,6 +30,7 @@
#pragma ident "%Z%%M% %I% %E% SMI"
#include <pthread.h>
#include <pthread_np.h>
#include <assert.h>
/*
@ -52,6 +53,7 @@ typedef pthread_rwlock_t rwlock_t;
#define mutex_lock(l) pthread_mutex_lock(l)
#define mutex_trylock(l) pthread_mutex_trylock(l)
#define mutex_unlock(l) pthread_mutex_unlock(l)
#define mutex_owned(l) pthread_mutex_isowned_np(l)
#define rwlock_init(l,f,a) pthread_rwlock_init(l,NULL)
#define rwlock_destroy(l) pthread_rwlock_destroy(l)
#define rw_rdlock(l) pthread_rwlock_rdlock(l)

View file

@ -868,15 +868,19 @@ dt_modtext(dtrace_hdl_t *dtp, char *p, int isenabled, GElf_Rela *rela,
/*
* We may have already processed this object file in an earlier linker
* invocation. Check to see if the present instruction sequence matches
* the one we would install.
* the one we would install below.
*/
if (isenabled) {
if (ip[0] == DT_OP_CLR_O0)
if (ip[0] == DT_OP_NOP) {
(*off) += sizeof (ip[0]);
return (0);
}
} else {
if (DT_IS_RESTORE(ip[1])) {
if (ip[0] == DT_OP_RET)
if (ip[0] == DT_OP_RET) {
(*off) += sizeof (ip[0]);
return (0);
}
} else if (DT_IS_MOV_O7(ip[1])) {
if (DT_IS_RETL(ip[0]))
return (0);
@ -910,7 +914,17 @@ dt_modtext(dtrace_hdl_t *dtp, char *p, int isenabled, GElf_Rela *rela,
return (-1);
}
ip[0] = DT_OP_CLR_O0;
/*
* On SPARC, we take advantage of the fact that the first
* argument shares the same register as for the return value.
* The macro handles the work of zeroing that register so we
* don't need to do anything special here. We instrument the
* instruction in the delay slot as we'll need to modify the
* return register after that instruction has been emulated.
*/
ip[0] = DT_OP_NOP;
(*off) += sizeof (ip[0]);
} else {
/*
* If the call is followed by a restore, it's a tail call so
@ -919,11 +933,16 @@ dt_modtext(dtrace_hdl_t *dtp, char *p, int isenabled, GElf_Rela *rela,
* so change the call to a retl-like instruction that returns
* to that register value + 8 (rather than the typical %o7 +
* 8); the delay slot instruction is left, but should have no
* effect. Otherwise we change the call to be a nop. In the
* first and the last case we adjust the offset to land on what
* was once the delay slot of the call so we correctly get all
* the arguments as they would have been passed in a normal
* function call.
* effect. Otherwise we change the call to be a nop. We
* identify the subsequent instruction as the probe point in
* all but the leaf tail-call case to ensure that arguments to
* the probe are complete and consistent. An astute, though
* largely hypothetical, observer would note that there is the
* possibility of a false-positive probe firing if the function
* contained a branch to the instruction in the delay slot of
* the call. Fixing this would require significant in-kernel
* modifications, and isn't worth doing until we see it in the
* wild.
*/
if (DT_IS_RESTORE(ip[1])) {
ip[0] = DT_OP_RET;

View file

@ -115,8 +115,9 @@
#define DT_VERS_1_5 DT_VERSION_NUMBER(1, 5, 0)
#define DT_VERS_1_6 DT_VERSION_NUMBER(1, 6, 0)
#define DT_VERS_1_6_1 DT_VERSION_NUMBER(1, 6, 1)
#define DT_VERS_LATEST DT_VERS_1_6_1
#define DT_VERS_STRING "Sun D 1.6.1"
#define DT_VERS_1_6_2 DT_VERSION_NUMBER(1, 6, 2)
#define DT_VERS_LATEST DT_VERS_1_6_2
#define DT_VERS_STRING "Sun D 1.6.2"
const dt_version_t _dtrace_versions[] = {
DT_VERS_1_0, /* D API 1.0.0 (PSARC 2001/466) Solaris 10 FCS */
@ -130,6 +131,7 @@ const dt_version_t _dtrace_versions[] = {
DT_VERS_1_5, /* D API 1.5 Solaris Express 7/07 */
DT_VERS_1_6, /* D API 1.6 */
DT_VERS_1_6_1, /* D API 1.6.1 */
DT_VERS_1_6_2, /* D API 1.6.2 */
0
};

View file

@ -955,7 +955,8 @@ dt_proc_create_thread(dtrace_hdl_t *dtp, dt_proc_t *dpr, uint_t stop)
}
struct ps_prochandle *
dt_proc_create(dtrace_hdl_t *dtp, const char *file, char *const *argv)
dt_proc_create(dtrace_hdl_t *dtp, const char *file, char *const *argv,
proc_child_func *pcf, void *child_arg)
{
dt_proc_hash_t *dph = dtp->dt_procs;
dt_proc_t *dpr;
@ -981,7 +982,7 @@ dt_proc_create(dtrace_hdl_t *dtp, const char *file, char *const *argv)
#else
(void) proc_clearflags(dpr->dpr_proc, PR_RLC);
(void) proc_setflags(dpr->dpr_proc, PR_KLC);
if ((err = proc_create(file, argv, &dpr->dpr_proc)) != 0)
if ((err = proc_create(file, argv, pcf, child_arg, &dpr->dpr_proc)) != 0)
return (dt_proc_error(dtp, dpr,
"failed to execute %s: %s\n", file, strerror(err)));
dpr->dpr_hdl = dtp;
@ -1183,10 +1184,11 @@ dt_proc_hash_destroy(dtrace_hdl_t *dtp)
}
struct ps_prochandle *
dtrace_proc_create(dtrace_hdl_t *dtp, const char *file, char *const *argv)
dtrace_proc_create(dtrace_hdl_t *dtp, const char *file, char *const *argv,
proc_child_func *pcf, void *child_arg)
{
dt_ident_t *idp = dt_idhash_lookup(dtp->dt_macros, "target");
struct ps_prochandle *P = dt_proc_create(dtp, file, argv);
struct ps_prochandle *P = dt_proc_create(dtp, file, argv, pcf, child_arg);
if (P != NULL && idp != NULL && idp->di_id == 0)
#if defined(sun)

View file

@ -99,7 +99,7 @@ typedef struct dt_proc_hash {
} dt_proc_hash_t;
extern struct ps_prochandle *dt_proc_create(dtrace_hdl_t *,
const char *, char *const *);
const char *, char *const *, proc_child_func *, void *);
extern struct ps_prochandle *dt_proc_grab(dtrace_hdl_t *, pid_t, int, int);
extern void dt_proc_release(dtrace_hdl_t *, struct ps_prochandle *);

View file

@ -20,7 +20,7 @@
*/
/*
* Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@ -436,8 +436,13 @@ dt_header_decl(dt_idhash_t *dhp, dt_ident_t *idp, void *data)
if (fprintf(infop->dthi_out, ");\n") < 0)
return (dt_set_errno(dtp, errno));
if (fprintf(infop->dthi_out, "extern int "
"__dtraceenabled_%s___%s(void);\n", infop->dthi_pfname, fname) < 0)
if (fprintf(infop->dthi_out,
"#ifndef\t__sparc\n"
"extern int __dtraceenabled_%s___%s(void);\n"
"#else\n"
"extern int __dtraceenabled_%s___%s(long);\n"
"#endif\n",
infop->dthi_pfname, fname, infop->dthi_pfname, fname) < 0)
return (dt_set_errno(dtp, errno));
return (0);
@ -499,13 +504,20 @@ dt_header_probe(dt_idhash_t *dhp, dt_ident_t *idp, void *data)
return (dt_set_errno(dtp, errno));
if (!infop->dthi_empty) {
if (fprintf(infop->dthi_out, "#define\t%s_%s_ENABLED() \\\n",
infop->dthi_pmname, mname) < 0)
return (dt_set_errno(dtp, errno));
if (fprintf(infop->dthi_out, "\t__dtraceenabled_%s___%s()\n",
if (fprintf(infop->dthi_out,
"#ifndef\t__sparc\n"
"#define\t%s_%s_ENABLED() \\\n"
"\t__dtraceenabled_%s___%s()\n"
"#else\n"
"#define\t%s_%s_ENABLED() \\\n"
"\t__dtraceenabled_%s___%s(0)\n"
"#endif\n",
infop->dthi_pmname, mname,
infop->dthi_pfname, fname,
infop->dthi_pmname, mname,
infop->dthi_pfname, fname) < 0)
return (dt_set_errno(dtp, errno));
} else {
if (fprintf(infop->dthi_out, "#define\t%s_%s_ENABLED() (0)\n",
infop->dthi_pmname, mname) < 0)

View file

@ -33,6 +33,7 @@
#include <stdarg.h>
#include <stdio.h>
#include <gelf.h>
#include <libproc.h>
#ifdef __cplusplus
extern "C" {
@ -413,7 +414,7 @@ extern int dtrace_aggregate_walk_valvarrevsorted(dtrace_hdl_t *,
*/
extern struct ps_prochandle *dtrace_proc_create(dtrace_hdl_t *,
const char *, char *const *);
const char *, char *const *, proc_child_func *, void *);
extern struct ps_prochandle *dtrace_proc_grab(dtrace_hdl_t *, pid_t, int);
extern void dtrace_proc_release(dtrace_hdl_t *, struct ps_prochandle *);

View file

@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (the "License"). You may not use this file except in compliance
* with the License.
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@ -20,12 +19,13 @@
* CDDL HEADER END
*/
/*
* Copyright 2004 Sun Microsystems, Inc. All rights reserved.
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
#include <inttypes.h>
#include <unistd.h>
#include <strings.h>
#include "libnvpair.h"
@ -137,6 +137,12 @@ nvlist_print_with_indent(FILE *fp, nvlist_t *nvl, int depth)
(void) fprintf(fp, " 0x%llx", (u_longlong_t)val);
break;
}
case DATA_TYPE_DOUBLE: {
double val;
(void) nvpair_value_double(nvp, &val);
(void) fprintf(fp, " 0x%llf", val);
break;
}
case DATA_TYPE_STRING: {
char *val;
(void) nvpair_value_string(nvp, &val);
@ -264,3 +270,348 @@ nvlist_print(FILE *fp, nvlist_t *nvl)
{
nvlist_print_with_indent(fp, nvl, 0);
}
/*
* Determine if string 'value' matches 'nvp' value. The 'value' string is
* converted, depending on the type of 'nvp', prior to match. For numeric
* types, a radix independent sscanf conversion of 'value' is used. If 'nvp'
* is an array type, 'ai' is the index into the array against which we are
* checking for match. If nvp is of DATA_TYPE_STRING*, the caller can pass
* in a regex_t compilation of value in 'value_regex' to trigger regular
* expression string match instead of simple strcmp().
*
* Return 1 on match, 0 on no-match, and -1 on error. If the error is
* related to value syntax error and 'ep' is non-NULL, *ep will point into
* the 'value' string at the location where the error exists.
*
* NOTE: It may be possible to move the non-regex_t version of this into
* common code used by library/kernel/boot.
*/
int
nvpair_value_match_regex(nvpair_t *nvp, int ai,
char *value, regex_t *value_regex, char **ep)
{
char *evalue;
uint_t a_len;
int sr;
if (ep)
*ep = NULL;
if ((nvp == NULL) || (value == NULL))
return (-1); /* error fail match - invalid args */
/* make sure array and index combination make sense */
if ((nvpair_type_is_array(nvp) && (ai < 0)) ||
(!nvpair_type_is_array(nvp) && (ai >= 0)))
return (-1); /* error fail match - bad index */
/* non-string values should be single 'chunk' */
if ((nvpair_type(nvp) != DATA_TYPE_STRING) &&
(nvpair_type(nvp) != DATA_TYPE_STRING_ARRAY)) {
value += strspn(value, " \t");
evalue = value + strcspn(value, " \t");
if (*evalue) {
if (ep)
*ep = evalue;
return (-1); /* error fail match - syntax */
}
}
sr = EOF;
switch (nvpair_type(nvp)) {
case DATA_TYPE_STRING: {
char *val;
/* check string value for match */
if (nvpair_value_string(nvp, &val) == 0) {
if (value_regex) {
if (regexec(value_regex, val,
(size_t)0, NULL, 0) == 0)
return (1); /* match */
} else {
if (strcmp(value, val) == 0)
return (1); /* match */
}
}
break;
}
case DATA_TYPE_STRING_ARRAY: {
char **val_array;
/* check indexed string value of array for match */
if ((nvpair_value_string_array(nvp, &val_array, &a_len) == 0) &&
(ai < a_len)) {
if (value_regex) {
if (regexec(value_regex, val_array[ai],
(size_t)0, NULL, 0) == 0)
return (1);
} else {
if (strcmp(value, val_array[ai]) == 0)
return (1);
}
}
break;
}
case DATA_TYPE_BYTE: {
uchar_t val, val_arg;
/* scanf uchar_t from value and check for match */
sr = sscanf(value, "%c", &val_arg);
if ((sr == 1) && (nvpair_value_byte(nvp, &val) == 0) &&
(val == val_arg))
return (1);
break;
}
case DATA_TYPE_BYTE_ARRAY: {
uchar_t *val_array, val_arg;
/* check indexed value of array for match */
sr = sscanf(value, "%c", &val_arg);
if ((sr == 1) &&
(nvpair_value_byte_array(nvp, &val_array, &a_len) == 0) &&
(ai < a_len) &&
(val_array[ai] == val_arg))
return (1);
break;
}
case DATA_TYPE_INT8: {
int8_t val, val_arg;
/* scanf int8_t from value and check for match */
sr = sscanf(value, "%"SCNi8, &val_arg);
if ((sr == 1) &&
(nvpair_value_int8(nvp, &val) == 0) &&
(val == val_arg))
return (1);
break;
}
case DATA_TYPE_INT8_ARRAY: {
int8_t *val_array, val_arg;
/* check indexed value of array for match */
sr = sscanf(value, "%"SCNi8, &val_arg);
if ((sr == 1) &&
(nvpair_value_int8_array(nvp, &val_array, &a_len) == 0) &&
(ai < a_len) &&
(val_array[ai] == val_arg))
return (1);
break;
}
case DATA_TYPE_UINT8: {
uint8_t val, val_arg;
/* scanf uint8_t from value and check for match */
sr = sscanf(value, "%"SCNi8, (int8_t *)&val_arg);
if ((sr == 1) &&
(nvpair_value_uint8(nvp, &val) == 0) &&
(val == val_arg))
return (1);
break;
}
case DATA_TYPE_UINT8_ARRAY: {
uint8_t *val_array, val_arg;
/* check indexed value of array for match */
sr = sscanf(value, "%"SCNi8, (int8_t *)&val_arg);
if ((sr == 1) &&
(nvpair_value_uint8_array(nvp, &val_array, &a_len) == 0) &&
(ai < a_len) &&
(val_array[ai] == val_arg))
return (1);
break;
}
case DATA_TYPE_INT16: {
int16_t val, val_arg;
/* scanf int16_t from value and check for match */
sr = sscanf(value, "%"SCNi16, &val_arg);
if ((sr == 1) &&
(nvpair_value_int16(nvp, &val) == 0) &&
(val == val_arg))
return (1);
break;
}
case DATA_TYPE_INT16_ARRAY: {
int16_t *val_array, val_arg;
/* check indexed value of array for match */
sr = sscanf(value, "%"SCNi16, &val_arg);
if ((sr == 1) &&
(nvpair_value_int16_array(nvp, &val_array, &a_len) == 0) &&
(ai < a_len) &&
(val_array[ai] == val_arg))
return (1);
break;
}
case DATA_TYPE_UINT16: {
uint16_t val, val_arg;
/* scanf uint16_t from value and check for match */
sr = sscanf(value, "%"SCNi16, (int16_t *)&val_arg);
if ((sr == 1) &&
(nvpair_value_uint16(nvp, &val) == 0) &&
(val == val_arg))
return (1);
break;
}
case DATA_TYPE_UINT16_ARRAY: {
uint16_t *val_array, val_arg;
/* check indexed value of array for match */
sr = sscanf(value, "%"SCNi16, (int16_t *)&val_arg);
if ((sr == 1) &&
(nvpair_value_uint16_array(nvp, &val_array, &a_len) == 0) &&
(ai < a_len) &&
(val_array[ai] == val_arg))
return (1);
break;
}
case DATA_TYPE_INT32: {
int32_t val, val_arg;
/* scanf int32_t from value and check for match */
sr = sscanf(value, "%"SCNi32, &val_arg);
if ((sr == 1) &&
(nvpair_value_int32(nvp, &val) == 0) &&
(val == val_arg))
return (1);
break;
}
case DATA_TYPE_INT32_ARRAY: {
int32_t *val_array, val_arg;
/* check indexed value of array for match */
sr = sscanf(value, "%"SCNi32, &val_arg);
if ((sr == 1) &&
(nvpair_value_int32_array(nvp, &val_array, &a_len) == 0) &&
(ai < a_len) &&
(val_array[ai] == val_arg))
return (1);
break;
}
case DATA_TYPE_UINT32: {
uint32_t val, val_arg;
/* scanf uint32_t from value and check for match */
sr = sscanf(value, "%"SCNi32, (int32_t *)&val_arg);
if ((sr == 1) &&
(nvpair_value_uint32(nvp, &val) == 0) &&
(val == val_arg))
return (1);
break;
}
case DATA_TYPE_UINT32_ARRAY: {
uint32_t *val_array, val_arg;
/* check indexed value of array for match */
sr = sscanf(value, "%"SCNi32, (int32_t *)&val_arg);
if ((sr == 1) &&
(nvpair_value_uint32_array(nvp, &val_array, &a_len) == 0) &&
(ai < a_len) &&
(val_array[ai] == val_arg))
return (1);
break;
}
case DATA_TYPE_INT64: {
int64_t val, val_arg;
/* scanf int64_t from value and check for match */
sr = sscanf(value, "%"SCNi64, &val_arg);
if ((sr == 1) &&
(nvpair_value_int64(nvp, &val) == 0) &&
(val == val_arg))
return (1);
break;
}
case DATA_TYPE_INT64_ARRAY: {
int64_t *val_array, val_arg;
/* check indexed value of array for match */
sr = sscanf(value, "%"SCNi64, &val_arg);
if ((sr == 1) &&
(nvpair_value_int64_array(nvp, &val_array, &a_len) == 0) &&
(ai < a_len) &&
(val_array[ai] == val_arg))
return (1);
break;
}
case DATA_TYPE_UINT64: {
uint64_t val_arg, val;
/* scanf uint64_t from value and check for match */
sr = sscanf(value, "%"SCNi64, (int64_t *)&val_arg);
if ((sr == 1) &&
(nvpair_value_uint64(nvp, &val) == 0) &&
(val == val_arg))
return (1);
break;
}
case DATA_TYPE_UINT64_ARRAY: {
uint64_t *val_array, val_arg;
/* check indexed value of array for match */
sr = sscanf(value, "%"SCNi64, (int64_t *)&val_arg);
if ((sr == 1) &&
(nvpair_value_uint64_array(nvp, &val_array, &a_len) == 0) &&
(ai < a_len) &&
(val_array[ai] == val_arg))
return (1);
break;
}
case DATA_TYPE_BOOLEAN_VALUE: {
boolean_t val, val_arg;
/* scanf boolean_t from value and check for match */
sr = sscanf(value, "%"SCNi32, &val_arg);
if ((sr == 1) &&
(nvpair_value_boolean_value(nvp, &val) == 0) &&
(val == val_arg))
return (1);
break;
}
case DATA_TYPE_BOOLEAN_ARRAY: {
boolean_t *val_array, val_arg;
/* check indexed value of array for match */
sr = sscanf(value, "%"SCNi32, &val_arg);
if ((sr == 1) &&
(nvpair_value_boolean_array(nvp,
&val_array, &a_len) == 0) &&
(ai < a_len) &&
(val_array[ai] == val_arg))
return (1);
break;
}
case DATA_TYPE_HRTIME:
case DATA_TYPE_NVLIST:
case DATA_TYPE_NVLIST_ARRAY:
case DATA_TYPE_BOOLEAN:
case DATA_TYPE_DOUBLE:
case DATA_TYPE_UNKNOWN:
default:
/*
* unknown/unsupported data type
*/
return (-1); /* error fail match */
}
/*
* check to see if sscanf failed conversion, return approximate
* pointer to problem
*/
if (sr != 1) {
if (ep)
*ep = value;
return (-1); /* error fail match - syntax */
}
return (0); /* fail match */
}
int
nvpair_value_match(nvpair_t *nvp, int ai, char *value, char **ep)
{
return (nvpair_value_match_regex(nvp, ai, value, NULL, ep));
}

View file

@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (the "License"). You may not use this file except in compliance
* with the License.
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
* Copyright 2005 Sun Microsystems, Inc. All rights reserved.
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@ -32,12 +31,15 @@
#include <sys/nvpair.h>
#include <stdlib.h>
#include <stdio.h>
#include <regex.h>
#ifdef __cplusplus
extern "C" {
#endif
void nvlist_print(FILE *, nvlist_t *);
int nvpair_value_match(nvpair_t *, int, char *, char **);
int nvpair_value_match_regex(nvpair_t *, int, char *, regex_t *, char **);
#ifdef __cplusplus
}

View file

@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (the "License"). You may not use this file except in compliance
* with the License.
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@ -20,15 +19,13 @@
* CDDL HEADER END
*/
/*
* Copyright 2005 Sun Microsystems, Inc. All rights reserved.
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#ifndef _LIBUUTIL_H
#define _LIBUUTIL_H
#pragma ident "%Z%%M% %I% %E% SMI"
#include <solaris.h>
#include <sys/types.h>
#include <stdarg.h>
@ -149,6 +146,7 @@ extern int uu_open_tmp(const char *dir, uint_t uflags);
/*PRINTFLIKE1*/
extern char *uu_msprintf(const char *format, ...);
extern void *uu_zalloc(size_t);
extern char *uu_strdup(const char *);
extern void uu_free(void *);
/*

View file

@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (the "License"). You may not use this file except in compliance
* with the License.
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@ -21,7 +20,7 @@
*/
/*
* Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@ -30,16 +29,6 @@
#pragma ident "%Z%%M% %I% %E% SMI"
#include <solaris.h>
/*
* We don't bind to the internal libc interfaces if this is a
* native build.
*/
#ifndef NATIVE_BUILD
#include "c_synonyms.h"
#endif
#include <libuutil.h>
#include <libuutil_impl.h>

View file

@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (the "License"). You may not use this file except in compliance
* with the License.
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@ -20,12 +19,10 @@
* CDDL HEADER END
*/
/*
* Copyright 2004 Sun Microsystems, Inc. All rights reserved.
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
#include "libuutil_common.h"
#include <stdarg.h>
@ -54,6 +51,22 @@ uu_free(void *p)
free(p);
}
char *
uu_strdup(const char *str)
{
char *buf = NULL;
if (str != NULL) {
size_t sz;
sz = strlen(str) + 1;
buf = uu_zalloc(sz);
if (buf != NULL)
(void) memcpy(buf, str, sz);
}
return (buf);
}
char *
uu_msprintf(const char *format, ...)
{

View file

@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
* Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@ -120,7 +120,8 @@ uu_avl_pool_destroy(uu_avl_pool_t *pp)
UU_PTR_ENCODE(&pp->uap_null_avl)) {
uu_panic("uu_avl_pool_destroy: Pool \"%.*s\" (%p) has "
"outstanding avls, or is corrupt.\n",
sizeof (pp->uap_name), pp->uap_name, pp);
(int)sizeof (pp->uap_name), pp->uap_name,
(void *)pp);
}
}
(void) pthread_mutex_lock(&uu_apool_list_lock);
@ -142,14 +143,14 @@ uu_avl_node_init(void *base, uu_avl_node_t *np, uu_avl_pool_t *pp)
if (offset + sizeof (*np) > pp->uap_objsize) {
uu_panic("uu_avl_node_init(%p, %p, %p (\"%s\")): "
"offset %ld doesn't fit in object (size %ld)\n",
base, np, pp, pp->uap_name, offset,
pp->uap_objsize);
base, (void *)np, (void *)pp, pp->uap_name,
(long)offset, (long)pp->uap_objsize);
}
if (offset != pp->uap_nodeoffset) {
uu_panic("uu_avl_node_init(%p, %p, %p (\"%s\")): "
"offset %ld doesn't match pool's offset (%ld)\n",
base, np, pp, pp->uap_name, offset,
pp->uap_objsize);
base, (void *)np, (void *)pp, pp->uap_name,
(long)offset, (long)pp->uap_objsize);
}
}
@ -166,12 +167,12 @@ uu_avl_node_fini(void *base, uu_avl_node_t *np, uu_avl_pool_t *pp)
if (na[0] == DEAD_MARKER && na[1] == DEAD_MARKER) {
uu_panic("uu_avl_node_fini(%p, %p, %p (\"%s\")): "
"node already finied\n",
base, np, pp, pp->uap_name);
base, (void *)np, (void *)pp, pp->uap_name);
}
if (na[0] != POOL_TO_MARKER(pp) || na[1] != 0) {
uu_panic("uu_avl_node_fini(%p, %p, %p (\"%s\")): "
"node corrupt, in tree, or in different pool\n",
base, np, pp, pp->uap_name);
base, (void *)np, (void *)pp, pp->uap_name);
}
}
@ -251,12 +252,13 @@ uu_avl_destroy(uu_avl_t *ap)
if (ap->ua_debug) {
if (avl_numnodes(&ap->ua_tree) != 0) {
uu_panic("uu_avl_destroy(%p): tree not empty\n", ap);
uu_panic("uu_avl_destroy(%p): tree not empty\n",
(void *)ap);
}
if (ap->ua_null_walk.uaw_next != &ap->ua_null_walk ||
ap->ua_null_walk.uaw_prev != &ap->ua_null_walk) {
uu_panic("uu_avl_destroy(%p): outstanding walkers\n",
ap);
(void *)ap);
}
}
(void) pthread_mutex_lock(&pp->uap_lock);
@ -441,7 +443,7 @@ uu_avl_remove(uu_avl_t *ap, void *elem)
(void) _avl_walk_advance(wp, ap);
} else if (wp->uaw_next_result != NULL) {
uu_panic("uu_avl_remove(%p, %p): active non-robust "
"walker\n", ap, elem);
"walker\n", (void *)ap, elem);
}
}
@ -497,19 +499,19 @@ uu_avl_insert(uu_avl_t *ap, void *elem, uu_avl_index_t idx)
if (na[1] != 0)
uu_panic("uu_avl_insert(%p, %p, %p): node already "
"in tree, or corrupt\n",
ap, elem, idx);
(void *)ap, elem, (void *)idx);
if (na[0] == 0)
uu_panic("uu_avl_insert(%p, %p, %p): node not "
"initialized\n",
ap, elem, idx);
(void *)ap, elem, (void *)idx);
if (na[0] != POOL_TO_MARKER(pp))
uu_panic("uu_avl_insert(%p, %p, %p): node from "
"other pool, or corrupt\n",
ap, elem, idx);
(void *)ap, elem, (void *)idx);
if (!INDEX_VALID(ap, idx))
uu_panic("uu_avl_insert(%p, %p, %p): %s\n",
ap, elem, idx,
(void *)ap, elem, (void *)idx,
INDEX_CHECK(idx)? "outdated index" :
"invalid index");
@ -526,8 +528,8 @@ uu_avl_nearest_next(uu_avl_t *ap, uu_avl_index_t idx)
{
if (ap->ua_debug && !INDEX_VALID(ap, idx))
uu_panic("uu_avl_nearest_next(%p, %p): %s\n",
ap, idx, INDEX_CHECK(idx)? "outdated index" :
"invalid index");
(void *)ap, (void *)idx, INDEX_CHECK(idx)?
"outdated index" : "invalid index");
return (avl_nearest(&ap->ua_tree, INDEX_DECODE(idx), AVL_AFTER));
}
@ -536,8 +538,8 @@ uu_avl_nearest_prev(uu_avl_t *ap, uu_avl_index_t idx)
{
if (ap->ua_debug && !INDEX_VALID(ap, idx))
uu_panic("uu_avl_nearest_prev(%p, %p): %s\n",
ap, idx, INDEX_CHECK(idx)? "outdated index" :
"invalid index");
(void *)ap, (void *)idx, INDEX_CHECK(idx)?
"outdated index" : "invalid index");
return (avl_nearest(&ap->ua_tree, INDEX_DECODE(idx), AVL_BEFORE));
}

View file

@ -33,7 +33,7 @@
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <strings.h>
#include <string.h>
#define FACILITY_FMT "%s (%s): "

View file

@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (the "License"). You may not use this file except in compliance
* with the License.
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
* Copyright 2005 Sun Microsystems, Inc. All rights reserved.
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@ -117,7 +116,8 @@ uu_list_pool_destroy(uu_list_pool_t *pp)
UU_PTR_ENCODE(&pp->ulp_null_list)) {
uu_panic("uu_list_pool_destroy: Pool \"%.*s\" (%p) has "
"outstanding lists, or is corrupt.\n",
sizeof (pp->ulp_name), pp->ulp_name, pp);
(int)sizeof (pp->ulp_name), pp->ulp_name,
(void *)pp);
}
}
(void) pthread_mutex_lock(&uu_lpool_list_lock);
@ -139,14 +139,14 @@ uu_list_node_init(void *base, uu_list_node_t *np_arg, uu_list_pool_t *pp)
if (offset + sizeof (*np) > pp->ulp_objsize) {
uu_panic("uu_list_node_init(%p, %p, %p (\"%s\")): "
"offset %ld doesn't fit in object (size %ld)\n",
base, np, pp, pp->ulp_name, offset,
pp->ulp_objsize);
base, (void *)np, (void *)pp, pp->ulp_name,
(long)offset, (long)pp->ulp_objsize);
}
if (offset != pp->ulp_nodeoffset) {
uu_panic("uu_list_node_init(%p, %p, %p (\"%s\")): "
"offset %ld doesn't match pool's offset (%ld)\n",
base, np, pp, pp->ulp_name, offset,
pp->ulp_objsize);
base, (void *)np, (void *)pp, pp->ulp_name,
(long)offset, (long)pp->ulp_objsize);
}
}
np->uln_next = POOL_TO_MARKER(pp);
@ -163,13 +163,13 @@ uu_list_node_fini(void *base, uu_list_node_t *np_arg, uu_list_pool_t *pp)
np->uln_prev == NULL) {
uu_panic("uu_list_node_fini(%p, %p, %p (\"%s\")): "
"node already finied\n",
base, np_arg, pp, pp->ulp_name);
base, (void *)np_arg, (void *)pp, pp->ulp_name);
}
if (np->uln_next != POOL_TO_MARKER(pp) ||
np->uln_prev != NULL) {
uu_panic("uu_list_node_fini(%p, %p, %p (\"%s\")): "
"node corrupt or on list\n",
base, np_arg, pp, pp->ulp_name);
base, (void *)np_arg, (void *)pp, pp->ulp_name);
}
}
np->uln_next = NULL;
@ -190,7 +190,7 @@ uu_list_create(uu_list_pool_t *pp, void *parent, uint32_t flags)
if (pp->ulp_debug)
uu_panic("uu_list_create(%p, ...): requested "
"UU_LIST_SORTED, but pool has no comparison func\n",
pp);
(void *)pp);
uu_set_error(UU_ERROR_NOT_SUPPORTED);
return (NULL);
}
@ -236,16 +236,16 @@ uu_list_destroy(uu_list_t *lp)
if (lp->ul_null_node.uln_next != &lp->ul_null_node ||
lp->ul_null_node.uln_prev != &lp->ul_null_node) {
uu_panic("uu_list_destroy(%p): list not empty\n",
lp);
(void *)lp);
}
if (lp->ul_numnodes != 0) {
uu_panic("uu_list_destroy(%p): numnodes is nonzero, "
"but list is empty\n", lp);
"but list is empty\n", (void *)lp);
}
if (lp->ul_null_walk.ulw_next != &lp->ul_null_walk ||
lp->ul_null_walk.ulw_prev != &lp->ul_null_walk) {
uu_panic("uu_list_destroy(%p): outstanding walkers\n",
lp);
(void *)lp);
}
}
@ -266,13 +266,14 @@ list_insert(uu_list_t *lp, uu_list_node_impl_t *np, uu_list_node_impl_t *prev,
if (lp->ul_debug) {
if (next->uln_prev != prev || prev->uln_next != next)
uu_panic("insert(%p): internal error: %p and %p not "
"neighbors\n", lp, next, prev);
"neighbors\n", (void *)lp, (void *)next,
(void *)prev);
if (np->uln_next != POOL_TO_MARKER(lp->ul_pool) ||
np->uln_prev != NULL) {
uu_panic("insert(%p): elem %p node %p corrupt, "
"not initialized, or already in a list.\n",
lp, NODE_TO_ELEM(lp, np), np);
(void *)lp, NODE_TO_ELEM(lp, np), (void *)np);
}
/*
* invalidate outstanding uu_list_index_ts.
@ -299,12 +300,12 @@ uu_list_insert(uu_list_t *lp, void *elem, uu_list_index_t idx)
if (lp->ul_debug) {
if (!INDEX_VALID(lp, idx))
uu_panic("uu_list_insert(%p, %p, %p): %s\n",
lp, elem, idx,
(void *)lp, elem, (void *)idx,
INDEX_CHECK(idx)? "outdated index" :
"invalid index");
if (np->uln_prev == NULL)
uu_panic("uu_list_insert(%p, %p, %p): out-of-date "
"index\n", lp, elem, idx);
"index\n", (void *)lp, elem, (void *)idx);
}
list_insert(lp, ELEM_TO_NODE(lp, elem), np->uln_prev, np);
@ -354,11 +355,12 @@ uu_list_nearest_next(uu_list_t *lp, uu_list_index_t idx)
if (lp->ul_debug) {
if (!INDEX_VALID(lp, idx))
uu_panic("uu_list_nearest_next(%p, %p): %s\n",
lp, idx, INDEX_CHECK(idx)? "outdated index" :
(void *)lp, (void *)idx,
INDEX_CHECK(idx)? "outdated index" :
"invalid index");
if (np->uln_prev == NULL)
uu_panic("uu_list_nearest_next(%p, %p): out-of-date "
"index\n", lp, idx);
"index\n", (void *)lp, (void *)idx);
}
if (np == &lp->ul_null_node)
@ -378,11 +380,11 @@ uu_list_nearest_prev(uu_list_t *lp, uu_list_index_t idx)
if (lp->ul_debug) {
if (!INDEX_VALID(lp, idx))
uu_panic("uu_list_nearest_prev(%p, %p): %s\n",
lp, idx, INDEX_CHECK(idx)? "outdated index" :
"invalid index");
(void *)lp, (void *)idx, INDEX_CHECK(idx)?
"outdated index" : "invalid index");
if (np->uln_prev == NULL)
uu_panic("uu_list_nearest_prev(%p, %p): out-of-date "
"index\n", lp, idx);
"index\n", (void *)lp, (void *)idx);
}
if ((np = np->uln_prev) == &lp->ul_null_node)
@ -409,6 +411,11 @@ list_walk_init(uu_list_walk_t *wp, uu_list_t *lp, uint32_t flags)
wp->ulw_next_result = lp->ul_null_node.uln_prev;
if (lp->ul_debug || robust) {
/*
* Add this walker to the list's list of walkers so
* uu_list_remove() can advance us if somebody tries to
* remove ulw_next_result.
*/
wp->ulw_next = next = &lp->ul_null_walk;
wp->ulw_prev = prev = next->ulw_prev;
next->ulw_prev = wp;
@ -538,7 +545,7 @@ uu_list_remove(uu_list_t *lp, void *elem)
if (lp->ul_debug) {
if (np->uln_prev == NULL)
uu_panic("uu_list_remove(%p, %p): elem not on list\n",
lp, elem);
(void *)lp, elem);
/*
* invalidate outstanding uu_list_index_ts.
*/
@ -556,7 +563,7 @@ uu_list_remove(uu_list_t *lp, void *elem)
(void) list_walk_advance(wp, lp);
} else if (wp->ulw_next_result != NULL) {
uu_panic("uu_list_remove(%p, %p): active non-robust "
"walker\n", lp, elem);
"walker\n", (void *)lp, elem);
}
}
@ -578,8 +585,8 @@ uu_list_teardown(uu_list_t *lp, void **cookie)
* XXX: disable list modification until list is empty
*/
if (lp->ul_debug && *cookie != NULL)
uu_panic("uu_list_teardown(%p, %p): unexpected cookie\n", lp,
cookie);
uu_panic("uu_list_teardown(%p, %p): unexpected cookie\n",
(void *)lp, (void *)cookie);
ep = uu_list_first(lp);
if (ep)
@ -599,12 +606,12 @@ uu_list_insert_before(uu_list_t *lp, void *target, void *elem)
if (np->uln_prev == NULL)
uu_panic("uu_list_insert_before(%p, %p, %p): %p is "
"not currently on a list\n",
lp, target, elem, target);
(void *)lp, target, elem, target);
}
if (lp->ul_sorted) {
if (lp->ul_debug)
uu_panic("uu_list_insert_before(%p, ...): list is "
"UU_LIST_SORTED\n", lp);
"UU_LIST_SORTED\n", (void *)lp);
uu_set_error(UU_ERROR_NOT_SUPPORTED);
return (-1);
}
@ -625,12 +632,12 @@ uu_list_insert_after(uu_list_t *lp, void *target, void *elem)
if (np->uln_prev == NULL)
uu_panic("uu_list_insert_after(%p, %p, %p): %p is "
"not currently on a list\n",
lp, target, elem, target);
(void *)lp, target, elem, target);
}
if (lp->ul_sorted) {
if (lp->ul_debug)
uu_panic("uu_list_insert_after(%p, ...): list is "
"UU_LIST_SORTED\n", lp);
"UU_LIST_SORTED\n", (void *)lp);
uu_set_error(UU_ERROR_NOT_SUPPORTED);
return (-1);
}

View file

@ -20,21 +20,20 @@
*/
/*
* Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#ifndef _LIBZFS_H
#define _LIBZFS_H
#pragma ident "%Z%%M% %I% %E% SMI"
#include <assert.h>
#include <libnvpair.h>
#include <sys/param.h>
#include <sys/types.h>
#include <sys/varargs.h>
#include <sys/fs/zfs.h>
#include <sys/avl.h>
#include <sys/zfs_ioctl.h>
#ifdef __cplusplus
@ -47,6 +46,7 @@ extern "C" {
#define ZFS_MAXNAMELEN MAXNAMELEN
#define ZPOOL_MAXNAMELEN MAXNAMELEN
#define ZFS_MAXPROPLEN MAXPATHLEN
#define ZPOOL_MAXPROPLEN MAXPATHLEN
/*
* libzfs errors
@ -99,9 +99,61 @@ enum {
EZFS_POOL_NOTSUP, /* ops not supported for this type of pool */
EZFS_POOL_INVALARG, /* invalid argument for this pool operation */
EZFS_NAMETOOLONG, /* dataset name is too long */
EZFS_OPENFAILED, /* open of device failed */
EZFS_NOCAP, /* couldn't get capacity */
EZFS_LABELFAILED, /* write of label failed */
EZFS_ISCSISVCUNAVAIL, /* iscsi service unavailable */
EZFS_BADWHO, /* invalid permission who */
EZFS_BADPERM, /* invalid permission */
EZFS_BADPERMSET, /* invalid permission set name */
EZFS_NODELEGATION, /* delegated administration is disabled */
EZFS_PERMRDONLY, /* pemissions are readonly */
EZFS_UNSHARESMBFAILED, /* failed to unshare over smb */
EZFS_SHARESMBFAILED, /* failed to share over smb */
EZFS_BADCACHE, /* bad cache file */
EZFS_ISL2CACHE, /* device is for the level 2 ARC */
EZFS_VDEVNOTSUP, /* unsupported vdev type */
EZFS_NOTSUP, /* ops not supported on this dataset */
EZFS_ACTIVE_SPARE, /* pool has active shared spare devices */
EZFS_UNKNOWN
};
/*
* The following data structures are all part
* of the zfs_allow_t data structure which is
* used for printing 'allow' permissions.
* It is a linked list of zfs_allow_t's which
* then contain avl tree's for user/group/sets/...
* and each one of the entries in those trees have
* avl tree's for the permissions they belong to and
* whether they are local,descendent or local+descendent
* permissions. The AVL trees are used primarily for
* sorting purposes, but also so that we can quickly find
* a given user and or permission.
*/
typedef struct zfs_perm_node {
avl_node_t z_node;
char z_pname[MAXPATHLEN];
} zfs_perm_node_t;
typedef struct zfs_allow_node {
avl_node_t z_node;
char z_key[MAXPATHLEN]; /* name, such as joe */
avl_tree_t z_localdescend; /* local+descendent perms */
avl_tree_t z_local; /* local permissions */
avl_tree_t z_descend; /* descendent permissions */
} zfs_allow_node_t;
typedef struct zfs_allow {
struct zfs_allow *z_next;
char z_setpoint[MAXPATHLEN];
avl_tree_t z_sets;
avl_tree_t z_crperms;
avl_tree_t z_user;
avl_tree_t z_group;
avl_tree_t z_everyone;
} zfs_allow_t;
/*
* Basic handle types
*/
@ -131,12 +183,9 @@ extern zpool_handle_t *zpool_open(libzfs_handle_t *, const char *);
extern zpool_handle_t *zpool_open_canfail(libzfs_handle_t *, const char *);
extern void zpool_close(zpool_handle_t *);
extern const char *zpool_get_name(zpool_handle_t *);
extern uint64_t zpool_get_guid(zpool_handle_t *);
extern uint64_t zpool_get_space_used(zpool_handle_t *);
extern uint64_t zpool_get_space_total(zpool_handle_t *);
extern int zpool_get_root(zpool_handle_t *, char *, size_t);
extern int zpool_get_state(zpool_handle_t *);
extern uint64_t zpool_get_version(zpool_handle_t *);
extern char *zpool_state_to_name(vdev_state_t, vdev_aux_t);
extern void zpool_free_handles(libzfs_handle_t *);
/*
* Iterate over all active pools in the system.
@ -148,7 +197,7 @@ extern int zpool_iter(libzfs_handle_t *, zpool_iter_f, void *);
* Functions to create and destroy pools
*/
extern int zpool_create(libzfs_handle_t *, const char *, nvlist_t *,
const char *);
nvlist_t *, nvlist_t *);
extern int zpool_destroy(zpool_handle_t *);
extern int zpool_add(zpool_handle_t *, nvlist_t *);
@ -156,22 +205,33 @@ extern int zpool_add(zpool_handle_t *, nvlist_t *);
* Functions to manipulate pool and vdev state
*/
extern int zpool_scrub(zpool_handle_t *, pool_scrub_type_t);
extern int zpool_clear(zpool_handle_t *, const char *);
extern int zpool_vdev_online(zpool_handle_t *, const char *);
extern int zpool_vdev_offline(zpool_handle_t *, const char *, int);
extern int zpool_vdev_attach(zpool_handle_t *, const char *, const char *,
nvlist_t *, int);
extern int zpool_vdev_online(zpool_handle_t *, const char *, int,
vdev_state_t *);
extern int zpool_vdev_offline(zpool_handle_t *, const char *, boolean_t);
extern int zpool_vdev_attach(zpool_handle_t *, const char *,
const char *, nvlist_t *, int);
extern int zpool_vdev_detach(zpool_handle_t *, const char *);
extern int zpool_vdev_remove(zpool_handle_t *, const char *);
extern int zpool_clear(zpool_handle_t *, const char *);
extern nvlist_t *zpool_find_vdev(zpool_handle_t *, const char *, boolean_t *);
extern int zpool_vdev_fault(zpool_handle_t *, uint64_t);
extern int zpool_vdev_degrade(zpool_handle_t *, uint64_t);
extern int zpool_vdev_clear(zpool_handle_t *, uint64_t);
extern nvlist_t *zpool_find_vdev(zpool_handle_t *, const char *, boolean_t *,
boolean_t *, boolean_t *);
extern int zpool_label_disk(libzfs_handle_t *, zpool_handle_t *, char *);
/*
* Functions to manage pool properties
*/
extern int zpool_set_prop(zpool_handle_t *, const char *, const char *);
extern int zpool_get_prop(zpool_handle_t *, zfs_prop_t, char *,
size_t proplen, zfs_source_t *);
extern int zpool_get_prop(zpool_handle_t *, zpool_prop_t, char *,
size_t proplen, zprop_source_t *);
extern uint64_t zpool_get_prop_int(zpool_handle_t *, zpool_prop_t,
zprop_source_t *);
extern const char *zpool_prop_to_name(zpool_prop_t);
extern const char *zpool_prop_values(zpool_prop_t);
@ -194,6 +254,11 @@ typedef enum {
ZPOOL_STATUS_FAILING_DEV, /* device experiencing errors */
ZPOOL_STATUS_VERSION_NEWER, /* newer on-disk version */
ZPOOL_STATUS_HOSTID_MISMATCH, /* last accessed by another system */
ZPOOL_STATUS_IO_FAILURE_WAIT, /* failed I/O, failmode 'wait' */
ZPOOL_STATUS_IO_FAILURE_CONTINUE, /* failed I/O, failmode 'continue' */
ZPOOL_STATUS_FAULTED_DEV_R, /* faulted device with replicas */
ZPOOL_STATUS_FAULTED_DEV_NR, /* faulted device with no replicas */
ZPOOL_STATUS_BAD_LOG, /* cannot read log chain(s) */
/*
* The following are not faults per se, but still an error possibly
@ -223,26 +288,39 @@ extern int zpool_get_errlog(zpool_handle_t *, nvlist_t **);
/*
* Import and export functions
*/
extern int zpool_export(zpool_handle_t *);
extern int zpool_export(zpool_handle_t *, boolean_t);
extern int zpool_import(libzfs_handle_t *, nvlist_t *, const char *,
const char *);
char *altroot);
extern int zpool_import_props(libzfs_handle_t *, nvlist_t *, const char *,
nvlist_t *, boolean_t);
/*
* Search for pools to import
*/
extern nvlist_t *zpool_find_import(libzfs_handle_t *, int, char **);
extern nvlist_t *zpool_find_import_cached(libzfs_handle_t *, const char *,
char *, uint64_t);
extern nvlist_t *zpool_find_import_byname(libzfs_handle_t *, int, char **,
char *);
extern nvlist_t *zpool_find_import_byguid(libzfs_handle_t *, int, char **,
uint64_t);
extern nvlist_t *zpool_find_import_activeok(libzfs_handle_t *, int, char **);
/*
* Miscellaneous pool functions
*/
struct zfs_cmd;
extern char *zpool_vdev_name(libzfs_handle_t *, zpool_handle_t *, nvlist_t *);
extern int zpool_upgrade(zpool_handle_t *);
extern int zpool_upgrade(zpool_handle_t *, uint64_t);
extern int zpool_get_history(zpool_handle_t *, nvlist_t **);
extern void zpool_log_history(libzfs_handle_t *, int, char **, const char *,
boolean_t, boolean_t);
extern void zpool_set_history_str(const char *subcommand, int argc,
char **argv, char *history_str);
extern int zpool_stage_history(libzfs_handle_t *, const char *);
extern void zpool_obj_to_path(zpool_handle_t *, uint64_t, uint64_t, char *,
size_t len);
extern int zfs_ioctl(libzfs_handle_t *, unsigned long, struct zfs_cmd *);
extern int zpool_get_physpath(zpool_handle_t *, char *);
/*
* Basic handle manipulations. These functions do not create or destroy the
* underlying datasets, only the references to them.
@ -251,65 +329,84 @@ extern zfs_handle_t *zfs_open(libzfs_handle_t *, const char *, int);
extern void zfs_close(zfs_handle_t *);
extern zfs_type_t zfs_get_type(const zfs_handle_t *);
extern const char *zfs_get_name(const zfs_handle_t *);
extern zpool_handle_t *zfs_get_pool_handle(const zfs_handle_t *);
/*
* Property management functions. Some functions are shared with the kernel,
* and are found in sys/fs/zfs.h.
*/
/*
* zfs dataset property management
*/
extern const char *zfs_prop_default_string(zfs_prop_t);
extern uint64_t zfs_prop_default_numeric(zfs_prop_t);
extern const char *zfs_prop_column_name(zfs_prop_t);
extern boolean_t zfs_prop_align_right(zfs_prop_t);
extern nvlist_t *zfs_valid_proplist(libzfs_handle_t *, zfs_type_t,
nvlist_t *, uint64_t, zfs_handle_t *, const char *);
extern const char *zfs_prop_to_name(zfs_prop_t);
extern int zfs_prop_set(zfs_handle_t *, const char *, const char *);
extern int zfs_prop_get(zfs_handle_t *, zfs_prop_t, char *, size_t,
zfs_source_t *, char *, size_t, boolean_t);
zprop_source_t *, char *, size_t, boolean_t);
extern int zfs_prop_get_numeric(zfs_handle_t *, zfs_prop_t, uint64_t *,
zfs_source_t *, char *, size_t);
zprop_source_t *, char *, size_t);
extern uint64_t zfs_prop_get_int(zfs_handle_t *, zfs_prop_t);
extern const char *zfs_prop_get_string(zfs_handle_t *, zfs_prop_t);
extern int zfs_prop_inherit(zfs_handle_t *, const char *);
extern const char *zfs_prop_values(zfs_prop_t);
extern int zfs_prop_valid_for_type(zfs_prop_t, int);
extern const char *zfs_prop_default_string(zfs_prop_t prop);
extern uint64_t zfs_prop_default_numeric(zfs_prop_t);
extern int zfs_prop_is_string(zfs_prop_t prop);
extern const char *zfs_prop_column_name(zfs_prop_t);
extern boolean_t zfs_prop_align_right(zfs_prop_t);
extern void nicebool(int value, char *buf, size_t buflen);
extern nvlist_t *zfs_get_user_props(zfs_handle_t *);
typedef struct zfs_proplist {
zfs_prop_t pl_prop;
typedef struct zprop_list {
int pl_prop;
char *pl_user_prop;
struct zfs_proplist *pl_next;
struct zprop_list *pl_next;
boolean_t pl_all;
size_t pl_width;
boolean_t pl_fixed;
} zfs_proplist_t;
} zprop_list_t;
typedef zfs_proplist_t zpool_proplist_t;
extern int zfs_get_proplist(libzfs_handle_t *, char *, zfs_proplist_t **);
extern int zpool_get_proplist(libzfs_handle_t *, char *, zpool_proplist_t **);
extern int zfs_expand_proplist(zfs_handle_t *, zfs_proplist_t **);
extern int zpool_expand_proplist(zpool_handle_t *, zpool_proplist_t **);
extern void zfs_free_proplist(zfs_proplist_t *);
extern nvlist_t *zfs_get_user_props(zfs_handle_t *);
extern int zfs_expand_proplist(zfs_handle_t *, zprop_list_t **);
#define ZFS_MOUNTPOINT_NONE "none"
#define ZFS_MOUNTPOINT_LEGACY "legacy"
/*
* Functions for printing properties from zfs/zpool
* zpool property management
*/
typedef struct libzfs_get_cbdata {
extern int zpool_expand_proplist(zpool_handle_t *, zprop_list_t **);
extern const char *zpool_prop_default_string(zpool_prop_t);
extern uint64_t zpool_prop_default_numeric(zpool_prop_t);
extern const char *zpool_prop_column_name(zpool_prop_t);
extern boolean_t zpool_prop_align_right(zpool_prop_t);
/*
* Functions shared by zfs and zpool property management.
*/
extern int zprop_iter(zprop_func func, void *cb, boolean_t show_all,
boolean_t ordered, zfs_type_t type);
extern int zprop_get_list(libzfs_handle_t *, char *, zprop_list_t **,
zfs_type_t);
extern void zprop_free_list(zprop_list_t *);
/*
* Functions for printing zfs or zpool properties
*/
typedef struct zprop_get_cbdata {
int cb_sources;
int cb_columns[4];
int cb_colwidths[5];
boolean_t cb_scripted;
boolean_t cb_literal;
boolean_t cb_first;
zfs_proplist_t *cb_proplist;
} libzfs_get_cbdata_t;
zprop_list_t *cb_proplist;
zfs_type_t cb_type;
} zprop_get_cbdata_t;
void libzfs_print_one_property(const char *, libzfs_get_cbdata_t *,
const char *, const char *, zfs_source_t, const char *);
void zprop_print_one_property(const char *, zprop_get_cbdata_t *,
const char *, const char *, zprop_source_t, const char *);
#define GET_COL_NAME 1
#define GET_COL_PROPERTY 2
@ -331,26 +428,61 @@ extern int zfs_iter_snapshots(zfs_handle_t *, zfs_iter_f, void *);
*/
extern int zfs_create(libzfs_handle_t *, const char *, zfs_type_t,
nvlist_t *);
extern int zfs_create_ancestors(libzfs_handle_t *, const char *);
extern int zfs_destroy(zfs_handle_t *);
extern int zfs_destroy_snaps(zfs_handle_t *, char *);
extern int zfs_clone(zfs_handle_t *, const char *, nvlist_t *);
extern int zfs_snapshot(libzfs_handle_t *, const char *, boolean_t);
extern int zfs_rollback(zfs_handle_t *, zfs_handle_t *, int);
extern int zfs_rename(zfs_handle_t *, const char *, int);
extern int zfs_send(zfs_handle_t *, const char *, int);
extern int zfs_receive(libzfs_handle_t *, const char *, int, int, int,
boolean_t, int);
extern int zfs_snapshot(libzfs_handle_t *, const char *, boolean_t, nvlist_t *);
extern int zfs_rollback(zfs_handle_t *, zfs_handle_t *, boolean_t);
extern int zfs_rename(zfs_handle_t *, const char *, boolean_t);
extern int zfs_send(zfs_handle_t *, const char *, const char *,
boolean_t, boolean_t, boolean_t, boolean_t, int);
extern int zfs_promote(zfs_handle_t *);
typedef struct recvflags {
/* print informational messages (ie, -v was specified) */
int verbose : 1;
/* the destination is a prefix, not the exact fs (ie, -d) */
int isprefix : 1;
/* do not actually do the recv, just check if it would work (ie, -n) */
int dryrun : 1;
/* rollback/destroy filesystems as necessary (eg, -F) */
int force : 1;
/* set "canmount=off" on all modified filesystems */
int canmountoff : 1;
/* byteswap flag is used internally; callers need not specify */
int byteswap : 1;
} recvflags_t;
extern int zfs_receive(libzfs_handle_t *, const char *, recvflags_t,
int, avl_tree_t *);
/*
* Miscellaneous functions.
*/
extern const char *zfs_type_to_name(zfs_type_t);
extern void zfs_refresh_properties(zfs_handle_t *);
extern int zfs_name_valid(const char *, zfs_type_t);
extern int zfs_disable(zfs_handle_t *);
extern int zfs_enable(zfs_handle_t *);
extern zfs_handle_t *zfs_path_to_zhandle(libzfs_handle_t *, char *, zfs_type_t);
extern boolean_t zfs_dataset_exists(libzfs_handle_t *, const char *,
zfs_type_t);
extern int zfs_spa_version(zfs_handle_t *, int *);
/*
* dataset permission functions.
*/
extern int zfs_perm_set(zfs_handle_t *, nvlist_t *);
extern int zfs_perm_remove(zfs_handle_t *, nvlist_t *);
extern int zfs_build_perms(zfs_handle_t *, char *, char *,
zfs_deleg_who_type_t, zfs_deleg_inherit_t, nvlist_t **nvlist_t);
extern int zfs_perm_get(zfs_handle_t *, zfs_allow_t **);
extern void zfs_free_allows(zfs_allow_t *);
extern void zfs_deleg_permissions(void);
/*
* Mount support functions.
@ -369,15 +501,27 @@ extern int zfs_share(zfs_handle_t *);
extern int zfs_unshare(zfs_handle_t *);
/*
* Protocol-specifc share support functions.
* Protocol-specific share support functions.
*/
extern boolean_t zfs_is_shared_nfs(zfs_handle_t *, char **);
extern boolean_t zfs_is_shared_smb(zfs_handle_t *, char **);
extern int zfs_share_nfs(zfs_handle_t *);
extern int zfs_share_smb(zfs_handle_t *);
extern int zfs_shareall(zfs_handle_t *);
extern int zfs_unshare_nfs(zfs_handle_t *, const char *);
extern int zfs_unshare_smb(zfs_handle_t *, const char *);
extern int zfs_unshareall_nfs(zfs_handle_t *);
extern int zfs_unshareall_smb(zfs_handle_t *);
extern int zfs_unshareall_bypath(zfs_handle_t *, const char *);
extern int zfs_unshareall(zfs_handle_t *);
extern boolean_t zfs_is_shared_iscsi(zfs_handle_t *);
extern int zfs_share_iscsi(zfs_handle_t *);
extern int zfs_unshare_iscsi(zfs_handle_t *);
#ifdef TODO
extern int zfs_iscsi_perm_check(libzfs_handle_t *, char *, ucred_t *);
#endif
extern int zfs_deleg_share_nfs(libzfs_handle_t *, char *, char *,
void *, void *, int, zfs_share_op_t);
/*
* FreeBSD-specific jail support function.
@ -401,12 +545,6 @@ extern int zfs_jail(zfs_handle_t *, int, int);
extern void zfs_nicenum(uint64_t, char *, size_t);
extern int zfs_nicestrtonum(libzfs_handle_t *, const char *, uint64_t *);
/*
* Pool destroy special. Remove the device information without destroying
* the underlying dataset.
*/
extern int zfs_remove_link(zfs_handle_t *);
/*
* Given a device or file, determine if it is part of a pool.
*/
@ -424,6 +562,9 @@ extern int zpool_read_label(int, nvlist_t **);
extern int zpool_create_zvol_links(zpool_handle_t *);
extern int zpool_remove_zvol_links(zpool_handle_t *);
/* is this zvol valid for use as a dump device? */
extern int zvol_check_dump_config(char *);
/*
* Enable and disable datasets within a pool by mounting/unmounting and
* sharing/unsharing them.

View file

@ -20,12 +20,12 @@
*/
/*
* Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*
* Portions Copyright 2007 Ramprakash Jelari
*/
#pragma ident "%Z%%M% %I% %E% SMI"
#include <libintl.h>
#include <libuutil.h>
#include <stddef.h>
@ -65,18 +65,21 @@ typedef struct prop_changenode {
int cn_shared;
int cn_mounted;
int cn_zoned;
boolean_t cn_needpost; /* is postfix() needed? */
uu_list_node_t cn_listnode;
} prop_changenode_t;
struct prop_changelist {
zfs_prop_t cl_prop;
zfs_prop_t cl_realprop;
zfs_prop_t cl_shareprop; /* used with sharenfs/sharesmb */
uu_list_pool_t *cl_pool;
uu_list_t *cl_list;
boolean_t cl_waslegacy;
boolean_t cl_allchildren;
boolean_t cl_alldependents;
int cl_flags;
int cl_mflags; /* Mount flags */
int cl_gflags; /* Gather request flags */
boolean_t cl_haszonedchild;
boolean_t cl_sorted;
};
@ -84,7 +87,8 @@ struct prop_changelist {
/*
* If the property is 'mountpoint', go through and unmount filesystems as
* necessary. We don't do the same for 'sharenfs', because we can just re-share
* with different options without interrupting service.
* with different options without interrupting service. We do handle 'sharesmb'
* since there may be old resource names that need to be removed.
*/
int
changelist_prefix(prop_changelist_t *clp)
@ -92,11 +96,19 @@ changelist_prefix(prop_changelist_t *clp)
prop_changenode_t *cn;
int ret = 0;
if (clp->cl_prop != ZFS_PROP_MOUNTPOINT)
if (clp->cl_prop != ZFS_PROP_MOUNTPOINT &&
clp->cl_prop != ZFS_PROP_SHARESMB)
return (0);
for (cn = uu_list_first(clp->cl_list); cn != NULL;
cn = uu_list_next(clp->cl_list, cn)) {
/* if a previous loop failed, set the remaining to false */
if (ret == -1) {
cn->cn_needpost = B_FALSE;
continue;
}
/*
* If we are in the global zone, but this dataset is exported
* to a local zone, do nothing.
@ -114,8 +126,11 @@ changelist_prefix(prop_changelist_t *clp)
(void) zfs_unshare_iscsi(cn->cn_handle);
if (zvol_remove_link(cn->cn_handle->zfs_hdl,
cn->cn_handle->zfs_name) != 0)
cn->cn_handle->zfs_name) != 0) {
ret = -1;
cn->cn_needpost = B_FALSE;
(void) zfs_share_iscsi(cn->cn_handle);
}
break;
case ZFS_PROP_VOLSIZE:
@ -126,10 +141,28 @@ changelist_prefix(prop_changelist_t *clp)
(void) zfs_unshare_iscsi(cn->cn_handle);
break;
}
} else if (zfs_unmount(cn->cn_handle, NULL, clp->cl_flags) != 0)
ret = -1;
} else {
/*
* Do the property specific processing.
*/
switch (clp->cl_prop) {
case ZFS_PROP_MOUNTPOINT:
if (zfs_unmount(cn->cn_handle, NULL,
clp->cl_mflags) != 0) {
ret = -1;
cn->cn_needpost = B_FALSE;
}
break;
case ZFS_PROP_SHARESMB:
(void) zfs_unshare_smb(cn->cn_handle, NULL);
break;
}
}
}
if (ret == -1)
(void) changelist_postfix(clp);
return (ret);
}
@ -147,7 +180,8 @@ changelist_postfix(prop_changelist_t *clp)
{
prop_changenode_t *cn;
char shareopts[ZFS_MAXPROPLEN];
int ret = 0;
int errors = 0;
libzfs_handle_t *hdl;
/*
* If we're changing the mountpoint, attempt to destroy the underlying
@ -162,12 +196,29 @@ changelist_postfix(prop_changelist_t *clp)
if (clp->cl_prop == ZFS_PROP_MOUNTPOINT)
remove_mountpoint(cn->cn_handle);
/*
* It is possible that the changelist_prefix() used libshare
* to unshare some entries. Since libshare caches data, an
* attempt to reshare during postfix can fail unless libshare
* is uninitialized here so that it will reinitialize later.
*/
if (cn->cn_handle != NULL) {
hdl = cn->cn_handle->zfs_hdl;
assert(hdl != NULL);
zfs_uninit_libshare(hdl);
}
/*
* We walk the datasets in reverse, because we want to mount any parent
* datasets before mounting the children.
* datasets before mounting the children. We walk all datasets even if
* there are errors.
*/
for (cn = uu_list_last(clp->cl_list); cn != NULL;
cn = uu_list_prev(clp->cl_list, cn)) {
boolean_t sharenfs;
boolean_t sharesmb;
/*
* If we are in the global zone, but this dataset is exported
* to a local zone, do nothing.
@ -175,6 +226,11 @@ changelist_postfix(prop_changelist_t *clp)
if (getzoneid() == GLOBAL_ZONEID && cn->cn_zoned)
continue;
/* Only do post-processing if it's required */
if (!cn->cn_needpost)
continue;
cn->cn_needpost = B_FALSE;
zfs_refresh_properties(cn->cn_handle);
if (ZFS_IS_VOLUME(cn->cn_handle)) {
@ -185,7 +241,7 @@ changelist_postfix(prop_changelist_t *clp)
if (clp->cl_realprop == ZFS_PROP_NAME &&
zvol_create_link(cn->cn_handle->zfs_hdl,
cn->cn_handle->zfs_name) != 0) {
ret = -1;
errors++;
} else if (cn->cn_shared ||
clp->cl_prop == ZFS_PROP_SHAREISCSI) {
if (zfs_prop_get(cn->cn_handle,
@ -193,43 +249,55 @@ changelist_postfix(prop_changelist_t *clp)
sizeof (shareopts), NULL, NULL, 0,
B_FALSE) == 0 &&
strcmp(shareopts, "off") == 0) {
ret = zfs_unshare_iscsi(cn->cn_handle);
errors +=
zfs_unshare_iscsi(cn->cn_handle);
} else {
ret = zfs_share_iscsi(cn->cn_handle);
errors +=
zfs_share_iscsi(cn->cn_handle);
}
}
continue;
}
if ((clp->cl_waslegacy || cn->cn_mounted) &&
!zfs_is_mounted(cn->cn_handle, NULL) &&
/*
* Remount if previously mounted or mountpoint was legacy,
* or sharenfs or sharesmb property is set.
*/
sharenfs = ((zfs_prop_get(cn->cn_handle, ZFS_PROP_SHARENFS,
shareopts, sizeof (shareopts), NULL, NULL, 0,
B_FALSE) == 0) && (strcmp(shareopts, "off") != 0));
sharesmb = ((zfs_prop_get(cn->cn_handle, ZFS_PROP_SHARESMB,
shareopts, sizeof (shareopts), NULL, NULL, 0,
B_FALSE) == 0) && (strcmp(shareopts, "off") != 0));
if ((cn->cn_mounted || clp->cl_waslegacy || sharenfs ||
sharesmb) && !zfs_is_mounted(cn->cn_handle, NULL) &&
zfs_mount(cn->cn_handle, NULL, 0) != 0)
ret = -1;
errors++;
/*
* We always re-share even if the filesystem is currently
* shared, so that we can adopt any new options.
*/
if (cn->cn_shared ||
(clp->cl_prop == ZFS_PROP_SHARENFS && clp->cl_waslegacy)) {
if (zfs_prop_get(cn->cn_handle, ZFS_PROP_SHARENFS,
shareopts, sizeof (shareopts), NULL, NULL, 0,
B_FALSE) == 0 && strcmp(shareopts, "off") == 0) {
ret = zfs_unshare_nfs(cn->cn_handle, NULL);
} else {
ret = zfs_share_nfs(cn->cn_handle);
}
}
if (sharenfs)
errors += zfs_share_nfs(cn->cn_handle);
else if (cn->cn_shared || clp->cl_waslegacy)
errors += zfs_unshare_nfs(cn->cn_handle, NULL);
if (sharesmb)
errors += zfs_share_smb(cn->cn_handle);
else if (cn->cn_shared || clp->cl_waslegacy)
errors += zfs_unshare_smb(cn->cn_handle, NULL);
}
return (ret);
return (errors ? -1 : 0);
}
/*
* Is this "dataset" a child of "parent"?
*/
static boolean_t
boolean_t
isa_child_of(const char *dataset, const char *parent)
{
int len;
@ -280,21 +348,22 @@ changelist_rename(prop_changelist_t *clp, const char *src, const char *dst)
}
/*
* Given a gathered changelist for the 'sharenfs' property, unshare all the
* datasets in the list.
* Given a gathered changelist for the 'sharenfs' or 'sharesmb' property,
* unshare all the datasets in the list.
*/
int
changelist_unshare(prop_changelist_t *clp)
changelist_unshare(prop_changelist_t *clp, zfs_share_proto_t *proto)
{
prop_changenode_t *cn;
int ret = 0;
if (clp->cl_prop != ZFS_PROP_SHARENFS)
if (clp->cl_prop != ZFS_PROP_SHARENFS &&
clp->cl_prop != ZFS_PROP_SHARESMB)
return (0);
for (cn = uu_list_first(clp->cl_list); cn != NULL;
cn = uu_list_next(clp->cl_list, cn)) {
if (zfs_unshare_nfs(cn->cn_handle, NULL) != 0)
if (zfs_unshare_proto(cn->cn_handle, NULL, proto) != 0)
ret = -1;
}
@ -316,14 +385,14 @@ changelist_haszonedchild(prop_changelist_t *clp)
* Remove a node from a gathered list.
*/
void
changelist_remove(zfs_handle_t *zhp, prop_changelist_t *clp)
changelist_remove(prop_changelist_t *clp, const char *name)
{
prop_changenode_t *cn;
for (cn = uu_list_first(clp->cl_list); cn != NULL;
cn = uu_list_next(clp->cl_list, cn)) {
if (strcmp(cn->cn_handle->zfs_name, zhp->zfs_name) == 0) {
if (strcmp(cn->cn_handle->zfs_name, name) == 0) {
uu_list_remove(clp->cl_list, cn);
zfs_close(cn->cn_handle);
free(cn);
@ -363,7 +432,8 @@ change_one(zfs_handle_t *zhp, void *data)
char property[ZFS_MAXPROPLEN];
char where[64];
prop_changenode_t *cn;
zfs_source_t sourcetype;
zprop_source_t sourcetype;
zprop_source_t share_sourcetype;
/*
* We only want to unmount/unshare those filesystems that may inherit
@ -383,8 +453,25 @@ change_one(zfs_handle_t *zhp, void *data)
return (0);
}
/*
* If we are "watching" sharenfs or sharesmb
* then check out the companion property which is tracked
* in cl_shareprop
*/
if (clp->cl_shareprop != ZPROP_INVAL &&
zfs_prop_get(zhp, clp->cl_shareprop, property,
sizeof (property), &share_sourcetype, where, sizeof (where),
B_FALSE) != 0) {
zfs_close(zhp);
return (0);
}
if (clp->cl_alldependents || clp->cl_allchildren ||
sourcetype == ZFS_SRC_DEFAULT || sourcetype == ZFS_SRC_INHERITED) {
sourcetype == ZPROP_SRC_DEFAULT ||
sourcetype == ZPROP_SRC_INHERITED ||
(clp->cl_shareprop != ZPROP_INVAL &&
(share_sourcetype == ZPROP_SRC_DEFAULT ||
share_sourcetype == ZPROP_SRC_INHERITED))) {
if ((cn = zfs_alloc(zfs_get_handle(zhp),
sizeof (prop_changenode_t))) == NULL) {
zfs_close(zhp);
@ -392,9 +479,11 @@ change_one(zfs_handle_t *zhp, void *data)
}
cn->cn_handle = zhp;
cn->cn_mounted = zfs_is_mounted(zhp, NULL);
cn->cn_mounted = (clp->cl_gflags & CL_GATHER_MOUNT_ALWAYS) ||
zfs_is_mounted(zhp, NULL);
cn->cn_shared = zfs_is_shared(zhp);
cn->cn_zoned = zfs_prop_get_int(zhp, ZFS_PROP_ZONED);
cn->cn_needpost = B_TRUE;
/* Indicate if any child is exported to a local zone. */
if (getzoneid() == GLOBAL_ZONEID && cn->cn_zoned)
@ -467,7 +556,8 @@ compare_mountpoints(const void *a, const void *b, void *unused)
* mark whether it was shared beforehand.
*/
prop_changelist_t *
changelist_gather(zfs_handle_t *zhp, zfs_prop_t prop, int flags)
changelist_gather(zfs_handle_t *zhp, zfs_prop_t prop, int gather_flags,
int mnt_flags)
{
prop_changelist_t *clp;
prop_changenode_t *cn;
@ -484,7 +574,8 @@ changelist_gather(zfs_handle_t *zhp, zfs_prop_t prop, int flags)
* order, regardless of their position in the hierarchy.
*/
if (prop == ZFS_PROP_NAME || prop == ZFS_PROP_ZONED ||
prop == ZFS_PROP_MOUNTPOINT || prop == ZFS_PROP_SHARENFS) {
prop == ZFS_PROP_MOUNTPOINT || prop == ZFS_PROP_SHARENFS ||
prop == ZFS_PROP_SHARESMB) {
compare = compare_mountpoints;
clp->cl_sorted = B_TRUE;
}
@ -502,7 +593,8 @@ changelist_gather(zfs_handle_t *zhp, zfs_prop_t prop, int flags)
clp->cl_list = uu_list_create(clp->cl_pool, NULL,
clp->cl_sorted ? UU_LIST_SORTED : 0);
clp->cl_flags = flags;
clp->cl_gflags = gather_flags;
clp->cl_mflags = mnt_flags;
if (clp->cl_list == NULL) {
assert(uu_error() == UU_ERROR_NO_MEMORY);
@ -529,6 +621,8 @@ changelist_gather(zfs_handle_t *zhp, zfs_prop_t prop, int flags)
clp->cl_prop = ZFS_PROP_MOUNTPOINT;
} else if (prop == ZFS_PROP_VOLSIZE) {
clp->cl_prop = ZFS_PROP_MOUNTPOINT;
} else if (prop == ZFS_PROP_VERSION) {
clp->cl_prop = ZFS_PROP_MOUNTPOINT;
} else {
clp->cl_prop = prop;
}
@ -536,9 +630,19 @@ changelist_gather(zfs_handle_t *zhp, zfs_prop_t prop, int flags)
if (clp->cl_prop != ZFS_PROP_MOUNTPOINT &&
clp->cl_prop != ZFS_PROP_SHARENFS &&
clp->cl_prop != ZFS_PROP_SHARESMB &&
clp->cl_prop != ZFS_PROP_SHAREISCSI)
return (clp);
/*
* If watching SHARENFS or SHARESMB then
* also watch its companion property.
*/
if (clp->cl_prop == ZFS_PROP_SHARENFS)
clp->cl_shareprop = ZFS_PROP_SHARESMB;
else if (clp->cl_prop == ZFS_PROP_SHARESMB)
clp->cl_shareprop = ZFS_PROP_SHARENFS;
if (clp->cl_alldependents) {
if (zfs_iter_dependents(zhp, B_TRUE, change_one, clp) != 0) {
changelist_free(clp);
@ -554,7 +658,7 @@ changelist_gather(zfs_handle_t *zhp, zfs_prop_t prop, int flags)
* and can't tell the difference.
*/
if ((temp = zfs_open(zhp->zfs_hdl, zfs_get_name(zhp),
ZFS_TYPE_ANY)) == NULL) {
ZFS_TYPE_DATASET)) == NULL) {
changelist_free(clp);
return (NULL);
}
@ -571,9 +675,11 @@ changelist_gather(zfs_handle_t *zhp, zfs_prop_t prop, int flags)
}
cn->cn_handle = temp;
cn->cn_mounted = zfs_is_mounted(temp, NULL);
cn->cn_mounted = (clp->cl_gflags & CL_GATHER_MOUNT_ALWAYS) ||
zfs_is_mounted(temp, NULL);
cn->cn_shared = zfs_is_shared(temp);
cn->cn_zoned = zfs_prop_get_int(zhp, ZFS_PROP_ZONED);
cn->cn_needpost = B_TRUE;
uu_list_node_init(cn, &cn->cn_listnode, clp->cl_pool);
if (clp->cl_sorted) {
@ -586,14 +692,22 @@ changelist_gather(zfs_handle_t *zhp, zfs_prop_t prop, int flags)
}
/*
* If the property was previously 'legacy' or 'none', record this fact,
* as the behavior of changelist_postfix() will be different.
* If the mountpoint property was previously 'legacy', or 'none',
* record it as the behavior of changelist_postfix() will be different.
*/
if (zfs_prop_get(zhp, prop, property, sizeof (property),
if ((clp->cl_prop == ZFS_PROP_MOUNTPOINT) &&
(zfs_prop_get(zhp, prop, property, sizeof (property),
NULL, NULL, 0, B_FALSE) == 0 &&
(strcmp(property, "legacy") == 0 || strcmp(property, "none") == 0 ||
strcmp(property, "off") == 0))
clp->cl_waslegacy = B_TRUE;
(strcmp(property, "legacy") == 0 ||
strcmp(property, "none") == 0))) {
/*
* do not automatically mount ex-legacy datasets if
* we specifically set canmount to noauto
*/
if (zfs_prop_get_int(zhp, ZFS_PROP_CANMOUNT) !=
ZFS_CANMOUNT_NOAUTO)
clp->cl_waslegacy = B_TRUE;
}
return (clp);
}

File diff suppressed because it is too large Load diff

View file

@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
* Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@ -126,6 +126,8 @@ typedef struct zfs_graph {
zfs_vertex_t **zg_hash;
size_t zg_size;
size_t zg_nvertex;
const char *zg_root;
int zg_clone_count;
} zfs_graph_t;
/*
@ -255,7 +257,7 @@ zfs_vertex_sort_edges(zfs_vertex_t *zvp)
* datasets in the pool.
*/
static zfs_graph_t *
zfs_graph_create(libzfs_handle_t *hdl, size_t size)
zfs_graph_create(libzfs_handle_t *hdl, const char *dataset, size_t size)
{
zfs_graph_t *zgp = zfs_alloc(hdl, sizeof (zfs_graph_t));
@ -269,6 +271,9 @@ zfs_graph_create(libzfs_handle_t *hdl, size_t size)
return (NULL);
}
zgp->zg_root = dataset;
zgp->zg_clone_count = 0;
return (zgp);
}
@ -367,17 +372,16 @@ zfs_graph_add(libzfs_handle_t *hdl, zfs_graph_t *zgp, const char *source,
}
/*
* Iterate over all children of the given dataset, adding any vertices as
* necessary. Returns 0 if no cloned snapshots were seen, -1 if there was an
* error, or 1 otherwise. This is a simple recursive algorithm - the ZFS
* namespace typically is very flat. We manually invoke the necessary ioctl()
* calls to avoid the overhead and additional semantics of zfs_open().
* Iterate over all children of the given dataset, adding any vertices
* as necessary. Returns -1 if there was an error, or 0 otherwise.
* This is a simple recursive algorithm - the ZFS namespace typically
* is very flat. We manually invoke the necessary ioctl() calls to
* avoid the overhead and additional semantics of zfs_open().
*/
static int
iterate_children(libzfs_handle_t *hdl, zfs_graph_t *zgp, const char *dataset)
{
zfs_cmd_t zc = { 0 };
int ret = 0, err;
zfs_vertex_t *zvp;
/*
@ -390,18 +394,8 @@ iterate_children(libzfs_handle_t *hdl, zfs_graph_t *zgp, const char *dataset)
return (0);
/*
* We check the clone parent here instead of within the loop, so that if
* the root dataset has been promoted from a clone, we find its parent
* appropriately.
* Iterate over all children
*/
(void) strlcpy(zc.zc_name, dataset, sizeof (zc.zc_name));
if (ioctl(hdl->libzfs_fd, ZFS_IOC_OBJSET_STATS, &zc) == 0 &&
zc.zc_objset_stats.dds_clone_of[0] != '\0') {
if (zfs_graph_add(hdl, zgp, zc.zc_objset_stats.dds_clone_of,
zc.zc_name, zc.zc_objset_stats.dds_creation_txg) != 0)
return (-1);
}
for ((void) strlcpy(zc.zc_name, dataset, sizeof (zc.zc_name));
ioctl(hdl->libzfs_fd, ZFS_IOC_DATASET_LIST_NEXT, &zc) == 0;
(void) strlcpy(zc.zc_name, dataset, sizeof (zc.zc_name))) {
@ -417,9 +411,23 @@ iterate_children(libzfs_handle_t *hdl, zfs_graph_t *zgp, const char *dataset)
* dataset and clone statistics. If this fails, the dataset has
* since been removed, and we're pretty much screwed anyway.
*/
zc.zc_objset_stats.dds_origin[0] = '\0';
if (ioctl(hdl->libzfs_fd, ZFS_IOC_OBJSET_STATS, &zc) != 0)
continue;
if (zc.zc_objset_stats.dds_origin[0] != '\0') {
if (zfs_graph_add(hdl, zgp,
zc.zc_objset_stats.dds_origin, zc.zc_name,
zc.zc_objset_stats.dds_creation_txg) != 0)
return (-1);
/*
* Count origins only if they are contained in the graph
*/
if (isa_child_of(zc.zc_objset_stats.dds_origin,
zgp->zg_root))
zgp->zg_clone_count--;
}
/*
* Add an edge between the parent and the child.
*/
@ -428,19 +436,10 @@ iterate_children(libzfs_handle_t *hdl, zfs_graph_t *zgp, const char *dataset)
return (-1);
/*
* Iterate over all children
* Recursively visit child
*/
err = iterate_children(hdl, zgp, zc.zc_name);
if (err == -1)
if (iterate_children(hdl, zgp, zc.zc_name))
return (-1);
else if (err == 1)
ret = 1;
/*
* Indicate if we found a dataset with a non-zero clone count.
*/
if (zc.zc_objset_stats.dds_num_clones != 0)
ret = 1;
}
/*
@ -467,67 +466,84 @@ iterate_children(libzfs_handle_t *hdl, zfs_graph_t *zgp, const char *dataset)
zc.zc_objset_stats.dds_creation_txg) != 0)
return (-1);
/*
* Indicate if we found a dataset with a non-zero clone count.
*/
if (zc.zc_objset_stats.dds_num_clones != 0)
ret = 1;
zgp->zg_clone_count += zc.zc_objset_stats.dds_num_clones;
}
zvp->zv_visited = VISIT_SEEN;
return (ret);
return (0);
}
/*
* Construct a complete graph of all necessary vertices. First, we iterate over
* only our object's children. If we don't find any cloned snapshots, then we
* simple return that. Otherwise, we have to start at the pool root and iterate
* over all datasets.
* Returns false if there are no snapshots with dependent clones in this
* subtree or if all of those clones are also in this subtree. Returns
* true if there is an error or there are external dependents.
*/
static boolean_t
external_dependents(libzfs_handle_t *hdl, zfs_graph_t *zgp, const char *dataset)
{
zfs_cmd_t zc = { 0 };
/*
* Check whether this dataset is a clone or has clones since
* iterate_children() only checks the children.
*/
(void) strlcpy(zc.zc_name, dataset, sizeof (zc.zc_name));
if (ioctl(hdl->libzfs_fd, ZFS_IOC_OBJSET_STATS, &zc) != 0)
return (B_TRUE);
if (zc.zc_objset_stats.dds_origin[0] != '\0') {
if (zfs_graph_add(hdl, zgp,
zc.zc_objset_stats.dds_origin, zc.zc_name,
zc.zc_objset_stats.dds_creation_txg) != 0)
return (B_TRUE);
if (isa_child_of(zc.zc_objset_stats.dds_origin, dataset))
zgp->zg_clone_count--;
}
if ((zc.zc_objset_stats.dds_num_clones) ||
iterate_children(hdl, zgp, dataset))
return (B_TRUE);
return (zgp->zg_clone_count != 0);
}
/*
* Construct a complete graph of all necessary vertices. First, iterate over
* only our object's children. If no cloned snapshots are found, or all of
* the cloned snapshots are in this subtree then return a graph of the subtree.
* Otherwise, start at the root of the pool and iterate over all datasets.
*/
static zfs_graph_t *
construct_graph(libzfs_handle_t *hdl, const char *dataset)
{
zfs_graph_t *zgp = zfs_graph_create(hdl, ZFS_GRAPH_SIZE);
zfs_cmd_t zc = { 0 };
zfs_graph_t *zgp = zfs_graph_create(hdl, dataset, ZFS_GRAPH_SIZE);
int ret = 0;
if (zgp == NULL)
return (zgp);
/*
* We need to explicitly check whether this dataset has clones or not,
* since iterate_children() only checks the children.
*/
(void) strlcpy(zc.zc_name, dataset, sizeof (zc.zc_name));
(void) ioctl(hdl->libzfs_fd, ZFS_IOC_OBJSET_STATS, &zc);
if (zc.zc_objset_stats.dds_num_clones != 0 ||
(ret = iterate_children(hdl, zgp, dataset)) != 0) {
if ((strchr(dataset, '/') == NULL) ||
(external_dependents(hdl, zgp, dataset))) {
/*
* Determine pool name and try again.
*/
char *pool, *slash;
int len = strcspn(dataset, "/@") + 1;
char *pool = zfs_alloc(hdl, len);
if ((slash = strchr(dataset, '/')) != NULL ||
(slash = strchr(dataset, '@')) != NULL) {
pool = zfs_alloc(hdl, slash - dataset + 1);
if (pool == NULL) {
zfs_graph_destroy(zgp);
return (NULL);
}
(void) strncpy(pool, dataset, slash - dataset);
pool[slash - dataset] = '\0';
if (iterate_children(hdl, zgp, pool) == -1 ||
zfs_graph_add(hdl, zgp, pool, NULL, 0) != 0) {
free(pool);
zfs_graph_destroy(zgp);
return (NULL);
}
free(pool);
if (pool == NULL) {
zfs_graph_destroy(zgp);
return (NULL);
}
(void) strlcpy(pool, dataset, len);
if (iterate_children(hdl, zgp, pool) == -1 ||
zfs_graph_add(hdl, zgp, pool, NULL, 0) != 0) {
free(pool);
zfs_graph_destroy(zgp);
return (NULL);
}
free(pool);
}
if (ret == -1 || zfs_graph_add(hdl, zgp, dataset, NULL, 0) != 0) {

View file

@ -1,5 +1,5 @@
/*
* CDDL HEADER START
* CDDL HEADER SART
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
@ -20,21 +20,21 @@
*/
/*
* Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#ifndef _LIBFS_IMPL_H
#define _LIBFS_IMPL_H
#pragma ident "%Z%%M% %I% %E% SMI"
#include <sys/dmu.h>
#include <sys/fs/zfs.h>
#include <sys/zfs_ioctl.h>
#include <sys/zfs_acl.h>
#include <sys/spa.h>
#include <sys/nvpair.h>
#include <libshare.h>
#include <libuutil.h>
#include <libzfs.h>
@ -42,22 +42,33 @@
extern "C" {
#endif
#ifdef VERIFY
#undef VERIFY
#endif
#define VERIFY verify
struct libzfs_handle {
int libzfs_error;
int libzfs_fd;
FILE *libzfs_mnttab;
FILE *libzfs_sharetab;
zpool_handle_t *libzfs_pool_handles;
uu_avl_pool_t *libzfs_ns_avlpool;
uu_avl_t *libzfs_ns_avl;
uint64_t libzfs_ns_gen;
int libzfs_desc_active;
char libzfs_action[1024];
char libzfs_desc[1024];
char *libzfs_log_str;
int libzfs_printerr;
void *libzfs_sharehdl; /* libshare handle */
uint_t libzfs_shareflags;
};
#define ZFSSHARE_MISS 0x01 /* Didn't find entry in cache */
struct zfs_handle {
libzfs_handle_t *zfs_hdl;
zpool_handle_t *zpool_hdl;
char zfs_name[ZFS_MAXNAMELEN];
zfs_type_t zfs_type; /* type including snapshot */
zfs_type_t zfs_head_type; /* type excluding snapshot */
@ -66,7 +77,6 @@ struct zfs_handle {
nvlist_t *zfs_user_props;
boolean_t zfs_mntcheck;
char *zfs_mntopts;
char zfs_root[MAXPATHLEN];
};
/*
@ -77,14 +87,33 @@ struct zfs_handle {
struct zpool_handle {
libzfs_handle_t *zpool_hdl;
zpool_handle_t *zpool_next;
char zpool_name[ZPOOL_MAXNAMELEN];
int zpool_state;
size_t zpool_config_size;
nvlist_t *zpool_config;
nvlist_t *zpool_old_config;
nvlist_t *zpool_props;
diskaddr_t zpool_start_block;
};
typedef enum {
PROTO_NFS = 0,
PROTO_SMB = 1,
PROTO_END = 2
} zfs_share_proto_t;
/*
* The following can be used as a bitmask and any new values
* added must preserve that capability.
*/
typedef enum {
SHARED_NOT_SHARED = 0x0,
SHARED_ISCSI = 0x1,
SHARED_NFS = 0x2,
SHARED_SMB = 0x4
} zfs_share_type_t;
int zfs_error(libzfs_handle_t *, int, const char *);
int zfs_error_fmt(libzfs_handle_t *, int, const char *, ...);
void zfs_error_aux(libzfs_handle_t *, const char *, ...);
@ -101,20 +130,24 @@ int zpool_standard_error_fmt(libzfs_handle_t *, int, const char *, ...);
int get_dependents(libzfs_handle_t *, boolean_t, const char *, char ***,
size_t *);
int zfs_expand_proplist_common(libzfs_handle_t *, zfs_proplist_t **,
zfs_type_t);
int zfs_get_proplist_common(libzfs_handle_t *, char *, zfs_proplist_t **,
zfs_type_t);
zfs_prop_t zfs_prop_iter_common(zfs_prop_f, void *, zfs_type_t, boolean_t);
zfs_prop_t zfs_name_to_prop_common(const char *, zfs_type_t);
nvlist_t *zfs_validate_properties(libzfs_handle_t *, zfs_type_t, char *,
nvlist_t *, uint64_t, zfs_handle_t *zhp, const char *errbuf);
int zprop_parse_value(libzfs_handle_t *, nvpair_t *, int, zfs_type_t,
nvlist_t *, char **, uint64_t *, const char *);
int zprop_expand_list(libzfs_handle_t *hdl, zprop_list_t **plp,
zfs_type_t type);
/*
* Use this changelist_gather() flag to force attempting mounts
* on each change node regardless of whether or not it is currently
* mounted.
*/
#define CL_GATHER_MOUNT_ALWAYS 1
typedef struct prop_changelist prop_changelist_t;
int zcmd_alloc_dst_nvlist(libzfs_handle_t *, zfs_cmd_t *, size_t);
int zcmd_write_src_nvlist(libzfs_handle_t *, zfs_cmd_t *, nvlist_t *, size_t *);
int zcmd_write_src_nvlist(libzfs_handle_t *, zfs_cmd_t *, nvlist_t *);
int zcmd_write_conf_nvlist(libzfs_handle_t *, zfs_cmd_t *, nvlist_t *);
int zcmd_expand_dst_nvlist(libzfs_handle_t *, zfs_cmd_t *);
int zcmd_read_dst_nvlist(libzfs_handle_t *, zfs_cmd_t *, nvlist_t **);
void zcmd_free_nvlists(zfs_cmd_t *);
@ -122,13 +155,15 @@ void zcmd_free_nvlists(zfs_cmd_t *);
int changelist_prefix(prop_changelist_t *);
int changelist_postfix(prop_changelist_t *);
void changelist_rename(prop_changelist_t *, const char *, const char *);
void changelist_remove(zfs_handle_t *, prop_changelist_t *);
void changelist_remove(prop_changelist_t *, const char *);
void changelist_free(prop_changelist_t *);
prop_changelist_t *changelist_gather(zfs_handle_t *, zfs_prop_t, int);
int changelist_unshare(prop_changelist_t *);
prop_changelist_t *changelist_gather(zfs_handle_t *, zfs_prop_t, int, int);
int changelist_unshare(prop_changelist_t *, zfs_share_proto_t *);
int changelist_haszonedchild(prop_changelist_t *);
void remove_mountpoint(zfs_handle_t *);
int create_parents(libzfs_handle_t *, char *, int);
boolean_t isa_child_of(const char *dataset, const char *parent);
zfs_handle_t *make_dataset_handle(libzfs_handle_t *, const char *);
@ -137,10 +172,23 @@ int zpool_open_silent(libzfs_handle_t *, const char *, zpool_handle_t **);
int zvol_create_link(libzfs_handle_t *, const char *);
int zvol_remove_link(libzfs_handle_t *, const char *);
int zpool_iter_zvol(zpool_handle_t *, int (*)(const char *, void *), void *);
boolean_t zpool_name_valid(libzfs_handle_t *, boolean_t, const char *);
void namespace_clear(libzfs_handle_t *);
/*
* libshare (sharemgr) interfaces used internally.
*/
extern int zfs_init_libshare(libzfs_handle_t *, int);
extern void zfs_uninit_libshare(libzfs_handle_t *);
extern int zfs_parse_options(char *, zfs_share_proto_t);
extern int zfs_unshare_proto(zfs_handle_t *zhp,
const char *, zfs_share_proto_t *);
#ifdef __FreeBSD__
/*
* This is FreeBSD version of ioctl, because Solaris' ioctl() updates
* zc_nvlist_dst_size even if an error is returned, on FreeBSD if an

View file

@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
* Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@ -213,11 +213,13 @@ add_config(libzfs_handle_t *hdl, pool_list_t *pl, const char *path,
name_entry_t *ne;
/*
* If this is a hot spare not currently in use, add it to the list of
* names to translate, but don't do anything else.
* If this is a hot spare not currently in use or level 2 cache
* device, add it to the list of names to translate, but don't do
* anything else.
*/
if (nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_STATE,
&state) == 0 && state == POOL_STATE_SPARE &&
&state) == 0 &&
(state == POOL_STATE_SPARE || state == POOL_STATE_L2CACHE) &&
nvlist_lookup_uint64(config, ZPOOL_CONFIG_GUID, &vdev_guid) == 0) {
if ((ne = zfs_alloc(hdl, sizeof (name_entry_t))) == NULL)
return (-1);
@ -361,6 +363,46 @@ pool_active(libzfs_handle_t *hdl, const char *name, uint64_t guid,
return (0);
}
static nvlist_t *
refresh_config(libzfs_handle_t *hdl, nvlist_t *config)
{
nvlist_t *nvl;
zfs_cmd_t zc = { 0 };
int err;
if (zcmd_write_conf_nvlist(hdl, &zc, config) != 0)
return (NULL);
if (zcmd_alloc_dst_nvlist(hdl, &zc,
zc.zc_nvlist_conf_size * 2) != 0) {
zcmd_free_nvlists(&zc);
return (NULL);
}
while ((err = ioctl(hdl->libzfs_fd, ZFS_IOC_POOL_TRYIMPORT,
&zc)) != 0 && errno == ENOMEM) {
if (zcmd_expand_dst_nvlist(hdl, &zc) != 0) {
zcmd_free_nvlists(&zc);
return (NULL);
}
}
if (err) {
(void) zpool_standard_error(hdl, errno,
dgettext(TEXT_DOMAIN, "cannot discover pools"));
zcmd_free_nvlists(&zc);
return (NULL);
}
if (zcmd_read_dst_nvlist(hdl, &zc, &nvl) != 0) {
zcmd_free_nvlists(&zc);
return (NULL);
}
zcmd_free_nvlists(&zc);
return (nvl);
}
/*
* Convert our list of pools into the definitive set of configurations. We
* start by picking the best config for each toplevel vdev. Once that's done,
@ -369,26 +411,25 @@ pool_active(libzfs_handle_t *hdl, const char *name, uint64_t guid,
* return to the user.
*/
static nvlist_t *
get_configs(libzfs_handle_t *hdl, pool_list_t *pl)
get_configs(libzfs_handle_t *hdl, pool_list_t *pl, boolean_t active_ok)
{
pool_entry_t *pe;
vdev_entry_t *ve;
config_entry_t *ce;
nvlist_t *ret = NULL, *config = NULL, *tmp, *nvtop, *nvroot;
nvlist_t **spares;
uint_t i, nspares;
nvlist_t **spares, **l2cache;
uint_t i, nspares, nl2cache;
boolean_t config_seen;
uint64_t best_txg;
char *name, *hostname;
zfs_cmd_t zc = { 0 };
uint64_t version, guid;
size_t len;
int err;
uint_t children = 0;
nvlist_t **child = NULL;
uint_t c;
boolean_t isactive;
uint64_t hostid;
nvlist_t *nvl;
boolean_t found_one = B_FALSE;
if (nvlist_alloc(&ret, 0, 0) != 0)
goto nomem;
@ -570,6 +611,13 @@ get_configs(libzfs_handle_t *hdl, pool_list_t *pl)
}
nvlist_free(nvroot);
/*
* zdb uses this path to report on active pools that were
* imported or created using -R.
*/
if (active_ok)
goto add_pool;
/*
* Determine if this pool is currently active, in which case we
* can't actually import it.
@ -588,41 +636,11 @@ get_configs(libzfs_handle_t *hdl, pool_list_t *pl)
continue;
}
/*
* Try to do the import in order to get vdev state.
*/
if (zcmd_write_src_nvlist(hdl, &zc, config, &len) != 0)
if ((nvl = refresh_config(hdl, config)) == NULL)
goto error;
nvlist_free(config);
config = NULL;
if (zcmd_alloc_dst_nvlist(hdl, &zc, len * 2) != 0) {
zcmd_free_nvlists(&zc);
goto error;
}
while ((err = ioctl(hdl->libzfs_fd, ZFS_IOC_POOL_TRYIMPORT,
&zc)) != 0 && errno == ENOMEM) {
if (zcmd_expand_dst_nvlist(hdl, &zc) != 0) {
zcmd_free_nvlists(&zc);
goto error;
}
}
if (err) {
(void) zpool_standard_error(hdl, errno,
dgettext(TEXT_DOMAIN, "cannot discover pools"));
zcmd_free_nvlists(&zc);
goto error;
}
if (zcmd_read_dst_nvlist(hdl, &zc, &config) != 0) {
zcmd_free_nvlists(&zc);
goto error;
}
zcmd_free_nvlists(&zc);
config = nvl;
/*
* Go through and update the paths for spares, now that we have
@ -638,6 +656,17 @@ get_configs(libzfs_handle_t *hdl, pool_list_t *pl)
}
}
/*
* Update the paths for l2cache devices.
*/
if (nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_L2CACHE,
&l2cache, &nl2cache) == 0) {
for (i = 0; i < nl2cache; i++) {
if (fix_paths(l2cache[i], pl->names) != 0)
goto nomem;
}
}
/*
* Restore the original information read from the actual label.
*/
@ -652,6 +681,7 @@ get_configs(libzfs_handle_t *hdl, pool_list_t *pl)
hostname) == 0);
}
add_pool:
/*
* Add this pool to the list of configs.
*/
@ -660,10 +690,16 @@ get_configs(libzfs_handle_t *hdl, pool_list_t *pl)
if (nvlist_add_nvlist(ret, name, config) != 0)
goto nomem;
found_one = B_TRUE;
nvlist_free(config);
config = NULL;
}
if (!found_one) {
nvlist_free(ret);
ret = NULL;
}
return (ret);
nomem:
@ -682,8 +718,9 @@ get_configs(libzfs_handle_t *hdl, pool_list_t *pl)
* Return the offset of the given label.
*/
static uint64_t
label_offset(size_t size, int l)
label_offset(uint64_t size, int l)
{
ASSERT(P2PHASE_TYPED(size, sizeof (vdev_label_t), uint64_t) == 0);
return (l * sizeof (vdev_label_t) + (l < VDEV_LABELS / 2 ?
0 : size - VDEV_LABELS * sizeof (vdev_label_t)));
}
@ -698,19 +735,20 @@ zpool_read_label(int fd, nvlist_t **config)
struct stat64 statbuf;
int l;
vdev_label_t *label;
uint64_t state, txg;
uint64_t state, txg, size;
*config = NULL;
if (fstat64(fd, &statbuf) == -1)
return (0);
size = P2ALIGN_TYPED(statbuf.st_size, sizeof (vdev_label_t), uint64_t);
if ((label = malloc(sizeof (vdev_label_t))) == NULL)
return (-1);
for (l = 0; l < VDEV_LABELS; l++) {
if (pread(fd, label, sizeof (vdev_label_t),
label_offset(statbuf.st_size, l)) != sizeof (vdev_label_t))
if (pread64(fd, label, sizeof (vdev_label_t),
label_offset(size, l)) != sizeof (vdev_label_t))
continue;
if (nvlist_unpack(label->vl_vdev_phys.vp_nvlist,
@ -718,12 +756,12 @@ zpool_read_label(int fd, nvlist_t **config)
continue;
if (nvlist_lookup_uint64(*config, ZPOOL_CONFIG_POOL_STATE,
&state) != 0 || state > POOL_STATE_SPARE) {
&state) != 0 || state > POOL_STATE_L2CACHE) {
nvlist_free(*config);
continue;
}
if (state != POOL_STATE_SPARE &&
if (state != POOL_STATE_SPARE && state != POOL_STATE_L2CACHE &&
(nvlist_lookup_uint64(*config, ZPOOL_CONFIG_POOL_TXG,
&txg) != 0 || txg == 0)) {
nvlist_free(*config);
@ -739,31 +777,20 @@ zpool_read_label(int fd, nvlist_t **config)
return (0);
}
/*
* Given a list of directories to search, find all pools stored on disk. This
* includes partial pools which are not available to import. If no args are
* given (argc is 0), then the default directory (/dev) is searched.
*/
nvlist_t *
zpool_find_import(libzfs_handle_t *hdl, int argc, char **argv)
static int
geom_find_import(libzfs_handle_t *hdl, pool_list_t *pools)
{
int i;
char path[MAXPATHLEN];
nvlist_t *ret = NULL, *config;
int fd;
pool_list_t pools = { 0 };
pool_entry_t *pe, *penext;
vdev_entry_t *ve, *venext;
config_entry_t *ce, *cenext;
name_entry_t *ne, *nenext;
struct gmesh mesh;
struct gclass *mp;
struct ggeom *gp;
struct gprovider *pp;
nvlist_t *config;
int fd, ret = 0;
/*
* Go through and read the label configuration information from every
* possible device, organizing the information according to pool GUID
* GEOM provider, organizing the information according to pool GUID
* and toplevel GUID.
*/
@ -773,32 +800,183 @@ zpool_find_import(libzfs_handle_t *hdl, int argc, char **argv)
LIST_FOREACH(mp, &mesh.lg_class, lg_class) {
LIST_FOREACH(gp, &mp->lg_geom, lg_geom) {
LIST_FOREACH(pp, &gp->lg_provider, lg_provider) {
if ((fd = g_open(pp->lg_name, 0)) < 0)
continue;
(void) snprintf(path, sizeof (path), "%s%s",
_PATH_DEV, pp->lg_name);
if ((fd = open64(path, O_RDONLY)) < 0)
continue;
if ((zpool_read_label(fd, &config)) != 0) {
(void) g_close(fd);
(void) no_memory(hdl);
goto error;
}
(void) close(fd);
(void) g_close(fd);
if (config == NULL)
continue;
if (add_config(hdl, pools, path, config) != 0) {
ret = -1;
goto error;
}
}
}
}
error:
geom_deletetree(&mesh);
return (ret);
}
/*
* Given a list of directories to search, find all pools stored on disk. This
* includes partial pools which are not available to import. If no args are
* given (argc is 0), then the default directory (/dev/dsk) is searched.
* poolname or guid (but not both) are provided by the caller when trying
* to import a specific pool.
*/
static nvlist_t *
zpool_find_import_impl(libzfs_handle_t *hdl, int argc, char **argv,
boolean_t active_ok, char *poolname, uint64_t guid)
{
int i;
DIR *dirp = NULL;
struct dirent64 *dp;
char path[MAXPATHLEN];
char *end;
size_t pathleft;
struct stat64 statbuf;
nvlist_t *ret = NULL, *config;
static char *default_dir = "/dev/dsk";
int fd;
pool_list_t pools = { 0 };
pool_entry_t *pe, *penext;
vdev_entry_t *ve, *venext;
config_entry_t *ce, *cenext;
name_entry_t *ne, *nenext;
verify(poolname == NULL || guid == 0);
if (argc == 0) {
argc = 1;
argv = &default_dir;
}
/*
* Go through and read the label configuration information from every
* possible device, organizing the information according to pool GUID
* and toplevel GUID.
*/
for (i = 0; i < argc; i++) {
char *rdsk;
int dfd;
/* use realpath to normalize the path */
if (realpath(argv[i], path) == 0) {
(void) zfs_error_fmt(hdl, EZFS_BADPATH,
dgettext(TEXT_DOMAIN, "cannot open '%s'"),
argv[i]);
goto error;
}
end = &path[strlen(path)];
*end++ = '/';
*end = 0;
pathleft = &path[sizeof (path)] - end;
if (strcmp(argv[i], default_dir) == 0) {
geom_find_import(hdl, &pools);
continue;
}
/*
* Using raw devices instead of block devices when we're
* reading the labels skips a bunch of slow operations during
* close(2) processing, so we replace /dev/dsk with /dev/rdsk.
*/
if (strcmp(path, "/dev/dsk/") == 0)
rdsk = "/dev/rdsk/";
else
rdsk = path;
if ((dirp = opendir(rdsk)) == NULL) {
zfs_error_aux(hdl, strerror(errno));
(void) zfs_error_fmt(hdl, EZFS_BADPATH,
dgettext(TEXT_DOMAIN, "cannot open '%s'"),
rdsk);
goto error;
}
/*
* This is not MT-safe, but we have no MT consumers of libzfs
*/
while ((dp = readdir64(dirp)) != NULL) {
const char *name = dp->d_name;
if (name[0] == '.' &&
(name[1] == 0 || (name[1] == '.' && name[2] == 0)))
continue;
(void) snprintf(path, sizeof (path), "%s/%s", rdsk,
dp->d_name);
if ((fd = open64(path, O_RDONLY)) < 0)
continue;
/*
* Ignore failed stats. We only want regular
* files, character devs and block devs.
*/
if (fstat64(fd, &statbuf) != 0 ||
(!S_ISREG(statbuf.st_mode) &&
!S_ISCHR(statbuf.st_mode) &&
!S_ISBLK(statbuf.st_mode))) {
(void) close(fd);
continue;
}
if ((zpool_read_label(fd, &config)) != 0) {
(void) close(fd);
(void) no_memory(hdl);
goto error;
}
(void) close(fd);
if (config != NULL) {
boolean_t matched = B_TRUE;
if (poolname != NULL) {
char *pname;
matched = nvlist_lookup_string(config,
ZPOOL_CONFIG_POOL_NAME,
&pname) == 0 &&
strcmp(poolname, pname) == 0;
} else if (guid != 0) {
uint64_t this_guid;
matched = nvlist_lookup_uint64(config,
ZPOOL_CONFIG_POOL_GUID,
&this_guid) == 0 &&
guid == this_guid;
}
if (!matched) {
nvlist_free(config);
config = NULL;
continue;
}
/* use the non-raw path for the config */
(void) strlcpy(end, name, pathleft);
if (add_config(hdl, &pools, path, config) != 0)
goto error;
}
}
(void) closedir(dirp);
dirp = NULL;
}
geom_deletetree(&mesh);
ret = get_configs(hdl, &pools);
ret = get_configs(hdl, &pools, active_ok);
error:
for (pe = pools.pools; pe != NULL; pe = penext) {
@ -823,9 +1001,158 @@ zpool_find_import(libzfs_handle_t *hdl, int argc, char **argv)
free(ne);
}
if (dirp)
(void) closedir(dirp);
return (ret);
}
nvlist_t *
zpool_find_import(libzfs_handle_t *hdl, int argc, char **argv)
{
return (zpool_find_import_impl(hdl, argc, argv, B_FALSE, NULL, 0));
}
nvlist_t *
zpool_find_import_byname(libzfs_handle_t *hdl, int argc, char **argv,
char *pool)
{
return (zpool_find_import_impl(hdl, argc, argv, B_FALSE, pool, 0));
}
nvlist_t *
zpool_find_import_byguid(libzfs_handle_t *hdl, int argc, char **argv,
uint64_t guid)
{
return (zpool_find_import_impl(hdl, argc, argv, B_FALSE, NULL, guid));
}
nvlist_t *
zpool_find_import_activeok(libzfs_handle_t *hdl, int argc, char **argv)
{
return (zpool_find_import_impl(hdl, argc, argv, B_TRUE, NULL, 0));
}
/*
* Given a cache file, return the contents as a list of importable pools.
* poolname or guid (but not both) are provided by the caller when trying
* to import a specific pool.
*/
nvlist_t *
zpool_find_import_cached(libzfs_handle_t *hdl, const char *cachefile,
char *poolname, uint64_t guid)
{
char *buf;
int fd;
struct stat64 statbuf;
nvlist_t *raw, *src, *dst;
nvlist_t *pools;
nvpair_t *elem;
char *name;
uint64_t this_guid;
boolean_t active;
verify(poolname == NULL || guid == 0);
if ((fd = open(cachefile, O_RDONLY)) < 0) {
zfs_error_aux(hdl, "%s", strerror(errno));
(void) zfs_error(hdl, EZFS_BADCACHE,
dgettext(TEXT_DOMAIN, "failed to open cache file"));
return (NULL);
}
if (fstat64(fd, &statbuf) != 0) {
zfs_error_aux(hdl, "%s", strerror(errno));
(void) close(fd);
(void) zfs_error(hdl, EZFS_BADCACHE,
dgettext(TEXT_DOMAIN, "failed to get size of cache file"));
return (NULL);
}
if ((buf = zfs_alloc(hdl, statbuf.st_size)) == NULL) {
(void) close(fd);
return (NULL);
}
if (read(fd, buf, statbuf.st_size) != statbuf.st_size) {
(void) close(fd);
free(buf);
(void) zfs_error(hdl, EZFS_BADCACHE,
dgettext(TEXT_DOMAIN,
"failed to read cache file contents"));
return (NULL);
}
(void) close(fd);
if (nvlist_unpack(buf, statbuf.st_size, &raw, 0) != 0) {
free(buf);
(void) zfs_error(hdl, EZFS_BADCACHE,
dgettext(TEXT_DOMAIN,
"invalid or corrupt cache file contents"));
return (NULL);
}
free(buf);
/*
* Go through and get the current state of the pools and refresh their
* state.
*/
if (nvlist_alloc(&pools, 0, 0) != 0) {
(void) no_memory(hdl);
nvlist_free(raw);
return (NULL);
}
elem = NULL;
while ((elem = nvlist_next_nvpair(raw, elem)) != NULL) {
verify(nvpair_value_nvlist(elem, &src) == 0);
verify(nvlist_lookup_string(src, ZPOOL_CONFIG_POOL_NAME,
&name) == 0);
if (poolname != NULL && strcmp(poolname, name) != 0)
continue;
verify(nvlist_lookup_uint64(src, ZPOOL_CONFIG_POOL_GUID,
&this_guid) == 0);
if (guid != 0) {
verify(nvlist_lookup_uint64(src, ZPOOL_CONFIG_POOL_GUID,
&this_guid) == 0);
if (guid != this_guid)
continue;
}
if (pool_active(hdl, name, this_guid, &active) != 0) {
nvlist_free(raw);
nvlist_free(pools);
return (NULL);
}
if (active)
continue;
if ((dst = refresh_config(hdl, src)) == NULL) {
nvlist_free(raw);
nvlist_free(pools);
return (NULL);
}
if (nvlist_add_nvlist(pools, nvpair_name(elem), dst) != 0) {
(void) no_memory(hdl);
nvlist_free(dst);
nvlist_free(raw);
nvlist_free(pools);
return (NULL);
}
nvlist_free(dst);
}
nvlist_free(raw);
return (pools);
}
boolean_t
find_guid(nvlist_t *nv, uint64_t guid)
{
@ -847,27 +1174,28 @@ find_guid(nvlist_t *nv, uint64_t guid)
return (B_FALSE);
}
typedef struct spare_cbdata {
typedef struct aux_cbdata {
const char *cb_type;
uint64_t cb_guid;
zpool_handle_t *cb_zhp;
} spare_cbdata_t;
} aux_cbdata_t;
static int
find_spare(zpool_handle_t *zhp, void *data)
find_aux(zpool_handle_t *zhp, void *data)
{
spare_cbdata_t *cbp = data;
nvlist_t **spares;
uint_t i, nspares;
aux_cbdata_t *cbp = data;
nvlist_t **list;
uint_t i, count;
uint64_t guid;
nvlist_t *nvroot;
verify(nvlist_lookup_nvlist(zhp->zpool_config, ZPOOL_CONFIG_VDEV_TREE,
&nvroot) == 0);
if (nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_SPARES,
&spares, &nspares) == 0) {
for (i = 0; i < nspares; i++) {
verify(nvlist_lookup_uint64(spares[i],
if (nvlist_lookup_nvlist_array(nvroot, cbp->cb_type,
&list, &count) == 0) {
for (i = 0; i < count; i++) {
verify(nvlist_lookup_uint64(list[i],
ZPOOL_CONFIG_GUID, &guid) == 0);
if (guid == cbp->cb_guid) {
cbp->cb_zhp = zhp;
@ -896,7 +1224,7 @@ zpool_in_use(libzfs_handle_t *hdl, int fd, pool_state_t *state, char **namestr,
zpool_handle_t *zhp;
nvlist_t *pool_config;
uint64_t stateval, isspare;
spare_cbdata_t cb = { 0 };
aux_cbdata_t cb = { 0 };
boolean_t isactive;
*inuse = B_FALSE;
@ -914,7 +1242,7 @@ zpool_in_use(libzfs_handle_t *hdl, int fd, pool_state_t *state, char **namestr,
verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_GUID,
&vdev_guid) == 0);
if (stateval != POOL_STATE_SPARE) {
if (stateval != POOL_STATE_SPARE && stateval != POOL_STATE_L2CACHE) {
verify(nvlist_lookup_string(config, ZPOOL_CONFIG_POOL_NAME,
&name) == 0);
verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_GUID,
@ -993,7 +1321,24 @@ zpool_in_use(libzfs_handle_t *hdl, int fd, pool_state_t *state, char **namestr,
*/
cb.cb_zhp = NULL;
cb.cb_guid = vdev_guid;
if (zpool_iter(hdl, find_spare, &cb) == 1) {
cb.cb_type = ZPOOL_CONFIG_SPARES;
if (zpool_iter(hdl, find_aux, &cb) == 1) {
name = (char *)zpool_get_name(cb.cb_zhp);
ret = TRUE;
} else {
ret = FALSE;
}
break;
case POOL_STATE_L2CACHE:
/*
* Check if any pool is currently using this l2cache device.
*/
cb.cb_zhp = NULL;
cb.cb_guid = vdev_guid;
cb.cb_type = ZPOOL_CONFIG_L2CACHE;
if (zpool_iter(hdl, find_aux, &cb) == 1) {
name = (char *)zpool_get_name(cb.cb_zhp);
ret = TRUE;
} else {
@ -1008,6 +1353,8 @@ zpool_in_use(libzfs_handle_t *hdl, int fd, pool_state_t *state, char **namestr,
if (ret) {
if ((*namestr = zfs_strdup(hdl, name)) == NULL) {
if (cb.cb_zhp)
zpool_close(cb.cb_zhp);
nvlist_free(config);
return (-1);
}

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -19,18 +19,16 @@
* CDDL HEADER END
*/
/*
* Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
/*
* This file contains the functions which analyze the status of a pool. This
* include both the status of an active pool, as well as the status exported
* pools. Returns one of the ZPOOL_STATUS_* defines describing the status of
* the pool. This status is independent (to a certain degree) from the state of
* the pool. A pool's state descsribes only whether or not it is capable of
* the pool. A pool's state describes only whether or not it is capable of
* providing the necessary fault tolerance for data. The status describes the
* overall status of devices. A pool that is online can still have a device
* that is experiencing errors.
@ -47,7 +45,7 @@
#include "libzfs_impl.h"
/*
* Message ID table. This must be kep in sync with the ZPOOL_STATUS_* defines
* Message ID table. This must be kept in sync with the ZPOOL_STATUS_* defines
* in libzfs.h. Note that there are some status results which go past the end
* of this table, and hence have no associated message ID.
*/
@ -62,26 +60,10 @@ static char *zfs_msgid_table[] = {
"ZFS-8000-8A",
"ZFS-8000-9P",
"ZFS-8000-A5",
"ZFS-8000-EY"
};
/*
* If the pool is active, a certain class of static errors is overridden by the
* faults as analayzed by FMA. These faults have separate knowledge articles,
* and the article referred to by 'zpool status' must match that indicated by
* the syslog error message. We override missing data as well as corrupt pool.
*/
static char *zfs_msgid_table_active[] = {
"ZFS-8000-14",
"ZFS-8000-D3", /* overridden */
"ZFS-8000-D3", /* overridden */
"ZFS-8000-4J",
"ZFS-8000-5E",
"ZFS-8000-6X",
"ZFS-8000-CS", /* overridden */
"ZFS-8000-8A",
"ZFS-8000-9P",
"ZFS-8000-CS", /* overridden */
"ZFS-8000-EY",
"ZFS-8000-HC",
"ZFS-8000-JQ",
"ZFS-8000-K4",
};
#define NMSGID (sizeof (zfs_msgid_table) / sizeof (zfs_msgid_table[0]))
@ -94,11 +76,18 @@ vdev_missing(uint64_t state, uint64_t aux, uint64_t errs)
aux == VDEV_AUX_OPEN_FAILED);
}
/* ARGSUSED */
static int
vdev_faulted(uint64_t state, uint64_t aux, uint64_t errs)
{
return (state == VDEV_STATE_FAULTED);
}
/* ARGSUSED */
static int
vdev_errors(uint64_t state, uint64_t aux, uint64_t errs)
{
return (errs != 0);
return (state == VDEV_STATE_DEGRADED || errs != 0);
}
/* ARGSUSED */
@ -163,9 +152,9 @@ find_vdev_problem(nvlist_t *vdev, int (*func)(uint64_t, uint64_t, uint64_t))
* following:
*
* - Check for a complete and valid configuration
* - Look for any missing devices in a non-replicated config
* - Look for any faulted or missing devices in a non-replicated config
* - Check for any data errors
* - Check for any missing devices in a replicated config
* - Check for any faulted or missing devices in a replicated config
* - Look for any devices showing errors
* - Check for any resilvering devices
*
@ -181,6 +170,7 @@ check_status(nvlist_t *config, boolean_t isimport)
uint64_t nerr;
uint64_t version;
uint64_t stateval;
uint64_t suspended;
uint64_t hostid = 0;
verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_VERSION,
@ -215,8 +205,30 @@ check_status(nvlist_t *config, boolean_t isimport)
return (ZPOOL_STATUS_BAD_GUID_SUM);
/*
* Missing devices in non-replicated config.
* Check whether the pool has suspended due to failed I/O.
*/
if (nvlist_lookup_uint64(config, ZPOOL_CONFIG_SUSPENDED,
&suspended) == 0) {
if (suspended == ZIO_FAILURE_MODE_CONTINUE)
return (ZPOOL_STATUS_IO_FAILURE_CONTINUE);
return (ZPOOL_STATUS_IO_FAILURE_WAIT);
}
/*
* Could not read a log.
*/
if (vs->vs_state == VDEV_STATE_CANT_OPEN &&
vs->vs_aux == VDEV_AUX_BAD_LOG) {
return (ZPOOL_STATUS_BAD_LOG);
}
/*
* Bad devices in non-replicated config.
*/
if (vs->vs_state == VDEV_STATE_CANT_OPEN &&
find_vdev_problem(nvroot, vdev_faulted))
return (ZPOOL_STATUS_FAULTED_DEV_NR);
if (vs->vs_state == VDEV_STATE_CANT_OPEN &&
find_vdev_problem(nvroot, vdev_missing))
return (ZPOOL_STATUS_MISSING_DEV_NR);
@ -244,6 +256,8 @@ check_status(nvlist_t *config, boolean_t isimport)
/*
* Missing devices in a replicated config.
*/
if (find_vdev_problem(nvroot, vdev_faulted))
return (ZPOOL_STATUS_FAULTED_DEV_R);
if (find_vdev_problem(nvroot, vdev_missing))
return (ZPOOL_STATUS_MISSING_DEV_R);
if (find_vdev_problem(nvroot, vdev_broken))
@ -270,7 +284,7 @@ check_status(nvlist_t *config, boolean_t isimport)
/*
* Outdated, but usable, version
*/
if (version < ZFS_VERSION)
if (version < SPA_VERSION)
return (ZPOOL_STATUS_VERSION_OLDER);
return (ZPOOL_STATUS_OK);
@ -284,7 +298,7 @@ zpool_get_status(zpool_handle_t *zhp, char **msgid)
if (ret >= NMSGID)
*msgid = NULL;
else
*msgid = zfs_msgid_table_active[ret];
*msgid = zfs_msgid_table[ret];
return (ret);
}

View file

@ -19,12 +19,10 @@
* CDDL HEADER END
*/
/*
* Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
/*
* Internal utility routines for the ZFS library.
*/
@ -37,6 +35,8 @@
#include <stdlib.h>
#include <strings.h>
#include <unistd.h>
#include <ctype.h>
#include <math.h>
#include <sys/mnttab.h>
#include <sys/mntent.h>
#include <sys/types.h>
@ -44,6 +44,7 @@
#include <libzfs.h>
#include "libzfs_impl.h"
#include "zfs_prop.h"
int
libzfs_errno(libzfs_handle_t *hdl)
@ -133,6 +134,14 @@ libzfs_error_description(libzfs_handle_t *hdl)
return (dgettext(TEXT_DOMAIN, "unshare(1M) failed"));
case EZFS_SHARENFSFAILED:
return (dgettext(TEXT_DOMAIN, "share(1M) failed"));
case EZFS_UNSHARESMBFAILED:
return (dgettext(TEXT_DOMAIN, "smb remove share failed"));
case EZFS_SHARESMBFAILED:
return (dgettext(TEXT_DOMAIN, "smb add share failed"));
case EZFS_ISCSISVCUNAVAIL:
return (dgettext(TEXT_DOMAIN,
"iscsitgt service need to be enabled by "
"a privileged user"));
case EZFS_DEVLINKS:
return (dgettext(TEXT_DOMAIN, "failed to create /dev links"));
case EZFS_PERM:
@ -169,6 +178,38 @@ libzfs_error_description(libzfs_handle_t *hdl)
"this pool operation"));
case EZFS_NAMETOOLONG:
return (dgettext(TEXT_DOMAIN, "dataset name is too long"));
case EZFS_OPENFAILED:
return (dgettext(TEXT_DOMAIN, "open failed"));
case EZFS_NOCAP:
return (dgettext(TEXT_DOMAIN,
"disk capacity information could not be retrieved"));
case EZFS_LABELFAILED:
return (dgettext(TEXT_DOMAIN, "write of label failed"));
case EZFS_BADWHO:
return (dgettext(TEXT_DOMAIN, "invalid user/group"));
case EZFS_BADPERM:
return (dgettext(TEXT_DOMAIN, "invalid permission"));
case EZFS_BADPERMSET:
return (dgettext(TEXT_DOMAIN, "invalid permission set name"));
case EZFS_NODELEGATION:
return (dgettext(TEXT_DOMAIN, "delegated administration is "
"disabled on pool"));
case EZFS_PERMRDONLY:
return (dgettext(TEXT_DOMAIN, "snapshot permissions cannot be"
" modified"));
case EZFS_BADCACHE:
return (dgettext(TEXT_DOMAIN, "invalid or missing cache file"));
case EZFS_ISL2CACHE:
return (dgettext(TEXT_DOMAIN, "device is in use as a cache"));
case EZFS_VDEVNOTSUP:
return (dgettext(TEXT_DOMAIN, "vdev specification is not "
"supported"));
case EZFS_NOTSUP:
return (dgettext(TEXT_DOMAIN, "operation not supported "
"on this dataset"));
case EZFS_ACTIVE_SPARE:
return (dgettext(TEXT_DOMAIN, "pool has active shared spare "
"device"));
case EZFS_UNKNOWN:
return (dgettext(TEXT_DOMAIN, "unknown error"));
default:
@ -249,6 +290,10 @@ zfs_common_error(libzfs_handle_t *hdl, int error, const char *fmt,
zfs_verror(hdl, EZFS_PERM, fmt, ap);
return (-1);
case ECANCELED:
zfs_verror(hdl, EZFS_NODELEGATION, fmt, ap);
return (-1);
case EIO:
zfs_verror(hdl, EZFS_IO, fmt, ap);
return (-1);
@ -280,9 +325,9 @@ zfs_standard_error_fmt(libzfs_handle_t *hdl, int error, const char *fmt, ...)
return (-1);
}
switch (error) {
case ENXIO:
case ENODEV:
zfs_verror(hdl, EZFS_IO, fmt, ap);
break;
@ -308,11 +353,17 @@ zfs_standard_error_fmt(libzfs_handle_t *hdl, int error, const char *fmt, ...)
"dataset is busy"));
zfs_verror(hdl, EZFS_BUSY, fmt, ap);
break;
case EROFS:
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
"snapshot permissions cannot be modified"));
zfs_verror(hdl, EZFS_PERMRDONLY, fmt, ap);
break;
case ENAMETOOLONG:
zfs_verror(hdl, EZFS_NAMETOOLONG, fmt, ap);
break;
case ENOTSUP:
zfs_verror(hdl, EZFS_BADVERSION, fmt, ap);
break;
default:
zfs_error_aux(hdl, strerror(errno));
zfs_verror(hdl, EZFS_UNKNOWN, fmt, ap);
@ -361,7 +412,7 @@ zpool_standard_error_fmt(libzfs_handle_t *hdl, int error, const char *fmt, ...)
case EBUSY:
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "pool is busy"));
zfs_verror(hdl, EZFS_EXISTS, fmt, ap);
zfs_verror(hdl, EZFS_BUSY, fmt, ap);
break;
case ENXIO:
@ -382,6 +433,11 @@ zpool_standard_error_fmt(libzfs_handle_t *hdl, int error, const char *fmt, ...)
zfs_verror(hdl, EZFS_POOL_INVALARG, fmt, ap);
break;
case ENOSPC:
case EDQUOT:
zfs_verror(hdl, EZFS_NOSPC, fmt, ap);
return (-1);
default:
zfs_error_aux(hdl, strerror(error));
zfs_verror(hdl, EZFS_UNKNOWN, fmt, ap);
@ -483,9 +539,8 @@ zfs_nicenum(uint64_t num, char *buf, size_t buflen)
*/
int i;
for (i = 2; i >= 0; i--) {
(void) snprintf(buf, buflen, "%.*f%c", i,
(double)num / (1ULL << 10 * index), u);
if (strlen(buf) <= 5)
if (snprintf(buf, buflen, "%.*f%c", i,
(double)num / (1ULL << 10 * index), u) <= 5)
break;
}
}
@ -538,6 +593,9 @@ libzfs_init(void)
hdl->libzfs_sharetab = fopen(ZFS_EXPORTS_PATH, "r");
zfs_prop_init();
zpool_prop_init();
return (hdl);
}
@ -549,6 +607,10 @@ libzfs_fini(libzfs_handle_t *hdl)
(void) fclose(hdl->libzfs_mnttab);
if (hdl->libzfs_sharetab)
(void) fclose(hdl->libzfs_sharetab);
zfs_uninit_libshare(hdl);
if (hdl->libzfs_log_str)
(void) free(hdl->libzfs_log_str);
zpool_free_handles(hdl);
namespace_clear(hdl);
free(hdl);
}
@ -565,6 +627,12 @@ zfs_get_handle(zfs_handle_t *zhp)
return (zhp->zfs_hdl);
}
zpool_handle_t *
zfs_get_pool_handle(const zfs_handle_t *zhp)
{
return (zhp->zpool_hdl);
}
/*
* Given a name, determine whether or not it's a valid path
* (starts with '/' or "./"). If so, walk the mnttab trying
@ -637,13 +705,14 @@ zcmd_expand_dst_nvlist(libzfs_handle_t *hdl, zfs_cmd_t *zc)
void
zcmd_free_nvlists(zfs_cmd_t *zc)
{
free((void *)(uintptr_t)zc->zc_nvlist_conf);
free((void *)(uintptr_t)zc->zc_nvlist_src);
free((void *)(uintptr_t)zc->zc_nvlist_dst);
}
int
zcmd_write_src_nvlist(libzfs_handle_t *hdl, zfs_cmd_t *zc, nvlist_t *nvl,
size_t *size)
static int
zcmd_write_nvlist_com(libzfs_handle_t *hdl, uint64_t *outnv, uint64_t *outlen,
nvlist_t *nvl)
{
char *packed;
size_t len;
@ -655,14 +724,26 @@ zcmd_write_src_nvlist(libzfs_handle_t *hdl, zfs_cmd_t *zc, nvlist_t *nvl,
verify(nvlist_pack(nvl, &packed, &len, NV_ENCODE_NATIVE, 0) == 0);
zc->zc_nvlist_src = (uint64_t)(uintptr_t)packed;
zc->zc_nvlist_src_size = len;
*outnv = (uint64_t)(uintptr_t)packed;
*outlen = len;
if (size)
*size = len;
return (0);
}
int
zcmd_write_conf_nvlist(libzfs_handle_t *hdl, zfs_cmd_t *zc, nvlist_t *nvl)
{
return (zcmd_write_nvlist_com(hdl, &zc->zc_nvlist_conf,
&zc->zc_nvlist_conf_size, nvl));
}
int
zcmd_write_src_nvlist(libzfs_handle_t *hdl, zfs_cmd_t *zc, nvlist_t *nvl)
{
return (zcmd_write_nvlist_com(hdl, &zc->zc_nvlist_src,
&zc->zc_nvlist_src_size, nvl));
}
/*
* Unpacks an nvlist from the ZFS ioctl command structure.
*/
@ -676,10 +757,32 @@ zcmd_read_dst_nvlist(libzfs_handle_t *hdl, zfs_cmd_t *zc, nvlist_t **nvlp)
return (0);
}
static void
zfs_print_prop_headers(libzfs_get_cbdata_t *cbp)
int
zfs_ioctl(libzfs_handle_t *hdl, unsigned long request, zfs_cmd_t *zc)
{
zfs_proplist_t *pl = cbp->cb_proplist;
int error;
zc->zc_history = (uint64_t)(uintptr_t)hdl->libzfs_log_str;
error = ioctl(hdl->libzfs_fd, request, zc);
if (hdl->libzfs_log_str) {
free(hdl->libzfs_log_str);
hdl->libzfs_log_str = NULL;
}
zc->zc_history = 0;
return (error);
}
/*
* ================================================================
* API shared by zfs and zpool property management
* ================================================================
*/
static void
zprop_print_headers(zprop_get_cbdata_t *cbp, zfs_type_t type)
{
zprop_list_t *pl = cbp->cb_proplist;
int i;
char *title;
size_t len;
@ -711,8 +814,12 @@ zfs_print_prop_headers(libzfs_get_cbdata_t *cbp)
/*
* 'PROPERTY' column
*/
if (pl->pl_prop != ZFS_PROP_INVAL) {
len = strlen(zfs_prop_to_name(pl->pl_prop));
if (pl->pl_prop != ZPROP_INVAL) {
const char *propname = (type == ZFS_TYPE_POOL) ?
zpool_prop_to_name(pl->pl_prop) :
zfs_prop_to_name(pl->pl_prop);
len = strlen(propname);
if (len > cbp->cb_colwidths[GET_COL_PROPERTY])
cbp->cb_colwidths[GET_COL_PROPERTY] = len;
} else {
@ -731,7 +838,8 @@ zfs_print_prop_headers(libzfs_get_cbdata_t *cbp)
/*
* 'NAME' and 'SOURCE' columns
*/
if (pl->pl_prop == ZFS_PROP_NAME &&
if (pl->pl_prop == (type == ZFS_TYPE_POOL ? ZPOOL_PROP_NAME :
ZFS_PROP_NAME) &&
pl->pl_width > cbp->cb_colwidths[GET_COL_NAME]) {
cbp->cb_colwidths[GET_COL_NAME] = pl->pl_width;
cbp->cb_colwidths[GET_COL_SOURCE] = pl->pl_width +
@ -777,8 +885,8 @@ zfs_print_prop_headers(libzfs_get_cbdata_t *cbp)
* structure.
*/
void
libzfs_print_one_property(const char *name, libzfs_get_cbdata_t *cbp,
const char *propname, const char *value, zfs_source_t sourcetype,
zprop_print_one_property(const char *name, zprop_get_cbdata_t *cbp,
const char *propname, const char *value, zprop_source_t sourcetype,
const char *source)
{
int i;
@ -792,7 +900,7 @@ libzfs_print_one_property(const char *name, libzfs_get_cbdata_t *cbp,
return;
if (cbp->cb_first)
zfs_print_prop_headers(cbp);
zprop_print_headers(cbp, cbp->cb_type);
for (i = 0; i < 4; i++) {
switch (cbp->cb_columns[i]) {
@ -810,23 +918,23 @@ libzfs_print_one_property(const char *name, libzfs_get_cbdata_t *cbp,
case GET_COL_SOURCE:
switch (sourcetype) {
case ZFS_SRC_NONE:
case ZPROP_SRC_NONE:
str = "-";
break;
case ZFS_SRC_DEFAULT:
case ZPROP_SRC_DEFAULT:
str = "default";
break;
case ZFS_SRC_LOCAL:
case ZPROP_SRC_LOCAL:
str = "local";
break;
case ZFS_SRC_TEMPORARY:
case ZPROP_SRC_TEMPORARY:
str = "temporary";
break;
case ZFS_SRC_INHERITED:
case ZPROP_SRC_INHERITED:
(void) snprintf(buf, sizeof (buf),
"inherited from %s", source);
str = buf;
@ -851,3 +959,451 @@ libzfs_print_one_property(const char *name, libzfs_get_cbdata_t *cbp,
(void) printf("\n");
}
/*
* Given a numeric suffix, convert the value into a number of bits that the
* resulting value must be shifted.
*/
static int
str2shift(libzfs_handle_t *hdl, const char *buf)
{
const char *ends = "BKMGTPEZ";
int i;
if (buf[0] == '\0')
return (0);
for (i = 0; i < strlen(ends); i++) {
if (toupper(buf[0]) == ends[i])
break;
}
if (i == strlen(ends)) {
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
"invalid numeric suffix '%s'"), buf);
return (-1);
}
/*
* We want to allow trailing 'b' characters for 'GB' or 'Mb'. But don't
* allow 'BB' - that's just weird.
*/
if (buf[1] == '\0' || (toupper(buf[1]) == 'B' && buf[2] == '\0' &&
toupper(buf[0]) != 'B'))
return (10*i);
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
"invalid numeric suffix '%s'"), buf);
return (-1);
}
/*
* Convert a string of the form '100G' into a real number. Used when setting
* properties or creating a volume. 'buf' is used to place an extended error
* message for the caller to use.
*/
int
zfs_nicestrtonum(libzfs_handle_t *hdl, const char *value, uint64_t *num)
{
char *end;
int shift;
*num = 0;
/* Check to see if this looks like a number. */
if ((value[0] < '0' || value[0] > '9') && value[0] != '.') {
if (hdl)
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
"bad numeric value '%s'"), value);
return (-1);
}
/* Rely on stroll() to process the numeric portion. */
errno = 0;
*num = strtoll(value, &end, 10);
/*
* Check for ERANGE, which indicates that the value is too large to fit
* in a 64-bit value.
*/
if (errno == ERANGE) {
if (hdl)
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
"numeric value is too large"));
return (-1);
}
/*
* If we have a decimal value, then do the computation with floating
* point arithmetic. Otherwise, use standard arithmetic.
*/
if (*end == '.') {
double fval = strtod(value, &end);
if ((shift = str2shift(hdl, end)) == -1)
return (-1);
fval *= pow(2, shift);
if (fval > UINT64_MAX) {
if (hdl)
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
"numeric value is too large"));
return (-1);
}
*num = (uint64_t)fval;
} else {
if ((shift = str2shift(hdl, end)) == -1)
return (-1);
/* Check for overflow */
if (shift >= 64 || (*num << shift) >> shift != *num) {
if (hdl)
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
"numeric value is too large"));
return (-1);
}
*num <<= shift;
}
return (0);
}
/*
* Given a propname=value nvpair to set, parse any numeric properties
* (index, boolean, etc) if they are specified as strings and add the
* resulting nvpair to the returned nvlist.
*
* At the DSL layer, all properties are either 64-bit numbers or strings.
* We want the user to be able to ignore this fact and specify properties
* as native values (numbers, for example) or as strings (to simplify
* command line utilities). This also handles converting index types
* (compression, checksum, etc) from strings to their on-disk index.
*/
int
zprop_parse_value(libzfs_handle_t *hdl, nvpair_t *elem, int prop,
zfs_type_t type, nvlist_t *ret, char **svalp, uint64_t *ivalp,
const char *errbuf)
{
data_type_t datatype = nvpair_type(elem);
zprop_type_t proptype;
const char *propname;
char *value;
boolean_t isnone = B_FALSE;
if (type == ZFS_TYPE_POOL) {
proptype = zpool_prop_get_type(prop);
propname = zpool_prop_to_name(prop);
} else {
proptype = zfs_prop_get_type(prop);
propname = zfs_prop_to_name(prop);
}
/*
* Convert any properties to the internal DSL value types.
*/
*svalp = NULL;
*ivalp = 0;
switch (proptype) {
case PROP_TYPE_STRING:
if (datatype != DATA_TYPE_STRING) {
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
"'%s' must be a string"), nvpair_name(elem));
goto error;
}
(void) nvpair_value_string(elem, svalp);
if (strlen(*svalp) >= ZFS_MAXPROPLEN) {
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
"'%s' is too long"), nvpair_name(elem));
goto error;
}
break;
case PROP_TYPE_NUMBER:
if (datatype == DATA_TYPE_STRING) {
(void) nvpair_value_string(elem, &value);
if (strcmp(value, "none") == 0) {
isnone = B_TRUE;
} else if (zfs_nicestrtonum(hdl, value, ivalp)
!= 0) {
goto error;
}
} else if (datatype == DATA_TYPE_UINT64) {
(void) nvpair_value_uint64(elem, ivalp);
} else {
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
"'%s' must be a number"), nvpair_name(elem));
goto error;
}
/*
* Quota special: force 'none' and don't allow 0.
*/
if ((type & ZFS_TYPE_DATASET) && *ivalp == 0 && !isnone &&
(prop == ZFS_PROP_QUOTA || prop == ZFS_PROP_REFQUOTA)) {
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
"use 'none' to disable quota/refquota"));
goto error;
}
break;
case PROP_TYPE_INDEX:
if (datatype != DATA_TYPE_STRING) {
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
"'%s' must be a string"), nvpair_name(elem));
goto error;
}
(void) nvpair_value_string(elem, &value);
if (zprop_string_to_index(prop, value, ivalp, type) != 0) {
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
"'%s' must be one of '%s'"), propname,
zprop_values(prop, type));
goto error;
}
break;
default:
abort();
}
/*
* Add the result to our return set of properties.
*/
if (*svalp != NULL) {
if (nvlist_add_string(ret, propname, *svalp) != 0) {
(void) no_memory(hdl);
return (-1);
}
} else {
if (nvlist_add_uint64(ret, propname, *ivalp) != 0) {
(void) no_memory(hdl);
return (-1);
}
}
return (0);
error:
(void) zfs_error(hdl, EZFS_BADPROP, errbuf);
return (-1);
}
static int
addlist(libzfs_handle_t *hdl, char *propname, zprop_list_t **listp,
zfs_type_t type)
{
int prop;
zprop_list_t *entry;
prop = zprop_name_to_prop(propname, type);
if (prop != ZPROP_INVAL && !zprop_valid_for_type(prop, type))
prop = ZPROP_INVAL;
/*
* When no property table entry can be found, return failure if
* this is a pool property or if this isn't a user-defined
* dataset property,
*/
if (prop == ZPROP_INVAL && (type == ZFS_TYPE_POOL ||
!zfs_prop_user(propname))) {
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
"invalid property '%s'"), propname);
return (zfs_error(hdl, EZFS_BADPROP,
dgettext(TEXT_DOMAIN, "bad property list")));
}
if ((entry = zfs_alloc(hdl, sizeof (zprop_list_t))) == NULL)
return (-1);
entry->pl_prop = prop;
if (prop == ZPROP_INVAL) {
if ((entry->pl_user_prop = zfs_strdup(hdl, propname)) == NULL) {
free(entry);
return (-1);
}
entry->pl_width = strlen(propname);
} else {
entry->pl_width = zprop_width(prop, &entry->pl_fixed,
type);
}
*listp = entry;
return (0);
}
/*
* Given a comma-separated list of properties, construct a property list
* containing both user-defined and native properties. This function will
* return a NULL list if 'all' is specified, which can later be expanded
* by zprop_expand_list().
*/
int
zprop_get_list(libzfs_handle_t *hdl, char *props, zprop_list_t **listp,
zfs_type_t type)
{
*listp = NULL;
/*
* If 'all' is specified, return a NULL list.
*/
if (strcmp(props, "all") == 0)
return (0);
/*
* If no props were specified, return an error.
*/
if (props[0] == '\0') {
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
"no properties specified"));
return (zfs_error(hdl, EZFS_BADPROP, dgettext(TEXT_DOMAIN,
"bad property list")));
}
/*
* It would be nice to use getsubopt() here, but the inclusion of column
* aliases makes this more effort than it's worth.
*/
while (*props != '\0') {
size_t len;
char *p;
char c;
if ((p = strchr(props, ',')) == NULL) {
len = strlen(props);
p = props + len;
} else {
len = p - props;
}
/*
* Check for empty options.
*/
if (len == 0) {
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
"empty property name"));
return (zfs_error(hdl, EZFS_BADPROP,
dgettext(TEXT_DOMAIN, "bad property list")));
}
/*
* Check all regular property names.
*/
c = props[len];
props[len] = '\0';
if (strcmp(props, "space") == 0) {
static char *spaceprops[] = {
"name", "avail", "used", "usedbysnapshots",
"usedbydataset", "usedbyrefreservation",
"usedbychildren", NULL
};
int i;
for (i = 0; spaceprops[i]; i++) {
if (addlist(hdl, spaceprops[i], listp, type))
return (-1);
listp = &(*listp)->pl_next;
}
} else {
if (addlist(hdl, props, listp, type))
return (-1);
listp = &(*listp)->pl_next;
}
props = p;
if (c == ',')
props++;
}
return (0);
}
void
zprop_free_list(zprop_list_t *pl)
{
zprop_list_t *next;
while (pl != NULL) {
next = pl->pl_next;
free(pl->pl_user_prop);
free(pl);
pl = next;
}
}
typedef struct expand_data {
zprop_list_t **last;
libzfs_handle_t *hdl;
zfs_type_t type;
} expand_data_t;
int
zprop_expand_list_cb(int prop, void *cb)
{
zprop_list_t *entry;
expand_data_t *edp = cb;
if ((entry = zfs_alloc(edp->hdl, sizeof (zprop_list_t))) == NULL)
return (ZPROP_INVAL);
entry->pl_prop = prop;
entry->pl_width = zprop_width(prop, &entry->pl_fixed, edp->type);
entry->pl_all = B_TRUE;
*(edp->last) = entry;
edp->last = &entry->pl_next;
return (ZPROP_CONT);
}
int
zprop_expand_list(libzfs_handle_t *hdl, zprop_list_t **plp, zfs_type_t type)
{
zprop_list_t *entry;
zprop_list_t **last;
expand_data_t exp;
if (*plp == NULL) {
/*
* If this is the very first time we've been called for an 'all'
* specification, expand the list to include all native
* properties.
*/
last = plp;
exp.last = last;
exp.hdl = hdl;
exp.type = type;
if (zprop_iter_common(zprop_expand_list_cb, &exp, B_FALSE,
B_FALSE, type) == ZPROP_INVAL)
return (-1);
/*
* Add 'name' to the beginning of the list, which is handled
* specially.
*/
if ((entry = zfs_alloc(hdl, sizeof (zprop_list_t))) == NULL)
return (-1);
entry->pl_prop = (type == ZFS_TYPE_POOL) ? ZPOOL_PROP_NAME :
ZFS_PROP_NAME;
entry->pl_width = zprop_width(entry->pl_prop,
&entry->pl_fixed, type);
entry->pl_all = B_TRUE;
entry->pl_next = *plp;
*plp = entry;
}
return (0);
}
int
zprop_iter(zprop_func func, void *cb, boolean_t show_all, boolean_t ordered,
zfs_type_t type)
{
return (zprop_iter_common(func, cb, show_all, ordered, type));
}

View file

@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
* Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@ -101,20 +101,24 @@ void
zmutex_init(kmutex_t *mp)
{
mp->m_owner = NULL;
mp->initialized = B_TRUE;
(void) _mutex_init(&mp->m_lock, USYNC_THREAD, NULL);
}
void
zmutex_destroy(kmutex_t *mp)
{
ASSERT(mp->initialized == B_TRUE);
ASSERT(mp->m_owner == NULL);
(void) _mutex_destroy(&(mp)->m_lock);
mp->m_owner = (void *)-1UL;
mp->initialized = B_FALSE;
}
void
mutex_enter(kmutex_t *mp)
{
ASSERT(mp->initialized == B_TRUE);
ASSERT(mp->m_owner != (void *)-1UL);
ASSERT(mp->m_owner != curthread);
VERIFY(mutex_lock(&mp->m_lock) == 0);
@ -125,6 +129,7 @@ mutex_enter(kmutex_t *mp)
int
mutex_tryenter(kmutex_t *mp)
{
ASSERT(mp->initialized == B_TRUE);
ASSERT(mp->m_owner != (void *)-1UL);
if (mutex_trylock(&mp->m_lock) == 0) {
ASSERT(mp->m_owner == NULL);
@ -138,6 +143,7 @@ mutex_tryenter(kmutex_t *mp)
void
mutex_exit(kmutex_t *mp)
{
ASSERT(mp->initialized == B_TRUE);
ASSERT(mp->m_owner == curthread);
mp->m_owner = NULL;
VERIFY(mutex_unlock(&mp->m_lock) == 0);
@ -146,6 +152,7 @@ mutex_exit(kmutex_t *mp)
void *
mutex_owner(kmutex_t *mp)
{
ASSERT(mp->initialized == B_TRUE);
return (mp->m_owner);
}
@ -160,7 +167,7 @@ rw_init(krwlock_t *rwlp, char *name, int type, void *arg)
{
rwlock_init(&rwlp->rw_lock, USYNC_THREAD, NULL);
rwlp->rw_owner = NULL;
rwlp->rw_count = 0;
rwlp->initialized = B_TRUE;
}
void
@ -168,22 +175,23 @@ rw_destroy(krwlock_t *rwlp)
{
rwlock_destroy(&rwlp->rw_lock);
rwlp->rw_owner = (void *)-1UL;
rwlp->rw_count = -2;
rwlp->initialized = B_FALSE;
}
void
rw_enter(krwlock_t *rwlp, krw_t rw)
{
//ASSERT(!RW_LOCK_HELD(rwlp));
ASSERT(rwlp->initialized == B_TRUE);
ASSERT(rwlp->rw_owner != (void *)-1UL);
ASSERT(rwlp->rw_owner != curthread);
if (rw == RW_READER) {
(void) rw_rdlock(&rwlp->rw_lock);
VERIFY(rw_rdlock(&rwlp->rw_lock) == 0);
ASSERT(rwlp->rw_count >= 0);
atomic_add_int(&rwlp->rw_count, 1);
} else {
(void) rw_wrlock(&rwlp->rw_lock);
VERIFY(rw_wrlock(&rwlp->rw_lock) == 0);
ASSERT(rwlp->rw_count == 0);
rwlp->rw_count = -1;
rwlp->rw_owner = curthread;
@ -193,6 +201,7 @@ rw_enter(krwlock_t *rwlp, krw_t rw)
void
rw_exit(krwlock_t *rwlp)
{
ASSERT(rwlp->initialized == B_TRUE);
ASSERT(rwlp->rw_owner != (void *)-1UL);
if (rwlp->rw_owner == curthread) {
@ -205,7 +214,7 @@ rw_exit(krwlock_t *rwlp)
ASSERT(rwlp->rw_count > 0);
atomic_add_int(&rwlp->rw_count, -1);
}
(void) rw_unlock(&rwlp->rw_lock);
VERIFY(rw_unlock(&rwlp->rw_lock) == 0);
}
int
@ -213,6 +222,7 @@ rw_tryenter(krwlock_t *rwlp, krw_t rw)
{
int rv;
ASSERT(rwlp->initialized == B_TRUE);
ASSERT(rwlp->rw_owner != (void *)-1UL);
ASSERT(rwlp->rw_owner != curthread);
@ -241,6 +251,7 @@ rw_tryenter(krwlock_t *rwlp, krw_t rw)
int
rw_tryupgrade(krwlock_t *rwlp)
{
ASSERT(rwlp->initialized == B_TRUE);
ASSERT(rwlp->rw_owner != (void *)-1UL);
return (0);
@ -422,9 +433,10 @@ vn_open(char *path, int x1, int flags, int mode, vnode_t **vpp, int x2, int x3)
return (0);
}
/*ARGSUSED*/
int
vn_openat(char *path, int x1, int flags, int mode, vnode_t **vpp, int x2,
int x3, vnode_t *startvp)
int x3, vnode_t *startvp, int fd)
{
char *realpath = umem_alloc(strlen(path) + 2, UMEM_NOFAIL);
int ret;
@ -432,6 +444,7 @@ vn_openat(char *path, int x1, int flags, int mode, vnode_t **vpp, int x2,
ASSERT(startvp == rootdir);
(void) sprintf(realpath, "/%s", path);
/* fd ignored for now, need if want to simulate nbmand support */
ret = vn_open(realpath, x1, flags, mode, vpp, x2, x3);
umem_free(realpath, strlen(path) + 2);
@ -469,7 +482,7 @@ vn_rdwr(int uio, vnode_t *vp, void *addr, ssize_t len, offset_t offset,
}
void
vn_close(vnode_t *vp)
vn_close(vnode_t *vp, int openflag, cred_t *cr, kthread_t *td)
{
close(vp->v_fd);
spa_strfree(vp->v_path);
@ -657,7 +670,8 @@ kobj_open_file(char *name)
vnode_t *vp;
/* set vp as the _fd field of the file */
if (vn_openat(name, UIO_SYSSPACE, FREAD, 0, &vp, 0, 0, rootdir) != 0)
if (vn_openat(name, UIO_SYSSPACE, FREAD, 0, &vp, 0, 0, rootdir,
-1) != 0)
return ((void *)-1UL);
file = umem_zalloc(sizeof (struct _buf), UMEM_NOFAIL);
@ -679,7 +693,7 @@ kobj_read_file(struct _buf *file, char *buf, unsigned size, unsigned off)
void
kobj_close_file(struct _buf *file)
{
vn_close((vnode_t *)file->_fd);
vn_close((vnode_t *)file->_fd, 0, NULL, NULL);
umem_free(file, sizeof (struct _buf));
}
@ -690,7 +704,7 @@ kobj_get_filesize(struct _buf *file, uint64_t *size)
vnode_t *vp = (vnode_t *)file->_fd;
if (fstat64(vp->v_fd, &st) == -1) {
vn_close(vp);
vn_close(vp, 0, NULL, NULL);
return (errno);
}
*size = st.st_size;
@ -746,10 +760,11 @@ highbit(ulong_t i)
}
#endif
static int random_fd = -1, urandom_fd = -1;
static int
random_get_bytes_common(uint8_t *ptr, size_t len, char *devname)
random_get_bytes_common(uint8_t *ptr, size_t len, int fd)
{
int fd = open(devname, O_RDONLY);
size_t resid = len;
ssize_t bytes;
@ -757,26 +772,24 @@ random_get_bytes_common(uint8_t *ptr, size_t len, char *devname)
while (resid != 0) {
bytes = read(fd, ptr, resid);
ASSERT(bytes >= 0);
ASSERT3S(bytes, >=, 0);
ptr += bytes;
resid -= bytes;
}
close(fd);
return (0);
}
int
random_get_bytes(uint8_t *ptr, size_t len)
{
return (random_get_bytes_common(ptr, len, "/dev/random"));
return (random_get_bytes_common(ptr, len, random_fd));
}
int
random_get_pseudo_bytes(uint8_t *ptr, size_t len)
{
return (random_get_bytes_common(ptr, len, "/dev/urandom"));
return (random_get_bytes_common(ptr, len, urandom_fd));
}
int
@ -815,7 +828,11 @@ kernel_init(int mode)
dprintf("physmem = %llu pages (%.2f GB)\n", physmem,
(double)physmem * sysconf(_SC_PAGE_SIZE) / (1ULL << 30));
snprintf(hw_serial, sizeof (hw_serial), "%ld", gethostid());
snprintf(hw_serial, sizeof (hw_serial), "%lu",
(unsigned long)gethostid());
VERIFY((random_fd = open("/dev/random", O_RDONLY)) != -1);
VERIFY((urandom_fd = open("/dev/urandom", O_RDONLY)) != -1);
spa_init(mode);
}
@ -824,6 +841,12 @@ void
kernel_fini(void)
{
spa_fini();
close(random_fd);
close(urandom_fd);
random_fd = -1;
urandom_fd = -1;
}
int
@ -850,3 +873,62 @@ z_compress_level(void *dst, size_t *dstlen, const void *src, size_t srclen,
return (ret);
}
uid_t
crgetuid(cred_t *cr)
{
return (0);
}
gid_t
crgetgid(cred_t *cr)
{
return (0);
}
int
crgetngroups(cred_t *cr)
{
return (0);
}
gid_t *
crgetgroups(cred_t *cr)
{
return (NULL);
}
int
zfs_secpolicy_snapshot_perms(const char *name, cred_t *cr)
{
return (0);
}
int
zfs_secpolicy_rename_perms(const char *from, const char *to, cred_t *cr)
{
return (0);
}
int
zfs_secpolicy_destroy_perms(const char *name, cred_t *cr)
{
return (0);
}
ksiddomain_t *
ksid_lookupdomain(const char *dom)
{
ksiddomain_t *kd;
kd = umem_zalloc(sizeof (ksiddomain_t), UMEM_NOFAIL);
kd->kd_name = spa_strdup(dom);
return (kd);
}
void
ksiddomain_rele(ksiddomain_t *ksid)
{
spa_strfree(ksid->kd_name);
umem_free(ksid, sizeof (ksiddomain_t));
}

View file

@ -19,15 +19,13 @@
* CDDL HEADER END
*/
/*
* Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#ifndef _SYS_ZFS_CONTEXT_H
#define _SYS_ZFS_CONTEXT_H
#pragma ident "%Z%%M% %I% %E% SMI"
#ifdef __cplusplus
extern "C" {
#endif
@ -64,6 +62,7 @@ extern "C" {
#include <fsshare.h>
#include <sys/note.h>
#include <sys/types.h>
#include <sys/cred.h>
#include <sys/atomic.h>
#include <sys/sysmacros.h>
#include <sys/bitmap.h>
@ -78,8 +77,10 @@ extern "C" {
#include <sys/debug.h>
#include <sys/sdt.h>
#include <sys/kstat.h>
#include <sys/u8_textprep.h>
#include <sys/kernel.h>
#include <sys/disk.h>
#include <sys/sysevent/eventdefs.h>
#include <machine/atomic.h>
#define ZFS_EXPORTS_PATH "/etc/zfs/exports"
@ -116,11 +117,12 @@ extern void vcmn_err(int, const char *, __va_list);
extern void panic(const char *, ...);
extern void vpanic(const char *, __va_list);
#define fm_panic panic
/* This definition is copied from assert.h. */
#if defined(__STDC__)
#if __STDC_VERSION__ - 0 >= 199901L
#define verify(EX) (void)((EX) || \
(__assert_c99(#EX, __FILE__, __LINE__, __func__), 0))
#define verify(EX) (void)((EX) || (__assert(#EX, __FILE__, __LINE__), 0))
#else
#define verify(EX) (void)((EX) || (__assert(#EX, __FILE__, __LINE__), 0))
#endif /* __STDC_VERSION__ - 0 >= 199901L */
@ -167,11 +169,16 @@ _NOTE(CONSTCOND) } while (0)
#endif
/*
* Dtrace SDT probes have different signatures in userland than they do in
* DTrace SDT probes have different signatures in userland than they do in
* kernel. If they're being used in kernel code, re-define them out of
* existence for their counterparts in libzpool.
*/
#ifdef DTRACE_PROBE
#undef DTRACE_PROBE
#define DTRACE_PROBE(a) ((void)0)
#endif /* DTRACE_PROBE */
#ifdef DTRACE_PROBE1
#undef DTRACE_PROBE1
#define DTRACE_PROBE1(a, b, c) ((void)0)
@ -212,8 +219,9 @@ extern kthread_t *zk_thread_create(void (*func)(), void *arg);
* Mutexes
*/
typedef struct kmutex {
void *m_owner;
mutex_t m_lock;
void *m_owner;
boolean_t initialized;
mutex_t m_lock;
} kmutex_t;
#define MUTEX_DEFAULT USYNC_THREAD
@ -243,6 +251,7 @@ extern void *mutex_owner(kmutex_t *mp);
typedef struct krwlock {
int rw_count;
void *rw_owner;
boolean_t initialized;
rwlock_t rw_lock;
} krwlock_t;
@ -253,6 +262,7 @@ typedef int krw_t;
#define RW_DEFAULT USYNC_THREAD
#undef RW_READ_HELD
#define RW_READ_HELD(x) ((x)->rw_owner == NULL && (x)->rw_count > 0)
#undef RW_WRITE_HELD
#define RW_WRITE_HELD(x) ((x)->rw_owner == curthread)
@ -267,6 +277,11 @@ extern void rw_exit(krwlock_t *rwlp);
extern int rw_lock_held(krwlock_t *rwlp);
#define rw_downgrade(rwlp) do { } while (0)
extern uid_t crgetuid(cred_t *cr);
extern gid_t crgetgid(cred_t *cr);
extern int crgetngroups(cred_t *cr);
extern gid_t *crgetgroups(cred_t *cr);
/*
* Condition variables
*/
@ -285,6 +300,7 @@ extern void cv_broadcast(kcondvar_t *cv);
* Kernel memory
*/
#define KM_SLEEP UMEM_NOFAIL
#define KM_PUSHPAGE KM_SLEEP
#define KM_NOSLEEP UMEM_DEFAULT
#define KMC_NODEBUG UMC_NODEBUG
#define kmem_alloc(_s, _f) umem_alloc(_s, _f)
@ -322,6 +338,9 @@ extern void taskq_destroy(taskq_t *);
extern void taskq_wait(taskq_t *);
extern int taskq_member(taskq_t *, void *);
#define XVA_MAPSIZE 3
#define XVA_MAGIC 0x78766174
/*
* vnodes
*/
@ -331,44 +350,93 @@ typedef struct vnode {
char *v_path;
} vnode_t;
typedef struct xoptattr {
timestruc_t xoa_createtime; /* Create time of file */
uint8_t xoa_archive;
uint8_t xoa_system;
uint8_t xoa_readonly;
uint8_t xoa_hidden;
uint8_t xoa_nounlink;
uint8_t xoa_immutable;
uint8_t xoa_appendonly;
uint8_t xoa_nodump;
uint8_t xoa_settable;
uint8_t xoa_opaque;
uint8_t xoa_av_quarantined;
uint8_t xoa_av_modified;
} xoptattr_t;
typedef struct vattr {
uint_t va_mask; /* bit-mask of attributes */
u_offset_t va_size; /* file size in bytes */
} vattr_t;
#define AT_TYPE 0x0001
#define AT_MODE 0x0002
#define AT_UID 0x0004
#define AT_GID 0x0008
#define AT_FSID 0x0010
#define AT_NODEID 0x0020
#define AT_NLINK 0x0040
#define AT_SIZE 0x0080
#define AT_ATIME 0x0100
#define AT_MTIME 0x0200
#define AT_CTIME 0x0400
#define AT_RDEV 0x0800
#define AT_BLKSIZE 0x1000
#define AT_NBLOCKS 0x2000
#define AT_SEQ 0x8000
typedef struct xvattr {
vattr_t xva_vattr; /* Embedded vattr structure */
uint32_t xva_magic; /* Magic Number */
uint32_t xva_mapsize; /* Size of attr bitmap (32-bit words) */
uint32_t *xva_rtnattrmapp; /* Ptr to xva_rtnattrmap[] */
uint32_t xva_reqattrmap[XVA_MAPSIZE]; /* Requested attrs */
uint32_t xva_rtnattrmap[XVA_MAPSIZE]; /* Returned attrs */
xoptattr_t xva_xoptattrs; /* Optional attributes */
} xvattr_t;
typedef struct vsecattr {
uint_t vsa_mask; /* See below */
int vsa_aclcnt; /* ACL entry count */
void *vsa_aclentp; /* pointer to ACL entries */
int vsa_dfaclcnt; /* default ACL entry count */
void *vsa_dfaclentp; /* pointer to default ACL entries */
size_t vsa_aclentsz; /* ACE size in bytes of vsa_aclentp */
} vsecattr_t;
#define AT_TYPE 0x00001
#define AT_MODE 0x00002
#define AT_UID 0x00004
#define AT_GID 0x00008
#define AT_FSID 0x00010
#define AT_NODEID 0x00020
#define AT_NLINK 0x00040
#define AT_SIZE 0x00080
#define AT_ATIME 0x00100
#define AT_MTIME 0x00200
#define AT_CTIME 0x00400
#define AT_RDEV 0x00800
#define AT_BLKSIZE 0x01000
#define AT_NBLOCKS 0x02000
#define AT_SEQ 0x08000
#define AT_XVATTR 0x10000
#define CRCREAT 0
#define VOP_CLOSE(vp, f, c, o, cr) 0
#define VOP_PUTPAGE(vp, of, sz, fl, cr) 0
#define VOP_GETATTR(vp, vap, fl) ((vap)->va_size = (vp)->v_size, 0)
#define VOP_CLOSE(vp, f, c, o, cr, ct) 0
#define VOP_PUTPAGE(vp, of, sz, fl, cr, ct) 0
#define VOP_GETATTR(vp, vap, cr) ((vap)->va_size = (vp)->v_size, 0)
#define VOP_FSYNC(vp, f, cr) fsync((vp)->v_fd)
#define VOP_FSYNC(vp, f, cr, ct) fsync((vp)->v_fd)
#define VN_RELE(vp) vn_close(vp)
#define VN_RELE(vp) vn_close(vp, 0, NULL, NULL)
#define vn_lock(vp, type)
#define VOP_UNLOCK(vp, type)
#ifdef VFS_LOCK_GIANT
#undef VFS_LOCK_GIANT
#endif
#define VFS_LOCK_GIANT(mp) 0
#ifdef VFS_UNLOCK_GIANT
#undef VFS_UNLOCK_GIANT
#endif
#define VFS_UNLOCK_GIANT(vfslocked)
extern int vn_open(char *path, int x1, int oflags, int mode, vnode_t **vpp,
int x2, int x3);
extern int vn_openat(char *path, int x1, int oflags, int mode, vnode_t **vpp,
int x2, int x3, vnode_t *vp);
int x2, int x3, vnode_t *vp, int fd);
extern int vn_rdwr(int uio, vnode_t *vp, void *addr, ssize_t len,
offset_t offset, int x1, int x2, rlim64_t x3, void *x4, ssize_t *residp);
extern void vn_close(vnode_t *vp);
extern void vn_close(vnode_t *vp, int openflag, cred_t *cr, kthread_t *td);
#define vn_remove(path, x1, x2) remove(path)
#define vn_rename(from, to, seg) rename((from), (to))
@ -397,8 +465,9 @@ extern void delay(clock_t ticks);
#define CPU_SEQID (thr_self() & (max_ncpus - 1))
#define kcred NULL
#define CRED() NULL
#ifndef ptob
#define ptob(x) ((x) * PAGESIZE)
#endif
extern uint64_t physmem;
@ -455,11 +524,31 @@ struct bootstat {
uint64_t st_size;
};
typedef struct ace_object {
uid_t a_who;
uint32_t a_access_mask;
uint16_t a_flags;
uint16_t a_type;
uint8_t a_obj_type[16];
uint8_t a_inherit_obj_type[16];
} ace_object_t;
#define ACE_ACCESS_ALLOWED_OBJECT_ACE_TYPE 0x05
#define ACE_ACCESS_DENIED_OBJECT_ACE_TYPE 0x06
#define ACE_SYSTEM_AUDIT_OBJECT_ACE_TYPE 0x07
#define ACE_SYSTEM_ALARM_OBJECT_ACE_TYPE 0x08
extern struct _buf *kobj_open_file(char *name);
extern int kobj_read_file(struct _buf *file, char *buf, unsigned size,
unsigned off);
extern void kobj_close_file(struct _buf *file);
extern int kobj_get_filesize(struct _buf *file, uint64_t *size);
extern int zfs_secpolicy_snapshot_perms(const char *name, cred_t *cr);
extern int zfs_secpolicy_rename_perms(const char *from, const char *to,
cred_t *cr);
extern int zfs_secpolicy_destroy_perms(const char *name, cred_t *cr);
extern zoneid_t getzoneid(void);
/* Random compatibility stuff. */
#define lbolt (gethrtime() >> 23)
#define lbolt64 (gethrtime() >> 23)
@ -482,18 +571,32 @@ struct file {
#define FCREAT O_CREAT
#define FOFFMAX 0x0
/* SID stuff */
typedef struct ksiddomain {
uint_t kd_ref;
uint_t kd_len;
char *kd_name;
} ksiddomain_t;
ksiddomain_t *ksid_lookupdomain(const char *);
void ksiddomain_rele(ksiddomain_t *);
#define SX_SYSINIT(name, lock, desc)
#define SYSCTL_DECL(...)
#define SYSCTL_NODE(...)
#define SYSCTL_INT(...)
#define SYSCTL_UINT(...)
#define SYSCTL_ULONG(...)
#define SYSCTL_QUAD(...)
#ifdef TUNABLE_INT
#undef TUNABLE_INT
#undef TUNABLE_ULONG
#undef TUNABLE_QUAD
#endif
#define TUNABLE_INT(...)
#define TUNABLE_ULONG(...)
#define TUNABLE_QUAD(...)
/* Errors */

View file

@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (the "License"). You may not use this file except in compliance
* with the License.
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
* Copyright 2005 Sun Microsystems, Inc. All rights reserved.
* Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@ -177,6 +176,9 @@ taskq_create(const char *name, int nthreads, pri_t pri,
int t;
rw_init(&tq->tq_threadlock, NULL, RW_DEFAULT, NULL);
mutex_init(&tq->tq_lock, NULL, MUTEX_DEFAULT, NULL);
cv_init(&tq->tq_dispatch_cv, NULL, CV_DEFAULT, NULL);
cv_init(&tq->tq_wait_cv, NULL, CV_DEFAULT, NULL);
tq->tq_flags = flags | TASKQ_ACTIVE;
tq->tq_active = nthreads;
tq->tq_nthreads = nthreads;
@ -230,6 +232,9 @@ taskq_destroy(taskq_t *tq)
kmem_free(tq->tq_threadlist, nthreads * sizeof (thread_t));
rw_destroy(&tq->tq_threadlock);
mutex_destroy(&tq->tq_lock);
cv_destroy(&tq->tq_dispatch_cv);
cv_destroy(&tq->tq_wait_cv);
kmem_free(tq, sizeof (taskq_t));
}

View file

@ -19,12 +19,10 @@
* CDDL HEADER END
*/
/*
* Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
#include <assert.h>
#include <sys/zfs_context.h>
#include <sys/avl.h>
@ -67,46 +65,58 @@ nicenum(uint64_t num, char *buf)
}
static void
show_vdev_stats(const char *desc, nvlist_t *nv, int indent)
show_vdev_stats(const char *desc, const char *ctype, nvlist_t *nv, int indent)
{
vdev_stat_t *vs;
vdev_stat_t v0 = { 0 };
uint64_t sec;
uint64_t is_log = 0;
nvlist_t **child;
uint_t c, children;
vdev_stat_t *vs;
uint64_t sec;
char used[6], avail[6];
char rops[6], wops[6], rbytes[6], wbytes[6], rerr[6], werr[6], cerr[6];
char *prefix = "";
if (indent == 0) {
(void) printf(" "
if (indent == 0 && desc != NULL) {
(void) printf(" "
" capacity operations bandwidth ---- errors ----\n");
(void) printf("description "
(void) printf("description "
"used avail read write read write read write cksum\n");
}
VERIFY(nvlist_lookup_uint64_array(nv, ZPOOL_CONFIG_STATS,
(uint64_t **)&vs, &c) == 0);
if (desc != NULL) {
(void) nvlist_lookup_uint64(nv, ZPOOL_CONFIG_IS_LOG, &is_log);
sec = MAX(1, vs->vs_timestamp / NANOSEC);
if (is_log)
prefix = "log ";
nicenum(vs->vs_alloc, used);
nicenum(vs->vs_space - vs->vs_alloc, avail);
nicenum(vs->vs_ops[ZIO_TYPE_READ] / sec, rops);
nicenum(vs->vs_ops[ZIO_TYPE_WRITE] / sec, wops);
nicenum(vs->vs_bytes[ZIO_TYPE_READ] / sec, rbytes);
nicenum(vs->vs_bytes[ZIO_TYPE_WRITE] / sec, wbytes);
nicenum(vs->vs_read_errors, rerr);
nicenum(vs->vs_write_errors, werr);
nicenum(vs->vs_checksum_errors, cerr);
if (nvlist_lookup_uint64_array(nv, ZPOOL_CONFIG_STATS,
(uint64_t **)&vs, &c) != 0)
vs = &v0;
(void) printf("%*s%*s%*s%*s %5s %5s %5s %5s %5s %5s %5s\n",
indent, "",
indent - 19 - (vs->vs_space ? 0 : 12), desc,
vs->vs_space ? 6 : 0, vs->vs_space ? used : "",
vs->vs_space ? 6 : 0, vs->vs_space ? avail : "",
rops, wops, rbytes, wbytes, rerr, werr, cerr);
sec = MAX(1, vs->vs_timestamp / NANOSEC);
if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
&child, &children) != 0)
nicenum(vs->vs_alloc, used);
nicenum(vs->vs_space - vs->vs_alloc, avail);
nicenum(vs->vs_ops[ZIO_TYPE_READ] / sec, rops);
nicenum(vs->vs_ops[ZIO_TYPE_WRITE] / sec, wops);
nicenum(vs->vs_bytes[ZIO_TYPE_READ] / sec, rbytes);
nicenum(vs->vs_bytes[ZIO_TYPE_WRITE] / sec, wbytes);
nicenum(vs->vs_read_errors, rerr);
nicenum(vs->vs_write_errors, werr);
nicenum(vs->vs_checksum_errors, cerr);
(void) printf("%*s%s%*s%*s%*s %5s %5s %5s %5s %5s %5s %5s\n",
indent, "",
prefix,
indent + strlen(prefix) - 25 - (vs->vs_space ? 0 : 12),
desc,
vs->vs_space ? 6 : 0, vs->vs_space ? used : "",
vs->vs_space ? 6 : 0, vs->vs_space ? avail : "",
rops, wops, rbytes, wbytes, rerr, werr, cerr);
}
if (nvlist_lookup_nvlist_array(nv, ctype, &child, &children) != 0)
return;
for (c = 0; c < children; c++) {
@ -120,7 +130,7 @@ show_vdev_stats(const char *desc, nvlist_t *nv, int indent)
(void) strcpy(tname, cname);
if (nvlist_lookup_uint64(cnv, ZPOOL_CONFIG_NPARITY, &np) == 0)
tname[strlen(tname)] = '0' + np;
show_vdev_stats(tname, cnv, indent + 2);
show_vdev_stats(tname, ctype, cnv, indent + 2);
free(tname);
}
}
@ -131,14 +141,16 @@ show_pool_stats(spa_t *spa)
nvlist_t *config, *nvroot;
char *name;
spa_config_enter(spa, RW_READER, FTAG);
config = spa_config_generate(spa, NULL, -1ULL, B_TRUE);
spa_config_exit(spa, FTAG);
VERIFY(spa_get_stats(spa_name(spa), &config, NULL, 0) == 0);
VERIFY(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
&nvroot) == 0);
VERIFY(nvlist_lookup_string(config, ZPOOL_CONFIG_POOL_NAME,
&name) == 0);
show_vdev_stats(name, nvroot, 0);
show_vdev_stats(name, ZPOOL_CONFIG_CHILDREN, nvroot, 0);
show_vdev_stats(NULL, ZPOOL_CONFIG_L2CACHE, nvroot, 0);
show_vdev_stats(NULL, ZPOOL_CONFIG_SPARES, nvroot, 0);
nvlist_free(config);
}

View file

@ -10,14 +10,17 @@ DPADD= ${LIBUTIL}
LDADD= -lutil
SRCS= deviceid.c \
mnttab.c \
mkdirp.c \
zmount.c \
fsshare.c \
mkdirp.c \
mnttab.c \
zmount.c \
zone.c
SRCS+= zfs_namecheck.c \
SRCS+= zfs_deleg.c \
zfs_namecheck.c \
zfs_prop.c \
zpool_prop.c \
zprop_common.c \
libzfs_dataset.c \
libzfs_util.c \
libzfs_graph.c \
@ -26,6 +29,7 @@ SRCS+= zfs_namecheck.c \
libzfs_changelist.c \
libzfs_config.c \
libzfs_import.c \
libzfs_sendrecv.c \
libzfs_status.c
CFLAGS+= -DZFS_NO_ACL

View file

@ -18,6 +18,8 @@ ATOMIC_SRCS= atomic.S
.PATH: ${.CURDIR}/../../../sys/cddl/compat/opensolaris/kern
ATOMIC_SRCS= opensolaris_atomic.c
.endif
# UNICODE_SRCS
.PATH: ${.CURDIR}/../../../sys/cddl/contrib/opensolaris/common/unicode
LIB= zpool
@ -25,9 +27,13 @@ ZFS_COMMON_SRCS= ${ZFS_COMMON_OBJS:C/.o$/.c/} vdev_file.c
ZFS_SHARED_SRCS= ${ZFS_SHARED_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} \
${KERNEL_SRCS} ${LIST_SRCS} ${ATOMIC_SRCS}
${KERNEL_SRCS} ${LIST_SRCS} ${ATOMIC_SRCS} \
${UNICODE_SRCS}
CFLAGS+= -std=c99
CFLAGS+= -I${.CURDIR}/../../../sys/cddl/compat/opensolaris
CFLAGS+= -I${.CURDIR}/../../../cddl/compat/opensolaris/include
@ -40,6 +46,13 @@ CFLAGS+= -I${.CURDIR}/../../../sys/cddl/contrib/opensolaris/uts/common
CFLAGS+= -I${.CURDIR}/../../../cddl/contrib/opensolaris/head
CFLAGS+= -I${.CURDIR}/../../../cddl/lib/libumem
CFLAGS+= -I${.CURDIR}/../../../cddl/contrib/opensolaris/lib/libnvpair
# XXX: pthread doesn't have mutex_owned() equivalent, so we need to look
# into libthr private structures. That's sooo evil, but it's only for
# ZFS debugging tools needs.
CFLAGS+= -DWANTS_MUTEX_OWNED
CFLAGS+= -I${.CURDIR}/../../../lib/libpthread/thread
CFLAGS+= -I${.CURDIR}/../../../lib/libpthread/sys
CFLAGS+= -I${.CURDIR}/../../../lib/libthr/arch/${MACHINE_ARCH}/include
DPADD= ${LIBPTHREAD} ${LIBZ}
LDADD= -lpthread -lz

View file

@ -1,10 +1,11 @@
# $FreeBSD$
.PATH: ${.CURDIR}/../../../cddl/contrib/opensolaris/cmd/zpool
.PATH: ${.CURDIR}/../../../cddl/contrib/opensolaris/cmd/zpool \
${.CURDIR}/../../../sys/cddl/contrib/opensolaris/common/zfs
PROG= zpool
MAN= zpool.8
SRCS= zpool_main.c zpool_vdev.c zpool_iter.c zpool_util.c
SRCS= zpool_main.c zpool_vdev.c zpool_iter.c zpool_util.c zfs_comutil.c
CFLAGS+= -I${.CURDIR}/../../../cddl/contrib/opensolaris/lib/libzpool/common
CFLAGS+= -I${.CURDIR}/../../../cddl/compat/opensolaris/include
@ -15,6 +16,7 @@ CFLAGS+= -I${.CURDIR}/../../../cddl/contrib/opensolaris/lib/libuutil/common
CFLAGS+= -I${.CURDIR}/../../../cddl/contrib/opensolaris/lib/libumem/common
CFLAGS+= -I${.CURDIR}/../../../cddl/contrib/opensolaris/lib/libzfs/common
CFLAGS+= -I${.CURDIR}/../../../cddl/contrib/opensolaris/lib/libnvpair
CFLAGS+= -I${.CURDIR}/../../../sys/cddl/contrib/opensolaris/common/zfs
CFLAGS+= -I${.CURDIR}/../../../sys/cddl/contrib/opensolaris/uts/common
CFLAGS+= -I${.CURDIR}/../../../sys/cddl/contrib/opensolaris/uts/common/fs/zfs
CFLAGS+= -I${.CURDIR}/../../../sys/cddl/contrib/opensolaris/uts/common/sys

View file

@ -7,9 +7,11 @@ SUBDIR= \
ctfdump \
ctfmerge \
sgsmsg \
${_zinject} \
${_ztest}
.if ${MK_ZFS} != "no"
_zinject= zinject
.if ${MK_LIBTHR} != "no"
_ztest= ztest
.endif

View file

@ -0,0 +1,25 @@
# $FreeBSD$
.PATH: ${.CURDIR}/../../contrib/opensolaris/cmd/zinject
PROG= zinject
SRCS= zinject.c translate.c
NO_MAN=
CFLAGS+= -I${.CURDIR}/../../../sys/cddl/compat/opensolaris
CFLAGS+= -I${.CURDIR}/../../compat/opensolaris/include
CFLAGS+= -I${.CURDIR}/../../compat/opensolaris/lib/libumem
CFLAGS+= -I${.CURDIR}/../../contrib/opensolaris/lib/libzfs/common
CFLAGS+= -I${.CURDIR}/../../contrib/opensolaris/lib/libzpool/common
CFLAGS+= -I${.CURDIR}/../../contrib/opensolaris/lib/libnvpair
CFLAGS+= -I${.CURDIR}/../../../sys/cddl/contrib/opensolaris/uts/common/fs/zfs
CFLAGS+= -I${.CURDIR}/../../../sys/cddl/contrib/opensolaris/uts/common/sys
CFLAGS+= -I${.CURDIR}/../../../sys/cddl/contrib/opensolaris/uts/common
CFLAGS+= -I${.CURDIR}/../../contrib/opensolaris/head
CFLAGS+= -I${.CURDIR}/../../lib/libumem
DPADD= ${LIBAVL} ${LIBGEOM} ${LIBM} ${LIBNVPAIR} ${LIBUMEM} ${LIBUUTIL} \
${LIBZFS} ${LIBZPOOL} ${LIBUUTIL}
LDADD= -lavl -lgeom -lm -lnvpair -lumem -luutil -lzfs -lzpool
.include <bsd.prog.mk>

View file

@ -1,18 +1,20 @@
# $FreeBSD$
.PATH: ${.CURDIR}/../../../cddl/contrib/opensolaris/cmd/ztest
.PATH: ${.CURDIR}/../..//contrib/opensolaris/cmd/ztest
PROG= ztest
NO_MAN=
CFLAGS+= -std=c99
CFLAGS+= -I${.CURDIR}/../../../sys/cddl/compat/opensolaris
CFLAGS+= -I${.CURDIR}/../../../cddl/compat/opensolaris/include
CFLAGS+= -I${.CURDIR}/../../../cddl/compat/opensolaris/lib/libumem
CFLAGS+= -I${.CURDIR}/../../../cddl/contrib/opensolaris/lib/libzpool/common
CFLAGS+= -I${.CURDIR}/../../compat/opensolaris/include
CFLAGS+= -I${.CURDIR}/../../compat/opensolaris/lib/libumem
CFLAGS+= -I${.CURDIR}/../../contrib/opensolaris/lib/libzpool/common
CFLAGS+= -I${.CURDIR}/../../../sys/cddl/contrib/opensolaris/uts/common/fs/zfs
CFLAGS+= -I${.CURDIR}/../../../sys/cddl/contrib/opensolaris/uts/common/sys
CFLAGS+= -I${.CURDIR}/../../../sys/cddl/contrib/opensolaris/uts/common
CFLAGS+= -I${.CURDIR}/../../../cddl/contrib/opensolaris/head
CFLAGS+= -I${.CURDIR}/../../contrib/opensolaris/head
CFLAGS+= -I${.CURDIR}/../../lib/libumem
DPADD= ${LIBM} ${LIBNVPAIR} ${LIBUMEM} ${LIBZPOOL} \

View file

@ -6,9 +6,14 @@ PROG= zdb
MAN= zdb.8
SRCS= zdb.c zdb_il.c
CFLAGS+= -std=c99
CFLAGS+= -I${.CURDIR}/../../../sys/cddl/compat/opensolaris
CFLAGS+= -I${.CURDIR}/../../../cddl/compat/opensolaris/include
CFLAGS+= -I${.CURDIR}/../../../cddl/compat/opensolaris/lib/libumem
CFLAGS+= -I${.CURDIR}/../../../cddl/contrib/opensolaris/lib/libnvpair
CFLAGS+= -I${.CURDIR}/../../../cddl/contrib/opensolaris/lib/libuutil/common
CFLAGS+= -I${.CURDIR}/../../../cddl/contrib/opensolaris/lib/libzfs/common
CFLAGS+= -I${.CURDIR}/../../../cddl/contrib/opensolaris/lib/libzpool/common
CFLAGS+= -I${.CURDIR}/../../../sys/cddl/contrib/opensolaris/uts/common/fs/zfs
CFLAGS+= -I${.CURDIR}/../../../sys/cddl/contrib/opensolaris/uts/common
@ -16,8 +21,8 @@ CFLAGS+= -I${.CURDIR}/../../../sys/cddl/contrib/opensolaris/uts/common/sys
CFLAGS+= -I${.CURDIR}/../../../cddl/contrib/opensolaris/head
CFLAGS+= -I${.CURDIR}/../../lib/libumem
DPADD= ${LIBM} ${LIBNVPAIR} ${LIBUMEM} ${LIBZPOOL} \
${LIBPTHREAD} ${LIBZ} ${LIBAVL}
LDADD= -lm -lnvpair -lumem -lzpool -lpthread -lz -lavl
DPADD= ${LIBAVL} ${LIBGEOM} ${LIBM} ${LIBNVPAIR} ${LIBPTHREAD} ${LIBUMEM} \
${LIBUUTIL} ${LIBZ} ${LIBZFS} ${LIBZPOOL}
LDADD= -lavl -lgeom -lm -lnvpair -lpthread -lumem -luutil -lz -lzfs -lzpool
.include <bsd.prog.mk>

View file

@ -181,20 +181,6 @@ struct arm_prologue_cache
int arm_apcs_32 = 1;
/* Flag set by arm_fix_call_dummy that tells whether the target
function is a Thumb function. This flag is checked by
arm_push_arguments. FIXME: Change the PUSH_ARGUMENTS macro (and
its use in valops.c) to pass the function address as an additional
parameter. */
static int target_is_thumb;
/* Flag set by arm_fix_call_dummy that tells whether the calling
function is a Thumb function. This flag is checked by
arm_pc_is_thumb and arm_call_dummy_breakpoint_offset. */
static int caller_is_thumb;
/* Determine if the program counter specified in MEMADDR is in a Thumb
function. */
@ -219,27 +205,6 @@ arm_pc_is_thumb (CORE_ADDR memaddr)
}
}
/* Determine if the program counter specified in MEMADDR is in a call
dummy being called from a Thumb function. */
int
arm_pc_is_thumb_dummy (CORE_ADDR memaddr)
{
CORE_ADDR sp = read_sp ();
/* FIXME: Until we switch for the new call dummy macros, this heuristic
is the best we can do. We are trying to determine if the pc is on
the stack, which (hopefully) will only happen in a call dummy.
We hope the current stack pointer is not so far alway from the dummy
frame location (true if we have not pushed large data structures or
gone too many levels deep) and that our 1024 is not enough to consider
code regions as part of the stack (true for most practical purposes). */
if (DEPRECATED_PC_IN_CALL_DUMMY (memaddr, sp, sp + 1024))
return caller_is_thumb;
else
return 0;
}
/* Remove useless bits from addresses in a running program. */
static CORE_ADDR
arm_addr_bits_remove (CORE_ADDR val)
@ -2021,7 +1986,7 @@ arm_breakpoint_from_pc (CORE_ADDR *pcptr, int *lenptr)
{
struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
if (arm_pc_is_thumb (*pcptr) || arm_pc_is_thumb_dummy (*pcptr))
if (arm_pc_is_thumb (*pcptr))
{
*pcptr = UNMAKE_THUMB_ADDR (*pcptr);
*lenptr = tdep->thumb_breakpoint_size;

View file

@ -1,4 +1,4 @@
Announcing ncurses 5.6
Announcing ncurses 5.7
The ncurses (new curses) library is a free software emulation of
curses in System V Release 4.0, and more. It uses terminfo format,
@ -27,205 +27,217 @@
Release Notes
This release is designed to be upward compatible from ncurses 5.0
through 5.5; very few applications will require recompilation,
through 5.6; very few applications will require recompilation,
depending on the platform. These are the highlights from the
change-log since ncurses 5.5 release.
change-log since ncurses 5.6 release.
Interface changes:
* generate linkable stubs for some macros:
getbegx, getbegy, getcurx, getcury, getmaxx, getmaxy, getparx,
getpary, getpary,
and (for libncursesw)
wgetbkgrnd
getattrs
New features and improvements:
* library
+ support hashed databases for the terminal descriptions. This
uses the Berkeley database, has been tested for several
versions on different platforms.
+ add use_legacy_coding() function to support lynx's
font-switching feature.
+ add extension nofilter(), to cancel a prior filter() call.
+ add/install a package config script, e.g., ncurses5-config or
ncursesw5-config, according to configuration options.
+ provide ifdef for NCURSES_NOMACROS which suppresses most
macro definitions from curses.h, i.e., where a macro is
defined to override a function to improve performance.
+ make ifdef's consistent in curses.h for the extended colors
so the header file can be used for the normal curses library.
The header file installed for extended colors is a variation
of the wide-character configuration.
+ improve tgetstr() by making the return value point into the
user's buffer, if provided.
+ add ifdef's allowing ncurses to be built with tparm() using
either varargs (the existing status), or using a
fixed-parameter list (to match X/Open).
+ widen the test for xterm kmous a little to allow for other
strings than "\E[M", e.g., for xterm-sco functionality in
xterm.
+ modify wgetnstr() to return KEY_RESIZE if a sigwinch occurs.
+ move prototypes for wide-character trace functions from
curses.tail to curses.wide to avoid accidental reference to
those if _XOPEN_SOURCE_EXTENDED is defined without ensuring
that <wchar.h> is included.
+ change the way shared libraries (other than libtool) are
installed. Rather than copying the build-tree's libraries,
link the shared objects into the install directory. This
makes the --with-rpath option work except with $(DESTDIR).
+ several improvements for rendering in hpterm. These are only
available if the library is configured using
--enable-xmc-glitch.
+ Add NCURSES_NO_HARD_TABS and NCURSES_NO_MAGIC_COOKIE
environment variables to allow runtime suppression of the
related hard-tabs and xmc-glitch features.
+ new flavor of the ncurses library provides rudimentary
support for POSIX threads. Several functions are reentrant,
but most require either a window-level or screen-level mutex.
(This is API-compatible, but not ABI-compatible with the
normal library).
+ add NCURSES_OPAQUE symbol to curses.h, will use to make
structs opaque in selected configurations.
+ add NCURSES_EXT_FUNCS and NCURSES_EXT_COLORS symbols to
curses.h to make it simpler to tell if the extended functions
and/or colors are declared.
+ add wresize() to C++ binding
+ eliminate fixed-buffer vsprintf() calls in C++ binding.
+ add several functions to C++ binding which wrap C functions
that pass a WINDOW* parameter.
+ adapt mouse-handling code from menu library in form-library
+ improve tracing for form library, showing created forms,
fields, etc.
+ make $NCURSES_NO_PADDING feature work for termcap interface .
+ add check to trace-file open, if the given name is a
directory, add ".log" to the name and try again.
+ several new manpages: curs_legacy.3x, curs_memleaks.3x,
curs_opaque.3x and curs_threads.3x
* programs:
+ add new test programs: chgat.c, demo_altkeys.c, echochar.c,
foldkeys.c, movewindow.c, redraw.c, (noting that existing
test programs also were modified to test additional
features).
+ modify tack to test extended capability function-key strings.
+ modify toe to access termcap data, e.g., via cgetent()
functions, or as a text file if those are not available.
+ improve infocmp/tic -f option formatting.
+ add toe -a option, to show all databases. This uses new
private interfaces in the ncurses library for iterating
through the list of databases.
+ modify MKfallback.sh to use tic -x when constructing fallback
tables to allow extended capabilities to be retrieved from a
fallback entry.
+ modified three test-programs to demonstrate the threading
support in this version: ditto, rain, worm.
+ several new test-programs: demo_panels, dots_mvcur,
inch_wide, inchs, key_name, key_names, savescreen,
savescreen.sh test_arrays, test_get_wstr, test_getstr,
test_instr, test_inwstr and test_opaque.
+ add adacurses-config to the Ada95 install.
+ modify tic -f option to format spaces as \s to prevent them
from being lost when that is read back in unformatted
strings.
+ The tack program is now distributed separately from ncurses.
* terminal database
+ add terminfo entries for xfce terminal (xfce) and multi gnome
terminal (mgt)
+ add nsterm-16color entry
+ updated mlterm terminfo entry
+ add kon, kon2 and jfbterm terminfo entry
+ remove invis capability from klone+sgr, mainly used by linux
entry, since it does not really do this
+ add ka2, kb1, kb3, kc2 to vt220-keypad as an extension
+ add shifted up/down arrow codes to xterm-new as kind/kri
strings
+ add hpterm-color terminfo entry
+ add 256color variants of terminfo entries for programs which
are reported to implement this feature
+ correct order of use-clauses in rxvt-basic entry which made
codes for f1-f4 vt100-style rather than vt220-style.
+ added entries:
o Eterm-256color, Eterm-88color and rxvt-88color
o aterm
o konsole-256color
o mrxvt
o screen.mlterm
o screen.rxvt
o teraterm4.59 is now the primary primary teraterm entry,
renamed original to teraterm2.3
o 9term terminal
o Newbury Data entries
+ updated/improved entries:
o gnome to version 2.22.3
o h19, z100
o konsole to version 1.6.6
o mlterm, mlterm+pcfkeys
o xterm, and building-blocks for function-keys to [3]xterm
patch #230.
Major bug fixes:
* correct a typo in configure --with-bool option for the case where
--without-cxx is used.
* move assignment from environment variable ESCDELAY from initscr()
down to newterm() so the environment variable affects timeouts for
terminals opened with newterm() as well.
* modify werase to clear multicolumn characters that extend into a
derived window.
* modify wchgat() to mark updated cells as changed so a refresh will
repaint those cells.
* correct logic in wadd_wch() and wecho_wch(), which did not guard
against passing the multi-column attribute into a call on
waddch(), e.g., using data returned by win_wch()
* fix redrawing of windows other than stdscr using wredrawln() by
touching the corresponding rows in curscr.
* reduce memory leaks in repeated calls to tgetent() by remembering
the last TERMINAL* value allocated to hold the corresponding data
and freeing that if the tgetent() result buffer is the same as the
previous call.
* modify read_termtype() so the term_names data is always allocated
as part of the str_table, a better fix for a memory leak.
* fix wins_nwstr(), which did not handle single-column non-8bit
codes.
* modify wbkgrnd() to avoid clearing the A_CHARTEXT attribute bits
since those record the state of multicolumn characters.
* improve SIGWINCH handling by postponing its effect during
newterm(), etc., when allocating screens.
* remove 970913 feature for copying subwindows as they are moved in
mvwin().
* add checks in waddchnstr() and wadd_wchnstr() to stop copying when
a null character is found.
* add some checks to ensure current position is within scrolling
region before scrolling on a new line.
* add a workaround to ACS mapping to allow applications such as
test/blue.c to use the "PC ROM" characters by masking them with
A_ALTCHARSET. This worked up til 5.5, but was lost in the revision
of legacy coding.
* add logic to tic for cancelling strings in user-defined
capabilities (this is needed for current konsole terminfo entry).
* modify mk-1st.awk so the generated makefile rules for linking or
installing shared libraries do not first remove the library, in
case it is in use, e.g., libncurses.so by /bin/sh.
* correct check for notimeout() in wgetch().
* fix a sign-extension bug in infocmp's repair_acsc() function.
* change winnstr() to stop at the end of the line.
* make Ada95 demo_panels() example work.
* fix for adding a non-spacing character at the beginning of a line.
* fill in extended-color pair to make colors work for
wide-characters using extended-colors.
* improve refresh of window on top of multi-column characters,
taking into account split characters on left/right window
boundaries.
* modify win_wchnstr() to ensure that only a base cell is returned
for each multi-column character.
* improve waddch() and winsch() handling of EILSEQ from mbrtowc() by
using unctrl() to display illegal bytes rather than trying to
append further bytes to make up a valid sequence.
* restore curs_set() state after endwin()/refresh()
* modify keyname() to use "^X" form only if meta() has been called,
or if keyname() is called without initializing curses, e.g., via
initscr() or newterm().
* modify unctrl() to check codes in 128-255 range versus isprint().
If they are not printable, and locale was set, use a "M-" or "~"
sequence.
* improve resizeterm() by moving ripped-off lines, and repainting
the soft-keys.
* modify form library to accept control characters such as newline
in set_field_buffer(), which is compatible with Solaris.
* use NCURSES_MOUSE_MASK() in definition of BUTTON_RELEASE(), etc.,
to make those work properly with the --enable-ext-mouse
configuration
* correct some functions in Ada95 binding which were using return
value from C where none was returned.
* reviewed/fixed issues reported by Coverity and Klocwork tools.
Portability:
* configure script:
+ new options:
--with-hashed-db
Use Berkeley hashed database for storing terminfo
data rather than storing each compiled entry in a
separate binary file within a directory tree.
--disable-big-strings
control whether static string tables are generated
as single large strings (to improve startup
performance), or as array of individual strings.
--without-dlsym
Do not use dlsym() to load GPM dynamically.
--disable-relink
control whether shared libraries are relinked
(during install) when rpath is enabled.
--with-valgrind
Simplify building for testing with valgrind.
--disable-tic-depends
make explicit whether tic library depends on
ncurses/ncursesw library.
--enable-wgetch-events
Compile with experimental wgetch-events code.
--enable-mixed-case
override the configure script's check if the
filesystem supports mixed-case filenames. This
allows one to control how the terminal database
maps to the filesystem. For filesystems that do not
support mixed-case, the library uses generate
2-character (hexadecimal) codes for the lower-level
of the filesystem terminfo database
--enable-signed-char
Store booleans in "signed char" rather than "char".
--enable-reentrant
builds a different flavor of the ncurses library
(ncursest) which improves reentrant use of the
library by reducing global and static variables
(see the "--with-pthread" option for the threaded
support).
--enable-weak-symbols
use weak-symbols for linking to the POSIX thread
library, and use the same soname for the ncurses
shared library as the normal library (caveat: the
ABI is for the threaded library, which makes global
data accessed via functions).
--with-pthread
build with the POSIX thread library (tested with
AIX, Linux, FreeBSD, OpenBSD, HPUX, IRIX64,
Solaris, Tru64).
--with-ticlib
build/install the tic-support functions in a
separate library
+ improved options:
--disable-largefile
make the option work both ways.
--enable-ext-colors
requires the wide-character configuration.
--with-gpm
The option now accepts a parameter, i.e., the name
of the dynamic GPM library to load via dlopen()
--with-chtype
ignore option value "unsigned" is always added to
the type in curses.h; do the same for
--with-mmask-t.
--disable-symlinks
The option now allows one to disable symlink() in
tic even when link() does not work.
--with-dmalloc
build-fix for redefinition of strndup.
--with-hashed-db
accepts a parameter which is the install-prefix of
a given Berkeley Database.
--with-hashed-db
the $LIBS environment variable overrides the search
for the db library.
--without-hashed-db
assumed when "--disable-database" is used.
* other configure/build issues:
+ remove special case for Darwin in CF_XOPEN_SOURCE configure
macro.
+ add configure check to ensure that SIGWINCH is defined on
platforms such as OS X which exclude that when _XOPEN_SOURCE,
etc., are defined
+ use ld's -search_paths_first option on Darwin to work around
odd search rules on that platform.
+ improve ifdef's for _POSIX_VDISABLE in tset to work with Mac
OS X.
+ modify configure script to ensure that if the C compiler is
used rather than the loader in making shared libraries, the
$(CFLAGS) variable is also used.
+ use ${CC} rather than ${LD} in shared library rules for
IRIX64, Solaris to help ensure that initialization sections
are provided for extra linkage requirements, e.g., of C++
applications.
+ improve some shared-library configure scripting for Linux,
FreeBSD and NetBSD to make --with-shlib-version work.
+ split up dependency of names.c and codes.c in
ncurses/Makefile to work with parallel make.
+ modify MKlib_gen.sh to change preprocessor-expanded _Bool
back to bool.
+ modify progs/Makefile.in to make tput init work properly with
cygwin, i.e., do not pass a .exe in the reference string used
in check_aliases.
+ build-fixes for LynxOS
+ modify shared-library rules to allow FreeBSD 3.x to use
rpath.
+ build-fix for FreeBSD "contemporary" TTY interface.
+ build-fixes for AIX with libtool.
+ build-fixes for Darwin and libtool.
+ modify BeOS-specific ifdef's to build on Haiku.
+ corrected gcc options for building shared libraries on
Solaris and IRIX64.
+ change shared-library configuration for OpenBSD, make rpath
work.
+ build-fixes for using libutf8, e.g., on OpenBSD 3.7
+ add "-e" option in ncurses/Makefile.in when generating
source-files to force earlier exit if the build environment
fails unexpectedly.
+ add support for shared libraries for QNX.
+ change delimiter in MKlib_gen.sh from '%' to '@', to avoid
substitution by IBM xlc to '#' as part of its extensions to
digraphs.
* library:
+ ignore wide-acs line-drawing characters that wcwidth() claims
are not one-column. This is a workaround for Solaris' broken
locale support.
+ reduce name-pollution in term.h by removing #define's for
HAVE_xxx symbols.
+ fix #ifdef in c++/internal.h for QNX 6.1
+ rewrite wrapper for wcrtomb(), making it work on Solaris.
This is used in the form library to determine the length of
the buffer needed by field_buffer.
+ add/use configure script macro CF_SIG_ATOMIC_T, use the
corresponding type for data manipulated by signal handlers.
+ set locale in misc/ncurses-config.in since it uses a range
+ disable GPM mouse support when $TERM does not happen to
contain "linux", since Gpm_Open() no longer limits its
assertion to terminals that it might handle, e.g., within
"screen" in xterm.
+ reset mouse file-descriptor when unloading GPM library.
* test programs:
+ modify test/configure script to allow building test programs
with PDCurses/X11.
+ modified test programs to allow some to work with NetBSD
curses. Several do not because NetBSD curses implements a
subset of X/Open curses, and also lacks much of SVr4
additions. But it is enough for comparison.
+ improved test/configure to build test/ncurses on HPUX 11
using the vendor curses.
+ change configure script to produce test/Makefile from data
file.
+ update test programs to build/work with various UNIX curses
for comparisons.
Features of Ncurses
@ -271,6 +283,8 @@
the use of function keys, e.g., disabling the ncurses KEY_MOUSE,
or by defining more than one control sequence to map to a given
key code.
* Support for 256-color terminals, such as modern xterm, when
configured using the --enable-ext-colors option.
* Support for 16-color terminals, such as aixterm and modern xterm.
* Better cursor-movement optimization. The package now features a
cursor-local-movement computation more efficient than either BSD's
@ -342,49 +356,45 @@
cdk
Curses Development Kit
[3]http://invisible-island.net/cdk/
[4]http://www.vexus.ca/products/CDK/
[4]http://invisible-island.net/cdk/
[5]http://www.vexus.ca/products/CDK/
ded
directory-editor
[5]http://invisible-island.net/ded/
[6]http://invisible-island.net/ded/
dialog
the underlying application used in Slackware's setup, and the
basis for similar applications on GNU/Linux.
[6]http://invisible-island.net/dialog/
[7]http://invisible-island.net/dialog/
lynx
the character-screen WWW browser
[7]http://lynx.isc.org/release/
[8]http://lynx.isc.org/release/
Midnight Commander
file manager
[8]http://www.ibiblio.org/mc/
[9]http://www.ibiblio.org/mc/
mutt
mail utility
[9]http://www.mutt.org/
[10]http://www.mutt.org/
ncftp
file-transfer utility
[10]http://www.ncftp.com/
[11]http://www.ncftp.com/
nvi
New vi versions 1.50 are able to use ncurses versions 1.9.7 and
later.
[11]http://www.bostic.com/vi/
[12]http://www.bostic.com/vi/
pinfo
Lynx-like info browser.
[12]http://dione.ids.pl/~pborys/software/pinfo/
[13]https://alioth.debian.org/projects/pinfo/
tin
newsreader, supporting color, MIME [13]http://www.tin.org/
vh-1.6
Volks-Hypertext browser for the Jargon File
[14]http://www.debian.org/Packages/unstable/text/vh.html
newsreader, supporting color, MIME [14]http://www.tin.org/
as well as some that use ncurses for the terminfo support alone:
@ -402,7 +412,7 @@
Who's Who and What's What
Zeyd Ben-Halim started it from a previous package pcurses, written by
Pavel Curtis. Eric S. Raymond continued development. Juergen Pfeifer
Pavel Curtis. Eric S. Raymond continued development. Jürgen Pfeifer
wrote most of the form and menu libraries. Ongoing work is being done
by [17]Thomas Dickey. Thomas Dickey acts as the maintainer for the
Free Software Foundation, which holds the copyright on ncurses.
@ -442,18 +452,18 @@ References
1. ftp://ftp.gnu.org/gnu/ncurses/
2. ftp://invisible-island.net/ncurses/
3. http://invisible-island.net/cdk/
4. http://www.vexus.ca/products/CDK/
5. http://invisible-island.net/ded/
6. http://invisible-island.net/dialog/
7. http://lynx.isc.org/release/
8. http://www.ibiblio.org/mc/
9. http://www.mutt.org/
10. http://www.ncftp.com/
11. http://www.bostic.com/vi/
12. http://dione.ids.pl/~pborys/software/pinfo/
13. http://www.tin.org/
14. http://www.debian.org/Packages/unstable/text/vh.html
3. http://invisible-island.net/xterm/xterm.log.html#xterm_230
4. http://invisible-island.net/cdk/
5. http://www.vexus.ca/products/CDK/
6. http://invisible-island.net/ded/
7. http://invisible-island.net/dialog/
8. http://lynx.isc.org/release/
9. http://www.ibiblio.org/mc/
10. http://www.mutt.org/
11. http://www.ncftp.com/
12. http://www.bostic.com/vi/
13. https://alioth.debian.org/projects/pinfo/
14. http://www.tin.org/
15. http://alioth.debian.org/projects/minicom/
16. http://invisible-island.net/vile/
17. mailto:dickey@invisible-island.net

View file

@ -8,26 +8,19 @@ ncurses
For the import files and directories were pruned by:
tar -X FREEBSD-Xlist -zxf ncurses-5.6.tar.gz
tar -X FREEBSD-Xlist -zxf ncurses-5.7.tar.gz
check if there are any new bits that we don't want.
then imported by:
The instructions for importing new release and merging to HEAD can be found
at FreeBSD wiki:
cvs import -m 'Import ncurses 5.6-20061217 onto the vendor branch' \
src/contrib/ncurses NCURSES v5_6_20061217
http://wiki.freebsd.org/SubversionPrimer/VendorImports
The date in the tag can be obtained from contrib/ncurses/dist.mk.
If the version is a snapshot,
The version tag can be obtained from contrib/ncurses/dist.mk.
cvs import -m 'Import ncurses 5.6-20080503 snapshot onto the vendor branch' \
src/contrib/ncurses NCURSES v5_6_20080503
Remove files that are removed in this release in vendor branch (NCURSES)
instead of HEAD.
To make local changes to ncurses, simply patch and commit to the main
branch (aka HEAD). Never make local changes on the vendor (NCURSES) branch.
To make local changes to ncurses, simply patch and commit to the trunk
branch (aka HEAD). Never make local changes on the vendor branch.
All local changes should be submitted to Thomas Dickey for inclusion in
the next vendor release. The author is very willing to help us.
@ -39,19 +32,20 @@ ncurses, go to /usr/ports/devel/ncurses and
Update ncurses_cfg.h and necessary Makefile glues from ${WRKSRC}/build.nowidec.
Directory for wide character support is ${WRKSRC}/build.widec
You may have to update ncurses-specific glue in termcap.c.
You may have to update ncurses-specific glue in termcap.c (check if
ncurses/tinfo/read_termcap.c has been changed since last import).
Current local changes:
ncurses/tinfo/comp_scan.c
rev 1.2: native termcap tweaking
r50620: native termcap tweaking (cvs r1.2)
ncurses/tinfo/lib_termcap.c
rev 1.2: native termcap tweaking
rev 1.4: remove GCC_UNUSED for rev 1.2
r50620: native termcap tweaking (cvs r1.2)
r50850: remove GCC_UNUSED for r50620 (cvs r1.4)
ncurses/tinfo/read_termcap.c
This is not used. We have our own src/lib/ncurses/termcap.c
rafan@FreeBSD.org
9-Jan-2007
15-Nov-2008

View file

@ -1,8 +0,0 @@
# $FreeBSD$
Project: Ncurses (new curses) library
ProjectURL: http://www.gnu.org/software/ncurses/
Version: 5.6-20080503 snapshot
VendorTag: NCURSES
VersionTag: v5_6_20080503
License: MIT-like
Maintainer: rafan

View file

@ -1,5 +1,5 @@
-------------------------------------------------------------------------------
-- Copyright (c) 1998-2005,2006 Free Software Foundation, Inc. --
-- Copyright (c) 1998-2006,2008 Free Software Foundation, Inc. --
-- --
-- Permission is hereby granted, free of charge, to any person obtaining a --
-- copy of this software and associated documentation files (the --
@ -25,7 +25,7 @@
-- sale, use or other dealings in this Software without prior written --
-- authorization. --
-------------------------------------------------------------------------------
-- $Id: INSTALL,v 1.124 2008/03/29 18:07:32 tom Exp $
-- $Id: INSTALL,v 1.135 2008/11/02 21:13:51 tom Exp $
---------------------------------------------------------------------
How to install Ncurses/Terminfo on your system
---------------------------------------------------------------------
@ -393,6 +393,18 @@ SUMMARY OF CONFIGURE OPTIONS:
Compile without scroll-hints code. This option is ignored when
hashmap scrolling is configured, which is the default.
--disable-tic-depends
When building shared libraries, normally the tic library is linked to
depend upon the ncurses library (and in turn, on the term-library if
the --with-termlib option was given). The tic- and term-libraries
ABI does not depend on the --enable-widec option. Some packagers have
used this to reduce the number of library files which are packaged
by using only one copy of those libraries. To make this work properly,
the tic library must be built without an explicit dependency on the
ncurses (or ncursesw) library. Use this configure option to do that.
For example
configure --with-ticlib --with-shared --disable-tic-depends
--disable-tparm-varargs
Portable programs should call tparm() using the fixed-length parameter
list documented in X/Open. ncurses provides varargs support for this
@ -572,6 +584,13 @@ SUMMARY OF CONFIGURE OPTIONS:
--enable-warnings
Turn on GCC compiler warnings. There should be only a few.
--enable-weak-symbols
If the --with-pthread option is set, check if the compiler supports
weak-symbols. If it does, then name the thread-capable library without
the "t" (libncurses rather than libncursest), and provide for
dynamically loading the pthreads entrypoints at runtime. This allows
one to reduce the number of library files for ncurses.
--enable-wgetch-events
Compile with experimental wgetch-events code. See ncurses/README.IZ
@ -598,6 +617,9 @@ SUMMARY OF CONFIGURE OPTIONS:
Normally this is the same as the release version; some ports have
special requirements for compatibility.
This option does not affect linking with libtool, which uses the
release major/minor numbers.
--with-ada-compiler=CMD
Specify the Ada95 compiler command (default "gnatmake")
@ -625,20 +647,32 @@ SUMMARY OF CONFIGURE OPTIONS:
to do this if the target compiler has unusual flags which confuse the
host compiler.
You can also set the environment variable $BUILD_CFLAGS rather than
use this option.
--with-build-cppflags=XXX
If cross-compiling, specify the host C preprocessor-flags. You might
need to do this if the target compiler has unusual flags which confuse
the host compiler.
You can also set the environment variable $BUILD_CPPFLAGS rather than
use this option.
--with-build-ldflags=XXX
If cross-compiling, specify the host linker-flags. You might need to
do this if the target linker has unusual flags which confuse the host
compiler.
You can also set the environment variable $BUILD_LDFLAGS rather than
use this option.
--with-build-libs=XXX
If cross-compiling, the host libraries. You might need to do this if
the target environment requires unusual libraries.
You can also set the environment variable $BUILD_LIBS rather than
use this option.
--with-caps=XXX
Specify an alternate terminfo capabilities file, which makes the
configure script look for "include/Caps.XXX". A few systems, e.g.,
@ -795,6 +829,14 @@ SUMMARY OF CONFIGURE OPTIONS:
may be unsigned. Use this option if you need to preserve compatibility
with 64-bit executables.
--with-normal
Generate normal (i.e., static) libraries (default).
Note: on Linux, the configure script will attempt to use the GPM
library via the dlsym() function call. Use --without-dlsym to disable
this feature, or --without-gpm, depending on whether you wish to use
GPM.
--with-ospeed=TYPE
Override type of ospeed variable, which is part of the termcap
compatibility interface. In termcap, this is a 'short', which works
@ -808,14 +850,6 @@ SUMMARY OF CONFIGURE OPTIONS:
those using termcap, do not use the higher speeds. Your application
(or system, in general) may or may not.
--with-normal
Generate normal (i.e., static) libraries (default).
Note: on Linux, the configure script will attempt to use the GPM
library via the dlsym() function call. Use --without-dlsym to disable
this feature, or --without-gpm, depending on whether you wish to use
GPM.
--with-profile
Generate profile-libraries These are named by adding "_p" to the root,
e.g., libncurses_p.a
@ -898,6 +932,12 @@ SUMMARY OF CONFIGURE OPTIONS:
library. As in termlib, there is no ABI difference between the
"wide" libticw.so and libtic.so
NOTE: Overriding the name of the tic library may be useful if you are
also using the --with-termlib option to rename libtinfo. If you are
not doing that, renaming the tic library can result in conflicting
library dependencies for tic and other programs built with the tic
library.
--with-trace
Configure the trace() function as part of the all models of the ncurses
library. Normally it is part of the debug (libncurses_g) library only.
@ -961,6 +1001,94 @@ COMPATIBILITY WITH OLDER VERSIONS OF NCURSES:
you may encounter when building a system with different versions of
ncurses:
5.7 (November 2, 2008)
Interface changes:
+ generate linkable stubs for some macros:
getattrs
+ Add new library configuration for tic-library (the non-curses portion
of the ncurses library used for the tic program as well as some
others such as tack. There is no API change, but makefiles would be
changed to use the tic-library built separately.
tack, distributed separately from ncurses, uses some of the internal
_nc_XXX functions, which are declared in the tic.h header file.
The reason for providing this separate library is that none of the
functions in it are suitable for threaded applications.
+ Add new library configuration (ncursest, ncurseswt) which provides
rudimentary support for POSIX threads. This introduces opaque
access functions to the WINDOW structure and adds a parameter to
several internal functions.
+ move most internal variables (except tic-library) into data blocks
_nc_globals and _nc_prescreen to simplify analysis. Those were
globally accessible, but since they were not part of the documented
API, there is no ABI change.
+ changed static tables of strings to be indices into long strings, to
improve startup performance. This changes parameter lists for some
of the internal functions.
Added extensions:
+ add NCURSES_OPAQUE definition in curses.h to control whether internal
details of the WINDOW structure are visible to an application. This
is always defined when the threaded library is built, and is optional
otherwise. New functions for this: is_cleared, is_idcok, is_idlok,
is_immedok, is_keypad, is_leaveok, is_nodelay, is_notimeout,
is_scrollok, is_syncok, wgetparent and wgetscrreg.
+ the threaded library (ncursest) also disallows direct updating of
global curses-level variables, providing functions (via macros) for
obtaining their value. A few of those variables can be modified by
the application, using new functions: set_escdelay, set_tabsize
+ added functions use_window() and use_screen() which wrap a mutex
(if threading is configured) around a call to a user-supplied
function.
Added internal functions:
_nc_get_alias_table
_nc_get_screensize
_nc_keyname
_nc_screen_of
_nc_set_no_padding
_nc_tracechar
_nc_tracemouse
_nc_unctrl
_nc_ungetch
These are used for leak-testing, and are stubs for
ABI compatibility when ncurses is not configured for that
using the --disable-leaks configure script option:
_nc_free_and_exit
_nc_leaks_tinfo
Removed internal functions:
none
Modified internal functions:
_nc_fifo_dump
_nc_find_entry
_nc_handle_sigwinch
_nc_init_keytry
_nc_keypad
_nc_locale_breaks_acs
_nc_timed_wait
_nc_update_screensize
Use new typedef TRIES to replace "struct tries":
_nc_add_to_try
_nc_expand_try
_nc_remove_key
_nc_remove_string
_nc_trace_tries
5.6 (December 17, 2006)
Interface changes:

View file

@ -349,8 +349,10 @@
./doc/html/man/curs_instr.3x.html
./doc/html/man/curs_inwstr.3x.html
./doc/html/man/curs_kernel.3x.html
./doc/html/man/curs_legacy.3x.html
./doc/html/man/curs_mouse.3x.html
./doc/html/man/curs_move.3x.html
./doc/html/man/curs_opaque.3x.html
./doc/html/man/curs_outopts.3x.html
./doc/html/man/curs_overlay.3x.html
./doc/html/man/curs_pad.3x.html
@ -364,6 +366,7 @@
./doc/html/man/curs_termattrs.3x.html
./doc/html/man/curs_termcap.3x.html
./doc/html/man/curs_terminfo.3x.html
./doc/html/man/curs_threads.3x.html
./doc/html/man/curs_touch.3x.html
./doc/html/man/curs_trace.3x.html
./doc/html/man/curs_util.3x.html
@ -555,6 +558,7 @@
./man/curs_inwstr.3x
./man/curs_kernel.3x
./man/curs_legacy.3x
./man/curs_memleaks.3x
./man/curs_mouse.3x
./man/curs_move.3x
./man/curs_opaque.3x
@ -700,6 +704,7 @@
./misc/ncurses-config.in
./misc/ncurses.def
./misc/ncurses.ref
./misc/ncurses.supp
./misc/panel.def
./misc/panel.ref
./misc/run_tic.in

View file

@ -25,7 +25,7 @@
-- sale, use or other dealings in this Software without prior written --
-- authorization. --
-------------------------------------------------------------------------------
-- $Id: NEWS,v 1.1233 2008/05/03 23:14:39 tom Exp $
-- $Id: NEWS,v 1.1320 2008/11/02 00:56:22 tom Exp $
-------------------------------------------------------------------------------
This is a log of changes that ncurses has gone through since Zeyd started
@ -45,6 +45,238 @@ See the AUTHORS file for the corresponding full names.
Changes through 1.9.9e did not credit all contributions;
it is not possible to add this information.
20081102 5.7 release for upload to ftp.gnu.org
20081025
+ add a manpage to discuss memory leaks.
+ add support for shared libraries for QNX (other than libtool, which
does not work well on that platform).
+ build-fix for QNX C++ binding.
20081018
+ build-fixes for OS/2 EMX.
+ modify form library to accept control characters such as newline
in set_field_buffer(), which is compatible with Solaris (report by
Nit Khair).
+ modify configure script to assume --without-hashed-db when
--disable-database is used.
+ add "-e" option in ncurses/Makefile.in when generating source-files
to force earlier exit if the build environment fails unexpectedly
(prompted by patch by Adrian Bunk).
+ change configure script to use CF_UTF8_LIB, improved variant of
CF_LIBUTF8.
20081012
+ add teraterm4.59 terminfo entry, use that as primary teraterm entry, rename
original to teraterm2.3 -TD
+ update "gnome" terminfo to 2.22.3 -TD
+ update "konsole" terminfo to 1.6.6, needs today's fix for tic -TD
+ add "aterm" terminfo -TD
+ add "linux2.6.26" terminfo -TD
+ add logic to tic for cancelling strings in user-defined capabilities,
overlooked til now.
20081011
+ update html documentation.
+ add -m and -s options to test/keynames.c and test/key_names.c to test
the meta() function with keyname() or key_name(), respectively.
+ correct return value of key_name() on error; it is null.
+ document some unresolved issues for rpath and pthreads in TO-DO.
+ fix a missing prototype for ioctl() on OpenBSD in tset.c
+ add configure option --disable-tic-depends to make explicit whether
tic library depends on ncurses/ncursesw library, amends change from
20080823 (prompted by Debian #501421).
20081004
+ some build-fixes for configure --disable-ext-funcs (incomplete, but
works for C/C++ parts).
+ improve configure-check for awks unable to handle large strings, e.g.
AIX 5.1 whose awk silently gives up on large printf's.
20080927
+ fix build for --with-dmalloc by workaround for redefinition of
strndup between string.h and dmalloc.h
+ fix build for --disable-sigwinch
+ add environment variable NCURSES_GPM_TERMS to allow override to use
GPM on terminals other than "linux", etc.
+ disable GPM mouse support when $TERM does not happen to contain
"linux", since Gpm_Open() no longer limits its assertion to terminals
that it might handle, e.g., within "screen" in xterm.
+ reset mouse file-descriptor when unloading GPM library (report by
Miroslav Lichvar).
+ fix build for --disable-leaks --enable-widec --with-termlib
> patch by Juergen Pfeifer:
+ use improved initialization for soft-label keys in Ada95 sample code.
+ discard internal symbol _nc_slk_format (unused since 20080112).
+ move call of slk_paint_info() from _nc_slk_initialize() to
slk_intern_refresh(), improving initialization.
20080925
+ fix bug in mouse code for GPM from 20080920 changes (reported in
Debian #500103, also Miroslav Lichvar).
20080920
+ fix shared-library rules for cygwin with tic- and tinfo-libraries.
+ fix a memory leak when failure to connect to GPM.
+ correct check for notimeout() in wgetch() (report on linux.redhat
newsgroup by FurtiveBertie).
+ add an example warning-suppression file for valgrind,
misc/ncurses.supp (based on example from Reuben Thomas)
20080913
+ change shared-library configuration for OpenBSD, make rpath work.
+ build-fixes for using libutf8, e.g., on OpenBSD 3.7
20080907
+ corrected fix for --enable-weak-symbols (report by Frederic L W
Meunier).
20080906
+ corrected gcc options for building shared libraries on IRIX64.
+ add configure check for awk programs unable to handle big-strings,
use that to improve the default for --enable-big-strings option.
+ makefile-fixes for --enable-weak-symbols (report by Frederic L W
Meunier).
+ update test/configure script.
+ adapt ifdef's from library to make test/view.c build when mbrtowc()
is unavailable, e.g., with HPUX 10.20.
+ add configure check for wcsrtombs, mbsrtowcs, which are used in
test/ncurses.c, and use wcstombs, mbstowcs instead if available,
fixing build of ncursew for HPUX 11.00
20080830
+ fixes to make Ada95 demo_panels() example work.
+ modify Ada95 'rain' test program to accept keyboard commands like the
C-version.
+ modify BeOS-specific ifdef's to build on Haiku (patch by Scott
Mccreary).
+ add configure-check to see if the std namespace is legal for cerr
and endl, to fix a build issue with Tru64.
+ consistently use NCURSES_BOOL in lib_gen.c
+ filter #line's from lib_gen.c
+ change delimiter in MKlib_gen.sh from '%' to '@', to avoid
substitution by IBM xlc to '#' as part of its extensions to digraphs.
+ update config.guess, config.sub from
http://savannah.gnu.org/projects/config
(caveat - its maintainer removed support for older Linux systems).
20080823
+ modify configure check for pthread library to work with OSF/1 5.1,
which uses #define's to associate its header and library.
+ use pthread_mutexattr_init() for initializing pthread_mutexattr_t,
makes threaded code work on HPUX 11.23
+ fix a bug in demo_menus in freeing menus (cf: 20080804).
+ modify configure script for the case where tic library is used (and
possibly renamed) to remove its dependency upon ncurses/ncursew
library (patch by Dr Werner Fink).
+ correct manpage for menu_fore() which gave wrong default for
the attribute used to display a selected entry (report by Mike Gran).
+ add Eterm-256color, Eterm-88color and rxvt-88color (prompted by
Debian #495815) -TD
20080816
+ add configure option --enable-weak-symbols to turn on new feature.
+ add configure-check for availability of weak symbols.
+ modify linkage with pthread library to use weak symbols so that
applications not linked to that library will not use the mutexes,
etc. This relies on gcc, and may be platform-specific (patch by Dr
Werner Fink).
+ add note to INSTALL to document limitation of renaming of tic library
using the --with-ticlib configure option (report by Dr Werner Fink).
+ document (in manpage) why tputs does not detect I/O errors (prompted
by comments by Samuel Thibault).
+ fix remaining warnings from Klocwork report.
20080804
+ modify _nc_panelhook() data to account for a permanent memory leak.
+ fix memory leaks in test/demo_menus
+ fix most warnings from Klocwork tool (report by Larry Zhou).
+ modify configure script CF_XOPEN_SOURCE macro to add case for
"dragonfly" from xterm #236 changes.
+ modify configure script --with-hashed-db to let $LIBS override the
search for the db library (prompted by report by Samson Pierre).
20080726
+ build-fixes for gcc 4.3.1 (changes to gnat "warnings", and C inlining
thresholds).
20080713
+ build-fix (reports by Christian Ebert, Funda Wang).
20080712
+ compiler-warning fixes for Solaris.
20080705
+ use NCURSES_MOUSE_MASK() in definition of BUTTON_RELEASE(), etc., to
make those work properly with the "--enable-ext-mouse" configuration
(cf: 20050205).
+ improve documentation of build-cc options in INSTALL.
+ work-around a bug in gcc 4.2.4 on AIX, which does not pass the
-static/-dynamic flags properly to linker, causing test/bs to
not link.
20080628
+ correct some ifdef's needed for the broken-linker configuration.
+ make debugging library's $BAUDRATE feature work for termcap
interface.
+ make $NCURSES_NO_PADDING feature work for termcap interface (prompted
by comment on FreeBSD mailing list).
+ add screen.mlterm terminfo entry -TD
+ improve mlterm and mlterm+pcfkeys terminfo entries -TD
20080621
+ regenerated html documentation.
+ expand manpage description of parameters for form_driver() and
menu_driver() (prompted by discussion with Adam Spragg).
+ add null-pointer checks for cur_term in baudrate() and
def_shell_mode(), def_prog_mode()
+ fix some memory leaks in delscreen() and wide acs.
20080614
+ modify test/ditto.c to illustrate multi-threaded use_screen().
+ change CC_SHARED_OPTS from -KPIC to -xcode=pic32 for Solaris.
+ add "-shared" option to MK_SHARED_LIB for gcc on Solaris (report
by Poor Yorick).
20080607
+ finish changes to wgetch(), making it switch as needed to the
window's actual screen when calling wrefresh() and wgetnstr(). That
allows wgetch() to get used concurrently in different threads with
some minor restrictions, e.g., the application should not delete a
window which is being used in a wgetch().
+ simplify mutex's, combining the window- and screen-mutex's.
20080531
+ modify wgetch() to use the screen which corresponds to its window
parameter rather than relying on SP; some dependent functions still
use SP internally.
+ factor out most use of SP in lib_mouse.c, using parameter.
+ add internal _nc_keyname(), replacing keyname() to associate with a
particular SCREEN rather than the global SP.
+ add internal _nc_unctrl(), replacing unctrl() to associate with a
particular SCREEN rather than the global SP.
+ add internal _nc_tracemouse(), replacing _tracemouse() to eliminate
its associated global buffer _nc_globals.tracemse_buf now in SCREEN.
+ add internal _nc_tracechar(), replacing _tracechar() to use SCREEN in
preference to the global _nc_globals.tracechr_buf buffer.
20080524
+ modify _nc_keypad() to make it switch temporarily as needed to the
screen which must be updated.
+ wrap cur_term variable to help make _nc_keymap() thread-safe, and
always set the screen's copy of this variable in set_curterm().
+ restore curs_set() state after endwin()/refresh() (report/patch
Miroslav Lichvar)
20080517
+ modify configure script to note that --enable-ext-colors and
--enable-ext-mouse are not experimental, but extensions from
the ncurses ABI 5.
+ corrected manpage description of setcchar() (discussion with
Emanuele Giaquinta).
+ fix for adding a non-spacing character at the beginning of a line
(report/patch by Miroslav Lichvar).
20080503
+ modify screen.* terminfo entries using new screen+fkeys to fix
overridden keys in screen.rxvt (Debian #478094) -TD
@ -375,7 +607,7 @@ it is not possible to add this information.
20070609
+ add test/key_name.c
+ add stdscr cases to test/inchs.c and test_inch_wide.c
+ add stdscr cases to test/inchs.c and test/inch_wide.c
+ update test/configure
+ correct formatting of DEL (0x7f) in _nc_vischar().
+ null-terminate result of wunctrl().
@ -596,7 +828,7 @@ it is not possible to add this information.
shared libraries on Darwin (report by Michail Vidiassov).
20070210
+ add test/inchs.c, test_inch_wide.c, to test win_wchnstr().
+ add test/inchs.c, test/inch_wide.c, to test win_wchnstr().
+ remove libdl from library list for termlib (report by Miroslav
Lichvar).
+ fix configure.in to allow --without-progs --with-termlib (patch by

View file

@ -1,5 +1,5 @@
-------------------------------------------------------------------------------
-- Copyright (c) 1998-2006,2007 Free Software Foundation, Inc. --
-- Copyright (c) 1998-2007,2008 Free Software Foundation, Inc. --
-- --
-- Permission is hereby granted, free of charge, to any person obtaining a --
-- copy of this software and associated documentation files (the --
@ -25,7 +25,7 @@
-- sale, use or other dealings in this Software without prior written --
-- authorization. --
-------------------------------------------------------------------------------
-- $Id: TO-DO,v 1.49 2007/02/03 16:29:17 tom Exp $
-- $Id: TO-DO,v 1.51 2008/10/11 19:22:27 tom Exp $
-------------------------------------------------------------------------------
SHORT-TERM TO-DO ITEMS:
@ -61,6 +61,17 @@ Known Problems:
+ vid_attr() should support the set_a_attributes (sgr1) string, but does not.
There appear to be no terminals that require that functionality.
+ the configure --disable-ext-funcs option does not work for Ada95 tree.
+ the --with-pthread configuration builds for Cygwin, but does not work
properly (test/worm.c shows all of the worms in the same location).
+ the --enable-rpath configure option builds for the corresponding platforms;
however combining it with --with-ticlib and --with-termlib does not always
produce libraries that can be run without setting environment variables.
Building those with libtool does not work either. (This is a problem with
the BSD platforms).
Portability (or lack thereof):
+ Users of older System V UNIXes (but not Solaris, and probably not SVr4) may

View file

@ -28,7 +28,7 @@ dnl***************************************************************************
dnl
dnl Author: Thomas E. Dickey 1995-on
dnl
dnl $Id: aclocal.m4,v 1.447 2008/04/12 23:49:55 tom Exp $
dnl $Id: aclocal.m4,v 1.470 2008/10/25 22:15:32 tom Exp $
dnl Macros used in NCURSES auto-configuration script.
dnl
dnl These macros are maintained separately from NCURSES. The copyright on
@ -261,6 +261,28 @@ if test -n "$1" ; then
fi
])dnl
dnl ---------------------------------------------------------------------------
dnl CF_ADD_SUBDIR_PATH version: 2 updated: 2007/07/29 10:12:59
dnl ------------------
dnl Append to a search-list for a nonstandard header/lib-file
dnl $1 = the variable to return as result
dnl $2 = the package name
dnl $3 = the subdirectory, e.g., bin, include or lib
dnl $4 = the directory under which we will test for subdirectories
dnl $5 = a directory that we do not want $4 to match
AC_DEFUN([CF_ADD_SUBDIR_PATH],
[
test "$4" != "$5" && \
test -d "$4" && \
ifelse([$5],NONE,,[(test $5 = NONE || test -d $5) &&]) {
test -n "$verbose" && echo " ... testing for $3-directories under $4"
test -d $4/$3 && $1="[$]$1 $4/$3"
test -d $4/$3/$2 && $1="[$]$1 $4/$3/$2"
test -d $4/$3/$2/$3 && $1="[$]$1 $4/$3/$2/$3"
test -d $4/$2/$3 && $1="[$]$1 $4/$2/$3"
test -d $4/$2/$3/$2 && $1="[$]$1 $4/$2/$3/$2"
}
])dnl
dnl ---------------------------------------------------------------------------
dnl CF_ANSI_CC_CHECK version: 9 updated: 2001/12/30 17:53:34
dnl ----------------
dnl This is adapted from the macros 'fp_PROG_CC_STDC' and 'fp_C_PROTOTYPES'
@ -331,6 +353,30 @@ You have the following choices:
fi
])dnl
dnl ---------------------------------------------------------------------------
dnl CF_AWK_BIG_PRINTF version: 2 updated: 2008/10/04 17:16:18
dnl -----------------
dnl Check if awk can handle big strings using printf. Some older versions of
dnl awk choke on large strings passed via "%s".
dnl
dnl $1 = desired string size
dnl $2 = variable to set with result
AC_DEFUN([CF_AWK_BIG_PRINTF],
[
case x$AWK in #(vi
x)
eval $2=no
;;
*) #(vi
if ( ${AWK} 'BEGIN { xx = "x"; while (length(xx) < $1) { xx = xx "x"; }; printf("%s\n", xx); }' \
| $AWK '{ printf "%d\n", length([$]0); }' | $AWK 'BEGIN { eqls=0; recs=0; } { recs++; if ([$]0 == 12000) eqls++; } END { if (recs != 1 || eqls != 1) exit 1; }' 2>/dev/null >/dev/null ) ; then
eval $2=yes
else
eval $2=no
fi
;;
esac
])dnl
dnl ---------------------------------------------------------------------------
dnl CF_BOOL_DECL version: 8 updated: 2004/01/30 15:51:18
dnl ------------
dnl Test if 'bool' is a builtin type in the configured C++ compiler. Some
@ -649,13 +695,14 @@ if test ".$system_name" != ".$cf_cv_system_name" ; then
fi
])dnl
dnl ---------------------------------------------------------------------------
dnl CF_CHECK_ERRNO version: 9 updated: 2001/12/30 18:03:23
dnl CF_CHECK_ERRNO version: 10 updated: 2008/08/22 16:33:22
dnl --------------
dnl Check for data that is usually declared in <stdio.h> or <errno.h>, e.g.,
dnl the 'errno' variable. Define a DECL_xxx symbol if we must declare it
dnl ourselves.
dnl
dnl $1 = the name to check
dnl $2 = the assumed type
AC_DEFUN([CF_CHECK_ERRNO],
[
AC_CACHE_CHECK(if external $1 is declared, cf_cv_dcl_$1,[
@ -666,7 +713,7 @@ AC_CACHE_CHECK(if external $1 is declared, cf_cv_dcl_$1,[
#include <stdio.h>
#include <sys/types.h>
#include <errno.h> ],
[long x = (long) $1],
ifelse($2,,int,$2) x = (ifelse($2,,int,$2)) $1,
[cf_cv_dcl_$1=yes],
[cf_cv_dcl_$1=no])
])
@ -677,7 +724,7 @@ if test "$cf_cv_dcl_$1" = no ; then
fi
# It's possible (for near-UNIX clones) that the data doesn't exist
CF_CHECK_EXTERN_DATA($1,int)
CF_CHECK_EXTERN_DATA($1,ifelse($2,,int,$2))
])dnl
dnl ---------------------------------------------------------------------------
dnl CF_CHECK_EXTERN_DATA version: 3 updated: 2001/12/30 18:03:23
@ -920,6 +967,20 @@ if test "$with_no_leaks" = yes ; then
fi
])dnl
dnl ---------------------------------------------------------------------------
dnl CF_ENABLE_RPATH version: 1 updated: 2008/09/13 10:22:30
dnl ---------------
dnl Check if the rpath option should be used, setting cache variable
dnl cf_cv_ld_rpath if so.
AC_DEFUN([CF_ENABLE_RPATH],
[
AC_MSG_CHECKING(if rpath option should be used)
AC_ARG_ENABLE(rpath,
[ --enable-rpath use rpath option when generating shared libraries],
[cf_cv_ld_rpath=$enableval],
[cf_cv_ld_rpath=no])
AC_MSG_RESULT($cf_cv_ld_rpath)
])dnl
dnl ---------------------------------------------------------------------------
dnl CF_ERRNO version: 5 updated: 1997/11/30 12:44:39
dnl --------
dnl Check if 'errno' is declared in <errno.h>
@ -958,6 +1019,118 @@ AC_MSG_RESULT($cf_result)
CXXFLAGS="$cf_save_CXXFLAGS"
])
dnl ---------------------------------------------------------------------------
dnl CF_FIND_LINKAGE version: 12 updated: 2007/07/29 20:13:53
dnl ---------------
dnl Find a library (specifically the linkage used in the code fragment),
dnl searching for it if it is not already in the library path.
dnl See also CF_ADD_SEARCHPATH.
dnl
dnl Parameters (4-on are optional):
dnl $1 = headers for library entrypoint
dnl $2 = code fragment for library entrypoint
dnl $3 = the library name without the "-l" option or ".so" suffix.
dnl $4 = action to perform if successful (default: update CPPFLAGS, etc)
dnl $5 = action to perform if not successful
dnl $6 = module name, if not the same as the library name
dnl $7 = extra libraries
dnl
dnl Sets these variables:
dnl $cf_cv_find_linkage_$3 - yes/no according to whether linkage is found
dnl $cf_cv_header_path_$3 - include-directory if needed
dnl $cf_cv_library_path_$3 - library-directory if needed
dnl $cf_cv_library_file_$3 - library-file if needed, e.g., -l$3
AC_DEFUN([CF_FIND_LINKAGE],[
# If the linkage is not already in the $CPPFLAGS/$LDFLAGS configuration, these
# will be set on completion of the AC_TRY_LINK below.
cf_cv_header_path_$3=
cf_cv_library_path_$3=
CF_MSG_LOG([Starting [FIND_LINKAGE]($3,$6)])
AC_TRY_LINK([$1],[$2],
cf_cv_find_linkage_$3=yes,[
cf_cv_find_linkage_$3=no
CF_MSG_LOG([Searching for headers in [FIND_LINKAGE]($3,$6)])
cf_save_CPPFLAGS="$CPPFLAGS"
cf_test_CPPFLAGS="$CPPFLAGS"
CF_HEADER_PATH(cf_search,ifelse([$6],,[$3],[$6]))
for cf_cv_header_path_$3 in $cf_search
do
if test -d $cf_cv_header_path_$3 ; then
CF_VERBOSE(... testing $cf_cv_header_path_$3)
CPPFLAGS="$cf_save_CPPFLAGS -I$cf_cv_header_path_$3"
AC_TRY_COMPILE([$1],[$2],[
CF_VERBOSE(... found $3 headers in $cf_cv_header_path_$3)
cf_cv_find_linkage_$3=maybe
cf_test_CPPFLAGS="$CPPFLAGS"
break],[
CPPFLAGS="$cf_save_CPPFLAGS"
])
fi
done
if test "$cf_cv_find_linkage_$3" = maybe ; then
CF_MSG_LOG([Searching for $3 library in [FIND_LINKAGE]($3,$6)])
cf_save_LIBS="$LIBS"
cf_save_LDFLAGS="$LDFLAGS"
ifelse([$6],,,[
CPPFLAGS="$cf_test_CPPFLAGS"
LIBS="-l$3 $7 $cf_save_LIBS"
AC_TRY_LINK([$1],[$2],[
CF_VERBOSE(... found $3 library in system)
cf_cv_find_linkage_$3=yes])
CPPFLAGS="$cf_save_CPPFLAGS"
LIBS="$cf_save_LIBS"
])
if test "$cf_cv_find_linkage_$3" != yes ; then
CF_LIBRARY_PATH(cf_search,$3)
for cf_cv_library_path_$3 in $cf_search
do
if test -d $cf_cv_library_path_$3 ; then
CF_VERBOSE(... testing $cf_cv_library_path_$3)
CPPFLAGS="$cf_test_CPPFLAGS"
LIBS="-l$3 $7 $cf_save_LIBS"
LDFLAGS="$cf_save_LDFLAGS -L$cf_cv_library_path_$3"
AC_TRY_LINK([$1],[$2],[
CF_VERBOSE(... found $3 library in $cf_cv_library_path_$3)
cf_cv_find_linkage_$3=yes
cf_cv_library_file_$3="-l$3"
break],[
CPPFLAGS="$cf_save_CPPFLAGS"
LIBS="$cf_save_LIBS"
LDFLAGS="$cf_save_LDFLAGS"
])
fi
done
LIBS="$cf_save_LIBS"
CPPFLAGS="$cf_save_CPPFLAGS"
LDFLAGS="$cf_save_LDFLAGS"
fi
else
cf_cv_find_linkage_$3=no
fi
],$7)
if test "$cf_cv_find_linkage_$3" = yes ; then
ifelse([$4],,[
CF_ADD_INCDIR($cf_cv_header_path_$3)
CF_ADD_LIBDIR($cf_cv_library_path_$3)
LIBS="-l$3 $LIBS"
],[$4])
else
ifelse([$5],,AC_MSG_WARN(Cannot find $3 library),[$5])
fi
])dnl
dnl ---------------------------------------------------------------------------
dnl CF_FUNC_DLSYM version: 1 updated: 2004/06/16 20:52:45
dnl -------------
dnl Test for dlsym() and related functions, as well as libdl.
@ -1278,7 +1451,7 @@ if test "$GCC" = yes ; then
fi
])dnl
dnl ---------------------------------------------------------------------------
dnl CF_GCC_WARNINGS version: 22 updated: 2007/07/29 09:55:12
dnl CF_GCC_WARNINGS version: 23 updated: 2008/07/26 17:54:02
dnl ---------------
dnl Check if the compiler supports useful warning options. There's a few that
dnl we don't use, simply because they're too noisy:
@ -1373,7 +1546,7 @@ then
;;
Winline) #(vi
case $GCC_VERSION in
3.3*)
[[34]].*)
CF_VERBOSE(feature is broken in gcc $GCC_VERSION)
continue;;
esac
@ -1715,7 +1888,7 @@ fi
])
])dnl
dnl ---------------------------------------------------------------------------
dnl CF_HASHED_DB_LIBS version: 7 updated: 2007/12/01 15:01:37
dnl CF_HASHED_DB_LIBS version: 8 updated: 2008/08/04 06:18:06
dnl -----------------
dnl Given that we have the header and version for hashed database, find the
dnl library information.
@ -1723,7 +1896,7 @@ AC_DEFUN([CF_HASHED_DB_LIBS],
[
AC_CACHE_CHECK(for db libraries, cf_cv_hashed_db_libs,[
cf_cv_hashed_db_libs=unknown
for cf_db_libs in db$cf_cv_hashed_db_version db-$cf_cv_hashed_db_version db ''
for cf_db_libs in "" db$cf_cv_hashed_db_version db-$cf_cv_hashed_db_version db ''
do
cf_save_libs="$LIBS"
if test -n "$cf_db_libs"; then
@ -1823,6 +1996,27 @@ $ac_includes_default
])
done
])
])dnl
dnl ---------------------------------------------------------------------------
dnl CF_HEADER_PATH version: 8 updated: 2002/11/10 14:46:59
dnl --------------
dnl Construct a search-list for a nonstandard header-file
AC_DEFUN([CF_HEADER_PATH],
[CF_SUBDIR_PATH($1,$2,include)
test "$includedir" != NONE && \
test "$includedir" != "/usr/include" && \
test -d "$includedir" && {
test -d $includedir && $1="[$]$1 $includedir"
test -d $includedir/$2 && $1="[$]$1 $includedir/$2"
}
test "$oldincludedir" != NONE && \
test "$oldincludedir" != "/usr/include" && \
test -d "$oldincludedir" && {
test -d $oldincludedir && $1="[$]$1 $oldincludedir"
test -d $oldincludedir/$2 && $1="[$]$1 $oldincludedir/$2"
}
])dnl
dnl ---------------------------------------------------------------------------
dnl CF_HELP_MESSAGE version: 3 updated: 1998/01/14 10:56:23
@ -1949,7 +2143,7 @@ ifdef([AC_FUNC_FSEEKO],[
])
])
dnl ---------------------------------------------------------------------------
dnl CF_LDFLAGS_STATIC version: 2 updated: 2007/04/28 15:25:27
dnl CF_LDFLAGS_STATIC version: 4 updated: 2008/10/18 17:58:20
dnl -----------------
dnl Check for compiler/linker flags used to temporarily force usage of static
dnl libraries. This depends on the compiler and platform. Use this to help
@ -1958,8 +2152,16 @@ dnl the list of linker options and libraries.
AC_DEFUN([CF_LDFLAGS_STATIC],[
if test "$GCC" = yes ; then
LDFLAGS_STATIC=-static
LDFLAGS_SHARED=-dynamic
case $cf_cv_system_name in #(
OS/2*|os2*|aix[[45]]*) #( vi
LDFLAGS_STATIC=
LDFLAGS_SHARED=
;;
*) #( normally, except when broken
LDFLAGS_STATIC=-static
LDFLAGS_SHARED=-dynamic
;;
esac
else
case $cf_cv_system_name in #(
aix[[45]]*) #( from ld manpage
@ -1991,43 +2193,30 @@ AC_SUBST(LDFLAGS_STATIC)
AC_SUBST(LDFLAGS_SHARED)
])
dnl ---------------------------------------------------------------------------
dnl CF_LIBUTF8 version: 2 updated: 2002/01/19 22:51:32
dnl ----------
dnl Check for libutf8
AC_DEFUN([CF_LIBUTF8],
[
AC_CACHE_CHECK(for putwc in libutf8,cf_cv_libutf8,[
cf_save_LIBS="$LIBS"
LIBS="-lutf8 $LIBS"
AC_TRY_LINK([
#include <libutf8.h>],[putwc(0,0);],
[cf_cv_libutf8=yes],
[cf_cv_libutf8=no])
LIBS="$cf_save_LIBS"
])
if test "$cf_cv_libutf8" = yes ; then
AC_DEFINE(HAVE_LIBUTF8_H)
LIBS="-lutf8 $LIBS"
fi
])dnl
dnl CF_LIBRARY_PATH version: 7 updated: 2002/11/10 14:46:59
dnl ---------------
dnl Construct a search-list for a nonstandard library-file
AC_DEFUN([CF_LIBRARY_PATH],
[CF_SUBDIR_PATH($1,$2,lib)])dnl
dnl ---------------------------------------------------------------------------
dnl CF_LIB_PREFIX version: 7 updated: 2001/01/12 01:23:48
dnl CF_LIB_PREFIX version: 8 updated: 2008/09/13 11:34:16
dnl -------------
dnl Compute the library-prefix for the given host system
dnl $1 = variable to set
AC_DEFUN([CF_LIB_PREFIX],
[
case $cf_cv_system_name in
OS/2*) LIB_PREFIX='' ;;
os2*) LIB_PREFIX='' ;;
*) LIB_PREFIX='lib' ;;
case $cf_cv_system_name in #(vi
OS/2*|os2*) #(vi
LIB_PREFIX=''
;;
*) LIB_PREFIX='lib'
;;
esac
ifelse($1,,,[$1=$LIB_PREFIX])
AC_SUBST(LIB_PREFIX)
])dnl
dnl ---------------------------------------------------------------------------
dnl CF_LIB_RULES version: 50 updated: 2007/03/24 18:26:59
dnl CF_LIB_RULES version: 53 updated: 2008/09/20 19:51:59
dnl ------------
dnl Append definitions and rules for the given models to the subdirectory
dnl Makefiles, and the recursion rule for the top-level Makefile. If the
@ -2044,6 +2233,12 @@ AC_DEFUN([CF_LIB_RULES],
[
CF_LIB_PREFIX(cf_prefix)
AC_REQUIRE([CF_SUBST_NCURSES_VERSION])
if test $cf_cv_shlib_version = cygdll ; then
TINFO_NAME=$TINFO_ARG_SUFFIX
TINFO_SUFFIX=.dll
fi
for cf_dir in $SRC_SUBDIRS
do
if test ! -d $srcdir/$cf_dir ; then
@ -2054,7 +2249,7 @@ do
LIBS_TO_MAKE=
for cf_item in $cf_LIST_MODELS
do
CF_LIB_SUFFIX($cf_item,cf_suffix)
CF_LIB_SUFFIX($cf_item,cf_suffix,cf_depsuf)
if test $cf_item = shared ; then
if test "$cf_cv_do_symlinks" = yes ; then
case "$cf_cv_shlib_version" in #(vi
@ -2096,7 +2291,8 @@ do
# use autodetected ${cf_prefix} for import lib and static lib, but
# use 'cyg' prefix for shared lib.
if test $cf_cv_shlib_version = cygdll ; then
LIBS_TO_MAKE="$LIBS_TO_MAKE ../lib/cyg${cf_dir}\${ABI_VERSION}.dll"
cf_cygsuf=`echo "$cf_suffix" | sed -e 's/\.dll/\${ABI_VERSION}.dll/'`
LIBS_TO_MAKE="$LIBS_TO_MAKE ../lib/cyg${cf_dir}${cf_cygsuf}"
continue
fi
fi
@ -2106,24 +2302,28 @@ do
if test $cf_dir = ncurses ; then
cf_subsets="$LIB_SUBSETS"
cf_r_parts="$cf_subsets"
cf_liblist="$LIBS_TO_MAKE"
while test -n "$cf_r_parts"
do
cf_l_parts=`echo "$cf_r_parts" |sed -e 's/ .*$//'`
cf_r_parts=`echo "$cf_r_parts" |sed -e 's/^[[^ ]]* //'`
if test "$cf_l_parts" != "$cf_r_parts" ; then
cf_item=
case $cf_l_parts in #(vi
*termlib*) #(vi
cf_item=`echo $LIBS_TO_MAKE |sed -e s%${LIB_NAME}${LIB_SUFFIX}%${TINFO_LIB_SUFFIX}%g`
cf_item=`echo $cf_liblist |sed -e s%${LIB_NAME}${LIB_SUFFIX}%${TINFO_LIB_SUFFIX}%g`
;;
*ticlib*)
cf_item=`echo $LIBS_TO_MAKE |sed -e s%${LIB_NAME}${LIB_SUFFIX}%${TICS_LIB_SUFFIX}%g`
cf_item=`echo $cf_liblist |sed -e s%${LIB_NAME}${LIB_SUFFIX}%${TICS_LIB_SUFFIX}%g`
;;
*)
break
;;
esac
LIBS_TO_MAKE="$cf_item $LIBS_TO_MAKE"
if test -n "$cf_item"; then
LIBS_TO_MAKE="$cf_item $LIBS_TO_MAKE"
fi
else
break
fi
@ -2148,7 +2348,7 @@ do
do
echo "Appending rules for ${cf_item} model (${cf_dir}: ${cf_subset})"
CF_UPPER(cf_ITEM,$cf_item)
CF_LIB_SUFFIX($cf_item,cf_suffix)
CF_LIB_SUFFIX($cf_item,cf_suffix,cf_depsuf)
CF_OBJ_SUBDIR($cf_item,cf_subdir)
# Test for case where we build libtinfo with a different name.
@ -2156,22 +2356,21 @@ do
if test $cf_dir = ncurses ; then
case $cf_subset in
*base*)
cf_libname=${cf_libname}$LIB_SUFFIX
;;
*termlib*)
cf_libname=$TINFO_LIB_SUFFIX
if test -n "${DFT_ARG_SUFFIX}" ; then
# undo $LIB_SUFFIX add-on in CF_LIB_SUFFIX
cf_suffix=`echo $cf_suffix |sed -e "s%^${LIB_SUFFIX}%%"`
fi
;;
ticlib*)
cf_libname=$TICS_LIB_SUFFIX
if test -n "${DFT_ARG_SUFFIX}" ; then
# undo $LIB_SUFFIX add-on in CF_LIB_SUFFIX
cf_suffix=`echo $cf_suffix |sed -e "s%^${LIB_SUFFIX}%%"`
fi
;;
esac
else
cf_libname=${cf_libname}$LIB_SUFFIX
fi
if test -n "${DFT_ARG_SUFFIX}" ; then
# undo $LIB_SUFFIX add-on in CF_LIB_SUFFIX
cf_suffix=`echo $cf_suffix |sed -e "s%^${LIB_SUFFIX}%%"`
fi
# These dependencies really are for development, not
@ -2480,34 +2679,62 @@ fi
])
])
dnl ---------------------------------------------------------------------------
dnl CF_LIB_SUFFIX version: 13 updated: 2003/11/01 16:09:07
dnl CF_LIB_SUFFIX version: 15 updated: 2008/09/13 11:54:48
dnl -------------
dnl Compute the library file-suffix from the given model name
dnl $1 = model name
dnl $2 = variable to set
dnl $2 = variable to set (the nominal library suffix)
dnl $3 = dependency variable to set (actual filename)
dnl The variable $LIB_SUFFIX, if set, prepends the variable to set.
AC_DEFUN([CF_LIB_SUFFIX],
[
AC_REQUIRE([CF_SUBST_NCURSES_VERSION])
case $1 in
libtool) $2='.la' ;;
normal) $2='.a' ;;
debug) $2='_g.a' ;;
profile) $2='_p.a' ;;
libtool)
$2='.la'
$3=[$]$2
;;
normal)
$2='.a'
$3=[$]$2
;;
debug)
$2='_g.a'
$3=[$]$2
;;
profile)
$2='_p.a'
$3=[$]$2
;;
shared)
case $cf_cv_system_name in
cygwin*) $2='.dll' ;;
darwin*) $2='.dylib' ;;
cygwin*)
$2='.dll'
$3='.dll.a'
;;
darwin*)
$2='.dylib'
$3=[$]$2
;;
hpux*)
case $target in
ia64*) $2='.so' ;;
*) $2='.sl' ;;
ia64*)
$2='.so'
$3=[$]$2
;;
*)
$2='.sl'
$3=[$]$2
;;
esac
;;
*) $2='.so' ;;
*) $2='.so'
$3=[$]$2
;;
esac
esac
test -n "$LIB_SUFFIX" && $2="${LIB_SUFFIX}[$]{$2}"
test -n "$LIB_SUFFIX" && $3="${LIB_SUFFIX}[$]{$3}"
])dnl
dnl ---------------------------------------------------------------------------
dnl CF_LIB_TYPE version: 4 updated: 2000/10/20 22:57:49
@ -3869,7 +4096,7 @@ define([CF_REMOVE_LIB],
$1=`echo "$2" | sed -e 's/-l$3[[ ]]//g' -e 's/-l$3[$]//'`
])dnl
dnl ---------------------------------------------------------------------------
dnl CF_RPATH_HACK version: 3 updated: 2007/12/01 11:14:13
dnl CF_RPATH_HACK version: 4 updated: 2008/09/13 12:53:26
dnl -------------
AC_DEFUN([CF_RPATH_HACK],
[
@ -3881,48 +4108,46 @@ CF_VERBOSE(...checking LDFLAGS $LDFLAGS)
CF_VERBOSE(...checking EXTRA_LDFLAGS $EXTRA_LDFLAGS)
case "$EXTRA_LDFLAGS" in #(vi
-Wl,-rpath,*) #(vi
cf_rpath_hack="-Wl,-rpath,"
;;
cf_rpath_hack="-Wl,-rpath,"
;;
-R\ *)
cf_rpath_hack="-R "
;;
cf_rpath_hack="-R "
;;
-R*)
cf_rpath_hack="-R"
;;
cf_rpath_hack="-R"
;;
*)
cf_rpath_hack=
;;
cf_rpath_hack=
;;
esac
if test -n "$cf_rpath_hack" ; then
cf_rpath_dst=
for cf_rpath_src in $LDFLAGS
do
CF_VERBOSE(Filtering $cf_rpath_src)
case $cf_rpath_src in #(vi
-L*) #(vi
if test "$cf_rpath_hack" = "-R " ; then
cf_rpath_tmp=`echo "$cf_rpath_src" |sed -e 's%-L%-R %'`
else
cf_rpath_tmp=`echo "$cf_rpath_src" |sed -e s%-L%$cf_rpath_hack%`
fi
CF_VERBOSE(...Filter $cf_rpath_tmp)
EXTRA_LDFLAGS="$cf_rpath_tmp $EXTRA_LDFLAGS"
;;
*)
cf_rpath_dst="$cf_rpath_dst $cf_rpath_src"
;;
esac
done
LDFLAGS=$cf_rpath_dst
CF_VERBOSE(...checked LDFLAGS $LDFLAGS)
CF_VERBOSE(...checked EXTRA_LDFLAGS $EXTRA_LDFLAGS)
cf_rpath_dst=
for cf_rpath_src in $LDFLAGS
do
CF_VERBOSE(Filtering $cf_rpath_src)
case $cf_rpath_src in #(vi
-L*) #(vi
if test "$cf_rpath_hack" = "-R " ; then
cf_rpath_tmp=`echo "$cf_rpath_src" |sed -e 's%-L%-R %'`
else
cf_rpath_tmp=`echo "$cf_rpath_src" |sed -e s%-L%$cf_rpath_hack%`
fi
CF_VERBOSE(...Filter $cf_rpath_tmp)
EXTRA_LDFLAGS="$cf_rpath_tmp $EXTRA_LDFLAGS"
;;
esac
cf_rpath_dst="$cf_rpath_dst $cf_rpath_src"
done
LDFLAGS=$cf_rpath_dst
CF_VERBOSE(...checked LDFLAGS $LDFLAGS)
CF_VERBOSE(...checked EXTRA_LDFLAGS $EXTRA_LDFLAGS)
fi
else
AC_MSG_RESULT(no)
fi
])dnl
dnl ---------------------------------------------------------------------------
dnl CF_SHARED_OPTS version: 47 updated: 2008/03/23 14:48:54
dnl CF_SHARED_OPTS version: 53 updated: 2008/10/25 18:14:20
dnl --------------
dnl --------------
dnl Attempt to determine the appropriate CC/LD options for creating a shared
@ -4057,8 +4282,10 @@ CF_EOF
# tested with IRIX 5.2 and 'cc'.
if test "$GCC" != yes; then
CC_SHARED_OPTS='-KPIC'
MK_SHARED_LIB='${CC} -shared -rdata_shared -soname `basename $[@]` -o $[@]'
else
MK_SHARED_LIB='${CC} -shared -Wl,-soname,`basename $[@]` -o $[@]'
fi
MK_SHARED_LIB='${CC} -shared -rdata_shared -soname `basename $[@]` -o $[@]'
cf_cv_rm_so_locs=yes
;;
linux*|gnu*|k*bsd*-gnu)
@ -4071,13 +4298,22 @@ CF_EOF
EXTRA_LDFLAGS="-Wl,-rpath,\${libdir} $EXTRA_LDFLAGS"
fi
CF_SHARED_SONAME
MK_SHARED_LIB='${CC} ${CFLAGS} -shared -Wl,-soname,'$cf_shared_soname',-stats,-lc -o $[@]'
MK_SHARED_LIB='${CC} ${CFLAGS} -shared -Wl,-soname,'$cf_cv_shared_soname',-stats,-lc -o $[@]'
;;
openbsd[[2-9]].*)
if test "$DFT_LWR_MODEL" = "shared" ; then
LOCAL_LDFLAGS="-Wl,-rpath,\$(LOCAL_LIBDIR)"
LOCAL_LDFLAGS2="$LOCAL_LDFLAGS"
fi
if test "$cf_cv_ld_rpath" = yes ; then
cf_ld_rpath_opt="-Wl,-rpath,"
EXTRA_LDFLAGS="-Wl,-rpath,\${libdir} $EXTRA_LDFLAGS"
fi
CC_SHARED_OPTS="$CC_SHARED_OPTS -DPIC"
MK_SHARED_LIB='${LD} -Bshareable -soname,`basename $[@].${ABI_VERSION}` -o $[@]'
CF_SHARED_SONAME
MK_SHARED_LIB='${CC} ${CFLAGS} -Wl,-Bshareable,-soname,'$cf_cv_shared_soname',-stats,-lc -o $[@]'
;;
openbsd*|freebsd[[12]].*)
nto-qnx*|openbsd*|freebsd[[12]].*)
CC_SHARED_OPTS="$CC_SHARED_OPTS -DPIC"
MK_SHARED_LIB='${LD} -Bshareable -o $[@]'
test "$cf_cv_shlib_version" = auto && cf_cv_shlib_version=rel
@ -4108,7 +4344,7 @@ CF_EOF
fi
fi
CF_SHARED_SONAME
MK_SHARED_LIB='${CC} ${CFLAGS} -shared -Wl,-soname,'$cf_shared_soname' -o $[@]'
MK_SHARED_LIB='${CC} ${CFLAGS} -shared -Wl,-soname,'$cf_cv_shared_soname' -o $[@]'
else
MK_SHARED_LIB='${LD} -Bshareable -o $[@]'
fi
@ -4158,9 +4394,7 @@ CF_EOF
;;
solaris2*)
# tested with SunOS 5.5.1 (solaris 2.5.1) and gcc 2.7.2
if test "$GCC" != yes; then
CC_SHARED_OPTS='-KPIC'
fi
# tested with SunOS 5.10 (solaris 10) and gcc 3.4.3
if test "$DFT_LWR_MODEL" = "shared" ; then
LOCAL_LDFLAGS="-R \$(LOCAL_LIBDIR):\${libdir}"
LOCAL_LDFLAGS2="$LOCAL_LDFLAGS"
@ -4170,7 +4404,12 @@ CF_EOF
EXTRA_LDFLAGS="$LOCAL_LDFLAGS $EXTRA_LDFLAGS"
fi
CF_SHARED_SONAME
MK_SHARED_LIB='${CC} -dy -G -h '$cf_shared_soname' -o $[@]'
if test "$GCC" != yes; then
CC_SHARED_OPTS='-xcode=pic32'
MK_SHARED_LIB='${CC} -dy -G -h '$cf_cv_shared_soname' -o $[@]'
else
MK_SHARED_LIB='${CC} -shared -dy -G -h '$cf_cv_shared_soname' -o $[@]'
fi
;;
sysv5uw7*|unix_sv*)
# tested with UnixWare 7.1.0 (gcc 2.95.2 and cc)
@ -4221,9 +4460,9 @@ CF_EOF
AC_SUBST(INSTALL_LIB)
])dnl
dnl ---------------------------------------------------------------------------
dnl CF_SHARED_SONAME version: 2 updated: 2006/10/21 12:33:41
dnl CF_SHARED_SONAME version: 3 updated: 2008/09/08 18:34:43
dnl ----------------
dnl utility macro for CF_SHARED_OPTS, constructs "$cf_shared_soname" for
dnl utility macro for CF_SHARED_OPTS, constructs "$cf_cv_shared_soname" for
dnl substitution into MK_SHARED_LIB string for the "-soname" (or similar)
dnl option.
dnl
@ -4233,9 +4472,9 @@ define([CF_SHARED_SONAME],
[
test "$cf_cv_shlib_version" = auto && cf_cv_shlib_version=ifelse($1,,rel,$1)
if test "$cf_cv_shlib_version" = rel; then
cf_shared_soname='`basename $[@] .${REL_VERSION}`.${ABI_VERSION}'
cf_cv_shared_soname='`basename $[@] .${REL_VERSION}`.${ABI_VERSION}'
else
cf_shared_soname='`basename $[@]`'
cf_cv_shared_soname='`basename $[@]`'
fi
])
dnl ---------------------------------------------------------------------------
@ -4607,6 +4846,22 @@ if test "$ac_cv_header_termios_h" = yes ; then
fi
])dnl
dnl ---------------------------------------------------------------------------
dnl CF_SUBDIR_PATH version: 5 updated: 2007/07/29 09:55:12
dnl --------------
dnl Construct a search-list for a nonstandard header/lib-file
dnl $1 = the variable to return as result
dnl $2 = the package name
dnl $3 = the subdirectory, e.g., bin, include or lib
AC_DEFUN([CF_SUBDIR_PATH],
[$1=""
CF_ADD_SUBDIR_PATH($1,$2,$3,/usr,$prefix)
CF_ADD_SUBDIR_PATH($1,$2,$3,$prefix,NONE)
CF_ADD_SUBDIR_PATH($1,$2,$3,/usr/local,$prefix)
CF_ADD_SUBDIR_PATH($1,$2,$3,/opt,$prefix)
CF_ADD_SUBDIR_PATH($1,$2,$3,[$]HOME,$prefix)
])dnl
dnl ---------------------------------------------------------------------------
dnl CF_SUBST version: 4 updated: 2006/06/17 12:33:03
dnl --------
dnl Shorthand macro for substituting things that the user may override
@ -4793,6 +5048,32 @@ AC_DEFUN([CF_UPPER],
$1=`echo "$2" | sed y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%`
])dnl
dnl ---------------------------------------------------------------------------
dnl CF_UTF8_LIB version: 5 updated: 2008/10/17 19:37:52
dnl -----------
dnl Check for multibyte support, and if not found, utf8 compatibility library
AC_DEFUN([CF_UTF8_LIB],
[
AC_CACHE_CHECK(for multibyte character support,cf_cv_utf8_lib,[
cf_save_LIBS="$LIBS"
AC_TRY_LINK([
#include <stdlib.h>],[putwc(0,0);],
[cf_cv_utf8_lib=yes],
[CF_FIND_LINKAGE([
#include <libutf8.h>],[putwc(0,0);],utf8,
[cf_cv_utf8_lib=add-on],
[cf_cv_utf8_lib=no])
])])
# HAVE_LIBUTF8_H is used by ncurses if curses.h is shared between
# ncurses/ncursesw:
if test "$cf_cv_utf8_lib" = "add-on" ; then
AC_DEFINE(HAVE_LIBUTF8_H)
CF_ADD_INCDIR($cf_cv_header_path_utf8)
CF_ADD_LIBDIR($cf_cv_library_path_utf8)
LIBS="-lutf8 $LIBS"
fi
])dnl
dnl ---------------------------------------------------------------------------
dnl CF_VERBOSE version: 3 updated: 2007/07/29 09:55:12
dnl ----------
dnl Use AC_VERBOSE w/o the warnings
@ -4851,6 +5132,32 @@ fi
])
])dnl
dnl ---------------------------------------------------------------------------
dnl CF_WEAK_SYMBOLS version: 1 updated: 2008/08/16 19:18:06
dnl ---------------
dnl Check for compiler-support for weak symbols.
dnl This works with "recent" gcc.
AC_DEFUN([CF_WEAK_SYMBOLS],[
AC_CACHE_CHECK(if $CC supports weak symbols,cf_cv_weak_symbols,[
AC_TRY_COMPILE([
#include <stdio.h>],
[
#if defined(__GNUC__)
# if defined __USE_ISOC99
# define _cat_pragma(exp) _Pragma(#exp)
# define _weak_pragma(exp) _cat_pragma(weak name)
# else
# define _weak_pragma(exp)
# endif
# define _declare(name) __extension__ extern __typeof__(name) name
# define weak_symbol(name) _weak_pragma(name) _declare(name) __attribute__((weak))
#endif
weak_symbol(fopen);
],[cf_cv_weak_symbols=yes],[cf_cv_weak_symbols=no])
])
])dnl
dnl ---------------------------------------------------------------------------
dnl CF_WITH_ABI_VERSION version: 1 updated: 2003/09/20 18:12:49
dnl -------------------
dnl Allow library's ABI to be overridden. Generally this happens when a
@ -5128,7 +5435,7 @@ AC_SUBST($3)dnl
])dnl
dnl ---------------------------------------------------------------------------
dnl CF_WITH_PTHREAD version: 1 updated: 2008/03/29 13:42:21
dnl CF_WITH_PTHREAD version: 2 updated: 2008/08/23 18:26:05
dnl ---------------
dnl Check for POSIX thread library.
AC_DEFUN([CF_WITH_PTHREAD],
@ -5143,13 +5450,24 @@ AC_MSG_RESULT($with_pthread)
if test "$with_pthread" != no ; then
AC_CHECK_HEADER(pthread.h,[
AC_DEFINE(HAVE_PTHREADS_H)
AC_CHECK_LIB(pthread,pthread_create,[
AC_MSG_CHECKING(if we can link with the pthread library)
cf_save_LIBS="$LIBS"
LIBS="-lpthread $LIBS"
AC_TRY_LINK([
#include <pthread.h>
],[
int rc = pthread_create(0,0,0,0);
],[with_pthread=yes],[with_pthread=no])
LIBS="$cf_save_LIBS"
AC_MSG_RESULT($with_pthread)
if test "$with_pthread" = yes ; then
LIBS="-lpthread $LIBS"
AC_DEFINE(HAVE_LIBPTHREADS)
with_pthread=yes
],[
else
AC_MSG_ERROR(Cannot link with pthread library)
])
fi
])
fi
])
@ -5217,7 +5535,7 @@ CF_NO_LEAKS_OPTION(valgrind,
[USE_VALGRIND])
])dnl
dnl ---------------------------------------------------------------------------
dnl CF_XOPEN_SOURCE version: 25 updated: 2007/01/29 18:36:38
dnl CF_XOPEN_SOURCE version: 26 updated: 2008/07/27 11:26:57
dnl ---------------
dnl Try to get _XOPEN_SOURCE defined properly that we can use POSIX functions,
dnl or adapt to the vendor's definitions to get equivalent functionality,
@ -5237,7 +5555,7 @@ case $host_os in #(vi
aix[[45]]*) #(vi
CPPFLAGS="$CPPFLAGS -D_ALL_SOURCE"
;;
freebsd*) #(vi
freebsd*|dragonfly*) #(vi
# 5.x headers associate
# _XOPEN_SOURCE=600 with _POSIX_C_SOURCE=200112L
# _XOPEN_SOURCE=500 with _POSIX_C_SOURCE=199506L

View file

@ -1,8 +1,8 @@
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 3.0//EN">
<!--
$Id: announce.html.in,v 1.64 2006/12/17 23:31:26 tom Exp $
$Id: announce.html.in,v 1.70 2008/11/02 01:03:05 tom Exp $
****************************************************************************
* Copyright (c) 1998-2005,2006 Free Software Foundation, Inc. *
* Copyright (c) 1998-2006,2008 Free Software Foundation, Inc. *
* *
* Permission is hereby granted, free of charge, to any person obtaining a *
* copy of this software and associated documentation files (the *
@ -69,185 +69,170 @@ the GNU distribution site
<H1>Release Notes</H1>
This release is designed to be upward compatible from ncurses 5.0 through 5.5;
This release is designed to be upward compatible from ncurses 5.0 through 5.6;
very few applications will require recompilation, depending on the platform.
These are the highlights from the change-log since ncurses 5.5 release.
These are the highlights from the change-log since ncurses 5.6 release.
<p>
Interface changes:
<ul>
<li>generate linkable stubs for some macros:
<br>
getbegx, getbegy, getcurx, getcury, getmaxx, getmaxy, getparx,
getpary, getpary,
<br>
and (for libncursesw)
<br>
wgetbkgrnd
getattrs
</ul>
New features and improvements:
<ul>
<li>library
<ul>
<li>support hashed databases for the terminal descriptions.
This uses the Berkeley database, has been tested for
several versions on different platforms.
<li>new flavor of the ncurses library provides rudimentary
support for POSIX threads. Several functions are
reentrant, but most require either a window-level or
screen-level mutex.<br>
(This is <em>API</em>-compatible,
but not <em>ABI</em>-compatible with the normal library).
<li>add <code>use_legacy_coding()</code> function to support
lynx's font-switching feature.
<li>add <code>NCURSES_OPAQUE</code> symbol to curses.h, will
use to make structs opaque in selected configurations.
<li>add extension <code>nofilter()</code>, to cancel a prior
<code>filter()</code> call.
<li>add <code>NCURSES_EXT_FUNCS</code> and
<code>NCURSES_EXT_COLORS</code> symbols to curses.h to make
it simpler to tell if the extended functions and/or colors
are declared.
<li>add/install a package config script, e.g.,
<code>ncurses5-config</code> or
<code>ncursesw5-config</code>, according to
configuration options.
<li>add wresize() to C++ binding
<li>provide ifdef for <code>NCURSES_NOMACROS</code> which
suppresses most macro definitions from curses.h, i.e.,
where a macro is defined to override a function to improve
performance.
<li>eliminate fixed-buffer vsprintf() calls in C++ binding.
<li>make ifdef's consistent in <code>curses.h</code> for the
extended colors so the header file can be used for the
normal curses library. The header file installed for
extended colors is a variation of the wide-character
configuration.
<li>add several functions to C++ binding which wrap C functions
that pass a WINDOW* parameter.
<li>improve <code>tgetstr()</code> by making the return value
point into the user's buffer, if provided.
<li>adapt mouse-handling code from menu library in form-library
<li>add ifdef's allowing ncurses to be built with
<code>tparm()</code> using either varargs (the existing
status), or using a fixed-parameter list (to match X/Open).
<li>improve tracing for form library, showing created forms,
fields, etc.
<li>widen the test for xterm <code>kmous</code> a little to
<code>allow</code> for other
strings than "\E[M", e.g., for <code>xterm-sco</code>
functionality in xterm.
<li>make $NCURSES_NO_PADDING feature work for termcap interface .
<li>modify <code>wgetnstr()</code> to return
<code>KEY_RESIZE</code> if a sigwinch occurs.
<li>add check to trace-file open, if the given name is a
directory, add ".log" to the name and try again.
<li>move prototypes for wide-character trace functions from
curses.tail to curses.wide to avoid accidental reference to
those if <code>_XOPEN_SOURCE_EXTENDED</code> is defined
without ensuring that &lt;wchar.h&gt; is included.
<li>change the way shared libraries (other than libtool) are
installed. Rather than copying the build-tree's libraries,
link the shared objects into the install directory. This
makes the <code>--with-rpath</code> option work except with
<code>$(DESTDIR)</code>.
<li>several improvements for rendering in hpterm. These are
only available if the library is configured using
<code>--enable-xmc-glitch</code>.
<li>Add <code>NCURSES_NO_HARD_TABS</code> and
<code>NCURSES_NO_MAGIC_COOKIE</code> environment variables
to allow runtime suppression of the related hard-tabs and
xmc-glitch features.
<li>several new manpages: curs_legacy.3x, curs_memleaks.3x,
curs_opaque.3x and curs_threads.3x
</ul>
<li>programs:
<ul>
<li>add new test programs: chgat.c, demo_altkeys.c,
echochar.c, foldkeys.c, movewindow.c, redraw.c, (noting
that existing test programs also were modified to test
additional features).
<li>modified three test-programs to demonstrate the threading
support in this version: ditto, rain, worm.
<li>modify tack to test extended capability function-key
strings.
<li>several new test-programs: demo_panels, dots_mvcur,
inch_wide, inchs, key_name, key_names, savescreen,
savescreen.sh test_arrays, test_get_wstr, test_getstr,
test_instr, test_inwstr and test_opaque.
<li>modify toe to access termcap data, e.g., via <code>cgetent()</code>
functions, or as a text file if those are not available.
<li>add <code>adacurses-config</code> to the Ada95 install.
<li>improve infocmp/tic <code>-f</code> option formatting.
<li>modify tic <code>-f</code> option to format spaces as
<code>\s</code> to prevent them from being lost when that
is read back in unformatted strings.
<li>add <code>toe -a</code> option, to show all databases.
This uses new private interfaces in the ncurses library for
iterating through the list of databases.
<li>modify <code>MKfallback.sh</code> to use
<code>tic&nbsp;-x</code> when constructing fallback tables to
allow extended capabilities to be retrieved from a fallback entry.
<li>The <code>tack</code> program is now distributed separately
from ncurses.
</ul>
<li>terminal database
<ul>
<li>add terminfo entries for xfce terminal (xfce) and multi gnome terminal (mgt)
<li>add nsterm-16color entry
<li>updated mlterm terminfo entry
<li>add kon, kon2 and jfbterm terminfo entry
<li>remove invis capability from klone+sgr, mainly used by linux entry, since it does not really do this
<li>add ka2, kb1, kb3, kc2 to vt220-keypad as an extension
<li>add shifted up/down arrow codes to xterm-new as kind/kri strings
<li>add hpterm-color terminfo entry
<li>add 256color variants of terminfo entries for programs which are reported to implement this feature
<li>correct order of use-clauses in rxvt-basic entry which made codes for f1-f4 vt100-style rather than vt220-style.
<li>added entries:
<ul>
<li><code>Eterm-256color</code>,
<code>Eterm-88color</code> and
<code>rxvt-88color</code>
<li><code>aterm</code>
<li><code>konsole-256color</code>
<li><code>mrxvt</code>
<li><code>screen.mlterm</code>
<li><code>screen.rxvt</code>
<li><code>teraterm4.59</code> is now the primary primary
teraterm entry, renamed original to
<code>teraterm2.3</code>
<li><code>9term</code> terminal
<li>Newbury Data entries
</ul>
<li>updated/improved entries:
<ul>
<li><code>gnome</code> to version 2.22.3
<li><code>h19</code>, <code>z100</code>
<li><code>konsole</code> to version 1.6.6
<li><code>mlterm</code>, <code>mlterm+pcfkeys</code>
<li><code>xterm</code>, and building-blocks for function-keys
to <a href="http://invisible-island.net/xterm/xterm.log.html#xterm_230">xterm patch #230</a>.
</ul>
</ul>
</ul>
Major bug fixes:
<ul>
<li>correct a typo in configure <code>--with-bool</code> option for the
case where <code>--without-cxx</code> is used.
<li>add logic to tic for cancelling strings in user-defined
capabilities
(this is <em>needed</em> for
current <code>konsole</code> terminfo entry).
<li>move assignment from environment variable <code>ESCDELAY</code>
from <code>initscr()</code> down to <code>newterm()</code> so the
environment variable affects timeouts for terminals opened with
newterm() as well.
<li>modify <code>mk-1st.awk</code> so the generated makefile rules for
linking or installing shared libraries do not first remove the
library, in case it is in use, e.g., <code>libncurses.so</code> by
<code>/bin/sh</code>.
<li>modify <code>werase</code> to clear multicolumn characters that
extend into a derived window.
<li>correct check for notimeout() in wgetch().
<li>modify <code>wchgat()</code> to mark updated cells as changed so a
refresh will repaint those cells.
<li>fix a sign-extension bug in infocmp's repair_acsc() function.
<li>correct logic in <code>wadd_wch()</code> and
<code>wecho_wch()</code>, which did not guard against passing the
multi-column attribute into a call on <code>waddch()</code>, e.g.,
using data returned by <code>win_wch()</code>
<li>change winnstr() to stop at the end of the line.
<li>fix redrawing of windows other than <code>stdscr</code> using
<code>wredrawln()</code> by touching the corresponding rows in
<code>curscr</code>.
<li>make Ada95 demo_panels() example work.
<li>reduce memory leaks in repeated calls to <code>tgetent()</code> by
remembering the last <code>TERMINAL*</code> value allocated to hold
the corresponding data and freeing that if the
<code>tgetent()</code> result buffer is the same as the previous
call.
<li>fix for adding a non-spacing character at the beginning of a line.
<li>modify <code>read_termtype()</code> so the <code>term_names</code>
data is always allocated as part of the <code>str_table</code>, a
better fix for a memory leak.
<li>fill in extended-color pair to make colors work
for wide-characters using extended-colors.
<li>fix <code>wins_nwstr(),</code> which did not handle single-column
non-8bit codes.
<li>improve refresh of window on top of multi-column characters,
taking into account split characters on left/right window
boundaries.
<li>modify <code>wbkgrnd()</code> to avoid clearing the
<code>A_CHARTEXT</code> attribute bits since those record the state
of multicolumn characters.
<li>modify <code>win_wchnstr()</code> to ensure that only a base cell
is returned for each multi-column character.
<li>improve <code>SIGWINCH</code> handling by postponing its effect
during <code>newterm()</code>, etc., when allocating screens.
<li>improve <code>waddch()</code> and <code>winsch()</code> handling of
EILSEQ from <code>mbrtowc()</code> by using <code>unctrl()</code>
to display illegal bytes rather than trying to append further bytes
to make up a valid sequence.
<li>remove 970913 feature for copying subwindows as they are moved in
<code>mvwin()</code>.
<li>restore <code>curs_set()</code> state after
<code>endwin()</code>/<code>refresh()</code>
<li>add checks in <code>waddchnstr()</code> and
<code>wadd_wchnstr()</code> to stop copying when a null character
is found.
<li>modify <code>keyname()</code> to use "^X" form only if
<code>meta()</code> has been called, or if <code>keyname()</code>
is called without initializing curses, e.g., via
<code>initscr()</code> or <code>newterm()</code>.
<li>add some checks to ensure current position is within scrolling
region before scrolling on a new line.
<li>modify <code>unctrl()</code> to check codes in 128-255 range versus
<code>isprint()</code>.
If they are not printable, and locale was set, use a "M-" or "~"
sequence.
<li>add a workaround to ACS mapping to allow applications such as
test/blue.c to use the "PC ROM" characters by masking them with
A_ALTCHARSET. This worked up til 5.5, but was lost in the revision
of legacy coding.
<li>improve <code>resizeterm()</code> by moving ripped-off lines, and
repainting the soft-keys.
<li>modify form library to accept control characters such as newline
in set_field_buffer(), which is compatible with Solaris.
<li>use <code>NCURSES_MOUSE_MASK()</code> in definition of
<code>BUTTON_RELEASE()</code>, etc., to make those work properly
with the <code>--enable-ext-mouse</code> configuration
<li>correct some functions in Ada95 binding which were using return
value from C where none was returned.
<li>reviewed/fixed issues reported by Coverity and Klocwork tools.
</ul>
Portability:
@ -257,110 +242,115 @@ Portability:
<li>new options:
<dl>
<dt>--with-hashed-db
<dd>Use Berkeley hashed database for storing terminfo data rather than storing
each compiled entry in a separate binary file within a directory
tree.
<dt>--disable-big-strings
<dd>control whether static string tables are generated as single
large strings (to improve startup performance), or as array
of individual strings.
<dt>--without-dlsym
<dd>Do not use <code>dlsym()</code> to load GPM dynamically.
<dt>--disable-relink
<dd>control whether shared libraries are relinked (during install)
when rpath is enabled.
<dt>--with-valgrind
<dd>Simplify building for testing with valgrind.
<dt>--disable-tic-depends
<dd>make explicit whether tic library depends on ncurses/ncursesw
library.
<dt>--enable-wgetch-events
<dd>Compile with experimental wgetch-events code.
<dt>--enable-mixed-case
<dd>override the configure script's check if the filesystem
supports mixed-case filenames.
This allows one to control how the terminal database
maps to the filesystem.
For filesystems that do not support mixed-case, the library
uses generate 2-character (hexadecimal) codes for the
lower-level of the filesystem terminfo database
<dt>--enable-signed-char
<dd>Store booleans in "signed char" rather than "char".
<dt>--enable-reentrant
<dd>builds a different flavor of the ncurses library (ncursest)
which improves reentrant use of the
library by reducing global and static variables
(see the "--with-pthread" option for the threaded support).
<dt>--enable-weak-symbols
<dd>use weak-symbols for linking to the POSIX thread library,
and use the same soname for the ncurses shared library
as the normal library (caveat: the ABI is for the threaded
library, which makes global data accessed via functions).
<dt>--with-pthread
<dd>build with the POSIX thread library (tested with AIX,
Linux, FreeBSD, OpenBSD, HPUX, IRIX64, Solaris, Tru64).
<dt>--with-ticlib
<dd>build/install the tic-support functions in a separate library
</dl>
<li>improved options:
<dl>
<dt>--disable-largefile
<dd>make the option work both ways.
<dt>--enable-ext-colors
<dd>requires the wide-character configuration.
<dt>--with-gpm
<dd>The option now accepts a parameter,
i.e., the name of the dynamic GPM library to load via
<code>dlopen()</code>
<dt>--with-chtype
<dd>ignore option value "unsigned" is always added to
the type in curses.h; do the same for --with-mmask-t.
<dt>--disable-symlinks
<dd>The option now allows one to
disable <code>symlink()</code> in <code>tic</code> even when
<code>link()</code> does not work.
<dt>--with-dmalloc
<dd>build-fix for redefinition of <code>strndup</code>.
<dt>--with-hashed-db
<dd>accepts a parameter which is the install-prefix of a given
Berkeley Database.
<dt>--with-hashed-db
<dd>the $LIBS environment variable overrides the search for the db
library.
<dt>--without-hashed-db
<dd>assumed when "--disable-database" is used.
</dl>
</ul>
<li>other configure/build issues: <ul> <li>remove special case for
Darwin in <code>CF_XOPEN_SOURCE</code> configure macro.
<li>add configure check to ensure that <code>SIGWINCH</code> is
defined on platforms such as OS X which exclude that when
<code>_XOPEN_SOURCE,</code> etc., are defined
<li>use ld's <code>-search_paths_first</code> option on Darwin
to work around odd search rules on that platform.
<li>improve ifdef's for <code>_POSIX_VDISABLE</code> in tset to
work with Mac OS X.
<li>modify configure script to ensure that if the C compiler is
used rather than the loader in making shared libraries, the
<code>$(CFLAGS)</code> variable is also used.
<li>use <code>${CC}</code> rather than <code>${LD}</code> in
shared library rules for IRIX64, Solaris to help ensure
that initialization sections are provided for extra linkage
requirements, e.g., of C++ applications.
<li>improve some shared-library configure scripting for Linux,
FreeBSD and NetBSD to make
<code>--with-shlib-version</code> work.
<li>split up dependency of <code>names.c</code> and
<code>codes.c</code> in <code>ncurses/Makefile</code> to
work with parallel make.
<li>modify <code>MKlib_gen.sh</code> to change
preprocessor-expanded <code>_Bool</code> back to <code>bool</code>.
<li>modify <code>progs/Makefile.in</code> to make
<code>tput&nbsp;init</code> work properly with cygwin,
i.e., do not pass a <code>.exe</code> in the reference
string used in check_aliases.
<li>other configure/build issues:
<ul>
<li>build-fixes for LynxOS
<li>modify shared-library rules to allow FreeBSD 3.x to use rpath.
<li>build-fix for FreeBSD "contemporary" TTY interface.
<li>build-fixes for AIX with libtool.
<li>build-fixes for Darwin and libtool.
<li>modify BeOS-specific ifdef's to build on Haiku.
<li>corrected gcc options for building shared libraries on Solaris
and IRIX64.
<li>change shared-library configuration for OpenBSD, make rpath work.
<li>build-fixes for using libutf8, e.g., on OpenBSD 3.7
<li>add "-e" option in ncurses/Makefile.in when generating source-files
to force earlier exit if the build environment fails unexpectedly.
<li>add support for shared libraries for QNX.
<li>change delimiter in <code>MKlib_gen.sh</code> from '%' to '@', to
avoid substitution by IBM xlc to '#' as part of its extensions to
digraphs.
</ul>
<li>library:
<ul>
<li>ignore wide-acs line-drawing characters that
<code>wcwidth()</code> claims are not one-column. This is
a workaround for Solaris' broken locale support.
<li>reduce name-pollution in <code>term.h</code> by removing
<code>#define</code>'s for HAVE_xxx symbols.
<li>fix <code>#ifdef</code> in <code>c++/internal.h</code> for
QNX 6.1
<li>rewrite wrapper for <code>wcrtomb()</code>, making it work on
Solaris. This is used in the form library to determine the length
of the buffer needed by <code>field_buffer</code>.
<li>add/use configure script macro CF_SIG_ATOMIC_T, use the corresponding
type for data manipulated by signal handlers.
<li>set locale in misc/ncurses-config.in since it uses a range
<li>disable GPM mouse support when $TERM does not happen to contain
"linux", since Gpm_Open() no longer limits its assertion to terminals
that it might handle, e.g., within "screen" in xterm.
<li>reset mouse file-descriptor when unloading GPM library.
</ul>
<li>test programs: <ul> <li>modify <code>test/configure</code> script
to allow building test programs with PDCurses/X11.
<li>modified test programs to allow some to work with NetBSD
curses. Several do not because NetBSD curses implements a
subset of X/Open curses, and also lacks much of SVr4
additions. But it is enough for comparison.
<li>improved <code>test/configure</code> to build test/ncurses
on HPUX 11 using the vendor curses.
<li>change configure script to produce
<code>test/Makefile</code> from data file.
<li>test programs:
<ul>
<li>update test programs to build/work with various UNIX curses for
comparisons.
</ul>
</ul>
@ -410,6 +400,8 @@ and <CODE>define_key()</CODE> allow
you to better control the use of function keys,
e.g., disabling the ncurses KEY_MOUSE,
or by defining more than one control sequence to map to a given key code.
<LI>Support for 256-color terminals, such as modern xterm, when configured
using the <code>--enable-ext-colors</code> option.
<LI>Support for 16-color terminals, such as aixterm and modern xterm.
<LI>Better cursor-movement optimization. The package now features a
cursor-local-movement computation more efficient than either BSD's
@ -513,14 +505,10 @@ for similar applications on GNU/Linux.
<br>
<DT> pinfo
<DD> Lynx-like info browser.
<A HREF="http://dione.ids.pl/~pborys/software/pinfo/">http://dione.ids.pl/~pborys/software/pinfo/</A>
<A HREF="https://alioth.debian.org/projects/pinfo/">https://alioth.debian.org/projects/pinfo/</A>
<DT> tin
<DD> newsreader, supporting color, MIME
<A HREF="http://www.tin.org/">http://www.tin.org/</A>
<DT> vh-1.6
<DD> Volks-Hypertext browser for the Jargon File
<br>
<A HREF="http://www.debian.org/Packages/unstable/text/vh.html">http://www.debian.org/Packages/unstable/text/vh.html</A>
</DL>
as well as some that use ncurses for the terminfo support alone:
<DL>

View file

@ -4,7 +4,7 @@
# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
# Free Software Foundation, Inc.
timestamp='2008-03-12'
timestamp='2008-04-14'
# This file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
@ -180,7 +180,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
fi
;;
*)
os=netbsd
os=netbsd
;;
esac
# The OS release
@ -219,11 +219,11 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
exit ;;
alpha:OSF1:*:*)
case $UNAME_RELEASE in
*4.0)
*4.0)
UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
;;
*5.*)
UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'`
*5.*)
UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'`
;;
esac
# According to Compaq, /usr/sbin/psrinfo has been available on
@ -295,7 +295,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
echo s390-ibm-zvmoe
exit ;;
*:OS400:*:*)
echo powerpc-ibm-os400
echo powerpc-ibm-os400
exit ;;
arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
echo arm-acorn-riscix${UNAME_RELEASE}
@ -375,23 +375,23 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
# MiNT. But MiNT is downward compatible to TOS, so this should
# be no problem.
atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*)
echo m68k-atari-mint${UNAME_RELEASE}
echo m68k-atari-mint${UNAME_RELEASE}
exit ;;
atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*)
echo m68k-atari-mint${UNAME_RELEASE}
exit ;;
exit ;;
*falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*)
echo m68k-atari-mint${UNAME_RELEASE}
echo m68k-atari-mint${UNAME_RELEASE}
exit ;;
milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*)
echo m68k-milan-mint${UNAME_RELEASE}
exit ;;
echo m68k-milan-mint${UNAME_RELEASE}
exit ;;
hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*)
echo m68k-hades-mint${UNAME_RELEASE}
exit ;;
echo m68k-hades-mint${UNAME_RELEASE}
exit ;;
*:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*)
echo m68k-unknown-mint${UNAME_RELEASE}
exit ;;
echo m68k-unknown-mint${UNAME_RELEASE}
exit ;;
m68k:machten:*:*)
echo m68k-apple-machten${UNAME_RELEASE}
exit ;;
@ -461,8 +461,8 @@ EOF
echo m88k-motorola-sysv3
exit ;;
AViiON:dgux:*:*)
# DG/UX returns AViiON for all architectures
UNAME_PROCESSOR=`/usr/bin/uname -p`
# DG/UX returns AViiON for all architectures
UNAME_PROCESSOR=`/usr/bin/uname -p`
if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ]
then
if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \
@ -575,8 +575,8 @@ EOF
9000/[678][0-9][0-9])
if [ -x /usr/bin/getconf ]; then
sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null`
sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
case "${sc_cpu_version}" in
sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
case "${sc_cpu_version}" in
523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0
528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1
532) # CPU_PA_RISC2_0
@ -711,22 +711,22 @@ EOF
exit ;;
C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
echo c1-convex-bsd
exit ;;
exit ;;
C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*)
if getsysinfo -f scalar_acc
then echo c32-convex-bsd
else echo c2-convex-bsd
fi
exit ;;
exit ;;
C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*)
echo c34-convex-bsd
exit ;;
exit ;;
C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*)
echo c38-convex-bsd
exit ;;
exit ;;
C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)
echo c4-convex-bsd
exit ;;
exit ;;
CRAY*Y-MP:*:*:*)
echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
exit ;;
@ -750,14 +750,14 @@ EOF
exit ;;
F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*)
FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
exit ;;
FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
exit ;;
5000:UNIX_System_V:4.*:*)
FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'`
echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'`
echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
exit ;;
i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*)
echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}
@ -785,14 +785,14 @@ EOF
echo ${UNAME_MACHINE}-pc-mingw32
exit ;;
i*:windows32*:*)
# uname -m includes "-pc" on this system.
echo ${UNAME_MACHINE}-mingw32
# uname -m includes "-pc" on this system.
echo ${UNAME_MACHINE}-mingw32
exit ;;
i*:PW*:*)
echo ${UNAME_MACHINE}-pc-pw32
exit ;;
*:Interix*:[3456]*)
case ${UNAME_MACHINE} in
case ${UNAME_MACHINE} in
x86)
echo i586-pc-interix${UNAME_RELEASE}
exit ;;
@ -800,8 +800,8 @@ EOF
echo x86_64-unknown-interix${UNAME_RELEASE}
exit ;;
IA64)
echo ia64-unknown-interix${UNAME_RELEASE}
exit ;;
echo ia64-unknown-interix${UNAME_RELEASE}
exit ;;
esac ;;
[345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*)
echo i${UNAME_MACHINE}-pc-mks
@ -837,7 +837,8 @@ EOF
exit ;;
arm*:Linux:*:*)
eval $set_cc_for_build
if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null | grep -q __ARM_EABI__
if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \
| grep -q __ARM_EABI__
then
echo ${UNAME_MACHINE}-unknown-linux-gnu
else
@ -854,7 +855,7 @@ EOF
echo crisv32-axis-linux-gnu
exit ;;
frv:Linux:*:*)
echo frv-unknown-linux-gnu
echo frv-unknown-linux-gnu
exit ;;
ia64:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-gnu
@ -882,10 +883,10 @@ EOF
#endif
EOF
eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n '
/^CPU/{
s: ::g
p
}'`"
/^CPU/{
s: ::g
p
}'`"
test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; }
;;
mips64:Linux:*:*)
@ -905,15 +906,15 @@ EOF
#endif
EOF
eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n '
/^CPU/{
s: ::g
p
}'`"
/^CPU/{
s: ::g
p
}'`"
test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; }
;;
or32:Linux:*:*)
echo or32-unknown-linux-gnu
exit ;;
echo or32-unknown-linux-gnu
exit ;;
ppc:Linux:*:*)
echo powerpc-unknown-linux-gnu
exit ;;
@ -929,7 +930,7 @@ EOF
EV6) UNAME_MACHINE=alphaev6 ;;
EV67) UNAME_MACHINE=alphaev67 ;;
EV68*) UNAME_MACHINE=alphaev68 ;;
esac
esac
objdump --private-headers /bin/sh | grep ld.so.1 >/dev/null
if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi
echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC}
@ -949,7 +950,7 @@ EOF
echo ${UNAME_MACHINE}-ibm-linux
exit ;;
sh64*:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-gnu
echo ${UNAME_MACHINE}-unknown-linux-gnu
exit ;;
sh*:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-gnu
@ -964,7 +965,7 @@ EOF
echo x86_64-unknown-linux-gnu
exit ;;
xtensa*:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-gnu
echo ${UNAME_MACHINE}-unknown-linux-gnu
exit ;;
i*86:Linux:*:*)
# The BFD linker knows what the default object file format is, so
@ -977,16 +978,13 @@ EOF
s/.*supported targets: *//
s/ .*//
p'`
case "$ld_supported_targets" in
case "$ld_supported_targets" in
elf32-i386)
TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu"
;;
a.out-i386-linux)
echo "${UNAME_MACHINE}-pc-linux-gnuaout"
exit ;;
coff-i386)
echo "${UNAME_MACHINE}-pc-linux-gnucoff"
exit ;;
"")
# Either a pre-BFD a.out linker (linux-gnuoldld) or
# one that does not give us useful --help.
@ -1019,10 +1017,10 @@ EOF
#endif
EOF
eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n '
/^LIBC/{
s: ::g
p
}'`"
/^LIBC/{
s: ::g
p
}'`"
test x"${LIBC}" != x && {
echo "${UNAME_MACHINE}-pc-linux-${LIBC}"
exit
@ -1036,11 +1034,11 @@ EOF
echo i386-sequent-sysv4
exit ;;
i*86:UNIX_SV:4.2MP:2.*)
# Unixware is an offshoot of SVR4, but it has its own version
# number series starting with 2...
# I am not positive that other SVR4 systems won't match this,
# Unixware is an offshoot of SVR4, but it has its own version
# number series starting with 2...
# I am not positive that other SVR4 systems won't match this,
# I just have to hope. -- rms.
# Use sysv4.2uw... so that sysv4* matches it.
# Use sysv4.2uw... so that sysv4* matches it.
echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION}
exit ;;
i*86:OS/2:*:*)
@ -1072,7 +1070,7 @@ EOF
fi
exit ;;
i*86:*:5:[678]*)
# UnixWare 7.x, OpenUNIX and OpenServer 6.
# UnixWare 7.x, OpenUNIX and OpenServer 6.
case `/bin/uname -X | grep "^Machine"` in
*486*) UNAME_MACHINE=i486 ;;
*Pentium) UNAME_MACHINE=i586 ;;
@ -1100,10 +1098,10 @@ EOF
exit ;;
pc:*:*:*)
# Left here for compatibility:
# uname -m prints for DJGPP always 'pc', but it prints nothing about
# the processor, so we play safe by assuming i386.
# uname -m prints for DJGPP always 'pc', but it prints nothing about
# the processor, so we play safe by assuming i386.
echo i386-pc-msdosdjgpp
exit ;;
exit ;;
Intel:Mach:3*:*)
echo i386-pc-mach3
exit ;;
@ -1138,8 +1136,8 @@ EOF
/bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
&& { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;;
3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
/bin/uname -p 2>/dev/null | grep 86 >/dev/null \
&& { echo i486-ncr-sysv4; exit; } ;;
/bin/uname -p 2>/dev/null | grep 86 >/dev/null \
&& { echo i486-ncr-sysv4; exit; } ;;
m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*)
echo m68k-unknown-lynxos${UNAME_RELEASE}
exit ;;
@ -1173,9 +1171,9 @@ EOF
fi
exit ;;
PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
# says <Richard.M.Bartel@ccMail.Census.GOV>
echo i586-unisys-sysv4
exit ;;
# says <Richard.M.Bartel@ccMail.Census.GOV>
echo i586-unisys-sysv4
exit ;;
*:UNIX_System_V:4*:FTX*)
# From Gerald Hewes <hewes@openmarket.com>.
# How about differentiating between stratus architectures? -djm
@ -1205,7 +1203,7 @@ EOF
else
echo mips-unknown-sysv${UNAME_RELEASE}
fi
exit ;;
exit ;;
BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only.
echo powerpc-be-beos
exit ;;
@ -1252,8 +1250,8 @@ EOF
*:procnto*:*:* | *:QNX:[0123456789]*:*)
UNAME_PROCESSOR=`uname -p`
if test "$UNAME_PROCESSOR" = "x86"; then
UNAME_PROCESSOR=i386
UNAME_MACHINE=pc
UNAME_PROCESSOR=i386
UNAME_MACHINE=pc
fi
echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE}
exit ;;
@ -1305,13 +1303,13 @@ EOF
echo pdp10-unknown-its
exit ;;
SEI:*:*:SEIUX)
echo mips-sei-seiux${UNAME_RELEASE}
echo mips-sei-seiux${UNAME_RELEASE}
exit ;;
*:DragonFly:*:*)
echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
exit ;;
*:*VMS:*:*)
UNAME_MACHINE=`(uname -p) 2>/dev/null`
UNAME_MACHINE=`(uname -p) 2>/dev/null`
case "${UNAME_MACHINE}" in
A*) echo alpha-dec-vms ; exit ;;
I*) echo ia64-dec-vms ; exit ;;
@ -1486,9 +1484,9 @@ This script, last modified $timestamp, has failed to recognize
the operating system you are using. It is advised that you
download the most up to date version of the config scripts from
http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess
http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD
and
http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub
http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD
If the version you run ($0) is already up to date, please
send the following data and any information you think might be

View file

@ -4,7 +4,7 @@
# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
# Free Software Foundation, Inc.
timestamp='2008-03-08'
timestamp='2008-06-16'
# This file is (in principle) common to ALL GNU software.
# The presence of a machine in this file suggests that SOME GNU software
@ -250,7 +250,7 @@ case $basic_machine in
| i370 | i860 | i960 | ia64 \
| ip2k | iq2000 \
| m32c | m32r | m32rle | m68000 | m68k | m88k \
| maxq | mb | microblaze | mcore | mep \
| maxq | mb | microblaze | mcore | mep | metag \
| mips | mipsbe | mipseb | mipsel | mipsle \
| mips16 \
| mips64 | mips64el \
@ -306,8 +306,8 @@ case $basic_machine in
# because (1) that's what they normally are, and
# (2) the word "unknown" tends to confuse beginning users.
i*86 | x86_64)
basic_machine=$basic_machine-pc
;;
basic_machine=$basic_machine-pc
;;
# Object if more than one company name word.
*-*-*)
echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
@ -331,9 +331,9 @@ case $basic_machine in
| hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
| i*86-* | i860-* | i960-* | ia64-* \
| ip2k-* | iq2000-* \
| m32c- | m32r-* | m32rle-* \
| m32c-* | m32r-* | m32rle-* \
| m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
| m88110-* | m88k-* | maxq-* | mcore-* \
| m88110-* | m88k-* | maxq-* | mcore-* | metag-* \
| mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
| mips16-* \
| mips64-* | mips64el-* \
@ -397,7 +397,7 @@ case $basic_machine in
basic_machine=a29k-amd
os=-udi
;;
abacus)
abacus)
basic_machine=abacus-unknown
;;
adobe68k)
@ -463,6 +463,10 @@ case $basic_machine in
basic_machine=c90-cray
os=-unicos
;;
cegcc)
basic_machine=arm-unknown
os=-cegcc
;;
convex-c1)
basic_machine=c1-convex
os=-bsd
@ -530,6 +534,10 @@ case $basic_machine in
basic_machine=m88k-motorola
os=-sysv3
;;
dicos)
basic_machine=i686-pc
os=-dicos
;;
djgpp)
basic_machine=i586-pc
os=-msdosdjgpp
@ -1217,8 +1225,8 @@ esac
if [ x"$os" != x"" ]
then
case $os in
# First match some system type aliases
# that might get confused with valid system types.
# First match some system type aliases
# that might get confused with valid system types.
# -solaris* is a basic system type, with this one exception.
-solaris1 | -solaris1.*)
os=`echo $os | sed -e 's|solaris1|sunos4|'`
@ -1252,7 +1260,7 @@ case $os in
| -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
| -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
| -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
| -chorusos* | -chorusrdb* \
| -chorusos* | -chorusrdb* | -cegcc* \
| -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
| -mingw32* | -linux-gnu* | -linux-newlib* | -linux-uclibc* \
| -uxpv* | -beos* | -mpeix* | -udk* \
@ -1301,7 +1309,7 @@ case $os in
-opened*)
os=-openedition
;;
-os400*)
-os400*)
os=-os400
;;
-wince*)
@ -1350,7 +1358,7 @@ case $os in
-sinix*)
os=-sysv4
;;
-tpf*)
-tpf*)
os=-tpf
;;
-triton*)
@ -1392,6 +1400,9 @@ case $os in
-zvmoe)
os=-zvmoe
;;
-dicos*)
os=-dicos
;;
-none)
;;
*)
@ -1414,10 +1425,10 @@ else
# system, and we'll never get to this point.
case $basic_machine in
score-*)
score-*)
os=-elf
;;
spu-*)
spu-*)
os=-elf
;;
*-acorn)
@ -1429,8 +1440,8 @@ case $basic_machine in
arm*-semi)
os=-aout
;;
c4x-* | tic4x-*)
os=-coff
c4x-* | tic4x-*)
os=-coff
;;
# This must come before the *-dec entry.
pdp10-*)
@ -1457,7 +1468,7 @@ case $basic_machine in
m68*-cisco)
os=-aout
;;
mep-*)
mep-*)
os=-elf
;;
mips*-cisco)
@ -1484,7 +1495,7 @@ case $basic_machine in
*-ibm)
os=-aix
;;
*-knuth)
*-knuth)
os=-mmixware
;;
*-wec)

File diff suppressed because it is too large Load diff

View file

@ -1,5 +1,5 @@
dnl***************************************************************************
dnl Copyright (c) 1998-2006,2007 Free Software Foundation, Inc. *
dnl Copyright (c) 1998-2007,2008 Free Software Foundation, Inc. *
dnl *
dnl Permission is hereby granted, free of charge, to any person obtaining a *
dnl copy of this software and associated documentation files (the *
@ -28,14 +28,14 @@ dnl***************************************************************************
dnl
dnl Author: Thomas E. Dickey 1995-on
dnl
dnl $Id: configure.in,v 1.433 2008/04/12 23:39:06 tom Exp $
dnl $Id: configure.in,v 1.454 2008/10/18 14:53:32 tom Exp $
dnl Process this file with autoconf to produce a configure script.
dnl
dnl See http://invisible-island.net/autoconf/ for additional information.
dnl
dnl ---------------------------------------------------------------------------
AC_PREREQ(2.13.20020210)
AC_REVISION($Revision: 1.433 $)
AC_REVISION($Revision: 1.454 $)
AC_INIT(ncurses/base/lib_initscr.c)
AC_CONFIG_HEADER(include/ncurses_cfg.h:include/ncurses_cfg.hin)
@ -361,12 +361,7 @@ AC_MSG_RESULT($LD_MODEL)
case $DFT_LWR_MODEL in
shared)
AC_MSG_CHECKING(if rpath option should be used)
AC_ARG_ENABLE(rpath,
[ --enable-rpath use rpath option when generating shared libraries],
[cf_cv_ld_rpath=$enableval],
[cf_cv_ld_rpath=no])
AC_MSG_RESULT($cf_cv_ld_rpath)
CF_ENABLE_RPATH
AC_MSG_CHECKING(if shared libraries should be relinked during install)
AC_ARG_ENABLE(relink,
[ --disable-relink relink shared libraries during install],
@ -428,6 +423,8 @@ if test "$use_database" != no ; then
[ --with-hashed-db specify hashed-database library],,
[with_hashed_db=no])
AC_MSG_RESULT($with_hashed_db)
else
with_hashed_db=no
fi
AC_MSG_CHECKING(for list of fallback descriptions)
@ -504,12 +501,13 @@ AC_MSG_RESULT($with_big_core)
test "$with_big_core" = "yes" && AC_DEFINE(HAVE_BIG_CORE)
### ISO C only guarantees 512-char strings, we have tables which load faster
### when constructed using "big" strings.
### when constructed using "big" strings. More than the C compiler, the awk
### program is a limit on most vendor UNIX systems. Check that we can build.
AC_MSG_CHECKING(if big-strings option selected)
AC_ARG_ENABLE(big-strings,
[ --disable-big-strings assume compiler has only standard-size strings],
[with_big_strings=no],
[with_big_strings=yes])
[with_big_strings=$enableval],
[CF_AWK_BIG_PRINTF(12000,with_big_strings)])
AC_MSG_RESULT($with_big_strings)
USE_BIG_STRINGS=0
@ -681,10 +679,10 @@ if test "$with_widec" = yes ; then
CF_PREDEFINE(_XOPEN_SOURCE_EXTENDED)
# with_overwrite=no
NCURSES_CH_T=cchar_t
AC_CHECK_FUNCS(putwc btowc wctob mbtowc wctomb mblen mbrlen mbrtowc)
AC_CHECK_FUNCS(putwc btowc wctob mbtowc wctomb mblen mbrlen mbrtowc wcsrtombs mbsrtowcs wcstombs mbstowcs)
if test "$ac_cv_func_putwc" != yes ; then
CF_LIBUTF8
if test "$cf_cv_libutf8" = yes ; then
CF_UTF8_LIB
if test "$cf_cv_utf8_lib" != no ; then
NCURSES_LIBUTF8=1
fi
fi
@ -744,6 +742,18 @@ NCURSES_TPARM_VARARGS=0
test "$with_tparm_varargs" = yes && NCURSES_TPARM_VARARGS=1
AC_SUBST(NCURSES_TPARM_VARARGS)
### use option --disable-tic-depends to make libtic not explicitly depend on ncurses/ncursesw
if test "$with_ticlib" != no ; then
AC_MSG_CHECKING(if you want tic library to use explicit dependency on ncurses$LIB_SUFFIX library)
AC_ARG_ENABLE(tic-depends,
[ --disable-tic-depends link tic library without explicit dependency on ncurses library],
[with_tic_depends=$enableval],
[with_tic_depends=yes])
AC_MSG_RESULT($with_tic_depends)
else
with_tic_depends=no
fi
### use option --with-bool to override bool's type
AC_MSG_CHECKING(for type of bool)
AC_ARG_WITH(bool,
@ -836,6 +846,40 @@ if test "$with_ext_const" = yes ; then
fi
AC_SUBST(NCURSES_CONST)
### use option --enable-ext-colors to turn on use of colors beyond 16.
AC_MSG_CHECKING(if you want to use extended colors)
AC_ARG_ENABLE(ext-colors,
[ --enable-ext-colors compile for 256-color support],
[with_ext_colors=$enableval],
[with_ext_colors=no])
AC_MSG_RESULT($with_ext_colors)
NCURSES_EXT_COLORS=0
if test "$with_ext_colors" = yes ; then
if test "$with_widec" != yes ; then
AC_MSG_ERROR(This option applies only to wide-character library)
else
# cannot be ABI 5 since it changes sizeof(cchar_t)
CF_NCURSES_ABI_6
fi
NCURSES_EXT_COLORS=1
AC_DEFINE(NCURSES_EXT_COLORS)
fi
AC_SUBST(NCURSES_EXT_COLORS)
### use option --enable-ext-mouse to modify coding to support 5-button mice
AC_MSG_CHECKING(if you want to use extended mouse encoding)
AC_ARG_ENABLE(ext-mouse,
[ --enable-ext-mouse compile for extended mouse-encoding],
[with_ext_mouse=$enableval],
[with_ext_mouse=no])
AC_MSG_RESULT($with_ext_mouse)
NCURSES_MOUSE_VERSION=1
if test "$with_ext_mouse" = yes ; then
NCURSES_MOUSE_VERSION=2
CF_NCURSES_ABI_6
fi
AC_SUBST(NCURSES_MOUSE_VERSION)
AC_MSG_CHECKING(if you want \$NCURSES_NO_PADDING code)
AC_ARG_ENABLE(no-padding,
[ --enable-no-padding compile with $NCURSES_NO_PADDING code],
@ -935,47 +979,35 @@ AC_ARG_ENABLE(colorfgbg,
AC_MSG_RESULT($with_colorfgbg)
test "$with_colorfgbg" = yes && AC_DEFINE(USE_COLORFGBG)
### use option --enable-ext-colors to turn on use of colors beyond 16.
AC_MSG_CHECKING(if you want to use experimental extended colors)
AC_ARG_ENABLE(ext-colors,
[ --enable-ext-colors compile for experimental 256-color support],
[with_ext_colors=$enableval],
[with_ext_colors=no])
AC_MSG_RESULT($with_ext_colors)
NCURSES_EXT_COLORS=0
if test "$with_ext_colors" = yes ; then
if test "$with_widec" != yes ; then
AC_MSG_ERROR(This option applies only to wide-character library)
else
# cannot be ABI 5 since it changes sizeof(cchar_t)
CF_NCURSES_ABI_6
fi
NCURSES_EXT_COLORS=1
AC_DEFINE(NCURSES_EXT_COLORS)
fi
AC_SUBST(NCURSES_EXT_COLORS)
### use option --enable-ext-mouse to modify coding to support 5-button mice
AC_MSG_CHECKING(if you want to use experimental extended mouse encoding)
AC_ARG_ENABLE(ext-mouse,
[ --enable-ext-mouse compile for experimental mouse-encoding],
[with_ext_mouse=$enableval],
[with_ext_mouse=no])
AC_MSG_RESULT($with_ext_mouse)
NCURSES_MOUSE_VERSION=1
if test "$with_ext_mouse" = yes ; then
NCURSES_MOUSE_VERSION=2
CF_NCURSES_ABI_6
fi
AC_SUBST(NCURSES_MOUSE_VERSION)
# This is still experimental (20080329), but should ultimately be moved to
# the script-block --with-normal, etc.
CF_WITH_PTHREAD
AC_MSG_CHECKING(if you want to use weak-symbols for pthreads)
AC_ARG_ENABLE(weak-symbols,
[ --enable-weak-symbols enable weak-symbols for pthreads],
[use_weak_symbols=$withval],
[use_weak_symbols=no])
AC_MSG_RESULT($use_weak_symbols)
if test "$use_weak_symbols" = yes ; then
CF_WEAK_SYMBOLS
else
cf_cv_weak_symbols=no
fi
if test $cf_cv_weak_symbols = yes ; then
AC_DEFINE(USE_WEAK_SYMBOLS)
fi
PTHREAD=
if test "$with_pthread" = "yes" ; then
AC_DEFINE(USE_PTHREADS)
enable_reentrant=yes
if test $cf_cv_weak_symbols = yes ; then
PTHREAD=-lpthread
fi
fi
AC_SUBST(PTHREAD)
# Reentrant code has to be opaque; there's little advantage to making ncurses
# opaque outside of that, so there is no --enable-opaque option. We can use
@ -992,7 +1024,11 @@ if test "$with_reentrant" = yes ; then
cf_cv_enable_opaque="NCURSES_INTERNALS"
NCURSES_OPAQUE=1
NCURSES_SIZE_T=int
LIB_SUFFIX="t${LIB_SUFFIX}"
if test $cf_cv_weak_symbols = yes ; then
CF_REMOVE_LIB(LIBS,$LIBS,pthread)
else
LIB_SUFFIX="t${LIB_SUFFIX}"
fi
AC_DEFINE(USE_REENTRANT)
CF_NCURSES_ABI_6
else
@ -1297,6 +1333,20 @@ if test -n "$CXX" ; then
AC_CHECK_HEADERS(iostream typeinfo)
if test x"$ac_cv_header_iostream" = xyes ; then
AC_MSG_CHECKING(if iostream uses std-namespace)
AC_TRY_COMPILE([
#include <iostream>
using std::endl;
using std::cerr;],[
cerr << "testing" << endl;
],[cf_iostream_namespace=yes],[cf_iostream_namespace=no])
AC_MSG_RESULT($cf_iostream_namespace)
if test "$cf_iostream_namespace" = yes ; then
AC_DEFINE(IOSTREAM_NAMESPACE)
fi
fi
CF_BOOL_DECL
CF_BOOL_SIZE
CF_ETIP_DEFINES
@ -1527,16 +1577,7 @@ AC_SUBST(DFT_ARG_SUFFIX)dnl the string to append to "-lncurses" ("")
AC_MSG_RESULT($DFT_ARG_SUFFIX)
AC_MSG_CHECKING(default library-dependency suffix)
CF_LIB_SUFFIX($DFT_LWR_MODEL,DFT_DEP_SUFFIX)dnl
DFT_LIB_SUFFIX=$DFT_DEP_SUFFIX
if test $DFT_LWR_MODEL = shared ; then
case $cf_cv_system_name in #(vi
cygwin*)
DFT_DEP_SUFFIX=".dll.a"
DFT_LIB_SUFFIX=".dll"
;;
esac
fi
CF_LIB_SUFFIX($DFT_LWR_MODEL,DFT_LIB_SUFFIX,DFT_DEP_SUFFIX)dnl
AC_SUBST(DFT_DEP_SUFFIX)dnl the corresponding library-suffix (".a")
AC_MSG_RESULT($DFT_DEP_SUFFIX)
@ -1551,7 +1592,7 @@ AC_MSG_CHECKING(c++ library-dependency suffix)
if test "$with_libtool" != "no"; then
CXX_LIB_SUFFIX=$DFT_DEP_SUFFIX
else
CF_LIB_SUFFIX(normal,CXX_LIB_SUFFIX)dnl we normally make a static library
CF_LIB_SUFFIX(normal,CXX_LIB_SUFFIX,CXX_DEP_SUFFIX)dnl we normally make a static library
fi
AC_MSG_RESULT($CXX_LIB_SUFFIX)
AC_SUBST(CXX_LIB_SUFFIX)
@ -1627,7 +1668,11 @@ else
TINFO_NAME=${LIB_NAME}
TINFO_SUFFIX=${DFT_LIB_SUFFIX}
TINFO_ARG_SUFFIX=${LIB_NAME}${DFT_ARG_SUFFIX}
TICS_LIST="$SHLIB_LIST -l${LIB_NAME}${DFT_ARG_SUFFIX}"
if test "$with_tic_depends" = yes ; then
TICS_LIST="$SHLIB_LIST -l${LIB_NAME}${DFT_ARG_SUFFIX}"
else
TICS_LIST="$SHLIB_LIST"
fi
TINFO_ARGS="-L${LIB_DIR} -l${LIB_NAME}${DFT_ARG_SUFFIX}"
fi
@ -1771,6 +1816,7 @@ cf_cv_prog_CC_c_o=$cf_cv_prog_CC_c_o
cf_cv_prog_CXX_c_o=$cf_cv_prog_CXX_c_o
cf_cv_rel_version="$cf_cv_rel_version"
cf_cv_rm_so_locs="$cf_cv_rm_so_locs"
cf_cv_shared_soname='$cf_cv_shared_soname'
cf_cv_shlib_version="$cf_cv_shlib_version"
cf_cv_shlib_version_infix="$cf_cv_shlib_version_infix"
cf_cv_system_name="$cf_cv_system_name"

View file

@ -25,7 +25,7 @@
# use or other dealings in this Software without prior written #
# authorization. #
##############################################################################
# $Id: dist.mk,v 1.641 2008/05/03 12:31:08 tom Exp $
# $Id: dist.mk,v 1.671 2008/11/02 00:58:38 tom Exp $
# Makefile for creating ncurses distributions.
#
# This only needs to be used directly as a makefile by developers, but
@ -36,8 +36,8 @@ SHELL = /bin/sh
# These define the major/minor/patch versions of ncurses.
NCURSES_MAJOR = 5
NCURSES_MINOR = 6
NCURSES_PATCH = 20080503
NCURSES_MINOR = 7
NCURSES_PATCH = 20081102
# We don't append the patch to the version, since this only applies to releases
VERSION = $(NCURSES_MAJOR).$(NCURSES_MINOR)
@ -91,6 +91,11 @@ doc/hackguide.doc: doc/html/hackguide.html
#
# The distributed html files are formatted using
# configure --without-manpage-renames
#
# The edit_man.sed script is built as a side-effect of installing the manpages.
# If that conflicts with the --without-manpage-renames, you can install those
# in a different location using the --with-install-prefix option of the
# configure script.
MANPROG = tbl | nroff -mandoc -rLL=65n -rLT=71n -Tascii
manhtml:

View file

@ -1,8 +1,8 @@
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 3.0//EN">
<!--
$Id: announce.html,v 1.51 2006/12/17 23:32:42 tom Exp $
$Id: announce.html,v 1.52 2008/11/02 01:05:08 tom Exp $
****************************************************************************
* Copyright (c) 1998-2005,2006 Free Software Foundation, Inc. *
* Copyright (c) 1998-2006,2008 Free Software Foundation, Inc. *
* *
* Permission is hereby granted, free of charge, to any person obtaining a *
* copy of this software and associated documentation files (the *
@ -31,13 +31,13 @@
-->
<HTML>
<HEAD>
<TITLE>Announcing ncurses 5.6</TITLE>
<TITLE>Announcing ncurses 5.7</TITLE>
<link rev=made href="mailto:bug-ncurses@gnu.org">
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
</HEAD>
<BODY>
<H1>Announcing ncurses 5.6</H1>
<H1>Announcing ncurses 5.7</H1>
The ncurses (new curses) library is a free software emulation of
curses in System V Release 4.0, and more. It uses terminfo format,
@ -69,185 +69,170 @@ the GNU distribution site
<H1>Release Notes</H1>
This release is designed to be upward compatible from ncurses 5.0 through 5.5;
This release is designed to be upward compatible from ncurses 5.0 through 5.6;
very few applications will require recompilation, depending on the platform.
These are the highlights from the change-log since ncurses 5.5 release.
These are the highlights from the change-log since ncurses 5.6 release.
<p>
Interface changes:
<ul>
<li>generate linkable stubs for some macros:
<br>
getbegx, getbegy, getcurx, getcury, getmaxx, getmaxy, getparx,
getpary, getpary,
<br>
and (for libncursesw)
<br>
wgetbkgrnd
getattrs
</ul>
New features and improvements:
<ul>
<li>library
<ul>
<li>support hashed databases for the terminal descriptions.
This uses the Berkeley database, has been tested for
several versions on different platforms.
<li>new flavor of the ncurses library provides rudimentary
support for POSIX threads. Several functions are
reentrant, but most require either a window-level or
screen-level mutex.<br>
(This is <em>API</em>-compatible,
but not <em>ABI</em>-compatible with the normal library).
<li>add <code>use_legacy_coding()</code> function to support
lynx's font-switching feature.
<li>add <code>NCURSES_OPAQUE</code> symbol to curses.h, will
use to make structs opaque in selected configurations.
<li>add extension <code>nofilter()</code>, to cancel a prior
<code>filter()</code> call.
<li>add <code>NCURSES_EXT_FUNCS</code> and
<code>NCURSES_EXT_COLORS</code> symbols to curses.h to make
it simpler to tell if the extended functions and/or colors
are declared.
<li>add/install a package config script, e.g.,
<code>ncurses5-config</code> or
<code>ncursesw5-config</code>, according to
configuration options.
<li>add wresize() to C++ binding
<li>provide ifdef for <code>NCURSES_NOMACROS</code> which
suppresses most macro definitions from curses.h, i.e.,
where a macro is defined to override a function to improve
performance.
<li>eliminate fixed-buffer vsprintf() calls in C++ binding.
<li>make ifdef's consistent in <code>curses.h</code> for the
extended colors so the header file can be used for the
normal curses library. The header file installed for
extended colors is a variation of the wide-character
configuration.
<li>add several functions to C++ binding which wrap C functions
that pass a WINDOW* parameter.
<li>improve <code>tgetstr()</code> by making the return value
point into the user's buffer, if provided.
<li>adapt mouse-handling code from menu library in form-library
<li>add ifdef's allowing ncurses to be built with
<code>tparm()</code> using either varargs (the existing
status), or using a fixed-parameter list (to match X/Open).
<li>improve tracing for form library, showing created forms,
fields, etc.
<li>widen the test for xterm <code>kmous</code> a little to
<code>allow</code> for other
strings than "\E[M", e.g., for <code>xterm-sco</code>
functionality in xterm.
<li>make $NCURSES_NO_PADDING feature work for termcap interface .
<li>modify <code>wgetnstr()</code> to return
<code>KEY_RESIZE</code> if a sigwinch occurs.
<li>add check to trace-file open, if the given name is a
directory, add ".log" to the name and try again.
<li>move prototypes for wide-character trace functions from
curses.tail to curses.wide to avoid accidental reference to
those if <code>_XOPEN_SOURCE_EXTENDED</code> is defined
without ensuring that &lt;wchar.h&gt; is included.
<li>change the way shared libraries (other than libtool) are
installed. Rather than copying the build-tree's libraries,
link the shared objects into the install directory. This
makes the <code>--with-rpath</code> option work except with
<code>$(DESTDIR)</code>.
<li>several improvements for rendering in hpterm. These are
only available if the library is configured using
<code>--enable-xmc-glitch</code>.
<li>Add <code>NCURSES_NO_HARD_TABS</code> and
<code>NCURSES_NO_MAGIC_COOKIE</code> environment variables
to allow runtime suppression of the related hard-tabs and
xmc-glitch features.
<li>several new manpages: curs_legacy.3x, curs_memleaks.3x,
curs_opaque.3x and curs_threads.3x
</ul>
<li>programs:
<ul>
<li>add new test programs: chgat.c, demo_altkeys.c,
echochar.c, foldkeys.c, movewindow.c, redraw.c, (noting
that existing test programs also were modified to test
additional features).
<li>modified three test-programs to demonstrate the threading
support in this version: ditto, rain, worm.
<li>modify tack to test extended capability function-key
strings.
<li>several new test-programs: demo_panels, dots_mvcur,
inch_wide, inchs, key_name, key_names, savescreen,
savescreen.sh test_arrays, test_get_wstr, test_getstr,
test_instr, test_inwstr and test_opaque.
<li>modify toe to access termcap data, e.g., via <code>cgetent()</code>
functions, or as a text file if those are not available.
<li>add <code>adacurses-config</code> to the Ada95 install.
<li>improve infocmp/tic <code>-f</code> option formatting.
<li>modify tic <code>-f</code> option to format spaces as
<code>\s</code> to prevent them from being lost when that
is read back in unformatted strings.
<li>add <code>toe -a</code> option, to show all databases.
This uses new private interfaces in the ncurses library for
iterating through the list of databases.
<li>modify <code>MKfallback.sh</code> to use
<code>tic&nbsp;-x</code> when constructing fallback tables to
allow extended capabilities to be retrieved from a fallback entry.
<li>The <code>tack</code> program is now distributed separately
from ncurses.
</ul>
<li>terminal database
<ul>
<li>add terminfo entries for xfce terminal (xfce) and multi gnome terminal (mgt)
<li>add nsterm-16color entry
<li>updated mlterm terminfo entry
<li>add kon, kon2 and jfbterm terminfo entry
<li>remove invis capability from klone+sgr, mainly used by linux entry, since it does not really do this
<li>add ka2, kb1, kb3, kc2 to vt220-keypad as an extension
<li>add shifted up/down arrow codes to xterm-new as kind/kri strings
<li>add hpterm-color terminfo entry
<li>add 256color variants of terminfo entries for programs which are reported to implement this feature
<li>correct order of use-clauses in rxvt-basic entry which made codes for f1-f4 vt100-style rather than vt220-style.
<li>added entries:
<ul>
<li><code>Eterm-256color</code>,
<code>Eterm-88color</code> and
<code>rxvt-88color</code>
<li><code>aterm</code>
<li><code>konsole-256color</code>
<li><code>mrxvt</code>
<li><code>screen.mlterm</code>
<li><code>screen.rxvt</code>
<li><code>teraterm4.59</code> is now the primary primary
teraterm entry, renamed original to
<code>teraterm2.3</code>
<li><code>9term</code> terminal
<li>Newbury Data entries
</ul>
<li>updated/improved entries:
<ul>
<li><code>gnome</code> to version 2.22.3
<li><code>h19</code>, <code>z100</code>
<li><code>konsole</code> to version 1.6.6
<li><code>mlterm</code>, <code>mlterm+pcfkeys</code>
<li><code>xterm</code>, and building-blocks for function-keys
to <a href="http://invisible-island.net/xterm/xterm.log.html#xterm_230">xterm patch #230</a>.
</ul>
</ul>
</ul>
Major bug fixes:
<ul>
<li>correct a typo in configure <code>--with-bool</code> option for the
case where <code>--without-cxx</code> is used.
<li>add logic to tic for cancelling strings in user-defined
capabilities
(this is <em>needed</em> for
current <code>konsole</code> terminfo entry).
<li>move assignment from environment variable <code>ESCDELAY</code>
from <code>initscr()</code> down to <code>newterm()</code> so the
environment variable affects timeouts for terminals opened with
newterm() as well.
<li>modify <code>mk-1st.awk</code> so the generated makefile rules for
linking or installing shared libraries do not first remove the
library, in case it is in use, e.g., <code>libncurses.so</code> by
<code>/bin/sh</code>.
<li>modify <code>werase</code> to clear multicolumn characters that
extend into a derived window.
<li>correct check for notimeout() in wgetch().
<li>modify <code>wchgat()</code> to mark updated cells as changed so a
refresh will repaint those cells.
<li>fix a sign-extension bug in infocmp's repair_acsc() function.
<li>correct logic in <code>wadd_wch()</code> and
<code>wecho_wch()</code>, which did not guard against passing the
multi-column attribute into a call on <code>waddch()</code>, e.g.,
using data returned by <code>win_wch()</code>
<li>change winnstr() to stop at the end of the line.
<li>fix redrawing of windows other than <code>stdscr</code> using
<code>wredrawln()</code> by touching the corresponding rows in
<code>curscr</code>.
<li>make Ada95 demo_panels() example work.
<li>reduce memory leaks in repeated calls to <code>tgetent()</code> by
remembering the last <code>TERMINAL*</code> value allocated to hold
the corresponding data and freeing that if the
<code>tgetent()</code> result buffer is the same as the previous
call.
<li>fix for adding a non-spacing character at the beginning of a line.
<li>modify <code>read_termtype()</code> so the <code>term_names</code>
data is always allocated as part of the <code>str_table</code>, a
better fix for a memory leak.
<li>fill in extended-color pair to make colors work
for wide-characters using extended-colors.
<li>fix <code>wins_nwstr(),</code> which did not handle single-column
non-8bit codes.
<li>improve refresh of window on top of multi-column characters,
taking into account split characters on left/right window
boundaries.
<li>modify <code>wbkgrnd()</code> to avoid clearing the
<code>A_CHARTEXT</code> attribute bits since those record the state
of multicolumn characters.
<li>modify <code>win_wchnstr()</code> to ensure that only a base cell
is returned for each multi-column character.
<li>improve <code>SIGWINCH</code> handling by postponing its effect
during <code>newterm()</code>, etc., when allocating screens.
<li>improve <code>waddch()</code> and <code>winsch()</code> handling of
EILSEQ from <code>mbrtowc()</code> by using <code>unctrl()</code>
to display illegal bytes rather than trying to append further bytes
to make up a valid sequence.
<li>remove 970913 feature for copying subwindows as they are moved in
<code>mvwin()</code>.
<li>restore <code>curs_set()</code> state after
<code>endwin()</code>/<code>refresh()</code>
<li>add checks in <code>waddchnstr()</code> and
<code>wadd_wchnstr()</code> to stop copying when a null character
is found.
<li>modify <code>keyname()</code> to use "^X" form only if
<code>meta()</code> has been called, or if <code>keyname()</code>
is called without initializing curses, e.g., via
<code>initscr()</code> or <code>newterm()</code>.
<li>add some checks to ensure current position is within scrolling
region before scrolling on a new line.
<li>modify <code>unctrl()</code> to check codes in 128-255 range versus
<code>isprint()</code>.
If they are not printable, and locale was set, use a "M-" or "~"
sequence.
<li>add a workaround to ACS mapping to allow applications such as
test/blue.c to use the "PC ROM" characters by masking them with
A_ALTCHARSET. This worked up til 5.5, but was lost in the revision
of legacy coding.
<li>improve <code>resizeterm()</code> by moving ripped-off lines, and
repainting the soft-keys.
<li>modify form library to accept control characters such as newline
in set_field_buffer(), which is compatible with Solaris.
<li>use <code>NCURSES_MOUSE_MASK()</code> in definition of
<code>BUTTON_RELEASE()</code>, etc., to make those work properly
with the <code>--enable-ext-mouse</code> configuration
<li>correct some functions in Ada95 binding which were using return
value from C where none was returned.
<li>reviewed/fixed issues reported by Coverity and Klocwork tools.
</ul>
Portability:
@ -257,110 +242,115 @@ Portability:
<li>new options:
<dl>
<dt>--with-hashed-db
<dd>Use Berkeley hashed database for storing terminfo data rather than storing
each compiled entry in a separate binary file within a directory
tree.
<dt>--disable-big-strings
<dd>control whether static string tables are generated as single
large strings (to improve startup performance), or as array
of individual strings.
<dt>--without-dlsym
<dd>Do not use <code>dlsym()</code> to load GPM dynamically.
<dt>--disable-relink
<dd>control whether shared libraries are relinked (during install)
when rpath is enabled.
<dt>--with-valgrind
<dd>Simplify building for testing with valgrind.
<dt>--disable-tic-depends
<dd>make explicit whether tic library depends on ncurses/ncursesw
library.
<dt>--enable-wgetch-events
<dd>Compile with experimental wgetch-events code.
<dt>--enable-mixed-case
<dd>override the configure script's check if the filesystem
supports mixed-case filenames.
This allows one to control how the terminal database
maps to the filesystem.
For filesystems that do not support mixed-case, the library
uses generate 2-character (hexadecimal) codes for the
lower-level of the filesystem terminfo database
<dt>--enable-signed-char
<dd>Store booleans in "signed char" rather than "char".
<dt>--enable-reentrant
<dd>builds a different flavor of the ncurses library (ncursest)
which improves reentrant use of the
library by reducing global and static variables
(see the "--with-pthread" option for the threaded support).
<dt>--enable-weak-symbols
<dd>use weak-symbols for linking to the POSIX thread library,
and use the same soname for the ncurses shared library
as the normal library (caveat: the ABI is for the threaded
library, which makes global data accessed via functions).
<dt>--with-pthread
<dd>build with the POSIX thread library (tested with AIX,
Linux, FreeBSD, OpenBSD, HPUX, IRIX64, Solaris, Tru64).
<dt>--with-ticlib
<dd>build/install the tic-support functions in a separate library
</dl>
<li>improved options:
<dl>
<dt>--disable-largefile
<dd>make the option work both ways.
<dt>--enable-ext-colors
<dd>requires the wide-character configuration.
<dt>--with-gpm
<dd>The option now accepts a parameter,
i.e., the name of the dynamic GPM library to load via
<code>dlopen()</code>
<dt>--with-chtype
<dd>ignore option value "unsigned" is always added to
the type in curses.h; do the same for --with-mmask-t.
<dt>--disable-symlinks
<dd>The option now allows one to
disable <code>symlink()</code> in <code>tic</code> even when
<code>link()</code> does not work.
<dt>--with-dmalloc
<dd>build-fix for redefinition of <code>strndup</code>.
<dt>--with-hashed-db
<dd>accepts a parameter which is the install-prefix of a given
Berkeley Database.
<dt>--with-hashed-db
<dd>the $LIBS environment variable overrides the search for the db
library.
<dt>--without-hashed-db
<dd>assumed when "--disable-database" is used.
</dl>
</ul>
<li>other configure/build issues: <ul> <li>remove special case for
Darwin in <code>CF_XOPEN_SOURCE</code> configure macro.
<li>add configure check to ensure that <code>SIGWINCH</code> is
defined on platforms such as OS X which exclude that when
<code>_XOPEN_SOURCE,</code> etc., are defined
<li>use ld's <code>-search_paths_first</code> option on Darwin
to work around odd search rules on that platform.
<li>improve ifdef's for <code>_POSIX_VDISABLE</code> in tset to
work with Mac OS X.
<li>modify configure script to ensure that if the C compiler is
used rather than the loader in making shared libraries, the
<code>$(CFLAGS)</code> variable is also used.
<li>use <code>${CC}</code> rather than <code>${LD}</code> in
shared library rules for IRIX64, Solaris to help ensure
that initialization sections are provided for extra linkage
requirements, e.g., of C++ applications.
<li>improve some shared-library configure scripting for Linux,
FreeBSD and NetBSD to make
<code>--with-shlib-version</code> work.
<li>split up dependency of <code>names.c</code> and
<code>codes.c</code> in <code>ncurses/Makefile</code> to
work with parallel make.
<li>modify <code>MKlib_gen.sh</code> to change
preprocessor-expanded <code>_Bool</code> back to <code>bool</code>.
<li>modify <code>progs/Makefile.in</code> to make
<code>tput&nbsp;init</code> work properly with cygwin,
i.e., do not pass a <code>.exe</code> in the reference
string used in check_aliases.
<li>other configure/build issues:
<ul>
<li>build-fixes for LynxOS
<li>modify shared-library rules to allow FreeBSD 3.x to use rpath.
<li>build-fix for FreeBSD "contemporary" TTY interface.
<li>build-fixes for AIX with libtool.
<li>build-fixes for Darwin and libtool.
<li>modify BeOS-specific ifdef's to build on Haiku.
<li>corrected gcc options for building shared libraries on Solaris
and IRIX64.
<li>change shared-library configuration for OpenBSD, make rpath work.
<li>build-fixes for using libutf8, e.g., on OpenBSD 3.7
<li>add "-e" option in ncurses/Makefile.in when generating source-files
to force earlier exit if the build environment fails unexpectedly.
<li>add support for shared libraries for QNX.
<li>change delimiter in <code>MKlib_gen.sh</code> from '%' to '@', to
avoid substitution by IBM xlc to '#' as part of its extensions to
digraphs.
</ul>
<li>library:
<ul>
<li>ignore wide-acs line-drawing characters that
<code>wcwidth()</code> claims are not one-column. This is
a workaround for Solaris' broken locale support.
<li>reduce name-pollution in <code>term.h</code> by removing
<code>#define</code>'s for HAVE_xxx symbols.
<li>fix <code>#ifdef</code> in <code>c++/internal.h</code> for
QNX 6.1
<li>rewrite wrapper for <code>wcrtomb()</code>, making it work on
Solaris. This is used in the form library to determine the length
of the buffer needed by <code>field_buffer</code>.
<li>add/use configure script macro CF_SIG_ATOMIC_T, use the corresponding
type for data manipulated by signal handlers.
<li>set locale in misc/ncurses-config.in since it uses a range
<li>disable GPM mouse support when $TERM does not happen to contain
"linux", since Gpm_Open() no longer limits its assertion to terminals
that it might handle, e.g., within "screen" in xterm.
<li>reset mouse file-descriptor when unloading GPM library.
</ul>
<li>test programs: <ul> <li>modify <code>test/configure</code> script
to allow building test programs with PDCurses/X11.
<li>modified test programs to allow some to work with NetBSD
curses. Several do not because NetBSD curses implements a
subset of X/Open curses, and also lacks much of SVr4
additions. But it is enough for comparison.
<li>improved <code>test/configure</code> to build test/ncurses
on HPUX 11 using the vendor curses.
<li>change configure script to produce
<code>test/Makefile</code> from data file.
<li>test programs:
<ul>
<li>update test programs to build/work with various UNIX curses for
comparisons.
</ul>
</ul>
@ -410,6 +400,8 @@ and <CODE>define_key()</CODE> allow
you to better control the use of function keys,
e.g., disabling the ncurses KEY_MOUSE,
or by defining more than one control sequence to map to a given key code.
<LI>Support for 256-color terminals, such as modern xterm, when configured
using the <code>--enable-ext-colors</code> option.
<LI>Support for 16-color terminals, such as aixterm and modern xterm.
<LI>Better cursor-movement optimization. The package now features a
cursor-local-movement computation more efficient than either BSD's
@ -513,14 +505,10 @@ for similar applications on GNU/Linux.
<br>
<DT> pinfo
<DD> Lynx-like info browser.
<A HREF="http://dione.ids.pl/~pborys/software/pinfo/">http://dione.ids.pl/~pborys/software/pinfo/</A>
<A HREF="https://alioth.debian.org/projects/pinfo/">https://alioth.debian.org/projects/pinfo/</A>
<DT> tin
<DD> newsreader, supporting color, MIME
<A HREF="http://www.tin.org/">http://www.tin.org/</A>
<DT> vh-1.6
<DD> Volks-Hypertext browser for the Jargon File
<br>
<A HREF="http://www.debian.org/Packages/unstable/text/vh.html">http://www.debian.org/Packages/unstable/text/vh.html</A>
</DL>
as well as some that use ncurses for the terminfo support alone:
<DL>

View file

@ -1,5 +1,5 @@
/****************************************************************************
* Copyright (c) 1998-2004,2005 Free Software Foundation, Inc. *
* Copyright (c) 1998-2006,2008 Free Software Foundation, Inc. *
* *
* Permission is hereby granted, free of charge, to any person obtaining a *
* copy of this software and associated documentation files (the *
@ -30,7 +30,7 @@
* Author: Juergen Pfeifer, 1995,1997 *
****************************************************************************/
/* $Id: form.priv.h,v 0.26 2006/12/17 19:47:09 tom Exp $ */
/* $Id: form.priv.h,v 0.27 2008/09/08 20:29:05 tom Exp $ */
#ifndef FORM_PRIV_H
#define FORM_PRIV_H 1
@ -39,8 +39,6 @@
#include "mf_common.h"
#if USE_WIDEC_SUPPORT
#include <wchar.h>
#if HAVE_WCTYPE_H
#include <wctype.h>
#endif

View file

@ -1,5 +1,5 @@
/****************************************************************************
* Copyright (c) 1998-2006,2007 Free Software Foundation, Inc. *
* Copyright (c) 1998-2007,2008 Free Software Foundation, Inc. *
* *
* Permission is hereby granted, free of charge, to any person obtaining a *
* copy of this software and associated documentation files (the *
@ -32,7 +32,7 @@
#include "form.priv.h"
MODULE_ID("$Id: frm_def.c,v 1.22 2007/10/13 19:31:17 tom Exp $")
MODULE_ID("$Id: frm_def.c,v 1.23 2008/08/04 00:07:55 tom Exp $")
/* this can't be readonly */
static FORM default_form =
@ -234,8 +234,16 @@ Connect_Fields(FORM *form, FIELD **fields)
fields[j]->page = page_nr;
fld = Insert_Field_By_Position(fields[j], fld);
}
form->page[page_nr].smin = fld->index;
form->page[page_nr].smax = fld->sprev->index;
if (fld)
{
form->page[page_nr].smin = fld->index;
form->page[page_nr].smax = fld->sprev->index;
}
else
{
form->page[page_nr].smin = 0;
form->page[page_nr].smax = 0;
}
}
RETURN(E_OK);
}

View file

@ -32,7 +32,7 @@
#include "form.priv.h"
MODULE_ID("$Id: frm_driver.c,v 1.86 2008/01/19 20:11:03 tom Exp $")
MODULE_ID("$Id: frm_driver.c,v 1.88 2008/10/18 16:25:00 tom Exp $")
/*----------------------------------------------------------------------------
This is the core module of the form library. It contains the majority
@ -4176,7 +4176,7 @@ form_driver(FORM *form, int c)
NULL /* Choice Request is generic */
};
size_t nMethods = (sizeof(Generic_Methods) / sizeof(Generic_Methods[0]));
size_t method = ((BI->keycode & ID_Mask) >> ID_Shft) & 0xffff;
size_t method = (BI->keycode >> ID_Shft) & 0xffff; /* see ID_Mask */
if ((method >= nMethods) || !(BI->cmd))
res = E_SYSTEM_ERROR;
@ -4333,15 +4333,6 @@ set_field_buffer(FIELD *field, int buffer, const char *value)
len = Buffer_Length(field);
if (buffer == 0)
{
for (i = 0; (value[i] != '\0') && (i < len); ++i)
{
if (iscntrl(UChar(value[i])))
RETURN(E_BAD_ARGUMENT);
}
}
if (Growable(field))
{
/* for a growable field we must assume zero terminated strings, because
@ -4356,14 +4347,6 @@ set_field_buffer(FIELD *field, int buffer, const char *value)
* field->cols))))
RETURN(E_SYSTEM_ERROR);
/* in this case we also have to check, whether or not the remaining
characters in value are also printable for buffer 0. */
if (buffer == 0)
{
for (i = len; i < vlen; i++)
if (iscntrl(UChar(value[i])))
RETURN(E_BAD_ARGUMENT);
}
len = vlen;
}
}
@ -4376,6 +4359,13 @@ set_field_buffer(FIELD *field, int buffer, const char *value)
* There should be a better way, but this handles nonspacing characters
* and other special cases that we really do not want to handle here.
*/
#if NCURSES_EXT_FUNCS
if (wresize(field->working, field->drows, field->dcols) == ERR)
#endif
{
delwin(field->working);
field->working = newpad(field->drows, field->dcols);
}
wclear(field->working);
mvwaddstr(field->working, 0, 0, value);
@ -4385,7 +4375,12 @@ set_field_buffer(FIELD *field, int buffer, const char *value)
}
else
{
mvwin_wchnstr(field->working, 0, 0, widevalue, (int)len);
for (i = 0; i < (unsigned)field->drows; ++i)
{
mvwin_wchnstr(field->working, i, 0,
widevalue + (i * field->dcols),
field->dcols);
}
for (i = 0; i < len; ++i)
{
if (CharEq(myZEROS, widevalue[i]))

View file

@ -1,5 +1,5 @@
/****************************************************************************
* Copyright (c) 1998-2004,2005 Free Software Foundation, Inc. *
* Copyright (c) 1998-2005,2008 Free Software Foundation, Inc. *
* *
* Permission is hereby granted, free of charge, to any person obtaining a *
* copy of this software and associated documentation files (the *
@ -37,7 +37,7 @@
#include "form.priv.h"
MODULE_ID("$Id: frm_req_name.c,v 1.15 2005/04/16 16:59:27 tom Exp $")
MODULE_ID("$Id: frm_req_name.c,v 1.16 2008/07/05 23:22:08 tom Exp $")
static const char *request_names[MAX_FORM_COMMAND - MIN_FORM_COMMAND + 1] =
{
@ -154,7 +154,7 @@ form_request_by_name(const char *str)
strncpy(buf, str, sizeof(buf));
while ((i < sizeof(buf)) && (buf[i] != '\0'))
{
buf[i] = toupper(buf[i]);
buf[i] = toupper(UChar(buf[i]));
i++;
}

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