Merge head
This commit is contained in:
commit
9d2ab4a62d
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/projects/bmake/; revision=265006
318
Makefile.inc1
318
Makefile.inc1
@ -15,7 +15,7 @@
|
|||||||
# -DNO_PORTSUPDATE do not update ports in ${MAKE} update
|
# -DNO_PORTSUPDATE do not update ports in ${MAKE} update
|
||||||
# -DNO_ROOT install without using root privilege
|
# -DNO_ROOT install without using root privilege
|
||||||
# -DNO_DOCUPDATE do not update doc in ${MAKE} update
|
# -DNO_DOCUPDATE do not update doc in ${MAKE} update
|
||||||
# -DNO_CTF do not run the DTrace CTF conversion tools on built objects
|
# -DWITHOUT_CTF do not run the DTrace CTF conversion tools on built objects
|
||||||
# LOCAL_DIRS="list of dirs" to add additional dirs to the SUBDIR list
|
# LOCAL_DIRS="list of dirs" to add additional dirs to the SUBDIR list
|
||||||
# LOCAL_LIB_DIRS="list of dirs" to add additional dirs to libraries target
|
# LOCAL_LIB_DIRS="list of dirs" to add additional dirs to libraries target
|
||||||
# LOCAL_MTREE="list of mtree files" to process to allow local directories
|
# LOCAL_MTREE="list of mtree files" to process to allow local directories
|
||||||
@ -58,6 +58,7 @@
|
|||||||
# use that new version. And the new (dynamically-linked) /bin/sh
|
# use that new version. And the new (dynamically-linked) /bin/sh
|
||||||
# will expect to find appropriate libraries in /lib and /libexec.
|
# will expect to find appropriate libraries in /lib and /libexec.
|
||||||
#
|
#
|
||||||
|
SRCDIR?= ${.CURDIR}
|
||||||
.if defined(SUBDIR_OVERRIDE)
|
.if defined(SUBDIR_OVERRIDE)
|
||||||
SUBDIR= ${SUBDIR_OVERRIDE}
|
SUBDIR= ${SUBDIR_OVERRIDE}
|
||||||
.else
|
.else
|
||||||
@ -84,6 +85,9 @@ SUBDIR+=secure
|
|||||||
SUBDIR+=share
|
SUBDIR+=share
|
||||||
.endif
|
.endif
|
||||||
SUBDIR+=sys usr.bin usr.sbin
|
SUBDIR+=sys usr.bin usr.sbin
|
||||||
|
.if ${MK_TESTS} != "no"
|
||||||
|
SUBDIR+= tests
|
||||||
|
.endif
|
||||||
.if ${MK_OFED} != "no"
|
.if ${MK_OFED} != "no"
|
||||||
SUBDIR+=contrib/ofed
|
SUBDIR+=contrib/ofed
|
||||||
.endif
|
.endif
|
||||||
@ -128,11 +132,14 @@ OSRELDATE= 0
|
|||||||
.endif
|
.endif
|
||||||
|
|
||||||
.if !defined(VERSION)
|
.if !defined(VERSION)
|
||||||
VERSION!= uname -srp
|
REVISION!= ${MAKE} -C ${SRCDIR}/release -V REVISION
|
||||||
VERSION+= ${OSRELDATE}
|
BRANCH!= ${MAKE} -C ${SRCDIR}/release -V BRANCH
|
||||||
|
SRCRELDATE!= awk '/^\#define[[:space:]]*__FreeBSD_version/ { print $$3 }' \
|
||||||
|
${SRCDIR}/sys/sys/param.h
|
||||||
|
VERSION= FreeBSD ${REVISION}-${BRANCH:C/-p[0-9]+$//} ${TARGET_ARCH} ${SRCRELDATE}
|
||||||
.endif
|
.endif
|
||||||
|
|
||||||
KNOWN_ARCHES?= amd64 arm armeb/arm armv6/arm i386 i386/pc98 ia64 mips mipsel/mips mips64el/mips mips64/mips mipsn32el/mips mipsn32/mips powerpc powerpc64/powerpc sparc64
|
KNOWN_ARCHES?= amd64 arm armeb/arm armv6/arm armv6hf/arm i386 i386/pc98 ia64 mips mipsel/mips mips64el/mips mips64/mips mipsn32el/mips mipsn32/mips powerpc powerpc64/powerpc sparc64
|
||||||
.if ${TARGET} == ${TARGET_ARCH}
|
.if ${TARGET} == ${TARGET_ARCH}
|
||||||
_t= ${TARGET}
|
_t= ${TARGET}
|
||||||
.else
|
.else
|
||||||
@ -224,22 +231,24 @@ CROSSENV+= GROFF_BIN_PATH=${WORLDTMP}/legacy/usr/bin \
|
|||||||
GROFF_FONT_PATH=${WORLDTMP}/legacy/usr/share/groff_font \
|
GROFF_FONT_PATH=${WORLDTMP}/legacy/usr/share/groff_font \
|
||||||
GROFF_TMAC_PATH=${WORLDTMP}/legacy/usr/share/tmac
|
GROFF_TMAC_PATH=${WORLDTMP}/legacy/usr/share/tmac
|
||||||
.endif
|
.endif
|
||||||
|
.if defined(TARGET_CFLAGS)
|
||||||
|
CROSSENV+= ${TARGET_CFLAGS}
|
||||||
|
.endif
|
||||||
|
|
||||||
# bootstrap-tools stage
|
# bootstrap-tools stage
|
||||||
BMAKEENV= INSTALL="sh ${.CURDIR}/tools/install.sh" \
|
BMAKEENV= INSTALL="sh ${.CURDIR}/tools/install.sh" \
|
||||||
PATH=${BPATH}:${PATH} \
|
PATH=${BPATH}:${PATH} \
|
||||||
WORLDTMP=${WORLDTMP} \
|
WORLDTMP=${WORLDTMP} \
|
||||||
VERSION="${VERSION}" \
|
VERSION="${VERSION}" \
|
||||||
MAKEFLAGS="-m ${.CURDIR}/tools/build/mk ${.MAKEFLAGS}" \
|
MAKEFLAGS="-m ${.CURDIR}/tools/build/mk ${.MAKEFLAGS}"
|
||||||
COMPILER_TYPE=${COMPILER_TYPE}
|
|
||||||
BMAKE= MAKEOBJDIRPREFIX=${WORLDTMP} \
|
BMAKE= MAKEOBJDIRPREFIX=${WORLDTMP} \
|
||||||
${BMAKEENV} ${MAKE} ${WORLD_FLAGS} -f Makefile.inc1 \
|
${BMAKEENV} ${MAKE} ${WORLD_FLAGS} -f Makefile.inc1 \
|
||||||
DESTDIR= \
|
DESTDIR= \
|
||||||
BOOTSTRAPPING=${OSRELDATE} \
|
BOOTSTRAPPING=${OSRELDATE} \
|
||||||
SSP_CFLAGS= \
|
SSP_CFLAGS= \
|
||||||
-DWITHOUT_HTML -DWITHOUT_INFO -DNO_LINT -DWITHOUT_MAN \
|
MK_HTML=no MK_INFO=no NO_LINT=yes MK_MAN=no \
|
||||||
-DNO_PIC -DNO_PROFILE -DNO_SHARED \
|
-DNO_PIC MK_PROFILE=no -DNO_SHARED \
|
||||||
-DNO_CPU_CFLAGS -DNO_WARNS -DNO_CTF -DEARLY_BUILD
|
-DNO_CPU_CFLAGS -DNO_WARNS MK_CTF=no -DEARLY_BUILD MK_TESTS=no
|
||||||
|
|
||||||
# build-tools stage
|
# build-tools stage
|
||||||
TMAKE= MAKEOBJDIRPREFIX=${OBJTREE} \
|
TMAKE= MAKEOBJDIRPREFIX=${OBJTREE} \
|
||||||
@ -249,12 +258,26 @@ TMAKE= MAKEOBJDIRPREFIX=${OBJTREE} \
|
|||||||
BOOTSTRAPPING=${OSRELDATE} \
|
BOOTSTRAPPING=${OSRELDATE} \
|
||||||
SSP_CFLAGS= \
|
SSP_CFLAGS= \
|
||||||
-DNO_LINT \
|
-DNO_LINT \
|
||||||
-DNO_CPU_CFLAGS -DNO_WARNS -DNO_CTF -DEARLY_BUILD
|
-DNO_CPU_CFLAGS -DNO_WARNS MK_CTF=no -DEARLY_BUILD MK_TESTS=no
|
||||||
|
|
||||||
# cross-tools stage
|
# cross-tools stage
|
||||||
XMAKE= TOOLS_PREFIX=${WORLDTMP} ${BMAKE} \
|
XMAKE= TOOLS_PREFIX=${WORLDTMP} ${BMAKE} \
|
||||||
TARGET=${TARGET} TARGET_ARCH=${TARGET_ARCH} \
|
TARGET=${TARGET} TARGET_ARCH=${TARGET_ARCH} \
|
||||||
-DWITHOUT_GDB
|
MK_GDB=no MK_TESTS=no
|
||||||
|
|
||||||
|
# kernel-tools stage
|
||||||
|
KTMAKEENV= INSTALL="sh ${.CURDIR}/tools/install.sh" \
|
||||||
|
PATH=${BPATH}:${PATH} \
|
||||||
|
WORLDTMP=${WORLDTMP} \
|
||||||
|
VERSION="${VERSION}"
|
||||||
|
KTMAKE= TOOLS_PREFIX=${WORLDTMP} MAKEOBJDIRPREFIX=${WORLDTMP} \
|
||||||
|
${KTMAKEENV} ${MAKE} ${WORLD_FLAGS} -f Makefile.inc1 \
|
||||||
|
DESTDIR= \
|
||||||
|
BOOTSTRAPPING=${OSRELDATE} \
|
||||||
|
SSP_CFLAGS= \
|
||||||
|
MK_HTML=no MK_INFO=no -DNO_LINT MK_MAN=no \
|
||||||
|
-DNO_PIC MK_PROFILE=no -DNO_SHARED \
|
||||||
|
-DNO_CPU_CFLAGS -DNO_WARNS MK_CTF=no -DEARLY_BUILD
|
||||||
|
|
||||||
# world stage
|
# world stage
|
||||||
WMAKEENV= ${CROSSENV} \
|
WMAKEENV= ${CROSSENV} \
|
||||||
@ -271,7 +294,7 @@ HMAKE+= PATH=${TMPPATH} METALOG=${METALOG} -DNO_ROOT
|
|||||||
.endif
|
.endif
|
||||||
|
|
||||||
.if ${MK_CDDL} == "no"
|
.if ${MK_CDDL} == "no"
|
||||||
WMAKEENV+= NO_CTF=1
|
WMAKEENV+= MK_CTF=no
|
||||||
.endif
|
.endif
|
||||||
|
|
||||||
.if defined(CROSS_TOOLCHAIN_PREFIX)
|
.if defined(CROSS_TOOLCHAIN_PREFIX)
|
||||||
@ -299,17 +322,6 @@ WMAKEENV+= CC="${XCC} ${XFLAGS}" CXX="${XCXX} ${XFLAGS}" \
|
|||||||
AS="${XAS}" AR="${XAR}" LD="${XLD}" NM=${XNM} \
|
AS="${XAS}" AR="${XAR}" LD="${XLD}" NM=${XNM} \
|
||||||
OBJDUMP=${XOBJDUMP} RANLIB=${XRANLIB} STRINGS=${XSTRINGS}
|
OBJDUMP=${XOBJDUMP} RANLIB=${XRANLIB} STRINGS=${XSTRINGS}
|
||||||
|
|
||||||
.if ${XCC:T:Mgcc} == "gcc"
|
|
||||||
WMAKE_COMPILER_TYPE= gcc
|
|
||||||
.elif ${XCC:T:Mclang} == "clang"
|
|
||||||
WMAKE_COMPILER_TYPE= clang
|
|
||||||
.elif ${MK_CLANG_IS_CC} == "no"
|
|
||||||
WMAKE_COMPILER_TYPE= gcc
|
|
||||||
.else
|
|
||||||
WMAKE_COMPILER_TYPE= clang
|
|
||||||
.endif
|
|
||||||
IMAKE_COMPILER_TYPE= COMPILER_TYPE=${WMAKE_COMPILER_TYPE}
|
|
||||||
|
|
||||||
.if ${XCC:M/*}
|
.if ${XCC:M/*}
|
||||||
XFLAGS= --sysroot=${WORLDTMP}
|
XFLAGS= --sysroot=${WORLDTMP}
|
||||||
.if defined(CROSS_BINUTILS_PREFIX)
|
.if defined(CROSS_BINUTILS_PREFIX)
|
||||||
@ -322,19 +334,18 @@ XFLAGS+= -B${CROSS_BINUTILS_PREFIX}
|
|||||||
.else
|
.else
|
||||||
XFLAGS+= -B${WORLDTMP}/usr/bin
|
XFLAGS+= -B${WORLDTMP}/usr/bin
|
||||||
.endif
|
.endif
|
||||||
.if ${TARGET_ARCH} != ${MACHINE_ARCH} && ${WMAKE_COMPILER_TYPE} == "clang"
|
.if ${TARGET} == "arm" && ${MK_ARM_EABI} != "no"
|
||||||
.if (${TARGET_ARCH} == "arm" || ${TARGET_ARCH} == "armv6") && \
|
.if ${TARGET_ARCH:M*eb*} == ""
|
||||||
${MK_ARM_EABI} != "no"
|
|
||||||
TARGET_ABI= gnueabi
|
TARGET_ABI= gnueabi
|
||||||
.else
|
.elif ${TARGET_ARCH} == "armv6hf"
|
||||||
TARGET_ABI= unknown
|
TARGET_ABI= gnueabihf
|
||||||
.endif
|
.endif
|
||||||
|
.endif
|
||||||
|
TARGET_ABI?= unknown
|
||||||
TARGET_TRIPLE?= ${TARGET_ARCH:C/amd64/x86_64/}-${TARGET_ABI}-freebsd11.0
|
TARGET_TRIPLE?= ${TARGET_ARCH:C/amd64/x86_64/}-${TARGET_ABI}-freebsd11.0
|
||||||
XFLAGS+= -target ${TARGET_TRIPLE}
|
XFLAGS+= -target ${TARGET_TRIPLE}
|
||||||
.endif
|
.endif
|
||||||
.endif
|
|
||||||
|
|
||||||
WMAKEENV+= COMPILER_TYPE=${WMAKE_COMPILER_TYPE}
|
|
||||||
WMAKE= ${WMAKEENV} ${MAKE} ${WORLD_FLAGS} -f Makefile.inc1 DESTDIR=${WORLDTMP}
|
WMAKE= ${WMAKEENV} ${MAKE} ${WORLD_FLAGS} -f Makefile.inc1 DESTDIR=${WORLDTMP}
|
||||||
|
|
||||||
.if ${TARGET_ARCH} == "amd64" || ${TARGET_ARCH} == "powerpc64"
|
.if ${TARGET_ARCH} == "amd64" || ${TARGET_ARCH} == "powerpc64"
|
||||||
@ -382,27 +393,26 @@ LIB32WMAKEENV+= MAKEOBJDIRPREFIX=${OBJTREE}/lib32 \
|
|||||||
PATH=${TMPPATH} \
|
PATH=${TMPPATH} \
|
||||||
LIBDIR=/usr/lib32 \
|
LIBDIR=/usr/lib32 \
|
||||||
SHLIBDIR=/usr/lib32 \
|
SHLIBDIR=/usr/lib32 \
|
||||||
LIBPRIVATEDIR=/usr/lib32/private \
|
LIBPRIVATEDIR=/usr/lib32/private
|
||||||
COMPILER_TYPE=${WMAKE_COMPILER_TYPE}
|
LIB32WMAKEFLAGS+= CC="${XCC} ${LIB32FLAGS}" \
|
||||||
LIB32WMAKEFLAGS+= \
|
|
||||||
CC="${XCC} ${LIB32FLAGS}" \
|
|
||||||
CXX="${XCXX} ${LIB32FLAGS}" \
|
CXX="${XCXX} ${LIB32FLAGS}" \
|
||||||
DESTDIR=${LIB32TMP} \
|
DESTDIR=${LIB32TMP} \
|
||||||
-DCOMPAT_32BIT \
|
-DCOMPAT_32BIT \
|
||||||
-DLIBRARIES_ONLY \
|
-DLIBRARIES_ONLY \
|
||||||
-DNO_CPU_CFLAGS \
|
-DNO_CPU_CFLAGS \
|
||||||
-DNO_CTF \
|
MK_CTF=no \
|
||||||
-DNO_LINT
|
-DNO_LINT \
|
||||||
|
MK_TESTS=no
|
||||||
|
|
||||||
LIB32WMAKE= ${LIB32WMAKEENV} ${MAKE} ${LIB32WMAKEFLAGS} \
|
LIB32WMAKE= ${LIB32WMAKEENV} ${MAKE} ${LIB32WMAKEFLAGS} \
|
||||||
-DWITHOUT_MAN -DWITHOUT_INFO -DWITHOUT_HTML
|
MK_MAN=no MK_INFO=no MK_HTML=no
|
||||||
LIB32IMAKE= ${LIB32WMAKE:NINSTALL=*:NDESTDIR=*:N_LDSCRIPTROOT=*} -DNO_INCS \
|
LIB32IMAKE= ${LIB32WMAKE:NINSTALL=*:NDESTDIR=*:N_LDSCRIPTROOT=*} \
|
||||||
${IMAKE_INSTALL}
|
MK_TOOLCHAIN=no ${IMAKE_INSTALL}
|
||||||
.endif
|
.endif
|
||||||
|
|
||||||
IMAKEENV= ${CROSSENV:N_LDSCRIPTROOT=*}
|
IMAKEENV= ${CROSSENV:N_LDSCRIPTROOT=*}
|
||||||
IMAKE= ${IMAKEENV} ${MAKE} -f Makefile.inc1 \
|
IMAKE= ${IMAKEENV} ${MAKE} -f Makefile.inc1 \
|
||||||
${IMAKE_INSTALL} ${IMAKE_MTREE} ${IMAKE_COMPILER_TYPE}
|
${IMAKE_INSTALL} ${IMAKE_MTREE}
|
||||||
.if empty(.MAKEFLAGS:M-n)
|
.if empty(.MAKEFLAGS:M-n)
|
||||||
IMAKEENV+= PATH=${STRICTTMPPATH}:${INSTALLTMP} \
|
IMAKEENV+= PATH=${STRICTTMPPATH}:${INSTALLTMP} \
|
||||||
LD_LIBRARY_PATH=${INSTALLTMP} \
|
LD_LIBRARY_PATH=${INSTALLTMP} \
|
||||||
@ -425,7 +435,7 @@ MTREEFLAGS+= -W
|
|||||||
.endif
|
.endif
|
||||||
.if defined(DB_FROM_SRC) || defined(NO_ROOT)
|
.if defined(DB_FROM_SRC) || defined(NO_ROOT)
|
||||||
IMAKE_INSTALL= INSTALL="install ${INSTALLFLAGS}"
|
IMAKE_INSTALL= INSTALL="install ${INSTALLFLAGS}"
|
||||||
IMAKE_MTREE= MTREE_CMD="nmtree ${MTREEFLAGS}"
|
IMAKE_MTREE= MTREE_CMD="mtree ${MTREEFLAGS}"
|
||||||
.endif
|
.endif
|
||||||
|
|
||||||
# kernel stage
|
# kernel stage
|
||||||
@ -485,6 +495,10 @@ _worldtmp:
|
|||||||
mtree -deU -f ${.CURDIR}/etc/mtree/BSD.debug.dist \
|
mtree -deU -f ${.CURDIR}/etc/mtree/BSD.debug.dist \
|
||||||
-p ${WORLDTMP}/usr/lib >/dev/null
|
-p ${WORLDTMP}/usr/lib >/dev/null
|
||||||
.endif
|
.endif
|
||||||
|
.if ${MK_TESTS} != "no"
|
||||||
|
mtree -deU -f ${.CURDIR}/etc/mtree/BSD.tests.dist \
|
||||||
|
-p ${WORLDTMP}/usr >/dev/null
|
||||||
|
.endif
|
||||||
.for _mtree in ${LOCAL_MTREE}
|
.for _mtree in ${LOCAL_MTREE}
|
||||||
mtree -deU -f ${.CURDIR}/${_mtree} -p ${WORLDTMP} > /dev/null
|
mtree -deU -f ${.CURDIR}/${_mtree} -p ${WORLDTMP} > /dev/null
|
||||||
.endfor
|
.endfor
|
||||||
@ -529,6 +543,7 @@ _cross-tools:
|
|||||||
@echo ">>> stage 3: cross tools"
|
@echo ">>> stage 3: cross tools"
|
||||||
@echo "--------------------------------------------------------------"
|
@echo "--------------------------------------------------------------"
|
||||||
${_+_}cd ${.CURDIR}; ${XMAKE} cross-tools
|
${_+_}cd ${.CURDIR}; ${XMAKE} cross-tools
|
||||||
|
${_+_}cd ${.CURDIR}; ${XMAKE} kernel-tools
|
||||||
_includes:
|
_includes:
|
||||||
@echo
|
@echo
|
||||||
@echo "--------------------------------------------------------------"
|
@echo "--------------------------------------------------------------"
|
||||||
@ -541,8 +556,8 @@ _libraries:
|
|||||||
@echo ">>> stage 4.2: building libraries"
|
@echo ">>> stage 4.2: building libraries"
|
||||||
@echo "--------------------------------------------------------------"
|
@echo "--------------------------------------------------------------"
|
||||||
${_+_}cd ${.CURDIR}; \
|
${_+_}cd ${.CURDIR}; \
|
||||||
${WMAKE} -DNO_FSCHG -DWITHOUT_HTML -DWITHOUT_INFO -DNO_LINT \
|
${WMAKE} -DNO_FSCHG MK_HTML=no MK_INFO=no -DNO_LINT MK_MAN=no \
|
||||||
-DWITHOUT_MAN -DNO_PROFILE libraries
|
MK_PROFILE=no MK_TESTS=no libraries
|
||||||
_depend:
|
_depend:
|
||||||
@echo
|
@echo
|
||||||
@echo "--------------------------------------------------------------"
|
@echo "--------------------------------------------------------------"
|
||||||
@ -594,7 +609,7 @@ build32:
|
|||||||
WORLDTMP=${WORLDTMP} \
|
WORLDTMP=${WORLDTMP} \
|
||||||
MAKEFLAGS="-m ${.CURDIR}/tools/build/mk ${.MAKEFLAGS}" \
|
MAKEFLAGS="-m ${.CURDIR}/tools/build/mk ${.MAKEFLAGS}" \
|
||||||
MAKEOBJDIRPREFIX=${OBJTREE}/lib32 ${MAKE} SSP_CFLAGS= DESTDIR= \
|
MAKEOBJDIRPREFIX=${OBJTREE}/lib32 ${MAKE} SSP_CFLAGS= DESTDIR= \
|
||||||
DIRPRFX=${_dir}/ -DNO_LINT -DNO_CPU_CFLAGS -DNO_WARNS -DNO_CTF \
|
DIRPRFX=${_dir}/ -DNO_LINT -DNO_CPU_CFLAGS -DNO_WARNS MK_CTF=no \
|
||||||
-DEARLY_BUILD build-tools
|
-DEARLY_BUILD build-tools
|
||||||
.endfor
|
.endfor
|
||||||
cd ${.CURDIR}; \
|
cd ${.CURDIR}; \
|
||||||
@ -737,14 +752,10 @@ _install-info= install-info
|
|||||||
_zoneinfo= zic tzsetup
|
_zoneinfo= zic tzsetup
|
||||||
.endif
|
.endif
|
||||||
|
|
||||||
.if exists(/usr/sbin/nmtree)
|
|
||||||
_nmtree_itools= nmtree
|
|
||||||
.endif
|
|
||||||
|
|
||||||
ITOOLS= [ awk cap_mkdb cat chflags chmod chown \
|
ITOOLS= [ awk cap_mkdb cat chflags chmod chown \
|
||||||
date echo egrep find grep id install ${_install-info} \
|
date echo egrep find grep id install ${_install-info} \
|
||||||
ln lockf make mkdir mtree ${_nmtree_itools} mv pwd_mkdb \
|
ln lockf make mkdir mtree mv pwd_mkdb \
|
||||||
rm sed sh sysctl test true uname wc ${_zoneinfo}
|
rm sed services_mkdb sh sysctl test true uname wc ${_zoneinfo}
|
||||||
|
|
||||||
#
|
#
|
||||||
# distributeworld
|
# distributeworld
|
||||||
@ -806,11 +817,11 @@ distributeworld installworld: _installcheck_world
|
|||||||
-p ${DESTDIR}/${DISTDIR}/${dist}/usr/lib >/dev/null
|
-p ${DESTDIR}/${DISTDIR}/${dist}/usr/lib >/dev/null
|
||||||
.endif
|
.endif
|
||||||
.if defined(NO_ROOT)
|
.if defined(NO_ROOT)
|
||||||
${IMAKEENV} nmtree -C -f ${.CURDIR}/etc/mtree/BSD.root.dist | \
|
${IMAKEENV} mtree -C -f ${.CURDIR}/etc/mtree/BSD.root.dist | \
|
||||||
sed -e 's#^\./#./${dist}/#' >> ${METALOG}
|
sed -e 's#^\./#./${dist}/#' >> ${METALOG}
|
||||||
${IMAKEENV} nmtree -C -f ${.CURDIR}/etc/mtree/BSD.usr.dist | \
|
${IMAKEENV} mtree -C -f ${.CURDIR}/etc/mtree/BSD.usr.dist | \
|
||||||
sed -e 's#^\./#./${dist}/usr/#' >> ${METALOG}
|
sed -e 's#^\./#./${dist}/usr/#' >> ${METALOG}
|
||||||
${IMAKEENV} nmtree -C -f ${.CURDIR}/etc/mtree/BSD.include.dist | \
|
${IMAKEENV} mtree -C -f ${.CURDIR}/etc/mtree/BSD.include.dist | \
|
||||||
sed -e 's#^\./#./${dist}/usr/include/#' >> ${METALOG}
|
sed -e 's#^\./#./${dist}/usr/include/#' >> ${METALOG}
|
||||||
.endif
|
.endif
|
||||||
.endfor
|
.endfor
|
||||||
@ -963,6 +974,8 @@ INSTALLKERNEL= ${_kernel}
|
|||||||
.endif
|
.endif
|
||||||
.endfor
|
.endfor
|
||||||
|
|
||||||
|
buildkernel ${WMAKE_TGTS} ${.ALLTARGETS:M_*}: .MAKE
|
||||||
|
|
||||||
#
|
#
|
||||||
# buildkernel
|
# buildkernel
|
||||||
#
|
#
|
||||||
@ -988,7 +1001,7 @@ buildkernel:
|
|||||||
cd ${KRNLCONFDIR}; \
|
cd ${KRNLCONFDIR}; \
|
||||||
PATH=${TMPPATH} \
|
PATH=${TMPPATH} \
|
||||||
config ${CONFIGARGS} -d ${KRNLOBJDIR}/${_kernel} \
|
config ${CONFIGARGS} -d ${KRNLOBJDIR}/${_kernel} \
|
||||||
${KERNCONFDIR}/${_kernel}
|
-I ${KERNCONFDIR} ${KERNCONFDIR}/${_kernel}
|
||||||
.endif
|
.endif
|
||||||
.if !defined(NO_CLEAN) && !defined(NO_KERNELCLEAN)
|
.if !defined(NO_CLEAN) && !defined(NO_KERNELCLEAN)
|
||||||
@echo
|
@echo
|
||||||
@ -1008,20 +1021,7 @@ buildkernel:
|
|||||||
@echo "--------------------------------------------------------------"
|
@echo "--------------------------------------------------------------"
|
||||||
@echo ">>> stage 2.3: build tools"
|
@echo ">>> stage 2.3: build tools"
|
||||||
@echo "--------------------------------------------------------------"
|
@echo "--------------------------------------------------------------"
|
||||||
cd ${KRNLOBJDIR}/${_kernel}; \
|
${_+_}cd ${.CURDIR}; ${KTMAKE} kernel-tools
|
||||||
PATH=${BPATH}:${PATH} \
|
|
||||||
MAKESRCPATH=${KERNSRCDIR}/dev/aic7xxx/aicasm \
|
|
||||||
${MAKE} SSP_CFLAGS= -DNO_CPU_CFLAGS -DNO_CTF -DEARLY_BUILD \
|
|
||||||
-f ${KERNSRCDIR}/dev/aic7xxx/aicasm/Makefile
|
|
||||||
# XXX - Gratuitously builds aicasm in the ``makeoptions NO_MODULES'' case.
|
|
||||||
.if !defined(MODULES_WITH_WORLD) && !defined(NO_MODULES) && exists(${KERNSRCDIR}/modules)
|
|
||||||
.for target in obj depend all
|
|
||||||
cd ${KERNSRCDIR}/modules/aic7xxx/aicasm; \
|
|
||||||
PATH=${BPATH}:${PATH} \
|
|
||||||
MAKEOBJDIRPREFIX=${KRNLOBJDIR}/${_kernel}/modules \
|
|
||||||
${MAKE} SSP_CFLAGS= -DNO_CPU_CFLAGS -DNO_CTF -DEARLY_BUILD ${target}
|
|
||||||
.endfor
|
|
||||||
.endif
|
|
||||||
.if !defined(NO_KERNELDEPEND)
|
.if !defined(NO_KERNELDEPEND)
|
||||||
@echo
|
@echo
|
||||||
@echo "--------------------------------------------------------------"
|
@echo "--------------------------------------------------------------"
|
||||||
@ -1159,8 +1159,8 @@ update:
|
|||||||
# legacy: Build compatibility shims for the next three targets
|
# legacy: Build compatibility shims for the next three targets
|
||||||
#
|
#
|
||||||
legacy:
|
legacy:
|
||||||
.if ${BOOTSTRAPPING} < 700055 && ${BOOTSTRAPPING} != 0
|
.if ${BOOTSTRAPPING} < 800107 && ${BOOTSTRAPPING} != 0
|
||||||
@echo "ERROR: Source upgrades from versions prior to 7.0 not supported."; \
|
@echo "ERROR: Source upgrades from versions prior to 8.0 not supported."; \
|
||||||
false
|
false
|
||||||
.endif
|
.endif
|
||||||
.for _tool in tools/build
|
.for _tool in tools/build
|
||||||
@ -1188,14 +1188,6 @@ _gperf= gnu/usr.bin/gperf
|
|||||||
_groff= gnu/usr.bin/groff
|
_groff= gnu/usr.bin/groff
|
||||||
.endif
|
.endif
|
||||||
|
|
||||||
.if ${BOOTSTRAPPING} < 800022
|
|
||||||
_ar= usr.bin/ar
|
|
||||||
.endif
|
|
||||||
|
|
||||||
.if ${BOOTSTRAPPING} < 800013
|
|
||||||
_mklocale= usr.bin/mklocale
|
|
||||||
.endif
|
|
||||||
|
|
||||||
.if ${BOOTSTRAPPING} < 900002
|
.if ${BOOTSTRAPPING} < 900002
|
||||||
_sed= usr.bin/sed
|
_sed= usr.bin/sed
|
||||||
.endif
|
.endif
|
||||||
@ -1234,7 +1226,9 @@ _awk= usr.bin/awk
|
|||||||
_gensnmptree= usr.sbin/bsnmpd/gensnmptree
|
_gensnmptree= usr.sbin/bsnmpd/gensnmptree
|
||||||
.endif
|
.endif
|
||||||
|
|
||||||
.if ${MK_CLANG} != "no"
|
# We need to build tlbgen when we're building clang either as
|
||||||
|
# the bootstrap compiler, or as the part of the normal build.
|
||||||
|
.if ${MK_CLANG_BOOTSTRAP} != "no" || ${MK_CLANG} != "no"
|
||||||
_clang_tblgen= \
|
_clang_tblgen= \
|
||||||
lib/clang/libllvmsupport \
|
lib/clang/libllvmsupport \
|
||||||
lib/clang/libllvmtablegen \
|
lib/clang/libllvmtablegen \
|
||||||
@ -1251,7 +1245,7 @@ _dtrace_tools= cddl/usr.bin/sgsmsg cddl/lib/libctf lib/libelf \
|
|||||||
lib/libdwarf cddl/usr.bin/ctfconvert cddl/usr.bin/ctfmerge
|
lib/libdwarf cddl/usr.bin/ctfconvert cddl/usr.bin/ctfmerge
|
||||||
.endif
|
.endif
|
||||||
|
|
||||||
# Default to building the BSDL DTC, but build the GPL one if users explicitly
|
# Default to building the GPL DTC, but build the BSDL one if users explicitly
|
||||||
# request it.
|
# request it.
|
||||||
_dtc= usr.bin/dtc
|
_dtc= usr.bin/dtc
|
||||||
.if ${MK_GPL_DTC} != "no"
|
.if ${MK_GPL_DTC} != "no"
|
||||||
@ -1279,13 +1273,11 @@ bootstrap-tools: .MAKE
|
|||||||
${_strfile} \
|
${_strfile} \
|
||||||
${_gperf} \
|
${_gperf} \
|
||||||
${_groff} \
|
${_groff} \
|
||||||
${_ar} \
|
|
||||||
${_dtc} \
|
${_dtc} \
|
||||||
${_awk} \
|
${_awk} \
|
||||||
${_cat} \
|
${_cat} \
|
||||||
usr.bin/lorder \
|
usr.bin/lorder \
|
||||||
usr.bin/makewhatis \
|
usr.bin/makewhatis \
|
||||||
${_mklocale} \
|
|
||||||
usr.bin/rpcgen \
|
usr.bin/rpcgen \
|
||||||
${_sed} \
|
${_sed} \
|
||||||
${_yacc} \
|
${_yacc} \
|
||||||
@ -1308,10 +1300,6 @@ bootstrap-tools: .MAKE
|
|||||||
#
|
#
|
||||||
# build-tools: Build special purpose build tools
|
# build-tools: Build special purpose build tools
|
||||||
#
|
#
|
||||||
.if defined(MODULES_WITH_WORLD) && exists(${KERNSRCDIR}/modules)
|
|
||||||
_aicasm= sys/modules/aic7xxx/aicasm
|
|
||||||
.endif
|
|
||||||
|
|
||||||
.if !defined(NO_SHARE)
|
.if !defined(NO_SHARE)
|
||||||
_share= share/syscons/scrnmaps
|
_share= share/syscons/scrnmaps
|
||||||
.endif
|
.endif
|
||||||
@ -1333,7 +1321,6 @@ build-tools: .MAKE
|
|||||||
lib/ncurses/ncurses \
|
lib/ncurses/ncurses \
|
||||||
lib/ncurses/ncursesw \
|
lib/ncurses/ncursesw \
|
||||||
${_share} \
|
${_share} \
|
||||||
${_aicasm} \
|
|
||||||
usr.bin/awk \
|
usr.bin/awk \
|
||||||
lib/libmagic \
|
lib/libmagic \
|
||||||
usr.bin/mkesdb_static \
|
usr.bin/mkesdb_static \
|
||||||
@ -1353,10 +1340,21 @@ build-tools: .MAKE
|
|||||||
${MAKE} DIRPRFX=${_tool}/ all
|
${MAKE} DIRPRFX=${_tool}/ all
|
||||||
.endfor
|
.endfor
|
||||||
|
|
||||||
|
#
|
||||||
|
# kernel-tools: Build kernel-building tools
|
||||||
|
#
|
||||||
|
kernel-tools: .MAKE
|
||||||
|
mkdir -p ${MAKEOBJDIRPREFIX}/usr
|
||||||
|
mtree -deU -f ${.CURDIR}/etc/mtree/BSD.usr.dist \
|
||||||
|
-p ${MAKEOBJDIRPREFIX}/usr >/dev/null
|
||||||
|
|
||||||
#
|
#
|
||||||
# cross-tools: Build cross-building tools
|
# cross-tools: Build cross-building tools
|
||||||
#
|
#
|
||||||
.if ${TARGET_ARCH} != ${MACHINE_ARCH} || ${BOOTSTRAPPING} < 800035
|
.if !defined(TARGET_ARCH) && defined(XDEV_ARCH)
|
||||||
|
TARGET_ARCH= ${XDEV_ARCH}
|
||||||
|
.endif
|
||||||
|
.if ${TARGET_ARCH} != ${MACHINE_ARCH}
|
||||||
.if ${TARGET_ARCH} == "amd64" || ${TARGET_ARCH} == "i386"
|
.if ${TARGET_ARCH} == "amd64" || ${TARGET_ARCH} == "i386"
|
||||||
_btxld= usr.sbin/btxld
|
_btxld= usr.sbin/btxld
|
||||||
.endif
|
.endif
|
||||||
@ -1370,19 +1368,19 @@ _kgzip= usr.sbin/kgzip
|
|||||||
.endif
|
.endif
|
||||||
.endif
|
.endif
|
||||||
|
|
||||||
.if ${XAS:M/*} == "" && ${MK_BINUTILS} != "no"
|
# If we're given an XAS, don't build binutils.
|
||||||
|
.if ${XAS:M/*} == "" && ${MK_BINUTILS_BOOTSTRAP} != "no"
|
||||||
_binutils= gnu/usr.bin/binutils
|
_binutils= gnu/usr.bin/binutils
|
||||||
.endif
|
.endif
|
||||||
|
|
||||||
# If an full path to an external cross compiler is given, don't build
|
# If an full path to an external cross compiler is given, don't build
|
||||||
# a cross compiler.
|
# a cross compiler.
|
||||||
.if ${XCC:M/*} == "" && ${MK_CROSS_COMPILER} != "no"
|
.if ${XCC:M/*} == "" && ${MK_CROSS_COMPILER} != "no"
|
||||||
.if ${MK_CLANG} != "no" && (${MK_CLANG_IS_CC} != "no" || ${CC:T:Mclang} == "clang")
|
.if ${MK_CLANG_BOOTSTRAP} != "no"
|
||||||
_clang= usr.bin/clang
|
_clang= usr.bin/clang
|
||||||
_clang_libs= lib/clang
|
_clang_libs= lib/clang
|
||||||
.endif
|
.endif
|
||||||
|
.if ${MK_GCC_BOOTSTRAP} != "no"
|
||||||
.if ${MK_GCC} != "no" && (${MK_CLANG_IS_CC} == "no" || ${TARGET} == "pc98")
|
|
||||||
_cc= gnu/usr.bin/cc
|
_cc= gnu/usr.bin/cc
|
||||||
.endif
|
.endif
|
||||||
.endif
|
.endif
|
||||||
@ -1446,11 +1444,13 @@ _startup_libs+= lib/csu/${MACHINE_CPUARCH}
|
|||||||
_startup_libs+= gnu/lib/libgcc
|
_startup_libs+= gnu/lib/libgcc
|
||||||
_startup_libs+= lib/libcompiler_rt
|
_startup_libs+= lib/libcompiler_rt
|
||||||
_startup_libs+= lib/libc
|
_startup_libs+= lib/libc
|
||||||
|
_startup_libs+= lib/libc_nonshared
|
||||||
.if ${MK_LIBCPLUSPLUS} != "no"
|
.if ${MK_LIBCPLUSPLUS} != "no"
|
||||||
_startup_libs+= lib/libcxxrt
|
_startup_libs+= lib/libcxxrt
|
||||||
.endif
|
.endif
|
||||||
|
|
||||||
gnu/lib/libgcc__L: lib/libc__L
|
gnu/lib/libgcc__L: lib/libc__L
|
||||||
|
gnu/lib/libgcc__L: lib/libc_nonshared__L
|
||||||
.if ${MK_LIBCPLUSPLUS} != "no"
|
.if ${MK_LIBCPLUSPLUS} != "no"
|
||||||
lib/libcxxrt__L: gnu/lib/libgcc__L
|
lib/libcxxrt__L: gnu/lib/libgcc__L
|
||||||
.endif
|
.endif
|
||||||
@ -1464,22 +1464,31 @@ _prebuild_libs= ${_kerberos5_lib_libasn1} \
|
|||||||
${_kerberos5_lib_libhx509} ${_kerberos5_lib_libkrb5} \
|
${_kerberos5_lib_libhx509} ${_kerberos5_lib_libkrb5} \
|
||||||
${_kerberos5_lib_libroken} \
|
${_kerberos5_lib_libroken} \
|
||||||
${_kerberos5_lib_libwind} \
|
${_kerberos5_lib_libwind} \
|
||||||
${_lib_atf_libatf_c} \
|
${_lib_atf} \
|
||||||
lib/libbz2 ${_libcom_err} lib/libcrypt \
|
lib/libbz2 ${_libcom_err} lib/libcrypt \
|
||||||
lib/libelf lib/libexpat \
|
lib/libelf lib/libexpat \
|
||||||
${_lib_libgssapi} ${_lib_libipx} \
|
${_lib_libgssapi} \
|
||||||
lib/libkiconv lib/libkvm lib/liblzma lib/libmd \
|
lib/libkiconv lib/libkvm lib/liblzma lib/libmd lib/libnv \
|
||||||
|
${_lib_libcapsicum} \
|
||||||
lib/ncurses/ncurses lib/ncurses/ncursesw \
|
lib/ncurses/ncurses lib/ncurses/ncursesw \
|
||||||
lib/libopie lib/libpam ${_lib_libthr} \
|
lib/libopie lib/libpam ${_lib_libthr} \
|
||||||
lib/libradius lib/libsbuf lib/libtacplus \
|
lib/libradius lib/libsbuf lib/libtacplus \
|
||||||
${_cddl_lib_libumem} ${_cddl_lib_libnvpair} \
|
${_cddl_lib_libumem} ${_cddl_lib_libnvpair} \
|
||||||
${_cddl_lib_libzfs_core} \
|
${_cddl_lib_libzfs_core} \
|
||||||
lib/libutil ${_lib_libypclnt} lib/libz lib/msun \
|
lib/libutil lib/libpjdlog ${_lib_libypclnt} lib/libz lib/msun \
|
||||||
${_secure_lib_libcrypto} ${_lib_libldns} \
|
${_secure_lib_libcrypto} ${_lib_libldns} \
|
||||||
${_secure_lib_libssh} ${_secure_lib_libssl}
|
${_secure_lib_libssh} ${_secure_lib_libssl}
|
||||||
|
.if ${MK_GNUCXX} != "no" && ${MK_CXX} != "no"
|
||||||
|
_prebuild_libs+= gnu/lib/libstdc++ gnu/lib/libsupc++
|
||||||
|
.endif
|
||||||
|
|
||||||
.if ${MK_ATF} != "no"
|
.if defined(WITH_ATF) || ${MK_TESTS} != "no"
|
||||||
_lib_atf_libatf_c= lib/atf/libatf-c
|
.if !defined(WITH_ATF)
|
||||||
|
# Ensure that the ATF libraries will be built during make libraries, even
|
||||||
|
# though they will have WITHOUT_TESTS
|
||||||
|
MAKE+= -DWITH_ATF
|
||||||
|
.endif
|
||||||
|
_lib_atf= lib/atf
|
||||||
.endif
|
.endif
|
||||||
|
|
||||||
.if ${MK_LIBTHR} != "no"
|
.if ${MK_LIBTHR} != "no"
|
||||||
@ -1490,6 +1499,13 @@ _lib_libthr= lib/libthr
|
|||||||
_ofed_lib= contrib/ofed/usr.lib/
|
_ofed_lib= contrib/ofed/usr.lib/
|
||||||
.endif
|
.endif
|
||||||
|
|
||||||
|
.if ${MK_CASPER} != "no"
|
||||||
|
_lib_libcapsicum=lib/libcapsicum
|
||||||
|
.endif
|
||||||
|
|
||||||
|
lib/libcapsicum__L: lib/libnv__L
|
||||||
|
lib/libpjdlog__L: lib/libutil__L
|
||||||
|
|
||||||
_generic_libs= ${_cddl_lib} gnu/lib ${_kerberos5_lib} lib ${_secure_lib} usr.bin/lex/lib ${_ofed_lib}
|
_generic_libs= ${_cddl_lib} gnu/lib ${_kerberos5_lib} lib ${_secure_lib} usr.bin/lex/lib ${_ofed_lib}
|
||||||
.for _DIR in ${LOCAL_LIB_DIRS}
|
.for _DIR in ${LOCAL_LIB_DIRS}
|
||||||
.if exists(${.CURDIR}/${_DIR}/Makefile)
|
.if exists(${.CURDIR}/${_DIR}/Makefile)
|
||||||
@ -1556,10 +1572,6 @@ kerberos5/lib/libheimsqlite__L: lib/libthr__L
|
|||||||
_lib_libgssapi= lib/libgssapi
|
_lib_libgssapi= lib/libgssapi
|
||||||
.endif
|
.endif
|
||||||
|
|
||||||
.if ${MK_IPX} != "no"
|
|
||||||
_lib_libipx= lib/libipx
|
|
||||||
.endif
|
|
||||||
|
|
||||||
.if ${MK_KERBEROS} != "no"
|
.if ${MK_KERBEROS} != "no"
|
||||||
_kerberos5_lib= kerberos5/lib
|
_kerberos5_lib= kerberos5/lib
|
||||||
_kerberos5_lib_libasn1= kerberos5/lib/libasn1
|
_kerberos5_lib_libasn1= kerberos5/lib/libasn1
|
||||||
@ -1588,10 +1600,12 @@ ${_lib}__PL: .PHONY .MAKE
|
|||||||
.if exists(${.CURDIR}/${_lib})
|
.if exists(${.CURDIR}/${_lib})
|
||||||
${_+_}@${ECHODIR} "===> ${_lib} (obj,depend,all,install)"; \
|
${_+_}@${ECHODIR} "===> ${_lib} (obj,depend,all,install)"; \
|
||||||
cd ${.CURDIR}/${_lib} && \
|
cd ${.CURDIR}/${_lib} && \
|
||||||
${MAKE} DIRPRFX=${_lib}/ obj && \
|
${MAKE} MK_TESTS=no DIRPRFX=${_lib}/ obj && \
|
||||||
${MAKE} DIRPRFX=${_lib}/ depend && \
|
${MAKE} MK_TESTS=no DIRPRFX=${_lib}/ depend && \
|
||||||
${MAKE} -DNO_PROFILE -DNO_PIC DIRPRFX=${_lib}/ all && \
|
${MAKE} MK_TESTS=no MK_PROFILE=no -DNO_PIC \
|
||||||
${MAKE} -DNO_PROFILE -DNO_PIC DIRPRFX=${_lib}/ install
|
DIRPRFX=${_lib}/ all && \
|
||||||
|
${MAKE} MK_TESTS=no MK_PROFILE=no -DNO_PIC \
|
||||||
|
DIRPRFX=${_lib}/ install
|
||||||
.endif
|
.endif
|
||||||
.endfor
|
.endfor
|
||||||
|
|
||||||
@ -1600,10 +1614,10 @@ ${_lib}__L: .PHONY .MAKE
|
|||||||
.if exists(${.CURDIR}/${_lib})
|
.if exists(${.CURDIR}/${_lib})
|
||||||
${_+_}@${ECHODIR} "===> ${_lib} (obj,depend,all,install)"; \
|
${_+_}@${ECHODIR} "===> ${_lib} (obj,depend,all,install)"; \
|
||||||
cd ${.CURDIR}/${_lib} && \
|
cd ${.CURDIR}/${_lib} && \
|
||||||
${MAKE} DIRPRFX=${_lib}/ obj && \
|
${MAKE} MK_TESTS=no DIRPRFX=${_lib}/ obj && \
|
||||||
${MAKE} DIRPRFX=${_lib}/ depend && \
|
${MAKE} MK_TESTS=no DIRPRFX=${_lib}/ depend && \
|
||||||
${MAKE} DIRPRFX=${_lib}/ all && \
|
${MAKE} MK_TESTS=no DIRPRFX=${_lib}/ all && \
|
||||||
${MAKE} DIRPRFX=${_lib}/ install
|
${MAKE} MK_TESTS=no DIRPRFX=${_lib}/ install
|
||||||
.endif
|
.endif
|
||||||
.endfor
|
.endfor
|
||||||
|
|
||||||
@ -1613,10 +1627,12 @@ ${_lib}__L: .PHONY .MAKE
|
|||||||
lib/libpam__L: .PHONY .MAKE
|
lib/libpam__L: .PHONY .MAKE
|
||||||
${_+_}@${ECHODIR} "===> lib/libpam (obj,depend,all,install)"; \
|
${_+_}@${ECHODIR} "===> lib/libpam (obj,depend,all,install)"; \
|
||||||
cd ${.CURDIR}/lib/libpam && \
|
cd ${.CURDIR}/lib/libpam && \
|
||||||
${MAKE} DIRPRFX=lib/libpam/ obj && \
|
${MAKE} MK_TESTS=no DIRPRFX=lib/libpam/ obj && \
|
||||||
${MAKE} DIRPRFX=lib/libpam/ depend && \
|
${MAKE} MK_TESTS=no DIRPRFX=lib/libpam/ depend && \
|
||||||
${MAKE} DIRPRFX=lib/libpam/ -D_NO_LIBPAM_SO_YET all && \
|
${MAKE} MK_TESTS=no DIRPRFX=lib/libpam/ \
|
||||||
${MAKE} DIRPRFX=lib/libpam/ -D_NO_LIBPAM_SO_YET install
|
-D_NO_LIBPAM_SO_YET all && \
|
||||||
|
${MAKE} MK_TESTS=no DIRPRFX=lib/libpam/ \
|
||||||
|
-D_NO_LIBPAM_SO_YET install
|
||||||
|
|
||||||
_prereq_libs: ${_prereq_libs:S/$/__PL/}
|
_prereq_libs: ${_prereq_libs:S/$/__PL/}
|
||||||
_startup_libs: ${_startup_libs:S/$/__L/}
|
_startup_libs: ${_startup_libs:S/$/__L/}
|
||||||
@ -1672,6 +1688,7 @@ delete-old-files:
|
|||||||
# argument list will get too long. Using .for/.endfor make "loops" will make
|
# argument list will get too long. Using .for/.endfor make "loops" will make
|
||||||
# the Makefile parser segfault.
|
# the Makefile parser segfault.
|
||||||
@exec 3<&0; \
|
@exec 3<&0; \
|
||||||
|
cd ${.CURDIR}; \
|
||||||
${MAKE} -f ${.CURDIR}/Makefile.inc1 ${.MAKEFLAGS} ${.TARGET} \
|
${MAKE} -f ${.CURDIR}/Makefile.inc1 ${.MAKEFLAGS} ${.TARGET} \
|
||||||
-V OLD_FILES -V "OLD_FILES:Musr/share/*.gz:R" | xargs -n1 | \
|
-V OLD_FILES -V "OLD_FILES:Musr/share/*.gz:R" | xargs -n1 | \
|
||||||
while read file; do \
|
while read file; do \
|
||||||
@ -1694,7 +1711,8 @@ delete-old-files:
|
|||||||
|
|
||||||
check-old-files:
|
check-old-files:
|
||||||
@echo ">>> Checking for old files"
|
@echo ">>> Checking for old files"
|
||||||
@${MAKE} -f ${.CURDIR}/Makefile.inc1 ${.MAKEFLAGS} ${.TARGET} \
|
@cd ${.CURDIR}; \
|
||||||
|
${MAKE} -f ${.CURDIR}/Makefile.inc1 ${.MAKEFLAGS} ${.TARGET} \
|
||||||
-V OLD_FILES -V "OLD_FILES:Musr/share/*.gz:R" | xargs -n1 | \
|
-V OLD_FILES -V "OLD_FILES:Musr/share/*.gz:R" | xargs -n1 | \
|
||||||
while read file; do \
|
while read file; do \
|
||||||
if [ -f "${DESTDIR}/$${file}" -o -L "${DESTDIR}/$${file}" ]; then \
|
if [ -f "${DESTDIR}/$${file}" -o -L "${DESTDIR}/$${file}" ]; then \
|
||||||
@ -1715,6 +1733,7 @@ delete-old-libs:
|
|||||||
@echo ">>> Removing old libraries"
|
@echo ">>> Removing old libraries"
|
||||||
@echo "${OLD_LIBS_MESSAGE}" | fmt
|
@echo "${OLD_LIBS_MESSAGE}" | fmt
|
||||||
@exec 3<&0; \
|
@exec 3<&0; \
|
||||||
|
cd ${.CURDIR}; \
|
||||||
${MAKE} -f ${.CURDIR}/Makefile.inc1 ${.MAKEFLAGS} ${.TARGET} \
|
${MAKE} -f ${.CURDIR}/Makefile.inc1 ${.MAKEFLAGS} ${.TARGET} \
|
||||||
-V OLD_LIBS | xargs -n1 | \
|
-V OLD_LIBS | xargs -n1 | \
|
||||||
while read file; do \
|
while read file; do \
|
||||||
@ -1722,22 +1741,36 @@ delete-old-libs:
|
|||||||
chflags noschg "${DESTDIR}/$${file}" 2>/dev/null || true; \
|
chflags noschg "${DESTDIR}/$${file}" 2>/dev/null || true; \
|
||||||
rm ${RM_I} "${DESTDIR}/$${file}" <&3; \
|
rm ${RM_I} "${DESTDIR}/$${file}" <&3; \
|
||||||
fi; \
|
fi; \
|
||||||
|
for ext in debug symbols; do \
|
||||||
|
if ! [ -e "${DESTDIR}/$${file}" ] && [ -f \
|
||||||
|
"${DESTDIR}${DEBUGDIR}/$${file}.$${ext}" ]; then \
|
||||||
|
rm ${RM_I} "${DESTDIR}${DEBUGDIR}/$${file}.$${ext}" \
|
||||||
|
<&3; \
|
||||||
|
fi; \
|
||||||
|
done; \
|
||||||
done
|
done
|
||||||
@echo ">>> Old libraries removed"
|
@echo ">>> Old libraries removed"
|
||||||
|
|
||||||
check-old-libs:
|
check-old-libs:
|
||||||
@echo ">>> Checking for old libraries"
|
@echo ">>> Checking for old libraries"
|
||||||
@${MAKE} -f ${.CURDIR}/Makefile.inc1 ${.MAKEFLAGS} ${.TARGET} \
|
@cd ${.CURDIR}; \
|
||||||
|
${MAKE} -f ${.CURDIR}/Makefile.inc1 ${.MAKEFLAGS} ${.TARGET} \
|
||||||
-V OLD_LIBS | xargs -n1 | \
|
-V OLD_LIBS | xargs -n1 | \
|
||||||
while read file; do \
|
while read file; do \
|
||||||
if [ -f "${DESTDIR}/$${file}" -o -L "${DESTDIR}/$${file}" ]; then \
|
if [ -f "${DESTDIR}/$${file}" -o -L "${DESTDIR}/$${file}" ]; then \
|
||||||
echo "${DESTDIR}/$${file}"; \
|
echo "${DESTDIR}/$${file}"; \
|
||||||
fi; \
|
fi; \
|
||||||
|
for ext in debug symbols; do \
|
||||||
|
if [ -f "${DESTDIR}${DEBUGDIR}/$${file}.$${ext}" ]; then \
|
||||||
|
echo "${DESTDIR}${DEBUGDIR}/$${file}.$${ext}"; \
|
||||||
|
fi; \
|
||||||
|
done; \
|
||||||
done
|
done
|
||||||
|
|
||||||
delete-old-dirs:
|
delete-old-dirs:
|
||||||
@echo ">>> Removing old directories"
|
@echo ">>> Removing old directories"
|
||||||
@${MAKE} -f ${.CURDIR}/Makefile.inc1 ${.MAKEFLAGS} ${.TARGET} \
|
@cd ${.CURDIR}; \
|
||||||
|
${MAKE} -f ${.CURDIR}/Makefile.inc1 ${.MAKEFLAGS} ${.TARGET} \
|
||||||
-V OLD_DIRS | xargs -n1 | sort -r | \
|
-V OLD_DIRS | xargs -n1 | sort -r | \
|
||||||
while read dir; do \
|
while read dir; do \
|
||||||
if [ -d "${DESTDIR}/$${dir}" ]; then \
|
if [ -d "${DESTDIR}/$${dir}" ]; then \
|
||||||
@ -1750,7 +1783,8 @@ delete-old-dirs:
|
|||||||
|
|
||||||
check-old-dirs:
|
check-old-dirs:
|
||||||
@echo ">>> Checking for old directories"
|
@echo ">>> Checking for old directories"
|
||||||
@${MAKE} -f ${.CURDIR}/Makefile.inc1 ${.MAKEFLAGS} ${.TARGET} \
|
@cd ${.CURDIR}; \
|
||||||
|
${MAKE} -f ${.CURDIR}/Makefile.inc1 ${.MAKEFLAGS} ${.TARGET} \
|
||||||
-V OLD_DIRS | xargs -n1 | \
|
-V OLD_DIRS | xargs -n1 | \
|
||||||
while read dir; do \
|
while read dir; do \
|
||||||
if [ -d "${DESTDIR}/$${dir}" ]; then \
|
if [ -d "${DESTDIR}/$${dir}" ]; then \
|
||||||
@ -1799,7 +1833,7 @@ builddtb:
|
|||||||
echo "ERROR: FDT_DTS_FILE must be specified!"; \
|
echo "ERROR: FDT_DTS_FILE must be specified!"; \
|
||||||
exit 1; \
|
exit 1; \
|
||||||
fi; \
|
fi; \
|
||||||
if [ ! -f ${.CURDIR}/sys/boot/fdt/dts/${FDT_DTS_FILE} ]; then \
|
if [ ! -f ${.CURDIR}/sys/boot/fdt/dts/${MACHINE}/${FDT_DTS_FILE} ]; then \
|
||||||
echo "ERROR: Specified DTS file (${FDT_DTS_FILE}) does not \
|
echo "ERROR: Specified DTS file (${FDT_DTS_FILE}) does not \
|
||||||
exist!"; \
|
exist!"; \
|
||||||
exit 1; \
|
exit 1; \
|
||||||
@ -1809,9 +1843,9 @@ builddtb:
|
|||||||
directory"; \
|
directory"; \
|
||||||
fi
|
fi
|
||||||
@PATH=${TMPPATH} \
|
@PATH=${TMPPATH} \
|
||||||
dtc -O dtb -o \
|
${.CURDIR}/sys/tools/fdt/make_dtb.sh ${.CURDIR}/sys \
|
||||||
${DTBOUTPUTPATH}/`echo ${FDT_DTS_FILE} | cut -d. -f1`.dtb -b 0 \
|
${FDT_DTS_FILE} \
|
||||||
-p 1024 ${.CURDIR}/sys/boot/fdt/dts/${FDT_DTS_FILE}
|
${DTBOUTPUTPATH}/`basename ${FDT_DTS_FILE} .dts`
|
||||||
|
|
||||||
###############
|
###############
|
||||||
|
|
||||||
@ -1823,28 +1857,34 @@ XDEV_CPUTYPE?=${CPUTYPE}
|
|||||||
XDEV_CPUTYPE?=${TARGET_CPUTYPE}
|
XDEV_CPUTYPE?=${TARGET_CPUTYPE}
|
||||||
.endif
|
.endif
|
||||||
|
|
||||||
NOFUN=-DNO_FSCHG -DWITHOUT_HTML -DWITHOUT_INFO -DNO_LINT \
|
NOFUN=-DNO_FSCHG MK_HTML=no MK_INFO=no -DNO_LINT \
|
||||||
-DWITHOUT_MAN -DWITHOUT_NLS -DNO_PROFILE \
|
MK_MAN=no MK_NLS=no MK_PROFILE=no \
|
||||||
-DWITHOUT_KERBEROS -DWITHOUT_RESCUE -DNO_WARNS \
|
MK_KERBEROS=no MK_RESCUE=no MK_TESTS=no -DNO_WARNS \
|
||||||
TARGET=${XDEV} TARGET_ARCH=${XDEV_ARCH} \
|
TARGET=${XDEV} TARGET_ARCH=${XDEV_ARCH} \
|
||||||
CPUTYPE=${XDEV_CPUTYPE}
|
CPUTYPE=${XDEV_CPUTYPE}
|
||||||
|
|
||||||
XDDIR=${XDEV_ARCH}-freebsd
|
XDDIR=${XDEV_ARCH}-freebsd
|
||||||
XDTP=/usr/${XDDIR}
|
XDTP?=/usr/${XDDIR}
|
||||||
|
.if ${XDTP:N/*}
|
||||||
|
.error XDTP variable should be an absolute path
|
||||||
|
.endif
|
||||||
|
|
||||||
CDBENV=MAKEOBJDIRPREFIX=${MAKEOBJDIRPREFIX}/${XDDIR} \
|
CDBENV=MAKEOBJDIRPREFIX=${MAKEOBJDIRPREFIX}/${XDDIR} \
|
||||||
INSTALL="sh ${.CURDIR}/tools/install.sh"
|
INSTALL="sh ${.CURDIR}/tools/install.sh"
|
||||||
CDENV= ${CDBENV} \
|
CDENV= ${CDBENV} \
|
||||||
_SHLIBDIRPREFIX=${XDDESTDIR} \
|
_SHLIBDIRPREFIX=${XDDESTDIR} \
|
||||||
TOOLS_PREFIX=${XDDESTDIR}
|
TOOLS_PREFIX=${XDTP}
|
||||||
CD2CFLAGS=-isystem ${XDDESTDIR}/usr/include -L${XDDESTDIR}/usr/lib \
|
CD2CFLAGS=-isystem ${XDDESTDIR}/usr/include -L${XDDESTDIR}/usr/lib \
|
||||||
-B${XDDESTDIR}/usr/lib
|
--sysroot=${XDDESTDIR}/ -B${XDDESTDIR}/usr/libexec \
|
||||||
CD2ENV=${CDENV} CC="${CC} ${CD2CFLAGS}" \
|
-B${XDDESTDIR}/usr/bin -B${XDDESTDIR}/usr/lib
|
||||||
|
CD2ENV=${CDENV} CC="${CC} ${CD2CFLAGS}" CXX="${CXX} ${CD2CFLAGS}" \
|
||||||
|
CPP="${CPP} ${CD2CFLAGS}" \
|
||||||
MACHINE=${XDEV} MACHINE_ARCH=${XDEV_ARCH}
|
MACHINE=${XDEV} MACHINE_ARCH=${XDEV_ARCH}
|
||||||
|
|
||||||
CDTMP= ${MAKEOBJDIRPREFIX}/${XDDIR}/${.CURDIR}/tmp
|
CDTMP= ${MAKEOBJDIRPREFIX}/${XDDIR}/${.CURDIR}/tmp
|
||||||
CDMAKE=${CDENV} PATH=${CDTMP}/usr/bin:${PATH} ${MAKE} ${NOFUN}
|
CDMAKE=${CDENV} PATH=${CDTMP}/usr/bin:${PATH} ${MAKE} ${NOFUN}
|
||||||
CD2MAKE=${CD2ENV} PATH=${CDTMP}/usr/bin:${XDTP}/usr/bin:${PATH} ${MAKE} ${NOFUN}
|
CD2MAKE=${CD2ENV} PATH=${CDTMP}/usr/bin:${XDDESTDIR}/usr/bin:${PATH} ${MAKE} ${NOFUN}
|
||||||
XDDESTDIR=${DESTDIR}${XDTP}
|
XDDESTDIR=${DESTDIR}/${XDTP}
|
||||||
.if !defined(OSREL)
|
.if !defined(OSREL)
|
||||||
OSREL!= uname -r | sed -e 's/[-(].*//'
|
OSREL!= uname -r | sed -e 's/[-(].*//'
|
||||||
.endif
|
.endif
|
||||||
@ -1877,11 +1917,11 @@ _xb-build-tools:
|
|||||||
|
|
||||||
_xb-cross-tools:
|
_xb-cross-tools:
|
||||||
.for _tool in \
|
.for _tool in \
|
||||||
gnu/usr.bin/binutils \
|
${_binutils} \
|
||||||
gnu/usr.bin/cc \
|
|
||||||
usr.bin/ar \
|
usr.bin/ar \
|
||||||
${_clang_libs} \
|
${_clang_libs} \
|
||||||
${_clang}
|
${_clang} \
|
||||||
|
${_cc}
|
||||||
${_+_}@${ECHODIR} "===> xdev ${_tool} (obj,depend,all)"; \
|
${_+_}@${ECHODIR} "===> xdev ${_tool} (obj,depend,all)"; \
|
||||||
cd ${.CURDIR}/${_tool} && \
|
cd ${.CURDIR}/${_tool} && \
|
||||||
${CDMAKE} DIRPRFX=${_tool}/ obj && \
|
${CDMAKE} DIRPRFX=${_tool}/ obj && \
|
||||||
@ -1905,10 +1945,11 @@ xdev-install: xdev-build _xi-mtree _xi-cross-tools _xi-includes _xi-libraries _x
|
|||||||
_xi-cross-tools:
|
_xi-cross-tools:
|
||||||
@echo "_xi-cross-tools"
|
@echo "_xi-cross-tools"
|
||||||
.for _tool in \
|
.for _tool in \
|
||||||
gnu/usr.bin/binutils \
|
${_binutils} \
|
||||||
gnu/usr.bin/cc \
|
|
||||||
usr.bin/ar \
|
usr.bin/ar \
|
||||||
${_clang}
|
${_clang_libs} \
|
||||||
|
${_clang} \
|
||||||
|
${_cc}
|
||||||
${_+_}@${ECHODIR} "===> xdev ${_tool} (install)"; \
|
${_+_}@${ECHODIR} "===> xdev ${_tool} (install)"; \
|
||||||
cd ${.CURDIR}/${_tool}; \
|
cd ${.CURDIR}/${_tool}; \
|
||||||
${CDMAKE} DIRPRFX=${_tool}/ install DESTDIR=${XDDESTDIR}
|
${CDMAKE} DIRPRFX=${_tool}/ install DESTDIR=${XDDESTDIR}
|
||||||
@ -1924,6 +1965,7 @@ _xi-libraries:
|
|||||||
|
|
||||||
_xi-links:
|
_xi-links:
|
||||||
${_+_}cd ${XDDESTDIR}/usr/bin; \
|
${_+_}cd ${XDDESTDIR}/usr/bin; \
|
||||||
|
mkdir -p ../../../../usr/bin; \
|
||||||
for i in *; do \
|
for i in *; do \
|
||||||
ln -sf ../../${XDTP}/usr/bin/$$i \
|
ln -sf ../../${XDTP}/usr/bin/$$i \
|
||||||
../../../../usr/bin/${XDDIR}-$$i; \
|
../../../../usr/bin/${XDDIR}-$$i; \
|
||||||
@ -1934,5 +1976,3 @@ _xi-links:
|
|||||||
xdev xdev-build xdev-install:
|
xdev xdev-build xdev-install:
|
||||||
@echo "*** Error: Both XDEV and XDEV_ARCH must be defined for \"${.TARGET}\" target"
|
@echo "*** Error: Both XDEV and XDEV_ARCH must be defined for \"${.TARGET}\" target"
|
||||||
.endif
|
.endif
|
||||||
|
|
||||||
buildkernel ${WMAKE_TGTS} ${.ALLTARGETS:M_*}: .MAKE
|
|
||||||
|
@ -1,5 +1,11 @@
|
|||||||
# $FreeBSD$
|
# $FreeBSD$
|
||||||
|
|
||||||
|
.include <bsd.own.mk>
|
||||||
|
|
||||||
SUBDIR= lib sbin usr.bin usr.sbin
|
SUBDIR= lib sbin usr.bin usr.sbin
|
||||||
|
|
||||||
|
.if ${MK_TESTS} != "no"
|
||||||
|
SUBDIR+=tests
|
||||||
|
.endif
|
||||||
|
|
||||||
.include <bsd.subdir.mk>
|
.include <bsd.subdir.mk>
|
||||||
|
@ -24,8 +24,6 @@
|
|||||||
* Use is subject to license terms.
|
* Use is subject to license terms.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma ident "%Z%%M% %I% %E% SMI"
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ASSERTION:
|
* ASSERTION:
|
||||||
* Checks that setting "bufresize" to "auto" will cause buffer
|
* Checks that setting "bufresize" to "auto" will cause buffer
|
||||||
@ -34,14 +32,8 @@
|
|||||||
* SECTION: Buffers and Buffering/Buffer Resizing Policy;
|
* SECTION: Buffers and Buffering/Buffer Resizing Policy;
|
||||||
* Options and Tunables/bufsize;
|
* Options and Tunables/bufsize;
|
||||||
* Options and Tunables/bufresize
|
* Options and Tunables/bufresize
|
||||||
*
|
|
||||||
* NOTES:
|
|
||||||
* We use the undocumented "preallocate" option to make sure dtrace(1M)
|
|
||||||
* has enough space in its heap to allocate a buffer as large as the
|
|
||||||
* kernel's trace buffer.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma D option preallocate=100t
|
|
||||||
#pragma D option bufresize=auto
|
#pragma D option bufresize=auto
|
||||||
#pragma D option bufsize=100t
|
#pragma D option bufsize=100t
|
||||||
|
|
||||||
|
@ -24,8 +24,6 @@
|
|||||||
* Use is subject to license terms.
|
* Use is subject to license terms.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma ident "%Z%%M% %I% %E% SMI"
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ASSERTION:
|
* ASSERTION:
|
||||||
* Checks that setting "bufresize" to "auto" will cause buffer
|
* Checks that setting "bufresize" to "auto" will cause buffer
|
||||||
@ -34,14 +32,8 @@
|
|||||||
* SECTION: Buffers and Buffering/Buffer Resizing Policy;
|
* SECTION: Buffers and Buffering/Buffer Resizing Policy;
|
||||||
* Options and Tunables/aggsize;
|
* Options and Tunables/aggsize;
|
||||||
* Options and Tunables/bufresize
|
* Options and Tunables/bufresize
|
||||||
*
|
|
||||||
* NOTES:
|
|
||||||
* We use the undocumented "preallocate" option to make sure dtrace(1M)
|
|
||||||
* has enough space in its heap to allocate a buffer as large as the
|
|
||||||
* kernel's trace buffer.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma D option preallocate=100t
|
|
||||||
#pragma D option bufresize=auto
|
#pragma D option bufresize=auto
|
||||||
#pragma D option aggsize=100t
|
#pragma D option aggsize=100t
|
||||||
|
|
||||||
|
@ -0,0 +1,97 @@
|
|||||||
|
#
|
||||||
|
# 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 (c) 2012, Joyent, Inc. All rights reserved.
|
||||||
|
#
|
||||||
|
|
||||||
|
let j=8
|
||||||
|
|
||||||
|
enable()
|
||||||
|
{
|
||||||
|
prog=/var/tmp/dtest.$$.d
|
||||||
|
err=/var/tmp/dtest.$$.err
|
||||||
|
|
||||||
|
nawk -v nprobes=$1 'BEGIN { \
|
||||||
|
for (i = 0; i < nprobes - 1; i++) { \
|
||||||
|
printf("dtrace:::BEGIN,\n"); \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
printf("dtrace:::BEGIN { exit(0); }\n"); \
|
||||||
|
}' /dev/null > $prog
|
||||||
|
|
||||||
|
dtrace -qs $prog > /dev/null 2> $err
|
||||||
|
|
||||||
|
if [[ "$?" -eq 0 ]]; then
|
||||||
|
return 0
|
||||||
|
else
|
||||||
|
if ! grep "DIF program exceeds maximum program size" $err \
|
||||||
|
1> /dev/null 2>&1 ; then
|
||||||
|
echo "failed to enable $prog: `cat $err`"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
#
|
||||||
|
# First, establish an upper bound
|
||||||
|
#
|
||||||
|
let upper=1
|
||||||
|
|
||||||
|
while enable $upper ; do
|
||||||
|
let lower=upper
|
||||||
|
let upper=upper+upper
|
||||||
|
echo success at $lower, raised to $upper
|
||||||
|
done
|
||||||
|
|
||||||
|
#
|
||||||
|
# Now search for the highest value that can be enabled
|
||||||
|
#
|
||||||
|
while [[ "$lower" -lt "$upper" ]]; do
|
||||||
|
let guess=$(((lower + upper) / 2))
|
||||||
|
echo "lower is $lower; upper is $upper; guess is $guess\c"
|
||||||
|
|
||||||
|
if enable $guess ; then
|
||||||
|
if [[ $((upper - lower)) -le 2 ]]; then
|
||||||
|
let upper=guess
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo " (success)"
|
||||||
|
let lower=guess
|
||||||
|
else
|
||||||
|
echo " (failure)"
|
||||||
|
let upper=guess
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
let expected=10000
|
||||||
|
|
||||||
|
if [[ "$lower" -lt "$expected" ]]; then
|
||||||
|
echo "expected support for enablings of at least $expected probes; \c"
|
||||||
|
echo "found $lower"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "maximum supported enabled probes found to be $lower"
|
||||||
|
exit 0
|
||||||
|
|
@ -44,7 +44,7 @@ BEGIN
|
|||||||
|
|
||||||
printf("\n");
|
printf("\n");
|
||||||
|
|
||||||
printf("%%a = %a\n", &`kmem_alloc);
|
printf("%%a = %a\n", &`malloc);
|
||||||
printf("%%c = %c\n", i);
|
printf("%%c = %c\n", i);
|
||||||
printf("%%d = %d\n", i);
|
printf("%%d = %d\n", i);
|
||||||
printf("%%hd = %hd\n", (short)i);
|
printf("%%hd = %hd\n", (short)i);
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
|
|
||||||
%a = genunix`kmem_alloc
|
%a = kernel`malloc
|
||||||
%c = a
|
%c = a
|
||||||
%d = 97
|
%d = 97
|
||||||
%hd = 97
|
%hd = 97
|
||||||
|
@ -36,6 +36,6 @@
|
|||||||
|
|
||||||
BEGIN
|
BEGIN
|
||||||
{
|
{
|
||||||
printf("sysname = %s", `utsname.sysname);
|
printf("sysname = %s", `ostype);
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
@ -1 +1 @@
|
|||||||
sysname = SunOS
|
sysname = FreeBSD
|
||||||
|
@ -38,6 +38,6 @@
|
|||||||
|
|
||||||
BEGIN
|
BEGIN
|
||||||
{
|
{
|
||||||
printf("symbol = %a", &`kmem_alloc);
|
printf("symbol = %a", &`malloc);
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
@ -1 +1 @@
|
|||||||
symbol = kernel`kmem_alloc
|
symbol = kernel`malloc
|
||||||
|
@ -64,7 +64,7 @@ child=$!
|
|||||||
# ksh doing work. (This actually goes one step further and assumes that we
|
# ksh doing work. (This actually goes one step further and assumes that we
|
||||||
# catch some non-static function in ksh.)
|
# catch some non-static function in ksh.)
|
||||||
#
|
#
|
||||||
script | tee /dev/fd/2 | grep 'ksh`[a-zA-Z_]' > /dev/null
|
script | tee /dev/fd/2 | egrep 'ksh(93)?`[a-zA-Z_]' > /dev/null
|
||||||
status=$?
|
status=$?
|
||||||
|
|
||||||
kill $child
|
kill $child
|
||||||
|
@ -62,7 +62,7 @@ child=$!
|
|||||||
#
|
#
|
||||||
# The only thing we can be sure of here is that ksh is doing some work.
|
# The only thing we can be sure of here is that ksh is doing some work.
|
||||||
#
|
#
|
||||||
script | tee /dev/fd/2 | grep -w ksh > /dev/null
|
script | tee /dev/fd/2 | egrep -w 'ksh(93)?' > /dev/null
|
||||||
status=$?
|
status=$?
|
||||||
|
|
||||||
kill $child
|
kill $child
|
||||||
|
@ -63,7 +63,7 @@ child=$!
|
|||||||
# This test is essentially the same as that in the ufunc test; see that
|
# This test is essentially the same as that in the ufunc test; see that
|
||||||
# test for the rationale.
|
# test for the rationale.
|
||||||
#
|
#
|
||||||
script | tee /dev/fd/2 | grep 'ksh`[a-zA-Z_]' > /dev/null
|
script | tee /dev/fd/2 | egrep 'ksh(93)?`[a-zA-Z_]' > /dev/null
|
||||||
status=$?
|
status=$?
|
||||||
|
|
||||||
kill $child
|
kill $child
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -179,8 +179,19 @@ symtab_init(void)
|
|||||||
size_t sz;
|
size_t sz;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(__FreeBSD__)
|
||||||
|
if ((fd = open("/dev/ksyms", O_RDONLY)) == -1) {
|
||||||
|
if (errno == ENOENT && modfind("ksyms") == -1) {
|
||||||
|
kldload("ksyms");
|
||||||
|
fd = open("/dev/ksyms", O_RDONLY);
|
||||||
|
}
|
||||||
|
if (fd == -1)
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
#else
|
||||||
if ((fd = open("/dev/ksyms", O_RDONLY)) == -1)
|
if ((fd = open("/dev/ksyms", O_RDONLY)) == -1)
|
||||||
return (-1);
|
return (-1);
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(sun)
|
#if defined(sun)
|
||||||
(void) elf_version(EV_CURRENT);
|
(void) elf_version(EV_CURRENT);
|
||||||
|
@ -778,7 +778,8 @@ main(int argc, char **argv)
|
|||||||
#endif
|
#endif
|
||||||
int err;
|
int err;
|
||||||
int opt_C = 0, opt_H = 0, opt_p = 0, opt_v = 0;
|
int opt_C = 0, opt_H = 0, opt_p = 0, opt_v = 0;
|
||||||
char c, *p, *end;
|
int c;
|
||||||
|
char *p, *end;
|
||||||
struct sigaction act;
|
struct sigaction act;
|
||||||
int done = 0;
|
int done = 0;
|
||||||
|
|
||||||
|
@ -14,11 +14,12 @@
|
|||||||
.\"
|
.\"
|
||||||
.\" Copyright 2012, Richard Lowe.
|
.\" Copyright 2012, Richard Lowe.
|
||||||
.\" Copyright (c) 2012, Marcelo Araujo <araujo@FreeBSD.org>.
|
.\" Copyright (c) 2012, Marcelo Araujo <araujo@FreeBSD.org>.
|
||||||
|
.\" Copyright (c) 2012 by Delphix. All rights reserved.
|
||||||
.\" All Rights Reserved.
|
.\" All Rights Reserved.
|
||||||
.\"
|
.\"
|
||||||
.\" $FreeBSD$
|
.\" $FreeBSD$
|
||||||
.\"
|
.\"
|
||||||
.Dd May 10, 2012
|
.Dd March 20, 2014
|
||||||
.Dt ZDB 8
|
.Dt ZDB 8
|
||||||
.Os
|
.Os
|
||||||
.Sh NAME
|
.Sh NAME
|
||||||
@ -29,27 +30,35 @@
|
|||||||
.Op Fl CumdibcsDvhLXFPA
|
.Op Fl CumdibcsDvhLXFPA
|
||||||
.Op Fl e Op Fl p Ar path...
|
.Op Fl e Op Fl p Ar path...
|
||||||
.Op Fl t Ar txg
|
.Op Fl t Ar txg
|
||||||
|
.Op Fl U Ar cache
|
||||||
|
.Op Fl M Ar inflight I/Os
|
||||||
.Ar poolname
|
.Ar poolname
|
||||||
.Op Ar object ...
|
.Op Ar object ...
|
||||||
.Nm
|
.Nm
|
||||||
.Op Fl divPA
|
.Op Fl divPA
|
||||||
.Op Fl e Op Fl p Ar path...
|
.Op Fl e Op Fl p Ar path...
|
||||||
|
.Op Fl U Ar cache
|
||||||
.Ar dataset
|
.Ar dataset
|
||||||
.Op Ar object ...
|
.Op Ar object ...
|
||||||
.Nm
|
.Nm
|
||||||
.Fl m Op Fl LXFPA
|
.Fl m Op Fl LXFPA
|
||||||
.Op Fl t Ar txg
|
.Op Fl t Ar txg
|
||||||
.Op Fl e Op Fl p Ar path...
|
.Op Fl e Op Fl p Ar path...
|
||||||
|
.Op Fl U Ar cache
|
||||||
.Ar poolname
|
.Ar poolname
|
||||||
.Nm
|
.Nm
|
||||||
.Fl R Op Fl A
|
.Fl R Op Fl A
|
||||||
.Op Fl e Op Fl p Ar path...
|
.Op Fl e Op Fl p Ar path...
|
||||||
|
.Op Fl U Ar cache
|
||||||
|
.Ar poolname
|
||||||
.Ar poolname
|
.Ar poolname
|
||||||
.Ar vdev Ns : Ns Ar offset Ns : Ns Ar size Ns Op Ns : Ns Ar flags
|
.Ar vdev Ns : Ns Ar offset Ns : Ns Ar size Ns Op Ns : Ns Ar flags
|
||||||
.Nm
|
.Nm
|
||||||
.Fl S
|
.Fl S
|
||||||
.Op Fl AP
|
.Op Fl AP
|
||||||
.Op Fl e Op Fl p Ar path...
|
.Op Fl e Op Fl p Ar path...
|
||||||
|
.Op Fl U Ar cache
|
||||||
|
.Ar poolname
|
||||||
.Ar poolname
|
.Ar poolname
|
||||||
.Nm
|
.Nm
|
||||||
.Fl l
|
.Fl l
|
||||||
@ -118,6 +127,12 @@ compression ratio (compress), inflation due to the zfs copies property
|
|||||||
If specified twice, display a histogram of deduplication statistics, showing
|
If specified twice, display a histogram of deduplication statistics, showing
|
||||||
the allocated (physically present on disk) and referenced (logically
|
the allocated (physically present on disk) and referenced (logically
|
||||||
referenced in the pool) block counts and sizes by reference count.
|
referenced in the pool) block counts and sizes by reference count.
|
||||||
|
.Pp
|
||||||
|
If specified a third time, display the statistics independently for each deduplication table.
|
||||||
|
.Pp
|
||||||
|
If specified a fourth time, dump the contents of the deduplication tables describing duplicate blocks.
|
||||||
|
.Pp
|
||||||
|
If specified a fifth time, also dump the contents of the deduplication tables describing unique blocks.
|
||||||
.It Fl h
|
.It Fl h
|
||||||
Display pool history similar to
|
Display pool history similar to
|
||||||
.Cm zpool history ,
|
.Cm zpool history ,
|
||||||
@ -205,6 +220,11 @@ flag specifies the path under which devices are to be searched.
|
|||||||
.It Fl F
|
.It Fl F
|
||||||
Attempt to make an unreadable pool readable by trying progressively older
|
Attempt to make an unreadable pool readable by trying progressively older
|
||||||
transactions.
|
transactions.
|
||||||
|
.It Fl M Ar inflight I/Os
|
||||||
|
Limit the number of outstanding checksum I/Os to the specified value.
|
||||||
|
The default value is 200. This option affects the performance of the
|
||||||
|
.Fl c
|
||||||
|
option.
|
||||||
.It Fl P
|
.It Fl P
|
||||||
Print numbers in an unscaled form more amenable to parsing, eg. 1000000 rather
|
Print numbers in an unscaled form more amenable to parsing, eg. 1000000 rather
|
||||||
than 1M.
|
than 1M.
|
||||||
@ -218,9 +238,7 @@ options for a means to see the available uberblocks and their associated
|
|||||||
transaction numbers.
|
transaction numbers.
|
||||||
.It Fl U Ar cachefile
|
.It Fl U Ar cachefile
|
||||||
Use a cache file other than
|
Use a cache file other than
|
||||||
.Pa /etc/zfs/zpool.cache .
|
.Pa /boot/zfs/zpool.cache .
|
||||||
This option is only valid with
|
|
||||||
.Fl C
|
|
||||||
.It Fl v
|
.It Fl v
|
||||||
Enable verbosity.
|
Enable verbosity.
|
||||||
Specify multiple times for increased verbosity.
|
Specify multiple times for increased verbosity.
|
||||||
|
@ -21,7 +21,7 @@
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||||
* Copyright (c) 2013 by Delphix. All rights reserved.
|
* Copyright (c) 2012, 2014 by Delphix. All rights reserved.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
@ -89,6 +89,7 @@ extern void dump_intent_log(zilog_t *);
|
|||||||
uint64_t *zopt_object = NULL;
|
uint64_t *zopt_object = NULL;
|
||||||
int zopt_objects = 0;
|
int zopt_objects = 0;
|
||||||
libzfs_handle_t *g_zfs;
|
libzfs_handle_t *g_zfs;
|
||||||
|
uint64_t max_inflight = 200;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* These libumem hooks provide a reasonable set of defaults for the allocator's
|
* These libumem hooks provide a reasonable set of defaults for the allocator's
|
||||||
@ -111,13 +112,14 @@ usage(void)
|
|||||||
{
|
{
|
||||||
(void) fprintf(stderr,
|
(void) fprintf(stderr,
|
||||||
"Usage: %s [-CumdibcsDvhLXFPA] [-t txg] [-e [-p path...]] "
|
"Usage: %s [-CumdibcsDvhLXFPA] [-t txg] [-e [-p path...]] "
|
||||||
"poolname [object...]\n"
|
"[-U config] [-M inflight I/Os] poolname [object...]\n"
|
||||||
" %s [-divPA] [-e -p path...] dataset [object...]\n"
|
" %s [-divPA] [-e -p path...] [-U config] dataset "
|
||||||
" %s -m [-LXFPA] [-t txg] [-e [-p path...]]"
|
"[object...]\n"
|
||||||
|
" %s -m [-LXFPA] [-t txg] [-e [-p path...]] [-U config] "
|
||||||
"poolname [vdev [metaslab...]]\n"
|
"poolname [vdev [metaslab...]]\n"
|
||||||
" %s -R [-A] [-e [-p path...]] poolname "
|
" %s -R [-A] [-e [-p path...]] poolname "
|
||||||
"vdev:offset:size[:flags]\n"
|
"vdev:offset:size[:flags]\n"
|
||||||
" %s -S [-PA] [-e [-p path...]] poolname\n"
|
" %s -S [-PA] [-e [-p path...]] [-U config] poolname\n"
|
||||||
" %s -l [-uA] device\n"
|
" %s -l [-uA] device\n"
|
||||||
" %s -C [-A] [-U config]\n\n",
|
" %s -C [-A] [-U config]\n\n",
|
||||||
cmdname, cmdname, cmdname, cmdname, cmdname, cmdname, cmdname);
|
cmdname, cmdname, cmdname, cmdname, cmdname, cmdname, cmdname);
|
||||||
@ -164,6 +166,8 @@ usage(void)
|
|||||||
(void) fprintf(stderr, " -P print numbers in parseable form\n");
|
(void) fprintf(stderr, " -P print numbers in parseable form\n");
|
||||||
(void) fprintf(stderr, " -t <txg> -- highest txg to use when "
|
(void) fprintf(stderr, " -t <txg> -- highest txg to use when "
|
||||||
"searching for uberblocks\n");
|
"searching for uberblocks\n");
|
||||||
|
(void) fprintf(stderr, " -M <number of inflight I/Os> -- "
|
||||||
|
"specify the maximum number of checksumming I/Os [default is 200]");
|
||||||
(void) fprintf(stderr, "Specify an option more than once (e.g. -bb) "
|
(void) fprintf(stderr, "Specify an option more than once (e.g. -bb) "
|
||||||
"to make only that option verbose\n");
|
"to make only that option verbose\n");
|
||||||
(void) fprintf(stderr, "Default is to dump everything non-verbosely\n");
|
(void) fprintf(stderr, "Default is to dump everything non-verbosely\n");
|
||||||
@ -242,7 +246,7 @@ const char histo_stars[] = "****************************************";
|
|||||||
const int histo_width = sizeof (histo_stars) - 1;
|
const int histo_width = sizeof (histo_stars) - 1;
|
||||||
|
|
||||||
static void
|
static void
|
||||||
dump_histogram(const uint64_t *histo, int size)
|
dump_histogram(const uint64_t *histo, int size, int offset)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
int minidx = size - 1;
|
int minidx = size - 1;
|
||||||
@ -263,7 +267,7 @@ dump_histogram(const uint64_t *histo, int size)
|
|||||||
|
|
||||||
for (i = minidx; i <= maxidx; i++) {
|
for (i = minidx; i <= maxidx; i++) {
|
||||||
(void) printf("\t\t\t%3u: %6llu %s\n",
|
(void) printf("\t\t\t%3u: %6llu %s\n",
|
||||||
i, (u_longlong_t)histo[i],
|
i + offset, (u_longlong_t)histo[i],
|
||||||
&histo_stars[(max - histo[i]) * histo_width / max]);
|
&histo_stars[(max - histo[i]) * histo_width / max]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -316,19 +320,19 @@ dump_zap_stats(objset_t *os, uint64_t object)
|
|||||||
(u_longlong_t)zs.zs_salt);
|
(u_longlong_t)zs.zs_salt);
|
||||||
|
|
||||||
(void) printf("\t\tLeafs with 2^n pointers:\n");
|
(void) printf("\t\tLeafs with 2^n pointers:\n");
|
||||||
dump_histogram(zs.zs_leafs_with_2n_pointers, ZAP_HISTOGRAM_SIZE);
|
dump_histogram(zs.zs_leafs_with_2n_pointers, ZAP_HISTOGRAM_SIZE, 0);
|
||||||
|
|
||||||
(void) printf("\t\tBlocks with n*5 entries:\n");
|
(void) printf("\t\tBlocks with n*5 entries:\n");
|
||||||
dump_histogram(zs.zs_blocks_with_n5_entries, ZAP_HISTOGRAM_SIZE);
|
dump_histogram(zs.zs_blocks_with_n5_entries, ZAP_HISTOGRAM_SIZE, 0);
|
||||||
|
|
||||||
(void) printf("\t\tBlocks n/10 full:\n");
|
(void) printf("\t\tBlocks n/10 full:\n");
|
||||||
dump_histogram(zs.zs_blocks_n_tenths_full, ZAP_HISTOGRAM_SIZE);
|
dump_histogram(zs.zs_blocks_n_tenths_full, ZAP_HISTOGRAM_SIZE, 0);
|
||||||
|
|
||||||
(void) printf("\t\tEntries with n chunks:\n");
|
(void) printf("\t\tEntries with n chunks:\n");
|
||||||
dump_histogram(zs.zs_entries_using_n_chunks, ZAP_HISTOGRAM_SIZE);
|
dump_histogram(zs.zs_entries_using_n_chunks, ZAP_HISTOGRAM_SIZE, 0);
|
||||||
|
|
||||||
(void) printf("\t\tBuckets with n entries:\n");
|
(void) printf("\t\tBuckets with n entries:\n");
|
||||||
dump_histogram(zs.zs_buckets_with_n_entries, ZAP_HISTOGRAM_SIZE);
|
dump_histogram(zs.zs_buckets_with_n_entries, ZAP_HISTOGRAM_SIZE, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*ARGSUSED*/
|
/*ARGSUSED*/
|
||||||
@ -517,26 +521,89 @@ dump_zpldir(objset_t *os, uint64_t object, void *data, size_t size)
|
|||||||
zap_cursor_fini(&zc);
|
zap_cursor_fini(&zc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
get_dtl_refcount(vdev_t *vd)
|
||||||
|
{
|
||||||
|
int refcount = 0;
|
||||||
|
|
||||||
|
if (vd->vdev_ops->vdev_op_leaf) {
|
||||||
|
space_map_t *sm = vd->vdev_dtl_sm;
|
||||||
|
|
||||||
|
if (sm != NULL &&
|
||||||
|
sm->sm_dbuf->db_size == sizeof (space_map_phys_t))
|
||||||
|
return (1);
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int c = 0; c < vd->vdev_children; c++)
|
||||||
|
refcount += get_dtl_refcount(vd->vdev_child[c]);
|
||||||
|
return (refcount);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
get_metaslab_refcount(vdev_t *vd)
|
||||||
|
{
|
||||||
|
int refcount = 0;
|
||||||
|
|
||||||
|
if (vd->vdev_top == vd) {
|
||||||
|
for (int m = 0; m < vd->vdev_ms_count; m++) {
|
||||||
|
space_map_t *sm = vd->vdev_ms[m]->ms_sm;
|
||||||
|
|
||||||
|
if (sm != NULL &&
|
||||||
|
sm->sm_dbuf->db_size == sizeof (space_map_phys_t))
|
||||||
|
refcount++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (int c = 0; c < vd->vdev_children; c++)
|
||||||
|
refcount += get_metaslab_refcount(vd->vdev_child[c]);
|
||||||
|
|
||||||
|
return (refcount);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
verify_spacemap_refcounts(spa_t *spa)
|
||||||
|
{
|
||||||
|
uint64_t expected_refcount = 0;
|
||||||
|
uint64_t actual_refcount;
|
||||||
|
|
||||||
|
(void) feature_get_refcount(spa,
|
||||||
|
&spa_feature_table[SPA_FEATURE_SPACEMAP_HISTOGRAM],
|
||||||
|
&expected_refcount);
|
||||||
|
actual_refcount = get_dtl_refcount(spa->spa_root_vdev);
|
||||||
|
actual_refcount += get_metaslab_refcount(spa->spa_root_vdev);
|
||||||
|
|
||||||
|
if (expected_refcount != actual_refcount) {
|
||||||
|
(void) printf("space map refcount mismatch: expected %lld != "
|
||||||
|
"actual %lld\n",
|
||||||
|
(longlong_t)expected_refcount,
|
||||||
|
(longlong_t)actual_refcount);
|
||||||
|
return (2);
|
||||||
|
}
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
dump_spacemap(objset_t *os, space_map_obj_t *smo, space_map_t *sm)
|
dump_spacemap(objset_t *os, space_map_t *sm)
|
||||||
{
|
{
|
||||||
uint64_t alloc, offset, entry;
|
uint64_t alloc, offset, entry;
|
||||||
uint8_t mapshift = sm->sm_shift;
|
|
||||||
uint64_t mapstart = sm->sm_start;
|
|
||||||
char *ddata[] = { "ALLOC", "FREE", "CONDENSE", "INVALID",
|
char *ddata[] = { "ALLOC", "FREE", "CONDENSE", "INVALID",
|
||||||
"INVALID", "INVALID", "INVALID", "INVALID" };
|
"INVALID", "INVALID", "INVALID", "INVALID" };
|
||||||
|
|
||||||
if (smo->smo_object == 0)
|
if (sm == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Print out the freelist entries in both encoded and decoded form.
|
* Print out the freelist entries in both encoded and decoded form.
|
||||||
*/
|
*/
|
||||||
alloc = 0;
|
alloc = 0;
|
||||||
for (offset = 0; offset < smo->smo_objsize; offset += sizeof (entry)) {
|
for (offset = 0; offset < space_map_length(sm);
|
||||||
VERIFY3U(0, ==, dmu_read(os, smo->smo_object, offset,
|
offset += sizeof (entry)) {
|
||||||
|
uint8_t mapshift = sm->sm_shift;
|
||||||
|
|
||||||
|
VERIFY0(dmu_read(os, space_map_object(sm), offset,
|
||||||
sizeof (entry), &entry, DMU_READ_PREFETCH));
|
sizeof (entry), &entry, DMU_READ_PREFETCH));
|
||||||
if (SM_DEBUG_DECODE(entry)) {
|
if (SM_DEBUG_DECODE(entry)) {
|
||||||
|
|
||||||
(void) printf("\t [%6llu] %s: txg %llu, pass %llu\n",
|
(void) printf("\t [%6llu] %s: txg %llu, pass %llu\n",
|
||||||
(u_longlong_t)(offset / sizeof (entry)),
|
(u_longlong_t)(offset / sizeof (entry)),
|
||||||
ddata[SM_DEBUG_ACTION_DECODE(entry)],
|
ddata[SM_DEBUG_ACTION_DECODE(entry)],
|
||||||
@ -548,10 +615,10 @@ dump_spacemap(objset_t *os, space_map_obj_t *smo, space_map_t *sm)
|
|||||||
(u_longlong_t)(offset / sizeof (entry)),
|
(u_longlong_t)(offset / sizeof (entry)),
|
||||||
SM_TYPE_DECODE(entry) == SM_ALLOC ? 'A' : 'F',
|
SM_TYPE_DECODE(entry) == SM_ALLOC ? 'A' : 'F',
|
||||||
(u_longlong_t)((SM_OFFSET_DECODE(entry) <<
|
(u_longlong_t)((SM_OFFSET_DECODE(entry) <<
|
||||||
mapshift) + mapstart),
|
mapshift) + sm->sm_start),
|
||||||
(u_longlong_t)((SM_OFFSET_DECODE(entry) <<
|
(u_longlong_t)((SM_OFFSET_DECODE(entry) <<
|
||||||
mapshift) + mapstart + (SM_RUN_DECODE(entry) <<
|
mapshift) + sm->sm_start +
|
||||||
mapshift)),
|
(SM_RUN_DECODE(entry) << mapshift)),
|
||||||
(u_longlong_t)(SM_RUN_DECODE(entry) << mapshift));
|
(u_longlong_t)(SM_RUN_DECODE(entry) << mapshift));
|
||||||
if (SM_TYPE_DECODE(entry) == SM_ALLOC)
|
if (SM_TYPE_DECODE(entry) == SM_ALLOC)
|
||||||
alloc += SM_RUN_DECODE(entry) << mapshift;
|
alloc += SM_RUN_DECODE(entry) << mapshift;
|
||||||
@ -559,10 +626,10 @@ dump_spacemap(objset_t *os, space_map_obj_t *smo, space_map_t *sm)
|
|||||||
alloc -= SM_RUN_DECODE(entry) << mapshift;
|
alloc -= SM_RUN_DECODE(entry) << mapshift;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (alloc != smo->smo_alloc) {
|
if (alloc != space_map_allocated(sm)) {
|
||||||
(void) printf("space_map_object alloc (%llu) INCONSISTENT "
|
(void) printf("space_map_object alloc (%llu) INCONSISTENT "
|
||||||
"with space map summary (%llu)\n",
|
"with space map summary (%llu)\n",
|
||||||
(u_longlong_t)smo->smo_alloc, (u_longlong_t)alloc);
|
(u_longlong_t)space_map_allocated(sm), (u_longlong_t)alloc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -570,15 +637,17 @@ static void
|
|||||||
dump_metaslab_stats(metaslab_t *msp)
|
dump_metaslab_stats(metaslab_t *msp)
|
||||||
{
|
{
|
||||||
char maxbuf[32];
|
char maxbuf[32];
|
||||||
space_map_t *sm = msp->ms_map;
|
range_tree_t *rt = msp->ms_tree;
|
||||||
avl_tree_t *t = sm->sm_pp_root;
|
avl_tree_t *t = &msp->ms_size_tree;
|
||||||
int free_pct = sm->sm_space * 100 / sm->sm_size;
|
int free_pct = range_tree_space(rt) * 100 / msp->ms_size;
|
||||||
|
|
||||||
zdb_nicenum(space_map_maxsize(sm), maxbuf);
|
zdb_nicenum(metaslab_block_maxsize(msp), maxbuf);
|
||||||
|
|
||||||
(void) printf("\t %25s %10lu %7s %6s %4s %4d%%\n",
|
(void) printf("\t %25s %10lu %7s %6s %4s %4d%%\n",
|
||||||
"segments", avl_numnodes(t), "maxsize", maxbuf,
|
"segments", avl_numnodes(t), "maxsize", maxbuf,
|
||||||
"freepct", free_pct);
|
"freepct", free_pct);
|
||||||
|
(void) printf("\tIn-memory histogram:\n");
|
||||||
|
dump_histogram(rt->rt_histogram, RANGE_TREE_HISTOGRAM_SIZE, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -586,33 +655,44 @@ dump_metaslab(metaslab_t *msp)
|
|||||||
{
|
{
|
||||||
vdev_t *vd = msp->ms_group->mg_vd;
|
vdev_t *vd = msp->ms_group->mg_vd;
|
||||||
spa_t *spa = vd->vdev_spa;
|
spa_t *spa = vd->vdev_spa;
|
||||||
space_map_t *sm = msp->ms_map;
|
space_map_t *sm = msp->ms_sm;
|
||||||
space_map_obj_t *smo = &msp->ms_smo;
|
|
||||||
char freebuf[32];
|
char freebuf[32];
|
||||||
|
|
||||||
zdb_nicenum(sm->sm_size - smo->smo_alloc, freebuf);
|
zdb_nicenum(msp->ms_size - space_map_allocated(sm), freebuf);
|
||||||
|
|
||||||
(void) printf(
|
(void) printf(
|
||||||
"\tmetaslab %6llu offset %12llx spacemap %6llu free %5s\n",
|
"\tmetaslab %6llu offset %12llx spacemap %6llu free %5s\n",
|
||||||
(u_longlong_t)(sm->sm_start / sm->sm_size),
|
(u_longlong_t)msp->ms_id, (u_longlong_t)msp->ms_start,
|
||||||
(u_longlong_t)sm->sm_start, (u_longlong_t)smo->smo_object, freebuf);
|
(u_longlong_t)space_map_object(sm), freebuf);
|
||||||
|
|
||||||
if (dump_opt['m'] > 1 && !dump_opt['L']) {
|
if (dump_opt['m'] > 2 && !dump_opt['L']) {
|
||||||
mutex_enter(&msp->ms_lock);
|
mutex_enter(&msp->ms_lock);
|
||||||
space_map_load_wait(sm);
|
metaslab_load_wait(msp);
|
||||||
if (!sm->sm_loaded)
|
if (!msp->ms_loaded) {
|
||||||
VERIFY(space_map_load(sm, zfs_metaslab_ops,
|
VERIFY0(metaslab_load(msp));
|
||||||
SM_FREE, smo, spa->spa_meta_objset) == 0);
|
range_tree_stat_verify(msp->ms_tree);
|
||||||
|
}
|
||||||
dump_metaslab_stats(msp);
|
dump_metaslab_stats(msp);
|
||||||
space_map_unload(sm);
|
metaslab_unload(msp);
|
||||||
mutex_exit(&msp->ms_lock);
|
mutex_exit(&msp->ms_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dump_opt['d'] > 5 || dump_opt['m'] > 2) {
|
if (dump_opt['m'] > 1 && sm != NULL &&
|
||||||
ASSERT(sm->sm_size == (1ULL << vd->vdev_ms_shift));
|
spa_feature_is_active(spa, SPA_FEATURE_SPACEMAP_HISTOGRAM)) {
|
||||||
|
/*
|
||||||
|
* The space map histogram represents free space in chunks
|
||||||
|
* of sm_shift (i.e. bucket 0 refers to 2^sm_shift).
|
||||||
|
*/
|
||||||
|
(void) printf("\tOn-disk histogram:\n");
|
||||||
|
dump_histogram(sm->sm_phys->smp_histogram,
|
||||||
|
SPACE_MAP_HISTOGRAM_SIZE(sm), sm->sm_shift);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dump_opt['d'] > 5 || dump_opt['m'] > 3) {
|
||||||
|
ASSERT(msp->ms_size == (1ULL << vd->vdev_ms_shift));
|
||||||
|
|
||||||
mutex_enter(&msp->ms_lock);
|
mutex_enter(&msp->ms_lock);
|
||||||
dump_spacemap(spa->spa_meta_objset, smo, sm);
|
dump_spacemap(spa->spa_meta_objset, msp->ms_sm);
|
||||||
mutex_exit(&msp->ms_lock);
|
mutex_exit(&msp->ms_lock);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -684,7 +764,7 @@ dump_dde(const ddt_t *ddt, const ddt_entry_t *dde, uint64_t index)
|
|||||||
if (ddp->ddp_phys_birth == 0)
|
if (ddp->ddp_phys_birth == 0)
|
||||||
continue;
|
continue;
|
||||||
ddt_bp_create(ddt->ddt_checksum, ddk, ddp, &blk);
|
ddt_bp_create(ddt->ddt_checksum, ddk, ddp, &blk);
|
||||||
sprintf_blkptr(blkbuf, &blk);
|
snprintf_blkptr(blkbuf, sizeof (blkbuf), &blk);
|
||||||
(void) printf("index %llx refcnt %llu %s %s\n",
|
(void) printf("index %llx refcnt %llu %s %s\n",
|
||||||
(u_longlong_t)index, (u_longlong_t)ddp->ddp_refcnt,
|
(u_longlong_t)index, (u_longlong_t)ddp->ddp_refcnt,
|
||||||
types[p], blkbuf);
|
types[p], blkbuf);
|
||||||
@ -801,9 +881,9 @@ dump_all_ddts(spa_t *spa)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
dump_dtl_seg(space_map_t *sm, uint64_t start, uint64_t size)
|
dump_dtl_seg(void *arg, uint64_t start, uint64_t size)
|
||||||
{
|
{
|
||||||
char *prefix = (void *)sm;
|
char *prefix = arg;
|
||||||
|
|
||||||
(void) printf("%s [%llu,%llu) length %llu\n",
|
(void) printf("%s [%llu,%llu) length %llu\n",
|
||||||
prefix,
|
prefix,
|
||||||
@ -833,28 +913,32 @@ dump_dtl(vdev_t *vd, int indent)
|
|||||||
required ? "DTL-required" : "DTL-expendable");
|
required ? "DTL-required" : "DTL-expendable");
|
||||||
|
|
||||||
for (int t = 0; t < DTL_TYPES; t++) {
|
for (int t = 0; t < DTL_TYPES; t++) {
|
||||||
space_map_t *sm = &vd->vdev_dtl[t];
|
range_tree_t *rt = vd->vdev_dtl[t];
|
||||||
if (sm->sm_space == 0)
|
if (range_tree_space(rt) == 0)
|
||||||
continue;
|
continue;
|
||||||
(void) snprintf(prefix, sizeof (prefix), "\t%*s%s",
|
(void) snprintf(prefix, sizeof (prefix), "\t%*s%s",
|
||||||
indent + 2, "", name[t]);
|
indent + 2, "", name[t]);
|
||||||
mutex_enter(sm->sm_lock);
|
mutex_enter(rt->rt_lock);
|
||||||
space_map_walk(sm, dump_dtl_seg, (void *)prefix);
|
range_tree_walk(rt, dump_dtl_seg, prefix);
|
||||||
mutex_exit(sm->sm_lock);
|
mutex_exit(rt->rt_lock);
|
||||||
if (dump_opt['d'] > 5 && vd->vdev_children == 0)
|
if (dump_opt['d'] > 5 && vd->vdev_children == 0)
|
||||||
dump_spacemap(spa->spa_meta_objset,
|
dump_spacemap(spa->spa_meta_objset, vd->vdev_dtl_sm);
|
||||||
&vd->vdev_dtl_smo, sm);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int c = 0; c < vd->vdev_children; c++)
|
for (int c = 0; c < vd->vdev_children; c++)
|
||||||
dump_dtl(vd->vdev_child[c], indent + 4);
|
dump_dtl(vd->vdev_child[c], indent + 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* from spa_history.c: spa_history_create_obj() */
|
||||||
|
#define HIS_BUF_LEN_DEF (128 << 10)
|
||||||
|
#define HIS_BUF_LEN_MAX (1 << 30)
|
||||||
|
|
||||||
static void
|
static void
|
||||||
dump_history(spa_t *spa)
|
dump_history(spa_t *spa)
|
||||||
{
|
{
|
||||||
nvlist_t **events = NULL;
|
nvlist_t **events = NULL;
|
||||||
char buf[SPA_MAXBLOCKSIZE];
|
char *buf = NULL;
|
||||||
|
uint64_t bufsize = HIS_BUF_LEN_DEF;
|
||||||
uint64_t resid, len, off = 0;
|
uint64_t resid, len, off = 0;
|
||||||
uint_t num = 0;
|
uint_t num = 0;
|
||||||
int error;
|
int error;
|
||||||
@ -863,8 +947,11 @@ dump_history(spa_t *spa)
|
|||||||
char tbuf[30];
|
char tbuf[30];
|
||||||
char internalstr[MAXPATHLEN];
|
char internalstr[MAXPATHLEN];
|
||||||
|
|
||||||
|
if ((buf = malloc(bufsize)) == NULL)
|
||||||
|
(void) fprintf(stderr, "Unable to read history: "
|
||||||
|
"out of memory\n");
|
||||||
do {
|
do {
|
||||||
len = sizeof (buf);
|
len = bufsize;
|
||||||
|
|
||||||
if ((error = spa_history_get(spa, &off, &len, buf)) != 0) {
|
if ((error = spa_history_get(spa, &off, &len, buf)) != 0) {
|
||||||
(void) fprintf(stderr, "Unable to read history: "
|
(void) fprintf(stderr, "Unable to read history: "
|
||||||
@ -874,9 +961,26 @@ dump_history(spa_t *spa)
|
|||||||
|
|
||||||
if (zpool_history_unpack(buf, len, &resid, &events, &num) != 0)
|
if (zpool_history_unpack(buf, len, &resid, &events, &num) != 0)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
off -= resid;
|
off -= resid;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If the history block is too big, double the buffer
|
||||||
|
* size and try again.
|
||||||
|
*/
|
||||||
|
if (resid == len) {
|
||||||
|
free(buf);
|
||||||
|
buf = NULL;
|
||||||
|
|
||||||
|
bufsize <<= 1;
|
||||||
|
if ((bufsize >= HIS_BUF_LEN_MAX) ||
|
||||||
|
((buf = malloc(bufsize)) == NULL)) {
|
||||||
|
(void) fprintf(stderr, "Unable to read history: "
|
||||||
|
"out of memory\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
} while (len != 0);
|
} while (len != 0);
|
||||||
|
free(buf);
|
||||||
|
|
||||||
(void) printf("\nHistory:\n");
|
(void) printf("\nHistory:\n");
|
||||||
for (int i = 0; i < num; i++) {
|
for (int i = 0; i < num; i++) {
|
||||||
@ -945,25 +1049,32 @@ blkid2offset(const dnode_phys_t *dnp, const blkptr_t *bp, const zbookmark_t *zb)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
sprintf_blkptr_compact(char *blkbuf, const blkptr_t *bp)
|
snprintf_blkptr_compact(char *blkbuf, size_t buflen, const blkptr_t *bp)
|
||||||
{
|
{
|
||||||
const dva_t *dva = bp->blk_dva;
|
const dva_t *dva = bp->blk_dva;
|
||||||
int ndvas = dump_opt['d'] > 5 ? BP_GET_NDVAS(bp) : 1;
|
int ndvas = dump_opt['d'] > 5 ? BP_GET_NDVAS(bp) : 1;
|
||||||
|
|
||||||
if (dump_opt['b'] >= 6) {
|
if (dump_opt['b'] >= 6) {
|
||||||
sprintf_blkptr(blkbuf, bp);
|
snprintf_blkptr(blkbuf, buflen, bp);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
blkbuf[0] = '\0';
|
blkbuf[0] = '\0';
|
||||||
|
|
||||||
for (int i = 0; i < ndvas; i++)
|
for (int i = 0; i < ndvas; i++)
|
||||||
(void) sprintf(blkbuf + strlen(blkbuf), "%llu:%llx:%llx ",
|
(void) snprintf(blkbuf + strlen(blkbuf),
|
||||||
|
buflen - strlen(blkbuf), "%llu:%llx:%llx ",
|
||||||
(u_longlong_t)DVA_GET_VDEV(&dva[i]),
|
(u_longlong_t)DVA_GET_VDEV(&dva[i]),
|
||||||
(u_longlong_t)DVA_GET_OFFSET(&dva[i]),
|
(u_longlong_t)DVA_GET_OFFSET(&dva[i]),
|
||||||
(u_longlong_t)DVA_GET_ASIZE(&dva[i]));
|
(u_longlong_t)DVA_GET_ASIZE(&dva[i]));
|
||||||
|
|
||||||
(void) sprintf(blkbuf + strlen(blkbuf),
|
if (BP_IS_HOLE(bp)) {
|
||||||
|
(void) snprintf(blkbuf + strlen(blkbuf),
|
||||||
|
buflen - strlen(blkbuf), "B=%llu",
|
||||||
|
(u_longlong_t)bp->blk_birth);
|
||||||
|
} else {
|
||||||
|
(void) snprintf(blkbuf + strlen(blkbuf),
|
||||||
|
buflen - strlen(blkbuf),
|
||||||
"%llxL/%llxP F=%llu B=%llu/%llu",
|
"%llxL/%llxP F=%llu B=%llu/%llu",
|
||||||
(u_longlong_t)BP_GET_LSIZE(bp),
|
(u_longlong_t)BP_GET_LSIZE(bp),
|
||||||
(u_longlong_t)BP_GET_PSIZE(bp),
|
(u_longlong_t)BP_GET_PSIZE(bp),
|
||||||
@ -971,6 +1082,7 @@ sprintf_blkptr_compact(char *blkbuf, const blkptr_t *bp)
|
|||||||
(u_longlong_t)bp->blk_birth,
|
(u_longlong_t)bp->blk_birth,
|
||||||
(u_longlong_t)BP_PHYSICAL_BIRTH(bp));
|
(u_longlong_t)BP_PHYSICAL_BIRTH(bp));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
print_indirect(blkptr_t *bp, const zbookmark_t *zb,
|
print_indirect(blkptr_t *bp, const zbookmark_t *zb,
|
||||||
@ -994,7 +1106,7 @@ print_indirect(blkptr_t *bp, const zbookmark_t *zb,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sprintf_blkptr_compact(blkbuf, bp);
|
snprintf_blkptr_compact(blkbuf, sizeof (blkbuf), bp);
|
||||||
(void) printf("%s\n", blkbuf);
|
(void) printf("%s\n", blkbuf);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1009,7 +1121,7 @@ visit_indirect(spa_t *spa, const dnode_phys_t *dnp,
|
|||||||
|
|
||||||
print_indirect(bp, zb, dnp);
|
print_indirect(bp, zb, dnp);
|
||||||
|
|
||||||
if (BP_GET_LEVEL(bp) > 0) {
|
if (BP_GET_LEVEL(bp) > 0 && !BP_IS_HOLE(bp)) {
|
||||||
uint32_t flags = ARC_WAIT;
|
uint32_t flags = ARC_WAIT;
|
||||||
int i;
|
int i;
|
||||||
blkptr_t *cbp;
|
blkptr_t *cbp;
|
||||||
@ -1134,7 +1246,7 @@ dump_dsl_dataset(objset_t *os, uint64_t object, void *data, size_t size)
|
|||||||
zdb_nicenum(ds->ds_compressed_bytes, compressed);
|
zdb_nicenum(ds->ds_compressed_bytes, compressed);
|
||||||
zdb_nicenum(ds->ds_uncompressed_bytes, uncompressed);
|
zdb_nicenum(ds->ds_uncompressed_bytes, uncompressed);
|
||||||
zdb_nicenum(ds->ds_unique_bytes, unique);
|
zdb_nicenum(ds->ds_unique_bytes, unique);
|
||||||
sprintf_blkptr(blkbuf, &ds->ds_bp);
|
snprintf_blkptr(blkbuf, sizeof (blkbuf), &ds->ds_bp);
|
||||||
|
|
||||||
(void) printf("\t\tdir_obj = %llu\n",
|
(void) printf("\t\tdir_obj = %llu\n",
|
||||||
(u_longlong_t)ds->ds_dir_obj);
|
(u_longlong_t)ds->ds_dir_obj);
|
||||||
@ -1179,7 +1291,7 @@ dump_bptree_cb(void *arg, const blkptr_t *bp, dmu_tx_t *tx)
|
|||||||
char blkbuf[BP_SPRINTF_LEN];
|
char blkbuf[BP_SPRINTF_LEN];
|
||||||
|
|
||||||
if (bp->blk_birth != 0) {
|
if (bp->blk_birth != 0) {
|
||||||
sprintf_blkptr(blkbuf, bp);
|
snprintf_blkptr(blkbuf, sizeof (blkbuf), bp);
|
||||||
(void) printf("\t%s\n", blkbuf);
|
(void) printf("\t%s\n", blkbuf);
|
||||||
}
|
}
|
||||||
return (0);
|
return (0);
|
||||||
@ -1217,7 +1329,7 @@ dump_bpobj_cb(void *arg, const blkptr_t *bp, dmu_tx_t *tx)
|
|||||||
char blkbuf[BP_SPRINTF_LEN];
|
char blkbuf[BP_SPRINTF_LEN];
|
||||||
|
|
||||||
ASSERT(bp->blk_birth != 0);
|
ASSERT(bp->blk_birth != 0);
|
||||||
sprintf_blkptr_compact(blkbuf, bp);
|
snprintf_blkptr_compact(blkbuf, sizeof (blkbuf), bp);
|
||||||
(void) printf("\t%s\n", blkbuf);
|
(void) printf("\t%s\n", blkbuf);
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
@ -1716,8 +1828,9 @@ dump_dir(objset_t *os)
|
|||||||
zdb_nicenum(refdbytes, numbuf);
|
zdb_nicenum(refdbytes, numbuf);
|
||||||
|
|
||||||
if (verbosity >= 4) {
|
if (verbosity >= 4) {
|
||||||
(void) sprintf(blkbuf, ", rootbp ");
|
(void) snprintf(blkbuf, sizeof (blkbuf), ", rootbp ");
|
||||||
(void) sprintf_blkptr(blkbuf + strlen(blkbuf), os->os_rootbp);
|
(void) snprintf_blkptr(blkbuf + strlen(blkbuf),
|
||||||
|
sizeof (blkbuf) - strlen(blkbuf), os->os_rootbp);
|
||||||
} else {
|
} else {
|
||||||
blkbuf[0] = '\0';
|
blkbuf[0] = '\0';
|
||||||
}
|
}
|
||||||
@ -1747,7 +1860,7 @@ dump_dir(objset_t *os)
|
|||||||
if (verbosity < 2)
|
if (verbosity < 2)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (os->os_rootbp->blk_birth == 0)
|
if (BP_IS_HOLE(os->os_rootbp))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
dump_object(os, 0, verbosity, &print_header);
|
dump_object(os, 0, verbosity, &print_header);
|
||||||
@ -1788,7 +1901,7 @@ dump_uberblock(uberblock_t *ub, const char *header, const char *footer)
|
|||||||
(u_longlong_t)ub->ub_timestamp, asctime(localtime(×tamp)));
|
(u_longlong_t)ub->ub_timestamp, asctime(localtime(×tamp)));
|
||||||
if (dump_opt['u'] >= 3) {
|
if (dump_opt['u'] >= 3) {
|
||||||
char blkbuf[BP_SPRINTF_LEN];
|
char blkbuf[BP_SPRINTF_LEN];
|
||||||
sprintf_blkptr(blkbuf, &ub->ub_rootbp);
|
snprintf_blkptr(blkbuf, sizeof (blkbuf), &ub->ub_rootbp);
|
||||||
(void) printf("\trootbp = %s\n", blkbuf);
|
(void) printf("\trootbp = %s\n", blkbuf);
|
||||||
}
|
}
|
||||||
(void) printf(footer ? footer : "");
|
(void) printf(footer ? footer : "");
|
||||||
@ -2079,45 +2192,30 @@ zdb_count_block(zdb_cb_t *zcb, zilog_t *zilog, const blkptr_t *bp,
|
|||||||
bp, NULL, NULL, ZIO_FLAG_CANFAIL)), ==, 0);
|
bp, NULL, NULL, ZIO_FLAG_CANFAIL)), ==, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
/* ARGSUSED */
|
||||||
zdb_blkptr_cb(spa_t *spa, zilog_t *zilog, const blkptr_t *bp,
|
static void
|
||||||
const zbookmark_t *zb, const dnode_phys_t *dnp, void *arg)
|
zdb_blkptr_done(zio_t *zio)
|
||||||
{
|
{
|
||||||
zdb_cb_t *zcb = arg;
|
spa_t *spa = zio->io_spa;
|
||||||
|
blkptr_t *bp = zio->io_bp;
|
||||||
|
int ioerr = zio->io_error;
|
||||||
|
zdb_cb_t *zcb = zio->io_private;
|
||||||
|
zbookmark_t *zb = &zio->io_bookmark;
|
||||||
|
|
||||||
|
zio_data_buf_free(zio->io_data, zio->io_size);
|
||||||
|
|
||||||
|
mutex_enter(&spa->spa_scrub_lock);
|
||||||
|
spa->spa_scrub_inflight--;
|
||||||
|
cv_broadcast(&spa->spa_scrub_io_cv);
|
||||||
|
|
||||||
|
if (ioerr && !(zio->io_flags & ZIO_FLAG_SPECULATIVE)) {
|
||||||
char blkbuf[BP_SPRINTF_LEN];
|
char blkbuf[BP_SPRINTF_LEN];
|
||||||
dmu_object_type_t type;
|
|
||||||
boolean_t is_metadata;
|
|
||||||
|
|
||||||
if (bp == NULL)
|
|
||||||
return (0);
|
|
||||||
|
|
||||||
type = BP_GET_TYPE(bp);
|
|
||||||
|
|
||||||
zdb_count_block(zcb, zilog, bp,
|
|
||||||
(type & DMU_OT_NEWTYPE) ? ZDB_OT_OTHER : type);
|
|
||||||
|
|
||||||
is_metadata = (BP_GET_LEVEL(bp) != 0 || DMU_OT_IS_METADATA(type));
|
|
||||||
|
|
||||||
if (dump_opt['c'] > 1 || (dump_opt['c'] && is_metadata)) {
|
|
||||||
int ioerr;
|
|
||||||
size_t size = BP_GET_PSIZE(bp);
|
|
||||||
void *data = malloc(size);
|
|
||||||
int flags = ZIO_FLAG_CANFAIL | ZIO_FLAG_SCRUB | ZIO_FLAG_RAW;
|
|
||||||
|
|
||||||
/* If it's an intent log block, failure is expected. */
|
|
||||||
if (zb->zb_level == ZB_ZIL_LEVEL)
|
|
||||||
flags |= ZIO_FLAG_SPECULATIVE;
|
|
||||||
|
|
||||||
ioerr = zio_wait(zio_read(NULL, spa, bp, data, size,
|
|
||||||
NULL, NULL, ZIO_PRIORITY_ASYNC_READ, flags, zb));
|
|
||||||
|
|
||||||
free(data);
|
|
||||||
if (ioerr && !(flags & ZIO_FLAG_SPECULATIVE)) {
|
|
||||||
zcb->zcb_haderrors = 1;
|
zcb->zcb_haderrors = 1;
|
||||||
zcb->zcb_errors[ioerr]++;
|
zcb->zcb_errors[ioerr]++;
|
||||||
|
|
||||||
if (dump_opt['b'] >= 2)
|
if (dump_opt['b'] >= 2)
|
||||||
sprintf_blkptr(blkbuf, bp);
|
snprintf_blkptr(blkbuf, sizeof (blkbuf), bp);
|
||||||
else
|
else
|
||||||
blkbuf[0] = '\0';
|
blkbuf[0] = '\0';
|
||||||
|
|
||||||
@ -2131,12 +2229,21 @@ zdb_blkptr_cb(spa_t *spa, zilog_t *zilog, const blkptr_t *bp,
|
|||||||
(u_longlong_t)zb->zb_blkid,
|
(u_longlong_t)zb->zb_blkid,
|
||||||
blkbuf);
|
blkbuf);
|
||||||
}
|
}
|
||||||
|
mutex_exit(&spa->spa_scrub_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
zcb->zcb_readfails = 0;
|
/* ARGSUSED */
|
||||||
|
static int
|
||||||
|
zdb_blkptr_cb(spa_t *spa, zilog_t *zilog, const blkptr_t *bp,
|
||||||
|
const zbookmark_t *zb, const dnode_phys_t *dnp, void *arg)
|
||||||
|
{
|
||||||
|
zdb_cb_t *zcb = arg;
|
||||||
|
dmu_object_type_t type;
|
||||||
|
boolean_t is_metadata;
|
||||||
|
|
||||||
if (dump_opt['b'] >= 5) {
|
if (dump_opt['b'] >= 5 && bp->blk_birth > 0) {
|
||||||
sprintf_blkptr(blkbuf, bp);
|
char blkbuf[BP_SPRINTF_LEN];
|
||||||
|
snprintf_blkptr(blkbuf, sizeof (blkbuf), bp);
|
||||||
(void) printf("objset %llu object %llu "
|
(void) printf("objset %llu object %llu "
|
||||||
"level %lld offset 0x%llx %s\n",
|
"level %lld offset 0x%llx %s\n",
|
||||||
(u_longlong_t)zb->zb_objset,
|
(u_longlong_t)zb->zb_objset,
|
||||||
@ -2146,6 +2253,37 @@ zdb_blkptr_cb(spa_t *spa, zilog_t *zilog, const blkptr_t *bp,
|
|||||||
blkbuf);
|
blkbuf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (BP_IS_HOLE(bp))
|
||||||
|
return (0);
|
||||||
|
|
||||||
|
type = BP_GET_TYPE(bp);
|
||||||
|
|
||||||
|
zdb_count_block(zcb, zilog, bp,
|
||||||
|
(type & DMU_OT_NEWTYPE) ? ZDB_OT_OTHER : type);
|
||||||
|
|
||||||
|
is_metadata = (BP_GET_LEVEL(bp) != 0 || DMU_OT_IS_METADATA(type));
|
||||||
|
|
||||||
|
if (dump_opt['c'] > 1 || (dump_opt['c'] && is_metadata)) {
|
||||||
|
size_t size = BP_GET_PSIZE(bp);
|
||||||
|
void *data = zio_data_buf_alloc(size);
|
||||||
|
int flags = ZIO_FLAG_CANFAIL | ZIO_FLAG_SCRUB | ZIO_FLAG_RAW;
|
||||||
|
|
||||||
|
/* If it's an intent log block, failure is expected. */
|
||||||
|
if (zb->zb_level == ZB_ZIL_LEVEL)
|
||||||
|
flags |= ZIO_FLAG_SPECULATIVE;
|
||||||
|
|
||||||
|
mutex_enter(&spa->spa_scrub_lock);
|
||||||
|
while (spa->spa_scrub_inflight > max_inflight)
|
||||||
|
cv_wait(&spa->spa_scrub_io_cv, &spa->spa_scrub_lock);
|
||||||
|
spa->spa_scrub_inflight++;
|
||||||
|
mutex_exit(&spa->spa_scrub_lock);
|
||||||
|
|
||||||
|
zio_nowait(zio_read(NULL, spa, bp, data, size,
|
||||||
|
zdb_blkptr_done, zcb, ZIO_PRIORITY_ASYNC_READ, flags, zb));
|
||||||
|
}
|
||||||
|
|
||||||
|
zcb->zcb_readfails = 0;
|
||||||
|
|
||||||
if (dump_opt['b'] < 5 && isatty(STDERR_FILENO) &&
|
if (dump_opt['b'] < 5 && isatty(STDERR_FILENO) &&
|
||||||
gethrtime() > zcb->zcb_lastprint + NANOSEC) {
|
gethrtime() > zcb->zcb_lastprint + NANOSEC) {
|
||||||
uint64_t now = gethrtime();
|
uint64_t now = gethrtime();
|
||||||
@ -2172,39 +2310,17 @@ zdb_blkptr_cb(spa_t *spa, zilog_t *zilog, const blkptr_t *bp,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
zdb_leak(space_map_t *sm, uint64_t start, uint64_t size)
|
zdb_leak(void *arg, uint64_t start, uint64_t size)
|
||||||
{
|
{
|
||||||
vdev_t *vd = sm->sm_ppd;
|
vdev_t *vd = arg;
|
||||||
|
|
||||||
(void) printf("leaked space: vdev %llu, offset 0x%llx, size %llu\n",
|
(void) printf("leaked space: vdev %llu, offset 0x%llx, size %llu\n",
|
||||||
(u_longlong_t)vd->vdev_id, (u_longlong_t)start, (u_longlong_t)size);
|
(u_longlong_t)vd->vdev_id, (u_longlong_t)start, (u_longlong_t)size);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ARGSUSED */
|
static metaslab_ops_t zdb_metaslab_ops = {
|
||||||
static void
|
|
||||||
zdb_space_map_load(space_map_t *sm)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
zdb_space_map_unload(space_map_t *sm)
|
|
||||||
{
|
|
||||||
space_map_vacate(sm, zdb_leak, sm);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ARGSUSED */
|
|
||||||
static void
|
|
||||||
zdb_space_map_claim(space_map_t *sm, uint64_t start, uint64_t size)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
static space_map_ops_t zdb_space_map_ops = {
|
|
||||||
zdb_space_map_load,
|
|
||||||
zdb_space_map_unload,
|
|
||||||
NULL, /* alloc */
|
NULL, /* alloc */
|
||||||
zdb_space_map_claim,
|
NULL /* fragmented */
|
||||||
NULL, /* free */
|
|
||||||
NULL /* maxsize */
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -2259,11 +2375,21 @@ zdb_leak_init(spa_t *spa, zdb_cb_t *zcb)
|
|||||||
for (int m = 0; m < vd->vdev_ms_count; m++) {
|
for (int m = 0; m < vd->vdev_ms_count; m++) {
|
||||||
metaslab_t *msp = vd->vdev_ms[m];
|
metaslab_t *msp = vd->vdev_ms[m];
|
||||||
mutex_enter(&msp->ms_lock);
|
mutex_enter(&msp->ms_lock);
|
||||||
space_map_unload(msp->ms_map);
|
metaslab_unload(msp);
|
||||||
VERIFY(space_map_load(msp->ms_map,
|
|
||||||
&zdb_space_map_ops, SM_ALLOC, &msp->ms_smo,
|
/*
|
||||||
spa->spa_meta_objset) == 0);
|
* For leak detection, we overload the metaslab
|
||||||
msp->ms_map->sm_ppd = vd;
|
* ms_tree to contain allocated segments
|
||||||
|
* instead of free segments. As a result,
|
||||||
|
* we can't use the normal metaslab_load/unload
|
||||||
|
* interfaces.
|
||||||
|
*/
|
||||||
|
if (msp->ms_sm != NULL) {
|
||||||
|
msp->ms_ops = &zdb_metaslab_ops;
|
||||||
|
VERIFY0(space_map_load(msp->ms_sm,
|
||||||
|
msp->ms_tree, SM_ALLOC));
|
||||||
|
msp->ms_loaded = B_TRUE;
|
||||||
|
}
|
||||||
mutex_exit(&msp->ms_lock);
|
mutex_exit(&msp->ms_lock);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2286,7 +2412,20 @@ zdb_leak_fini(spa_t *spa)
|
|||||||
for (int m = 0; m < vd->vdev_ms_count; m++) {
|
for (int m = 0; m < vd->vdev_ms_count; m++) {
|
||||||
metaslab_t *msp = vd->vdev_ms[m];
|
metaslab_t *msp = vd->vdev_ms[m];
|
||||||
mutex_enter(&msp->ms_lock);
|
mutex_enter(&msp->ms_lock);
|
||||||
space_map_unload(msp->ms_map);
|
|
||||||
|
/*
|
||||||
|
* The ms_tree has been overloaded to
|
||||||
|
* contain allocated segments. Now that we
|
||||||
|
* finished traversing all blocks, any
|
||||||
|
* block that remains in the ms_tree
|
||||||
|
* represents an allocated block that we
|
||||||
|
* did not claim during the traversal.
|
||||||
|
* Claimed blocks would have been removed
|
||||||
|
* from the ms_tree.
|
||||||
|
*/
|
||||||
|
range_tree_vacate(msp->ms_tree, zdb_leak, vd);
|
||||||
|
msp->ms_loaded = B_FALSE;
|
||||||
|
|
||||||
mutex_exit(&msp->ms_lock);
|
mutex_exit(&msp->ms_lock);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2301,7 +2440,7 @@ count_block_cb(void *arg, const blkptr_t *bp, dmu_tx_t *tx)
|
|||||||
|
|
||||||
if (dump_opt['b'] >= 5) {
|
if (dump_opt['b'] >= 5) {
|
||||||
char blkbuf[BP_SPRINTF_LEN];
|
char blkbuf[BP_SPRINTF_LEN];
|
||||||
sprintf_blkptr(blkbuf, bp);
|
snprintf_blkptr(blkbuf, sizeof (blkbuf), bp);
|
||||||
(void) printf("[%s] %s\n",
|
(void) printf("[%s] %s\n",
|
||||||
"deferred free", blkbuf);
|
"deferred free", blkbuf);
|
||||||
}
|
}
|
||||||
@ -2344,8 +2483,7 @@ dump_block_stats(spa_t *spa)
|
|||||||
(void) bpobj_iterate_nofree(&spa->spa_dsl_pool->dp_free_bpobj,
|
(void) bpobj_iterate_nofree(&spa->spa_dsl_pool->dp_free_bpobj,
|
||||||
count_block_cb, &zcb, NULL);
|
count_block_cb, &zcb, NULL);
|
||||||
}
|
}
|
||||||
if (spa_feature_is_active(spa,
|
if (spa_feature_is_active(spa, SPA_FEATURE_ASYNC_DESTROY)) {
|
||||||
&spa_feature_table[SPA_FEATURE_ASYNC_DESTROY])) {
|
|
||||||
VERIFY3U(0, ==, bptree_iterate(spa->spa_meta_objset,
|
VERIFY3U(0, ==, bptree_iterate(spa->spa_meta_objset,
|
||||||
spa->spa_dsl_pool->dp_bptree_obj, B_FALSE, count_block_cb,
|
spa->spa_dsl_pool->dp_bptree_obj, B_FALSE, count_block_cb,
|
||||||
&zcb, NULL));
|
&zcb, NULL));
|
||||||
@ -2358,6 +2496,18 @@ dump_block_stats(spa_t *spa)
|
|||||||
zcb.zcb_start = zcb.zcb_lastprint = gethrtime();
|
zcb.zcb_start = zcb.zcb_lastprint = gethrtime();
|
||||||
zcb.zcb_haderrors |= traverse_pool(spa, 0, flags, zdb_blkptr_cb, &zcb);
|
zcb.zcb_haderrors |= traverse_pool(spa, 0, flags, zdb_blkptr_cb, &zcb);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If we've traversed the data blocks then we need to wait for those
|
||||||
|
* I/Os to complete. We leverage "The Godfather" zio to wait on
|
||||||
|
* all async I/Os to complete.
|
||||||
|
*/
|
||||||
|
if (dump_opt['c']) {
|
||||||
|
(void) zio_wait(spa->spa_async_zio_root);
|
||||||
|
spa->spa_async_zio_root = zio_root(spa, NULL, NULL,
|
||||||
|
ZIO_FLAG_CANFAIL | ZIO_FLAG_SPECULATIVE |
|
||||||
|
ZIO_FLAG_GODFATHER);
|
||||||
|
}
|
||||||
|
|
||||||
if (zcb.zcb_haderrors) {
|
if (zcb.zcb_haderrors) {
|
||||||
(void) printf("\nError counts:\n\n");
|
(void) printf("\nError counts:\n\n");
|
||||||
(void) printf("\t%5s %s\n", "errno", "count");
|
(void) printf("\t%5s %s\n", "errno", "count");
|
||||||
@ -2489,7 +2639,7 @@ dump_block_stats(spa_t *spa)
|
|||||||
"(in 512-byte sectors): "
|
"(in 512-byte sectors): "
|
||||||
"number of blocks\n");
|
"number of blocks\n");
|
||||||
dump_histogram(zb->zb_psize_histogram,
|
dump_histogram(zb->zb_psize_histogram,
|
||||||
PSIZE_HISTO_SIZE);
|
PSIZE_HISTO_SIZE, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2524,7 +2674,7 @@ zdb_ddt_add_cb(spa_t *spa, zilog_t *zilog, const blkptr_t *bp,
|
|||||||
avl_index_t where;
|
avl_index_t where;
|
||||||
zdb_ddt_entry_t *zdde, zdde_search;
|
zdb_ddt_entry_t *zdde, zdde_search;
|
||||||
|
|
||||||
if (bp == NULL)
|
if (BP_IS_HOLE(bp))
|
||||||
return (0);
|
return (0);
|
||||||
|
|
||||||
if (dump_opt['S'] > 1 && zb->zb_level == ZB_ROOT_LEVEL) {
|
if (dump_opt['S'] > 1 && zb->zb_level == ZB_ROOT_LEVEL) {
|
||||||
@ -2591,7 +2741,8 @@ dump_simulated_ddt(spa_t *spa)
|
|||||||
dds.dds_ref_psize = zdde->zdde_ref_psize;
|
dds.dds_ref_psize = zdde->zdde_ref_psize;
|
||||||
dds.dds_ref_dsize = zdde->zdde_ref_dsize;
|
dds.dds_ref_dsize = zdde->zdde_ref_dsize;
|
||||||
|
|
||||||
ddt_stat_add(&ddh_total.ddh_stat[highbit(refcnt) - 1], &dds, 0);
|
ddt_stat_add(&ddh_total.ddh_stat[highbit64(refcnt) - 1],
|
||||||
|
&dds, 0);
|
||||||
|
|
||||||
umem_free(zdde, sizeof (*zdde));
|
umem_free(zdde, sizeof (*zdde));
|
||||||
}
|
}
|
||||||
@ -2646,7 +2797,7 @@ dump_zpool(spa_t *spa)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (spa_feature_is_active(spa,
|
if (spa_feature_is_active(spa,
|
||||||
&spa_feature_table[SPA_FEATURE_ASYNC_DESTROY])) {
|
SPA_FEATURE_ASYNC_DESTROY)) {
|
||||||
dump_bptree(spa->spa_meta_objset,
|
dump_bptree(spa->spa_meta_objset,
|
||||||
spa->spa_dsl_pool->dp_bptree_obj,
|
spa->spa_dsl_pool->dp_bptree_obj,
|
||||||
"Pool dataset frees");
|
"Pool dataset frees");
|
||||||
@ -2659,6 +2810,9 @@ dump_zpool(spa_t *spa)
|
|||||||
if (dump_opt['b'] || dump_opt['c'])
|
if (dump_opt['b'] || dump_opt['c'])
|
||||||
rc = dump_block_stats(spa);
|
rc = dump_block_stats(spa);
|
||||||
|
|
||||||
|
if (rc == 0)
|
||||||
|
rc = verify_spacemap_refcounts(spa);
|
||||||
|
|
||||||
if (dump_opt['s'])
|
if (dump_opt['s'])
|
||||||
show_pool_stats(spa);
|
show_pool_stats(spa);
|
||||||
|
|
||||||
@ -2688,7 +2842,7 @@ zdb_print_blkptr(blkptr_t *bp, int flags)
|
|||||||
if (flags & ZDB_FLAG_BSWAP)
|
if (flags & ZDB_FLAG_BSWAP)
|
||||||
byteswap_uint64_array((void *)bp, sizeof (blkptr_t));
|
byteswap_uint64_array((void *)bp, sizeof (blkptr_t));
|
||||||
|
|
||||||
sprintf_blkptr(blkbuf, bp);
|
snprintf_blkptr(blkbuf, sizeof (blkbuf), bp);
|
||||||
(void) printf("%s\n", blkbuf);
|
(void) printf("%s\n", blkbuf);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2884,6 +3038,7 @@ zdb_read_block(char *thing, spa_t *spa)
|
|||||||
free(dup);
|
free(dup);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
i += p - &flagstr[i + 1]; /* skip over the number */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3124,7 +3279,7 @@ main(int argc, char **argv)
|
|||||||
|
|
||||||
dprintf_setup(&argc, argv);
|
dprintf_setup(&argc, argv);
|
||||||
|
|
||||||
while ((c = getopt(argc, argv, "bcdhilmsuCDRSAFLXevp:t:U:P")) != -1) {
|
while ((c = getopt(argc, argv, "bcdhilmM:suCDRSAFLXevp:t:U:P")) != -1) {
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case 'b':
|
case 'b':
|
||||||
case 'c':
|
case 'c':
|
||||||
@ -3153,6 +3308,15 @@ main(int argc, char **argv)
|
|||||||
case 'v':
|
case 'v':
|
||||||
verbose++;
|
verbose++;
|
||||||
break;
|
break;
|
||||||
|
case 'M':
|
||||||
|
max_inflight = strtoull(optarg, NULL, 0);
|
||||||
|
if (max_inflight == 0) {
|
||||||
|
(void) fprintf(stderr, "maximum number "
|
||||||
|
"of inflight I/Os must be greater "
|
||||||
|
"than 0\n");
|
||||||
|
usage();
|
||||||
|
}
|
||||||
|
break;
|
||||||
case 'p':
|
case 'p':
|
||||||
if (searchdirs == NULL) {
|
if (searchdirs == NULL) {
|
||||||
searchdirs = umem_alloc(sizeof (char *),
|
searchdirs = umem_alloc(sizeof (char *),
|
||||||
|
@ -23,6 +23,10 @@
|
|||||||
* Use is subject to license terms.
|
* Use is subject to license terms.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2013 by Delphix. All rights reserved.
|
||||||
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Print intent log header and statistics.
|
* Print intent log header and statistics.
|
||||||
*/
|
*/
|
||||||
@ -47,7 +51,7 @@ print_log_bp(const blkptr_t *bp, const char *prefix)
|
|||||||
{
|
{
|
||||||
char blkbuf[BP_SPRINTF_LEN];
|
char blkbuf[BP_SPRINTF_LEN];
|
||||||
|
|
||||||
sprintf_blkptr(blkbuf, bp);
|
snprintf_blkptr(blkbuf, sizeof (blkbuf), bp);
|
||||||
(void) printf("%s%s\n", prefix, blkbuf);
|
(void) printf("%s%s\n", prefix, blkbuf);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -132,6 +136,7 @@ zil_prt_rec_write(zilog_t *zilog, int txtype, lr_write_t *lr)
|
|||||||
|
|
||||||
if (lr->lr_common.lrc_reclen == sizeof (lr_write_t)) {
|
if (lr->lr_common.lrc_reclen == sizeof (lr_write_t)) {
|
||||||
(void) printf("%shas blkptr, %s\n", prefix,
|
(void) printf("%shas blkptr, %s\n", prefix,
|
||||||
|
!BP_IS_HOLE(bp) &&
|
||||||
bp->blk_birth >= spa_first_txg(zilog->zl_spa) ?
|
bp->blk_birth >= spa_first_txg(zilog->zl_spa) ?
|
||||||
"will claim" : "won't claim");
|
"will claim" : "won't claim");
|
||||||
print_log_bp(bp, prefix);
|
print_log_bp(bp, prefix);
|
||||||
@ -139,8 +144,6 @@ zil_prt_rec_write(zilog_t *zilog, int txtype, lr_write_t *lr)
|
|||||||
if (BP_IS_HOLE(bp)) {
|
if (BP_IS_HOLE(bp)) {
|
||||||
(void) printf("\t\t\tLSIZE 0x%llx\n",
|
(void) printf("\t\t\tLSIZE 0x%llx\n",
|
||||||
(u_longlong_t)BP_GET_LSIZE(bp));
|
(u_longlong_t)BP_GET_LSIZE(bp));
|
||||||
}
|
|
||||||
if (bp->blk_birth == 0) {
|
|
||||||
bzero(buf, sizeof (buf));
|
bzero(buf, sizeof (buf));
|
||||||
(void) printf("%s<hole>\n", prefix);
|
(void) printf("%s<hole>\n", prefix);
|
||||||
return;
|
return;
|
||||||
@ -313,7 +316,8 @@ print_log_block(zilog_t *zilog, blkptr_t *bp, void *arg, uint64_t claim_txg)
|
|||||||
|
|
||||||
if (verbose >= 5) {
|
if (verbose >= 5) {
|
||||||
(void) strcpy(blkbuf, ", ");
|
(void) strcpy(blkbuf, ", ");
|
||||||
sprintf_blkptr(blkbuf + strlen(blkbuf), bp);
|
snprintf_blkptr(blkbuf + strlen(blkbuf),
|
||||||
|
sizeof (blkbuf) - strlen(blkbuf), bp);
|
||||||
} else {
|
} else {
|
||||||
blkbuf[0] = '\0';
|
blkbuf[0] = '\0';
|
||||||
}
|
}
|
||||||
@ -361,7 +365,7 @@ dump_intent_log(zilog_t *zilog)
|
|||||||
int verbose = MAX(dump_opt['d'], dump_opt['i']);
|
int verbose = MAX(dump_opt['d'], dump_opt['i']);
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if (zh->zh_log.blk_birth == 0 || verbose < 1)
|
if (BP_IS_HOLE(&zh->zh_log) || verbose < 1)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
(void) printf("\n ZIL header: claim_txg %llu, "
|
(void) printf("\n ZIL header: claim_txg %llu, "
|
||||||
|
@ -18,17 +18,19 @@
|
|||||||
.\" information: Portions Copyright [yyyy] [name of copyright owner]
|
.\" information: Portions Copyright [yyyy] [name of copyright owner]
|
||||||
.\"
|
.\"
|
||||||
.\" Copyright (c) 2010, Sun Microsystems, Inc. All Rights Reserved.
|
.\" Copyright (c) 2010, Sun Microsystems, Inc. All Rights Reserved.
|
||||||
.\" Copyright (c) 2012 by Delphix. All rights reserved.
|
.\" Copyright (c) 2013 by Delphix. All rights reserved.
|
||||||
.\" Copyright (c) 2011, Pawel Jakub Dawidek <pjd@FreeBSD.org>
|
.\" Copyright (c) 2011, Pawel Jakub Dawidek <pjd@FreeBSD.org>
|
||||||
.\" Copyright (c) 2012, Glen Barber <gjb@FreeBSD.org>
|
.\" Copyright (c) 2012, Glen Barber <gjb@FreeBSD.org>
|
||||||
.\" Copyright (c) 2012, Bryan Drewery <bdrewery@FreeBSD.org>
|
.\" Copyright (c) 2012, Bryan Drewery <bdrewery@FreeBSD.org>
|
||||||
.\" Copyright (c) 2013 by Saso Kiselkov. All rights reserved.
|
.\" Copyright (c) 2013 by Saso Kiselkov. All rights reserved.
|
||||||
.\" Copyright (c) 2013 Nexenta Systems, Inc. All Rights Reserved.
|
.\" Copyright (c) 2013 Nexenta Systems, Inc. All Rights Reserved.
|
||||||
.\" Copyright (c) 2013, Joyent, Inc. All rights reserved.
|
.\" Copyright (c) 2014, Joyent, Inc. All rights reserved.
|
||||||
|
.\" Copyright (c) 2013, Steven Hartland <smh@FreeBSD.org>
|
||||||
|
.\" Copyright (c) 2014, Xin LI <delphij@FreeBSD.org>
|
||||||
.\"
|
.\"
|
||||||
.\" $FreeBSD$
|
.\" $FreeBSD$
|
||||||
.\"
|
.\"
|
||||||
.Dd September 20, 2013
|
.Dd April 23, 2014
|
||||||
.Dt ZFS 8
|
.Dt ZFS 8
|
||||||
.Os
|
.Os
|
||||||
.Sh NAME
|
.Sh NAME
|
||||||
@ -56,12 +58,17 @@
|
|||||||
.Cm destroy
|
.Cm destroy
|
||||||
.Op Fl dnpRrv
|
.Op Fl dnpRrv
|
||||||
.Sm off
|
.Sm off
|
||||||
.Ar snapshot
|
.Ar filesystem Ns | Ns volume
|
||||||
.Op % Ns Ar snapname
|
.Ns @snap
|
||||||
|
.Op % Ns Ar snap
|
||||||
|
.Op , Ns Ar snap Op % Ns Ar snap
|
||||||
.Op , Ns ...
|
.Op , Ns ...
|
||||||
.Sm on
|
.Sm on
|
||||||
.Nm
|
.Nm
|
||||||
.Cm snapshot
|
.Cm destroy
|
||||||
|
.Ar filesystem Ns | Ns Ar volume Ns # Ns Ar bookmark
|
||||||
|
.Nm
|
||||||
|
.Cm snapshot Ns | Ns Cm snap
|
||||||
.Op Fl r
|
.Op Fl r
|
||||||
.Oo Fl o Ar property Ns = Ns Ar value Oc Ns ...
|
.Oo Fl o Ar property Ns = Ns Ar value Oc Ns ...
|
||||||
.Ar filesystem@snapname Ns | Ns Ar volume@snapname
|
.Ar filesystem@snapname Ns | Ns Ar volume@snapname
|
||||||
@ -101,7 +108,7 @@
|
|||||||
.Nm
|
.Nm
|
||||||
.Cm list
|
.Cm list
|
||||||
.Op Fl r Ns | Ns Fl d Ar depth
|
.Op Fl r Ns | Ns Fl d Ar depth
|
||||||
.Op Fl H
|
.Op Fl Hp
|
||||||
.Op Fl o Ar property Ns Oo , Ns property Ns Oc Ns ...
|
.Op Fl o Ar property Ns Oo , Ns property Ns Oc Ns ...
|
||||||
.Op Fl t Ar type Ns Oo , Ns type Ns Oc Ns ...
|
.Op Fl t Ar type Ns Oo , Ns type Ns Oc Ns ...
|
||||||
.Oo Fl s Ar property Oc Ns ...
|
.Oo Fl s Ar property Oc Ns ...
|
||||||
@ -157,7 +164,7 @@
|
|||||||
.Op Fl o Ar property Ns Oo , Ns Ar property Oc Ns ...
|
.Op Fl o Ar property Ns Oo , Ns Ar property Oc Ns ...
|
||||||
.Fl a | Ar filesystem
|
.Fl a | Ar filesystem
|
||||||
.Nm
|
.Nm
|
||||||
.Cm unmount
|
.Cm unmount Ns | Ns Cm umount
|
||||||
.Op Fl f
|
.Op Fl f
|
||||||
.Fl a | Ar filesystem Ns | Ns Ar mountpoint
|
.Fl a | Ar filesystem Ns | Ns Ar mountpoint
|
||||||
.Nm
|
.Nm
|
||||||
@ -167,16 +174,24 @@
|
|||||||
.Cm unshare
|
.Cm unshare
|
||||||
.Fl a | Ar filesystem Ns | Ns Ar mountpoint
|
.Fl a | Ar filesystem Ns | Ns Ar mountpoint
|
||||||
.Nm
|
.Nm
|
||||||
|
.Cm bookmark
|
||||||
|
.Ar snapshot
|
||||||
|
.Ar bookmark
|
||||||
|
.Nm
|
||||||
.Cm send
|
.Cm send
|
||||||
.Op Fl DnPpRv
|
.Op Fl DnPpRv
|
||||||
.Op Fl i Ar snapshot | Fl I Ar snapshot
|
.Op Fl i Ar snapshot | Fl I Ar snapshot
|
||||||
.Ar snapshot
|
.Ar snapshot
|
||||||
.Nm
|
.Nm
|
||||||
.Cm receive
|
.Cm send
|
||||||
|
.Op Fl i Ar snapshot Ns | Ns bookmark
|
||||||
|
.Ar filesystem Ns | Ns Ar volume Ns | Ns Ar snapshot
|
||||||
|
.Nm
|
||||||
|
.Cm receive Ns | Ns Cm recv
|
||||||
.Op Fl vnFu
|
.Op Fl vnFu
|
||||||
.Ar filesystem Ns | Ns Ar volume Ns | Ns Ar snapshot
|
.Ar filesystem Ns | Ns Ar volume Ns | Ns Ar snapshot
|
||||||
.Nm
|
.Nm
|
||||||
.Cm receive
|
.Cm receive Ns | Ns Cm recv
|
||||||
.Op Fl vnFu
|
.Op Fl vnFu
|
||||||
.Op Fl d | e
|
.Op Fl d | e
|
||||||
.Ar filesystem
|
.Ar filesystem
|
||||||
@ -527,6 +542,13 @@ if the snapshot has been marked for deferred destroy by using the
|
|||||||
.Qq Nm Cm destroy -d
|
.Qq Nm Cm destroy -d
|
||||||
command. Otherwise, the property is
|
command. Otherwise, the property is
|
||||||
.Cm off .
|
.Cm off .
|
||||||
|
.It Sy filesystem_count
|
||||||
|
The total number of filesystems and volumes that exist under this location in the
|
||||||
|
dataset tree.
|
||||||
|
This value is only available when a
|
||||||
|
.Sy filesystem_limit
|
||||||
|
has
|
||||||
|
been set somewhere in the tree under which the dataset resides.
|
||||||
.It Sy logicalreferenced
|
.It Sy logicalreferenced
|
||||||
The amount of space that is
|
The amount of space that is
|
||||||
.Qq logically
|
.Qq logically
|
||||||
@ -585,6 +607,12 @@ The compression ratio achieved for the
|
|||||||
space of this dataset, expressed as a multiplier. See also the
|
space of this dataset, expressed as a multiplier. See also the
|
||||||
.Sy compressratio
|
.Sy compressratio
|
||||||
property.
|
property.
|
||||||
|
.It Sy snapshot_count
|
||||||
|
The total number of snapshots that exist under this location in the dataset tree.
|
||||||
|
This value is only available when a
|
||||||
|
.Sy snapshot_limit
|
||||||
|
has been set somewhere
|
||||||
|
in the tree under which the dataset resides.
|
||||||
.It Sy type
|
.It Sy type
|
||||||
The type of dataset:
|
The type of dataset:
|
||||||
.Sy filesystem , volume , No or Sy snapshot .
|
.Sy filesystem , volume , No or Sy snapshot .
|
||||||
@ -1005,6 +1033,23 @@ The
|
|||||||
.Sy mlslabel
|
.Sy mlslabel
|
||||||
property is currently not supported on
|
property is currently not supported on
|
||||||
.Fx .
|
.Fx .
|
||||||
|
.It Sy filesystem_limit Ns = Ns Ar count | Cm none
|
||||||
|
Limits the number of filesystems and volumes that can exist under this point in
|
||||||
|
the dataset tree.
|
||||||
|
The limit is not enforced if the user is allowed to change
|
||||||
|
the limit.
|
||||||
|
Setting a
|
||||||
|
.Sy filesystem_limit
|
||||||
|
on a descendent of a filesystem that
|
||||||
|
already has a
|
||||||
|
.Sy filesystem_limit
|
||||||
|
does not override the ancestor's
|
||||||
|
.Sy filesystem_limit ,
|
||||||
|
but rather imposes an additional limit.
|
||||||
|
This feature must be enabled to be used
|
||||||
|
.Po see
|
||||||
|
.Xr zpool-features 7
|
||||||
|
.Pc .
|
||||||
.It Sy mountpoint Ns = Ns Ar path | Cm none | legacy
|
.It Sy mountpoint Ns = Ns Ar path | Cm none | legacy
|
||||||
Controls the mount point used for this file system. See the
|
Controls the mount point used for this file system. See the
|
||||||
.Qq Sx Mount Points
|
.Qq Sx Mount Points
|
||||||
@ -1046,6 +1091,27 @@ the ancestor's quota, but rather imposes an additional limit.
|
|||||||
Quotas cannot be set on volumes, as the
|
Quotas cannot be set on volumes, as the
|
||||||
.Sy volsize
|
.Sy volsize
|
||||||
property acts as an implicit quota.
|
property acts as an implicit quota.
|
||||||
|
.It Sy snapshot_limit Ns = Ns Ar count | Cm none
|
||||||
|
Limits the number of snapshots that can be created on a dataset and its
|
||||||
|
descendents.
|
||||||
|
Setting a
|
||||||
|
.Sy snapshot_limit
|
||||||
|
on a descendent of a dataset that already
|
||||||
|
has a
|
||||||
|
.Sy snapshot_limit
|
||||||
|
does not override the ancestor's
|
||||||
|
.Sy snapshot_limit ,
|
||||||
|
but
|
||||||
|
rather imposes an additional limit.
|
||||||
|
The limit is not enforced if the user is
|
||||||
|
allowed to change the limit.
|
||||||
|
For example, this means that recursive snapshots
|
||||||
|
taken from the global zone are counted against each delegated dataset within
|
||||||
|
a jail.
|
||||||
|
This feature must be enabled to be used
|
||||||
|
.Po see
|
||||||
|
.Xr zpool-features 7
|
||||||
|
.Pc .
|
||||||
.It Sy userquota@ Ns Ar user Ns = Ns Ar size | Cm none
|
.It Sy userquota@ Ns Ar user Ns = Ns Ar size | Cm none
|
||||||
Limits the amount of space consumed by the specified user.
|
Limits the amount of space consumed by the specified user.
|
||||||
Similar to the
|
Similar to the
|
||||||
@ -1291,6 +1357,38 @@ Consequently, writes to a sparse volume can fail with
|
|||||||
when the pool is low on space. For a sparse volume, changes to
|
when the pool is low on space. For a sparse volume, changes to
|
||||||
.Sy volsize
|
.Sy volsize
|
||||||
are not reflected in the reservation.
|
are not reflected in the reservation.
|
||||||
|
.It Sy volmode Ns = Ns Cm default | geom | dev | none
|
||||||
|
This property specifies how volumes should be exposed to the OS.
|
||||||
|
Setting it to
|
||||||
|
.Sy geom
|
||||||
|
exposes volumes as
|
||||||
|
.Xr geom 4
|
||||||
|
providers, providing maximal functionality.
|
||||||
|
Setting it to
|
||||||
|
.Sy dev
|
||||||
|
exposes volumes only as cdev device in devfs.
|
||||||
|
Such volumes can be accessed only as raw disk device files, i.e. they
|
||||||
|
can not be partitioned, mounted, participate in RAIDs, etc, but they
|
||||||
|
are faster, and in some use scenarios with untrusted consumer, such as
|
||||||
|
NAS or VM storage, can be more safe.
|
||||||
|
Volumes with property set to
|
||||||
|
.Sy none
|
||||||
|
are not exposed outside ZFS, but can be snapshoted, cloned, replicated, etc,
|
||||||
|
that can be suitable for backup purposes.
|
||||||
|
Value
|
||||||
|
.Sy default
|
||||||
|
means that volumes exposition is controlled by system-wide sysctl/tunable
|
||||||
|
.Va vfs.zfs.vol.mode ,
|
||||||
|
where
|
||||||
|
.Sy geom ,
|
||||||
|
.Sy dev
|
||||||
|
and
|
||||||
|
.Sy none
|
||||||
|
are encoded as 1, 2 and 3 respectively.
|
||||||
|
The default values is
|
||||||
|
.Sy geom .
|
||||||
|
This property can be changed any time, but so far it is processed only
|
||||||
|
during volume creation and pool import.
|
||||||
.It Sy vscan Ns = Ns Cm off | on
|
.It Sy vscan Ns = Ns Cm off | on
|
||||||
The
|
The
|
||||||
.Sy vscan
|
.Sy vscan
|
||||||
@ -1320,10 +1418,21 @@ features being supported, the new file system will have the default values for
|
|||||||
these properties.
|
these properties.
|
||||||
.Bl -tag -width 4n
|
.Bl -tag -width 4n
|
||||||
.It Sy casesensitivity Ns = Ns Cm sensitive | insensitive | mixed
|
.It Sy casesensitivity Ns = Ns Cm sensitive | insensitive | mixed
|
||||||
The
|
Indicates whether the file name matching algorithm used by the file system
|
||||||
|
should be case-sensitive, case-insensitive, or allow a combination of both
|
||||||
|
styles of matching. The default value for the
|
||||||
.Sy casesensitivity
|
.Sy casesensitivity
|
||||||
property is currently not supported on
|
property is
|
||||||
.Fx .
|
.Cm sensitive .
|
||||||
|
Traditionally, UNIX and POSIX file systems have case-sensitive file names.
|
||||||
|
.Pp
|
||||||
|
The
|
||||||
|
.Cm mixed
|
||||||
|
value for the
|
||||||
|
.Sy casesensitivity
|
||||||
|
property indicates that the
|
||||||
|
file system can support requests for both case-sensitive and case-insensitive
|
||||||
|
matching behavior.
|
||||||
.It Sy normalization Ns = Ns Cm none | formC | formD | formKC | formKD
|
.It Sy normalization Ns = Ns Cm none | formC | formD | formKC | formKD
|
||||||
Indicates whether the file system should perform a
|
Indicates whether the file system should perform a
|
||||||
.Sy unicode
|
.Sy unicode
|
||||||
@ -1653,7 +1762,14 @@ options, as they can destroy large portions of a pool and cause unexpected
|
|||||||
behavior for mounted file systems in use.
|
behavior for mounted file systems in use.
|
||||||
.It Xo
|
.It Xo
|
||||||
.Nm
|
.Nm
|
||||||
.Cm snapshot
|
.Cm destroy
|
||||||
|
.Ar filesystem Ns | Ns Ar volume Ns # Ns Ar bookmark
|
||||||
|
.Xc
|
||||||
|
.Pp
|
||||||
|
The given bookmark is destroyed.
|
||||||
|
.It Xo
|
||||||
|
.Nm
|
||||||
|
.Cm snapshot Ns | Ns Cm snap
|
||||||
.Op Fl r
|
.Op Fl r
|
||||||
.Oo Fl o Ar property Ns = Ns Ar value Oc Ns ...
|
.Oo Fl o Ar property Ns = Ns Ar value Oc Ns ...
|
||||||
.Ar filesystem@snapname Ns | Ns volume@snapname
|
.Ar filesystem@snapname Ns | Ns volume@snapname
|
||||||
@ -1685,14 +1801,24 @@ Roll back the given dataset to a previous snapshot. When a dataset is rolled
|
|||||||
back, all data that has changed since the snapshot is discarded, and the
|
back, all data that has changed since the snapshot is discarded, and the
|
||||||
dataset reverts to the state at the time of the snapshot. By default, the
|
dataset reverts to the state at the time of the snapshot. By default, the
|
||||||
command refuses to roll back to a snapshot other than the most recent one. In
|
command refuses to roll back to a snapshot other than the most recent one. In
|
||||||
order to do so, all intermediate snapshots must be destroyed by specifying the
|
order to do so, all intermediate snapshots and bookmarks must be destroyed
|
||||||
|
by specifying the
|
||||||
.Fl r
|
.Fl r
|
||||||
option.
|
option.
|
||||||
|
.Pp
|
||||||
|
The
|
||||||
|
.Fl rR
|
||||||
|
options do not recursively destroy the child snapshots of a
|
||||||
|
recursive snapshot.
|
||||||
|
Only direct snapshots of the specified filesystem
|
||||||
|
are destroyed by either of these options.
|
||||||
|
To completely roll back a
|
||||||
|
recursive snapshot, you must rollback the individual child snapshots.
|
||||||
.Bl -tag -width indent
|
.Bl -tag -width indent
|
||||||
.It Fl r
|
.It Fl r
|
||||||
Recursively destroy any snapshots more recent than the one specified.
|
Destroy any snapshots and bookmarks more recent than the one specified.
|
||||||
.It Fl R
|
.It Fl R
|
||||||
Recursively destroy any more recent snapshots, as well as any clones of those
|
Destroy any more recent snapshots and bookmarks, as well as any clones of those
|
||||||
snapshots.
|
snapshots.
|
||||||
.It Fl f
|
.It Fl f
|
||||||
Used with the
|
Used with the
|
||||||
@ -1806,7 +1932,7 @@ only dataset that can be renamed recursively.
|
|||||||
.Nm
|
.Nm
|
||||||
.Cm list
|
.Cm list
|
||||||
.Op Fl r Ns | Ns Fl d Ar depth
|
.Op Fl r Ns | Ns Fl d Ar depth
|
||||||
.Op Fl H
|
.Op Fl Hp
|
||||||
.Op Fl o Ar property Ns Oo , Ns Ar property Oc Ns ...
|
.Op Fl o Ar property Ns Oo , Ns Ar property Oc Ns ...
|
||||||
.Op Fl t Ar type Ns Oo , Ns Ar type Oc Ns ...
|
.Op Fl t Ar type Ns Oo , Ns Ar type Oc Ns ...
|
||||||
.Oo Fl s Ar property Oc Ns ...
|
.Oo Fl s Ar property Oc Ns ...
|
||||||
@ -1837,6 +1963,8 @@ will display only the dataset and its direct children.
|
|||||||
.It Fl H
|
.It Fl H
|
||||||
Used for scripting mode. Do not print headers and separate fields by a single
|
Used for scripting mode. Do not print headers and separate fields by a single
|
||||||
tab instead of arbitrary white space.
|
tab instead of arbitrary white space.
|
||||||
|
.It Fl p
|
||||||
|
Display numbers in parsable (exact) values.
|
||||||
.It Fl o Ar property Ns Oo , Ns Ar property Oc Ns ...
|
.It Fl o Ar property Ns Oo , Ns Ar property Oc Ns ...
|
||||||
A comma-separated list of properties to display. The property must be:
|
A comma-separated list of properties to display. The property must be:
|
||||||
.Bl -bullet -offset 2n
|
.Bl -bullet -offset 2n
|
||||||
@ -1865,7 +1993,7 @@ syntax.
|
|||||||
A comma-separated list of types to display, where
|
A comma-separated list of types to display, where
|
||||||
.Ar type
|
.Ar type
|
||||||
is one of
|
is one of
|
||||||
.Sy filesystem , snapshot , volume , No or Sy all .
|
.Sy filesystem , snapshot , snap , volume , bookmark , No or Sy all .
|
||||||
For example, specifying
|
For example, specifying
|
||||||
.Fl t Cm snapshot
|
.Fl t Cm snapshot
|
||||||
displays only snapshots.
|
displays only snapshots.
|
||||||
@ -1962,7 +2090,7 @@ sections.
|
|||||||
The special value
|
The special value
|
||||||
.Cm all
|
.Cm all
|
||||||
can be used to display all properties that apply to the given dataset's type
|
can be used to display all properties that apply to the given dataset's type
|
||||||
(filesystem, volume, or snapshot).
|
(filesystem, volume, snapshot, or bookmark).
|
||||||
.Bl -tag -width indent
|
.Bl -tag -width indent
|
||||||
.It Fl r
|
.It Fl r
|
||||||
Recursively display properties for any children.
|
Recursively display properties for any children.
|
||||||
@ -1977,7 +2105,7 @@ Display output in a form more easily parsed by scripts. Any headers are
|
|||||||
omitted, and fields are explicitly separated by a single tab instead of an
|
omitted, and fields are explicitly separated by a single tab instead of an
|
||||||
arbitrary amount of space.
|
arbitrary amount of space.
|
||||||
.It Fl p
|
.It Fl p
|
||||||
Display numbers in parseable (exact) values.
|
Display numbers in parsable (exact) values.
|
||||||
.It Fl o Cm all | Ar field Ns Oo , Ns Ar field Oc Ns ...
|
.It Fl o Cm all | Ar field Ns Oo , Ns Ar field Oc Ns ...
|
||||||
A comma-separated list of columns to display. Supported values are
|
A comma-separated list of columns to display. Supported values are
|
||||||
.Sy name,property,value,received,source .
|
.Sy name,property,value,received,source .
|
||||||
@ -2194,7 +2322,7 @@ Mount the specified filesystem.
|
|||||||
.El
|
.El
|
||||||
.It Xo
|
.It Xo
|
||||||
.Nm
|
.Nm
|
||||||
.Cm unmount
|
.Cm unmount Ns | Ns Cm umount
|
||||||
.Op Fl f
|
.Op Fl f
|
||||||
.Fl a | Ar filesystem Ns | Ns Ar mountpoint
|
.Fl a | Ar filesystem Ns | Ns Ar mountpoint
|
||||||
.Xc
|
.Xc
|
||||||
@ -2280,6 +2408,26 @@ file system shared on the system.
|
|||||||
.El
|
.El
|
||||||
.It Xo
|
.It Xo
|
||||||
.Nm
|
.Nm
|
||||||
|
.Cm bookmark
|
||||||
|
.Ar snapshot
|
||||||
|
.Ar bookmark
|
||||||
|
.Xc
|
||||||
|
.Pp
|
||||||
|
Creates a bookmark of the given snapshot.
|
||||||
|
Bookmarks mark the point in time
|
||||||
|
when the snapshot was created, and can be used as the incremental source for
|
||||||
|
a
|
||||||
|
.Qq Nm Cm send
|
||||||
|
command.
|
||||||
|
.Pp
|
||||||
|
This feature must be enabled to be used.
|
||||||
|
See
|
||||||
|
.Xr zpool-features 7
|
||||||
|
for details on ZFS feature flags and the
|
||||||
|
.Sy bookmark
|
||||||
|
feature.
|
||||||
|
.It Xo
|
||||||
|
.Nm
|
||||||
.Cm send
|
.Cm send
|
||||||
.Op Fl DnPpRv
|
.Op Fl DnPpRv
|
||||||
.Op Fl i Ar snapshot | Fl I Ar snapshot
|
.Op Fl i Ar snapshot | Fl I Ar snapshot
|
||||||
@ -2298,17 +2446,15 @@ a file or to a different system (for example, using
|
|||||||
By default, a full stream is generated.
|
By default, a full stream is generated.
|
||||||
.Bl -tag -width indent
|
.Bl -tag -width indent
|
||||||
.It Fl i Ar snapshot
|
.It Fl i Ar snapshot
|
||||||
Generate an incremental stream from the
|
Generate an incremental stream from the first
|
||||||
.Fl i Ar snapshot
|
.Ar snapshot Pq the incremental source
|
||||||
to the last
|
to the second
|
||||||
.Ar snapshot .
|
.Ar snapshot Pq the incremental target .
|
||||||
The incremental source (the
|
The incremental source can be specified as the last component of the
|
||||||
.Fl i Ar snapshot )
|
snapshot name
|
||||||
can be specified as the last component of the snapshot name (for example, the
|
.Pq the Em @ No character and following
|
||||||
part after the
|
and
|
||||||
.Sy @ ) ,
|
it is assumed to be from the same file system as the incremental target.
|
||||||
and it is assumed to be from the same file system as the last
|
|
||||||
.Ar snapshot .
|
|
||||||
.Pp
|
.Pp
|
||||||
If the destination is a clone, the source may be the origin snapshot, which
|
If the destination is a clone, the source may be the origin snapshot, which
|
||||||
must be fully specified (for example,
|
must be fully specified (for example,
|
||||||
@ -2316,15 +2462,16 @@ must be fully specified (for example,
|
|||||||
not just
|
not just
|
||||||
.Cm @origin ) .
|
.Cm @origin ) .
|
||||||
.It Fl I Ar snapshot
|
.It Fl I Ar snapshot
|
||||||
Generate a stream package that sends all intermediary snapshots from the
|
Generate a stream package that sends all intermediary snapshots from the first
|
||||||
.Fl I Ar snapshot
|
.Ar snapshot
|
||||||
to the last
|
to the second
|
||||||
.Ar snapshot .
|
.Ar snapshot .
|
||||||
For example,
|
For example,
|
||||||
.Ic -I @a fs@d
|
.Ic -I @a fs@d
|
||||||
is similar to
|
is similar to
|
||||||
.Ic -i @a fs@b; -i @b fs@c; -i @c fs@d .
|
.Ic -i @a fs@b; -i @b fs@c; -i @c fs@d .
|
||||||
The incremental source snapshot may be specified as with the
|
The incremental
|
||||||
|
source may be specified as with the
|
||||||
.Fl i
|
.Fl i
|
||||||
option.
|
option.
|
||||||
.It Fl R
|
.It Fl R
|
||||||
@ -2377,13 +2524,42 @@ on future versions of
|
|||||||
.Tn ZFS .
|
.Tn ZFS .
|
||||||
.It Xo
|
.It Xo
|
||||||
.Nm
|
.Nm
|
||||||
.Cm receive
|
.Cm send
|
||||||
|
.Op Fl i Ar snapshot Ns | Ns Ar bookmark
|
||||||
|
.Ar filesystem Ns | Ns Ar volume Ns | Ns Ar snapshot
|
||||||
|
.Xc
|
||||||
|
.Pp
|
||||||
|
Generate a send stream, which may be of a filesystem, and may be
|
||||||
|
incremental from a bookmark.
|
||||||
|
If the destination is a filesystem or volume,
|
||||||
|
the pool must be read-only, or the filesystem must not be mounted.
|
||||||
|
When the
|
||||||
|
stream generated from a filesystem or volume is received, the default snapshot
|
||||||
|
name will be
|
||||||
|
.Pq --head-- .
|
||||||
|
.Bl -tag -width indent
|
||||||
|
.It Fl i Ar snapshot Ns | Ns bookmark
|
||||||
|
Generate an incremental send stream.
|
||||||
|
The incremental source must be an earlier
|
||||||
|
snapshot in the destination's history.
|
||||||
|
It will commonly be an earlier
|
||||||
|
snapshot in the destination's filesystem, in which case it can be
|
||||||
|
specified as the last component of the name
|
||||||
|
.Pq the Em # No or Em @ No character and following .
|
||||||
|
.Pp
|
||||||
|
If the incremental target is a clone, the incremental source can
|
||||||
|
be the origin snapshot, or an earlier snapshot in the origin's filesystem,
|
||||||
|
or the origin's origin, etc.
|
||||||
|
.El
|
||||||
|
.It Xo
|
||||||
|
.Nm
|
||||||
|
.Cm receive Ns | Ns Cm recv
|
||||||
.Op Fl vnFu
|
.Op Fl vnFu
|
||||||
.Ar filesystem Ns | Ns Ar volume Ns | Ns Ar snapshot
|
.Ar filesystem Ns | Ns Ar volume Ns | Ns Ar snapshot
|
||||||
.Xc
|
.Xc
|
||||||
.It Xo
|
.It Xo
|
||||||
.Nm
|
.Nm
|
||||||
.Cm receive
|
.Cm receive Ns | Ns Cm recv
|
||||||
.Op Fl vnFu
|
.Op Fl vnFu
|
||||||
.Op Fl d | e
|
.Op Fl d | e
|
||||||
.Ar filesystem
|
.Ar filesystem
|
||||||
@ -2474,7 +2650,7 @@ option to verify the name the receive operation would use.
|
|||||||
Force a rollback of the file system to the most recent snapshot before
|
Force a rollback of the file system to the most recent snapshot before
|
||||||
performing the receive operation. If receiving an incremental replication
|
performing the receive operation. If receiving an incremental replication
|
||||||
stream (for example, one generated by
|
stream (for example, one generated by
|
||||||
.Qq Nm Cm send Fl R Fi iI ) ,
|
.Qq Nm Cm send Fl R Bro Fl i | Fl I Brc ) ,
|
||||||
destroy snapshots and file systems that do not exist on the sending side.
|
destroy snapshots and file systems that do not exist on the sending side.
|
||||||
.El
|
.El
|
||||||
.It Xo
|
.It Xo
|
||||||
@ -2613,6 +2789,7 @@ protocol
|
|||||||
.It dedup Ta property
|
.It dedup Ta property
|
||||||
.It devices Ta property
|
.It devices Ta property
|
||||||
.It exec Ta property
|
.It exec Ta property
|
||||||
|
.It filesystem_limit Ta property
|
||||||
.It logbias Ta property
|
.It logbias Ta property
|
||||||
.It jailed Ta property
|
.It jailed Ta property
|
||||||
.It mlslabel Ta property
|
.It mlslabel Ta property
|
||||||
@ -2631,6 +2808,7 @@ protocol
|
|||||||
.It sharenfs Ta property
|
.It sharenfs Ta property
|
||||||
.It sharesmb Ta property
|
.It sharesmb Ta property
|
||||||
.It snapdir Ta property
|
.It snapdir Ta property
|
||||||
|
.It snapshot_limit Ta property
|
||||||
.It sync Ta property
|
.It sync Ta property
|
||||||
.It utf8only Ta property
|
.It utf8only Ta property
|
||||||
.It version Ta property
|
.It version Ta property
|
||||||
@ -2819,7 +2997,7 @@ option of
|
|||||||
.It \&P Ta event port (not supported on Fx )
|
.It \&P Ta event port (not supported on Fx )
|
||||||
.El
|
.El
|
||||||
.It Fl H
|
.It Fl H
|
||||||
Give more parseable tab-separated output, without header lines and without
|
Give more parsable tab-separated output, without header lines and without
|
||||||
arrows.
|
arrows.
|
||||||
.It Fl t
|
.It Fl t
|
||||||
Display the path's inode change time as the first column of output.
|
Display the path's inode change time as the first column of output.
|
||||||
@ -2977,10 +3155,12 @@ pool/home/bob compression on local
|
|||||||
pool/home/bob atime on default
|
pool/home/bob atime on default
|
||||||
pool/home/bob devices on default
|
pool/home/bob devices on default
|
||||||
pool/home/bob exec on default
|
pool/home/bob exec on default
|
||||||
|
pool/home/bob filesystem_limit none default
|
||||||
pool/home/bob setuid on default
|
pool/home/bob setuid on default
|
||||||
pool/home/bob readonly off default
|
pool/home/bob readonly off default
|
||||||
pool/home/bob jailed off default
|
pool/home/bob jailed off default
|
||||||
pool/home/bob snapdir hidden default
|
pool/home/bob snapdir hidden default
|
||||||
|
pool/home/bob snapshot_limit none default
|
||||||
pool/home/bob aclmode discard default
|
pool/home/bob aclmode discard default
|
||||||
pool/home/bob aclinherit restricted default
|
pool/home/bob aclinherit restricted default
|
||||||
pool/home/bob canmount on default
|
pool/home/bob canmount on default
|
||||||
|
@ -18,10 +18,13 @@
|
|||||||
*
|
*
|
||||||
* CDDL HEADER END
|
* CDDL HEADER END
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||||
* Copyright (c) 2012 Pawel Jakub Dawidek <pawel@dawidek.net>.
|
* Copyright (c) 2012 Pawel Jakub Dawidek <pawel@dawidek.net>.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
|
* Copyright 2013 Nexenta Systems, Inc. All rights reserved.
|
||||||
|
* Copyright (c) 2013 by Delphix. All rights reserved.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <libintl.h>
|
#include <libintl.h>
|
||||||
@ -70,7 +73,7 @@ uu_avl_pool_t *avl_pool;
|
|||||||
* Include snaps if they were requested or if this a zfs list where types
|
* 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.
|
* were not specified and the "listsnapshots" property is set on this pool.
|
||||||
*/
|
*/
|
||||||
static int
|
static boolean_t
|
||||||
zfs_include_snapshots(zfs_handle_t *zhp, callback_data_t *cb)
|
zfs_include_snapshots(zfs_handle_t *zhp, callback_data_t *cb)
|
||||||
{
|
{
|
||||||
zpool_handle_t *zph;
|
zpool_handle_t *zph;
|
||||||
@ -90,8 +93,9 @@ static int
|
|||||||
zfs_callback(zfs_handle_t *zhp, void *data)
|
zfs_callback(zfs_handle_t *zhp, void *data)
|
||||||
{
|
{
|
||||||
callback_data_t *cb = data;
|
callback_data_t *cb = data;
|
||||||
int dontclose = 0;
|
boolean_t dontclose = B_FALSE;
|
||||||
int include_snaps = zfs_include_snapshots(zhp, cb);
|
boolean_t include_snaps = zfs_include_snapshots(zhp, cb);
|
||||||
|
boolean_t include_bmarks = (cb->cb_types & ZFS_TYPE_BOOKMARK);
|
||||||
|
|
||||||
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)) {
|
((zfs_get_type(zhp) == ZFS_TYPE_SNAPSHOT) && include_snaps)) {
|
||||||
@ -109,14 +113,15 @@ zfs_callback(zfs_handle_t *zhp, void *data)
|
|||||||
cb->cb_props_table);
|
cb->cb_props_table);
|
||||||
|
|
||||||
if (zfs_expand_proplist(zhp, cb->cb_proplist,
|
if (zfs_expand_proplist(zhp, cb->cb_proplist,
|
||||||
(cb->cb_flags & ZFS_ITER_RECVD_PROPS))
|
(cb->cb_flags & ZFS_ITER_RECVD_PROPS),
|
||||||
|
(cb->cb_flags & ZFS_ITER_LITERAL_PROPS))
|
||||||
!= 0) {
|
!= 0) {
|
||||||
free(node);
|
free(node);
|
||||||
return (-1);
|
return (-1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
uu_avl_insert(cb->cb_avl, node, idx);
|
uu_avl_insert(cb->cb_avl, node, idx);
|
||||||
dontclose = 1;
|
dontclose = B_TRUE;
|
||||||
} else {
|
} else {
|
||||||
free(node);
|
free(node);
|
||||||
}
|
}
|
||||||
@ -131,11 +136,14 @@ zfs_callback(zfs_handle_t *zhp, void *data)
|
|||||||
cb->cb_depth++;
|
cb->cb_depth++;
|
||||||
if (zfs_get_type(zhp) == ZFS_TYPE_FILESYSTEM)
|
if (zfs_get_type(zhp) == ZFS_TYPE_FILESYSTEM)
|
||||||
(void) zfs_iter_filesystems(zhp, zfs_callback, data);
|
(void) zfs_iter_filesystems(zhp, zfs_callback, data);
|
||||||
if ((zfs_get_type(zhp) != ZFS_TYPE_SNAPSHOT) && include_snaps) {
|
if (((zfs_get_type(zhp) & (ZFS_TYPE_SNAPSHOT |
|
||||||
|
ZFS_TYPE_BOOKMARK)) == 0) && include_snaps)
|
||||||
(void) zfs_iter_snapshots(zhp,
|
(void) zfs_iter_snapshots(zhp,
|
||||||
(cb->cb_flags & ZFS_ITER_SIMPLE) != 0, zfs_callback,
|
(cb->cb_flags & ZFS_ITER_SIMPLE) != 0, zfs_callback,
|
||||||
data);
|
data);
|
||||||
}
|
if (((zfs_get_type(zhp) & (ZFS_TYPE_SNAPSHOT |
|
||||||
|
ZFS_TYPE_BOOKMARK)) == 0) && include_bmarks)
|
||||||
|
(void) zfs_iter_bookmarks(zhp, zfs_callback, data);
|
||||||
cb->cb_depth--;
|
cb->cb_depth--;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18,9 +18,11 @@
|
|||||||
*
|
*
|
||||||
* CDDL HEADER END
|
* CDDL HEADER END
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
|
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
|
||||||
* Use is subject to license terms.
|
* Use is subject to license terms.
|
||||||
|
* Copyright 2013 Nexenta Systems, Inc. All rights reserved.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef ZFS_ITER_H
|
#ifndef ZFS_ITER_H
|
||||||
@ -44,6 +46,7 @@ typedef struct zfs_sort_column {
|
|||||||
#define ZFS_ITER_DEPTH_LIMIT (1 << 3)
|
#define ZFS_ITER_DEPTH_LIMIT (1 << 3)
|
||||||
#define ZFS_ITER_RECVD_PROPS (1 << 4)
|
#define ZFS_ITER_RECVD_PROPS (1 << 4)
|
||||||
#define ZFS_ITER_SIMPLE (1 << 5)
|
#define ZFS_ITER_SIMPLE (1 << 5)
|
||||||
|
#define ZFS_ITER_LITERAL_PROPS (1 << 6)
|
||||||
|
|
||||||
int zfs_for_each(int, char **, int options, zfs_type_t,
|
int zfs_for_each(int, char **, int options, zfs_type_t,
|
||||||
zfs_sort_column_t *, zprop_list_t **, int, zfs_iter_f, void *);
|
zfs_sort_column_t *, zprop_list_t **, int, zfs_iter_f, void *);
|
||||||
|
@ -21,14 +21,14 @@
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||||
* Copyright 2012 Nexenta Systems, Inc. All rights reserved.
|
* Copyright (c) 2013 by Delphix. All rights reserved.
|
||||||
* Copyright (c) 2012 by Delphix. All rights reserved.
|
|
||||||
* Copyright 2012 Milan Jurik. All rights reserved.
|
* Copyright 2012 Milan Jurik. All rights reserved.
|
||||||
* Copyright (c) 2012, Joyent, Inc. All rights reserved.
|
* Copyright (c) 2012, Joyent, Inc. All rights reserved.
|
||||||
* Copyright (c) 2011-2012 Pawel Jakub Dawidek <pawel@dawidek.net>.
|
* Copyright (c) 2011-2012 Pawel Jakub Dawidek <pawel@dawidek.net>.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
* Copyright (c) 2012 Martin Matuska <mm@FreeBSD.org>. All rights reserved.
|
* Copyright (c) 2012 Martin Matuska <mm@FreeBSD.org>. All rights reserved.
|
||||||
* Copyright (c) 2013 Steven Hartland. All rights reserved.
|
* Copyright (c) 2013 Steven Hartland. All rights reserved.
|
||||||
|
* Copyright 2013 Nexenta Systems, Inc. All rights reserved.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
@ -107,6 +107,7 @@ static int zfs_do_release(int argc, char **argv);
|
|||||||
static int zfs_do_diff(int argc, char **argv);
|
static int zfs_do_diff(int argc, char **argv);
|
||||||
static int zfs_do_jail(int argc, char **argv);
|
static int zfs_do_jail(int argc, char **argv);
|
||||||
static int zfs_do_unjail(int argc, char **argv);
|
static int zfs_do_unjail(int argc, char **argv);
|
||||||
|
static int zfs_do_bookmark(int argc, char **argv);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Enable a reasonable set of defaults for libumem debugging on DEBUG builds.
|
* Enable a reasonable set of defaults for libumem debugging on DEBUG builds.
|
||||||
@ -155,6 +156,7 @@ typedef enum {
|
|||||||
HELP_HOLDS,
|
HELP_HOLDS,
|
||||||
HELP_RELEASE,
|
HELP_RELEASE,
|
||||||
HELP_DIFF,
|
HELP_DIFF,
|
||||||
|
HELP_BOOKMARK,
|
||||||
} zfs_help_t;
|
} zfs_help_t;
|
||||||
|
|
||||||
typedef struct zfs_command {
|
typedef struct zfs_command {
|
||||||
@ -181,6 +183,7 @@ static zfs_command_t command_table[] = {
|
|||||||
{ "clone", zfs_do_clone, HELP_CLONE },
|
{ "clone", zfs_do_clone, HELP_CLONE },
|
||||||
{ "promote", zfs_do_promote, HELP_PROMOTE },
|
{ "promote", zfs_do_promote, HELP_PROMOTE },
|
||||||
{ "rename", zfs_do_rename, HELP_RENAME },
|
{ "rename", zfs_do_rename, HELP_RENAME },
|
||||||
|
{ "bookmark", zfs_do_bookmark, HELP_BOOKMARK },
|
||||||
{ NULL },
|
{ NULL },
|
||||||
{ "list", zfs_do_list, HELP_LIST },
|
{ "list", zfs_do_list, HELP_LIST },
|
||||||
{ NULL },
|
{ NULL },
|
||||||
@ -231,11 +234,12 @@ get_usage(zfs_help_t idx)
|
|||||||
case HELP_DESTROY:
|
case HELP_DESTROY:
|
||||||
return (gettext("\tdestroy [-fnpRrv] <filesystem|volume>\n"
|
return (gettext("\tdestroy [-fnpRrv] <filesystem|volume>\n"
|
||||||
"\tdestroy [-dnpRrv] "
|
"\tdestroy [-dnpRrv] "
|
||||||
"<snapshot>[%<snapname>][,...]\n"));
|
"<filesystem|volume>@<snap>[%<snap>][,...]\n"
|
||||||
|
"\tdestroy <filesystem|volume>#<bookmark>\n"));
|
||||||
case HELP_GET:
|
case HELP_GET:
|
||||||
return (gettext("\tget [-rHp] [-d max] "
|
return (gettext("\tget [-rHp] [-d max] "
|
||||||
"[-o \"all\" | field[,...]] [-t type[,...]] "
|
"[-o \"all\" | field[,...]]\n"
|
||||||
"[-s source[,...]]\n"
|
"\t [-t type[,...]] [-s source[,...]]\n"
|
||||||
"\t <\"all\" | property[,...]> "
|
"\t <\"all\" | property[,...]> "
|
||||||
"[filesystem|volume|snapshot] ...\n"));
|
"[filesystem|volume|snapshot] ...\n"));
|
||||||
case HELP_INHERIT:
|
case HELP_INHERIT:
|
||||||
@ -249,9 +253,8 @@ get_usage(zfs_help_t idx)
|
|||||||
case HELP_UNJAIL:
|
case HELP_UNJAIL:
|
||||||
return (gettext("\tunjail <jailid|jailname> <filesystem>\n"));
|
return (gettext("\tunjail <jailid|jailname> <filesystem>\n"));
|
||||||
case HELP_LIST:
|
case HELP_LIST:
|
||||||
return (gettext("\tlist [-rH][-d max] "
|
return (gettext("\tlist [-Hp] [-r|-d max] [-o property[,...]] "
|
||||||
"[-o property[,...]] [-t type[,...]] [-s property] ...\n"
|
"[-s property]...\n\t [-S property]... [-t type[,...]] "
|
||||||
"\t [-S property] ... "
|
|
||||||
"[filesystem|volume|snapshot] ...\n"));
|
"[filesystem|volume|snapshot] ...\n"));
|
||||||
case HELP_MOUNT:
|
case HELP_MOUNT:
|
||||||
return (gettext("\tmount\n"
|
return (gettext("\tmount\n"
|
||||||
@ -259,31 +262,32 @@ get_usage(zfs_help_t idx)
|
|||||||
case HELP_PROMOTE:
|
case HELP_PROMOTE:
|
||||||
return (gettext("\tpromote <clone-filesystem>\n"));
|
return (gettext("\tpromote <clone-filesystem>\n"));
|
||||||
case HELP_RECEIVE:
|
case HELP_RECEIVE:
|
||||||
return (gettext("\treceive [-vnFu] <filesystem|volume|"
|
return (gettext("\treceive|recv [-vnFu] <filesystem|volume|"
|
||||||
"snapshot>\n"
|
"snapshot>\n"
|
||||||
"\treceive [-vnFu] [-d | -e] <filesystem>\n"));
|
"\treceive|recv [-vnFu] [-d | -e] <filesystem>\n"));
|
||||||
case HELP_RENAME:
|
case HELP_RENAME:
|
||||||
return (gettext("\trename [-f] <filesystem|volume|snapshot> "
|
return (gettext("\trename [-f] <filesystem|volume|snapshot> "
|
||||||
"<filesystem|volume|snapshot>\n"
|
"<filesystem|volume|snapshot>\n"
|
||||||
"\trename [-f] -p <filesystem|volume> "
|
"\trename [-f] -p <filesystem|volume> <filesystem|volume>\n"
|
||||||
"<filesystem|volume>\n"
|
|
||||||
"\trename -r <snapshot> <snapshot>\n"
|
"\trename -r <snapshot> <snapshot>\n"
|
||||||
"\trename -u [-p] <filesystem> <filesystem>"));
|
"\trename -u [-p] <filesystem> <filesystem>"));
|
||||||
case HELP_ROLLBACK:
|
case HELP_ROLLBACK:
|
||||||
return (gettext("\trollback [-rRf] <snapshot>\n"));
|
return (gettext("\trollback [-rRf] <snapshot>\n"));
|
||||||
case HELP_SEND:
|
case HELP_SEND:
|
||||||
return (gettext("\tsend [-DnPpRv] "
|
return (gettext("\tsend [-DnPpRv] [-[iI] snapshot] "
|
||||||
"[-i snapshot | -I snapshot] <snapshot>\n"));
|
"<snapshot>\n"
|
||||||
|
"\tsend [-i snapshot|bookmark] "
|
||||||
|
"<filesystem|volume|snapshot>\n"));
|
||||||
case HELP_SET:
|
case HELP_SET:
|
||||||
return (gettext("\tset <property=value> "
|
return (gettext("\tset <property=value> "
|
||||||
"<filesystem|volume|snapshot> ...\n"));
|
"<filesystem|volume|snapshot> ...\n"));
|
||||||
case HELP_SHARE:
|
case HELP_SHARE:
|
||||||
return (gettext("\tshare <-a | filesystem>\n"));
|
return (gettext("\tshare <-a | filesystem>\n"));
|
||||||
case HELP_SNAPSHOT:
|
case HELP_SNAPSHOT:
|
||||||
return (gettext("\tsnapshot [-r] [-o property=value] ... "
|
return (gettext("\tsnapshot|snap [-r] [-o property=value] ... "
|
||||||
"<filesystem@snapname|volume@snapname> ...\n"));
|
"<filesystem|volume>@<snap> ...\n"));
|
||||||
case HELP_UNMOUNT:
|
case HELP_UNMOUNT:
|
||||||
return (gettext("\tunmount [-f] "
|
return (gettext("\tunmount|umount [-f] "
|
||||||
"<-a | filesystem|mountpoint>\n"));
|
"<-a | filesystem|mountpoint>\n"));
|
||||||
case HELP_UNSHARE:
|
case HELP_UNSHARE:
|
||||||
return (gettext("\tunshare "
|
return (gettext("\tunshare "
|
||||||
@ -310,12 +314,14 @@ get_usage(zfs_help_t idx)
|
|||||||
"<filesystem|volume>\n"));
|
"<filesystem|volume>\n"));
|
||||||
case HELP_USERSPACE:
|
case HELP_USERSPACE:
|
||||||
return (gettext("\tuserspace [-Hinp] [-o field[,...]] "
|
return (gettext("\tuserspace [-Hinp] [-o field[,...]] "
|
||||||
"[-s field] ...\n\t[-S field] ... "
|
"[-s field] ...\n"
|
||||||
"[-t type[,...]] <filesystem|snapshot>\n"));
|
"\t [-S field] ... [-t type[,...]] "
|
||||||
|
"<filesystem|snapshot>\n"));
|
||||||
case HELP_GROUPSPACE:
|
case HELP_GROUPSPACE:
|
||||||
return (gettext("\tgroupspace [-Hinp] [-o field[,...]] "
|
return (gettext("\tgroupspace [-Hinp] [-o field[,...]] "
|
||||||
"[-s field] ...\n\t[-S field] ... "
|
"[-s field] ...\n"
|
||||||
"[-t type[,...]] <filesystem|snapshot>\n"));
|
"\t [-S field] ... [-t type[,...]] "
|
||||||
|
"<filesystem|snapshot>\n"));
|
||||||
case HELP_HOLD:
|
case HELP_HOLD:
|
||||||
return (gettext("\thold [-r] <tag> <snapshot> ...\n"));
|
return (gettext("\thold [-r] <tag> <snapshot> ...\n"));
|
||||||
case HELP_HOLDS:
|
case HELP_HOLDS:
|
||||||
@ -325,6 +331,8 @@ get_usage(zfs_help_t idx)
|
|||||||
case HELP_DIFF:
|
case HELP_DIFF:
|
||||||
return (gettext("\tdiff [-FHt] <snapshot> "
|
return (gettext("\tdiff [-FHt] <snapshot> "
|
||||||
"[snapshot|filesystem]\n"));
|
"[snapshot|filesystem]\n"));
|
||||||
|
case HELP_BOOKMARK:
|
||||||
|
return (gettext("\tbookmark <snapshot> <bookmark>\n"));
|
||||||
}
|
}
|
||||||
|
|
||||||
abort();
|
abort();
|
||||||
@ -487,9 +495,8 @@ usage(boolean_t requested)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
parseprop(nvlist_t *props)
|
parseprop(nvlist_t *props, char *propname)
|
||||||
{
|
{
|
||||||
char *propname = optarg;
|
|
||||||
char *propval, *strval;
|
char *propval, *strval;
|
||||||
|
|
||||||
if ((propval = strchr(propname, '=')) == NULL) {
|
if ((propval = strchr(propname, '=')) == NULL) {
|
||||||
@ -518,7 +525,7 @@ parse_depth(char *opt, int *flags)
|
|||||||
depth = (int)strtol(opt, &tmp, 0);
|
depth = (int)strtol(opt, &tmp, 0);
|
||||||
if (*tmp) {
|
if (*tmp) {
|
||||||
(void) fprintf(stderr,
|
(void) fprintf(stderr,
|
||||||
gettext("%s is not an integer\n"), optarg);
|
gettext("%s is not an integer\n"), opt);
|
||||||
usage(B_FALSE);
|
usage(B_FALSE);
|
||||||
}
|
}
|
||||||
if (depth < 0) {
|
if (depth < 0) {
|
||||||
@ -609,7 +616,7 @@ zfs_do_clone(int argc, char **argv)
|
|||||||
while ((c = getopt(argc, argv, "o:p")) != -1) {
|
while ((c = getopt(argc, argv, "o:p")) != -1) {
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case 'o':
|
case 'o':
|
||||||
if (parseprop(props))
|
if (parseprop(props, optarg))
|
||||||
return (1);
|
return (1);
|
||||||
break;
|
break;
|
||||||
case 'p':
|
case 'p':
|
||||||
@ -759,7 +766,7 @@ zfs_do_create(int argc, char **argv)
|
|||||||
nomem();
|
nomem();
|
||||||
break;
|
break;
|
||||||
case 'o':
|
case 'o':
|
||||||
if (parseprop(props))
|
if (parseprop(props, optarg))
|
||||||
goto error;
|
goto error;
|
||||||
break;
|
break;
|
||||||
case 's':
|
case 's':
|
||||||
@ -927,6 +934,7 @@ typedef struct destroy_cbdata {
|
|||||||
char *cb_prevsnap;
|
char *cb_prevsnap;
|
||||||
int64_t cb_snapused;
|
int64_t cb_snapused;
|
||||||
char *cb_snapspec;
|
char *cb_snapspec;
|
||||||
|
char *cb_bookmark;
|
||||||
} destroy_cbdata_t;
|
} destroy_cbdata_t;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1196,7 +1204,7 @@ zfs_do_destroy(int argc, char **argv)
|
|||||||
int err = 0;
|
int err = 0;
|
||||||
int c;
|
int c;
|
||||||
zfs_handle_t *zhp = NULL;
|
zfs_handle_t *zhp = NULL;
|
||||||
char *at;
|
char *at, *pound;
|
||||||
zfs_type_t type = ZFS_TYPE_DATASET;
|
zfs_type_t type = ZFS_TYPE_DATASET;
|
||||||
|
|
||||||
/* check options */
|
/* check options */
|
||||||
@ -1248,6 +1256,7 @@ zfs_do_destroy(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
|
|
||||||
at = strchr(argv[0], '@');
|
at = strchr(argv[0], '@');
|
||||||
|
pound = strchr(argv[0], '#');
|
||||||
if (at != NULL) {
|
if (at != NULL) {
|
||||||
|
|
||||||
/* Build the list of snaps to destroy in cb_nvl. */
|
/* Build the list of snaps to destroy in cb_nvl. */
|
||||||
@ -1309,6 +1318,46 @@ zfs_do_destroy(int argc, char **argv)
|
|||||||
|
|
||||||
if (err != 0)
|
if (err != 0)
|
||||||
rv = 1;
|
rv = 1;
|
||||||
|
} else if (pound != NULL) {
|
||||||
|
int err;
|
||||||
|
nvlist_t *nvl;
|
||||||
|
|
||||||
|
if (cb.cb_dryrun) {
|
||||||
|
(void) fprintf(stderr,
|
||||||
|
"dryrun is not supported with bookmark\n");
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cb.cb_defer_destroy) {
|
||||||
|
(void) fprintf(stderr,
|
||||||
|
"defer destroy is not supported with bookmark\n");
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cb.cb_recurse) {
|
||||||
|
(void) fprintf(stderr,
|
||||||
|
"recursive is not supported with bookmark\n");
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!zfs_bookmark_exists(argv[0])) {
|
||||||
|
(void) fprintf(stderr, gettext("bookmark '%s' "
|
||||||
|
"does not exist.\n"), argv[0]);
|
||||||
|
return (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
nvl = fnvlist_alloc();
|
||||||
|
fnvlist_add_boolean(nvl, argv[0]);
|
||||||
|
|
||||||
|
err = lzc_destroy_bookmarks(nvl, NULL);
|
||||||
|
if (err != 0) {
|
||||||
|
(void) zfs_standard_error(g_zfs, err,
|
||||||
|
"cannot destroy bookmark");
|
||||||
|
}
|
||||||
|
|
||||||
|
nvlist_free(cb.cb_nvl);
|
||||||
|
|
||||||
|
return (err);
|
||||||
} else {
|
} else {
|
||||||
/* Open the given dataset */
|
/* Open the given dataset */
|
||||||
if ((zhp = zfs_open(g_zfs, argv[0], type)) == NULL)
|
if ((zhp = zfs_open(g_zfs, argv[0], type)) == NULL)
|
||||||
@ -1671,7 +1720,8 @@ zfs_do_get(int argc, char **argv)
|
|||||||
flags &= ~ZFS_ITER_PROP_LISTSNAPS;
|
flags &= ~ZFS_ITER_PROP_LISTSNAPS;
|
||||||
while (*optarg != '\0') {
|
while (*optarg != '\0') {
|
||||||
static char *type_subopts[] = { "filesystem",
|
static char *type_subopts[] = { "filesystem",
|
||||||
"volume", "snapshot", "all", NULL };
|
"volume", "snapshot", "bookmark",
|
||||||
|
"all", NULL };
|
||||||
|
|
||||||
switch (getsubopt(&optarg, type_subopts,
|
switch (getsubopt(&optarg, type_subopts,
|
||||||
&value)) {
|
&value)) {
|
||||||
@ -1685,7 +1735,11 @@ zfs_do_get(int argc, char **argv)
|
|||||||
types |= ZFS_TYPE_SNAPSHOT;
|
types |= ZFS_TYPE_SNAPSHOT;
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
types = ZFS_TYPE_DATASET;
|
types |= ZFS_TYPE_BOOKMARK;
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
types = ZFS_TYPE_DATASET |
|
||||||
|
ZFS_TYPE_BOOKMARK;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@ -2011,7 +2065,7 @@ zfs_do_upgrade(int argc, char **argv)
|
|||||||
boolean_t showversions = B_FALSE;
|
boolean_t showversions = B_FALSE;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
upgrade_cbdata_t cb = { 0 };
|
upgrade_cbdata_t cb = { 0 };
|
||||||
char c;
|
int c;
|
||||||
int flags = ZFS_ITER_ARGS_CAN_BE_PATHS;
|
int flags = ZFS_ITER_ARGS_CAN_BE_PATHS;
|
||||||
|
|
||||||
/* check options */
|
/* check options */
|
||||||
@ -2124,7 +2178,7 @@ zfs_do_upgrade(int argc, char **argv)
|
|||||||
* -i Translate SID to POSIX ID.
|
* -i Translate SID to POSIX ID.
|
||||||
* -n Print numeric ID instead of user/group name.
|
* -n Print numeric ID instead of user/group name.
|
||||||
* -o Control which fields to display.
|
* -o Control which fields to display.
|
||||||
* -p Use exact (parseable) numeric output.
|
* -p Use exact (parsable) numeric output.
|
||||||
* -s Specify sort columns, descending order.
|
* -s Specify sort columns, descending order.
|
||||||
* -S Specify sort columns, ascending order.
|
* -S Specify sort columns, ascending order.
|
||||||
* -t Control which object types to display.
|
* -t Control which object types to display.
|
||||||
@ -2158,7 +2212,7 @@ static int us_type_bits[] = {
|
|||||||
USTYPE_SMB_USR,
|
USTYPE_SMB_USR,
|
||||||
USTYPE_ALL
|
USTYPE_ALL
|
||||||
};
|
};
|
||||||
static char *us_type_names[] = { "posixgroup", "posxiuser", "smbgroup",
|
static char *us_type_names[] = { "posixgroup", "posixuser", "smbgroup",
|
||||||
"smbuser", "all" };
|
"smbuser", "all" };
|
||||||
|
|
||||||
typedef struct us_node {
|
typedef struct us_node {
|
||||||
@ -2811,24 +2865,25 @@ zfs_do_userspace(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* list [-r][-d max] [-H] [-o property[,property]...] [-t type[,type]...]
|
* list [-Hp][-r|-d max] [-o property[,...]] [-s property] ... [-S property] ...
|
||||||
* [-s property [-s property]...] [-S property [-S property]...]
|
* [-t type[,...]] [filesystem|volume|snapshot] ...
|
||||||
* <dataset> ...
|
|
||||||
*
|
*
|
||||||
* -r Recurse over all children
|
* -H Scripted mode; elide headers and separate columns by tabs.
|
||||||
|
* -p Display values in parsable (literal) format.
|
||||||
|
* -r Recurse over all children.
|
||||||
* -d Limit recursion by depth.
|
* -d Limit recursion by depth.
|
||||||
* -H Scripted mode; elide headers and separate columns by tabs
|
|
||||||
* -o Control which fields to display.
|
* -o Control which fields to display.
|
||||||
* -t Control which object types to display.
|
|
||||||
* -s Specify sort columns, descending order.
|
* -s Specify sort columns, descending order.
|
||||||
* -S Specify sort columns, ascending order.
|
* -S Specify sort columns, ascending order.
|
||||||
|
* -t Control which object types to display.
|
||||||
*
|
*
|
||||||
* When given no arguments, lists all filesystems in the system.
|
* When given no arguments, list all filesystems in the system.
|
||||||
* Otherwise, list the specified datasets, optionally recursing down them if
|
* Otherwise, list the specified datasets, optionally recursing down them if
|
||||||
* '-r' is specified.
|
* '-r' is specified.
|
||||||
*/
|
*/
|
||||||
typedef struct list_cbdata {
|
typedef struct list_cbdata {
|
||||||
boolean_t cb_first;
|
boolean_t cb_first;
|
||||||
|
boolean_t cb_literal;
|
||||||
boolean_t cb_scripted;
|
boolean_t cb_scripted;
|
||||||
zprop_list_t *cb_proplist;
|
zprop_list_t *cb_proplist;
|
||||||
} list_cbdata_t;
|
} list_cbdata_t;
|
||||||
@ -2837,8 +2892,9 @@ typedef struct list_cbdata {
|
|||||||
* Given a list of columns to display, output appropriate headers for each one.
|
* Given a list of columns to display, output appropriate headers for each one.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
print_header(zprop_list_t *pl)
|
print_header(list_cbdata_t *cb)
|
||||||
{
|
{
|
||||||
|
zprop_list_t *pl = cb->cb_proplist;
|
||||||
char headerbuf[ZFS_MAXPROPLEN];
|
char headerbuf[ZFS_MAXPROPLEN];
|
||||||
const char *header;
|
const char *header;
|
||||||
int i;
|
int i;
|
||||||
@ -2879,19 +2935,19 @@ print_header(zprop_list_t *pl)
|
|||||||
* to the described layout.
|
* to the described layout.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
print_dataset(zfs_handle_t *zhp, zprop_list_t *pl, boolean_t scripted)
|
print_dataset(zfs_handle_t *zhp, list_cbdata_t *cb)
|
||||||
{
|
{
|
||||||
|
zprop_list_t *pl = cb->cb_proplist;
|
||||||
boolean_t first = B_TRUE;
|
boolean_t first = B_TRUE;
|
||||||
char property[ZFS_MAXPROPLEN];
|
char property[ZFS_MAXPROPLEN];
|
||||||
nvlist_t *userprops = zfs_get_user_props(zhp);
|
nvlist_t *userprops = zfs_get_user_props(zhp);
|
||||||
nvlist_t *propval;
|
nvlist_t *propval;
|
||||||
char *propstr;
|
char *propstr;
|
||||||
boolean_t right_justify;
|
boolean_t right_justify;
|
||||||
int width;
|
|
||||||
|
|
||||||
for (; pl != NULL; pl = pl->pl_next) {
|
for (; pl != NULL; pl = pl->pl_next) {
|
||||||
if (!first) {
|
if (!first) {
|
||||||
if (scripted)
|
if (cb->cb_scripted)
|
||||||
(void) printf("\t");
|
(void) printf("\t");
|
||||||
else
|
else
|
||||||
(void) printf(" ");
|
(void) printf(" ");
|
||||||
@ -2906,22 +2962,22 @@ print_dataset(zfs_handle_t *zhp, zprop_list_t *pl, boolean_t scripted)
|
|||||||
right_justify = zfs_prop_align_right(pl->pl_prop);
|
right_justify = zfs_prop_align_right(pl->pl_prop);
|
||||||
} else if (pl->pl_prop != ZPROP_INVAL) {
|
} else if (pl->pl_prop != ZPROP_INVAL) {
|
||||||
if (zfs_prop_get(zhp, pl->pl_prop, property,
|
if (zfs_prop_get(zhp, pl->pl_prop, property,
|
||||||
sizeof (property), NULL, NULL, 0, B_FALSE) != 0)
|
sizeof (property), NULL, NULL, 0,
|
||||||
|
cb->cb_literal) != 0)
|
||||||
propstr = "-";
|
propstr = "-";
|
||||||
else
|
else
|
||||||
propstr = property;
|
propstr = property;
|
||||||
|
|
||||||
right_justify = zfs_prop_align_right(pl->pl_prop);
|
right_justify = zfs_prop_align_right(pl->pl_prop);
|
||||||
} else if (zfs_prop_userquota(pl->pl_user_prop)) {
|
} else if (zfs_prop_userquota(pl->pl_user_prop)) {
|
||||||
if (zfs_prop_get_userquota(zhp, pl->pl_user_prop,
|
if (zfs_prop_get_userquota(zhp, pl->pl_user_prop,
|
||||||
property, sizeof (property), B_FALSE) != 0)
|
property, sizeof (property), cb->cb_literal) != 0)
|
||||||
propstr = "-";
|
propstr = "-";
|
||||||
else
|
else
|
||||||
propstr = property;
|
propstr = property;
|
||||||
right_justify = B_TRUE;
|
right_justify = B_TRUE;
|
||||||
} else if (zfs_prop_written(pl->pl_user_prop)) {
|
} else if (zfs_prop_written(pl->pl_user_prop)) {
|
||||||
if (zfs_prop_get_written(zhp, pl->pl_user_prop,
|
if (zfs_prop_get_written(zhp, pl->pl_user_prop,
|
||||||
property, sizeof (property), B_FALSE) != 0)
|
property, sizeof (property), cb->cb_literal) != 0)
|
||||||
propstr = "-";
|
propstr = "-";
|
||||||
else
|
else
|
||||||
propstr = property;
|
propstr = property;
|
||||||
@ -2936,19 +2992,17 @@ print_dataset(zfs_handle_t *zhp, zprop_list_t *pl, boolean_t scripted)
|
|||||||
right_justify = B_FALSE;
|
right_justify = B_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
width = pl->pl_width;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If this is being called in scripted mode, or if this is the
|
* If this is being called in scripted mode, or if this is the
|
||||||
* last column and it is left-justified, don't include a width
|
* last column and it is left-justified, don't include a width
|
||||||
* format specifier.
|
* format specifier.
|
||||||
*/
|
*/
|
||||||
if (scripted || (pl->pl_next == NULL && !right_justify))
|
if (cb->cb_scripted || (pl->pl_next == NULL && !right_justify))
|
||||||
(void) printf("%s", propstr);
|
(void) printf("%s", propstr);
|
||||||
else if (right_justify)
|
else if (right_justify)
|
||||||
(void) printf("%*s", width, propstr);
|
(void) printf("%*s", pl->pl_width, propstr);
|
||||||
else
|
else
|
||||||
(void) printf("%-*s", width, propstr);
|
(void) printf("%-*s", pl->pl_width, propstr);
|
||||||
}
|
}
|
||||||
|
|
||||||
(void) printf("\n");
|
(void) printf("\n");
|
||||||
@ -2964,11 +3018,11 @@ list_callback(zfs_handle_t *zhp, void *data)
|
|||||||
|
|
||||||
if (cbp->cb_first) {
|
if (cbp->cb_first) {
|
||||||
if (!cbp->cb_scripted)
|
if (!cbp->cb_scripted)
|
||||||
print_header(cbp->cb_proplist);
|
print_header(cbp);
|
||||||
cbp->cb_first = B_FALSE;
|
cbp->cb_first = B_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
print_dataset(zhp, cbp->cb_proplist, cbp->cb_scripted);
|
print_dataset(zhp, cbp);
|
||||||
|
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
@ -2977,7 +3031,6 @@ static int
|
|||||||
zfs_do_list(int argc, char **argv)
|
zfs_do_list(int argc, char **argv)
|
||||||
{
|
{
|
||||||
int c;
|
int c;
|
||||||
boolean_t scripted = B_FALSE;
|
|
||||||
static char default_fields[] =
|
static char default_fields[] =
|
||||||
"name,used,available,referenced,mountpoint";
|
"name,used,available,referenced,mountpoint";
|
||||||
int types = ZFS_TYPE_DATASET;
|
int types = ZFS_TYPE_DATASET;
|
||||||
@ -2991,11 +3044,15 @@ zfs_do_list(int argc, char **argv)
|
|||||||
int flags = ZFS_ITER_PROP_LISTSNAPS | ZFS_ITER_ARGS_CAN_BE_PATHS;
|
int flags = ZFS_ITER_PROP_LISTSNAPS | ZFS_ITER_ARGS_CAN_BE_PATHS;
|
||||||
|
|
||||||
/* check options */
|
/* check options */
|
||||||
while ((c = getopt(argc, argv, ":d:o:rt:Hs:S:")) != -1) {
|
while ((c = getopt(argc, argv, "HS:d:o:prs:t:")) != -1) {
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case 'o':
|
case 'o':
|
||||||
fields = optarg;
|
fields = optarg;
|
||||||
break;
|
break;
|
||||||
|
case 'p':
|
||||||
|
cb.cb_literal = B_TRUE;
|
||||||
|
flags |= ZFS_ITER_LITERAL_PROPS;
|
||||||
|
break;
|
||||||
case 'd':
|
case 'd':
|
||||||
limit = parse_depth(optarg, &flags);
|
limit = parse_depth(optarg, &flags);
|
||||||
break;
|
break;
|
||||||
@ -3003,7 +3060,7 @@ zfs_do_list(int argc, char **argv)
|
|||||||
flags |= ZFS_ITER_RECURSE;
|
flags |= ZFS_ITER_RECURSE;
|
||||||
break;
|
break;
|
||||||
case 'H':
|
case 'H':
|
||||||
scripted = B_TRUE;
|
cb.cb_scripted = B_TRUE;
|
||||||
break;
|
break;
|
||||||
case 's':
|
case 's':
|
||||||
if (zfs_add_sort_column(&sortcol, optarg,
|
if (zfs_add_sort_column(&sortcol, optarg,
|
||||||
@ -3027,7 +3084,8 @@ zfs_do_list(int argc, char **argv)
|
|||||||
flags &= ~ZFS_ITER_PROP_LISTSNAPS;
|
flags &= ~ZFS_ITER_PROP_LISTSNAPS;
|
||||||
while (*optarg != '\0') {
|
while (*optarg != '\0') {
|
||||||
static char *type_subopts[] = { "filesystem",
|
static char *type_subopts[] = { "filesystem",
|
||||||
"volume", "snapshot", "all", NULL };
|
"volume", "snapshot", "snap", "bookmark",
|
||||||
|
"all", NULL };
|
||||||
|
|
||||||
switch (getsubopt(&optarg, type_subopts,
|
switch (getsubopt(&optarg, type_subopts,
|
||||||
&value)) {
|
&value)) {
|
||||||
@ -3038,12 +3096,16 @@ zfs_do_list(int argc, char **argv)
|
|||||||
types |= ZFS_TYPE_VOLUME;
|
types |= ZFS_TYPE_VOLUME;
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
|
case 3:
|
||||||
types |= ZFS_TYPE_SNAPSHOT;
|
types |= ZFS_TYPE_SNAPSHOT;
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 4:
|
||||||
types = ZFS_TYPE_DATASET;
|
types |= ZFS_TYPE_BOOKMARK;
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
types = ZFS_TYPE_DATASET |
|
||||||
|
ZFS_TYPE_BOOKMARK;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
(void) fprintf(stderr,
|
(void) fprintf(stderr,
|
||||||
gettext("invalid type '%s'\n"),
|
gettext("invalid type '%s'\n"),
|
||||||
@ -3092,7 +3154,6 @@ zfs_do_list(int argc, char **argv)
|
|||||||
!= 0)
|
!= 0)
|
||||||
usage(B_FALSE);
|
usage(B_FALSE);
|
||||||
|
|
||||||
cb.cb_scripted = scripted;
|
|
||||||
cb.cb_first = B_TRUE;
|
cb.cb_first = B_TRUE;
|
||||||
|
|
||||||
ret = zfs_for_each(argc, argv, flags, types, sortcol, &cb.cb_proplist,
|
ret = zfs_for_each(argc, argv, flags, types, sortcol, &cb.cb_proplist,
|
||||||
@ -3284,9 +3345,29 @@ typedef struct rollback_cbdata {
|
|||||||
char *cb_target;
|
char *cb_target;
|
||||||
int cb_error;
|
int cb_error;
|
||||||
boolean_t cb_recurse;
|
boolean_t cb_recurse;
|
||||||
boolean_t cb_dependent;
|
|
||||||
} rollback_cbdata_t;
|
} rollback_cbdata_t;
|
||||||
|
|
||||||
|
static int
|
||||||
|
rollback_check_dependent(zfs_handle_t *zhp, void *data)
|
||||||
|
{
|
||||||
|
rollback_cbdata_t *cbp = data;
|
||||||
|
|
||||||
|
if (cbp->cb_first && cbp->cb_recurse) {
|
||||||
|
(void) fprintf(stderr, gettext("cannot rollback to "
|
||||||
|
"'%s': clones of previous snapshots exist\n"),
|
||||||
|
cbp->cb_target);
|
||||||
|
(void) fprintf(stderr, gettext("use '-R' to "
|
||||||
|
"force deletion of the following clones and "
|
||||||
|
"dependents:\n"));
|
||||||
|
cbp->cb_first = 0;
|
||||||
|
cbp->cb_error = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
(void) fprintf(stderr, "%s\n", zfs_get_name(zhp));
|
||||||
|
|
||||||
|
zfs_close(zhp);
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
/*
|
/*
|
||||||
* Report any snapshots more recent than the one specified. Used when '-r' is
|
* Report any snapshots more recent than the one specified. Used when '-r' is
|
||||||
* not specified. We reuse this same callback for the snapshot dependents - if
|
* not specified. We reuse this same callback for the snapshot dependents - if
|
||||||
@ -3303,52 +3384,30 @@ rollback_check(zfs_handle_t *zhp, void *data)
|
|||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!cbp->cb_dependent) {
|
if (zfs_prop_get_int(zhp, ZFS_PROP_CREATETXG) > cbp->cb_create) {
|
||||||
if (strcmp(zfs_get_name(zhp), cbp->cb_target) != 0 &&
|
|
||||||
zfs_get_type(zhp) == ZFS_TYPE_SNAPSHOT &&
|
|
||||||
zfs_prop_get_int(zhp, ZFS_PROP_CREATETXG) >
|
|
||||||
cbp->cb_create) {
|
|
||||||
|
|
||||||
if (cbp->cb_first && !cbp->cb_recurse) {
|
if (cbp->cb_first && !cbp->cb_recurse) {
|
||||||
(void) fprintf(stderr, gettext("cannot "
|
(void) fprintf(stderr, gettext("cannot "
|
||||||
"rollback to '%s': more recent snapshots "
|
"rollback to '%s': more recent snapshots "
|
||||||
"exist\n"),
|
"or bookmarks exist\n"),
|
||||||
cbp->cb_target);
|
cbp->cb_target);
|
||||||
(void) fprintf(stderr, gettext("use '-r' to "
|
(void) fprintf(stderr, gettext("use '-r' to "
|
||||||
"force deletion of the following "
|
"force deletion of the following "
|
||||||
"snapshots:\n"));
|
"snapshots and bookmarks:\n"));
|
||||||
cbp->cb_first = 0;
|
cbp->cb_first = 0;
|
||||||
cbp->cb_error = 1;
|
cbp->cb_error = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cbp->cb_recurse) {
|
if (cbp->cb_recurse) {
|
||||||
cbp->cb_dependent = B_TRUE;
|
|
||||||
if (zfs_iter_dependents(zhp, B_TRUE,
|
if (zfs_iter_dependents(zhp, B_TRUE,
|
||||||
rollback_check, cbp) != 0) {
|
rollback_check_dependent, cbp) != 0) {
|
||||||
zfs_close(zhp);
|
zfs_close(zhp);
|
||||||
return (-1);
|
return (-1);
|
||||||
}
|
}
|
||||||
cbp->cb_dependent = B_FALSE;
|
|
||||||
} else {
|
} else {
|
||||||
(void) fprintf(stderr, "%s\n",
|
(void) fprintf(stderr, "%s\n",
|
||||||
zfs_get_name(zhp));
|
zfs_get_name(zhp));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
if (cbp->cb_first && cbp->cb_recurse) {
|
|
||||||
(void) fprintf(stderr, gettext("cannot rollback to "
|
|
||||||
"'%s': clones of previous snapshots exist\n"),
|
|
||||||
cbp->cb_target);
|
|
||||||
(void) fprintf(stderr, gettext("use '-R' to "
|
|
||||||
"force deletion of the following clones and "
|
|
||||||
"dependents:\n"));
|
|
||||||
cbp->cb_first = 0;
|
|
||||||
cbp->cb_error = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
(void) fprintf(stderr, "%s\n", zfs_get_name(zhp));
|
|
||||||
}
|
|
||||||
|
|
||||||
zfs_close(zhp);
|
zfs_close(zhp);
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
@ -3418,7 +3477,9 @@ zfs_do_rollback(int argc, char **argv)
|
|||||||
cb.cb_create = zfs_prop_get_int(snap, ZFS_PROP_CREATETXG);
|
cb.cb_create = zfs_prop_get_int(snap, ZFS_PROP_CREATETXG);
|
||||||
cb.cb_first = B_TRUE;
|
cb.cb_first = B_TRUE;
|
||||||
cb.cb_error = 0;
|
cb.cb_error = 0;
|
||||||
if ((ret = zfs_iter_children(zhp, rollback_check, &cb)) != 0)
|
if ((ret = zfs_iter_snapshots(zhp, B_FALSE, rollback_check, &cb)) != 0)
|
||||||
|
goto out;
|
||||||
|
if ((ret = zfs_iter_bookmarks(zhp, rollback_check, &cb)) != 0)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
if ((ret = cb.cb_error) != 0)
|
if ((ret = cb.cb_error) != 0)
|
||||||
@ -3560,7 +3621,7 @@ static int
|
|||||||
zfs_do_snapshot(int argc, char **argv)
|
zfs_do_snapshot(int argc, char **argv)
|
||||||
{
|
{
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
char c;
|
int c;
|
||||||
nvlist_t *props;
|
nvlist_t *props;
|
||||||
snap_cbdata_t sd = { 0 };
|
snap_cbdata_t sd = { 0 };
|
||||||
boolean_t multiple_snaps = B_FALSE;
|
boolean_t multiple_snaps = B_FALSE;
|
||||||
@ -3574,7 +3635,7 @@ zfs_do_snapshot(int argc, char **argv)
|
|||||||
while ((c = getopt(argc, argv, "ro:")) != -1) {
|
while ((c = getopt(argc, argv, "ro:")) != -1) {
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case 'o':
|
case 'o':
|
||||||
if (parseprop(props))
|
if (parseprop(props, optarg))
|
||||||
return (1);
|
return (1);
|
||||||
break;
|
break;
|
||||||
case 'r':
|
case 'r':
|
||||||
@ -3713,12 +3774,45 @@ zfs_do_send(int argc, char **argv)
|
|||||||
return (1);
|
return (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
cp = strchr(argv[0], '@');
|
/*
|
||||||
if (cp == NULL) {
|
* Special case sending a filesystem, or from a bookmark.
|
||||||
|
*/
|
||||||
|
if (strchr(argv[0], '@') == NULL ||
|
||||||
|
(fromname && strchr(fromname, '#') != NULL)) {
|
||||||
|
char frombuf[ZFS_MAXNAMELEN];
|
||||||
|
|
||||||
|
if (flags.replicate || flags.doall || flags.props ||
|
||||||
|
flags.dedup || flags.dryrun || flags.verbose ||
|
||||||
|
flags.progress) {
|
||||||
(void) fprintf(stderr,
|
(void) fprintf(stderr,
|
||||||
gettext("argument must be a snapshot\n"));
|
gettext("Error: "
|
||||||
usage(B_FALSE);
|
"Unsupported flag with filesystem or bookmark.\n"));
|
||||||
|
return (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
zhp = zfs_open(g_zfs, argv[0], ZFS_TYPE_DATASET);
|
||||||
|
if (zhp == NULL)
|
||||||
|
return (1);
|
||||||
|
|
||||||
|
if (fromname != NULL &&
|
||||||
|
(fromname[0] == '#' || fromname[0] == '@')) {
|
||||||
|
/*
|
||||||
|
* Incremental source name begins with # or @.
|
||||||
|
* Default to same fs as target.
|
||||||
|
*/
|
||||||
|
(void) strncpy(frombuf, argv[0], sizeof (frombuf));
|
||||||
|
cp = strchr(frombuf, '@');
|
||||||
|
if (cp != NULL)
|
||||||
|
*cp = '\0';
|
||||||
|
(void) strlcat(frombuf, fromname, sizeof (frombuf));
|
||||||
|
fromname = frombuf;
|
||||||
|
}
|
||||||
|
err = zfs_send_one(zhp, fromname, STDOUT_FILENO);
|
||||||
|
zfs_close(zhp);
|
||||||
|
return (err != 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
cp = strchr(argv[0], '@');
|
||||||
*cp = '\0';
|
*cp = '\0';
|
||||||
toname = cp + 1;
|
toname = cp + 1;
|
||||||
zhp = zfs_open(g_zfs, argv[0], ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME);
|
zhp = zfs_open(g_zfs, argv[0], ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME);
|
||||||
@ -3874,6 +3968,7 @@ zfs_do_receive(int argc, char **argv)
|
|||||||
#define ZFS_DELEG_PERM_HOLD "hold"
|
#define ZFS_DELEG_PERM_HOLD "hold"
|
||||||
#define ZFS_DELEG_PERM_RELEASE "release"
|
#define ZFS_DELEG_PERM_RELEASE "release"
|
||||||
#define ZFS_DELEG_PERM_DIFF "diff"
|
#define ZFS_DELEG_PERM_DIFF "diff"
|
||||||
|
#define ZFS_DELEG_PERM_BOOKMARK "bookmark"
|
||||||
|
|
||||||
#define ZFS_NUM_DELEG_NOTES ZFS_DELEG_NOTE_NONE
|
#define ZFS_NUM_DELEG_NOTES ZFS_DELEG_NOTE_NONE
|
||||||
|
|
||||||
@ -3893,6 +3988,7 @@ static zfs_deleg_perm_tab_t zfs_deleg_perm_tbl[] = {
|
|||||||
{ ZFS_DELEG_PERM_SEND, ZFS_DELEG_NOTE_SEND },
|
{ ZFS_DELEG_PERM_SEND, ZFS_DELEG_NOTE_SEND },
|
||||||
{ ZFS_DELEG_PERM_SHARE, ZFS_DELEG_NOTE_SHARE },
|
{ ZFS_DELEG_PERM_SHARE, ZFS_DELEG_NOTE_SHARE },
|
||||||
{ ZFS_DELEG_PERM_SNAPSHOT, ZFS_DELEG_NOTE_SNAPSHOT },
|
{ ZFS_DELEG_PERM_SNAPSHOT, ZFS_DELEG_NOTE_SNAPSHOT },
|
||||||
|
{ ZFS_DELEG_PERM_BOOKMARK, ZFS_DELEG_NOTE_BOOKMARK },
|
||||||
|
|
||||||
{ ZFS_DELEG_PERM_GROUPQUOTA, ZFS_DELEG_NOTE_GROUPQUOTA },
|
{ ZFS_DELEG_PERM_GROUPQUOTA, ZFS_DELEG_NOTE_GROUPQUOTA },
|
||||||
{ ZFS_DELEG_PERM_GROUPUSED, ZFS_DELEG_NOTE_GROUPUSED },
|
{ ZFS_DELEG_PERM_GROUPUSED, ZFS_DELEG_NOTE_GROUPUSED },
|
||||||
@ -6664,6 +6760,108 @@ zfs_do_diff(int argc, char **argv)
|
|||||||
return (err != 0);
|
return (err != 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* zfs bookmark <fs@snap> <fs#bmark>
|
||||||
|
*
|
||||||
|
* Creates a bookmark with the given name from the given snapshot.
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
zfs_do_bookmark(int argc, char **argv)
|
||||||
|
{
|
||||||
|
char snapname[ZFS_MAXNAMELEN];
|
||||||
|
zfs_handle_t *zhp;
|
||||||
|
nvlist_t *nvl;
|
||||||
|
int ret = 0;
|
||||||
|
int c;
|
||||||
|
|
||||||
|
/* check options */
|
||||||
|
while ((c = getopt(argc, argv, "")) != -1) {
|
||||||
|
switch (c) {
|
||||||
|
case '?':
|
||||||
|
(void) fprintf(stderr,
|
||||||
|
gettext("invalid option '%c'\n"), optopt);
|
||||||
|
goto usage;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
argc -= optind;
|
||||||
|
argv += optind;
|
||||||
|
|
||||||
|
/* check number of arguments */
|
||||||
|
if (argc < 1) {
|
||||||
|
(void) fprintf(stderr, gettext("missing snapshot argument\n"));
|
||||||
|
goto usage;
|
||||||
|
}
|
||||||
|
if (argc < 2) {
|
||||||
|
(void) fprintf(stderr, gettext("missing bookmark argument\n"));
|
||||||
|
goto usage;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strchr(argv[1], '#') == NULL) {
|
||||||
|
(void) fprintf(stderr,
|
||||||
|
gettext("invalid bookmark name '%s' -- "
|
||||||
|
"must contain a '#'\n"), argv[1]);
|
||||||
|
goto usage;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (argv[0][0] == '@') {
|
||||||
|
/*
|
||||||
|
* Snapshot name begins with @.
|
||||||
|
* Default to same fs as bookmark.
|
||||||
|
*/
|
||||||
|
(void) strncpy(snapname, argv[1], sizeof (snapname));
|
||||||
|
*strchr(snapname, '#') = '\0';
|
||||||
|
(void) strlcat(snapname, argv[0], sizeof (snapname));
|
||||||
|
} else {
|
||||||
|
(void) strncpy(snapname, argv[0], sizeof (snapname));
|
||||||
|
}
|
||||||
|
zhp = zfs_open(g_zfs, snapname, ZFS_TYPE_SNAPSHOT);
|
||||||
|
if (zhp == NULL)
|
||||||
|
goto usage;
|
||||||
|
zfs_close(zhp);
|
||||||
|
|
||||||
|
|
||||||
|
nvl = fnvlist_alloc();
|
||||||
|
fnvlist_add_string(nvl, argv[1], snapname);
|
||||||
|
ret = lzc_bookmark(nvl, NULL);
|
||||||
|
fnvlist_free(nvl);
|
||||||
|
|
||||||
|
if (ret != 0) {
|
||||||
|
const char *err_msg;
|
||||||
|
char errbuf[1024];
|
||||||
|
|
||||||
|
(void) snprintf(errbuf, sizeof (errbuf),
|
||||||
|
dgettext(TEXT_DOMAIN,
|
||||||
|
"cannot create bookmark '%s'"), argv[1]);
|
||||||
|
|
||||||
|
switch (ret) {
|
||||||
|
case EXDEV:
|
||||||
|
err_msg = "bookmark is in a different pool";
|
||||||
|
break;
|
||||||
|
case EEXIST:
|
||||||
|
err_msg = "bookmark exists";
|
||||||
|
break;
|
||||||
|
case EINVAL:
|
||||||
|
err_msg = "invalid argument";
|
||||||
|
break;
|
||||||
|
case ENOTSUP:
|
||||||
|
err_msg = "bookmark feature not enabled";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
err_msg = "unknown error";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
(void) fprintf(stderr, "%s: %s\n", errbuf,
|
||||||
|
dgettext(TEXT_DOMAIN, err_msg));
|
||||||
|
}
|
||||||
|
|
||||||
|
return (ret);
|
||||||
|
|
||||||
|
usage:
|
||||||
|
usage(B_FALSE);
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
main(int argc, char **argv)
|
main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
@ -6725,6 +6923,12 @@ main(int argc, char **argv)
|
|||||||
if (strcmp(cmdname, "recv") == 0)
|
if (strcmp(cmdname, "recv") == 0)
|
||||||
cmdname = "receive";
|
cmdname = "receive";
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The 'snap' command is an alias for 'snapshot'
|
||||||
|
*/
|
||||||
|
if (strcmp(cmdname, "snap") == 0)
|
||||||
|
cmdname = "snapshot";
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Special case '-?'
|
* Special case '-?'
|
||||||
*/
|
*/
|
||||||
|
@ -20,7 +20,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2012 by Delphix. All rights reserved.
|
* Copyright (c) 2013 by Delphix. All rights reserved.
|
||||||
* Copyright (c) 2013 Steven Hartland. All rights reserved.
|
* Copyright (c) 2013 Steven Hartland. All rights reserved.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -85,10 +85,15 @@ usage(void)
|
|||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
fatal(const char *fmt, ...)
|
fatal(spa_t *spa, void *tag, const char *fmt, ...)
|
||||||
{
|
{
|
||||||
va_list ap;
|
va_list ap;
|
||||||
|
|
||||||
|
if (spa != NULL) {
|
||||||
|
spa_close(spa, tag);
|
||||||
|
(void) spa_export(g_pool, NULL, B_TRUE, B_FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
va_start(ap, fmt);
|
va_start(ap, fmt);
|
||||||
(void) fprintf(stderr, "%s: ", cmdname);
|
(void) fprintf(stderr, "%s: ", cmdname);
|
||||||
(void) vfprintf(stderr, fmt, ap);
|
(void) vfprintf(stderr, fmt, ap);
|
||||||
@ -159,13 +164,14 @@ import_pool(const char *target, boolean_t readonly)
|
|||||||
g_importargs.can_be_active = B_TRUE;
|
g_importargs.can_be_active = B_TRUE;
|
||||||
if (zpool_search_import(g_zfs, &g_importargs) != NULL ||
|
if (zpool_search_import(g_zfs, &g_importargs) != NULL ||
|
||||||
spa_open(target, &spa, FTAG) == 0) {
|
spa_open(target, &spa, FTAG) == 0) {
|
||||||
fatal("cannot import '%s': pool is active; run "
|
fatal(spa, FTAG, "cannot import '%s': pool is "
|
||||||
"\"zpool export %s\" first\n",
|
"active; run " "\"zpool export %s\" "
|
||||||
g_pool, g_pool);
|
"first\n", g_pool, g_pool);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fatal("cannot import '%s': no such pool available\n", g_pool);
|
fatal(NULL, FTAG, "cannot import '%s': no such pool "
|
||||||
|
"available\n", g_pool);
|
||||||
}
|
}
|
||||||
|
|
||||||
elem = nvlist_next_nvpair(pools, NULL);
|
elem = nvlist_next_nvpair(pools, NULL);
|
||||||
@ -186,7 +192,8 @@ import_pool(const char *target, boolean_t readonly)
|
|||||||
error = 0;
|
error = 0;
|
||||||
|
|
||||||
if (error)
|
if (error)
|
||||||
fatal("can't import '%s': %s", name, strerror(error));
|
fatal(NULL, FTAG, "can't import '%s': %s", name,
|
||||||
|
strerror(error));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -201,10 +208,11 @@ zhack_spa_open(const char *target, boolean_t readonly, void *tag, spa_t **spa)
|
|||||||
zfeature_checks_disable = B_FALSE;
|
zfeature_checks_disable = B_FALSE;
|
||||||
|
|
||||||
if (err != 0)
|
if (err != 0)
|
||||||
fatal("cannot open '%s': %s", target, strerror(err));
|
fatal(*spa, FTAG, "cannot open '%s': %s", target,
|
||||||
|
strerror(err));
|
||||||
if (spa_version(*spa) < SPA_VERSION_FEATURES) {
|
if (spa_version(*spa) < SPA_VERSION_FEATURES) {
|
||||||
fatal("'%s' has version %d, features not enabled", target,
|
fatal(*spa, FTAG, "'%s' has version %d, features not enabled",
|
||||||
(int)spa_version(*spa));
|
target, (int)spa_version(*spa));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -269,18 +277,22 @@ zhack_do_feature_stat(int argc, char **argv)
|
|||||||
dump_obj(os, spa->spa_feat_for_read_obj, "for_read");
|
dump_obj(os, spa->spa_feat_for_read_obj, "for_read");
|
||||||
dump_obj(os, spa->spa_feat_for_write_obj, "for_write");
|
dump_obj(os, spa->spa_feat_for_write_obj, "for_write");
|
||||||
dump_obj(os, spa->spa_feat_desc_obj, "descriptions");
|
dump_obj(os, spa->spa_feat_desc_obj, "descriptions");
|
||||||
|
if (spa_feature_is_active(spa, SPA_FEATURE_ENABLED_TXG)) {
|
||||||
|
dump_obj(os, spa->spa_feat_enabled_txg_obj, "enabled_txg");
|
||||||
|
}
|
||||||
dump_mos(spa);
|
dump_mos(spa);
|
||||||
|
|
||||||
spa_close(spa, FTAG);
|
spa_close(spa, FTAG);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
feature_enable_sync(void *arg, dmu_tx_t *tx)
|
zhack_feature_enable_sync(void *arg, dmu_tx_t *tx)
|
||||||
{
|
{
|
||||||
spa_t *spa = dmu_tx_pool(tx)->dp_spa;
|
spa_t *spa = dmu_tx_pool(tx)->dp_spa;
|
||||||
zfeature_info_t *feature = arg;
|
zfeature_info_t *feature = arg;
|
||||||
|
|
||||||
spa_feature_enable(spa, feature, tx);
|
feature_enable_sync(spa, feature, tx);
|
||||||
|
|
||||||
spa_history_log_internal(spa, "zhack enable feature", tx,
|
spa_history_log_internal(spa, "zhack enable feature", tx,
|
||||||
"name=%s can_readonly=%u",
|
"name=%s can_readonly=%u",
|
||||||
feature->fi_guid, feature->fi_can_readonly);
|
feature->fi_guid, feature->fi_can_readonly);
|
||||||
@ -294,7 +306,7 @@ zhack_do_feature_enable(int argc, char **argv)
|
|||||||
spa_t *spa;
|
spa_t *spa;
|
||||||
objset_t *mos;
|
objset_t *mos;
|
||||||
zfeature_info_t feature;
|
zfeature_info_t feature;
|
||||||
zfeature_info_t *nodeps[] = { NULL };
|
spa_feature_t nodeps[] = { SPA_FEATURE_NONE };
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Features are not added to the pool's label until their refcounts
|
* Features are not added to the pool's label until their refcounts
|
||||||
@ -304,7 +316,9 @@ zhack_do_feature_enable(int argc, char **argv)
|
|||||||
feature.fi_uname = "zhack";
|
feature.fi_uname = "zhack";
|
||||||
feature.fi_mos = B_FALSE;
|
feature.fi_mos = B_FALSE;
|
||||||
feature.fi_can_readonly = B_FALSE;
|
feature.fi_can_readonly = B_FALSE;
|
||||||
|
feature.fi_activate_on_enable = B_FALSE;
|
||||||
feature.fi_depends = nodeps;
|
feature.fi_depends = nodeps;
|
||||||
|
feature.fi_feature = SPA_FEATURE_NONE;
|
||||||
|
|
||||||
optind = 1;
|
optind = 1;
|
||||||
while ((c = getopt(argc, argv, "rmd:")) != -1) {
|
while ((c = getopt(argc, argv, "rmd:")) != -1) {
|
||||||
@ -336,18 +350,19 @@ zhack_do_feature_enable(int argc, char **argv)
|
|||||||
feature.fi_guid = argv[1];
|
feature.fi_guid = argv[1];
|
||||||
|
|
||||||
if (!zfeature_is_valid_guid(feature.fi_guid))
|
if (!zfeature_is_valid_guid(feature.fi_guid))
|
||||||
fatal("invalid feature guid: %s", feature.fi_guid);
|
fatal(NULL, FTAG, "invalid feature guid: %s", feature.fi_guid);
|
||||||
|
|
||||||
zhack_spa_open(target, B_FALSE, FTAG, &spa);
|
zhack_spa_open(target, B_FALSE, FTAG, &spa);
|
||||||
mos = spa->spa_meta_objset;
|
mos = spa->spa_meta_objset;
|
||||||
|
|
||||||
if (0 == zfeature_lookup_guid(feature.fi_guid, NULL))
|
if (zfeature_is_supported(feature.fi_guid))
|
||||||
fatal("'%s' is a real feature, will not enable");
|
fatal(spa, FTAG, "'%s' is a real feature, will not enable");
|
||||||
if (0 == zap_contains(mos, spa->spa_feat_desc_obj, feature.fi_guid))
|
if (0 == zap_contains(mos, spa->spa_feat_desc_obj, feature.fi_guid))
|
||||||
fatal("feature already enabled: %s", feature.fi_guid);
|
fatal(spa, FTAG, "feature already enabled: %s",
|
||||||
|
feature.fi_guid);
|
||||||
|
|
||||||
VERIFY0(dsl_sync_task(spa_name(spa), NULL,
|
VERIFY0(dsl_sync_task(spa_name(spa), NULL,
|
||||||
feature_enable_sync, &feature, 5));
|
zhack_feature_enable_sync, &feature, 5));
|
||||||
|
|
||||||
spa_close(spa, FTAG);
|
spa_close(spa, FTAG);
|
||||||
|
|
||||||
@ -359,8 +374,10 @@ feature_incr_sync(void *arg, dmu_tx_t *tx)
|
|||||||
{
|
{
|
||||||
spa_t *spa = dmu_tx_pool(tx)->dp_spa;
|
spa_t *spa = dmu_tx_pool(tx)->dp_spa;
|
||||||
zfeature_info_t *feature = arg;
|
zfeature_info_t *feature = arg;
|
||||||
|
uint64_t refcount;
|
||||||
|
|
||||||
spa_feature_incr(spa, feature, tx);
|
VERIFY0(feature_get_refcount_from_disk(spa, feature, &refcount));
|
||||||
|
feature_sync(spa, feature, refcount + 1, tx);
|
||||||
spa_history_log_internal(spa, "zhack feature incr", tx,
|
spa_history_log_internal(spa, "zhack feature incr", tx,
|
||||||
"name=%s", feature->fi_guid);
|
"name=%s", feature->fi_guid);
|
||||||
}
|
}
|
||||||
@ -370,8 +387,10 @@ feature_decr_sync(void *arg, dmu_tx_t *tx)
|
|||||||
{
|
{
|
||||||
spa_t *spa = dmu_tx_pool(tx)->dp_spa;
|
spa_t *spa = dmu_tx_pool(tx)->dp_spa;
|
||||||
zfeature_info_t *feature = arg;
|
zfeature_info_t *feature = arg;
|
||||||
|
uint64_t refcount;
|
||||||
|
|
||||||
spa_feature_decr(spa, feature, tx);
|
VERIFY0(feature_get_refcount_from_disk(spa, feature, &refcount));
|
||||||
|
feature_sync(spa, feature, refcount - 1, tx);
|
||||||
spa_history_log_internal(spa, "zhack feature decr", tx,
|
spa_history_log_internal(spa, "zhack feature decr", tx,
|
||||||
"name=%s", feature->fi_guid);
|
"name=%s", feature->fi_guid);
|
||||||
}
|
}
|
||||||
@ -385,7 +404,7 @@ zhack_do_feature_ref(int argc, char **argv)
|
|||||||
spa_t *spa;
|
spa_t *spa;
|
||||||
objset_t *mos;
|
objset_t *mos;
|
||||||
zfeature_info_t feature;
|
zfeature_info_t feature;
|
||||||
zfeature_info_t *nodeps[] = { NULL };
|
spa_feature_t nodeps[] = { SPA_FEATURE_NONE };
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* fi_desc does not matter here because it was written to disk
|
* fi_desc does not matter here because it was written to disk
|
||||||
@ -397,6 +416,7 @@ zhack_do_feature_ref(int argc, char **argv)
|
|||||||
feature.fi_mos = B_FALSE;
|
feature.fi_mos = B_FALSE;
|
||||||
feature.fi_desc = NULL;
|
feature.fi_desc = NULL;
|
||||||
feature.fi_depends = nodeps;
|
feature.fi_depends = nodeps;
|
||||||
|
feature.fi_feature = SPA_FEATURE_NONE;
|
||||||
|
|
||||||
optind = 1;
|
optind = 1;
|
||||||
while ((c = getopt(argc, argv, "md")) != -1) {
|
while ((c = getopt(argc, argv, "md")) != -1) {
|
||||||
@ -423,13 +443,15 @@ zhack_do_feature_ref(int argc, char **argv)
|
|||||||
feature.fi_guid = argv[1];
|
feature.fi_guid = argv[1];
|
||||||
|
|
||||||
if (!zfeature_is_valid_guid(feature.fi_guid))
|
if (!zfeature_is_valid_guid(feature.fi_guid))
|
||||||
fatal("invalid feature guid: %s", feature.fi_guid);
|
fatal(NULL, FTAG, "invalid feature guid: %s", feature.fi_guid);
|
||||||
|
|
||||||
zhack_spa_open(target, B_FALSE, FTAG, &spa);
|
zhack_spa_open(target, B_FALSE, FTAG, &spa);
|
||||||
mos = spa->spa_meta_objset;
|
mos = spa->spa_meta_objset;
|
||||||
|
|
||||||
if (0 == zfeature_lookup_guid(feature.fi_guid, NULL))
|
if (zfeature_is_supported(feature.fi_guid)) {
|
||||||
fatal("'%s' is a real feature, will not change refcount");
|
fatal(spa, FTAG,
|
||||||
|
"'%s' is a real feature, will not change refcount");
|
||||||
|
}
|
||||||
|
|
||||||
if (0 == zap_contains(mos, spa->spa_feat_for_read_obj,
|
if (0 == zap_contains(mos, spa->spa_feat_for_read_obj,
|
||||||
feature.fi_guid)) {
|
feature.fi_guid)) {
|
||||||
@ -438,11 +460,17 @@ zhack_do_feature_ref(int argc, char **argv)
|
|||||||
feature.fi_guid)) {
|
feature.fi_guid)) {
|
||||||
feature.fi_can_readonly = B_TRUE;
|
feature.fi_can_readonly = B_TRUE;
|
||||||
} else {
|
} else {
|
||||||
fatal("feature is not enabled: %s", feature.fi_guid);
|
fatal(spa, FTAG, "feature is not enabled: %s", feature.fi_guid);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (decr && !spa_feature_is_active(spa, &feature))
|
if (decr) {
|
||||||
fatal("feature refcount already 0: %s", feature.fi_guid);
|
uint64_t count;
|
||||||
|
if (feature_get_refcount_from_disk(spa, &feature,
|
||||||
|
&count) == 0 && count != 0) {
|
||||||
|
fatal(spa, FTAG, "feature refcount already 0: %s",
|
||||||
|
feature.fi_guid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
VERIFY0(dsl_sync_task(spa_name(spa), NULL,
|
VERIFY0(dsl_sync_task(spa_name(spa), NULL,
|
||||||
decr ? feature_decr_sync : feature_incr_sync, &feature, 5));
|
decr ? feature_decr_sync : feature_incr_sync, &feature, 5));
|
||||||
@ -530,8 +558,8 @@ main(int argc, char **argv)
|
|||||||
usage();
|
usage();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!g_readonly && spa_export(g_pool, NULL, B_TRUE, B_TRUE) != 0) {
|
if (!g_readonly && spa_export(g_pool, NULL, B_TRUE, B_FALSE) != 0) {
|
||||||
fatal("pool export failed; "
|
fatal(NULL, FTAG, "pool export failed; "
|
||||||
"changes may not be committed to disk\n");
|
"changes may not be committed to disk\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -148,6 +148,7 @@
|
|||||||
#include <sys/mount.h>
|
#include <sys/mount.h>
|
||||||
|
|
||||||
#include <libzfs.h>
|
#include <libzfs.h>
|
||||||
|
#include <libzfs_compat.h>
|
||||||
|
|
||||||
#undef verify /* both libzfs.h and zfs_context.h want to define this */
|
#undef verify /* both libzfs.h and zfs_context.h want to define this */
|
||||||
|
|
||||||
|
@ -23,7 +23,7 @@
|
|||||||
.\"
|
.\"
|
||||||
.\" $FreeBSD$
|
.\" $FreeBSD$
|
||||||
.\"
|
.\"
|
||||||
.Dd September 20, 2013
|
.Dd April 23, 2014
|
||||||
.Dt ZPOOL-FEATURES 7
|
.Dt ZPOOL-FEATURES 7
|
||||||
.Os
|
.Os
|
||||||
.Sh NAME
|
.Sh NAME
|
||||||
@ -187,6 +187,23 @@ This feature is
|
|||||||
.Sy active
|
.Sy active
|
||||||
while there are any filesystems, volumes, or snapshots which were created
|
while there are any filesystems, volumes, or snapshots which were created
|
||||||
after enabling this feature.
|
after enabling this feature.
|
||||||
|
.It Sy filesystem_limits
|
||||||
|
.Bl -column "READ\-ONLY COMPATIBLE" "com.joyent:filesystem_limits"
|
||||||
|
.It GUID Ta com.joyent:filesystem_limits
|
||||||
|
.It READ\-ONLY COMPATIBLE Ta yes
|
||||||
|
.It DEPENDENCIES Ta extensible_dataset
|
||||||
|
.El
|
||||||
|
.Pp
|
||||||
|
This feature enables filesystem and snapshot limits.
|
||||||
|
These limits can be used
|
||||||
|
to control how many filesystems and/or snapshots can be created at the point in
|
||||||
|
the tree on which the limits are set.
|
||||||
|
.Pp
|
||||||
|
This feature is
|
||||||
|
.Sy active
|
||||||
|
once either of the limit properties has been
|
||||||
|
set on a dataset.
|
||||||
|
Once activated the feature is never deactivated.
|
||||||
.It Sy lz4_compress
|
.It Sy lz4_compress
|
||||||
.Bl -column "READ\-ONLY COMPATIBLE" "org.illumos:lz4_compress"
|
.Bl -column "READ\-ONLY COMPATIBLE" "org.illumos:lz4_compress"
|
||||||
.It GUID Ta org.illumos:lz4_compress
|
.It GUID Ta org.illumos:lz4_compress
|
||||||
@ -222,12 +239,16 @@ command. Please note that doing so will
|
|||||||
immediately activate the
|
immediately activate the
|
||||||
.Sy lz4_compress
|
.Sy lz4_compress
|
||||||
feature on the underlying
|
feature on the underlying
|
||||||
pool (even before any data is written). Since this feature is not
|
pool
|
||||||
read-only compatible, this operation will render the pool unimportable
|
.Pq even before any data is written ,
|
||||||
on systems without support for the
|
and the feature will not be
|
||||||
|
deactivated.
|
||||||
|
Since this feature is not read-only compatible, this
|
||||||
|
operation will render the pool unimportable on systems without support
|
||||||
|
for the
|
||||||
.Sy lz4_compress
|
.Sy lz4_compress
|
||||||
feature. At the
|
feature.
|
||||||
moment, this operation cannot be reversed. Booting off of
|
Booting off of
|
||||||
.Sy lz4
|
.Sy lz4
|
||||||
-compressed root pools is supported.
|
-compressed root pools is supported.
|
||||||
.It Sy multi_vdev_crash_dump
|
.It Sy multi_vdev_crash_dump
|
||||||
@ -251,6 +272,130 @@ configuration.
|
|||||||
.\" .Xr dumpon 8
|
.\" .Xr dumpon 8
|
||||||
.\" command to configure a
|
.\" command to configure a
|
||||||
.\" dump device on a pool comprised of multiple vdevs.
|
.\" dump device on a pool comprised of multiple vdevs.
|
||||||
|
.It Sy spacemap_histogram
|
||||||
|
.Bl -column "READ\-ONLY COMPATIBLE" "com.delphix:spacemap_histogram"
|
||||||
|
.It GUID Ta com.delphix:spacemap_histogram
|
||||||
|
.It READ\-ONLY COMPATIBLE Ta yes
|
||||||
|
.It DEPENDENCIES Ta none
|
||||||
|
.El
|
||||||
|
.Pp
|
||||||
|
This features allows ZFS to maintain more information about how free space
|
||||||
|
is organized within the pool. If this feature is
|
||||||
|
.Sy enabled ,
|
||||||
|
ZFS will
|
||||||
|
set this feature to
|
||||||
|
.Sy active
|
||||||
|
when a new space map object is created or
|
||||||
|
an existing space map is upgraded to the new format.
|
||||||
|
Once the feature is
|
||||||
|
.Sy active ,
|
||||||
|
it will remain in that state until the pool is destroyed.
|
||||||
|
.It Sy extensible_dataset
|
||||||
|
.Bl -column "READ\-ONLY COMPATIBLE" "com.delphix:extensible_dataset"
|
||||||
|
.It GUID Ta com.delphix:extensible_dataset
|
||||||
|
.It READ\-ONLY COMPATIBLE Ta no
|
||||||
|
.It DEPENDENCIES Ta none
|
||||||
|
.El
|
||||||
|
.Pp
|
||||||
|
This feature allows more flexible use of internal ZFS data structures,
|
||||||
|
and exists for other features to depend on.
|
||||||
|
.Pp
|
||||||
|
This feature will be
|
||||||
|
.Sy active
|
||||||
|
when the first dependent feature uses it,
|
||||||
|
and will be returned to the
|
||||||
|
.Sy enabled
|
||||||
|
state when all datasets that use
|
||||||
|
this feature are destroyed.
|
||||||
|
.It Sy bookmarks
|
||||||
|
.Bl -column "READ\-ONLY COMPATIBLE" "com.delphix:bookmarks"
|
||||||
|
.It GUID Ta com.delphix:bookmarks
|
||||||
|
.It READ\-ONLY COMPATIBLE Ta yes
|
||||||
|
.It DEPENDENCIES Ta extensible_dataset
|
||||||
|
.El
|
||||||
|
.Pp
|
||||||
|
This feature enables use of the
|
||||||
|
.Nm zfs
|
||||||
|
.Cm bookmark
|
||||||
|
subcommand.
|
||||||
|
.Pp
|
||||||
|
This feature is
|
||||||
|
.Sy active
|
||||||
|
while any bookmarks exist in the pool.
|
||||||
|
All bookmarks in the pool can be listed by running
|
||||||
|
.Nm zfs
|
||||||
|
.Cm list
|
||||||
|
.Fl t No bookmark Fl r Ar poolname .
|
||||||
|
.It Sy enabled_txg
|
||||||
|
.Bl -column "READ\-ONLY COMPATIBLE" "com.delphix:enabled_txg"
|
||||||
|
.It GUID Ta com.delphix:enabled_txg
|
||||||
|
.It READ\-ONLY COMPATIBLE Ta yes
|
||||||
|
.It DEPENDENCIES Ta none
|
||||||
|
.El
|
||||||
|
.Pp
|
||||||
|
Once this feature is enabled ZFS records the transaction group number
|
||||||
|
in which new features are enabled. This has no user-visible impact,
|
||||||
|
but other features may depend on this feature.
|
||||||
|
.Pp
|
||||||
|
This feature becomes
|
||||||
|
.Sy active
|
||||||
|
as soon as it is enabled and will
|
||||||
|
never return to being
|
||||||
|
.Sy enabled .
|
||||||
|
.It Sy hole_birth
|
||||||
|
.Bl -column "READ\-ONLY COMPATIBLE" "com.delphix:hole_birth"
|
||||||
|
.It GUID Ta com.delphix:hole_birth
|
||||||
|
.It READ\-ONLY COMPATIBLE Ta no
|
||||||
|
.It DEPENDENCIES Ta enabled_txg
|
||||||
|
.El
|
||||||
|
.Pp
|
||||||
|
This feature improves performance of incremental sends
|
||||||
|
.Pq Dq zfs send -i
|
||||||
|
and receives for objects with many holes.
|
||||||
|
The most common case of
|
||||||
|
hole-filled objects is zvols.
|
||||||
|
.Pp
|
||||||
|
An incremental send stream from snapshot
|
||||||
|
.Sy A
|
||||||
|
to snapshot
|
||||||
|
.Sy B
|
||||||
|
contains information about every block that changed between
|
||||||
|
.Sy A
|
||||||
|
and
|
||||||
|
.Sy B .
|
||||||
|
Blocks which did not change between those snapshots can be
|
||||||
|
identified and omitted from the stream using a piece of metadata called
|
||||||
|
the 'block birth time', but birth times are not recorded for holes
|
||||||
|
.Pq blocks filled only with zeroes .
|
||||||
|
Since holes created after
|
||||||
|
.Sy A
|
||||||
|
cannot be
|
||||||
|
distinguished from holes created before
|
||||||
|
.Sy A ,
|
||||||
|
information about every
|
||||||
|
hole in the entire filesystem or zvol is included in the send stream.
|
||||||
|
.Pp
|
||||||
|
For workloads where holes are rare this is not a problem.
|
||||||
|
However, when
|
||||||
|
incrementally replicating filesystems or zvols with many holes
|
||||||
|
.Pq for example a zvol formatted with another filesystem
|
||||||
|
a lot of time will
|
||||||
|
be spent sending and receiving unnecessary information about holes that
|
||||||
|
already exist on the receiving side.
|
||||||
|
.Pp
|
||||||
|
Once the
|
||||||
|
.Sy hole_birth
|
||||||
|
feature has been enabled the block birth times
|
||||||
|
of all new holes will be recorded.
|
||||||
|
Incremental sends between snapshots
|
||||||
|
created after this feature is enabled will use this new metadata to avoid
|
||||||
|
sending information about holes that already exist on the receiving side.
|
||||||
|
.Pp
|
||||||
|
This feature becomes
|
||||||
|
.Sy active
|
||||||
|
as soon as it is enabled and will
|
||||||
|
never return to being
|
||||||
|
.Sy enabled .
|
||||||
.El
|
.El
|
||||||
.Sh SEE ALSO
|
.Sh SEE ALSO
|
||||||
.Xr zpool 8
|
.Xr zpool 8
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
'\" te
|
'\" te
|
||||||
.\" Copyright (c) 2012, Martin Matuska <mm@FreeBSD.org>.
|
.\" Copyright (c) 2012, Martin Matuska <mm@FreeBSD.org>.
|
||||||
|
.\" Copyright (c) 2013-2014, Xin Li <delphij@FreeBSD.org>.
|
||||||
.\" All Rights Reserved.
|
.\" All Rights Reserved.
|
||||||
.\"
|
.\"
|
||||||
.\" The contents of this file are subject to the terms of the
|
.\" The contents of this file are subject to the terms of the
|
||||||
@ -25,7 +26,7 @@
|
|||||||
.\"
|
.\"
|
||||||
.\" $FreeBSD$
|
.\" $FreeBSD$
|
||||||
.\"
|
.\"
|
||||||
.Dd March 14, 2013
|
.Dd March 28, 2014
|
||||||
.Dt ZPOOL 8
|
.Dt ZPOOL 8
|
||||||
.Os
|
.Os
|
||||||
.Sh NAME
|
.Sh NAME
|
||||||
@ -70,6 +71,8 @@
|
|||||||
.Ar pool ...
|
.Ar pool ...
|
||||||
.Nm
|
.Nm
|
||||||
.Cm get
|
.Cm get
|
||||||
|
.Op Fl Hp
|
||||||
|
.Op Fl o Ar field Ns Op , Ns Ar ...
|
||||||
.Ar all | property Ns Op , Ns Ar ...
|
.Ar all | property Ns Op , Ns Ar ...
|
||||||
.Ar pool ...
|
.Ar pool ...
|
||||||
.Nm
|
.Nm
|
||||||
@ -120,7 +123,7 @@
|
|||||||
.Ar device
|
.Ar device
|
||||||
.Nm
|
.Nm
|
||||||
.Cm list
|
.Cm list
|
||||||
.Op Fl H
|
.Op Fl Hpv
|
||||||
.Op Fl o Ar property Ns Op , Ns Ar ...
|
.Op Fl o Ar property Ns Op , Ns Ar ...
|
||||||
.Op Fl T Cm d Ns | Ns Cm u
|
.Op Fl T Cm d Ns | Ns Cm u
|
||||||
.Op Ar pool
|
.Op Ar pool
|
||||||
@ -141,6 +144,9 @@
|
|||||||
.Cm remove
|
.Cm remove
|
||||||
.Ar pool device ...
|
.Ar pool device ...
|
||||||
.Nm
|
.Nm
|
||||||
|
.Cm reopen
|
||||||
|
.Ar pool
|
||||||
|
.Nm
|
||||||
.Cm replace
|
.Cm replace
|
||||||
.Op Fl f
|
.Op Fl f
|
||||||
.Ar pool device
|
.Ar pool device
|
||||||
@ -621,6 +627,9 @@ Datasets of this pool can only be mounted read-only
|
|||||||
.It
|
.It
|
||||||
To write to a read-only pool, a export and import of the pool is required.
|
To write to a read-only pool, a export and import of the pool is required.
|
||||||
.El
|
.El
|
||||||
|
.Pp
|
||||||
|
This property can also be referred to by its shortened column name,
|
||||||
|
.Sy rdonly .
|
||||||
.El
|
.El
|
||||||
.Pp
|
.Pp
|
||||||
The following properties can be set at creation time and import time, and later
|
The following properties can be set at creation time and import time, and later
|
||||||
@ -679,7 +688,9 @@ property.
|
|||||||
Threshold for the number of block ditto copies. If the reference count for a
|
Threshold for the number of block ditto copies. If the reference count for a
|
||||||
deduplicated block increases above this number, a new ditto copy of this block
|
deduplicated block increases above this number, a new ditto copy of this block
|
||||||
is automatically stored. Default setting is
|
is automatically stored. Default setting is
|
||||||
.Cm 0 .
|
.Cm 0
|
||||||
|
which causes no ditto copies to be created for deduplicated blocks.
|
||||||
|
The miniumum legal nonzero setting is 100.
|
||||||
.It Sy delegation Ns = Ns Cm on No | Cm off
|
.It Sy delegation Ns = Ns Cm on No | Cm off
|
||||||
Controls whether a non-privileged user is granted access based on the dataset
|
Controls whether a non-privileged user is granted access based on the dataset
|
||||||
permissions defined on the dataset. See
|
permissions defined on the dataset. See
|
||||||
@ -1010,6 +1021,8 @@ is currently being used. This may lead to potential data corruption.
|
|||||||
.It Xo
|
.It Xo
|
||||||
.Nm
|
.Nm
|
||||||
.Cm get
|
.Cm get
|
||||||
|
.Op Fl Hp
|
||||||
|
.Op Fl o Ar field Ns Op , Ns Ar ...
|
||||||
.Ar all | property Ns Op , Ns Ar ...
|
.Ar all | property Ns Op , Ns Ar ...
|
||||||
.Ar pool ...
|
.Ar pool ...
|
||||||
.Xc
|
.Xc
|
||||||
@ -1028,6 +1041,19 @@ the following fields:
|
|||||||
See the
|
See the
|
||||||
.Qq Sx Properties
|
.Qq Sx Properties
|
||||||
section for more information on the available pool properties.
|
section for more information on the available pool properties.
|
||||||
|
.Pp
|
||||||
|
.It Fl H
|
||||||
|
Scripted mode. Do not display headers, and separate fields by a single tab
|
||||||
|
instead of arbitrary space.
|
||||||
|
.It Fl p
|
||||||
|
Display numbers in parsable (exact) values.
|
||||||
|
.It Fl o Ar field
|
||||||
|
A comma-separated list of columns to display.
|
||||||
|
.Sy name Ns , Ns
|
||||||
|
.Sy property Ns , Ns
|
||||||
|
.Sy value Ns , Ns
|
||||||
|
.Sy source
|
||||||
|
is the default value.
|
||||||
.It Xo
|
.It Xo
|
||||||
.Nm
|
.Nm
|
||||||
.Cm history
|
.Cm history
|
||||||
@ -1149,9 +1175,10 @@ option is also required.
|
|||||||
.It Fl f
|
.It Fl f
|
||||||
Forces import, even if the pool appears to be potentially active.
|
Forces import, even if the pool appears to be potentially active.
|
||||||
.It Fl m
|
.It Fl m
|
||||||
Enables import with missing log devices.
|
Allows a pool to import when there is a missing log device. Recent transactions
|
||||||
|
can be lost because the log device will be discarded.
|
||||||
.It Fl N
|
.It Fl N
|
||||||
Do not mount any filesystems from the imported pool.
|
Import the pool without mounting any file systems.
|
||||||
.It Fl R Ar root
|
.It Fl R Ar root
|
||||||
Sets the
|
Sets the
|
||||||
.Qq Sy cachefile
|
.Qq Sy cachefile
|
||||||
@ -1242,9 +1269,10 @@ option is also required.
|
|||||||
.It Fl f
|
.It Fl f
|
||||||
Forces import, even if the pool appears to be potentially active.
|
Forces import, even if the pool appears to be potentially active.
|
||||||
.It Fl m
|
.It Fl m
|
||||||
Enables import with missing log devices.
|
Allows a pool to import when there is a missing log device. Recent transactions
|
||||||
|
can be lost because the log device will be discarded.
|
||||||
.It Fl N
|
.It Fl N
|
||||||
Do not mount any filesystems from the imported pool.
|
Import the pool without mounting any file systems.
|
||||||
.It Fl R Ar root
|
.It Fl R Ar root
|
||||||
Equivalent to
|
Equivalent to
|
||||||
.Qq Fl o Cm cachefile=none,altroot= Ns Pa root
|
.Qq Fl o Cm cachefile=none,altroot= Ns Pa root
|
||||||
@ -1319,13 +1347,13 @@ The
|
|||||||
.Ar device
|
.Ar device
|
||||||
must not be part of an active pool configuration.
|
must not be part of an active pool configuration.
|
||||||
.Bl -tag -width indent
|
.Bl -tag -width indent
|
||||||
.It Fl v
|
.It Fl f
|
||||||
Treat exported or foreign devices as inactive.
|
Treat exported or foreign devices as inactive.
|
||||||
.El
|
.El
|
||||||
.It Xo
|
.It Xo
|
||||||
.Nm
|
.Nm
|
||||||
.Cm list
|
.Cm list
|
||||||
.Op Fl Hv
|
.Op Fl Hpv
|
||||||
.Op Fl o Ar property Ns Op , Ns Ar ...
|
.Op Fl o Ar property Ns Op , Ns Ar ...
|
||||||
.Op Fl T Cm d Ns | Ns Cm u
|
.Op Fl T Cm d Ns | Ns Cm u
|
||||||
.Op Ar pool
|
.Op Ar pool
|
||||||
@ -1333,8 +1361,9 @@ Treat exported or foreign devices as inactive.
|
|||||||
.Op Ar inverval Op Ar count
|
.Op Ar inverval Op Ar count
|
||||||
.Xc
|
.Xc
|
||||||
.Pp
|
.Pp
|
||||||
Lists the given pools along with a health status and space usage. When given no
|
Lists the given pools along with a health status and space usage. If no
|
||||||
arguments, all pools in the system are listed.
|
.Ar pools
|
||||||
|
are specified, all pools in the system are listed.
|
||||||
.Pp
|
.Pp
|
||||||
When given an interval, the output is printed every
|
When given an interval, the output is printed every
|
||||||
.Ar interval
|
.Ar interval
|
||||||
@ -1346,9 +1375,22 @@ is specified, the command exits after
|
|||||||
.Ar count
|
.Ar count
|
||||||
reports are printed.
|
reports are printed.
|
||||||
.Bl -tag -width indent
|
.Bl -tag -width indent
|
||||||
|
.It Fl T Cm d Ns | Ns Cm u
|
||||||
|
Print a timestamp.
|
||||||
|
.Pp
|
||||||
|
Use modifier
|
||||||
|
.Cm d
|
||||||
|
for standard date format. See
|
||||||
|
.Xr date 1 .
|
||||||
|
Use modifier
|
||||||
|
.Cm u
|
||||||
|
for unixtime
|
||||||
|
.Pq equals Qq Ic date +%s .
|
||||||
.It Fl H
|
.It Fl H
|
||||||
Scripted mode. Do not display headers, and separate fields by a single tab
|
Scripted mode. Do not display headers, and separate fields by a single tab
|
||||||
instead of arbitrary space.
|
instead of arbitrary space.
|
||||||
|
.It Fl p
|
||||||
|
Display numbers in parsable (exact) values.
|
||||||
.It Fl v
|
.It Fl v
|
||||||
Show more detailed information.
|
Show more detailed information.
|
||||||
.It Fl o Ar property Ns Op , Ns Ar ...
|
.It Fl o Ar property Ns Op , Ns Ar ...
|
||||||
@ -1431,6 +1473,13 @@ command. Non-redundant and
|
|||||||
devices cannot be removed from a pool.
|
devices cannot be removed from a pool.
|
||||||
.It Xo
|
.It Xo
|
||||||
.Nm
|
.Nm
|
||||||
|
.Cm reopen
|
||||||
|
.Ar pool
|
||||||
|
.Xc
|
||||||
|
.Pp
|
||||||
|
Reopen all the vdevs associated with the pool.
|
||||||
|
.It Xo
|
||||||
|
.Nm
|
||||||
.Cm replace
|
.Cm replace
|
||||||
.Op Fl f
|
.Op Fl f
|
||||||
.Ar pool device
|
.Ar pool device
|
||||||
@ -1667,7 +1716,7 @@ Once this is done, the pool will no longer be accessible on systems that do
|
|||||||
not support feature flags.
|
not support feature flags.
|
||||||
See
|
See
|
||||||
.Xr zpool-features 7
|
.Xr zpool-features 7
|
||||||
for details on compatability with system sthat support feature flags, but do
|
for details on compatibility with systems that support feature flags, but do
|
||||||
not support all features enabled on the pool.
|
not support all features enabled on the pool.
|
||||||
.Bl -tag -width indent
|
.Bl -tag -width indent
|
||||||
.It Fl a
|
.It Fl a
|
||||||
@ -1946,3 +1995,9 @@ The
|
|||||||
.Xr mdoc 7
|
.Xr mdoc 7
|
||||||
implementation of this manual page was initially written by
|
implementation of this manual page was initially written by
|
||||||
.An Martin Matuska Aq mm@FreeBSD.org .
|
.An Martin Matuska Aq mm@FreeBSD.org .
|
||||||
|
.Sh CAVEATS
|
||||||
|
The
|
||||||
|
.Cm spare
|
||||||
|
feature requires a utility to detect zpool degradation and initiate
|
||||||
|
disk replacement within the zpool.
|
||||||
|
FreeBSD does not provide such a utility at this time.
|
||||||
|
@ -22,7 +22,7 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||||
* Copyright 2011 Nexenta Systems, Inc. All rights reserved.
|
* Copyright 2011 Nexenta Systems, Inc. All rights reserved.
|
||||||
* Copyright (c) 2012 by Delphix. All rights reserved.
|
* Copyright (c) 2013 by Delphix. All rights reserved.
|
||||||
* Copyright (c) 2012 by Frederik Wessels. All rights reserved.
|
* Copyright (c) 2012 by Frederik Wessels. All rights reserved.
|
||||||
* Copyright (c) 2012 Martin Matuska <mm@FreeBSD.org>. All rights reserved.
|
* Copyright (c) 2012 Martin Matuska <mm@FreeBSD.org>. All rights reserved.
|
||||||
* Copyright (c) 2013 by Prasad Joshi (sTec). All rights reserved.
|
* Copyright (c) 2013 by Prasad Joshi (sTec). All rights reserved.
|
||||||
@ -236,7 +236,7 @@ get_usage(zpool_help_t idx) {
|
|||||||
case HELP_LABELCLEAR:
|
case HELP_LABELCLEAR:
|
||||||
return (gettext("\tlabelclear [-f] <vdev>\n"));
|
return (gettext("\tlabelclear [-f] <vdev>\n"));
|
||||||
case HELP_LIST:
|
case HELP_LIST:
|
||||||
return (gettext("\tlist [-Hv] [-o property[,...]] "
|
return (gettext("\tlist [-Hpv] [-o property[,...]] "
|
||||||
"[-T d|u] [pool] ... [interval [count]]\n"));
|
"[-T d|u] [pool] ... [interval [count]]\n"));
|
||||||
case HELP_OFFLINE:
|
case HELP_OFFLINE:
|
||||||
return (gettext("\toffline [-t] <pool> <device> ...\n"));
|
return (gettext("\toffline [-t] <pool> <device> ...\n"));
|
||||||
@ -248,7 +248,7 @@ get_usage(zpool_help_t idx) {
|
|||||||
case HELP_REMOVE:
|
case HELP_REMOVE:
|
||||||
return (gettext("\tremove <pool> <device> ...\n"));
|
return (gettext("\tremove <pool> <device> ...\n"));
|
||||||
case HELP_REOPEN:
|
case HELP_REOPEN:
|
||||||
return (""); /* Undocumented command */
|
return (gettext("\treopen <pool>\n"));
|
||||||
case HELP_SCRUB:
|
case HELP_SCRUB:
|
||||||
return (gettext("\tscrub [-s] <pool> ...\n"));
|
return (gettext("\tscrub [-s] <pool> ...\n"));
|
||||||
case HELP_STATUS:
|
case HELP_STATUS:
|
||||||
@ -258,8 +258,8 @@ get_usage(zpool_help_t idx) {
|
|||||||
return (gettext("\tupgrade [-v]\n"
|
return (gettext("\tupgrade [-v]\n"
|
||||||
"\tupgrade [-V version] <-a | pool ...>\n"));
|
"\tupgrade [-V version] <-a | pool ...>\n"));
|
||||||
case HELP_GET:
|
case HELP_GET:
|
||||||
return (gettext("\tget <\"all\" | property[,...]> "
|
return (gettext("\tget [-Hp] [-o \"all\" | field[,...]] "
|
||||||
"<pool> ...\n"));
|
"<\"all\" | property[,...]> <pool> ...\n"));
|
||||||
case HELP_SET:
|
case HELP_SET:
|
||||||
return (gettext("\tset <property=value> <pool> \n"));
|
return (gettext("\tset <property=value> <pool> \n"));
|
||||||
case HELP_SPLIT:
|
case HELP_SPLIT:
|
||||||
@ -1004,7 +1004,7 @@ zpool_do_create(int argc, char **argv)
|
|||||||
* Hand off to libzfs.
|
* Hand off to libzfs.
|
||||||
*/
|
*/
|
||||||
if (enable_all_pool_feat) {
|
if (enable_all_pool_feat) {
|
||||||
int i;
|
spa_feature_t i;
|
||||||
for (i = 0; i < SPA_FEATURES; i++) {
|
for (i = 0; i < SPA_FEATURES; i++) {
|
||||||
char propname[MAXPATHLEN];
|
char propname[MAXPATHLEN];
|
||||||
zfeature_info_t *feat = &spa_feature_table[i];
|
zfeature_info_t *feat = &spa_feature_table[i];
|
||||||
@ -1702,6 +1702,12 @@ show_import(nvlist_t *config)
|
|||||||
"resilvered.\n"));
|
"resilvered.\n"));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case ZPOOL_STATUS_NON_NATIVE_ASHIFT:
|
||||||
|
(void) printf(gettext("status: One or more devices were "
|
||||||
|
"configured to use a non-native block size.\n"
|
||||||
|
"\tExpect reduced performance.\n"));
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
/*
|
/*
|
||||||
* No other status can be seen when importing pools.
|
* No other status can be seen when importing pools.
|
||||||
@ -1963,7 +1969,7 @@ zpool_do_import(int argc, char **argv)
|
|||||||
char *endptr;
|
char *endptr;
|
||||||
|
|
||||||
/* check options */
|
/* check options */
|
||||||
while ((c = getopt(argc, argv, ":aCc:d:DEfFmnNo:rR:T:VX")) != -1) {
|
while ((c = getopt(argc, argv, ":aCc:d:DEfFmnNo:R:T:VX")) != -1) {
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case 'a':
|
case 'a':
|
||||||
do_all = B_TRUE;
|
do_all = B_TRUE;
|
||||||
@ -2759,6 +2765,7 @@ typedef struct list_cbdata {
|
|||||||
int cb_namewidth;
|
int cb_namewidth;
|
||||||
boolean_t cb_scripted;
|
boolean_t cb_scripted;
|
||||||
zprop_list_t *cb_proplist;
|
zprop_list_t *cb_proplist;
|
||||||
|
boolean_t cb_literal;
|
||||||
} list_cbdata_t;
|
} list_cbdata_t;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -2854,7 +2861,7 @@ print_pool(zpool_handle_t *zhp, list_cbdata_t *cb)
|
|||||||
zpool_get_prop_int(zhp, pl->pl_prop, NULL) == 0)
|
zpool_get_prop_int(zhp, pl->pl_prop, NULL) == 0)
|
||||||
propstr = "-";
|
propstr = "-";
|
||||||
else if (zpool_get_prop(zhp, pl->pl_prop, property,
|
else if (zpool_get_prop(zhp, pl->pl_prop, property,
|
||||||
sizeof (property), NULL) != 0)
|
sizeof (property), NULL, cb->cb_literal) != 0)
|
||||||
propstr = "-";
|
propstr = "-";
|
||||||
else
|
else
|
||||||
propstr = property;
|
propstr = property;
|
||||||
@ -3005,12 +3012,13 @@ list_callback(zpool_handle_t *zhp, void *data)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* zpool list [-H] [-o prop[,prop]*] [-T d|u] [pool] ... [interval [count]]
|
* zpool list [-Hp] [-o prop[,prop]*] [-T d|u] [pool] ... [interval [count]]
|
||||||
*
|
*
|
||||||
* -H Scripted mode. Don't display headers, and separate properties
|
* -H Scripted mode. Don't display headers, and separate properties
|
||||||
* by a single tab.
|
* by a single tab.
|
||||||
* -o List of properties to display. Defaults to
|
* -o List of properties to display. Defaults to
|
||||||
* "name,size,allocated,free,capacity,health,altroot"
|
* "name,size,allocated,free,capacity,health,altroot"
|
||||||
|
* -p Diplay values in parsable (exact) format.
|
||||||
* -T Display a timestamp in date(1) or Unix format
|
* -T Display a timestamp in date(1) or Unix format
|
||||||
*
|
*
|
||||||
* List all pools in the system, whether or not they're healthy. Output space
|
* List all pools in the system, whether or not they're healthy. Output space
|
||||||
@ -3031,7 +3039,7 @@ zpool_do_list(int argc, char **argv)
|
|||||||
boolean_t first = B_TRUE;
|
boolean_t first = B_TRUE;
|
||||||
|
|
||||||
/* check options */
|
/* check options */
|
||||||
while ((c = getopt(argc, argv, ":Ho:T:v")) != -1) {
|
while ((c = getopt(argc, argv, ":Ho:pT:v")) != -1) {
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case 'H':
|
case 'H':
|
||||||
cb.cb_scripted = B_TRUE;
|
cb.cb_scripted = B_TRUE;
|
||||||
@ -3039,6 +3047,9 @@ zpool_do_list(int argc, char **argv)
|
|||||||
case 'o':
|
case 'o':
|
||||||
props = optarg;
|
props = optarg;
|
||||||
break;
|
break;
|
||||||
|
case 'p':
|
||||||
|
cb.cb_literal = B_TRUE;
|
||||||
|
break;
|
||||||
case 'T':
|
case 'T':
|
||||||
get_timestamp_arg(*optarg);
|
get_timestamp_arg(*optarg);
|
||||||
break;
|
break;
|
||||||
@ -3714,22 +3725,37 @@ zpool_do_reguid(int argc, char **argv)
|
|||||||
* zpool reopen <pool>
|
* zpool reopen <pool>
|
||||||
*
|
*
|
||||||
* Reopen the pool so that the kernel can update the sizes of all vdevs.
|
* Reopen the pool so that the kernel can update the sizes of all vdevs.
|
||||||
*
|
|
||||||
* NOTE: This command is currently undocumented. If the command is ever
|
|
||||||
* exposed then the appropriate usage() messages will need to be made.
|
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
zpool_do_reopen(int argc, char **argv)
|
zpool_do_reopen(int argc, char **argv)
|
||||||
{
|
{
|
||||||
|
int c;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
zpool_handle_t *zhp;
|
zpool_handle_t *zhp;
|
||||||
char *pool;
|
char *pool;
|
||||||
|
|
||||||
|
/* check options */
|
||||||
|
while ((c = getopt(argc, argv, "")) != -1) {
|
||||||
|
switch (c) {
|
||||||
|
case '?':
|
||||||
|
(void) fprintf(stderr, gettext("invalid option '%c'\n"),
|
||||||
|
optopt);
|
||||||
|
usage(B_FALSE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
argc--;
|
argc--;
|
||||||
argv++;
|
argv++;
|
||||||
|
|
||||||
if (argc != 1)
|
if (argc < 1) {
|
||||||
return (2);
|
(void) fprintf(stderr, gettext("missing pool name\n"));
|
||||||
|
usage(B_FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (argc > 1) {
|
||||||
|
(void) fprintf(stderr, gettext("too many arguments\n"));
|
||||||
|
usage(B_FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
pool = argv[0];
|
pool = argv[0];
|
||||||
if ((zhp = zpool_open_canfail(g_zfs, pool)) == NULL)
|
if ((zhp = zpool_open_canfail(g_zfs, pool)) == NULL)
|
||||||
@ -5178,7 +5204,7 @@ get_callback(zpool_handle_t *zhp, void *data)
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (zpool_get_prop(zhp, pl->pl_prop, value,
|
if (zpool_get_prop(zhp, pl->pl_prop, value,
|
||||||
sizeof (value), &srctype) != 0)
|
sizeof (value), &srctype, cbp->cb_literal) != 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
zprop_print_one_property(zpool_get_name(zhp), cbp,
|
zprop_print_one_property(zpool_get_name(zhp), cbp,
|
||||||
@ -5189,20 +5215,32 @@ get_callback(zpool_handle_t *zhp, void *data)
|
|||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* zpool get [-Hp] [-o "all" | field[,...]] <"all" | property[,...]> <pool> ...
|
||||||
|
*
|
||||||
|
* -H Scripted mode. Don't display headers, and separate properties
|
||||||
|
* by a single tab.
|
||||||
|
* -o List of columns to display. Defaults to
|
||||||
|
* "name,property,value,source".
|
||||||
|
* -p Diplay values in parsable (exact) format.
|
||||||
|
*
|
||||||
|
* Get properties of pools in the system. Output space statistics
|
||||||
|
* for each one as well as other attributes.
|
||||||
|
*/
|
||||||
int
|
int
|
||||||
zpool_do_get(int argc, char **argv)
|
zpool_do_get(int argc, char **argv)
|
||||||
{
|
{
|
||||||
zprop_get_cbdata_t cb = { 0 };
|
zprop_get_cbdata_t cb = { 0 };
|
||||||
zprop_list_t fake_name = { 0 };
|
zprop_list_t fake_name = { 0 };
|
||||||
int ret;
|
int ret;
|
||||||
|
int c, i;
|
||||||
if (argc < 2) {
|
char *value;
|
||||||
(void) fprintf(stderr, gettext("missing property "
|
|
||||||
"argument\n"));
|
|
||||||
usage(B_FALSE);
|
|
||||||
}
|
|
||||||
|
|
||||||
cb.cb_first = B_TRUE;
|
cb.cb_first = B_TRUE;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set up default columns and sources.
|
||||||
|
*/
|
||||||
cb.cb_sources = ZPROP_SRC_ALL;
|
cb.cb_sources = ZPROP_SRC_ALL;
|
||||||
cb.cb_columns[0] = GET_COL_NAME;
|
cb.cb_columns[0] = GET_COL_NAME;
|
||||||
cb.cb_columns[1] = GET_COL_PROPERTY;
|
cb.cb_columns[1] = GET_COL_PROPERTY;
|
||||||
@ -5210,10 +5248,89 @@ zpool_do_get(int argc, char **argv)
|
|||||||
cb.cb_columns[3] = GET_COL_SOURCE;
|
cb.cb_columns[3] = GET_COL_SOURCE;
|
||||||
cb.cb_type = ZFS_TYPE_POOL;
|
cb.cb_type = ZFS_TYPE_POOL;
|
||||||
|
|
||||||
if (zprop_get_list(g_zfs, argv[1], &cb.cb_proplist,
|
/* check options */
|
||||||
|
while ((c = getopt(argc, argv, ":Hpo:")) != -1) {
|
||||||
|
switch (c) {
|
||||||
|
case 'p':
|
||||||
|
cb.cb_literal = B_TRUE;
|
||||||
|
break;
|
||||||
|
case 'H':
|
||||||
|
cb.cb_scripted = B_TRUE;
|
||||||
|
break;
|
||||||
|
case 'o':
|
||||||
|
bzero(&cb.cb_columns, sizeof (cb.cb_columns));
|
||||||
|
i = 0;
|
||||||
|
while (*optarg != '\0') {
|
||||||
|
static char *col_subopts[] =
|
||||||
|
{ "name", "property", "value", "source",
|
||||||
|
"all", NULL };
|
||||||
|
|
||||||
|
if (i == ZFS_GET_NCOLS) {
|
||||||
|
(void) fprintf(stderr, gettext("too "
|
||||||
|
"many fields given to -o "
|
||||||
|
"option\n"));
|
||||||
|
usage(B_FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (getsubopt(&optarg, col_subopts,
|
||||||
|
&value)) {
|
||||||
|
case 0:
|
||||||
|
cb.cb_columns[i++] = GET_COL_NAME;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
cb.cb_columns[i++] = GET_COL_PROPERTY;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
cb.cb_columns[i++] = GET_COL_VALUE;
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
cb.cb_columns[i++] = GET_COL_SOURCE;
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
if (i > 0) {
|
||||||
|
(void) fprintf(stderr,
|
||||||
|
gettext("\"all\" conflicts "
|
||||||
|
"with specific fields "
|
||||||
|
"given to -o option\n"));
|
||||||
|
usage(B_FALSE);
|
||||||
|
}
|
||||||
|
cb.cb_columns[0] = GET_COL_NAME;
|
||||||
|
cb.cb_columns[1] = GET_COL_PROPERTY;
|
||||||
|
cb.cb_columns[2] = GET_COL_VALUE;
|
||||||
|
cb.cb_columns[3] = GET_COL_SOURCE;
|
||||||
|
i = ZFS_GET_NCOLS;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
(void) fprintf(stderr,
|
||||||
|
gettext("invalid column name "
|
||||||
|
"'%s'\n"), value);
|
||||||
|
usage(B_FALSE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case '?':
|
||||||
|
(void) fprintf(stderr, gettext("invalid option '%c'\n"),
|
||||||
|
optopt);
|
||||||
|
usage(B_FALSE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
argc -= optind;
|
||||||
|
argv += optind;
|
||||||
|
|
||||||
|
if (argc < 1) {
|
||||||
|
(void) fprintf(stderr, gettext("missing property "
|
||||||
|
"argument\n"));
|
||||||
|
usage(B_FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (zprop_get_list(g_zfs, argv[0], &cb.cb_proplist,
|
||||||
ZFS_TYPE_POOL) != 0)
|
ZFS_TYPE_POOL) != 0)
|
||||||
usage(B_FALSE);
|
usage(B_FALSE);
|
||||||
|
|
||||||
|
argc--;
|
||||||
|
argv++;
|
||||||
|
|
||||||
if (cb.cb_proplist != NULL) {
|
if (cb.cb_proplist != NULL) {
|
||||||
fake_name.pl_prop = ZPOOL_PROP_NAME;
|
fake_name.pl_prop = ZPOOL_PROP_NAME;
|
||||||
fake_name.pl_width = strlen(gettext("NAME"));
|
fake_name.pl_width = strlen(gettext("NAME"));
|
||||||
@ -5221,7 +5338,7 @@ zpool_do_get(int argc, char **argv)
|
|||||||
cb.cb_proplist = &fake_name;
|
cb.cb_proplist = &fake_name;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = for_each_pool(argc - 2, argv + 2, B_TRUE, &cb.cb_proplist,
|
ret = for_each_pool(argc, argv, B_TRUE, &cb.cb_proplist,
|
||||||
get_callback, &cb);
|
get_callback, &cb);
|
||||||
|
|
||||||
if (cb.cb_proplist == &fake_name)
|
if (cb.cb_proplist == &fake_name)
|
||||||
|
@ -18,10 +18,11 @@
|
|||||||
.\" information: Portions Copyright [yyyy] [name of copyright owner]
|
.\" information: Portions Copyright [yyyy] [name of copyright owner]
|
||||||
.\"
|
.\"
|
||||||
.\" Copyright (c) 2009, Sun Microsystems, Inc. All Rights Reserved.
|
.\" Copyright (c) 2009, Sun Microsystems, Inc. All Rights Reserved.
|
||||||
|
.\" Copyright (c) 2013, Delphix. All Rights Reserved.
|
||||||
.\"
|
.\"
|
||||||
.\" $FreeBSD$
|
.\" $FreeBSD$
|
||||||
.\"
|
.\"
|
||||||
.Dd November 26, 2011
|
.Dd December 31, 2013
|
||||||
.Dt ZSTREAMDUMP 8
|
.Dt ZSTREAMDUMP 8
|
||||||
.Os
|
.Os
|
||||||
.Sh NAME
|
.Sh NAME
|
||||||
@ -30,6 +31,7 @@
|
|||||||
.Sh SYNOPSIS
|
.Sh SYNOPSIS
|
||||||
.Nm
|
.Nm
|
||||||
.Op Fl C
|
.Op Fl C
|
||||||
|
.Op Fl d
|
||||||
.Op Fl v
|
.Op Fl v
|
||||||
.Sh DESCRIPTION
|
.Sh DESCRIPTION
|
||||||
The
|
The
|
||||||
@ -43,6 +45,8 @@ The following options are supported:
|
|||||||
.Bl -tag -width indent
|
.Bl -tag -width indent
|
||||||
.It Fl C
|
.It Fl C
|
||||||
Suppress the validation of checksums.
|
Suppress the validation of checksums.
|
||||||
|
.It Fl d
|
||||||
|
Dump contents of blocks modified, implies verbose.
|
||||||
.It Fl v
|
.It Fl v
|
||||||
Verbose. Dump all headers, not only begin and end headers.
|
Verbose. Dump all headers, not only begin and end headers.
|
||||||
.El
|
.El
|
||||||
|
@ -24,6 +24,11 @@
|
|||||||
* Use is subject to license terms.
|
* Use is subject to license terms.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2013 by Delphix. All rights reserved.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <ctype.h>
|
||||||
#include <libnvpair.h>
|
#include <libnvpair.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
@ -34,6 +39,16 @@
|
|||||||
#include <sys/zfs_ioctl.h>
|
#include <sys/zfs_ioctl.h>
|
||||||
#include <zfs_fletcher.h>
|
#include <zfs_fletcher.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If dump mode is enabled, the number of bytes to print per line
|
||||||
|
*/
|
||||||
|
#define BYTES_PER_LINE 16
|
||||||
|
/*
|
||||||
|
* If dump mode is enabled, the number of bytes to group together, separated
|
||||||
|
* by newlines or spaces
|
||||||
|
*/
|
||||||
|
#define DUMP_GROUPING 4
|
||||||
|
|
||||||
uint64_t drr_record_count[DRR_NUMTYPES];
|
uint64_t drr_record_count[DRR_NUMTYPES];
|
||||||
uint64_t total_write_size = 0;
|
uint64_t total_write_size = 0;
|
||||||
uint64_t total_stream_len = 0;
|
uint64_t total_stream_len = 0;
|
||||||
@ -45,9 +60,11 @@ boolean_t do_cksum = B_TRUE;
|
|||||||
static void
|
static void
|
||||||
usage(void)
|
usage(void)
|
||||||
{
|
{
|
||||||
(void) fprintf(stderr, "usage: zstreamdump [-v] [-C] < file\n");
|
(void) fprintf(stderr, "usage: zstreamdump [-v] [-C] [-d] < file\n");
|
||||||
(void) fprintf(stderr, "\t -v -- verbose\n");
|
(void) fprintf(stderr, "\t -v -- verbose\n");
|
||||||
(void) fprintf(stderr, "\t -C -- suppress checksum verification\n");
|
(void) fprintf(stderr, "\t -C -- suppress checksum verification\n");
|
||||||
|
(void) fprintf(stderr, "\t -d -- dump contents of blocks modified, "
|
||||||
|
"implies verbose\n");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -75,6 +92,70 @@ ssread(void *buf, size_t len, zio_cksum_t *cksum)
|
|||||||
return (outlen);
|
return (outlen);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Print part of a block in ASCII characters
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
print_ascii_block(char *subbuf, int length)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < length; i++) {
|
||||||
|
char char_print = isprint(subbuf[i]) ? subbuf[i] : '.';
|
||||||
|
if (i != 0 && i % DUMP_GROUPING == 0) {
|
||||||
|
(void) printf(" ");
|
||||||
|
}
|
||||||
|
(void) printf("%c", char_print);
|
||||||
|
}
|
||||||
|
(void) printf("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* print_block - Dump the contents of a modified block to STDOUT
|
||||||
|
*
|
||||||
|
* Assume that buf has capacity evenly divisible by BYTES_PER_LINE
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
print_block(char *buf, int length)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
/*
|
||||||
|
* Start printing ASCII characters at a constant offset, after
|
||||||
|
* the hex prints. Leave 3 characters per byte on a line (2 digit
|
||||||
|
* hex number plus 1 space) plus spaces between characters and
|
||||||
|
* groupings
|
||||||
|
*/
|
||||||
|
int ascii_start = BYTES_PER_LINE * 3 +
|
||||||
|
BYTES_PER_LINE / DUMP_GROUPING + 2;
|
||||||
|
|
||||||
|
for (i = 0; i < length; i += BYTES_PER_LINE) {
|
||||||
|
int j;
|
||||||
|
int this_line_length = MIN(BYTES_PER_LINE, length - i);
|
||||||
|
int print_offset = 0;
|
||||||
|
|
||||||
|
for (j = 0; j < this_line_length; j++) {
|
||||||
|
int buf_offset = i + j;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Separate every DUMP_GROUPING bytes by a space.
|
||||||
|
*/
|
||||||
|
if (buf_offset % DUMP_GROUPING == 0) {
|
||||||
|
print_offset += printf(" ");
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Print the two-digit hex value for this byte.
|
||||||
|
*/
|
||||||
|
unsigned char hex_print = buf[buf_offset];
|
||||||
|
print_offset += printf("%02x ", hex_print);
|
||||||
|
}
|
||||||
|
|
||||||
|
(void) printf("%*s", ascii_start - print_offset, " ");
|
||||||
|
|
||||||
|
print_ascii_block(buf + i, this_line_length);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
main(int argc, char *argv[])
|
main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
@ -92,11 +173,17 @@ main(int argc, char *argv[])
|
|||||||
char c;
|
char c;
|
||||||
boolean_t verbose = B_FALSE;
|
boolean_t verbose = B_FALSE;
|
||||||
boolean_t first = B_TRUE;
|
boolean_t first = B_TRUE;
|
||||||
|
/*
|
||||||
|
* dump flag controls whether the contents of any modified data blocks
|
||||||
|
* are printed to the console during processing of the stream. Warning:
|
||||||
|
* for large streams, this can obviously lead to massive prints.
|
||||||
|
*/
|
||||||
|
boolean_t dump = B_FALSE;
|
||||||
int err;
|
int err;
|
||||||
zio_cksum_t zc = { 0 };
|
zio_cksum_t zc = { 0 };
|
||||||
zio_cksum_t pcksum = { 0 };
|
zio_cksum_t pcksum = { 0 };
|
||||||
|
|
||||||
while ((c = getopt(argc, argv, ":vC")) != -1) {
|
while ((c = getopt(argc, argv, ":vCd")) != -1) {
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case 'C':
|
case 'C':
|
||||||
do_cksum = B_FALSE;
|
do_cksum = B_FALSE;
|
||||||
@ -104,6 +191,10 @@ main(int argc, char *argv[])
|
|||||||
case 'v':
|
case 'v':
|
||||||
verbose = B_TRUE;
|
verbose = B_TRUE;
|
||||||
break;
|
break;
|
||||||
|
case 'd':
|
||||||
|
dump = B_TRUE;
|
||||||
|
verbose = B_TRUE;
|
||||||
|
break;
|
||||||
case ':':
|
case ':':
|
||||||
(void) fprintf(stderr,
|
(void) fprintf(stderr,
|
||||||
"missing argument for '%c' option\n", optopt);
|
"missing argument for '%c' option\n", optopt);
|
||||||
@ -128,6 +219,10 @@ main(int argc, char *argv[])
|
|||||||
pcksum = zc;
|
pcksum = zc;
|
||||||
while (ssread(drr, sizeof (dmu_replay_record_t), &zc)) {
|
while (ssread(drr, sizeof (dmu_replay_record_t), &zc)) {
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If this is the first DMU record being processed, check for
|
||||||
|
* the magic bytes and figure out the endian-ness based on them.
|
||||||
|
*/
|
||||||
if (first) {
|
if (first) {
|
||||||
if (drrb->drr_magic == BSWAP_64(DMU_BACKUP_MAGIC)) {
|
if (drrb->drr_magic == BSWAP_64(DMU_BACKUP_MAGIC)) {
|
||||||
do_byteswap = B_TRUE;
|
do_byteswap = B_TRUE;
|
||||||
@ -209,7 +304,7 @@ main(int argc, char *argv[])
|
|||||||
nvlist_t *nv;
|
nvlist_t *nv;
|
||||||
int sz = drr->drr_payloadlen;
|
int sz = drr->drr_payloadlen;
|
||||||
|
|
||||||
if (sz > 1<<20) {
|
if (sz > INITIAL_BUFLEN) {
|
||||||
free(buf);
|
free(buf);
|
||||||
buf = malloc(sz);
|
buf = malloc(sz);
|
||||||
}
|
}
|
||||||
@ -283,6 +378,10 @@ main(int argc, char *argv[])
|
|||||||
if (drro->drr_bonuslen > 0) {
|
if (drro->drr_bonuslen > 0) {
|
||||||
(void) ssread(buf, P2ROUNDUP(drro->drr_bonuslen,
|
(void) ssread(buf, P2ROUNDUP(drro->drr_bonuslen,
|
||||||
8), &zc);
|
8), &zc);
|
||||||
|
if (dump) {
|
||||||
|
print_block(buf,
|
||||||
|
P2ROUNDUP(drro->drr_bonuslen, 8));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -312,6 +411,10 @@ main(int argc, char *argv[])
|
|||||||
drrw->drr_key.ddk_prop =
|
drrw->drr_key.ddk_prop =
|
||||||
BSWAP_64(drrw->drr_key.ddk_prop);
|
BSWAP_64(drrw->drr_key.ddk_prop);
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
|
* If this is verbose and/or dump output,
|
||||||
|
* print info on the modified block
|
||||||
|
*/
|
||||||
if (verbose) {
|
if (verbose) {
|
||||||
(void) printf("WRITE object = %llu type = %u "
|
(void) printf("WRITE object = %llu type = %u "
|
||||||
"checksum type = %u\n"
|
"checksum type = %u\n"
|
||||||
@ -324,7 +427,16 @@ main(int argc, char *argv[])
|
|||||||
(u_longlong_t)drrw->drr_length,
|
(u_longlong_t)drrw->drr_length,
|
||||||
(u_longlong_t)drrw->drr_key.ddk_prop);
|
(u_longlong_t)drrw->drr_key.ddk_prop);
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
|
* Read the contents of the block in from STDIN to buf
|
||||||
|
*/
|
||||||
(void) ssread(buf, drrw->drr_length, &zc);
|
(void) ssread(buf, drrw->drr_length, &zc);
|
||||||
|
/*
|
||||||
|
* If in dump mode
|
||||||
|
*/
|
||||||
|
if (dump) {
|
||||||
|
print_block(buf, drrw->drr_length);
|
||||||
|
}
|
||||||
total_write_size += drrw->drr_length;
|
total_write_size += drrw->drr_length;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -390,6 +502,9 @@ main(int argc, char *argv[])
|
|||||||
drrs->drr_length);
|
drrs->drr_length);
|
||||||
}
|
}
|
||||||
(void) ssread(buf, drrs->drr_length, &zc);
|
(void) ssread(buf, drrs->drr_length, &zc);
|
||||||
|
if (dump) {
|
||||||
|
print_block(buf, drrs->drr_length);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
pcksum = zc;
|
pcksum = zc;
|
||||||
|
@ -186,7 +186,7 @@ static const ztest_shared_opts_t ztest_opts_defaults = {
|
|||||||
|
|
||||||
extern uint64_t metaslab_gang_bang;
|
extern uint64_t metaslab_gang_bang;
|
||||||
extern uint64_t metaslab_df_alloc_threshold;
|
extern uint64_t metaslab_df_alloc_threshold;
|
||||||
extern uint64_t zfs_deadman_synctime;
|
extern uint64_t zfs_deadman_synctime_ms;
|
||||||
|
|
||||||
static ztest_shared_opts_t *ztest_shared_opts;
|
static ztest_shared_opts_t *ztest_shared_opts;
|
||||||
static ztest_shared_opts_t ztest_opts;
|
static ztest_shared_opts_t ztest_opts;
|
||||||
@ -5328,10 +5328,10 @@ ztest_deadman_thread(void *arg)
|
|||||||
hrtime_t delta, total = 0;
|
hrtime_t delta, total = 0;
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
delta = (zs->zs_thread_stop - zs->zs_thread_start) /
|
delta = zs->zs_thread_stop - zs->zs_thread_start +
|
||||||
NANOSEC + zfs_deadman_synctime;
|
MSEC2NSEC(zfs_deadman_synctime_ms);
|
||||||
|
|
||||||
(void) poll(NULL, 0, (int)(1000 * delta));
|
(void) poll(NULL, 0, (int)NSEC2MSEC(delta));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If the pool is suspended then fail immediately. Otherwise,
|
* If the pool is suspended then fail immediately. Otherwise,
|
||||||
@ -5339,15 +5339,15 @@ ztest_deadman_thread(void *arg)
|
|||||||
* vdev_deadman() discovers that there hasn't been any recent
|
* vdev_deadman() discovers that there hasn't been any recent
|
||||||
* I/Os then it will end up aborting the tests.
|
* I/Os then it will end up aborting the tests.
|
||||||
*/
|
*/
|
||||||
if (spa_suspended(spa)) {
|
if (spa_suspended(spa) || spa->spa_root_vdev == NULL) {
|
||||||
fatal(0, "aborting test after %llu seconds because "
|
fatal(0, "aborting test after %llu seconds because "
|
||||||
"pool has transitioned to a suspended state.",
|
"pool has transitioned to a suspended state.",
|
||||||
zfs_deadman_synctime);
|
zfs_deadman_synctime_ms / 1000);
|
||||||
return (NULL);
|
return (NULL);
|
||||||
}
|
}
|
||||||
vdev_deadman(spa->spa_root_vdev);
|
vdev_deadman(spa->spa_root_vdev);
|
||||||
|
|
||||||
total += zfs_deadman_synctime;
|
total += zfs_deadman_synctime_ms/1000;
|
||||||
(void) printf("ztest has been running for %lld seconds\n",
|
(void) printf("ztest has been running for %lld seconds\n",
|
||||||
total);
|
total);
|
||||||
}
|
}
|
||||||
@ -6080,7 +6080,7 @@ main(int argc, char **argv)
|
|||||||
(void) setvbuf(stdout, NULL, _IOLBF, 0);
|
(void) setvbuf(stdout, NULL, _IOLBF, 0);
|
||||||
|
|
||||||
dprintf_setup(&argc, argv);
|
dprintf_setup(&argc, argv);
|
||||||
zfs_deadman_synctime = 300;
|
zfs_deadman_synctime_ms = 300000;
|
||||||
|
|
||||||
ztest_fd_rand = open("/dev/urandom", O_RDONLY);
|
ztest_fd_rand = open("/dev/urandom", O_RDONLY);
|
||||||
ASSERT3S(ztest_fd_rand, >=, 0);
|
ASSERT3S(ztest_fd_rand, >=, 0);
|
||||||
|
@ -65,7 +65,7 @@ ctf_create(int *errp)
|
|||||||
cts.cts_name = _CTF_SECTION;
|
cts.cts_name = _CTF_SECTION;
|
||||||
cts.cts_type = SHT_PROGBITS;
|
cts.cts_type = SHT_PROGBITS;
|
||||||
cts.cts_flags = 0;
|
cts.cts_flags = 0;
|
||||||
cts.cts_data = &hdr;
|
cts.cts_data = (void *)&hdr;
|
||||||
cts.cts_size = sizeof (hdr);
|
cts.cts_size = sizeof (hdr);
|
||||||
cts.cts_entsize = 1;
|
cts.cts_entsize = 1;
|
||||||
cts.cts_offset = 0;
|
cts.cts_offset = 0;
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
|
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
|
||||||
|
* Copyright 2013 Voxer Inc. All rights reserved.
|
||||||
* Use is subject to license terms.
|
* Use is subject to license terms.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -144,7 +145,8 @@ dtrace_dof_init(void)
|
|||||||
Lmid_t lmid;
|
Lmid_t lmid;
|
||||||
#else
|
#else
|
||||||
u_long lmid = 0;
|
u_long lmid = 0;
|
||||||
dof_sec_t *sec;
|
dof_sec_t *sec, *secstart, *dofstrtab, *dofprobes;
|
||||||
|
dof_provider_t *dofprovider;
|
||||||
size_t i;
|
size_t i;
|
||||||
#endif
|
#endif
|
||||||
int fd;
|
int fd;
|
||||||
@ -152,14 +154,15 @@ dtrace_dof_init(void)
|
|||||||
#if !defined(sun)
|
#if !defined(sun)
|
||||||
Elf *e;
|
Elf *e;
|
||||||
Elf_Scn *scn = NULL;
|
Elf_Scn *scn = NULL;
|
||||||
Elf_Data *symtabdata = NULL, *dynsymdata = NULL;
|
Elf_Data *symtabdata = NULL, *dynsymdata = NULL, *dofdata = NULL;
|
||||||
|
dof_hdr_t *dof_next = NULL;
|
||||||
GElf_Shdr shdr;
|
GElf_Shdr shdr;
|
||||||
int efd, nprobes;
|
int efd, nprobes;
|
||||||
char *s;
|
char *s;
|
||||||
|
char *dofstrtabraw;
|
||||||
size_t shstridx, symtabidx = 0, dynsymidx = 0;
|
size_t shstridx, symtabidx = 0, dynsymidx = 0;
|
||||||
unsigned char *dofstrtab = NULL;
|
|
||||||
unsigned char *buf;
|
unsigned char *buf;
|
||||||
int fixedprobes = 0;
|
int fixedprobes;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (getenv("DTRACE_DOF_INIT_DISABLE") != NULL)
|
if (getenv("DTRACE_DOF_INIT_DISABLE") != NULL)
|
||||||
@ -209,7 +212,8 @@ dtrace_dof_init(void)
|
|||||||
} else if (shdr.sh_type == SHT_PROGBITS) {
|
} else if (shdr.sh_type == SHT_PROGBITS) {
|
||||||
s = elf_strptr(e, shstridx, shdr.sh_name);
|
s = elf_strptr(e, shstridx, shdr.sh_name);
|
||||||
if (s && strcmp(s, ".SUNW_dof") == 0) {
|
if (s && strcmp(s, ".SUNW_dof") == 0) {
|
||||||
dof = elf_getdata(scn, NULL)->d_buf;
|
dofdata = elf_getdata(scn, NULL);
|
||||||
|
dof = dofdata->d_buf;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -219,6 +223,10 @@ dtrace_dof_init(void)
|
|||||||
close(efd);
|
close(efd);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
while ((char *) dof < (char *) dofdata->d_buf + dofdata->d_size) {
|
||||||
|
fixedprobes = 0;
|
||||||
|
dof_next = (void *) ((char *) dof + dof->dofh_filesz);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (dof->dofh_ident[DOF_ID_MAG0] != DOF_MAG_MAG0 ||
|
if (dof->dofh_ident[DOF_ID_MAG0] != DOF_MAG_MAG0 ||
|
||||||
@ -290,26 +298,40 @@ dtrace_dof_init(void)
|
|||||||
* We are assuming the number of probes is less than the number of
|
* We are assuming the number of probes is less than the number of
|
||||||
* symbols (libc can have 4k symbols, for example).
|
* symbols (libc can have 4k symbols, for example).
|
||||||
*/
|
*/
|
||||||
sec = (dof_sec_t *)(dof + 1);
|
secstart = sec = (dof_sec_t *)(dof + 1);
|
||||||
buf = (char *)dof;
|
buf = (char *)dof;
|
||||||
for (i = 0; i < dof->dofh_secnum; i++, sec++) {
|
for (i = 0; i < dof->dofh_secnum; i++, sec++) {
|
||||||
if (sec->dofs_type == DOF_SECT_STRTAB)
|
if (sec->dofs_type != DOF_SECT_PROVIDER)
|
||||||
dofstrtab = (unsigned char *)(buf + sec->dofs_offset);
|
continue;
|
||||||
else if (sec->dofs_type == DOF_SECT_PROBES && dofstrtab)
|
|
||||||
break;
|
|
||||||
|
|
||||||
|
dofprovider = (void *) (buf + sec->dofs_offset);
|
||||||
|
dofstrtab = secstart + dofprovider->dofpv_strtab;
|
||||||
|
dofprobes = secstart + dofprovider->dofpv_probes;
|
||||||
|
|
||||||
|
if (dofstrtab->dofs_type != DOF_SECT_STRTAB) {
|
||||||
|
fprintf(stderr, "WARNING: expected STRTAB section, but got %d\n",
|
||||||
|
dofstrtab->dofs_type);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
nprobes = sec->dofs_size / sec->dofs_entsize;
|
if (dofprobes->dofs_type != DOF_SECT_PROBES) {
|
||||||
fixsymbol(e, symtabdata, symtabidx, nprobes, buf, sec, &fixedprobes,
|
fprintf(stderr, "WARNING: expected PROBES section, but got %d\n",
|
||||||
dofstrtab);
|
dofprobes->dofs_type);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
dprintf(1, "found provider %p\n", dofprovider);
|
||||||
|
dofstrtabraw = (char *)(buf + dofstrtab->dofs_offset);
|
||||||
|
nprobes = dofprobes->dofs_size / dofprobes->dofs_entsize;
|
||||||
|
fixsymbol(e, symtabdata, symtabidx, nprobes, buf, dofprobes, &fixedprobes,
|
||||||
|
dofstrtabraw);
|
||||||
if (fixedprobes != nprobes) {
|
if (fixedprobes != nprobes) {
|
||||||
/*
|
/*
|
||||||
* If we haven't fixed all the probes using the
|
* If we haven't fixed all the probes using the
|
||||||
* symtab section, look inside the dynsym
|
* symtab section, look inside the dynsym
|
||||||
* section.
|
* section.
|
||||||
*/
|
*/
|
||||||
fixsymbol(e, dynsymdata, dynsymidx, nprobes, buf, sec,
|
fixsymbol(e, dynsymdata, dynsymidx, nprobes, buf, dofprobes,
|
||||||
&fixedprobes, dofstrtab);
|
&fixedprobes, dofstrtabraw);
|
||||||
}
|
}
|
||||||
if (fixedprobes != nprobes) {
|
if (fixedprobes != nprobes) {
|
||||||
fprintf(stderr, "WARNING: number of probes "
|
fprintf(stderr, "WARNING: number of probes "
|
||||||
@ -319,6 +341,7 @@ dtrace_dof_init(void)
|
|||||||
fprintf(stderr, "WARNING: some probes might "
|
fprintf(stderr, "WARNING: some probes might "
|
||||||
"not fire or your program might crash\n");
|
"not fire or your program might crash\n");
|
||||||
}
|
}
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
if ((gen = ioctl(fd, DTRACEHIOC_ADDDOF, &dh)) == -1)
|
if ((gen = ioctl(fd, DTRACEHIOC_ADDDOF, &dh)) == -1)
|
||||||
dprintf(1, "DTrace ioctl failed for DOF at %p", dof);
|
dprintf(1, "DTrace ioctl failed for DOF at %p", dof);
|
||||||
@ -330,7 +353,12 @@ dtrace_dof_init(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
(void) close(fd);
|
(void) close(fd);
|
||||||
|
|
||||||
#if !defined(sun)
|
#if !defined(sun)
|
||||||
|
/* End of while loop */
|
||||||
|
dof = dof_next;
|
||||||
|
}
|
||||||
|
|
||||||
elf_end(e);
|
elf_end(e);
|
||||||
(void) close(efd);
|
(void) close(efd);
|
||||||
#endif
|
#endif
|
||||||
|
@ -22,6 +22,7 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||||
* Copyright (c) 2011 by Delphix. All rights reserved.
|
* Copyright (c) 2011 by Delphix. All rights reserved.
|
||||||
|
* Copyright (c) 2013, Joyent, Inc. All rights reserved.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
@ -486,7 +487,7 @@ dof_add_probe(dt_idhash_t *dhp, dt_ident_t *idp, void *data)
|
|||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static int
|
||||||
dof_add_provider(dt_dof_t *ddo, const dt_provider_t *pvp)
|
dof_add_provider(dt_dof_t *ddo, const dt_provider_t *pvp)
|
||||||
{
|
{
|
||||||
dtrace_hdl_t *dtp = ddo->ddo_hdl;
|
dtrace_hdl_t *dtp = ddo->ddo_hdl;
|
||||||
@ -497,8 +498,12 @@ dof_add_provider(dt_dof_t *ddo, const dt_provider_t *pvp)
|
|||||||
size_t sz;
|
size_t sz;
|
||||||
id_t i;
|
id_t i;
|
||||||
|
|
||||||
if (pvp->pv_flags & DT_PROVIDER_IMPL)
|
if (pvp->pv_flags & DT_PROVIDER_IMPL) {
|
||||||
return; /* ignore providers that are exported by dtrace(7D) */
|
/*
|
||||||
|
* ignore providers that are exported by dtrace(7D)
|
||||||
|
*/
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
nxr = dt_popcb(pvp->pv_xrefs, pvp->pv_xrmax);
|
nxr = dt_popcb(pvp->pv_xrefs, pvp->pv_xrmax);
|
||||||
dofs = alloca(sizeof (dof_secidx_t) * (nxr + 1));
|
dofs = alloca(sizeof (dof_secidx_t) * (nxr + 1));
|
||||||
@ -525,6 +530,9 @@ dof_add_provider(dt_dof_t *ddo, const dt_provider_t *pvp)
|
|||||||
|
|
||||||
(void) dt_idhash_iter(pvp->pv_probes, dof_add_probe, ddo);
|
(void) dt_idhash_iter(pvp->pv_probes, dof_add_probe, ddo);
|
||||||
|
|
||||||
|
if (dt_buf_len(&ddo->ddo_probes) == 0)
|
||||||
|
return (dt_set_errno(dtp, EDT_NOPROBES));
|
||||||
|
|
||||||
dofpv.dofpv_probes = dof_add_lsect(ddo, NULL, DOF_SECT_PROBES,
|
dofpv.dofpv_probes = dof_add_lsect(ddo, NULL, DOF_SECT_PROBES,
|
||||||
sizeof (uint64_t), 0, sizeof (dof_probe_t),
|
sizeof (uint64_t), 0, sizeof (dof_probe_t),
|
||||||
dt_buf_len(&ddo->ddo_probes));
|
dt_buf_len(&ddo->ddo_probes));
|
||||||
@ -579,6 +587,8 @@ dof_add_provider(dt_dof_t *ddo, const dt_provider_t *pvp)
|
|||||||
sizeof (dof_secidx_t), 0, sizeof (dof_secidx_t),
|
sizeof (dof_secidx_t), 0, sizeof (dof_secidx_t),
|
||||||
sizeof (dof_secidx_t) * (nxr + 1));
|
sizeof (dof_secidx_t) * (nxr + 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
@ -822,8 +832,10 @@ dtrace_dof_create(dtrace_hdl_t *dtp, dtrace_prog_t *pgp, uint_t flags)
|
|||||||
*/
|
*/
|
||||||
if (flags & DTRACE_D_PROBES) {
|
if (flags & DTRACE_D_PROBES) {
|
||||||
for (pvp = dt_list_next(&dtp->dt_provlist);
|
for (pvp = dt_list_next(&dtp->dt_provlist);
|
||||||
pvp != NULL; pvp = dt_list_next(pvp))
|
pvp != NULL; pvp = dt_list_next(pvp)) {
|
||||||
dof_add_provider(ddo, pvp);
|
if (dof_add_provider(ddo, pvp) != 0)
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -26,6 +26,7 @@
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2012 by Delphix. All rights reserved.
|
* Copyright (c) 2012 by Delphix. All rights reserved.
|
||||||
|
* Copyright (c) 2013, Joyent, Inc. All rights reserved.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
@ -109,7 +110,8 @@ static const struct {
|
|||||||
{ EDT_BADSTACKPC, "Invalid stack program counter size" },
|
{ EDT_BADSTACKPC, "Invalid stack program counter size" },
|
||||||
{ EDT_BADAGGVAR, "Invalid aggregation variable identifier" },
|
{ EDT_BADAGGVAR, "Invalid aggregation variable identifier" },
|
||||||
{ EDT_OVERSION, "Client requested deprecated version of library" },
|
{ EDT_OVERSION, "Client requested deprecated version of library" },
|
||||||
{ EDT_ENABLING_ERR, "Failed to enable probe" }
|
{ EDT_ENABLING_ERR, "Failed to enable probe" },
|
||||||
|
{ EDT_NOPROBES, "No probe sites found for declared provider" }
|
||||||
};
|
};
|
||||||
|
|
||||||
static const int _dt_nerr = sizeof (_dt_errlist) / sizeof (_dt_errlist[0]);
|
static const int _dt_nerr = sizeof (_dt_errlist) / sizeof (_dt_errlist[0]);
|
||||||
|
@ -25,7 +25,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2011, Joyent, Inc. All rights reserved.
|
* Copyright (c) 2013, Joyent, Inc. All rights reserved.
|
||||||
* Copyright (c) 2012 by Delphix. All rights reserved.
|
* Copyright (c) 2012 by Delphix. All rights reserved.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -535,7 +535,8 @@ enum {
|
|||||||
EDT_BADSTACKPC, /* invalid stack program counter size */
|
EDT_BADSTACKPC, /* invalid stack program counter size */
|
||||||
EDT_BADAGGVAR, /* invalid aggregation variable identifier */
|
EDT_BADAGGVAR, /* invalid aggregation variable identifier */
|
||||||
EDT_OVERSION, /* client is requesting deprecated version */
|
EDT_OVERSION, /* client is requesting deprecated version */
|
||||||
EDT_ENABLING_ERR /* failed to enable probe */
|
EDT_ENABLING_ERR, /* failed to enable probe */
|
||||||
|
EDT_NOPROBES /* no probes sites for declared provider */
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -242,8 +242,14 @@ printf("%s:%s(%d): DOODAD\n",__FUNCTION__,__FILE__,__LINE__);
|
|||||||
/* XXX */
|
/* XXX */
|
||||||
printf("%s:%s(%d): DOODAD\n",__FUNCTION__,__FILE__,__LINE__);
|
printf("%s:%s(%d): DOODAD\n",__FUNCTION__,__FILE__,__LINE__);
|
||||||
#elif defined(__powerpc__)
|
#elif defined(__powerpc__)
|
||||||
/* XXX */
|
/*
|
||||||
printf("%s:%s(%d): DOODAD\n",__FUNCTION__,__FILE__,__LINE__);
|
* Add 4 bytes to hit the low half of this 64-bit
|
||||||
|
* big-endian address.
|
||||||
|
*/
|
||||||
|
rel->r_offset = s->dofs_offset +
|
||||||
|
dofr[j].dofr_offset + 4;
|
||||||
|
rel->r_info = ELF32_R_INFO(count + dep->de_global,
|
||||||
|
R_PPC_REL32);
|
||||||
#elif defined(__sparc)
|
#elif defined(__sparc)
|
||||||
/*
|
/*
|
||||||
* Add 4 bytes to hit the low half of this 64-bit
|
* Add 4 bytes to hit the low half of this 64-bit
|
||||||
@ -423,7 +429,10 @@ prepare_elf64(dtrace_hdl_t *dtp, const dof_hdr_t *dof, dof_elf64_t *dep)
|
|||||||
#elif defined(__mips__)
|
#elif defined(__mips__)
|
||||||
/* XXX */
|
/* XXX */
|
||||||
#elif defined(__powerpc__)
|
#elif defined(__powerpc__)
|
||||||
/* XXX */
|
rel->r_offset = s->dofs_offset +
|
||||||
|
dofr[j].dofr_offset;
|
||||||
|
rel->r_info = ELF64_R_INFO(count + dep->de_global,
|
||||||
|
R_PPC64_REL64);
|
||||||
#elif defined(__i386) || defined(__amd64)
|
#elif defined(__i386) || defined(__amd64)
|
||||||
rel->r_offset = s->dofs_offset +
|
rel->r_offset = s->dofs_offset +
|
||||||
dofr[j].dofr_offset;
|
dofr[j].dofr_offset;
|
||||||
@ -824,12 +833,84 @@ printf("%s:%s(%d): DOODAD\n",__FUNCTION__,__FILE__,__LINE__);
|
|||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
#elif defined(__powerpc__)
|
#elif defined(__powerpc__)
|
||||||
|
/* The sentinel is 'xor r3,r3,r3'. */
|
||||||
|
#define DT_OP_XOR_R3 0x7c631a78
|
||||||
|
|
||||||
|
#define DT_OP_NOP 0x60000000
|
||||||
|
#define DT_OP_BLR 0x4e800020
|
||||||
|
|
||||||
|
/* This captures all forms of branching to address. */
|
||||||
|
#define DT_IS_BRANCH(inst) ((inst & 0xfc000000) == 0x48000000)
|
||||||
|
#define DT_IS_BL(inst) (DT_IS_BRANCH(inst) && (inst & 0x01))
|
||||||
|
|
||||||
/* XXX */
|
/* XXX */
|
||||||
static int
|
static int
|
||||||
dt_modtext(dtrace_hdl_t *dtp, char *p, int isenabled, GElf_Rela *rela,
|
dt_modtext(dtrace_hdl_t *dtp, char *p, int isenabled, GElf_Rela *rela,
|
||||||
uint32_t *off)
|
uint32_t *off)
|
||||||
{
|
{
|
||||||
printf("%s:%s(%d): DOODAD\n",__FUNCTION__,__FILE__,__LINE__);
|
uint32_t *ip;
|
||||||
|
|
||||||
|
if ((rela->r_offset & (sizeof (uint32_t) - 1)) != 0)
|
||||||
|
return (-1);
|
||||||
|
|
||||||
|
/*LINTED*/
|
||||||
|
ip = (uint32_t *)(p + rela->r_offset);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We only know about some specific relocation types.
|
||||||
|
*/
|
||||||
|
if (GELF_R_TYPE(rela->r_info) != R_PPC_REL24 &&
|
||||||
|
GELF_R_TYPE(rela->r_info) != R_PPC_PLTREL24)
|
||||||
|
return (-1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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 below.
|
||||||
|
*/
|
||||||
|
if (isenabled) {
|
||||||
|
if (ip[0] == DT_OP_XOR_R3) {
|
||||||
|
(*off) += sizeof (ip[0]);
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (ip[0] == DT_OP_NOP) {
|
||||||
|
(*off) += sizeof (ip[0]);
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We only expect branch to address instructions.
|
||||||
|
*/
|
||||||
|
if (!DT_IS_BRANCH(ip[0])) {
|
||||||
|
dt_dprintf("found %x instead of a branch instruction at %llx\n",
|
||||||
|
ip[0], (u_longlong_t)rela->r_offset);
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isenabled) {
|
||||||
|
/*
|
||||||
|
* It would necessarily indicate incorrect usage if an is-
|
||||||
|
* enabled probe were tail-called so flag that as an error.
|
||||||
|
* It's also potentially (very) tricky to handle gracefully,
|
||||||
|
* but could be done if this were a desired use scenario.
|
||||||
|
*/
|
||||||
|
if (!DT_IS_BL(ip[0])) {
|
||||||
|
dt_dprintf("tail call to is-enabled probe at %llx\n",
|
||||||
|
(u_longlong_t)rela->r_offset);
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
ip[0] = DT_OP_XOR_R3;
|
||||||
|
(*off) += sizeof (ip[0]);
|
||||||
|
} else {
|
||||||
|
if (DT_IS_BL(ip[0]))
|
||||||
|
ip[0] = DT_OP_NOP;
|
||||||
|
else
|
||||||
|
ip[0] = DT_OP_BLR;
|
||||||
|
}
|
||||||
|
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1539,10 +1620,17 @@ process_obj(dtrace_hdl_t *dtp, const char *obj, int *eprobesp)
|
|||||||
* the executable file as the symbol is going to be
|
* the executable file as the symbol is going to be
|
||||||
* change from UND to ABS.
|
* change from UND to ABS.
|
||||||
*/
|
*/
|
||||||
|
if (shdr_rel.sh_type == SHT_RELA) {
|
||||||
rela.r_offset = 0;
|
rela.r_offset = 0;
|
||||||
rela.r_info = 0;
|
rela.r_info = 0;
|
||||||
rela.r_addend = 0;
|
rela.r_addend = 0;
|
||||||
(void) gelf_update_rela(data_rel, i, &rela);
|
(void) gelf_update_rela(data_rel, i, &rela);
|
||||||
|
} else {
|
||||||
|
GElf_Rel rel;
|
||||||
|
rel.r_offset = 0;
|
||||||
|
rel.r_info = 0;
|
||||||
|
(void) gelf_update_rel(data_rel, i, &rel);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
mod = 1;
|
mod = 1;
|
||||||
@ -1628,8 +1716,6 @@ dtrace_program_link(dtrace_hdl_t *dtp, dtrace_prog_t *pgp, uint_t dflags,
|
|||||||
*/
|
*/
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
/* XXX Should get a temp file name here. */
|
|
||||||
snprintf(tfile, sizeof(tfile), "%s.tmp", file);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1704,9 +1790,11 @@ dtrace_program_link(dtrace_hdl_t *dtp, dtrace_prog_t *pgp, uint_t dflags,
|
|||||||
"failed to open %s: %s", file, strerror(errno)));
|
"failed to open %s: %s", file, strerror(errno)));
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
if ((fd = open(tfile, O_RDWR | O_CREAT | O_TRUNC, 0666)) == -1)
|
snprintf(tfile, sizeof(tfile), "%s.XXXXXX", file);
|
||||||
|
if ((fd = mkstemp(tfile)) == -1)
|
||||||
return (dt_link_error(dtp, NULL, -1, NULL,
|
return (dt_link_error(dtp, NULL, -1, NULL,
|
||||||
"failed to open %s: %s", tfile, strerror(errno)));
|
"failed to create temporary file %s: %s",
|
||||||
|
tfile, strerror(errno)));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1749,13 +1837,15 @@ dtrace_program_link(dtrace_hdl_t *dtp, dtrace_prog_t *pgp, uint_t dflags,
|
|||||||
status = dump_elf32(dtp, dof, fd);
|
status = dump_elf32(dtp, dof, fd);
|
||||||
|
|
||||||
if (status != 0 || lseek(fd, 0, SEEK_SET) != 0) {
|
if (status != 0 || lseek(fd, 0, SEEK_SET) != 0) {
|
||||||
#else
|
|
||||||
/* We don't write the ELF header, just the DOF section */
|
|
||||||
if (dt_write(dtp, fd, dof, dof->dofh_filesz) < dof->dofh_filesz) {
|
|
||||||
#endif
|
|
||||||
return (dt_link_error(dtp, NULL, -1, NULL,
|
return (dt_link_error(dtp, NULL, -1, NULL,
|
||||||
"failed to write %s: %s", file, strerror(errno)));
|
"failed to write %s: %s", file, strerror(errno)));
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
/* We don't write the ELF header, just the DOF section */
|
||||||
|
if (dt_write(dtp, fd, dof, dof->dofh_filesz) < dof->dofh_filesz)
|
||||||
|
return (dt_link_error(dtp, NULL, -1, NULL,
|
||||||
|
"failed to write %s: %s", tfile, strerror(errno)));
|
||||||
|
#endif
|
||||||
|
|
||||||
if (!dtp->dt_lazyload) {
|
if (!dtp->dt_lazyload) {
|
||||||
#if defined(sun)
|
#if defined(sun)
|
||||||
@ -1783,7 +1873,7 @@ dtrace_program_link(dtrace_hdl_t *dtp, dtrace_prog_t *pgp, uint_t dflags,
|
|||||||
* Arches which default to 64-bit need to explicitly use
|
* Arches which default to 64-bit need to explicitly use
|
||||||
* the 32-bit library path.
|
* the 32-bit library path.
|
||||||
*/
|
*/
|
||||||
int use_32 = !(dtp->dt_oflags & DTRACE_O_LP64);
|
int use_32 = (dtp->dt_oflags & DTRACE_O_ILP32);
|
||||||
#else
|
#else
|
||||||
/*
|
/*
|
||||||
* Arches which are 32-bit only just use the normal
|
* Arches which are 32-bit only just use the normal
|
||||||
@ -1798,9 +1888,7 @@ dtrace_program_link(dtrace_hdl_t *dtp, dtrace_prog_t *pgp, uint_t dflags,
|
|||||||
len = snprintf(&tmp, 1, fmt, dtp->dt_ld_path, file, tfile,
|
len = snprintf(&tmp, 1, fmt, dtp->dt_ld_path, file, tfile,
|
||||||
drti) + 1;
|
drti) + 1;
|
||||||
|
|
||||||
#if !defined(sun)
|
|
||||||
len *= 2;
|
len *= 2;
|
||||||
#endif
|
|
||||||
cmd = alloca(len);
|
cmd = alloca(len);
|
||||||
|
|
||||||
(void) snprintf(cmd, len, fmt, dtp->dt_ld_path, file,
|
(void) snprintf(cmd, len, fmt, dtp->dt_ld_path, file,
|
||||||
|
@ -311,6 +311,10 @@ static const dt_ident_t _dtrace_globals[] = {
|
|||||||
&dt_idops_func, "void(@)" },
|
&dt_idops_func, "void(@)" },
|
||||||
{ "memref", DT_IDENT_FUNC, 0, DIF_SUBR_MEMREF, DT_ATTR_STABCMN, DT_VERS_1_1,
|
{ "memref", DT_IDENT_FUNC, 0, DIF_SUBR_MEMREF, DT_ATTR_STABCMN, DT_VERS_1_1,
|
||||||
&dt_idops_func, "uintptr_t *(void *, size_t)" },
|
&dt_idops_func, "uintptr_t *(void *, size_t)" },
|
||||||
|
#if !defined(sun)
|
||||||
|
{ "memstr", DT_IDENT_FUNC, 0, DIF_SUBR_MEMSTR, DT_ATTR_STABCMN, DT_VERS_1_0,
|
||||||
|
&dt_idops_func, "string(void *, char, size_t)" },
|
||||||
|
#endif
|
||||||
{ "min", DT_IDENT_AGGFUNC, 0, DTRACEAGG_MIN, DT_ATTR_STABCMN, DT_VERS_1_0,
|
{ "min", DT_IDENT_AGGFUNC, 0, DTRACEAGG_MIN, DT_ATTR_STABCMN, DT_VERS_1_0,
|
||||||
&dt_idops_func, "void(@)" },
|
&dt_idops_func, "void(@)" },
|
||||||
{ "mod", DT_IDENT_ACTFUNC, 0, DT_ACT_MOD, DT_ATTR_STABCMN,
|
{ "mod", DT_IDENT_ACTFUNC, 0, DT_ACT_MOD, DT_ATTR_STABCMN,
|
||||||
@ -483,22 +487,16 @@ static const dt_ident_t _dtrace_globals[] = {
|
|||||||
DT_VERS_1_0, &dt_idops_func, "void(...)" },
|
DT_VERS_1_0, &dt_idops_func, "void(...)" },
|
||||||
{ "typeref", DT_IDENT_FUNC, 0, DIF_SUBR_TYPEREF, DT_ATTR_STABCMN, DT_VERS_1_1,
|
{ "typeref", DT_IDENT_FUNC, 0, DIF_SUBR_TYPEREF, DT_ATTR_STABCMN, DT_VERS_1_1,
|
||||||
&dt_idops_func, "uintptr_t *(void *, size_t, string, size_t)" },
|
&dt_idops_func, "uintptr_t *(void *, size_t, string, size_t)" },
|
||||||
#if defined(sun)
|
|
||||||
{ "uaddr", DT_IDENT_ACTFUNC, 0, DT_ACT_UADDR, DT_ATTR_STABCMN,
|
{ "uaddr", DT_IDENT_ACTFUNC, 0, DT_ACT_UADDR, DT_ATTR_STABCMN,
|
||||||
DT_VERS_1_2, &dt_idops_func, "_usymaddr(uintptr_t)" },
|
DT_VERS_1_2, &dt_idops_func, "_usymaddr(uintptr_t)" },
|
||||||
#endif
|
|
||||||
{ "ucaller", DT_IDENT_SCALAR, 0, DIF_VAR_UCALLER, DT_ATTR_STABCMN,
|
{ "ucaller", DT_IDENT_SCALAR, 0, DIF_VAR_UCALLER, DT_ATTR_STABCMN,
|
||||||
DT_VERS_1_2, &dt_idops_type, "uint64_t" },
|
DT_VERS_1_2, &dt_idops_type, "uint64_t" },
|
||||||
#if defined(sun)
|
|
||||||
{ "ufunc", DT_IDENT_ACTFUNC, 0, DT_ACT_USYM, DT_ATTR_STABCMN,
|
{ "ufunc", DT_IDENT_ACTFUNC, 0, DT_ACT_USYM, DT_ATTR_STABCMN,
|
||||||
DT_VERS_1_2, &dt_idops_func, "_usymaddr(uintptr_t)" },
|
DT_VERS_1_2, &dt_idops_func, "_usymaddr(uintptr_t)" },
|
||||||
#endif
|
|
||||||
{ "uid", DT_IDENT_SCALAR, 0, DIF_VAR_UID, DT_ATTR_STABCMN, DT_VERS_1_0,
|
{ "uid", DT_IDENT_SCALAR, 0, DIF_VAR_UID, DT_ATTR_STABCMN, DT_VERS_1_0,
|
||||||
&dt_idops_type, "uid_t" },
|
&dt_idops_type, "uid_t" },
|
||||||
#if defined(sun)
|
|
||||||
{ "umod", DT_IDENT_ACTFUNC, 0, DT_ACT_UMOD, DT_ATTR_STABCMN,
|
{ "umod", DT_IDENT_ACTFUNC, 0, DT_ACT_UMOD, DT_ATTR_STABCMN,
|
||||||
DT_VERS_1_2, &dt_idops_func, "_usymaddr(uintptr_t)" },
|
DT_VERS_1_2, &dt_idops_func, "_usymaddr(uintptr_t)" },
|
||||||
#endif
|
|
||||||
{ "uregs", DT_IDENT_ARRAY, 0, DIF_VAR_UREGS, DT_ATTR_STABCMN, DT_VERS_1_0,
|
{ "uregs", DT_IDENT_ARRAY, 0, DIF_VAR_UREGS, DT_ATTR_STABCMN, DT_VERS_1_0,
|
||||||
&dt_idops_regs, NULL },
|
&dt_idops_regs, NULL },
|
||||||
{ "ustack", DT_IDENT_ACTFUNC, 0, DT_ACT_USTACK, DT_ATTR_STABCMN, DT_VERS_1_0,
|
{ "ustack", DT_IDENT_ACTFUNC, 0, DT_ACT_USTACK, DT_ATTR_STABCMN, DT_VERS_1_0,
|
||||||
@ -506,10 +504,8 @@ static const dt_ident_t _dtrace_globals[] = {
|
|||||||
{ "ustackdepth", DT_IDENT_SCALAR, 0, DIF_VAR_USTACKDEPTH,
|
{ "ustackdepth", DT_IDENT_SCALAR, 0, DIF_VAR_USTACKDEPTH,
|
||||||
DT_ATTR_STABCMN, DT_VERS_1_2,
|
DT_ATTR_STABCMN, DT_VERS_1_2,
|
||||||
&dt_idops_type, "uint32_t" },
|
&dt_idops_type, "uint32_t" },
|
||||||
#if defined(sun)
|
|
||||||
{ "usym", DT_IDENT_ACTFUNC, 0, DT_ACT_USYM, DT_ATTR_STABCMN,
|
{ "usym", DT_IDENT_ACTFUNC, 0, DT_ACT_USYM, DT_ATTR_STABCMN,
|
||||||
DT_VERS_1_2, &dt_idops_func, "_usymaddr(uintptr_t)" },
|
DT_VERS_1_2, &dt_idops_func, "_usymaddr(uintptr_t)" },
|
||||||
#endif
|
|
||||||
{ "vtimestamp", DT_IDENT_SCALAR, 0, DIF_VAR_VTIMESTAMP,
|
{ "vtimestamp", DT_IDENT_SCALAR, 0, DIF_VAR_VTIMESTAMP,
|
||||||
DT_ATTR_STABCMN, DT_VERS_1_0,
|
DT_ATTR_STABCMN, DT_VERS_1_0,
|
||||||
&dt_idops_type, "uint64_t" },
|
&dt_idops_type, "uint64_t" },
|
||||||
|
@ -24,8 +24,6 @@
|
|||||||
* Use is subject to license terms.
|
* Use is subject to license terms.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma ident "%Z%%M% %I% %E% SMI"
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2012 by Delphix. All rights reserved.
|
* Copyright (c) 2012 by Delphix. All rights reserved.
|
||||||
*/
|
*/
|
||||||
@ -906,30 +904,6 @@ dt_options_load(dtrace_hdl_t *dtp)
|
|||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*ARGSUSED*/
|
|
||||||
static int
|
|
||||||
dt_opt_preallocate(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
|
|
||||||
{
|
|
||||||
dtrace_optval_t size;
|
|
||||||
void *p;
|
|
||||||
|
|
||||||
if (arg == NULL || dt_optval_parse(arg, &size) != 0)
|
|
||||||
return (dt_set_errno(dtp, EDT_BADOPTVAL));
|
|
||||||
|
|
||||||
if (size > SIZE_MAX)
|
|
||||||
size = SIZE_MAX;
|
|
||||||
|
|
||||||
if ((p = dt_zalloc(dtp, size)) == NULL) {
|
|
||||||
do {
|
|
||||||
size /= 2;
|
|
||||||
} while ((p = dt_zalloc(dtp, size)) == NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
dt_free(dtp, p);
|
|
||||||
|
|
||||||
return (0);
|
|
||||||
}
|
|
||||||
|
|
||||||
typedef struct dt_option {
|
typedef struct dt_option {
|
||||||
const char *o_name;
|
const char *o_name;
|
||||||
int (*o_func)(dtrace_hdl_t *, const char *, uintptr_t);
|
int (*o_func)(dtrace_hdl_t *, const char *, uintptr_t);
|
||||||
@ -968,7 +942,6 @@ static const dt_option_t _dtrace_ctoptions[] = {
|
|||||||
{ "linktype", dt_opt_linktype },
|
{ "linktype", dt_opt_linktype },
|
||||||
{ "nolibs", dt_opt_cflags, DTRACE_C_NOLIBS },
|
{ "nolibs", dt_opt_cflags, DTRACE_C_NOLIBS },
|
||||||
{ "pgmax", dt_opt_pgmax },
|
{ "pgmax", dt_opt_pgmax },
|
||||||
{ "preallocate", dt_opt_preallocate },
|
|
||||||
{ "pspec", dt_opt_cflags, DTRACE_C_PSPEC },
|
{ "pspec", dt_opt_cflags, DTRACE_C_PSPEC },
|
||||||
{ "setenv", dt_opt_setenv, 1 },
|
{ "setenv", dt_opt_setenv, 1 },
|
||||||
{ "stdc", dt_opt_stdc },
|
{ "stdc", dt_opt_stdc },
|
||||||
|
@ -694,8 +694,13 @@ static const dt_pfconv_t _dtrace_conversions[] = {
|
|||||||
{ "S", "s", pfproto_cstr, pfcheck_str, pfprint_estr },
|
{ "S", "s", pfproto_cstr, pfcheck_str, pfprint_estr },
|
||||||
{ "T", "s", "int64_t", pfcheck_time, pfprint_time822 },
|
{ "T", "s", "int64_t", pfcheck_time, pfprint_time822 },
|
||||||
{ "u", "u", pfproto_xint, pfcheck_xint, pfprint_uint },
|
{ "u", "u", pfproto_xint, pfcheck_xint, pfprint_uint },
|
||||||
|
#if defined(sun)
|
||||||
{ "wc", "wc", "int", pfcheck_type, pfprint_sint }, /* a.k.a. wchar_t */
|
{ "wc", "wc", "int", pfcheck_type, pfprint_sint }, /* a.k.a. wchar_t */
|
||||||
{ "ws", "ws", pfproto_wstr, pfcheck_wstr, pfprint_wstr },
|
{ "ws", "ws", pfproto_wstr, pfcheck_wstr, pfprint_wstr },
|
||||||
|
#else
|
||||||
|
{ "wc", "lc", "int", pfcheck_type, pfprint_sint }, /* a.k.a. wchar_t */
|
||||||
|
{ "ws", "ls", pfproto_wstr, pfcheck_wstr, pfprint_wstr },
|
||||||
|
#endif
|
||||||
{ "x", "x", pfproto_xint, pfcheck_xint, pfprint_uint },
|
{ "x", "x", pfproto_xint, pfcheck_xint, pfprint_uint },
|
||||||
{ "X", "X", pfproto_xint, pfcheck_xint, pfprint_uint },
|
{ "X", "X", pfproto_xint, pfcheck_xint, pfprint_uint },
|
||||||
{ "Y", "s", "int64_t", pfcheck_time, pfprint_time },
|
{ "Y", "s", "int64_t", pfcheck_time, pfprint_time },
|
||||||
|
@ -734,11 +734,6 @@ dt_zalloc(dtrace_hdl_t *dtp, size_t size)
|
|||||||
{
|
{
|
||||||
void *data;
|
void *data;
|
||||||
|
|
||||||
if (size > 16 * 1024 * 1024) {
|
|
||||||
(void) dt_set_errno(dtp, EDT_NOMEM);
|
|
||||||
return (NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((data = malloc(size)) == NULL)
|
if ((data = malloc(size)) == NULL)
|
||||||
(void) dt_set_errno(dtp, EDT_NOMEM);
|
(void) dt_set_errno(dtp, EDT_NOMEM);
|
||||||
else
|
else
|
||||||
@ -752,11 +747,6 @@ dt_alloc(dtrace_hdl_t *dtp, size_t size)
|
|||||||
{
|
{
|
||||||
void *data;
|
void *data;
|
||||||
|
|
||||||
if (size > 16 * 1024 * 1024) {
|
|
||||||
(void) dt_set_errno(dtp, EDT_NOMEM);
|
|
||||||
return (NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((data = malloc(size)) == NULL)
|
if ((data = malloc(size)) == NULL)
|
||||||
(void) dt_set_errno(dtp, EDT_NOMEM);
|
(void) dt_set_errno(dtp, EDT_NOMEM);
|
||||||
|
|
||||||
|
@ -35,14 +35,26 @@
|
|||||||
#include <dt_impl.h>
|
#include <dt_impl.h>
|
||||||
#include <dt_pid.h>
|
#include <dt_pid.h>
|
||||||
|
|
||||||
|
#include <libproc_compat.h>
|
||||||
|
|
||||||
/*ARGSUSED*/
|
/*ARGSUSED*/
|
||||||
int
|
int
|
||||||
dt_pid_create_entry_probe(struct ps_prochandle *P, dtrace_hdl_t *dtp,
|
dt_pid_create_entry_probe(struct ps_prochandle *P, dtrace_hdl_t *dtp,
|
||||||
fasttrap_probe_spec_t *ftp, const GElf_Sym *symp)
|
fasttrap_probe_spec_t *ftp, const GElf_Sym *symp)
|
||||||
{
|
{
|
||||||
|
ftp->ftps_type = DTFTP_ENTRY;
|
||||||
|
ftp->ftps_pc = (uintptr_t)symp->st_value;
|
||||||
|
ftp->ftps_size = (size_t)symp->st_size;
|
||||||
|
ftp->ftps_noffs = 1;
|
||||||
|
ftp->ftps_offs[0] = 0;
|
||||||
|
|
||||||
dt_dprintf("%s: unimplemented\n", __func__);
|
if (ioctl(dtp->dt_ftfd, FASTTRAPIOC_MAKEPROBE, ftp) != 0) {
|
||||||
return (DT_PROC_ERR);
|
dt_dprintf("fasttrap probe creation ioctl failed: %s\n",
|
||||||
|
strerror(errno));
|
||||||
|
return (dt_set_errno(dtp, errno));
|
||||||
|
}
|
||||||
|
|
||||||
|
return (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
@ -50,18 +62,97 @@ dt_pid_create_return_probe(struct ps_prochandle *P, dtrace_hdl_t *dtp,
|
|||||||
fasttrap_probe_spec_t *ftp, const GElf_Sym *symp, uint64_t *stret)
|
fasttrap_probe_spec_t *ftp, const GElf_Sym *symp, uint64_t *stret)
|
||||||
{
|
{
|
||||||
|
|
||||||
dt_dprintf("%s: unimplemented\n", __func__);
|
uintptr_t temp;
|
||||||
|
uint32_t *text;
|
||||||
|
int i;
|
||||||
|
int srdepth = 0;
|
||||||
|
|
||||||
|
if ((text = malloc(symp->st_size + 4)) == NULL) {
|
||||||
|
dt_dprintf("mr sparkle: malloc() failed\n");
|
||||||
return (DT_PROC_ERR);
|
return (DT_PROC_ERR);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (Pread(P, text, symp->st_size, symp->st_value) != symp->st_size) {
|
||||||
|
dt_dprintf("mr sparkle: Pread() failed\n");
|
||||||
|
free(text);
|
||||||
|
return (DT_PROC_ERR);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Leave a dummy instruction in the last slot to simplify edge
|
||||||
|
* conditions.
|
||||||
|
*/
|
||||||
|
text[symp->st_size / 4] = 0;
|
||||||
|
|
||||||
|
ftp->ftps_type = DTFTP_RETURN;
|
||||||
|
ftp->ftps_pc = symp->st_value;
|
||||||
|
ftp->ftps_size = symp->st_size;
|
||||||
|
ftp->ftps_noffs = 0;
|
||||||
|
|
||||||
|
for (i = 0; i < symp->st_size / 4; i++) {
|
||||||
|
|
||||||
|
if ((text[i] & 0xfc000001) != 0x48000000 &&
|
||||||
|
text[i] != 0x4e800020)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check for a jump within this function. If it's outside this
|
||||||
|
* function then it's a tail-call, so a return point.
|
||||||
|
*/
|
||||||
|
if ((text[i] & 0xfc000000) == 0x48000000) {
|
||||||
|
temp = (text[i] & 0x03fffffc);
|
||||||
|
/* Bit 30 denotes an absolute address. */
|
||||||
|
if (!(text[i] & 0x02)) {
|
||||||
|
temp += symp->st_value + i * 4;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* Sign extend the absolute address. */
|
||||||
|
if (temp & 0x02000000) {
|
||||||
|
temp |= (UINTPTR_MAX - 0x03ffffff);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (temp >= symp->st_value &&
|
||||||
|
temp <= (symp->st_value + symp->st_size))
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
dt_dprintf("return at offset %x\n", i * 4);
|
||||||
|
ftp->ftps_offs[ftp->ftps_noffs++] = i * 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
free(text);
|
||||||
|
if (ftp->ftps_noffs > 0) {
|
||||||
|
if (ioctl(dtp->dt_ftfd, FASTTRAPIOC_MAKEPROBE, ftp) != 0) {
|
||||||
|
dt_dprintf("fasttrap probe creation ioctl failed: %s\n",
|
||||||
|
strerror(errno));
|
||||||
|
return (dt_set_errno(dtp, errno));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return (ftp->ftps_noffs);
|
||||||
|
}
|
||||||
|
|
||||||
/*ARGSUSED*/
|
/*ARGSUSED*/
|
||||||
int
|
int
|
||||||
dt_pid_create_offset_probe(struct ps_prochandle *P, dtrace_hdl_t *dtp,
|
dt_pid_create_offset_probe(struct ps_prochandle *P, dtrace_hdl_t *dtp,
|
||||||
fasttrap_probe_spec_t *ftp, const GElf_Sym *symp, ulong_t off)
|
fasttrap_probe_spec_t *ftp, const GElf_Sym *symp, ulong_t off)
|
||||||
{
|
{
|
||||||
|
if (off & 0x3)
|
||||||
|
return (DT_PROC_ALIGN);
|
||||||
|
|
||||||
dt_dprintf("%s: unimplemented\n", __func__);
|
ftp->ftps_type = DTFTP_OFFSETS;
|
||||||
return (DT_PROC_ERR);
|
ftp->ftps_pc = (uintptr_t)symp->st_value;
|
||||||
|
ftp->ftps_size = (size_t)symp->st_size;
|
||||||
|
ftp->ftps_noffs = 1;
|
||||||
|
ftp->ftps_offs[0] = off;
|
||||||
|
|
||||||
|
if (ioctl(dtp->dt_ftfd, FASTTRAPIOC_MAKEPROBE, ftp) != 0) {
|
||||||
|
dt_dprintf("fasttrap probe creation ioctl failed: %s\n",
|
||||||
|
strerror(errno));
|
||||||
|
return (dt_set_errno(dtp, errno));
|
||||||
|
}
|
||||||
|
|
||||||
|
return (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*ARGSUSED*/
|
/*ARGSUSED*/
|
||||||
@ -69,7 +160,38 @@ int
|
|||||||
dt_pid_create_glob_offset_probes(struct ps_prochandle *P, dtrace_hdl_t *dtp,
|
dt_pid_create_glob_offset_probes(struct ps_prochandle *P, dtrace_hdl_t *dtp,
|
||||||
fasttrap_probe_spec_t *ftp, const GElf_Sym *symp, const char *pattern)
|
fasttrap_probe_spec_t *ftp, const GElf_Sym *symp, const char *pattern)
|
||||||
{
|
{
|
||||||
|
ulong_t i;
|
||||||
|
|
||||||
dt_dprintf("%s: unimplemented\n", __func__);
|
ftp->ftps_type = DTFTP_OFFSETS;
|
||||||
return (DT_PROC_ERR);
|
ftp->ftps_pc = (uintptr_t)symp->st_value;
|
||||||
|
ftp->ftps_size = (size_t)symp->st_size;
|
||||||
|
ftp->ftps_noffs = 0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If we're matching against everything, just iterate through each
|
||||||
|
* instruction in the function, otherwise look for matching offset
|
||||||
|
* names by constructing the string and comparing it against the
|
||||||
|
* pattern.
|
||||||
|
*/
|
||||||
|
if (strcmp("*", pattern) == 0) {
|
||||||
|
for (i = 0; i < symp->st_size; i += 4) {
|
||||||
|
ftp->ftps_offs[ftp->ftps_noffs++] = i;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
char name[sizeof (i) * 2 + 1];
|
||||||
|
|
||||||
|
for (i = 0; i < symp->st_size; i += 4) {
|
||||||
|
(void) sprintf(name, "%lx", i);
|
||||||
|
if (gmatch(name, pattern))
|
||||||
|
ftp->ftps_offs[ftp->ftps_noffs++] = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ioctl(dtp->dt_ftfd, FASTTRAPIOC_MAKEPROBE, ftp) != 0) {
|
||||||
|
dt_dprintf("fasttrap probe creation ioctl failed: %s\n",
|
||||||
|
strerror(errno));
|
||||||
|
return (dt_set_errno(dtp, errno));
|
||||||
|
}
|
||||||
|
|
||||||
|
return (ftp->ftps_noffs);
|
||||||
}
|
}
|
||||||
|
@ -210,7 +210,7 @@ NVLIST_PRTFUNC(int32, int32_t, int32_t, "%d")
|
|||||||
NVLIST_PRTFUNC(uint32, uint32_t, uint32_t, "0x%x")
|
NVLIST_PRTFUNC(uint32, uint32_t, uint32_t, "0x%x")
|
||||||
NVLIST_PRTFUNC(int64, int64_t, longlong_t, "%lld")
|
NVLIST_PRTFUNC(int64, int64_t, longlong_t, "%lld")
|
||||||
NVLIST_PRTFUNC(uint64, uint64_t, u_longlong_t, "0x%llx")
|
NVLIST_PRTFUNC(uint64, uint64_t, u_longlong_t, "0x%llx")
|
||||||
NVLIST_PRTFUNC(double, double, double, "0x%llf")
|
NVLIST_PRTFUNC(double, double, double, "0x%f")
|
||||||
NVLIST_PRTFUNC(string, char *, char *, "%s")
|
NVLIST_PRTFUNC(string, char *, char *, "%s")
|
||||||
NVLIST_PRTFUNC(hrtime, hrtime_t, hrtime_t, "0x%llx")
|
NVLIST_PRTFUNC(hrtime, hrtime_t, hrtime_t, "0x%llx")
|
||||||
|
|
||||||
|
@ -128,6 +128,7 @@ uu_avl_pool_destroy(uu_avl_pool_t *pp)
|
|||||||
pp->uap_next->uap_prev = pp->uap_prev;
|
pp->uap_next->uap_prev = pp->uap_prev;
|
||||||
pp->uap_prev->uap_next = pp->uap_next;
|
pp->uap_prev->uap_next = pp->uap_next;
|
||||||
(void) pthread_mutex_unlock(&uu_apool_list_lock);
|
(void) pthread_mutex_unlock(&uu_apool_list_lock);
|
||||||
|
(void) pthread_mutex_destroy(&pp->uap_lock);
|
||||||
pp->uap_prev = NULL;
|
pp->uap_prev = NULL;
|
||||||
pp->uap_next = NULL;
|
pp->uap_next = NULL;
|
||||||
uu_free(pp);
|
uu_free(pp);
|
||||||
|
@ -21,13 +21,13 @@
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||||
* Copyright 2011 Nexenta Systems, Inc. All rights reserved.
|
|
||||||
* Copyright (c) 2011 Pawel Jakub Dawidek <pawel@dawidek.net>.
|
* Copyright (c) 2011 Pawel Jakub Dawidek <pawel@dawidek.net>.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
* Copyright (c) 2012 by Delphix. All rights reserved.
|
* Copyright (c) 2013 by Delphix. All rights reserved.
|
||||||
* Copyright (c) 2012, Joyent, Inc. All rights reserved.
|
* Copyright (c) 2012, Joyent, Inc. All rights reserved.
|
||||||
* Copyright (c) 2012 Martin Matuska <mm@FreeBSD.org>. All rights reserved.
|
* Copyright (c) 2012 Martin Matuska <mm@FreeBSD.org>. All rights reserved.
|
||||||
* Copyright (c) 2013 Steven Hartland. All rights reserved.
|
* Copyright (c) 2013 Steven Hartland. All rights reserved.
|
||||||
|
* Copyright 2013 Nexenta Systems, Inc. All rights reserved.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _LIBZFS_H
|
#ifndef _LIBZFS_H
|
||||||
@ -193,6 +193,7 @@ extern int zpool_log_history(libzfs_handle_t *, const char *);
|
|||||||
extern int libzfs_errno(libzfs_handle_t *);
|
extern int libzfs_errno(libzfs_handle_t *);
|
||||||
extern const char *libzfs_error_action(libzfs_handle_t *);
|
extern const char *libzfs_error_action(libzfs_handle_t *);
|
||||||
extern const char *libzfs_error_description(libzfs_handle_t *);
|
extern const char *libzfs_error_description(libzfs_handle_t *);
|
||||||
|
extern int zfs_standard_error(libzfs_handle_t *, int, const char *);
|
||||||
extern void libzfs_mnttab_init(libzfs_handle_t *);
|
extern void libzfs_mnttab_init(libzfs_handle_t *);
|
||||||
extern void libzfs_mnttab_fini(libzfs_handle_t *);
|
extern void libzfs_mnttab_fini(libzfs_handle_t *);
|
||||||
extern void libzfs_mnttab_cache(libzfs_handle_t *, boolean_t);
|
extern void libzfs_mnttab_cache(libzfs_handle_t *, boolean_t);
|
||||||
@ -269,7 +270,7 @@ extern int zpool_label_disk(libzfs_handle_t *, zpool_handle_t *, const char *);
|
|||||||
*/
|
*/
|
||||||
extern int zpool_set_prop(zpool_handle_t *, const char *, const char *);
|
extern int zpool_set_prop(zpool_handle_t *, const char *, const char *);
|
||||||
extern int zpool_get_prop(zpool_handle_t *, zpool_prop_t, char *,
|
extern int zpool_get_prop(zpool_handle_t *, zpool_prop_t, char *,
|
||||||
size_t proplen, zprop_source_t *);
|
size_t proplen, zprop_source_t *, boolean_t);
|
||||||
extern uint64_t zpool_get_prop_int(zpool_handle_t *, zpool_prop_t,
|
extern uint64_t zpool_get_prop_int(zpool_handle_t *, zpool_prop_t,
|
||||||
zprop_source_t *);
|
zprop_source_t *);
|
||||||
|
|
||||||
@ -463,7 +464,8 @@ typedef struct zprop_list {
|
|||||||
boolean_t pl_fixed;
|
boolean_t pl_fixed;
|
||||||
} zprop_list_t;
|
} zprop_list_t;
|
||||||
|
|
||||||
extern int zfs_expand_proplist(zfs_handle_t *, zprop_list_t **, boolean_t);
|
extern int zfs_expand_proplist(zfs_handle_t *, zprop_list_t **, boolean_t,
|
||||||
|
boolean_t);
|
||||||
extern void zfs_prune_proplist(zfs_handle_t *, uint8_t *);
|
extern void zfs_prune_proplist(zfs_handle_t *, uint8_t *);
|
||||||
|
|
||||||
#define ZFS_MOUNTPOINT_NONE "none"
|
#define ZFS_MOUNTPOINT_NONE "none"
|
||||||
@ -536,6 +538,7 @@ extern int zfs_iter_filesystems(zfs_handle_t *, zfs_iter_f, void *);
|
|||||||
extern int zfs_iter_snapshots(zfs_handle_t *, boolean_t, zfs_iter_f, void *);
|
extern int zfs_iter_snapshots(zfs_handle_t *, boolean_t, zfs_iter_f, void *);
|
||||||
extern int zfs_iter_snapshots_sorted(zfs_handle_t *, zfs_iter_f, void *);
|
extern int zfs_iter_snapshots_sorted(zfs_handle_t *, zfs_iter_f, void *);
|
||||||
extern int zfs_iter_snapspec(zfs_handle_t *, const char *, zfs_iter_f, void *);
|
extern int zfs_iter_snapspec(zfs_handle_t *, const char *, zfs_iter_f, void *);
|
||||||
|
extern int zfs_iter_bookmarks(zfs_handle_t *, zfs_iter_f, void *);
|
||||||
|
|
||||||
typedef struct get_all_cb {
|
typedef struct get_all_cb {
|
||||||
zfs_handle_t **cb_handles;
|
zfs_handle_t **cb_handles;
|
||||||
@ -610,6 +613,7 @@ typedef boolean_t (snapfilter_cb_t)(zfs_handle_t *, void *);
|
|||||||
|
|
||||||
extern int zfs_send(zfs_handle_t *, const char *, const char *,
|
extern int zfs_send(zfs_handle_t *, const char *, const char *,
|
||||||
sendflags_t *, int, snapfilter_cb_t, void *, nvlist_t **);
|
sendflags_t *, int, snapfilter_cb_t, void *, nvlist_t **);
|
||||||
|
extern int zfs_send_one(zfs_handle_t *, const char *, int);
|
||||||
|
|
||||||
extern int zfs_promote(zfs_handle_t *);
|
extern int zfs_promote(zfs_handle_t *);
|
||||||
extern int zfs_hold(zfs_handle_t *, const char *, const char *,
|
extern int zfs_hold(zfs_handle_t *, const char *, const char *,
|
||||||
@ -679,6 +683,7 @@ 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 *,
|
extern boolean_t zfs_dataset_exists(libzfs_handle_t *, const char *,
|
||||||
zfs_type_t);
|
zfs_type_t);
|
||||||
extern int zfs_spa_version(zfs_handle_t *, int *);
|
extern int zfs_spa_version(zfs_handle_t *, int *);
|
||||||
|
extern boolean_t zfs_bookmark_exists(const char *path);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Mount support functions.
|
* Mount support functions.
|
||||||
|
@ -21,13 +21,14 @@
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||||
|
* Copyright (c) 2013, Joyent, Inc. All rights reserved.
|
||||||
* Copyright (c) 2013 by Delphix. All rights reserved.
|
* Copyright (c) 2013 by Delphix. All rights reserved.
|
||||||
* Copyright (c) 2012 DEY Storage Systems, Inc. All rights reserved.
|
* Copyright (c) 2012 DEY Storage Systems, Inc. All rights reserved.
|
||||||
* Copyright 2012 Nexenta Systems, Inc. All rights reserved.
|
|
||||||
* Copyright (c) 2011-2012 Pawel Jakub Dawidek <pawel@dawidek.net>.
|
* Copyright (c) 2011-2012 Pawel Jakub Dawidek <pawel@dawidek.net>.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
* Copyright (c) 2012 Martin Matuska <mm@FreeBSD.org>. All rights reserved.
|
* Copyright (c) 2012 Martin Matuska <mm@FreeBSD.org>. All rights reserved.
|
||||||
* Copyright (c) 2013 Steven Hartland. All rights reserved.
|
* Copyright (c) 2013 Steven Hartland. All rights reserved.
|
||||||
|
* Copyright 2013 Nexenta Systems, Inc. All rights reserved.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
@ -295,7 +296,7 @@ zpool_handle(zfs_handle_t *zhp)
|
|||||||
int len;
|
int len;
|
||||||
zpool_handle_t *zph;
|
zpool_handle_t *zph;
|
||||||
|
|
||||||
len = strcspn(zhp->zfs_name, "/@") + 1;
|
len = strcspn(zhp->zfs_name, "/@#") + 1;
|
||||||
pool_name = zfs_alloc(zhp->zfs_hdl, len);
|
pool_name = zfs_alloc(zhp->zfs_hdl, len);
|
||||||
(void) strlcpy(pool_name, zhp->zfs_name, len);
|
(void) strlcpy(pool_name, zhp->zfs_name, len);
|
||||||
|
|
||||||
@ -579,6 +580,70 @@ zfs_handle_dup(zfs_handle_t *zhp_orig)
|
|||||||
return (zhp);
|
return (zhp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
boolean_t
|
||||||
|
zfs_bookmark_exists(const char *path)
|
||||||
|
{
|
||||||
|
nvlist_t *bmarks;
|
||||||
|
nvlist_t *props;
|
||||||
|
char fsname[ZFS_MAXNAMELEN];
|
||||||
|
char *bmark_name;
|
||||||
|
char *pound;
|
||||||
|
int err;
|
||||||
|
boolean_t rv;
|
||||||
|
|
||||||
|
|
||||||
|
(void) strlcpy(fsname, path, sizeof (fsname));
|
||||||
|
pound = strchr(fsname, '#');
|
||||||
|
if (pound == NULL)
|
||||||
|
return (B_FALSE);
|
||||||
|
|
||||||
|
*pound = '\0';
|
||||||
|
bmark_name = pound + 1;
|
||||||
|
props = fnvlist_alloc();
|
||||||
|
err = lzc_get_bookmarks(fsname, props, &bmarks);
|
||||||
|
nvlist_free(props);
|
||||||
|
if (err != 0) {
|
||||||
|
nvlist_free(bmarks);
|
||||||
|
return (B_FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
rv = nvlist_exists(bmarks, bmark_name);
|
||||||
|
nvlist_free(bmarks);
|
||||||
|
return (rv);
|
||||||
|
}
|
||||||
|
|
||||||
|
zfs_handle_t *
|
||||||
|
make_bookmark_handle(zfs_handle_t *parent, const char *path,
|
||||||
|
nvlist_t *bmark_props)
|
||||||
|
{
|
||||||
|
zfs_handle_t *zhp = calloc(sizeof (zfs_handle_t), 1);
|
||||||
|
|
||||||
|
if (zhp == NULL)
|
||||||
|
return (NULL);
|
||||||
|
|
||||||
|
/* Fill in the name. */
|
||||||
|
zhp->zfs_hdl = parent->zfs_hdl;
|
||||||
|
(void) strlcpy(zhp->zfs_name, path, sizeof (zhp->zfs_name));
|
||||||
|
|
||||||
|
/* Set the property lists. */
|
||||||
|
if (nvlist_dup(bmark_props, &zhp->zfs_props, 0) != 0) {
|
||||||
|
free(zhp);
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set the types. */
|
||||||
|
zhp->zfs_head_type = parent->zfs_head_type;
|
||||||
|
zhp->zfs_type = ZFS_TYPE_BOOKMARK;
|
||||||
|
|
||||||
|
if ((zhp->zpool_hdl = zpool_handle(zhp)) == NULL) {
|
||||||
|
nvlist_free(zhp->zfs_props);
|
||||||
|
free(zhp);
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (zhp);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Opens the given snapshot, filesystem, or volume. The 'types'
|
* Opens the given snapshot, filesystem, or volume. The 'types'
|
||||||
* argument is a mask of acceptable types. The function will print an
|
* argument is a mask of acceptable types. The function will print an
|
||||||
@ -1846,6 +1911,10 @@ get_numeric_property(zfs_handle_t *zhp, zfs_prop_t prop, zprop_source_t *src,
|
|||||||
case ZFS_PROP_REFQUOTA:
|
case ZFS_PROP_REFQUOTA:
|
||||||
case ZFS_PROP_RESERVATION:
|
case ZFS_PROP_RESERVATION:
|
||||||
case ZFS_PROP_REFRESERVATION:
|
case ZFS_PROP_REFRESERVATION:
|
||||||
|
case ZFS_PROP_FILESYSTEM_LIMIT:
|
||||||
|
case ZFS_PROP_SNAPSHOT_LIMIT:
|
||||||
|
case ZFS_PROP_FILESYSTEM_COUNT:
|
||||||
|
case ZFS_PROP_SNAPSHOT_COUNT:
|
||||||
*val = getprop_uint64(zhp, prop, source);
|
*val = getprop_uint64(zhp, prop, source);
|
||||||
|
|
||||||
if (*source == NULL) {
|
if (*source == NULL) {
|
||||||
@ -2173,8 +2242,8 @@ zfs_prop_get(zfs_handle_t *zhp, zfs_prop_t prop, char *propbuf, size_t proplen,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ((zpool_get_prop(zhp->zpool_hdl,
|
if ((zpool_get_prop(zhp->zpool_hdl,
|
||||||
ZPOOL_PROP_ALTROOT, buf, MAXPATHLEN, NULL)) ||
|
ZPOOL_PROP_ALTROOT, buf, MAXPATHLEN, NULL,
|
||||||
(strcmp(root, "-") == 0))
|
B_FALSE)) || (strcmp(root, "-") == 0))
|
||||||
root[0] = '\0';
|
root[0] = '\0';
|
||||||
/*
|
/*
|
||||||
* Special case an alternate root of '/'. This will
|
* Special case an alternate root of '/'. This will
|
||||||
@ -2251,6 +2320,30 @@ zfs_prop_get(zfs_handle_t *zhp, zfs_prop_t prop, char *propbuf, size_t proplen,
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case ZFS_PROP_FILESYSTEM_LIMIT:
|
||||||
|
case ZFS_PROP_SNAPSHOT_LIMIT:
|
||||||
|
case ZFS_PROP_FILESYSTEM_COUNT:
|
||||||
|
case ZFS_PROP_SNAPSHOT_COUNT:
|
||||||
|
|
||||||
|
if (get_numeric_property(zhp, prop, src, &source, &val) != 0)
|
||||||
|
return (-1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If limit is UINT64_MAX, we translate this into 'none' (unless
|
||||||
|
* literal is set), and indicate that it's the default value.
|
||||||
|
* Otherwise, we print the number nicely and indicate that it's
|
||||||
|
* set locally.
|
||||||
|
*/
|
||||||
|
if (literal) {
|
||||||
|
(void) snprintf(propbuf, proplen, "%llu",
|
||||||
|
(u_longlong_t)val);
|
||||||
|
} else if (val == UINT64_MAX) {
|
||||||
|
(void) strlcpy(propbuf, "none", proplen);
|
||||||
|
} else {
|
||||||
|
zfs_nicenum(val, propbuf, proplen);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case ZFS_PROP_REFRATIO:
|
case ZFS_PROP_REFRATIO:
|
||||||
case ZFS_PROP_COMPRESSRATIO:
|
case ZFS_PROP_COMPRESSRATIO:
|
||||||
if (get_numeric_property(zhp, prop, src, &source, &val) != 0)
|
if (get_numeric_property(zhp, prop, src, &source, &val) != 0)
|
||||||
@ -2271,6 +2364,9 @@ zfs_prop_get(zfs_handle_t *zhp, zfs_prop_t prop, char *propbuf, size_t proplen,
|
|||||||
case ZFS_TYPE_SNAPSHOT:
|
case ZFS_TYPE_SNAPSHOT:
|
||||||
str = "snapshot";
|
str = "snapshot";
|
||||||
break;
|
break;
|
||||||
|
case ZFS_TYPE_BOOKMARK:
|
||||||
|
str = "bookmark";
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
@ -2477,6 +2573,7 @@ idmap_id_to_numeric_domain_rid(uid_t id, boolean_t isuser,
|
|||||||
return (err);
|
return (err);
|
||||||
#else /* !sun */
|
#else /* !sun */
|
||||||
assert(!"invalid code path");
|
assert(!"invalid code path");
|
||||||
|
return (EINVAL); // silence compiler warning
|
||||||
#endif /* !sun */
|
#endif /* !sun */
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3133,6 +3230,19 @@ zfs_destroy(zfs_handle_t *zhp, boolean_t defer)
|
|||||||
{
|
{
|
||||||
zfs_cmd_t zc = { 0 };
|
zfs_cmd_t zc = { 0 };
|
||||||
|
|
||||||
|
if (zhp->zfs_type == ZFS_TYPE_BOOKMARK) {
|
||||||
|
nvlist_t *nv = fnvlist_alloc();
|
||||||
|
fnvlist_add_boolean(nv, zhp->zfs_name);
|
||||||
|
int error = lzc_destroy_bookmarks(nv, NULL);
|
||||||
|
fnvlist_free(nv);
|
||||||
|
if (error != 0) {
|
||||||
|
return (zfs_standard_error_fmt(zhp->zfs_hdl, errno,
|
||||||
|
dgettext(TEXT_DOMAIN, "cannot destroy '%s'"),
|
||||||
|
zhp->zfs_name));
|
||||||
|
}
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
(void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
|
(void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
|
||||||
|
|
||||||
if (ZFS_IS_VOLUME(zhp)) {
|
if (ZFS_IS_VOLUME(zhp)) {
|
||||||
@ -3515,32 +3625,16 @@ typedef struct rollback_data {
|
|||||||
const char *cb_target; /* the snapshot */
|
const char *cb_target; /* the snapshot */
|
||||||
uint64_t cb_create; /* creation time reference */
|
uint64_t cb_create; /* creation time reference */
|
||||||
boolean_t cb_error;
|
boolean_t cb_error;
|
||||||
boolean_t cb_dependent;
|
|
||||||
boolean_t cb_force;
|
boolean_t cb_force;
|
||||||
} rollback_data_t;
|
} rollback_data_t;
|
||||||
|
|
||||||
static int
|
static int
|
||||||
rollback_destroy(zfs_handle_t *zhp, void *data)
|
rollback_destroy_dependent(zfs_handle_t *zhp, void *data)
|
||||||
{
|
{
|
||||||
rollback_data_t *cbp = data;
|
rollback_data_t *cbp = data;
|
||||||
|
|
||||||
if (!cbp->cb_dependent) {
|
|
||||||
if (strcmp(zhp->zfs_name, cbp->cb_target) != 0 &&
|
|
||||||
zfs_get_type(zhp) == ZFS_TYPE_SNAPSHOT &&
|
|
||||||
zfs_prop_get_int(zhp, ZFS_PROP_CREATETXG) >
|
|
||||||
cbp->cb_create) {
|
|
||||||
|
|
||||||
cbp->cb_dependent = B_TRUE;
|
|
||||||
cbp->cb_error |= zfs_iter_dependents(zhp, B_FALSE,
|
|
||||||
rollback_destroy, cbp);
|
|
||||||
cbp->cb_dependent = B_FALSE;
|
|
||||||
|
|
||||||
cbp->cb_error |= zfs_destroy(zhp, B_FALSE);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
/* We must destroy this clone; first unmount it */
|
|
||||||
prop_changelist_t *clp;
|
prop_changelist_t *clp;
|
||||||
|
|
||||||
|
/* We must destroy this clone; first unmount it */
|
||||||
clp = changelist_gather(zhp, ZFS_PROP_NAME, 0,
|
clp = changelist_gather(zhp, ZFS_PROP_NAME, 0,
|
||||||
cbp->cb_force ? MS_FORCE: 0);
|
cbp->cb_force ? MS_FORCE: 0);
|
||||||
if (clp == NULL || changelist_prefix(clp) != 0) {
|
if (clp == NULL || changelist_prefix(clp) != 0) {
|
||||||
@ -3554,6 +3648,21 @@ rollback_destroy(zfs_handle_t *zhp, void *data)
|
|||||||
changelist_remove(clp, zhp->zfs_name);
|
changelist_remove(clp, zhp->zfs_name);
|
||||||
(void) changelist_postfix(clp);
|
(void) changelist_postfix(clp);
|
||||||
changelist_free(clp);
|
changelist_free(clp);
|
||||||
|
|
||||||
|
zfs_close(zhp);
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
rollback_destroy(zfs_handle_t *zhp, void *data)
|
||||||
|
{
|
||||||
|
rollback_data_t *cbp = data;
|
||||||
|
|
||||||
|
if (zfs_prop_get_int(zhp, ZFS_PROP_CREATETXG) > cbp->cb_create) {
|
||||||
|
cbp->cb_error |= zfs_iter_dependents(zhp, B_FALSE,
|
||||||
|
rollback_destroy_dependent, cbp);
|
||||||
|
|
||||||
|
cbp->cb_error |= zfs_destroy(zhp, B_FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
zfs_close(zhp);
|
zfs_close(zhp);
|
||||||
@ -3564,8 +3673,8 @@ rollback_destroy(zfs_handle_t *zhp, void *data)
|
|||||||
* Given a dataset, rollback to a specific snapshot, discarding any
|
* Given a dataset, rollback to a specific snapshot, discarding any
|
||||||
* data changes since then and making it the active dataset.
|
* data changes since then and making it the active dataset.
|
||||||
*
|
*
|
||||||
* Any snapshots more recent than the target are destroyed, along with
|
* Any snapshots and bookmarks more recent than the target are
|
||||||
* their dependents.
|
* destroyed, along with their dependents (i.e. clones).
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
zfs_rollback(zfs_handle_t *zhp, zfs_handle_t *snap, boolean_t force)
|
zfs_rollback(zfs_handle_t *zhp, zfs_handle_t *snap, boolean_t force)
|
||||||
@ -3585,7 +3694,8 @@ zfs_rollback(zfs_handle_t *zhp, zfs_handle_t *snap, boolean_t force)
|
|||||||
cb.cb_force = force;
|
cb.cb_force = force;
|
||||||
cb.cb_target = snap->zfs_name;
|
cb.cb_target = snap->zfs_name;
|
||||||
cb.cb_create = zfs_prop_get_int(snap, ZFS_PROP_CREATETXG);
|
cb.cb_create = zfs_prop_get_int(snap, ZFS_PROP_CREATETXG);
|
||||||
(void) zfs_iter_children(zhp, rollback_destroy, &cb);
|
(void) zfs_iter_snapshots(zhp, B_FALSE, rollback_destroy, &cb);
|
||||||
|
(void) zfs_iter_bookmarks(zhp, rollback_destroy, &cb);
|
||||||
|
|
||||||
if (cb.cb_error)
|
if (cb.cb_error)
|
||||||
return (-1);
|
return (-1);
|
||||||
@ -3882,7 +3992,8 @@ zfs_get_recvd_props(zfs_handle_t *zhp)
|
|||||||
* of the RECEIVED column.
|
* of the RECEIVED column.
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
zfs_expand_proplist(zfs_handle_t *zhp, zprop_list_t **plp, boolean_t received)
|
zfs_expand_proplist(zfs_handle_t *zhp, zprop_list_t **plp, boolean_t received,
|
||||||
|
boolean_t literal)
|
||||||
{
|
{
|
||||||
libzfs_handle_t *hdl = zhp->zfs_hdl;
|
libzfs_handle_t *hdl = zhp->zfs_hdl;
|
||||||
zprop_list_t *entry;
|
zprop_list_t *entry;
|
||||||
@ -3944,18 +4055,18 @@ zfs_expand_proplist(zfs_handle_t *zhp, zprop_list_t **plp, boolean_t received)
|
|||||||
* Now go through and check the width of any non-fixed columns
|
* Now go through and check the width of any non-fixed columns
|
||||||
*/
|
*/
|
||||||
for (entry = *plp; entry != NULL; entry = entry->pl_next) {
|
for (entry = *plp; entry != NULL; entry = entry->pl_next) {
|
||||||
if (entry->pl_fixed)
|
if (entry->pl_fixed && !literal)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (entry->pl_prop != ZPROP_INVAL) {
|
if (entry->pl_prop != ZPROP_INVAL) {
|
||||||
if (zfs_prop_get(zhp, entry->pl_prop,
|
if (zfs_prop_get(zhp, entry->pl_prop,
|
||||||
buf, sizeof (buf), NULL, NULL, 0, B_FALSE) == 0) {
|
buf, sizeof (buf), NULL, NULL, 0, literal) == 0) {
|
||||||
if (strlen(buf) > entry->pl_width)
|
if (strlen(buf) > entry->pl_width)
|
||||||
entry->pl_width = strlen(buf);
|
entry->pl_width = strlen(buf);
|
||||||
}
|
}
|
||||||
if (received && zfs_prop_get_recvd(zhp,
|
if (received && zfs_prop_get_recvd(zhp,
|
||||||
zfs_prop_to_name(entry->pl_prop),
|
zfs_prop_to_name(entry->pl_prop),
|
||||||
buf, sizeof (buf), B_FALSE) == 0)
|
buf, sizeof (buf), literal) == 0)
|
||||||
if (strlen(buf) > entry->pl_recvd_width)
|
if (strlen(buf) > entry->pl_recvd_width)
|
||||||
entry->pl_recvd_width = strlen(buf);
|
entry->pl_recvd_width = strlen(buf);
|
||||||
} else {
|
} else {
|
||||||
@ -3968,7 +4079,7 @@ zfs_expand_proplist(zfs_handle_t *zhp, zprop_list_t **plp, boolean_t received)
|
|||||||
}
|
}
|
||||||
if (received && zfs_prop_get_recvd(zhp,
|
if (received && zfs_prop_get_recvd(zhp,
|
||||||
entry->pl_user_prop,
|
entry->pl_user_prop,
|
||||||
buf, sizeof (buf), B_FALSE) == 0)
|
buf, sizeof (buf), literal) == 0)
|
||||||
if (strlen(buf) > entry->pl_recvd_width)
|
if (strlen(buf) > entry->pl_recvd_width)
|
||||||
entry->pl_recvd_width = strlen(buf);
|
entry->pl_recvd_width = strlen(buf);
|
||||||
}
|
}
|
||||||
|
@ -23,7 +23,7 @@
|
|||||||
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||||
* Copyright (c) 2011 Pawel Jakub Dawidek <pawel@dawidek.net>.
|
* Copyright (c) 2011 Pawel Jakub Dawidek <pawel@dawidek.net>.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
* Copyright (c) 2012 by Delphix. All rights reserved.
|
* Copyright (c) 2013 by Delphix. All rights reserved.
|
||||||
* Copyright (c) 2013 Martin Matuska <mm@FreeBSD.org>. All rights reserved.
|
* Copyright (c) 2013 Martin Matuska <mm@FreeBSD.org>. All rights reserved.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -191,6 +191,8 @@ int create_parents(libzfs_handle_t *, char *, int);
|
|||||||
boolean_t isa_child_of(const char *dataset, const char *parent);
|
boolean_t isa_child_of(const char *dataset, const char *parent);
|
||||||
|
|
||||||
zfs_handle_t *make_dataset_handle(libzfs_handle_t *, const char *);
|
zfs_handle_t *make_dataset_handle(libzfs_handle_t *, const char *);
|
||||||
|
zfs_handle_t *make_bookmark_handle(zfs_handle_t *, const char *,
|
||||||
|
nvlist_t *props);
|
||||||
|
|
||||||
int zpool_open_silent(libzfs_handle_t *, const char *, zpool_handle_t **);
|
int zpool_open_silent(libzfs_handle_t *, const char *, zpool_handle_t **);
|
||||||
|
|
||||||
|
@ -20,8 +20,8 @@
|
|||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||||
* Copyright 2011 Nexenta Systems, Inc. All rights reserved.
|
|
||||||
* Copyright (c) 2012 by Delphix. All rights reserved.
|
* Copyright (c) 2012 by Delphix. All rights reserved.
|
||||||
|
* Copyright 2014 Nexenta Systems, Inc. All rights reserved.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -995,10 +995,10 @@ nozpool_all_slices(avl_tree_t *r, const char *sname)
|
|||||||
#endif /* sun */
|
#endif /* sun */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef sun
|
||||||
static void
|
static void
|
||||||
check_slices(avl_tree_t *r, int fd, const char *sname)
|
check_slices(avl_tree_t *r, int fd, const char *sname)
|
||||||
{
|
{
|
||||||
#ifdef sun
|
|
||||||
struct extvtoc vtoc;
|
struct extvtoc vtoc;
|
||||||
struct dk_gpt *gpt;
|
struct dk_gpt *gpt;
|
||||||
char diskname[MAXNAMELEN];
|
char diskname[MAXNAMELEN];
|
||||||
@ -1028,8 +1028,8 @@ check_slices(avl_tree_t *r, int fd, const char *sname)
|
|||||||
check_one_slice(r, diskname, i, 0, 1);
|
check_one_slice(r, diskname, i, 0, 1);
|
||||||
efi_free(gpt);
|
efi_free(gpt);
|
||||||
}
|
}
|
||||||
#endif /* sun */
|
|
||||||
}
|
}
|
||||||
|
#endif /* sun */
|
||||||
|
|
||||||
static void
|
static void
|
||||||
zpool_open_func(void *arg)
|
zpool_open_func(void *arg)
|
||||||
@ -1059,6 +1059,7 @@ zpool_open_func(void *arg)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
/* this file is too small to hold a zpool */
|
/* this file is too small to hold a zpool */
|
||||||
|
#ifdef sun
|
||||||
if (S_ISREG(statbuf.st_mode) &&
|
if (S_ISREG(statbuf.st_mode) &&
|
||||||
statbuf.st_size < SPA_MINDEVSIZE) {
|
statbuf.st_size < SPA_MINDEVSIZE) {
|
||||||
(void) close(fd);
|
(void) close(fd);
|
||||||
@ -1070,6 +1071,12 @@ zpool_open_func(void *arg)
|
|||||||
*/
|
*/
|
||||||
check_slices(rn->rn_avl, fd, rn->rn_name);
|
check_slices(rn->rn_avl, fd, rn->rn_name);
|
||||||
}
|
}
|
||||||
|
#else /* !sun */
|
||||||
|
if (statbuf.st_size < SPA_MINDEVSIZE) {
|
||||||
|
(void) close(fd);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif /* sun */
|
||||||
|
|
||||||
if ((zpool_read_label(fd, &config)) != 0) {
|
if ((zpool_read_label(fd, &config)) != 0) {
|
||||||
(void) close(fd);
|
(void) close(fd);
|
||||||
@ -1606,10 +1613,17 @@ zpool_in_use(libzfs_handle_t *hdl, int fd, pool_state_t *state, char **namestr,
|
|||||||
* its state to active.
|
* its state to active.
|
||||||
*/
|
*/
|
||||||
if (pool_active(hdl, name, guid, &isactive) == 0 && isactive &&
|
if (pool_active(hdl, name, guid, &isactive) == 0 && isactive &&
|
||||||
(zhp = zpool_open_canfail(hdl, name)) != NULL &&
|
(zhp = zpool_open_canfail(hdl, name)) != NULL) {
|
||||||
zpool_get_prop_int(zhp, ZPOOL_PROP_READONLY, NULL))
|
if (zpool_get_prop_int(zhp, ZPOOL_PROP_READONLY, NULL))
|
||||||
stateval = POOL_STATE_ACTIVE;
|
stateval = POOL_STATE_ACTIVE;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* All we needed the zpool handle for is the
|
||||||
|
* readonly prop check.
|
||||||
|
*/
|
||||||
|
zpool_close(zhp);
|
||||||
|
}
|
||||||
|
|
||||||
ret = B_TRUE;
|
ret = B_TRUE;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -21,7 +21,7 @@
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||||
* Copyright (c) 2012 by Delphix. All rights reserved.
|
* Copyright (c) 2013 by Delphix. All rights reserved.
|
||||||
* Copyright (c) 2012 Pawel Jakub Dawidek <pawel@dawidek.net>.
|
* Copyright (c) 2012 Pawel Jakub Dawidek <pawel@dawidek.net>.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
* Copyright 2013 Nexenta Systems, Inc. All rights reserved.
|
* Copyright 2013 Nexenta Systems, Inc. All rights reserved.
|
||||||
@ -146,7 +146,8 @@ zfs_iter_snapshots(zfs_handle_t *zhp, boolean_t simple, zfs_iter_f func,
|
|||||||
zfs_handle_t *nzhp;
|
zfs_handle_t *nzhp;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (zhp->zfs_type == ZFS_TYPE_SNAPSHOT)
|
if (zhp->zfs_type == ZFS_TYPE_SNAPSHOT ||
|
||||||
|
zhp->zfs_type == ZFS_TYPE_BOOKMARK)
|
||||||
return (0);
|
return (0);
|
||||||
|
|
||||||
zc.zc_simple = simple;
|
zc.zc_simple = simple;
|
||||||
@ -172,6 +173,59 @@ zfs_iter_snapshots(zfs_handle_t *zhp, boolean_t simple, zfs_iter_f func,
|
|||||||
return ((ret < 0) ? ret : 0);
|
return ((ret < 0) ? ret : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Iterate over all bookmarks
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
zfs_iter_bookmarks(zfs_handle_t *zhp, zfs_iter_f func, void *data)
|
||||||
|
{
|
||||||
|
zfs_handle_t *nzhp;
|
||||||
|
nvlist_t *props = NULL;
|
||||||
|
nvlist_t *bmarks = NULL;
|
||||||
|
int err;
|
||||||
|
|
||||||
|
if ((zfs_get_type(zhp) & (ZFS_TYPE_SNAPSHOT | ZFS_TYPE_BOOKMARK)) != 0)
|
||||||
|
return (0);
|
||||||
|
|
||||||
|
/* Setup the requested properties nvlist. */
|
||||||
|
props = fnvlist_alloc();
|
||||||
|
fnvlist_add_boolean(props, zfs_prop_to_name(ZFS_PROP_GUID));
|
||||||
|
fnvlist_add_boolean(props, zfs_prop_to_name(ZFS_PROP_CREATETXG));
|
||||||
|
fnvlist_add_boolean(props, zfs_prop_to_name(ZFS_PROP_CREATION));
|
||||||
|
|
||||||
|
/* Allocate an nvlist to hold the bookmarks. */
|
||||||
|
bmarks = fnvlist_alloc();
|
||||||
|
|
||||||
|
if ((err = lzc_get_bookmarks(zhp->zfs_name, props, &bmarks)) != 0)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
for (nvpair_t *pair = nvlist_next_nvpair(bmarks, NULL);
|
||||||
|
pair != NULL; pair = nvlist_next_nvpair(bmarks, pair)) {
|
||||||
|
char name[ZFS_MAXNAMELEN];
|
||||||
|
char *bmark_name;
|
||||||
|
nvlist_t *bmark_props;
|
||||||
|
|
||||||
|
bmark_name = nvpair_name(pair);
|
||||||
|
bmark_props = fnvpair_value_nvlist(pair);
|
||||||
|
|
||||||
|
(void) snprintf(name, sizeof (name), "%s#%s", zhp->zfs_name,
|
||||||
|
bmark_name);
|
||||||
|
|
||||||
|
nzhp = make_bookmark_handle(zhp, name, bmark_props);
|
||||||
|
if (nzhp == NULL)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if ((err = func(nzhp, data)) != 0)
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
out:
|
||||||
|
fnvlist_free(props);
|
||||||
|
fnvlist_free(bmarks);
|
||||||
|
|
||||||
|
return (err);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Routines for dealing with the sorted snapshot functionality
|
* Routines for dealing with the sorted snapshot functionality
|
||||||
*/
|
*/
|
||||||
@ -406,13 +460,13 @@ static int
|
|||||||
iter_dependents_cb(zfs_handle_t *zhp, void *arg)
|
iter_dependents_cb(zfs_handle_t *zhp, void *arg)
|
||||||
{
|
{
|
||||||
iter_dependents_arg_t *ida = arg;
|
iter_dependents_arg_t *ida = arg;
|
||||||
int err;
|
int err = 0;
|
||||||
boolean_t first = ida->first;
|
boolean_t first = ida->first;
|
||||||
ida->first = B_FALSE;
|
ida->first = B_FALSE;
|
||||||
|
|
||||||
if (zhp->zfs_type == ZFS_TYPE_SNAPSHOT) {
|
if (zhp->zfs_type == ZFS_TYPE_SNAPSHOT) {
|
||||||
err = zfs_iter_clones(zhp, iter_dependents_cb, ida);
|
err = zfs_iter_clones(zhp, iter_dependents_cb, ida);
|
||||||
} else {
|
} else if (zhp->zfs_type != ZFS_TYPE_BOOKMARK) {
|
||||||
iter_stack_frame_t isf;
|
iter_stack_frame_t isf;
|
||||||
iter_stack_frame_t *f;
|
iter_stack_frame_t *f;
|
||||||
|
|
||||||
|
@ -22,7 +22,7 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||||
* Copyright 2011 Nexenta Systems, Inc. All rights reserved.
|
* Copyright 2011 Nexenta Systems, Inc. All rights reserved.
|
||||||
* Copyright (c) 2012 by Delphix. All rights reserved.
|
* Copyright (c) 2013 by Delphix. All rights reserved.
|
||||||
* Copyright (c) 2013, Joyent, Inc. All rights reserved.
|
* Copyright (c) 2013, Joyent, Inc. All rights reserved.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -240,7 +240,7 @@ zpool_pool_state_to_name(pool_state_t state)
|
|||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
zpool_get_prop(zpool_handle_t *zhp, zpool_prop_t prop, char *buf, size_t len,
|
zpool_get_prop(zpool_handle_t *zhp, zpool_prop_t prop, char *buf, size_t len,
|
||||||
zprop_source_t *srctype)
|
zprop_source_t *srctype, boolean_t literal)
|
||||||
{
|
{
|
||||||
uint64_t intval;
|
uint64_t intval;
|
||||||
const char *strval;
|
const char *strval;
|
||||||
@ -272,9 +272,7 @@ zpool_get_prop(zpool_handle_t *zhp, zpool_prop_t prop, char *buf, size_t len,
|
|||||||
(void) strlcpy(buf,
|
(void) strlcpy(buf,
|
||||||
zpool_get_prop_string(zhp, prop, &src),
|
zpool_get_prop_string(zhp, prop, &src),
|
||||||
len);
|
len);
|
||||||
if (srctype != NULL)
|
break;
|
||||||
*srctype = src;
|
|
||||||
return (0);
|
|
||||||
}
|
}
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
default:
|
default:
|
||||||
@ -306,12 +304,22 @@ zpool_get_prop(zpool_handle_t *zhp, zpool_prop_t prop, char *buf, size_t len,
|
|||||||
case ZPOOL_PROP_FREE:
|
case ZPOOL_PROP_FREE:
|
||||||
case ZPOOL_PROP_FREEING:
|
case ZPOOL_PROP_FREEING:
|
||||||
case ZPOOL_PROP_EXPANDSZ:
|
case ZPOOL_PROP_EXPANDSZ:
|
||||||
|
if (literal) {
|
||||||
|
(void) snprintf(buf, len, "%llu",
|
||||||
|
(u_longlong_t)intval);
|
||||||
|
} else {
|
||||||
(void) zfs_nicenum(intval, buf, len);
|
(void) zfs_nicenum(intval, buf, len);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ZPOOL_PROP_CAPACITY:
|
case ZPOOL_PROP_CAPACITY:
|
||||||
|
if (literal) {
|
||||||
|
(void) snprintf(buf, len, "%llu",
|
||||||
|
(u_longlong_t)intval);
|
||||||
|
} else {
|
||||||
(void) snprintf(buf, len, "%llu%%",
|
(void) snprintf(buf, len, "%llu%%",
|
||||||
(u_longlong_t)intval);
|
(u_longlong_t)intval);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ZPOOL_PROP_DEDUPRATIO:
|
case ZPOOL_PROP_DEDUPRATIO:
|
||||||
@ -407,7 +415,7 @@ zpool_is_bootable(zpool_handle_t *zhp)
|
|||||||
char bootfs[ZPOOL_MAXNAMELEN];
|
char bootfs[ZPOOL_MAXNAMELEN];
|
||||||
|
|
||||||
return (zpool_get_prop(zhp, ZPOOL_PROP_BOOTFS, bootfs,
|
return (zpool_get_prop(zhp, ZPOOL_PROP_BOOTFS, bootfs,
|
||||||
sizeof (bootfs), NULL) == 0 && strncmp(bootfs, "-",
|
sizeof (bootfs), NULL, B_FALSE) == 0 && strncmp(bootfs, "-",
|
||||||
sizeof (bootfs)) != 0);
|
sizeof (bootfs)) != 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -443,10 +451,9 @@ zpool_valid_proplist(libzfs_handle_t *hdl, const char *poolname,
|
|||||||
prop = zpool_name_to_prop(propname);
|
prop = zpool_name_to_prop(propname);
|
||||||
if (prop == ZPROP_INVAL && zpool_prop_feature(propname)) {
|
if (prop == ZPROP_INVAL && zpool_prop_feature(propname)) {
|
||||||
int err;
|
int err;
|
||||||
zfeature_info_t *feature;
|
|
||||||
char *fname = strchr(propname, '@') + 1;
|
char *fname = strchr(propname, '@') + 1;
|
||||||
|
|
||||||
err = zfeature_lookup_name(fname, &feature);
|
err = zfeature_lookup_name(fname, NULL);
|
||||||
if (err != 0) {
|
if (err != 0) {
|
||||||
ASSERT3U(err, ==, ENOENT);
|
ASSERT3U(err, ==, ENOENT);
|
||||||
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
|
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
|
||||||
@ -807,7 +814,7 @@ zpool_expand_proplist(zpool_handle_t *zhp, zprop_list_t **plp)
|
|||||||
|
|
||||||
if (entry->pl_prop != ZPROP_INVAL &&
|
if (entry->pl_prop != ZPROP_INVAL &&
|
||||||
zpool_get_prop(zhp, entry->pl_prop, buf, sizeof (buf),
|
zpool_get_prop(zhp, entry->pl_prop, buf, sizeof (buf),
|
||||||
NULL) == 0) {
|
NULL, B_FALSE) == 0) {
|
||||||
if (strlen(buf) > entry->pl_width)
|
if (strlen(buf) > entry->pl_width)
|
||||||
entry->pl_width = strlen(buf);
|
entry->pl_width = strlen(buf);
|
||||||
}
|
}
|
||||||
@ -839,14 +846,14 @@ zpool_prop_get_feature(zpool_handle_t *zhp, const char *propname, char *buf,
|
|||||||
*/
|
*/
|
||||||
if (supported) {
|
if (supported) {
|
||||||
int ret;
|
int ret;
|
||||||
zfeature_info_t *fi;
|
spa_feature_t fid;
|
||||||
|
|
||||||
ret = zfeature_lookup_name(feature, &fi);
|
ret = zfeature_lookup_name(feature, &fid);
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
(void) strlcpy(buf, "-", len);
|
(void) strlcpy(buf, "-", len);
|
||||||
return (ENOTSUP);
|
return (ENOTSUP);
|
||||||
}
|
}
|
||||||
feature = fi->fi_guid;
|
feature = spa_feature_table[fid].fi_guid;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nvlist_lookup_uint64(features, feature, &refcount) == 0)
|
if (nvlist_lookup_uint64(features, feature, &refcount) == 0)
|
||||||
@ -3737,7 +3744,9 @@ zpool_history_unpack(char *buf, uint64_t bytes_read, uint64_t *leftover,
|
|||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define HIS_BUF_LEN (128*1024)
|
/* from spa_history.c: spa_history_create_obj() */
|
||||||
|
#define HIS_BUF_LEN_DEF (128 << 10)
|
||||||
|
#define HIS_BUF_LEN_MAX (1 << 30)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Retrieve the command history of a pool.
|
* Retrieve the command history of a pool.
|
||||||
@ -3745,21 +3754,24 @@ zpool_history_unpack(char *buf, uint64_t bytes_read, uint64_t *leftover,
|
|||||||
int
|
int
|
||||||
zpool_get_history(zpool_handle_t *zhp, nvlist_t **nvhisp)
|
zpool_get_history(zpool_handle_t *zhp, nvlist_t **nvhisp)
|
||||||
{
|
{
|
||||||
char buf[HIS_BUF_LEN];
|
char *buf = NULL;
|
||||||
|
uint64_t bufsize = HIS_BUF_LEN_DEF;
|
||||||
uint64_t off = 0;
|
uint64_t off = 0;
|
||||||
nvlist_t **records = NULL;
|
nvlist_t **records = NULL;
|
||||||
uint_t numrecords = 0;
|
uint_t numrecords = 0;
|
||||||
int err, i;
|
int err, i;
|
||||||
|
|
||||||
|
if ((buf = malloc(bufsize)) == NULL)
|
||||||
|
return (ENOMEM);
|
||||||
do {
|
do {
|
||||||
uint64_t bytes_read = sizeof (buf);
|
uint64_t bytes_read = bufsize;
|
||||||
uint64_t leftover;
|
uint64_t leftover;
|
||||||
|
|
||||||
if ((err = get_history(zhp, buf, &off, &bytes_read)) != 0)
|
if ((err = get_history(zhp, buf, &off, &bytes_read)) != 0)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* if nothing else was read in, we're at EOF, just return */
|
/* if nothing else was read in, we're at EOF, just return */
|
||||||
if (!bytes_read)
|
if (bytes_read == 0)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if ((err = zpool_history_unpack(buf, bytes_read,
|
if ((err = zpool_history_unpack(buf, bytes_read,
|
||||||
@ -3767,8 +3779,25 @@ zpool_get_history(zpool_handle_t *zhp, nvlist_t **nvhisp)
|
|||||||
break;
|
break;
|
||||||
off -= leftover;
|
off -= leftover;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If the history block is too big, double the buffer
|
||||||
|
* size and try again.
|
||||||
|
*/
|
||||||
|
if (leftover == bytes_read) {
|
||||||
|
free(buf);
|
||||||
|
buf = NULL;
|
||||||
|
|
||||||
|
bufsize <<= 1;
|
||||||
|
if ((bufsize >= HIS_BUF_LEN_MAX) ||
|
||||||
|
((buf = malloc(bufsize)) == NULL)) {
|
||||||
|
err = ENOMEM;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* CONSTCOND */
|
/* CONSTCOND */
|
||||||
} while (1);
|
} while (1);
|
||||||
|
free(buf);
|
||||||
|
|
||||||
if (!err) {
|
if (!err) {
|
||||||
verify(nvlist_alloc(nvhisp, NV_UNIQUE_NAME, 0) == 0);
|
verify(nvlist_alloc(nvhisp, NV_UNIQUE_NAME, 0) == 0);
|
||||||
|
@ -21,7 +21,7 @@
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||||
* Copyright (c) 2012 by Delphix. All rights reserved.
|
* Copyright (c) 2013 by Delphix. All rights reserved.
|
||||||
* Copyright (c) 2012, Joyent, Inc. All rights reserved.
|
* Copyright (c) 2012, Joyent, Inc. All rights reserved.
|
||||||
* Copyright (c) 2012 Pawel Jakub Dawidek <pawel@dawidek.net>.
|
* Copyright (c) 2012 Pawel Jakub Dawidek <pawel@dawidek.net>.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
@ -1619,6 +1619,62 @@ zfs_send(zfs_handle_t *zhp, const char *fromsnap, const char *tosnap,
|
|||||||
return (err);
|
return (err);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
zfs_send_one(zfs_handle_t *zhp, const char *from, int fd)
|
||||||
|
{
|
||||||
|
int err;
|
||||||
|
libzfs_handle_t *hdl = zhp->zfs_hdl;
|
||||||
|
|
||||||
|
char errbuf[1024];
|
||||||
|
(void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
|
||||||
|
"warning: cannot send '%s'"), zhp->zfs_name);
|
||||||
|
|
||||||
|
err = lzc_send(zhp->zfs_name, from, fd);
|
||||||
|
if (err != 0) {
|
||||||
|
switch (errno) {
|
||||||
|
case EXDEV:
|
||||||
|
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
|
||||||
|
"not an earlier snapshot from the same fs"));
|
||||||
|
return (zfs_error(hdl, EZFS_CROSSTARGET, errbuf));
|
||||||
|
|
||||||
|
case ENOENT:
|
||||||
|
case ESRCH:
|
||||||
|
if (lzc_exists(zhp->zfs_name)) {
|
||||||
|
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
|
||||||
|
"incremental source (%s) does not exist"),
|
||||||
|
from);
|
||||||
|
}
|
||||||
|
return (zfs_error(hdl, EZFS_NOENT, errbuf));
|
||||||
|
|
||||||
|
case EBUSY:
|
||||||
|
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
|
||||||
|
"target is busy; if a filesystem, "
|
||||||
|
"it must not be mounted"));
|
||||||
|
return (zfs_error(hdl, EZFS_BUSY, errbuf));
|
||||||
|
|
||||||
|
case EDQUOT:
|
||||||
|
case EFBIG:
|
||||||
|
case EIO:
|
||||||
|
case ENOLINK:
|
||||||
|
case ENOSPC:
|
||||||
|
#ifdef illumos
|
||||||
|
case ENOSTR:
|
||||||
|
#endif
|
||||||
|
case ENXIO:
|
||||||
|
case EPIPE:
|
||||||
|
case ERANGE:
|
||||||
|
case EFAULT:
|
||||||
|
case EROFS:
|
||||||
|
zfs_error_aux(hdl, strerror(errno));
|
||||||
|
return (zfs_error(hdl, EZFS_BADBACKUP, errbuf));
|
||||||
|
|
||||||
|
default:
|
||||||
|
return (zfs_standard_error(hdl, errno, errbuf));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return (err != 0);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Routines specific to "zfs recv"
|
* Routines specific to "zfs recv"
|
||||||
*/
|
*/
|
||||||
|
@ -21,6 +21,7 @@
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||||
|
* Copyright (c) 2013, Joyent, Inc. All rights reserved.
|
||||||
* Copyright (c) 2012 by Delphix. All rights reserved.
|
* Copyright (c) 2012 by Delphix. All rights reserved.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -1268,6 +1269,16 @@ zprop_parse_value(libzfs_handle_t *hdl, nvpair_t *elem, int prop,
|
|||||||
"use 'none' to disable quota/refquota"));
|
"use 'none' to disable quota/refquota"));
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Special handling for "*_limit=none". In this case it's not
|
||||||
|
* 0 but UINT64_MAX.
|
||||||
|
*/
|
||||||
|
if ((type & ZFS_TYPE_DATASET) && isnone &&
|
||||||
|
(prop == ZFS_PROP_FILESYSTEM_LIMIT ||
|
||||||
|
prop == ZFS_PROP_SNAPSHOT_LIMIT)) {
|
||||||
|
*ivalp = UINT64_MAX;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PROP_TYPE_INDEX:
|
case PROP_TYPE_INDEX:
|
||||||
|
@ -486,18 +486,30 @@ lzc_get_holds(const char *snapname, nvlist_t **holdsp)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If fromsnap is NULL, a full (non-incremental) stream will be sent.
|
*
|
||||||
|
* "snapname" is the full name of the snapshot to send (e.g. "pool/fs@snap")
|
||||||
|
*
|
||||||
|
* If "from" is NULL, a full (non-incremental) stream will be sent.
|
||||||
|
* If "from" is non-NULL, it must be the full name of a snapshot or
|
||||||
|
* bookmark to send an incremental from (e.g. "pool/fs@earlier_snap" or
|
||||||
|
* "pool/fs#earlier_bmark"). If non-NULL, the specified snapshot or
|
||||||
|
* bookmark must represent an earlier point in the history of "snapname").
|
||||||
|
* It can be an earlier snapshot in the same filesystem or zvol as "snapname",
|
||||||
|
* or it can be the origin of "snapname"'s filesystem, or an earlier
|
||||||
|
* snapshot in the origin, etc.
|
||||||
|
*
|
||||||
|
* "fd" is the file descriptor to write the send stream to.
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
lzc_send(const char *snapname, const char *fromsnap, int fd)
|
lzc_send(const char *snapname, const char *from, int fd)
|
||||||
{
|
{
|
||||||
nvlist_t *args;
|
nvlist_t *args;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
args = fnvlist_alloc();
|
args = fnvlist_alloc();
|
||||||
fnvlist_add_int32(args, "fd", fd);
|
fnvlist_add_int32(args, "fd", fd);
|
||||||
if (fromsnap != NULL)
|
if (from != NULL)
|
||||||
fnvlist_add_string(args, "fromsnap", fromsnap);
|
fnvlist_add_string(args, "fromsnap", from);
|
||||||
err = lzc_ioctl(ZFS_IOC_SEND_NEW, snapname, args, NULL);
|
err = lzc_ioctl(ZFS_IOC_SEND_NEW, snapname, args, NULL);
|
||||||
nvlist_free(args);
|
nvlist_free(args);
|
||||||
return (err);
|
return (err);
|
||||||
@ -652,3 +664,97 @@ lzc_rollback(const char *fsname, char *snapnamebuf, int snapnamelen)
|
|||||||
}
|
}
|
||||||
return (err);
|
return (err);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Creates bookmarks.
|
||||||
|
*
|
||||||
|
* The bookmarks nvlist maps from name of the bookmark (e.g. "pool/fs#bmark") to
|
||||||
|
* the name of the snapshot (e.g. "pool/fs@snap"). All the bookmarks and
|
||||||
|
* snapshots must be in the same pool.
|
||||||
|
*
|
||||||
|
* The returned results nvlist will have an entry for each bookmark that failed.
|
||||||
|
* The value will be the (int32) error code.
|
||||||
|
*
|
||||||
|
* The return value will be 0 if all bookmarks were created, otherwise it will
|
||||||
|
* be the errno of a (undetermined) bookmarks that failed.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
lzc_bookmark(nvlist_t *bookmarks, nvlist_t **errlist)
|
||||||
|
{
|
||||||
|
nvpair_t *elem;
|
||||||
|
int error;
|
||||||
|
char pool[MAXNAMELEN];
|
||||||
|
|
||||||
|
/* determine the pool name */
|
||||||
|
elem = nvlist_next_nvpair(bookmarks, NULL);
|
||||||
|
if (elem == NULL)
|
||||||
|
return (0);
|
||||||
|
(void) strlcpy(pool, nvpair_name(elem), sizeof (pool));
|
||||||
|
pool[strcspn(pool, "/#")] = '\0';
|
||||||
|
|
||||||
|
error = lzc_ioctl(ZFS_IOC_BOOKMARK, pool, bookmarks, errlist);
|
||||||
|
|
||||||
|
return (error);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Retrieve bookmarks.
|
||||||
|
*
|
||||||
|
* Retrieve the list of bookmarks for the given file system. The props
|
||||||
|
* parameter is an nvlist of property names (with no values) that will be
|
||||||
|
* returned for each bookmark.
|
||||||
|
*
|
||||||
|
* The following are valid properties on bookmarks, all of which are numbers
|
||||||
|
* (represented as uint64 in the nvlist)
|
||||||
|
*
|
||||||
|
* "guid" - globally unique identifier of the snapshot it refers to
|
||||||
|
* "createtxg" - txg when the snapshot it refers to was created
|
||||||
|
* "creation" - timestamp when the snapshot it refers to was created
|
||||||
|
*
|
||||||
|
* The format of the returned nvlist as follows:
|
||||||
|
* <short name of bookmark> -> {
|
||||||
|
* <name of property> -> {
|
||||||
|
* "value" -> uint64
|
||||||
|
* }
|
||||||
|
* }
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
lzc_get_bookmarks(const char *fsname, nvlist_t *props, nvlist_t **bmarks)
|
||||||
|
{
|
||||||
|
return (lzc_ioctl(ZFS_IOC_GET_BOOKMARKS, fsname, props, bmarks));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Destroys bookmarks.
|
||||||
|
*
|
||||||
|
* The keys in the bmarks nvlist are the bookmarks to be destroyed.
|
||||||
|
* They must all be in the same pool. Bookmarks are specified as
|
||||||
|
* <fs>#<bmark>.
|
||||||
|
*
|
||||||
|
* Bookmarks that do not exist will be silently ignored.
|
||||||
|
*
|
||||||
|
* The return value will be 0 if all bookmarks that existed were destroyed.
|
||||||
|
*
|
||||||
|
* Otherwise the return value will be the errno of a (undetermined) bookmark
|
||||||
|
* that failed, no bookmarks will be destroyed, and the errlist will have an
|
||||||
|
* entry for each bookmarks that failed. The value in the errlist will be
|
||||||
|
* the (int32) error code.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
lzc_destroy_bookmarks(nvlist_t *bmarks, nvlist_t **errlist)
|
||||||
|
{
|
||||||
|
nvpair_t *elem;
|
||||||
|
int error;
|
||||||
|
char pool[MAXNAMELEN];
|
||||||
|
|
||||||
|
/* determine the pool name */
|
||||||
|
elem = nvlist_next_nvpair(bmarks, NULL);
|
||||||
|
if (elem == NULL)
|
||||||
|
return (0);
|
||||||
|
(void) strlcpy(pool, nvpair_name(elem), sizeof (pool));
|
||||||
|
pool[strcspn(pool, "/#")] = '\0';
|
||||||
|
|
||||||
|
error = lzc_ioctl(ZFS_IOC_DESTROY_BOOKMARKS, pool, bmarks, errlist);
|
||||||
|
|
||||||
|
return (error);
|
||||||
|
}
|
||||||
|
@ -39,27 +39,27 @@ extern "C" {
|
|||||||
int libzfs_core_init(void);
|
int libzfs_core_init(void);
|
||||||
void libzfs_core_fini(void);
|
void libzfs_core_fini(void);
|
||||||
|
|
||||||
int lzc_snapshot(nvlist_t *snaps, nvlist_t *props, nvlist_t **errlist);
|
int lzc_snapshot(nvlist_t *, nvlist_t *, nvlist_t **);
|
||||||
int lzc_create(const char *fsname, dmu_objset_type_t type, nvlist_t *props);
|
int lzc_create(const char *, dmu_objset_type_t, nvlist_t *);
|
||||||
int lzc_clone(const char *fsname, const char *origin, nvlist_t *props);
|
int lzc_clone(const char *, const char *, nvlist_t *);
|
||||||
int lzc_destroy_snaps(nvlist_t *snaps, boolean_t defer, nvlist_t **errlist);
|
int lzc_destroy_snaps(nvlist_t *, boolean_t, nvlist_t **);
|
||||||
|
int lzc_bookmark(nvlist_t *, nvlist_t **);
|
||||||
|
int lzc_get_bookmarks(const char *, nvlist_t *, nvlist_t **);
|
||||||
|
int lzc_destroy_bookmarks(nvlist_t *, nvlist_t **);
|
||||||
|
|
||||||
int lzc_snaprange_space(const char *firstsnap, const char *lastsnap,
|
int lzc_snaprange_space(const char *, const char *, uint64_t *);
|
||||||
uint64_t *usedp);
|
|
||||||
|
|
||||||
int lzc_hold(nvlist_t *holds, int cleanup_fd, nvlist_t **errlist);
|
int lzc_hold(nvlist_t *, int, nvlist_t **);
|
||||||
int lzc_release(nvlist_t *holds, nvlist_t **errlist);
|
int lzc_release(nvlist_t *, nvlist_t **);
|
||||||
int lzc_get_holds(const char *snapname, nvlist_t **holdsp);
|
int lzc_get_holds(const char *, nvlist_t **);
|
||||||
|
|
||||||
int lzc_send(const char *snapname, const char *fromsnap, int fd);
|
int lzc_send(const char *, const char *, int);
|
||||||
int lzc_receive(const char *snapname, nvlist_t *props, const char *origin,
|
int lzc_receive(const char *, nvlist_t *, const char *, boolean_t, int);
|
||||||
boolean_t force, int fd);
|
int lzc_send_space(const char *, const char *, uint64_t *);
|
||||||
int lzc_send_space(const char *snapname, const char *fromsnap,
|
|
||||||
uint64_t *result);
|
|
||||||
|
|
||||||
boolean_t lzc_exists(const char *dataset);
|
boolean_t lzc_exists(const char *);
|
||||||
|
|
||||||
int lzc_rollback(const char *fsname, char *snapnamebuf, int snapnamelen);
|
int lzc_rollback(const char *, char *, int);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
@ -20,6 +20,8 @@
|
|||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||||
|
* Copyright (c) 2012, 2014 by Delphix. All rights reserved.
|
||||||
|
* Copyright (c) 2013, Joyent, Inc. All rights reserved.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
@ -661,7 +663,7 @@ __dprintf(const char *file, const char *func, int line, const char *fmt, ...)
|
|||||||
if (dprintf_find_string("pid"))
|
if (dprintf_find_string("pid"))
|
||||||
(void) printf("%d ", getpid());
|
(void) printf("%d ", getpid());
|
||||||
if (dprintf_find_string("tid"))
|
if (dprintf_find_string("tid"))
|
||||||
(void) printf("%u ", thr_self());
|
(void) printf("%ul ", thr_self());
|
||||||
#if 0
|
#if 0
|
||||||
if (dprintf_find_string("cpu"))
|
if (dprintf_find_string("cpu"))
|
||||||
(void) printf("%u ", getcpuid());
|
(void) printf("%u ", getcpuid());
|
||||||
@ -800,20 +802,17 @@ delay(clock_t ticks)
|
|||||||
/*
|
/*
|
||||||
* Find highest one bit set.
|
* Find highest one bit set.
|
||||||
* Returns bit number + 1 of highest bit that is set, otherwise returns 0.
|
* Returns bit number + 1 of highest bit that is set, otherwise returns 0.
|
||||||
* High order bit is 31 (or 63 in _LP64 kernel).
|
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
highbit(ulong_t i)
|
highbit64(uint64_t i)
|
||||||
{
|
{
|
||||||
register int h = 1;
|
int h = 1;
|
||||||
|
|
||||||
if (i == 0)
|
if (i == 0)
|
||||||
return (0);
|
return (0);
|
||||||
#ifdef _LP64
|
if (i & 0xffffffff00000000ULL) {
|
||||||
if (i & 0xffffffff00000000ul) {
|
|
||||||
h += 32; i >>= 32;
|
h += 32; i >>= 32;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
if (i & 0xffff0000) {
|
if (i & 0xffff0000) {
|
||||||
h += 16; i >>= 16;
|
h += 16; i >>= 16;
|
||||||
}
|
}
|
||||||
@ -1125,3 +1124,50 @@ zvol_create_minors(const char *name)
|
|||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef illumos
|
||||||
|
void
|
||||||
|
bioinit(buf_t *bp)
|
||||||
|
{
|
||||||
|
bzero(bp, sizeof (buf_t));
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
biodone(buf_t *bp)
|
||||||
|
{
|
||||||
|
if (bp->b_iodone != NULL) {
|
||||||
|
(*(bp->b_iodone))(bp);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ASSERT((bp->b_flags & B_DONE) == 0);
|
||||||
|
bp->b_flags |= B_DONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
bioerror(buf_t *bp, int error)
|
||||||
|
{
|
||||||
|
ASSERT(bp != NULL);
|
||||||
|
ASSERT(error >= 0);
|
||||||
|
|
||||||
|
if (error != 0) {
|
||||||
|
bp->b_flags |= B_ERROR;
|
||||||
|
} else {
|
||||||
|
bp->b_flags &= ~B_ERROR;
|
||||||
|
}
|
||||||
|
bp->b_error = error;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
geterror(struct buf *bp)
|
||||||
|
{
|
||||||
|
int error = 0;
|
||||||
|
|
||||||
|
if (bp->b_flags & B_ERROR) {
|
||||||
|
error = bp->b_error;
|
||||||
|
if (!error)
|
||||||
|
error = EIO;
|
||||||
|
}
|
||||||
|
return (error);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
@ -20,9 +20,12 @@
|
|||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||||
* Copyright (c) 2013 by Delphix. All rights reserved.
|
* Copyright (c) 2012, 2014 by Delphix. All rights reserved.
|
||||||
* Copyright (c) 2012, Joyent, Inc. All rights reserved.
|
* Copyright (c) 2012, Joyent, Inc. All rights reserved.
|
||||||
*/
|
*/
|
||||||
|
/*
|
||||||
|
* Copyright 2011 Nexenta Systems, Inc. All rights reserved.
|
||||||
|
*/
|
||||||
|
|
||||||
#ifndef _SYS_ZFS_CONTEXT_H
|
#ifndef _SYS_ZFS_CONTEXT_H
|
||||||
#define _SYS_ZFS_CONTEXT_H
|
#define _SYS_ZFS_CONTEXT_H
|
||||||
@ -62,6 +65,7 @@ extern "C" {
|
|||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
#include <fsshare.h>
|
#include <fsshare.h>
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
|
#include <sched.h>
|
||||||
#include <sys/debug.h>
|
#include <sys/debug.h>
|
||||||
#include <sys/note.h>
|
#include <sys/note.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
@ -201,6 +205,8 @@ extern int aok;
|
|||||||
*/
|
*/
|
||||||
#define curthread ((void *)(uintptr_t)thr_self())
|
#define curthread ((void *)(uintptr_t)thr_self())
|
||||||
|
|
||||||
|
#define kpreempt(x) sched_yield()
|
||||||
|
|
||||||
typedef struct kthread kthread_t;
|
typedef struct kthread kthread_t;
|
||||||
|
|
||||||
#define thread_create(stk, stksize, func, arg, len, pp, state, pri) \
|
#define thread_create(stk, stksize, func, arg, len, pp, state, pri) \
|
||||||
@ -367,6 +373,16 @@ typedef struct taskq taskq_t;
|
|||||||
typedef uintptr_t taskqid_t;
|
typedef uintptr_t taskqid_t;
|
||||||
typedef void (task_func_t)(void *);
|
typedef void (task_func_t)(void *);
|
||||||
|
|
||||||
|
typedef struct taskq_ent {
|
||||||
|
struct taskq_ent *tqent_next;
|
||||||
|
struct taskq_ent *tqent_prev;
|
||||||
|
task_func_t *tqent_func;
|
||||||
|
void *tqent_arg;
|
||||||
|
uintptr_t tqent_flags;
|
||||||
|
} taskq_ent_t;
|
||||||
|
|
||||||
|
#define TQENT_FLAG_PREALLOC 0x1 /* taskq_dispatch_ent used */
|
||||||
|
|
||||||
#define TASKQ_PREPOPULATE 0x0001
|
#define TASKQ_PREPOPULATE 0x0001
|
||||||
#define TASKQ_CPR_SAFE 0x0002 /* Use CPR safe protocol */
|
#define TASKQ_CPR_SAFE 0x0002 /* Use CPR safe protocol */
|
||||||
#define TASKQ_DYNAMIC 0x0004 /* Use dynamic thread scheduling */
|
#define TASKQ_DYNAMIC 0x0004 /* Use dynamic thread scheduling */
|
||||||
@ -378,6 +394,7 @@ typedef void (task_func_t)(void *);
|
|||||||
#define TQ_NOQUEUE 0x02 /* Do not enqueue if can't dispatch */
|
#define TQ_NOQUEUE 0x02 /* Do not enqueue if can't dispatch */
|
||||||
#define TQ_FRONT 0x08 /* Queue in front */
|
#define TQ_FRONT 0x08 /* Queue in front */
|
||||||
|
|
||||||
|
|
||||||
extern taskq_t *system_taskq;
|
extern taskq_t *system_taskq;
|
||||||
|
|
||||||
extern taskq_t *taskq_create(const char *, int, pri_t, int, int, uint_t);
|
extern taskq_t *taskq_create(const char *, int, pri_t, int, int, uint_t);
|
||||||
@ -386,6 +403,8 @@ extern taskq_t *taskq_create(const char *, int, pri_t, int, int, uint_t);
|
|||||||
#define taskq_create_sysdc(a, b, d, e, p, dc, f) \
|
#define taskq_create_sysdc(a, b, d, e, p, dc, f) \
|
||||||
(taskq_create(a, b, maxclsyspri, d, e, f))
|
(taskq_create(a, b, maxclsyspri, d, e, f))
|
||||||
extern taskqid_t taskq_dispatch(taskq_t *, task_func_t, void *, uint_t);
|
extern taskqid_t taskq_dispatch(taskq_t *, task_func_t, void *, uint_t);
|
||||||
|
extern void taskq_dispatch_ent(taskq_t *, task_func_t, void *, uint_t,
|
||||||
|
taskq_ent_t *);
|
||||||
extern void taskq_destroy(taskq_t *);
|
extern void taskq_destroy(taskq_t *);
|
||||||
extern void taskq_wait(taskq_t *);
|
extern void taskq_wait(taskq_t *);
|
||||||
extern int taskq_member(taskq_t *, void *);
|
extern int taskq_member(taskq_t *, void *);
|
||||||
@ -539,7 +558,7 @@ extern void delay(clock_t ticks);
|
|||||||
|
|
||||||
extern uint64_t physmem;
|
extern uint64_t physmem;
|
||||||
|
|
||||||
extern int highbit(ulong_t i);
|
extern int highbit64(uint64_t i);
|
||||||
extern int random_get_bytes(uint8_t *ptr, size_t len);
|
extern int random_get_bytes(uint8_t *ptr, size_t len);
|
||||||
extern int random_get_pseudo_bytes(uint8_t *ptr, size_t len);
|
extern int random_get_pseudo_bytes(uint8_t *ptr, size_t len);
|
||||||
|
|
||||||
@ -759,6 +778,38 @@ extern void cyclic_remove(cyclic_id_t);
|
|||||||
extern int cyclic_reprogram(cyclic_id_t, hrtime_t);
|
extern int cyclic_reprogram(cyclic_id_t, hrtime_t);
|
||||||
#endif /* illumos */
|
#endif /* illumos */
|
||||||
|
|
||||||
|
#ifdef illumos
|
||||||
|
/*
|
||||||
|
* Buf structure
|
||||||
|
*/
|
||||||
|
#define B_BUSY 0x0001
|
||||||
|
#define B_DONE 0x0002
|
||||||
|
#define B_ERROR 0x0004
|
||||||
|
#define B_READ 0x0040 /* read when I/O occurs */
|
||||||
|
#define B_WRITE 0x0100 /* non-read pseudo-flag */
|
||||||
|
|
||||||
|
typedef struct buf {
|
||||||
|
int b_flags;
|
||||||
|
size_t b_bcount;
|
||||||
|
union {
|
||||||
|
caddr_t b_addr;
|
||||||
|
} b_un;
|
||||||
|
|
||||||
|
lldaddr_t _b_blkno;
|
||||||
|
#define b_lblkno _b_blkno._f
|
||||||
|
size_t b_resid;
|
||||||
|
size_t b_bufsize;
|
||||||
|
int (*b_iodone)(struct buf *);
|
||||||
|
int b_error;
|
||||||
|
void *b_private;
|
||||||
|
} buf_t;
|
||||||
|
|
||||||
|
extern void bioinit(buf_t *);
|
||||||
|
extern void biodone(buf_t *);
|
||||||
|
extern void bioerror(buf_t *, int);
|
||||||
|
extern int geterror(buf_t *);
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -22,19 +22,15 @@
|
|||||||
* Copyright 2010 Sun Microsystems, Inc. All rights reserved.
|
* Copyright 2010 Sun Microsystems, Inc. All rights reserved.
|
||||||
* Use is subject to license terms.
|
* Use is subject to license terms.
|
||||||
*/
|
*/
|
||||||
|
/*
|
||||||
|
* Copyright 2011 Nexenta Systems, Inc. All rights reserved.
|
||||||
|
*/
|
||||||
|
|
||||||
#include <sys/zfs_context.h>
|
#include <sys/zfs_context.h>
|
||||||
|
|
||||||
int taskq_now;
|
int taskq_now;
|
||||||
taskq_t *system_taskq;
|
taskq_t *system_taskq;
|
||||||
|
|
||||||
typedef struct task {
|
|
||||||
struct task *task_next;
|
|
||||||
struct task *task_prev;
|
|
||||||
task_func_t *task_func;
|
|
||||||
void *task_arg;
|
|
||||||
} task_t;
|
|
||||||
|
|
||||||
#define TASKQ_ACTIVE 0x00010000
|
#define TASKQ_ACTIVE 0x00010000
|
||||||
|
|
||||||
struct taskq {
|
struct taskq {
|
||||||
@ -51,18 +47,18 @@ struct taskq {
|
|||||||
int tq_maxalloc;
|
int tq_maxalloc;
|
||||||
kcondvar_t tq_maxalloc_cv;
|
kcondvar_t tq_maxalloc_cv;
|
||||||
int tq_maxalloc_wait;
|
int tq_maxalloc_wait;
|
||||||
task_t *tq_freelist;
|
taskq_ent_t *tq_freelist;
|
||||||
task_t tq_task;
|
taskq_ent_t tq_task;
|
||||||
};
|
};
|
||||||
|
|
||||||
static task_t *
|
static taskq_ent_t *
|
||||||
task_alloc(taskq_t *tq, int tqflags)
|
task_alloc(taskq_t *tq, int tqflags)
|
||||||
{
|
{
|
||||||
task_t *t;
|
taskq_ent_t *t;
|
||||||
int rv;
|
int rv;
|
||||||
|
|
||||||
again: if ((t = tq->tq_freelist) != NULL && tq->tq_nalloc >= tq->tq_minalloc) {
|
again: if ((t = tq->tq_freelist) != NULL && tq->tq_nalloc >= tq->tq_minalloc) {
|
||||||
tq->tq_freelist = t->task_next;
|
tq->tq_freelist = t->tqent_next;
|
||||||
} else {
|
} else {
|
||||||
if (tq->tq_nalloc >= tq->tq_maxalloc) {
|
if (tq->tq_nalloc >= tq->tq_maxalloc) {
|
||||||
if (!(tqflags & KM_SLEEP))
|
if (!(tqflags & KM_SLEEP))
|
||||||
@ -87,7 +83,7 @@ again: if ((t = tq->tq_freelist) != NULL && tq->tq_nalloc >= tq->tq_minalloc) {
|
|||||||
}
|
}
|
||||||
mutex_exit(&tq->tq_lock);
|
mutex_exit(&tq->tq_lock);
|
||||||
|
|
||||||
t = kmem_alloc(sizeof (task_t), tqflags & KM_SLEEP);
|
t = kmem_alloc(sizeof (taskq_ent_t), tqflags & KM_SLEEP);
|
||||||
|
|
||||||
mutex_enter(&tq->tq_lock);
|
mutex_enter(&tq->tq_lock);
|
||||||
if (t != NULL)
|
if (t != NULL)
|
||||||
@ -97,15 +93,15 @@ again: if ((t = tq->tq_freelist) != NULL && tq->tq_nalloc >= tq->tq_minalloc) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
task_free(taskq_t *tq, task_t *t)
|
task_free(taskq_t *tq, taskq_ent_t *t)
|
||||||
{
|
{
|
||||||
if (tq->tq_nalloc <= tq->tq_minalloc) {
|
if (tq->tq_nalloc <= tq->tq_minalloc) {
|
||||||
t->task_next = tq->tq_freelist;
|
t->tqent_next = tq->tq_freelist;
|
||||||
tq->tq_freelist = t;
|
tq->tq_freelist = t;
|
||||||
} else {
|
} else {
|
||||||
tq->tq_nalloc--;
|
tq->tq_nalloc--;
|
||||||
mutex_exit(&tq->tq_lock);
|
mutex_exit(&tq->tq_lock);
|
||||||
kmem_free(t, sizeof (task_t));
|
kmem_free(t, sizeof (taskq_ent_t));
|
||||||
mutex_enter(&tq->tq_lock);
|
mutex_enter(&tq->tq_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -116,7 +112,7 @@ task_free(taskq_t *tq, task_t *t)
|
|||||||
taskqid_t
|
taskqid_t
|
||||||
taskq_dispatch(taskq_t *tq, task_func_t func, void *arg, uint_t tqflags)
|
taskq_dispatch(taskq_t *tq, task_func_t func, void *arg, uint_t tqflags)
|
||||||
{
|
{
|
||||||
task_t *t;
|
taskq_ent_t *t;
|
||||||
|
|
||||||
if (taskq_now) {
|
if (taskq_now) {
|
||||||
func(arg);
|
func(arg);
|
||||||
@ -130,26 +126,58 @@ taskq_dispatch(taskq_t *tq, task_func_t func, void *arg, uint_t tqflags)
|
|||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
if (tqflags & TQ_FRONT) {
|
if (tqflags & TQ_FRONT) {
|
||||||
t->task_next = tq->tq_task.task_next;
|
t->tqent_next = tq->tq_task.tqent_next;
|
||||||
t->task_prev = &tq->tq_task;
|
t->tqent_prev = &tq->tq_task;
|
||||||
} else {
|
} else {
|
||||||
t->task_next = &tq->tq_task;
|
t->tqent_next = &tq->tq_task;
|
||||||
t->task_prev = tq->tq_task.task_prev;
|
t->tqent_prev = tq->tq_task.tqent_prev;
|
||||||
}
|
}
|
||||||
t->task_next->task_prev = t;
|
t->tqent_next->tqent_prev = t;
|
||||||
t->task_prev->task_next = t;
|
t->tqent_prev->tqent_next = t;
|
||||||
t->task_func = func;
|
t->tqent_func = func;
|
||||||
t->task_arg = arg;
|
t->tqent_arg = arg;
|
||||||
cv_signal(&tq->tq_dispatch_cv);
|
cv_signal(&tq->tq_dispatch_cv);
|
||||||
mutex_exit(&tq->tq_lock);
|
mutex_exit(&tq->tq_lock);
|
||||||
return (1);
|
return (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
taskq_dispatch_ent(taskq_t *tq, task_func_t func, void *arg, uint_t flags,
|
||||||
|
taskq_ent_t *t)
|
||||||
|
{
|
||||||
|
ASSERT(func != NULL);
|
||||||
|
ASSERT(!(tq->tq_flags & TASKQ_DYNAMIC));
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Mark it as a prealloc'd task. This is important
|
||||||
|
* to ensure that we don't free it later.
|
||||||
|
*/
|
||||||
|
t->tqent_flags |= TQENT_FLAG_PREALLOC;
|
||||||
|
/*
|
||||||
|
* Enqueue the task to the underlying queue.
|
||||||
|
*/
|
||||||
|
mutex_enter(&tq->tq_lock);
|
||||||
|
|
||||||
|
if (flags & TQ_FRONT) {
|
||||||
|
t->tqent_next = tq->tq_task.tqent_next;
|
||||||
|
t->tqent_prev = &tq->tq_task;
|
||||||
|
} else {
|
||||||
|
t->tqent_next = &tq->tq_task;
|
||||||
|
t->tqent_prev = tq->tq_task.tqent_prev;
|
||||||
|
}
|
||||||
|
t->tqent_next->tqent_prev = t;
|
||||||
|
t->tqent_prev->tqent_next = t;
|
||||||
|
t->tqent_func = func;
|
||||||
|
t->tqent_arg = arg;
|
||||||
|
cv_signal(&tq->tq_dispatch_cv);
|
||||||
|
mutex_exit(&tq->tq_lock);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
taskq_wait(taskq_t *tq)
|
taskq_wait(taskq_t *tq)
|
||||||
{
|
{
|
||||||
mutex_enter(&tq->tq_lock);
|
mutex_enter(&tq->tq_lock);
|
||||||
while (tq->tq_task.task_next != &tq->tq_task || tq->tq_active != 0)
|
while (tq->tq_task.tqent_next != &tq->tq_task || tq->tq_active != 0)
|
||||||
cv_wait(&tq->tq_wait_cv, &tq->tq_lock);
|
cv_wait(&tq->tq_wait_cv, &tq->tq_lock);
|
||||||
mutex_exit(&tq->tq_lock);
|
mutex_exit(&tq->tq_lock);
|
||||||
}
|
}
|
||||||
@ -158,26 +186,31 @@ static void *
|
|||||||
taskq_thread(void *arg)
|
taskq_thread(void *arg)
|
||||||
{
|
{
|
||||||
taskq_t *tq = arg;
|
taskq_t *tq = arg;
|
||||||
task_t *t;
|
taskq_ent_t *t;
|
||||||
|
boolean_t prealloc;
|
||||||
|
|
||||||
mutex_enter(&tq->tq_lock);
|
mutex_enter(&tq->tq_lock);
|
||||||
while (tq->tq_flags & TASKQ_ACTIVE) {
|
while (tq->tq_flags & TASKQ_ACTIVE) {
|
||||||
if ((t = tq->tq_task.task_next) == &tq->tq_task) {
|
if ((t = tq->tq_task.tqent_next) == &tq->tq_task) {
|
||||||
if (--tq->tq_active == 0)
|
if (--tq->tq_active == 0)
|
||||||
cv_broadcast(&tq->tq_wait_cv);
|
cv_broadcast(&tq->tq_wait_cv);
|
||||||
cv_wait(&tq->tq_dispatch_cv, &tq->tq_lock);
|
cv_wait(&tq->tq_dispatch_cv, &tq->tq_lock);
|
||||||
tq->tq_active++;
|
tq->tq_active++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
t->task_prev->task_next = t->task_next;
|
t->tqent_prev->tqent_next = t->tqent_next;
|
||||||
t->task_next->task_prev = t->task_prev;
|
t->tqent_next->tqent_prev = t->tqent_prev;
|
||||||
|
t->tqent_next = NULL;
|
||||||
|
t->tqent_prev = NULL;
|
||||||
|
prealloc = t->tqent_flags & TQENT_FLAG_PREALLOC;
|
||||||
mutex_exit(&tq->tq_lock);
|
mutex_exit(&tq->tq_lock);
|
||||||
|
|
||||||
rw_enter(&tq->tq_threadlock, RW_READER);
|
rw_enter(&tq->tq_threadlock, RW_READER);
|
||||||
t->task_func(t->task_arg);
|
t->tqent_func(t->tqent_arg);
|
||||||
rw_exit(&tq->tq_threadlock);
|
rw_exit(&tq->tq_threadlock);
|
||||||
|
|
||||||
mutex_enter(&tq->tq_lock);
|
mutex_enter(&tq->tq_lock);
|
||||||
|
if (!prealloc)
|
||||||
task_free(tq, t);
|
task_free(tq, t);
|
||||||
}
|
}
|
||||||
tq->tq_nthreads--;
|
tq->tq_nthreads--;
|
||||||
@ -217,8 +250,8 @@ taskq_create(const char *name, int nthreads, pri_t pri,
|
|||||||
tq->tq_nthreads = nthreads;
|
tq->tq_nthreads = nthreads;
|
||||||
tq->tq_minalloc = minalloc;
|
tq->tq_minalloc = minalloc;
|
||||||
tq->tq_maxalloc = maxalloc;
|
tq->tq_maxalloc = maxalloc;
|
||||||
tq->tq_task.task_next = &tq->tq_task;
|
tq->tq_task.tqent_next = &tq->tq_task;
|
||||||
tq->tq_task.task_prev = &tq->tq_task;
|
tq->tq_task.tqent_prev = &tq->tq_task;
|
||||||
tq->tq_threadlist = kmem_alloc(nthreads * sizeof (thread_t), KM_SLEEP);
|
tq->tq_threadlist = kmem_alloc(nthreads * sizeof (thread_t), KM_SLEEP);
|
||||||
|
|
||||||
if (flags & TASKQ_PREPOPULATE) {
|
if (flags & TASKQ_PREPOPULATE) {
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
# CDDL HEADER END
|
# CDDL HEADER END
|
||||||
#
|
#
|
||||||
# Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
|
# Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||||
|
# Copyright (c) 2013 by Delphix. All rights reserved.
|
||||||
#
|
#
|
||||||
|
|
||||||
"""This module implements the "zfs allow" and "zfs unallow" subcommands.
|
"""This module implements the "zfs allow" and "zfs unallow" subcommands.
|
||||||
@ -219,6 +220,7 @@ def decodeid(w, toidfunc, fmt):
|
|||||||
hold=_("Allows adding a user hold to a snapshot"),
|
hold=_("Allows adding a user hold to a snapshot"),
|
||||||
release=_("Allows releasing a user hold which\n\t\t\t\tmight destroy the snapshot"),
|
release=_("Allows releasing a user hold which\n\t\t\t\tmight destroy the snapshot"),
|
||||||
diff=_("Allows lookup of paths within a dataset,\n\t\t\t\tgiven an object number. Ordinary users need this\n\t\t\t\tin order to use zfs diff"),
|
diff=_("Allows lookup of paths within a dataset,\n\t\t\t\tgiven an object number. Ordinary users need this\n\t\t\t\tin order to use zfs diff"),
|
||||||
|
bookmark="",
|
||||||
)
|
)
|
||||||
|
|
||||||
perms_other = dict(
|
perms_other = dict(
|
||||||
|
@ -96,9 +96,6 @@
|
|||||||
#include "list.h"
|
#include "list.h"
|
||||||
#include "traverse.h"
|
#include "traverse.h"
|
||||||
|
|
||||||
/* The version of DWARF which we support. */
|
|
||||||
#define DWARF_VERSION 2
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We need to define a couple of our own intrinsics, to smooth out some of the
|
* We need to define a couple of our own intrinsics, to smooth out some of the
|
||||||
* differences between the GCC and DevPro DWARF emitters. See the referenced
|
* differences between the GCC and DevPro DWARF emitters. See the referenced
|
||||||
@ -271,7 +268,7 @@ die_off(dwarf_t *dw, Dwarf_Die die)
|
|||||||
return (off);
|
return (off);
|
||||||
|
|
||||||
terminate("failed to get offset for die: %s\n",
|
terminate("failed to get offset for die: %s\n",
|
||||||
dwarf_errmsg(&dw->dw_err));
|
dwarf_errmsg(dw->dw_err));
|
||||||
/*NOTREACHED*/
|
/*NOTREACHED*/
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
@ -289,7 +286,7 @@ die_sibling(dwarf_t *dw, Dwarf_Die die)
|
|||||||
return (NULL);
|
return (NULL);
|
||||||
|
|
||||||
terminate("die %llu: failed to find type sibling: %s\n",
|
terminate("die %llu: failed to find type sibling: %s\n",
|
||||||
die_off(dw, die), dwarf_errmsg(&dw->dw_err));
|
die_off(dw, die), dwarf_errmsg(dw->dw_err));
|
||||||
/*NOTREACHED*/
|
/*NOTREACHED*/
|
||||||
return (NULL);
|
return (NULL);
|
||||||
}
|
}
|
||||||
@ -306,7 +303,7 @@ die_child(dwarf_t *dw, Dwarf_Die die)
|
|||||||
return (NULL);
|
return (NULL);
|
||||||
|
|
||||||
terminate("die %llu: failed to find type child: %s\n",
|
terminate("die %llu: failed to find type child: %s\n",
|
||||||
die_off(dw, die), dwarf_errmsg(&dw->dw_err));
|
die_off(dw, die), dwarf_errmsg(dw->dw_err));
|
||||||
/*NOTREACHED*/
|
/*NOTREACHED*/
|
||||||
return (NULL);
|
return (NULL);
|
||||||
}
|
}
|
||||||
@ -320,7 +317,7 @@ die_tag(dwarf_t *dw, Dwarf_Die die)
|
|||||||
return (tag);
|
return (tag);
|
||||||
|
|
||||||
terminate("die %llu: failed to get tag for type: %s\n",
|
terminate("die %llu: failed to get tag for type: %s\n",
|
||||||
die_off(dw, die), dwarf_errmsg(&dw->dw_err));
|
die_off(dw, die), dwarf_errmsg(dw->dw_err));
|
||||||
/*NOTREACHED*/
|
/*NOTREACHED*/
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
@ -343,7 +340,7 @@ die_attr(dwarf_t *dw, Dwarf_Die die, Dwarf_Half name, int req)
|
|||||||
}
|
}
|
||||||
|
|
||||||
terminate("die %llu: failed to get attribute for type: %s\n",
|
terminate("die %llu: failed to get attribute for type: %s\n",
|
||||||
die_off(dw, die), dwarf_errmsg(&dw->dw_err));
|
die_off(dw, die), dwarf_errmsg(dw->dw_err));
|
||||||
/*NOTREACHED*/
|
/*NOTREACHED*/
|
||||||
return (NULL);
|
return (NULL);
|
||||||
}
|
}
|
||||||
@ -353,10 +350,10 @@ die_signed(dwarf_t *dw, Dwarf_Die die, Dwarf_Half name, Dwarf_Signed *valp,
|
|||||||
int req)
|
int req)
|
||||||
{
|
{
|
||||||
*valp = 0;
|
*valp = 0;
|
||||||
if (dwarf_attrval_signed(die, name, valp, &dw->dw_err) != DWARF_E_NONE) {
|
if (dwarf_attrval_signed(die, name, valp, &dw->dw_err) != DW_DLV_OK) {
|
||||||
if (req)
|
if (req)
|
||||||
terminate("die %llu: failed to get signed: %s\n",
|
terminate("die %llu: failed to get signed: %s\n",
|
||||||
die_off(dw, die), dwarf_errmsg(&dw->dw_err));
|
die_off(dw, die), dwarf_errmsg(dw->dw_err));
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -368,10 +365,10 @@ die_unsigned(dwarf_t *dw, Dwarf_Die die, Dwarf_Half name, Dwarf_Unsigned *valp,
|
|||||||
int req)
|
int req)
|
||||||
{
|
{
|
||||||
*valp = 0;
|
*valp = 0;
|
||||||
if (dwarf_attrval_unsigned(die, name, valp, &dw->dw_err) != DWARF_E_NONE) {
|
if (dwarf_attrval_unsigned(die, name, valp, &dw->dw_err) != DW_DLV_OK) {
|
||||||
if (req)
|
if (req)
|
||||||
terminate("die %llu: failed to get unsigned: %s\n",
|
terminate("die %llu: failed to get unsigned: %s\n",
|
||||||
die_off(dw, die), dwarf_errmsg(&dw->dw_err));
|
die_off(dw, die), dwarf_errmsg(dw->dw_err));
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -383,10 +380,10 @@ die_bool(dwarf_t *dw, Dwarf_Die die, Dwarf_Half name, Dwarf_Bool *valp, int req)
|
|||||||
{
|
{
|
||||||
*valp = 0;
|
*valp = 0;
|
||||||
|
|
||||||
if (dwarf_attrval_flag(die, name, valp, &dw->dw_err) != DWARF_E_NONE) {
|
if (dwarf_attrval_flag(die, name, valp, &dw->dw_err) != DW_DLV_OK) {
|
||||||
if (req)
|
if (req)
|
||||||
terminate("die %llu: failed to get flag: %s\n",
|
terminate("die %llu: failed to get flag: %s\n",
|
||||||
die_off(dw, die), dwarf_errmsg(&dw->dw_err));
|
die_off(dw, die), dwarf_errmsg(dw->dw_err));
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -398,11 +395,11 @@ die_string(dwarf_t *dw, Dwarf_Die die, Dwarf_Half name, char **strp, int req)
|
|||||||
{
|
{
|
||||||
const char *str = NULL;
|
const char *str = NULL;
|
||||||
|
|
||||||
if (dwarf_attrval_string(die, name, &str, &dw->dw_err) != DWARF_E_NONE ||
|
if (dwarf_attrval_string(die, name, &str, &dw->dw_err) != DW_DLV_OK ||
|
||||||
str == NULL) {
|
str == NULL) {
|
||||||
if (req)
|
if (req)
|
||||||
terminate("die %llu: failed to get string: %s\n",
|
terminate("die %llu: failed to get string: %s\n",
|
||||||
die_off(dw, die), dwarf_errmsg(&dw->dw_err));
|
die_off(dw, die), dwarf_errmsg(dw->dw_err));
|
||||||
else
|
else
|
||||||
*strp = NULL;
|
*strp = NULL;
|
||||||
return (0);
|
return (0);
|
||||||
@ -417,9 +414,9 @@ die_attr_ref(dwarf_t *dw, Dwarf_Die die, Dwarf_Half name)
|
|||||||
{
|
{
|
||||||
Dwarf_Off off;
|
Dwarf_Off off;
|
||||||
|
|
||||||
if (dwarf_attrval_unsigned(die, name, &off, &dw->dw_err) != DWARF_E_NONE) {
|
if (dwarf_attrval_unsigned(die, name, &off, &dw->dw_err) != DW_DLV_OK) {
|
||||||
terminate("die %llu: failed to get ref: %s\n",
|
terminate("die %llu: failed to get ref: %s\n",
|
||||||
die_off(dw, die), dwarf_errmsg(&dw->dw_err));
|
die_off(dw, die), dwarf_errmsg(dw->dw_err));
|
||||||
}
|
}
|
||||||
|
|
||||||
return (off);
|
return (off);
|
||||||
@ -431,6 +428,8 @@ die_name(dwarf_t *dw, Dwarf_Die die)
|
|||||||
char *str = NULL;
|
char *str = NULL;
|
||||||
|
|
||||||
(void) die_string(dw, die, DW_AT_name, &str, 0);
|
(void) die_string(dw, die, DW_AT_name, &str, 0);
|
||||||
|
if (str == NULL)
|
||||||
|
str = xstrdup("");
|
||||||
|
|
||||||
return (str);
|
return (str);
|
||||||
}
|
}
|
||||||
@ -489,21 +488,73 @@ die_mem_offset(dwarf_t *dw, Dwarf_Die die, Dwarf_Half name,
|
|||||||
{
|
{
|
||||||
Dwarf_Locdesc *loc = NULL;
|
Dwarf_Locdesc *loc = NULL;
|
||||||
Dwarf_Signed locnum = 0;
|
Dwarf_Signed locnum = 0;
|
||||||
|
Dwarf_Attribute at;
|
||||||
|
Dwarf_Half form;
|
||||||
|
|
||||||
if (dwarf_locdesc(die, name, &loc, &locnum, &dw->dw_err) != DW_DLV_OK)
|
if (name != DW_AT_data_member_location)
|
||||||
|
terminate("die %llu: can only process attribute "
|
||||||
|
"DW_AT_data_member_location\n", die_off(dw, die));
|
||||||
|
|
||||||
|
if ((at = die_attr(dw, die, name, 0)) == NULL)
|
||||||
return (0);
|
return (0);
|
||||||
|
|
||||||
|
if (dwarf_whatform(at, &form, &dw->dw_err) != DW_DLV_OK)
|
||||||
|
return (0);
|
||||||
|
|
||||||
|
switch (form) {
|
||||||
|
case DW_FORM_sec_offset:
|
||||||
|
case DW_FORM_block:
|
||||||
|
case DW_FORM_block1:
|
||||||
|
case DW_FORM_block2:
|
||||||
|
case DW_FORM_block4:
|
||||||
|
/*
|
||||||
|
* GCC in base and Clang (3.3 or below) generates
|
||||||
|
* DW_AT_data_member_location attribute with DW_FORM_block*
|
||||||
|
* form. The attribute contains one DW_OP_plus_uconst
|
||||||
|
* operator. The member offset stores in the operand.
|
||||||
|
*/
|
||||||
|
if (dwarf_loclist(at, &loc, &locnum, &dw->dw_err) != DW_DLV_OK)
|
||||||
|
return (0);
|
||||||
if (locnum != 1 || loc->ld_s->lr_atom != DW_OP_plus_uconst) {
|
if (locnum != 1 || loc->ld_s->lr_atom != DW_OP_plus_uconst) {
|
||||||
terminate("die %llu: cannot parse member offset\n",
|
terminate("die %llu: cannot parse member offset with "
|
||||||
|
"operator other than DW_OP_plus_uconst\n",
|
||||||
die_off(dw, die));
|
die_off(dw, die));
|
||||||
}
|
}
|
||||||
|
|
||||||
*valp = loc->ld_s->lr_number;
|
*valp = loc->ld_s->lr_number;
|
||||||
|
if (loc != NULL) {
|
||||||
|
dwarf_dealloc(dw->dw_dw, loc->ld_s, DW_DLA_LOC_BLOCK);
|
||||||
|
dwarf_dealloc(dw->dw_dw, loc, DW_DLA_LOCDESC);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
if (loc != NULL)
|
case DW_FORM_data1:
|
||||||
if (dwarf_locdesc_free(loc, &dw->dw_err) != DW_DLV_OK)
|
case DW_FORM_data2:
|
||||||
terminate("die %llu: cannot free location descriptor: %s\n",
|
case DW_FORM_data4:
|
||||||
die_off(dw, die), dwarf_errmsg(&dw->dw_err));
|
case DW_FORM_data8:
|
||||||
|
case DW_FORM_udata:
|
||||||
|
/*
|
||||||
|
* Clang 3.4 generates DW_AT_data_member_location attribute
|
||||||
|
* with DW_FORM_data* form (constant class). The attribute
|
||||||
|
* stores a contant value which is the member offset.
|
||||||
|
*
|
||||||
|
* However, note that DW_FORM_data[48] in DWARF version 2 or 3
|
||||||
|
* could be used as a section offset (offset into .debug_loc in
|
||||||
|
* this case). Here we assume the attribute always stores a
|
||||||
|
* constant because we know Clang 3.4 does this and GCC in
|
||||||
|
* base won't emit DW_FORM_data[48] for this attribute. This
|
||||||
|
* code will remain correct if future vesrions of Clang and
|
||||||
|
* GCC conform to DWARF4 standard and only use the form
|
||||||
|
* DW_FORM_sec_offset for section offset.
|
||||||
|
*/
|
||||||
|
if (dwarf_attrval_unsigned(die, name, valp, &dw->dw_err) !=
|
||||||
|
DW_DLV_OK)
|
||||||
|
return (0);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
terminate("die %llu: cannot parse member offset with form "
|
||||||
|
"%u\n", die_off(dw, die), form);
|
||||||
|
}
|
||||||
|
|
||||||
return (1);
|
return (1);
|
||||||
}
|
}
|
||||||
@ -885,6 +936,9 @@ die_sou_create(dwarf_t *dw, Dwarf_Die str, Dwarf_Off off, tdesc_t *tdp,
|
|||||||
int type, const char *typename)
|
int type, const char *typename)
|
||||||
{
|
{
|
||||||
Dwarf_Unsigned sz, bitsz, bitoff, maxsz=0;
|
Dwarf_Unsigned sz, bitsz, bitoff, maxsz=0;
|
||||||
|
#if BYTE_ORDER == _LITTLE_ENDIAN
|
||||||
|
Dwarf_Unsigned bysz;
|
||||||
|
#endif
|
||||||
Dwarf_Die mem;
|
Dwarf_Die mem;
|
||||||
mlist_t *ml, **mlastp;
|
mlist_t *ml, **mlastp;
|
||||||
iidesc_t *ii;
|
iidesc_t *ii;
|
||||||
@ -959,8 +1013,26 @@ die_sou_create(dwarf_t *dw, Dwarf_Die str, Dwarf_Off off, tdesc_t *tdp,
|
|||||||
#if BYTE_ORDER == _BIG_ENDIAN
|
#if BYTE_ORDER == _BIG_ENDIAN
|
||||||
ml->ml_offset += bitoff;
|
ml->ml_offset += bitoff;
|
||||||
#else
|
#else
|
||||||
ml->ml_offset += tdesc_bitsize(ml->ml_type) - bitoff -
|
/*
|
||||||
|
* Note that Clang 3.4 will sometimes generate
|
||||||
|
* member DIE before generating the DIE for the
|
||||||
|
* member's type. The code can not handle this
|
||||||
|
* properly so that tdesc_bitsize(ml->ml_type) will
|
||||||
|
* return 0 because ml->ml_type is unknown. As a
|
||||||
|
* result, a wrong member offset will be calculated.
|
||||||
|
* To workaround this, we can instead try to
|
||||||
|
* retrieve the value of DW_AT_byte_size attribute
|
||||||
|
* which stores the byte size of the space occupied
|
||||||
|
* by the type. If this attribute exists, its value
|
||||||
|
* should equal to tdesc_bitsize(ml->ml_type)/NBBY.
|
||||||
|
*/
|
||||||
|
if (die_unsigned(dw, mem, DW_AT_byte_size, &bysz, 0) &&
|
||||||
|
bysz > 0)
|
||||||
|
ml->ml_offset += bysz * NBBY - bitoff -
|
||||||
ml->ml_size;
|
ml->ml_size;
|
||||||
|
else
|
||||||
|
ml->ml_offset += tdesc_bitsize(ml->ml_type) -
|
||||||
|
bitoff - ml->ml_size;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1852,7 +1924,7 @@ int
|
|||||||
dw_read(tdata_t *td, Elf *elf, char *filename __unused)
|
dw_read(tdata_t *td, Elf *elf, char *filename __unused)
|
||||||
{
|
{
|
||||||
Dwarf_Unsigned abboff, hdrlen, nxthdr;
|
Dwarf_Unsigned abboff, hdrlen, nxthdr;
|
||||||
Dwarf_Half vers, addrsz;
|
Dwarf_Half vers, addrsz, offsz;
|
||||||
Dwarf_Die cu = 0;
|
Dwarf_Die cu = 0;
|
||||||
Dwarf_Die child = 0;
|
Dwarf_Die child = 0;
|
||||||
dwarf_t dw;
|
dwarf_t dw;
|
||||||
@ -1869,7 +1941,7 @@ dw_read(tdata_t *td, Elf *elf, char *filename __unused)
|
|||||||
dw.dw_enumhash = hash_new(TDESC_HASH_BUCKETS, tdesc_namehash,
|
dw.dw_enumhash = hash_new(TDESC_HASH_BUCKETS, tdesc_namehash,
|
||||||
tdesc_namecmp);
|
tdesc_namecmp);
|
||||||
|
|
||||||
if ((rc = dwarf_elf_init(elf, DW_DLC_READ, &dw.dw_dw,
|
if ((rc = dwarf_elf_init(elf, DW_DLC_READ, NULL, NULL, &dw.dw_dw,
|
||||||
&dw.dw_err)) == DW_DLV_NO_ENTRY) {
|
&dw.dw_err)) == DW_DLV_NO_ENTRY) {
|
||||||
if (should_have_dwarf(elf)) {
|
if (should_have_dwarf(elf)) {
|
||||||
errno = ENOENT;
|
errno = ENOENT;
|
||||||
@ -1878,7 +1950,7 @@ dw_read(tdata_t *td, Elf *elf, char *filename __unused)
|
|||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
} else if (rc != DW_DLV_OK) {
|
} else if (rc != DW_DLV_OK) {
|
||||||
if (dwarf_errno(&dw.dw_err) == DW_DLE_DEBUG_INFO_NULL) {
|
if (dwarf_errno(dw.dw_err) == DW_DLE_DEBUG_INFO_NULL) {
|
||||||
/*
|
/*
|
||||||
* There's no type data in the DWARF section, but
|
* There's no type data in the DWARF section, but
|
||||||
* libdwarf is too clever to handle that properly.
|
* libdwarf is too clever to handle that properly.
|
||||||
@ -1887,12 +1959,12 @@ dw_read(tdata_t *td, Elf *elf, char *filename __unused)
|
|||||||
}
|
}
|
||||||
|
|
||||||
terminate("failed to initialize DWARF: %s\n",
|
terminate("failed to initialize DWARF: %s\n",
|
||||||
dwarf_errmsg(&dw.dw_err));
|
dwarf_errmsg(dw.dw_err));
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((rc = dwarf_next_cu_header(dw.dw_dw, &hdrlen, &vers, &abboff,
|
if ((rc = dwarf_next_cu_header_b(dw.dw_dw, &hdrlen, &vers, &abboff,
|
||||||
&addrsz, &nxthdr, &dw.dw_err)) != DW_DLV_OK)
|
&addrsz, &offsz, NULL, &nxthdr, &dw.dw_err)) != DW_DLV_OK)
|
||||||
terminate("rc = %d %s\n", rc, dwarf_errmsg(&dw.dw_err));
|
terminate("rc = %d %s\n", rc, dwarf_errmsg(dw.dw_err));
|
||||||
|
|
||||||
if ((cu = die_sibling(&dw, NULL)) == NULL ||
|
if ((cu = die_sibling(&dw, NULL)) == NULL ||
|
||||||
(((child = die_child(&dw, cu)) == NULL) &&
|
(((child = die_child(&dw, cu)) == NULL) &&
|
||||||
@ -1909,9 +1981,9 @@ dw_read(tdata_t *td, Elf *elf, char *filename __unused)
|
|||||||
terminate("file contains too many types\n");
|
terminate("file contains too many types\n");
|
||||||
|
|
||||||
debug(1, "DWARF version: %d\n", vers);
|
debug(1, "DWARF version: %d\n", vers);
|
||||||
if (vers != DWARF_VERSION) {
|
if (vers < 2 || vers > 4) {
|
||||||
terminate("file contains incompatible version %d DWARF code "
|
terminate("file contains incompatible version %d DWARF code "
|
||||||
"(version 2 required)\n", vers);
|
"(version 2, 3 or 4 required)\n", vers);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (die_string(&dw, cu, DW_AT_producer, &prod, 0)) {
|
if (die_string(&dw, cu, DW_AT_producer, &prod, 0)) {
|
||||||
@ -1930,11 +2002,11 @@ dw_read(tdata_t *td, Elf *elf, char *filename __unused)
|
|||||||
if ((child = die_child(&dw, cu)) != NULL)
|
if ((child = die_child(&dw, cu)) != NULL)
|
||||||
die_create(&dw, child);
|
die_create(&dw, child);
|
||||||
|
|
||||||
if ((rc = dwarf_next_cu_header(dw.dw_dw, &hdrlen, &vers, &abboff,
|
if ((rc = dwarf_next_cu_header_b(dw.dw_dw, &hdrlen, &vers, &abboff,
|
||||||
&addrsz, &nxthdr, &dw.dw_err)) != DW_DLV_NO_ENTRY)
|
&addrsz, &offsz, NULL, &nxthdr, &dw.dw_err)) != DW_DLV_NO_ENTRY)
|
||||||
terminate("multiple compilation units not supported\n");
|
terminate("multiple compilation units not supported\n");
|
||||||
|
|
||||||
(void) dwarf_finish(&dw.dw_dw, &dw.dw_err);
|
(void) dwarf_finish(dw.dw_dw, &dw.dw_err);
|
||||||
|
|
||||||
die_resolve(&dw);
|
die_resolve(&dw);
|
||||||
|
|
||||||
|
@ -11,7 +11,12 @@ SUBDIR= ${_drti} \
|
|||||||
libuutil \
|
libuutil \
|
||||||
${_libzfs_core} \
|
${_libzfs_core} \
|
||||||
${_libzfs} \
|
${_libzfs} \
|
||||||
${_libzpool}
|
${_libzpool} \
|
||||||
|
${_tests}
|
||||||
|
|
||||||
|
.if ${MK_TESTS} != "no"
|
||||||
|
_tests= tests
|
||||||
|
.endif
|
||||||
|
|
||||||
.if ${MK_ZFS} != "no"
|
.if ${MK_ZFS} != "no"
|
||||||
_libzfs_core= libzfs_core
|
_libzfs_core= libzfs_core
|
||||||
|
@ -27,5 +27,8 @@ CFLAGS+= -I${.CURDIR}/../../../sys/cddl/compat/opensolaris \
|
|||||||
-I${OPENSOLARIS_USR_DISTDIR}/lib/libctf/common \
|
-I${OPENSOLARIS_USR_DISTDIR}/lib/libctf/common \
|
||||||
-I${OPENSOLARIS_SYS_DISTDIR}/uts/common
|
-I${OPENSOLARIS_SYS_DISTDIR}/uts/common
|
||||||
|
|
||||||
|
DPADD= ${LIBZ}
|
||||||
|
LDADD= -lz
|
||||||
|
|
||||||
.include <bsd.lib.mk>
|
.include <bsd.lib.mk>
|
||||||
|
|
||||||
|
@ -69,9 +69,11 @@ CFLAGS+= -I${.OBJDIR} -I${.CURDIR} \
|
|||||||
#CFLAGS+= -DYYDEBUG
|
#CFLAGS+= -DYYDEBUG
|
||||||
|
|
||||||
.if ${MACHINE_CPUARCH} == "i386" || ${MACHINE_CPUARCH} == "amd64"
|
.if ${MACHINE_CPUARCH} == "i386" || ${MACHINE_CPUARCH} == "amd64"
|
||||||
|
CFLAGS+= -I${.CURDIR}/../../../sys/cddl/dev/dtrace/x86
|
||||||
CFLAGS+= -I${OPENSOLARIS_SYS_DISTDIR}/uts/intel -DDIS_MEM
|
CFLAGS+= -I${OPENSOLARIS_SYS_DISTDIR}/uts/intel -DDIS_MEM
|
||||||
.PATH: ${.CURDIR}/../../../cddl/contrib/opensolaris/lib/libdtrace/i386
|
.PATH: ${.CURDIR}/../../../cddl/contrib/opensolaris/lib/libdtrace/i386
|
||||||
.PATH: ${.CURDIR}/../../../sys/cddl/dev/dtrace/${MACHINE_ARCH}
|
.PATH: ${.CURDIR}/../../../sys/cddl/dev/dtrace/${MACHINE_ARCH}
|
||||||
|
.PATH: ${.CURDIR}/../../../sys/cddl/dev/dtrace/x86
|
||||||
.elif ${MACHINE_CPUARCH} == "sparc64"
|
.elif ${MACHINE_CPUARCH} == "sparc64"
|
||||||
CFLAGS+= -I${OPENSOLARIS_SYS_DISTDIR}/uts/sparc
|
CFLAGS+= -I${OPENSOLARIS_SYS_DISTDIR}/uts/sparc
|
||||||
.PATH: ${.CURDIR}/../../../cddl/contrib/opensolaris/lib/libdtrace/sparc
|
.PATH: ${.CURDIR}/../../../cddl/contrib/opensolaris/lib/libdtrace/sparc
|
||||||
|
@ -57,7 +57,8 @@ translator psinfo_t < struct proc *T > {
|
|||||||
pr_gid = T->p_ucred->cr_rgid;
|
pr_gid = T->p_ucred->cr_rgid;
|
||||||
pr_egid = T->p_ucred->cr_groups[0];
|
pr_egid = T->p_ucred->cr_groups[0];
|
||||||
pr_addr = 0;
|
pr_addr = 0;
|
||||||
pr_psargs = stringof(T->p_args->ar_args);
|
pr_psargs = (T->p_args->ar_args == 0) ? "" :
|
||||||
|
memstr(T->p_args->ar_args, ' ', T->p_args->ar_length);
|
||||||
pr_arglen = T->p_args->ar_length;
|
pr_arglen = T->p_args->ar_length;
|
||||||
pr_jailid = T->p_ucred->cr_prison->pr_id;
|
pr_jailid = T->p_ucred->cr_prison->pr_id;
|
||||||
};
|
};
|
||||||
|
@ -21,4 +21,13 @@ CFLAGS+= -I${.CURDIR}/../../../sys
|
|||||||
CFLAGS+= -I${.CURDIR}/../../../cddl/contrib/opensolaris/head
|
CFLAGS+= -I${.CURDIR}/../../../cddl/contrib/opensolaris/head
|
||||||
CFLAGS+= -I${.CURDIR}/../../../cddl/compat/opensolaris/lib/libumem
|
CFLAGS+= -I${.CURDIR}/../../../cddl/compat/opensolaris/lib/libumem
|
||||||
|
|
||||||
|
# This library uses macros to define fprintf behavior for several object types
|
||||||
|
# The compiler will see the non-string literal arguments to the fprintf calls and
|
||||||
|
# omit warnings for them. Quiesce these warnings in contrib code:
|
||||||
|
#
|
||||||
|
# cddl/contrib/opensolaris/lib/libnvpair/libnvpair.c:743:12: warning: format
|
||||||
|
# string is not a string literal (potentially insecure) [-Wformat-security]
|
||||||
|
# ARENDER(pctl, nvlist_array, nvl, name, val, nelem);
|
||||||
|
#
|
||||||
|
CFLAGS+= -Wno-format-security
|
||||||
.include <bsd.lib.mk>
|
.include <bsd.lib.mk>
|
||||||
|
@ -60,7 +60,7 @@ DPADD= ${LIBMD} ${LIBPTHREAD} ${LIBZ}
|
|||||||
LDADD= -lmd -lpthread -lz
|
LDADD= -lmd -lpthread -lz
|
||||||
|
|
||||||
# atomic.S doesn't like profiling.
|
# atomic.S doesn't like profiling.
|
||||||
NO_PROFILE=
|
MK_PROFILE= no
|
||||||
|
|
||||||
CSTD= c99
|
CSTD= c99
|
||||||
|
|
||||||
|
10
cddl/lib/tests/Makefile
Normal file
10
cddl/lib/tests/Makefile
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
# $FreeBSD$
|
||||||
|
|
||||||
|
.include <bsd.own.mk>
|
||||||
|
|
||||||
|
TESTSDIR= ${TESTSBASE}/cddl/lib
|
||||||
|
|
||||||
|
.PATH: ${.CURDIR:H:H:H}/tests
|
||||||
|
KYUAFILE= yes
|
||||||
|
|
||||||
|
.include <bsd.test.mk>
|
@ -2,7 +2,11 @@
|
|||||||
|
|
||||||
.include <bsd.own.mk>
|
.include <bsd.own.mk>
|
||||||
|
|
||||||
SUBDIR= ${_zfs} ${_zpool}
|
SUBDIR= ${_tests} ${_zfs} ${_zpool}
|
||||||
|
|
||||||
|
.if ${MK_TESTS} != "no"
|
||||||
|
_tests= tests
|
||||||
|
.endif
|
||||||
|
|
||||||
.if ${MK_ZFS} != "no"
|
.if ${MK_ZFS} != "no"
|
||||||
_zfs= zfs
|
_zfs= zfs
|
||||||
|
10
cddl/sbin/tests/Makefile
Normal file
10
cddl/sbin/tests/Makefile
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
# $FreeBSD$
|
||||||
|
|
||||||
|
.include <bsd.own.mk>
|
||||||
|
|
||||||
|
TESTSDIR= ${TESTSBASE}/cddl/sbin
|
||||||
|
|
||||||
|
.PATH: ${.CURDIR:H:H:H}/tests
|
||||||
|
KYUAFILE= yes
|
||||||
|
|
||||||
|
.include <bsd.test.mk>
|
10
cddl/tests/Makefile
Normal file
10
cddl/tests/Makefile
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
# $FreeBSD$
|
||||||
|
|
||||||
|
.include <bsd.own.mk>
|
||||||
|
|
||||||
|
TESTSDIR= ${TESTSBASE}/cddl
|
||||||
|
|
||||||
|
.PATH: ${.CURDIR:H:H}/tests
|
||||||
|
KYUAFILE= yes
|
||||||
|
|
||||||
|
.include <bsd.test.mk>
|
@ -7,11 +7,16 @@ SUBDIR= \
|
|||||||
ctfdump \
|
ctfdump \
|
||||||
ctfmerge \
|
ctfmerge \
|
||||||
sgsmsg \
|
sgsmsg \
|
||||||
|
${_tests} \
|
||||||
${_zinject} \
|
${_zinject} \
|
||||||
${_zlook} \
|
${_zlook} \
|
||||||
${_zstreamdump} \
|
${_zstreamdump} \
|
||||||
${_ztest}
|
${_ztest}
|
||||||
|
|
||||||
|
.if ${MK_TESTS} != "no"
|
||||||
|
_tests= tests
|
||||||
|
.endif
|
||||||
|
|
||||||
.if ${MK_ZFS} != "no"
|
.if ${MK_ZFS} != "no"
|
||||||
_zinject= zinject
|
_zinject= zinject
|
||||||
#_zlook= zlook
|
#_zlook= zlook
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
|
|
||||||
# This program is required as a bootstrap tool for 'make buildworld'
|
# This program is required as a bootstrap tool for 'make buildworld'
|
||||||
PROG= sgsmsg
|
PROG= sgsmsg
|
||||||
NO_MAN=
|
MAN=
|
||||||
SRCS= avl.c sgsmsg.c string_table.c findprime.c
|
SRCS= avl.c sgsmsg.c string_table.c findprime.c
|
||||||
|
|
||||||
WARNS?= 0
|
WARNS?= 0
|
||||||
|
10
cddl/usr.bin/tests/Makefile
Normal file
10
cddl/usr.bin/tests/Makefile
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
# $FreeBSD$
|
||||||
|
|
||||||
|
.include <bsd.own.mk>
|
||||||
|
|
||||||
|
TESTSDIR= ${TESTSBASE}/cddl/usr.bin
|
||||||
|
|
||||||
|
.PATH: ${.CURDIR:H:H:H}/tests
|
||||||
|
KYUAFILE= yes
|
||||||
|
|
||||||
|
.include <bsd.test.mk>
|
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
PROG= zinject
|
PROG= zinject
|
||||||
SRCS= zinject.c translate.c
|
SRCS= zinject.c translate.c
|
||||||
NO_MAN=
|
MAN=
|
||||||
|
|
||||||
WARNS?= 0
|
WARNS?= 0
|
||||||
CFLAGS+= -I${.CURDIR}/../../../sys/cddl/compat/opensolaris
|
CFLAGS+= -I${.CURDIR}/../../../sys/cddl/compat/opensolaris
|
||||||
@ -16,6 +16,7 @@ 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/fs/zfs
|
||||||
CFLAGS+= -I${.CURDIR}/../../../sys/cddl/contrib/opensolaris/uts/common/sys
|
CFLAGS+= -I${.CURDIR}/../../../sys/cddl/contrib/opensolaris/uts/common/sys
|
||||||
CFLAGS+= -I${.CURDIR}/../../../sys/cddl/contrib/opensolaris/uts/common
|
CFLAGS+= -I${.CURDIR}/../../../sys/cddl/contrib/opensolaris/uts/common
|
||||||
|
CFLAGS+= -I${.CURDIR}/../../../sys/cddl/contrib/opensolaris/common/zfs/
|
||||||
CFLAGS+= -I${.CURDIR}/../../contrib/opensolaris/head
|
CFLAGS+= -I${.CURDIR}/../../contrib/opensolaris/head
|
||||||
CFLAGS+= -I${.CURDIR}/../../lib/libumem
|
CFLAGS+= -I${.CURDIR}/../../lib/libumem
|
||||||
|
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
.PATH: ${.CURDIR}/../../contrib/opensolaris/cmd/zlook
|
.PATH: ${.CURDIR}/../../contrib/opensolaris/cmd/zlook
|
||||||
|
|
||||||
PROG= zlook
|
PROG= zlook
|
||||||
NO_MAN=
|
MAN=
|
||||||
|
|
||||||
WARNS?= 0
|
WARNS?= 0
|
||||||
CFLAGS+= -I${.CURDIR}/../../../sys/cddl/compat/opensolaris
|
CFLAGS+= -I${.CURDIR}/../../../sys/cddl/compat/opensolaris
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
.PATH: ${.CURDIR}/../..//contrib/opensolaris/cmd/ztest
|
.PATH: ${.CURDIR}/../..//contrib/opensolaris/cmd/ztest
|
||||||
|
|
||||||
PROG= ztest
|
PROG= ztest
|
||||||
NO_MAN=
|
MAN=
|
||||||
|
|
||||||
WARNS?= 0
|
WARNS?= 0
|
||||||
CFLAGS+= -I${.CURDIR}/../../../sys/cddl/compat/opensolaris
|
CFLAGS+= -I${.CURDIR}/../../../sys/cddl/compat/opensolaris
|
||||||
|
@ -5,9 +5,14 @@
|
|||||||
SUBDIR= ${_dtrace} \
|
SUBDIR= ${_dtrace} \
|
||||||
${_dtruss} \
|
${_dtruss} \
|
||||||
${_lockstat} \
|
${_lockstat} \
|
||||||
|
${_tests} \
|
||||||
${_zdb} \
|
${_zdb} \
|
||||||
${_zhack}
|
${_zhack}
|
||||||
|
|
||||||
|
.if ${MK_TESTS} != "no"
|
||||||
|
_tests= tests
|
||||||
|
.endif
|
||||||
|
|
||||||
.if ${MK_ZFS} != "no"
|
.if ${MK_ZFS} != "no"
|
||||||
.if ${MK_LIBTHR} != "no"
|
.if ${MK_LIBTHR} != "no"
|
||||||
_zdb= zdb
|
_zdb= zdb
|
||||||
|
@ -3,7 +3,6 @@
|
|||||||
.PATH: ${.CURDIR}/../../../cddl/contrib/opensolaris/cmd/lockstat
|
.PATH: ${.CURDIR}/../../../cddl/contrib/opensolaris/cmd/lockstat
|
||||||
|
|
||||||
PROG= lockstat
|
PROG= lockstat
|
||||||
NO_MAN=
|
|
||||||
SRCS= lockstat.c sym.c
|
SRCS= lockstat.c sym.c
|
||||||
BINDIR?= /usr/sbin
|
BINDIR?= /usr/sbin
|
||||||
|
|
||||||
|
10
cddl/usr.sbin/tests/Makefile
Normal file
10
cddl/usr.sbin/tests/Makefile
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
# $FreeBSD$
|
||||||
|
|
||||||
|
.include <bsd.own.mk>
|
||||||
|
|
||||||
|
TESTSDIR= ${TESTSBASE}/cddl/usr.sbin
|
||||||
|
|
||||||
|
.PATH: ${.CURDIR:H:H:H}/tests
|
||||||
|
KYUAFILE= yes
|
||||||
|
|
||||||
|
.include <bsd.test.mk>
|
@ -3,7 +3,7 @@
|
|||||||
.PATH: ${.CURDIR}/../../../cddl/contrib/opensolaris/cmd/zhack
|
.PATH: ${.CURDIR}/../../../cddl/contrib/opensolaris/cmd/zhack
|
||||||
|
|
||||||
PROG= zhack
|
PROG= zhack
|
||||||
NO_MAN=
|
MAN=
|
||||||
|
|
||||||
WARNS?= 0
|
WARNS?= 0
|
||||||
CSTD= c99
|
CSTD= c99
|
||||||
|
41
lib/Makefile
41
lib/Makefile
@ -32,8 +32,13 @@
|
|||||||
|
|
||||||
SUBDIR_ORDERED= ${_csu} \
|
SUBDIR_ORDERED= ${_csu} \
|
||||||
libc \
|
libc \
|
||||||
|
libc_nonshared \
|
||||||
libbsm \
|
libbsm \
|
||||||
libauditd \
|
libauditd \
|
||||||
|
libutil \
|
||||||
|
libpjdlog \
|
||||||
|
libnv \
|
||||||
|
${_libcapsicum} \
|
||||||
libcompiler_rt \
|
libcompiler_rt \
|
||||||
libcrypt \
|
libcrypt \
|
||||||
libelf \
|
libelf \
|
||||||
@ -48,7 +53,6 @@ SUBDIR_ORDERED= ${_csu} \
|
|||||||
librpcsvc \
|
librpcsvc \
|
||||||
libsbuf \
|
libsbuf \
|
||||||
libtacplus \
|
libtacplus \
|
||||||
libutil \
|
|
||||||
${_libypclnt} \
|
${_libypclnt} \
|
||||||
${_libcxxrt} \
|
${_libcxxrt} \
|
||||||
${_libcplusplus}
|
${_libcplusplus}
|
||||||
@ -65,9 +69,11 @@ SUBDIR= ${SUBDIR_ORDERED} \
|
|||||||
libblocksruntime \
|
libblocksruntime \
|
||||||
${_libbluetooth} \
|
${_libbluetooth} \
|
||||||
${_libbsnmp} \
|
${_libbsnmp} \
|
||||||
|
libbsdstat \
|
||||||
libbz2 \
|
libbz2 \
|
||||||
libcalendar \
|
libcalendar \
|
||||||
libcam \
|
libcam \
|
||||||
|
${_libcasper} \
|
||||||
libcompat \
|
libcompat \
|
||||||
libdevinfo \
|
libdevinfo \
|
||||||
libdevstat \
|
libdevstat \
|
||||||
@ -81,9 +87,7 @@ SUBDIR= ${SUBDIR_ORDERED} \
|
|||||||
${_libgpib} \
|
${_libgpib} \
|
||||||
${_libgssapi} \
|
${_libgssapi} \
|
||||||
${_librpcsec_gss} \
|
${_librpcsec_gss} \
|
||||||
${_libiconv_compat} \
|
|
||||||
libipsec \
|
libipsec \
|
||||||
${_libipx} \
|
|
||||||
libjail \
|
libjail \
|
||||||
libkiconv \
|
libkiconv \
|
||||||
liblzma \
|
liblzma \
|
||||||
@ -114,6 +118,7 @@ SUBDIR= ${SUBDIR_ORDERED} \
|
|||||||
${_libtelnet} \
|
${_libtelnet} \
|
||||||
${_libthr} \
|
${_libthr} \
|
||||||
libthread_db \
|
libthread_db \
|
||||||
|
libucl \
|
||||||
libufs \
|
libufs \
|
||||||
libugidfw \
|
libugidfw \
|
||||||
libulog \
|
libulog \
|
||||||
@ -124,10 +129,10 @@ SUBDIR= ${SUBDIR_ORDERED} \
|
|||||||
${_libvmmapi} \
|
${_libvmmapi} \
|
||||||
libwrap \
|
libwrap \
|
||||||
liby \
|
liby \
|
||||||
libyaml \
|
|
||||||
libz \
|
libz \
|
||||||
${_atf} \
|
${_atf} \
|
||||||
${_clang}
|
${_clang} \
|
||||||
|
${_tests}
|
||||||
|
|
||||||
.if exists(${.CURDIR}/csu/${MACHINE_ARCH}-elf)
|
.if exists(${.CURDIR}/csu/${MACHINE_ARCH}-elf)
|
||||||
_csu=csu/${MACHINE_ARCH}-elf
|
_csu=csu/${MACHINE_ARCH}-elf
|
||||||
@ -141,10 +146,6 @@ _csu=csu
|
|||||||
|
|
||||||
# NB: keep these sorted by MK_* knobs
|
# NB: keep these sorted by MK_* knobs
|
||||||
|
|
||||||
.if ${MK_ATF} != "no"
|
|
||||||
_atf= atf
|
|
||||||
.endif
|
|
||||||
|
|
||||||
.if ${MK_ATM} != "no"
|
.if ${MK_ATM} != "no"
|
||||||
_libngatm= libngatm
|
_libngatm= libngatm
|
||||||
.endif
|
.endif
|
||||||
@ -158,6 +159,11 @@ _libsdp= libsdp
|
|||||||
_libbsnmp= libbsnmp
|
_libbsnmp= libbsnmp
|
||||||
.endif
|
.endif
|
||||||
|
|
||||||
|
.if ${MK_CASPER} != "no"
|
||||||
|
_libcapsicum= libcapsicum
|
||||||
|
_libcasper= libcasper
|
||||||
|
.endif
|
||||||
|
|
||||||
.if ${MK_CLANG} != "no" && !defined(COMPAT_32BIT)
|
.if ${MK_CLANG} != "no" && !defined(COMPAT_32BIT)
|
||||||
_clang= clang
|
_clang= clang
|
||||||
.endif
|
.endif
|
||||||
@ -175,10 +181,6 @@ _librpcsec_gss= librpcsec_gss
|
|||||||
_libiconv_modules= libiconv_modules
|
_libiconv_modules= libiconv_modules
|
||||||
.endif
|
.endif
|
||||||
|
|
||||||
.if ${MK_IPX} != "no"
|
|
||||||
_libipx= libipx
|
|
||||||
.endif
|
|
||||||
|
|
||||||
.if ${MK_LDNS} != "no"
|
.if ${MK_LDNS} != "no"
|
||||||
_libldns= libldns
|
_libldns= libldns
|
||||||
.endif
|
.endif
|
||||||
@ -188,10 +190,6 @@ _libcxxrt= libcxxrt
|
|||||||
_libcplusplus= libc++
|
_libcplusplus= libc++
|
||||||
.endif
|
.endif
|
||||||
|
|
||||||
.if ${MK_LIBICONV_COMPAT} != "no"
|
|
||||||
_libiconv_compat= libiconv_compat
|
|
||||||
.endif
|
|
||||||
|
|
||||||
.if ${MK_LIBTHR} != "no"
|
.if ${MK_LIBTHR} != "no"
|
||||||
_libthr= libthr
|
_libthr= libthr
|
||||||
.endif
|
.endif
|
||||||
@ -258,6 +256,11 @@ _libsmutil= libsmutil
|
|||||||
_libtelnet= libtelnet
|
_libtelnet= libtelnet
|
||||||
.endif
|
.endif
|
||||||
|
|
||||||
|
.if ${MK_TESTS} != "no"
|
||||||
|
_atf= atf
|
||||||
|
_tests= tests
|
||||||
|
.endif
|
||||||
|
|
||||||
.if ${MK_UNBOUND} != "no"
|
.if ${MK_UNBOUND} != "no"
|
||||||
_libunbound= libunbound
|
_libunbound= libunbound
|
||||||
.endif
|
.endif
|
||||||
@ -272,4 +275,8 @@ afterinstall:
|
|||||||
${INSTALL_SYMLINK} ../include ${DESTDIR}/usr/lib/include
|
${INSTALL_SYMLINK} ../include ${DESTDIR}/usr/lib/include
|
||||||
.endif
|
.endif
|
||||||
|
|
||||||
|
.if !make(install)
|
||||||
|
SUBDIR_PARALLEL=
|
||||||
|
.endif
|
||||||
|
|
||||||
.include <bsd.subdir.mk>
|
.include <bsd.subdir.mk>
|
||||||
|
@ -27,9 +27,13 @@
|
|||||||
|
|
||||||
.include <bsd.own.mk>
|
.include <bsd.own.mk>
|
||||||
|
|
||||||
SUBDIR= \
|
SUBDIR= libatf-c \
|
||||||
libatf-c \
|
libatf-c++ \
|
||||||
libatf-c++
|
${_tests}
|
||||||
|
|
||||||
|
.if ${MK_TESTS} != "no"
|
||||||
|
_tests= tests
|
||||||
|
.endif
|
||||||
|
|
||||||
.ORDER: ${SUBDIR}
|
.ORDER: ${SUBDIR}
|
||||||
|
|
||||||
|
@ -25,8 +25,6 @@
|
|||||||
#
|
#
|
||||||
# $FreeBSD$
|
# $FreeBSD$
|
||||||
|
|
||||||
ATF= ${.CURDIR}/../../../contrib/atf
|
|
||||||
|
|
||||||
_CFLAGS:= ${CFLAGS}
|
_CFLAGS:= ${CFLAGS}
|
||||||
_CPPFLAGS:= ${CPPFLAGS}
|
_CPPFLAGS:= ${CPPFLAGS}
|
||||||
_CXXFLAGS:= ${CXXFLAGS}
|
_CXXFLAGS:= ${CXXFLAGS}
|
||||||
@ -40,6 +38,7 @@ CFLAGS+= -DATF_BUILD_CPPFLAGS='"${_CPPFLAGS}"'
|
|||||||
CFLAGS+= -DATF_BUILD_CXX='"${CXX}"'
|
CFLAGS+= -DATF_BUILD_CXX='"${CXX}"'
|
||||||
CFLAGS+= -DATF_BUILD_CXXFLAGS='"${_CXXFLAGS}"'
|
CFLAGS+= -DATF_BUILD_CXXFLAGS='"${_CXXFLAGS}"'
|
||||||
CFLAGS+= -DATF_CONFDIR='"${CONFDIR}/atf"'
|
CFLAGS+= -DATF_CONFDIR='"${CONFDIR}/atf"'
|
||||||
|
CFLAGS+= -DATF_C_TESTS_BASE='"${TESTSBASE}/lib/atf/libatf-c"'
|
||||||
CFLAGS+= -DATF_INCLUDEDIR='"${INCLUDEDIR}"'
|
CFLAGS+= -DATF_INCLUDEDIR='"${INCLUDEDIR}"'
|
||||||
CFLAGS+= -DATF_LIBDIR='"${LIBDIR}"'
|
CFLAGS+= -DATF_LIBDIR='"${LIBDIR}"'
|
||||||
CFLAGS+= -DATF_LIBEXECDIR='"${LIBEXECDIR}"'
|
CFLAGS+= -DATF_LIBEXECDIR='"${LIBEXECDIR}"'
|
||||||
|
19
lib/atf/common.mk
Normal file
19
lib/atf/common.mk
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
# $FreeBSD$
|
||||||
|
#
|
||||||
|
# Common Makefile code for all components of ATF.
|
||||||
|
#
|
||||||
|
|
||||||
|
.if !defined(ATF)
|
||||||
|
.error "ATF must be defined and point to the contrib/atf directory"
|
||||||
|
.endif
|
||||||
|
|
||||||
|
# Depend on the atf-version target to generate a file that contains the
|
||||||
|
# version number of the currently imported ATF release and that only
|
||||||
|
# changes on new imports.
|
||||||
|
atf-version: atf-version-real
|
||||||
|
@cmp -s atf-version atf-version-real \
|
||||||
|
|| cp atf-version-real atf-version
|
||||||
|
atf-version-real: .PHONY
|
||||||
|
@grep 'define VERSION' ${ATF}/bconfig.h \
|
||||||
|
| cut -d '"' -f 2 >atf-version-real
|
||||||
|
CLEANFILES+= atf-version atf-version-real
|
@ -28,7 +28,7 @@
|
|||||||
.include <bsd.init.mk>
|
.include <bsd.init.mk>
|
||||||
|
|
||||||
LIB= atf-c++
|
LIB= atf-c++
|
||||||
SHLIB_MAJOR= 1
|
SHLIB_MAJOR= 2
|
||||||
|
|
||||||
# libatf-c++ depends on the C version of the ATF library to build.
|
# libatf-c++ depends on the C version of the ATF library to build.
|
||||||
DPADD= ${LIBATFC}
|
DPADD= ${LIBATFC}
|
||||||
@ -36,6 +36,7 @@ LDADD= -latf-c
|
|||||||
|
|
||||||
LDFLAGS+= -L${.OBJDIR}/../libatf-c
|
LDFLAGS+= -L${.OBJDIR}/../libatf-c
|
||||||
|
|
||||||
|
ATF= ${.CURDIR:H:H:H}/contrib/atf
|
||||||
.PATH: ${ATF}
|
.PATH: ${ATF}
|
||||||
.PATH: ${ATF}/atf-c++
|
.PATH: ${ATF}/atf-c++
|
||||||
.PATH: ${ATF}/atf-c++/detail
|
.PATH: ${ATF}/atf-c++/detail
|
||||||
@ -52,13 +53,11 @@ SRCS= application.cpp \
|
|||||||
config.cpp \
|
config.cpp \
|
||||||
env.cpp \
|
env.cpp \
|
||||||
exceptions.cpp \
|
exceptions.cpp \
|
||||||
expand.cpp \
|
|
||||||
fs.cpp \
|
fs.cpp \
|
||||||
parser.cpp \
|
|
||||||
process.cpp \
|
process.cpp \
|
||||||
tests.cpp \
|
tests.cpp \
|
||||||
text.cpp \
|
text.cpp \
|
||||||
ui.cpp
|
utils.cpp
|
||||||
|
|
||||||
INCS= build.hpp \
|
INCS= build.hpp \
|
||||||
check.hpp \
|
check.hpp \
|
||||||
@ -73,4 +72,23 @@ INCSDIR_atf-c++.hpp= ${INCLUDEDIR}
|
|||||||
|
|
||||||
MAN= atf-c++-api.3
|
MAN= atf-c++-api.3
|
||||||
|
|
||||||
|
all: atf-c++.pc
|
||||||
|
atf-c++.pc: atf-c++.pc.in atf-version
|
||||||
|
sed -e 's,__CXX__,${CXX},g' \
|
||||||
|
-e 's,__INCLUDEDIR__,${INCLUDEDIR},g' \
|
||||||
|
-e 's,__LIBDIR__,${LIBDIR},g' \
|
||||||
|
-e "s,__ATF_VERSION__,$$(cat atf-version),g" \
|
||||||
|
<${ATF}/atf-c++/atf-c++.pc.in >atf-c++.pc
|
||||||
|
|
||||||
|
beforeinstall:
|
||||||
|
${INSTALL} -C -o ${LIBOWN} -g ${LIBGRP} -m ${LIBMODE} \
|
||||||
|
atf-c++.pc ${DESTDIR}${LIBDATADIR}/pkgconfig
|
||||||
|
${INSTALL} -C -o ${SHAREOWN} -g ${SHAREGRP} -m ${SHAREMODE} \
|
||||||
|
${ATF}/atf-c++/atf-c++.m4 ${DESTDIR}${SHAREDIR}/aclocal
|
||||||
|
|
||||||
|
.if ${MK_TESTS} != "no"
|
||||||
|
SUBDIR= tests
|
||||||
|
.endif
|
||||||
|
|
||||||
|
.include "../common.mk"
|
||||||
.include <bsd.lib.mk>
|
.include <bsd.lib.mk>
|
||||||
|
3
lib/atf/libatf-c++/Makefile.inc
Normal file
3
lib/atf/libatf-c++/Makefile.inc
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
# $FreeBSD$
|
||||||
|
|
||||||
|
.include "../Makefile.inc"
|
31
lib/atf/libatf-c++/tests/Makefile
Normal file
31
lib/atf/libatf-c++/tests/Makefile
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
# $FreeBSD$
|
||||||
|
|
||||||
|
.include <bsd.init.mk>
|
||||||
|
|
||||||
|
TESTSDIR= ${TESTSBASE}/lib/atf/libatf-c++
|
||||||
|
TESTS_SUBDIRS= detail
|
||||||
|
|
||||||
|
ATF= ${.CURDIR:H:H:H:H}/contrib/atf
|
||||||
|
.PATH: ${ATF}/atf-c++
|
||||||
|
.PATH: ${ATF}/atf-c++/detail
|
||||||
|
|
||||||
|
CFLAGS+= -I${ATF}
|
||||||
|
|
||||||
|
FILESDIR= ${TESTSDIR}
|
||||||
|
FILES= macros_hpp_test.cpp
|
||||||
|
FILES+= unused_test.cpp
|
||||||
|
|
||||||
|
.for _T in atf_c++_test \
|
||||||
|
build_test \
|
||||||
|
check_test \
|
||||||
|
config_test \
|
||||||
|
macros_test \
|
||||||
|
tests_test \
|
||||||
|
utils_test
|
||||||
|
ATF_TESTS_CXX+= ${_T}
|
||||||
|
SRCS.${_T}= ${_T}.cpp test_helpers.cpp
|
||||||
|
.endfor
|
||||||
|
|
||||||
|
ATF_TESTS_SH= pkg_config_test
|
||||||
|
|
||||||
|
.include <bsd.test.mk>
|
3
lib/atf/libatf-c++/tests/Makefile.inc
Normal file
3
lib/atf/libatf-c++/tests/Makefile.inc
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
# $FreeBSD$
|
||||||
|
|
||||||
|
.include "../Makefile.inc"
|
32
lib/atf/libatf-c++/tests/detail/Makefile
Normal file
32
lib/atf/libatf-c++/tests/detail/Makefile
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
# $FreeBSD$
|
||||||
|
|
||||||
|
.include <bsd.init.mk>
|
||||||
|
|
||||||
|
TESTSDIR= ${TESTSBASE}/lib/atf/libatf-c++/detail
|
||||||
|
|
||||||
|
ATF= ${.CURDIR:H:H:H:H:H}/contrib/atf
|
||||||
|
.PATH: ${ATF}/atf-c++/detail
|
||||||
|
|
||||||
|
CFLAGS+= -I${ATF}
|
||||||
|
|
||||||
|
.for _T in application_test \
|
||||||
|
env_test \
|
||||||
|
exceptions_test \
|
||||||
|
fs_test \
|
||||||
|
process_test \
|
||||||
|
sanity_test \
|
||||||
|
text_test
|
||||||
|
ATF_TESTS_CXX+= ${_T}
|
||||||
|
SRCS.${_T}= ${_T}.cpp test_helpers.cpp
|
||||||
|
.endfor
|
||||||
|
|
||||||
|
.for p in version_helper
|
||||||
|
PROGS_CXX+= ${p}
|
||||||
|
SRCS.${p}= ${p}.cpp
|
||||||
|
MAN.${p}= # defined
|
||||||
|
BINDIR.${p}= ${TESTSDIR}
|
||||||
|
.endfor
|
||||||
|
version_helper.o: atf-version
|
||||||
|
|
||||||
|
.include "../../../common.mk"
|
||||||
|
.include <bsd.test.mk>
|
@ -30,6 +30,7 @@
|
|||||||
LIB= atf-c
|
LIB= atf-c
|
||||||
SHLIB_MAJOR= 1
|
SHLIB_MAJOR= 1
|
||||||
|
|
||||||
|
ATF= ${.CURDIR:H:H:H}/contrib/atf
|
||||||
.PATH: ${ATF}
|
.PATH: ${ATF}
|
||||||
.PATH: ${ATF}/atf-c
|
.PATH: ${ATF}/atf-c
|
||||||
.PATH: ${ATF}/atf-c/detail
|
.PATH: ${ATF}/atf-c/detail
|
||||||
@ -73,4 +74,25 @@ INCSDIR_atf-c.h= ${INCLUDEDIR}
|
|||||||
|
|
||||||
MAN= atf-c-api.3
|
MAN= atf-c-api.3
|
||||||
|
|
||||||
|
all: atf-c.pc
|
||||||
|
atf-c.pc: atf-c.pc.in atf-version
|
||||||
|
sed -e 's,__CC__,${CC},g' \
|
||||||
|
-e 's,__INCLUDEDIR__,${INCLUDEDIR},g' \
|
||||||
|
-e 's,__LIBDIR__,${LIBDIR},g' \
|
||||||
|
-e "s,__ATF_VERSION__,$$(cat atf-version),g" \
|
||||||
|
<${ATF}/atf-c/atf-c.pc.in >atf-c.pc
|
||||||
|
|
||||||
|
beforeinstall:
|
||||||
|
${INSTALL} -C -o ${LIBOWN} -g ${LIBGRP} -m ${LIBMODE} \
|
||||||
|
atf-c.pc ${DESTDIR}${LIBDATADIR}/pkgconfig
|
||||||
|
${INSTALL} -C -o ${SHAREOWN} -g ${SHAREGRP} -m ${SHAREMODE} \
|
||||||
|
${ATF}/atf-c/atf-common.m4 ${DESTDIR}${SHAREDIR}/aclocal
|
||||||
|
${INSTALL} -C -o ${SHAREOWN} -g ${SHAREGRP} -m ${SHAREMODE} \
|
||||||
|
${ATF}/atf-c/atf-c.m4 ${DESTDIR}${SHAREDIR}/aclocal
|
||||||
|
|
||||||
|
.if ${MK_TESTS} != "no"
|
||||||
|
SUBDIR= tests
|
||||||
|
.endif
|
||||||
|
|
||||||
|
.include "../common.mk"
|
||||||
.include <bsd.lib.mk>
|
.include <bsd.lib.mk>
|
||||||
|
3
lib/atf/libatf-c/Makefile.inc
Normal file
3
lib/atf/libatf-c/Makefile.inc
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
# $FreeBSD$
|
||||||
|
|
||||||
|
.include "../Makefile.inc"
|
38
lib/atf/libatf-c/tests/Makefile
Normal file
38
lib/atf/libatf-c/tests/Makefile
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
# $FreeBSD$
|
||||||
|
|
||||||
|
.include <bsd.init.mk>
|
||||||
|
|
||||||
|
TESTSDIR= ${TESTSBASE}/lib/atf/libatf-c
|
||||||
|
TESTS_SUBDIRS= detail
|
||||||
|
|
||||||
|
ATF= ${.CURDIR:H:H:H:H}/contrib/atf
|
||||||
|
.PATH: ${ATF}/atf-c
|
||||||
|
.PATH: ${ATF}/atf-c/detail
|
||||||
|
|
||||||
|
CFLAGS+= -I${ATF}
|
||||||
|
|
||||||
|
# macros_test.c contains a double 'const const' which will be gone with
|
||||||
|
# the import of atf-0.18.
|
||||||
|
# TODO(jmmv): Remove this workaround once we do that update.
|
||||||
|
CFLAGS.clang+= -Wno-duplicate-decl-specifier
|
||||||
|
|
||||||
|
FILESDIR= ${TESTSDIR}
|
||||||
|
FILES= macros_h_test.c
|
||||||
|
FILES+= unused_test.c
|
||||||
|
|
||||||
|
.for _T in atf_c_test \
|
||||||
|
build_test \
|
||||||
|
check_test \
|
||||||
|
config_test \
|
||||||
|
error_test \
|
||||||
|
macros_test \
|
||||||
|
tc_test \
|
||||||
|
tp_test \
|
||||||
|
utils_test
|
||||||
|
ATF_TESTS_C+= ${_T}
|
||||||
|
SRCS.${_T}= ${_T}.c test_helpers.c
|
||||||
|
.endfor
|
||||||
|
|
||||||
|
ATF_TESTS_SH= pkg_config_test
|
||||||
|
|
||||||
|
.include <bsd.test.mk>
|
3
lib/atf/libatf-c/tests/Makefile.inc
Normal file
3
lib/atf/libatf-c/tests/Makefile.inc
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
# $FreeBSD$
|
||||||
|
|
||||||
|
.include "../Makefile.inc"
|
34
lib/atf/libatf-c/tests/detail/Makefile
Normal file
34
lib/atf/libatf-c/tests/detail/Makefile
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
# $FreeBSD$
|
||||||
|
|
||||||
|
.include <bsd.init.mk>
|
||||||
|
|
||||||
|
TESTSDIR= ${TESTSBASE}/lib/atf/libatf-c/detail
|
||||||
|
|
||||||
|
ATF= ${.CURDIR:H:H:H:H:H}/contrib/atf
|
||||||
|
.PATH: ${ATF}/atf-c/detail
|
||||||
|
|
||||||
|
CFLAGS+= -I${ATF}
|
||||||
|
|
||||||
|
.for _T in dynstr_test \
|
||||||
|
env_test \
|
||||||
|
fs_test \
|
||||||
|
list_test \
|
||||||
|
map_test \
|
||||||
|
process_test \
|
||||||
|
sanity_test \
|
||||||
|
text_test \
|
||||||
|
user_test
|
||||||
|
ATF_TESTS_C+= ${_T}
|
||||||
|
SRCS.${_T}= ${_T}.c test_helpers.c
|
||||||
|
.endfor
|
||||||
|
|
||||||
|
.for p in process_helpers version_helper
|
||||||
|
PROGS+= ${p}
|
||||||
|
SRCS.${p}= ${p}.c
|
||||||
|
MAN.${p}= # defined
|
||||||
|
BINDIR.${p}= ${TESTSDIR}
|
||||||
|
.endfor
|
||||||
|
version_helper.o: atf-version
|
||||||
|
|
||||||
|
.include "../../../common.mk"
|
||||||
|
.include <bsd.test.mk>
|
12
lib/atf/tests/Makefile
Normal file
12
lib/atf/tests/Makefile
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
# $FreeBSD$
|
||||||
|
|
||||||
|
.include <bsd.own.mk>
|
||||||
|
|
||||||
|
TESTSDIR= ${TESTSBASE}/lib/atf
|
||||||
|
|
||||||
|
.PATH: ${.CURDIR:H:H:H}/tests
|
||||||
|
KYUAFILE= yes
|
||||||
|
|
||||||
|
SUBDIR= test-programs
|
||||||
|
|
||||||
|
.include <bsd.test.mk>
|
24
lib/atf/tests/test-programs/Makefile
Normal file
24
lib/atf/tests/test-programs/Makefile
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
# $FreeBSD$
|
||||||
|
|
||||||
|
.include <bsd.init.mk>
|
||||||
|
|
||||||
|
TESTSDIR= ${TESTSBASE}/lib/atf/test-programs
|
||||||
|
KYUAFILE= yes
|
||||||
|
|
||||||
|
ATF= ${.CURDIR:H:H:H:H}/contrib/atf
|
||||||
|
.PATH: ${ATF}/test-programs
|
||||||
|
|
||||||
|
CFLAGS+= -I${ATF}
|
||||||
|
|
||||||
|
ATF_TESTS_C= c_helpers
|
||||||
|
|
||||||
|
ATF_TESTS_CXX= cpp_helpers
|
||||||
|
SRCS.cpp_helpers= cpp_helpers.cpp
|
||||||
|
|
||||||
|
ATF_TESTS_SH= sh_helpers
|
||||||
|
.for _T in config_test expect_test meta_data_test result_test srcdir_test
|
||||||
|
ATF_TESTS_SH+= ${_T}
|
||||||
|
ATF_TESTS_SH_SRC_${_T}= common.sh ${_T}.sh
|
||||||
|
.endfor
|
||||||
|
|
||||||
|
.include <bsd.test.mk>
|
@ -123,7 +123,7 @@ static const struct {
|
|||||||
char desc[sizeof(MACHINE_ARCH)];
|
char desc[sizeof(MACHINE_ARCH)];
|
||||||
} archtag __attribute__ ((section (NOTE_SECTION), aligned(4))) __used = {
|
} archtag __attribute__ ((section (NOTE_SECTION), aligned(4))) __used = {
|
||||||
.namesz = sizeof(NOTE_FREEBSD_VENDOR),
|
.namesz = sizeof(NOTE_FREEBSD_VENDOR),
|
||||||
.descsz = sizeof(int32_t),
|
.descsz = sizeof(MACHINE_ARCH),
|
||||||
.type = ARCH_NOTETYPE,
|
.type = ARCH_NOTETYPE,
|
||||||
.name = NOTE_FREEBSD_VENDOR,
|
.name = NOTE_FREEBSD_VENDOR,
|
||||||
.desc = MACHINE_ARCH
|
.desc = MACHINE_ARCH
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
LIBARCHIVEDIR= ${.CURDIR}/../../../contrib/libarchive
|
LIBARCHIVEDIR= ${.CURDIR}/../../../contrib/libarchive
|
||||||
|
|
||||||
NO_MAN=yes
|
MAN=
|
||||||
|
|
||||||
PROG=libarchive_test
|
PROG=libarchive_test
|
||||||
INTERNALPROG=yes # Don't install this; it's just for testing
|
INTERNALPROG=yes # Don't install this; it's just for testing
|
||||||
|
@ -19,6 +19,6 @@ CFLAGS+= -I${OPENBSMDIR} -I${LIBBSMDIR}
|
|||||||
|
|
||||||
WARNS?= 3
|
WARNS?= 3
|
||||||
|
|
||||||
NO_MAN=
|
MAN=
|
||||||
|
|
||||||
.include <bsd.lib.mk>
|
.include <bsd.lib.mk>
|
||||||
|
10
lib/libbsdstat/Makefile
Normal file
10
lib/libbsdstat/Makefile
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
# $FreeBSD$
|
||||||
|
|
||||||
|
LIB= bsdstat
|
||||||
|
SHLIB_MAJOR= 1
|
||||||
|
PRIVATELIB=
|
||||||
|
|
||||||
|
SRCS= bsdstat.c
|
||||||
|
INCS= bsdstat.h
|
||||||
|
|
||||||
|
.include <bsd.lib.mk>
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user