]> git.proxmox.com Git - mirror_zfs-debian.git/commitdiff
New upstream version 0.7.6
authorAron Xu <happyaron.xu@gmail.com>
Mon, 26 Feb 2018 08:29:27 +0000 (16:29 +0800)
committerAron Xu <happyaron.xu@gmail.com>
Mon, 26 Feb 2018 08:29:27 +0000 (16:29 +0800)
57 files changed:
META
Makefile.am
Makefile.in
cmd/arc_summary/arc_summary.py
cmd/zed/zed.d/zed-functions.sh
cmd/zhack/zhack.c
cmd/zpool/zpool_vdev.c
config/deb.am
config/kernel-vfs-rw-iterate.m4
configure
etc/init.d/Makefile.am
etc/init.d/Makefile.in
include/sys/arc.h
include/sys/dmu.h
include/sys/dmu_tx.h
include/sys/vdev.h
include/sys/vdev_impl.h
include/sys/vdev_raidz_impl.h
lib/libshare/libshare.c
lib/libzfs/libzfs.pc
lib/libzfs/libzfs_core.pc
lib/libzfs/libzfs_dataset.c
lib/libzfs/libzfs_import.c
lib/libzfs/libzfs_sendrecv.c
man/man5/zfs-module-parameters.5
module/zfs/abd.c
module/zfs/arc.c
module/zfs/dbuf.c
module/zfs/dmu_objset.c
module/zfs/dmu_tx.c
module/zfs/dmu_zfetch.c
module/zfs/vdev_mirror.c
module/zfs/vdev_queue.c
module/zfs/zfs_dir.c
module/zfs/zfs_ioctl.c
module/zfs/zfs_vnops.c
module/zfs/zpl_xattr.c
module/zfs/zvol.c
rpm/generic/zfs-kmod.spec.in
rpm/generic/zfs.spec.in
rpm/redhat/zfs.spec.in
scripts/cstyle.pl
scripts/zloop.sh
tests/runfiles/linux.run
tests/zfs-tests/include/Makefile.am
tests/zfs-tests/include/Makefile.in
tests/zfs-tests/include/libtest.shlib
tests/zfs-tests/tests/functional/acl/acl_common.kshlib
tests/zfs-tests/tests/functional/cli_root/zfs_receive/receive-o-x_props_override.ksh
tests/zfs-tests/tests/functional/cli_root/zpool_add/Makefile.am
tests/zfs-tests/tests/functional/cli_root/zpool_add/Makefile.in
tests/zfs-tests/tests/functional/cli_root/zpool_add/add_nested_replacing_spare.ksh [new file with mode: 0755]
tests/zfs-tests/tests/functional/cli_user/misc/Makefile.am
tests/zfs-tests/tests/functional/cli_user/misc/Makefile.in
tests/zfs-tests/tests/functional/cli_user/misc/arc_summary_001_pos.ksh
tests/zfs-tests/tests/functional/cli_user/misc/arc_summary_002_neg.ksh [new file with mode: 0755]
zfs_config.h.in

diff --git a/META b/META
index 8bcb520b6479075c38774997cae6c66e00460773..1f4686df7fd0a83a0fd9631f23cd09edaa3aee27 100644 (file)
--- a/META
+++ b/META
@@ -1,7 +1,7 @@
 Meta:         1
 Name:         zfs
 Branch:       1.0
 Meta:         1
 Name:         zfs
 Branch:       1.0
-Version:      0.7.5
+Version:      0.7.6
 Release:      1
 Release-Tags: relext
 License:      CDDL
 Release:      1
 Release-Tags: relext
 License:      CDDL
index e46ac2dbe5aaf9e654666f430fa074b502abab09..508d3f40e87693f38e14b68703c995d8c130f6ba 100644 (file)
@@ -65,10 +65,10 @@ lint: cppcheck paxcheck
 
 cppcheck:
        @if type cppcheck > /dev/null 2>&1; then \
 
 cppcheck:
        @if type cppcheck > /dev/null 2>&1; then \
-               cppcheck --quiet --force --error-exitcode=2 \
+               cppcheck --quiet --force --error-exitcode=2 --inline-suppr \
                        --suppressions-list=.github/suppressions.txt \
                        --suppressions-list=.github/suppressions.txt \
-                       -UHAVE_SSE2 -UHAVE_AVX512F \
-                       ${top_srcdir}; \
+                       -UHAVE_SSE2 -UHAVE_AVX512F -UHAVE_UIO_ZEROCOPY \
+                       -UHAVE_DNLC ${top_srcdir}; \
        fi
 
 paxcheck:
        fi
 
 paxcheck:
index f40b3052576b83e7498eeab15ad69bfba81c88d6..26172c11aece93c1f071cb8128081079b864045f 100644 (file)
@@ -1139,22 +1139,25 @@ deb-kmod: deb-local rpm-kmod
        name=${PACKAGE}; \
        version=${VERSION}-${RELEASE}; \
        arch=`$(RPM) -qp $${name}-kmod-$${version}.src.rpm --qf %{arch} | tail -1`; \
        name=${PACKAGE}; \
        version=${VERSION}-${RELEASE}; \
        arch=`$(RPM) -qp $${name}-kmod-$${version}.src.rpm --qf %{arch} | tail -1`; \
+       debarch=`$(DPKG) --print-architecture`; \
        pkg1=kmod-$${name}*$${version}.$${arch}.rpm; \
        pkg1=kmod-$${name}*$${version}.$${arch}.rpm; \
-       fakeroot $(ALIEN) --bump=0 --scripts --to-deb $$pkg1; \
+       fakeroot $(ALIEN) --bump=0 --scripts --to-deb --target=$$debarch $$pkg1; \
        $(RM) $$pkg1
 
 deb-dkms: deb-local rpm-dkms
        name=${PACKAGE}; \
        version=${VERSION}-${RELEASE}; \
        arch=`$(RPM) -qp $${name}-dkms-$${version}.src.rpm --qf %{arch} | tail -1`; \
        $(RM) $$pkg1
 
 deb-dkms: deb-local rpm-dkms
        name=${PACKAGE}; \
        version=${VERSION}-${RELEASE}; \
        arch=`$(RPM) -qp $${name}-dkms-$${version}.src.rpm --qf %{arch} | tail -1`; \
+       debarch=`$(DPKG) --print-architecture`; \
        pkg1=$${name}-dkms-$${version}.$${arch}.rpm; \
        pkg1=$${name}-dkms-$${version}.$${arch}.rpm; \
-       fakeroot $(ALIEN) --bump=0 --scripts --to-deb $$pkg1; \
+       fakeroot $(ALIEN) --bump=0 --scripts --to-deb --target=$$debarch $$pkg1; \
        $(RM) $$pkg1
 
 deb-utils: deb-local rpm-utils
        name=${PACKAGE}; \
        version=${VERSION}-${RELEASE}; \
        arch=`$(RPM) -qp $${name}-$${version}.src.rpm --qf %{arch} | tail -1`; \
        $(RM) $$pkg1
 
 deb-utils: deb-local rpm-utils
        name=${PACKAGE}; \
        version=${VERSION}-${RELEASE}; \
        arch=`$(RPM) -qp $${name}-$${version}.src.rpm --qf %{arch} | tail -1`; \
+       debarch=`$(DPKG) --print-architecture`; \
        pkg1=$${name}-$${version}.$${arch}.rpm; \
        pkg2=libnvpair1-$${version}.$${arch}.rpm; \
        pkg3=libuutil1-$${version}.$${arch}.rpm; \
        pkg1=$${name}-$${version}.$${arch}.rpm; \
        pkg2=libnvpair1-$${version}.$${arch}.rpm; \
        pkg3=libuutil1-$${version}.$${arch}.rpm; \
@@ -1171,7 +1174,7 @@ deb-utils: deb-local rpm-utils
         >> $${path_prepend}/dh_shlibdeps; \
        chmod +x $${path_prepend}/dh_shlibdeps; \
        env PATH=$${path_prepend}:$${PATH} \
         >> $${path_prepend}/dh_shlibdeps; \
        chmod +x $${path_prepend}/dh_shlibdeps; \
        env PATH=$${path_prepend}:$${PATH} \
-       fakeroot $(ALIEN) --bump=0 --scripts --to-deb \
+       fakeroot $(ALIEN) --bump=0 --scripts --to-deb --target=$$debarch \
            $$pkg1 $$pkg2 $$pkg3 $$pkg4 $$pkg5 $$pkg6 $$pkg7 \
            $$pkg8 $$pkg9; \
        $(RM) $${path_prepend}/dh_shlibdeps; \
            $$pkg1 $$pkg2 $$pkg3 $$pkg4 $$pkg5 $$pkg6 $$pkg7 \
            $$pkg8 $$pkg9; \
        $(RM) $${path_prepend}/dh_shlibdeps; \
@@ -1251,10 +1254,10 @@ lint: cppcheck paxcheck
 
 cppcheck:
        @if type cppcheck > /dev/null 2>&1; then \
 
 cppcheck:
        @if type cppcheck > /dev/null 2>&1; then \
-               cppcheck --quiet --force --error-exitcode=2 \
+               cppcheck --quiet --force --error-exitcode=2 --inline-suppr \
                        --suppressions-list=.github/suppressions.txt \
                        --suppressions-list=.github/suppressions.txt \
-                       -UHAVE_SSE2 -UHAVE_AVX512F \
-                       ${top_srcdir}; \
+                       -UHAVE_SSE2 -UHAVE_AVX512F -UHAVE_UIO_ZEROCOPY \
+                       -UHAVE_DNLC ${top_srcdir}; \
        fi
 
 paxcheck:
        fi
 
 paxcheck:
index 93918a08f31fb6185bdd926f6f9bd60abba60a39..f6dbb9bfbc1d5836e5fa4dfa9c6cd25b15173006 100755 (executable)
 # If you are having troubles when using this script from cron(8) please try
 # adjusting your PATH before reporting problems.
 #
 # If you are having troubles when using this script from cron(8) please try
 # adjusting your PATH before reporting problems.
 #
-# /usr/bin & /sbin
-#
-# Binaries used are:
-#
-# dc(1), kldstat(8), sed(1), sysctl(8) & vmstat(8)
-#
-# Binaries that I am working on phasing out are:
-#
-# dc(1) & sed(1)
+# Note some of this code uses older code (eg getopt instead of argparse,
+# subprocess.Popen() instead of subprocess.run()) because we need to support
+# some very old versions of Python.
+"""Print statistics on the ZFS Adjustable Replacement Cache (ARC)
 
 
+Provides basic information on the ARC, its efficiency, the L2ARC (if present),
+the Data Management Unit (DMU), Virtual Devices (VDEVs), and tunables. See the
+in-source documentation and code at
+https://github.com/zfsonlinux/zfs/blob/master/module/zfs/arc.c for details.
+"""
+
+import getopt
+import os
 import sys
 import time
 import sys
 import time
-import getopt
-import re
-from os import listdir
+import errno
+
 from subprocess import Popen, PIPE
 from decimal import Decimal as D
 
 from subprocess import Popen, PIPE
 from decimal import Decimal as D
 
-
-usetunable = True
 show_tunable_descriptions = False
 alternate_tunable_layout = False
 show_tunable_descriptions = False
 alternate_tunable_layout = False
-kstat_pobj = re.compile("^([^:]+):\s+(.+)\s*$", flags=re.M)
+
+
+def handle_Exception(ex_cls, ex, tb):
+    if ex is IOError:
+        if ex.errno == errno.EPIPE:
+            sys.exit()
+
+    if ex is KeyboardInterrupt:
+        sys.exit()
+
+
+sys.excepthook = handle_Exception
 
 
 def get_Kstat():
 
 
 def get_Kstat():
+    """Collect information on the ZFS subsystem from the /proc virtual
+    file system. The name "kstat" is a holdover from the Solaris utility
+    of the same name.
+    """
+
     def load_proc_kstats(fn, namespace):
     def load_proc_kstats(fn, namespace):
+        """Collect information on a specific subsystem of the ARC"""
+
         kstats = [line.strip() for line in open(fn)]
         del kstats[0:2]
         for kstat in kstats:
             kstat = kstat.strip()
         kstats = [line.strip() for line in open(fn)]
         del kstats[0:2]
         for kstat in kstats:
             kstat = kstat.strip()
-            name, unused, value = kstat.split()
+            name, _, value = kstat.split()
             Kstat[namespace + name] = D(value)
 
     Kstat = {}
             Kstat[namespace + name] = D(value)
 
     Kstat = {}
@@ -77,82 +95,79 @@ def get_Kstat():
     return Kstat
 
 
     return Kstat
 
 
-def div1():
-    sys.stdout.write("\n")
-    for i in range(18):
-        sys.stdout.write("%s" % "----")
-    sys.stdout.write("\n")
+def fBytes(b=0):
+    """Return human-readable representation of a byte value in
+    powers of 2 (eg "KiB" for "kibibytes", etc) to two decimal
+    points. Values smaller than one KiB are returned without
+    decimal points.
+    """
 
 
+    prefixes = [
+        [2**80, "YiB"],   # yobibytes (yotta)
+        [2**70, "ZiB"],   # zebibytes (zetta)
+        [2**60, "EiB"],   # exbibytes (exa)
+        [2**50, "PiB"],   # pebibytes (peta)
+        [2**40, "TiB"],   # tebibytes (tera)
+        [2**30, "GiB"],   # gibibytes (giga)
+        [2**20, "MiB"],   # mebibytes (mega)
+        [2**10, "KiB"]]   # kibibytes (kilo)
 
 
-def div2():
-    sys.stdout.write("\n")
+    if b >= 2**10:
+
+        for limit, unit in prefixes:
 
 
+            if b >= limit:
+                value = b / limit
+                break
+
+        result = "%0.2f\t%s" % (value, unit)
 
 
-def fBytes(Bytes=0, Decimal=2):
-    kbytes = (2 ** 10)
-    mbytes = (2 ** 20)
-    gbytes = (2 ** 30)
-    tbytes = (2 ** 40)
-    pbytes = (2 ** 50)
-    ebytes = (2 ** 60)
-    zbytes = (2 ** 70)
-    ybytes = (2 ** 80)
-
-    if Bytes >= ybytes:
-        return str("%0." + str(Decimal) + "f") % (Bytes / ybytes) + "\tYiB"
-    elif Bytes >= zbytes:
-        return str("%0." + str(Decimal) + "f") % (Bytes / zbytes) + "\tZiB"
-    elif Bytes >= ebytes:
-        return str("%0." + str(Decimal) + "f") % (Bytes / ebytes) + "\tEiB"
-    elif Bytes >= pbytes:
-        return str("%0." + str(Decimal) + "f") % (Bytes / pbytes) + "\tPiB"
-    elif Bytes >= tbytes:
-        return str("%0." + str(Decimal) + "f") % (Bytes / tbytes) + "\tTiB"
-    elif Bytes >= gbytes:
-        return str("%0." + str(Decimal) + "f") % (Bytes / gbytes) + "\tGiB"
-    elif Bytes >= mbytes:
-        return str("%0." + str(Decimal) + "f") % (Bytes / mbytes) + "\tMiB"
-    elif Bytes >= kbytes:
-        return str("%0." + str(Decimal) + "f") % (Bytes / kbytes) + "\tKiB"
-    elif Bytes == 0:
-        return str("%d" % 0) + "\tBytes"
     else:
     else:
-        return str("%d" % Bytes) + "\tBytes"
-
-
-def fHits(Hits=0, Decimal=2):
-    khits = (10 ** 3)
-    mhits = (10 ** 6)
-    bhits = (10 ** 9)
-    thits = (10 ** 12)
-    qhits = (10 ** 15)
-    Qhits = (10 ** 18)
-    shits = (10 ** 21)
-    Shits = (10 ** 24)
-
-    if Hits >= Shits:
-        return str("%0." + str(Decimal) + "f") % (Hits / Shits) + "S"
-    elif Hits >= shits:
-        return str("%0." + str(Decimal) + "f") % (Hits / shits) + "s"
-    elif Hits >= Qhits:
-        return str("%0." + str(Decimal) + "f") % (Hits / Qhits) + "Q"
-    elif Hits >= qhits:
-        return str("%0." + str(Decimal) + "f") % (Hits / qhits) + "q"
-    elif Hits >= thits:
-        return str("%0." + str(Decimal) + "f") % (Hits / thits) + "t"
-    elif Hits >= bhits:
-        return str("%0." + str(Decimal) + "f") % (Hits / bhits) + "b"
-    elif Hits >= mhits:
-        return str("%0." + str(Decimal) + "f") % (Hits / mhits) + "m"
-    elif Hits >= khits:
-        return str("%0." + str(Decimal) + "f") % (Hits / khits) + "k"
-    elif Hits == 0:
-        return str("%d" % 0)
+
+        result = "%d\tBytes" % b
+
+    return result
+
+
+def fHits(hits=0):
+    """Create a human-readable representation of the number of hits.
+    The single-letter symbols used are SI to avoid the confusion caused
+    by the different "short scale" and "long scale" representations in
+    English, which use the same words for different values. See
+    https://en.wikipedia.org/wiki/Names_of_large_numbers and
+    https://physics.nist.gov/cuu/Units/prefixes.html
+    """
+
+    numbers = [
+            [10**24, 'Y'],  # yotta (septillion)
+            [10**21, 'Z'],  # zetta (sextillion)
+            [10**18, 'E'],  # exa   (quintrillion)
+            [10**15, 'P'],  # peta  (quadrillion)
+            [10**12, 'T'],  # tera  (trillion)
+            [10**9, 'G'],   # giga  (billion)
+            [10**6, 'M'],   # mega  (million)
+            [10**3, 'k']]   # kilo  (thousand)
+
+    if hits >= 1000:
+
+        for limit, symbol in numbers:
+
+            if hits >= limit:
+                value = hits/limit
+                break
+
+        result = "%0.2f%s" % (value, symbol)
+
     else:
     else:
-        return str("%d" % Hits)
+
+        result = "%d" % hits
+
+    return result
 
 
 def fPerc(lVal=0, rVal=0, Decimal=2):
 
 
 def fPerc(lVal=0, rVal=0, Decimal=2):
+    """Calculate percentage value and return in human-readable format"""
+
     if rVal > 0:
         return str("%0." + str(Decimal) + "f") % (100 * (lVal / rVal)) + "%"
     else:
     if rVal > 0:
         return str("%0." + str(Decimal) + "f") % (100 * (lVal / rVal)) + "%"
     else:
@@ -160,6 +175,7 @@ def fPerc(lVal=0, rVal=0, Decimal=2):
 
 
 def get_arc_summary(Kstat):
 
 
 def get_arc_summary(Kstat):
+    """Collect general data on the ARC"""
 
     output = {}
     memory_throttle_count = Kstat[
 
     output = {}
     memory_throttle_count = Kstat[
@@ -176,12 +192,13 @@ def get_arc_summary(Kstat):
     # ARC Misc.
     deleted = Kstat["kstat.zfs.misc.arcstats.deleted"]
     mutex_miss = Kstat["kstat.zfs.misc.arcstats.mutex_miss"]
     # ARC Misc.
     deleted = Kstat["kstat.zfs.misc.arcstats.deleted"]
     mutex_miss = Kstat["kstat.zfs.misc.arcstats.mutex_miss"]
+    evict_skip = Kstat["kstat.zfs.misc.arcstats.evict_skip"]
 
     # ARC Misc.
     output["arc_misc"] = {}
     output["arc_misc"]["deleted"] = fHits(deleted)
     output["arc_misc"]['mutex_miss'] = fHits(mutex_miss)
 
     # ARC Misc.
     output["arc_misc"] = {}
     output["arc_misc"]["deleted"] = fHits(deleted)
     output["arc_misc"]['mutex_miss'] = fHits(mutex_miss)
-    output["arc_misc"]['evict_skips'] = fHits(mutex_miss)
+    output["arc_misc"]['evict_skips'] = fHits(evict_skip)
 
     # ARC Sizing
     arc_size = Kstat["kstat.zfs.misc.arcstats.size"]
 
     # ARC Sizing
     arc_size = Kstat["kstat.zfs.misc.arcstats.size"]
@@ -261,6 +278,8 @@ def get_arc_summary(Kstat):
 
 
 def _arc_summary(Kstat):
 
 
 def _arc_summary(Kstat):
+    """Print information on the ARC"""
+
     # ARC Sizing
     arc = get_arc_summary(Kstat)
 
     # ARC Sizing
     arc = get_arc_summary(Kstat)
 
@@ -276,7 +295,7 @@ def _arc_summary(Kstat):
     sys.stdout.write("\tMutex Misses:\t\t\t\t%s\n" %
                      arc['arc_misc']['mutex_miss'])
     sys.stdout.write("\tEvict Skips:\t\t\t\t%s\n" %
     sys.stdout.write("\tMutex Misses:\t\t\t\t%s\n" %
                      arc['arc_misc']['mutex_miss'])
     sys.stdout.write("\tEvict Skips:\t\t\t\t%s\n" %
-                     arc['arc_misc']['mutex_miss'])
+                     arc['arc_misc']['evict_skips'])
     sys.stdout.write("\n")
 
     # ARC Sizing
     sys.stdout.write("\n")
 
     # ARC Sizing
@@ -335,6 +354,8 @@ def _arc_summary(Kstat):
 
 
 def get_arc_efficiency(Kstat):
 
 
 def get_arc_efficiency(Kstat):
+    """Collect information on the efficiency of the ARC"""
+
     output = {}
 
     arc_hits = Kstat["kstat.zfs.misc.arcstats.hits"]
     output = {}
 
     arc_hits = Kstat["kstat.zfs.misc.arcstats.hits"]
@@ -458,6 +479,8 @@ def get_arc_efficiency(Kstat):
 
 
 def _arc_efficiency(Kstat):
 
 
 def _arc_efficiency(Kstat):
+    """Print information on the efficiency of the ARC"""
+
     arc = get_arc_efficiency(Kstat)
 
     sys.stdout.write("ARC Total accesses:\t\t\t\t\t%s\n" %
     arc = get_arc_efficiency(Kstat)
 
     sys.stdout.write("ARC Total accesses:\t\t\t\t\t%s\n" %
@@ -568,6 +591,8 @@ def _arc_efficiency(Kstat):
 
 
 def get_l2arc_summary(Kstat):
 
 
 def get_l2arc_summary(Kstat):
+    """Collection information on the L2ARC"""
+
     output = {}
 
     l2_abort_lowmem = Kstat["kstat.zfs.misc.arcstats.l2_abort_lowmem"]
     output = {}
 
     l2_abort_lowmem = Kstat["kstat.zfs.misc.arcstats.l2_abort_lowmem"]
@@ -662,6 +687,7 @@ def get_l2arc_summary(Kstat):
 
 
 def _l2arc_summary(Kstat):
 
 
 def _l2arc_summary(Kstat):
+    """Print information on the L2ARC"""
 
     arc = get_l2arc_summary(Kstat)
 
 
     arc = get_l2arc_summary(Kstat)
 
@@ -746,6 +772,8 @@ def _l2arc_summary(Kstat):
 
 
 def get_dmu_summary(Kstat):
 
 
 def get_dmu_summary(Kstat):
+    """Collect information on the DMU"""
+
     output = {}
 
     zfetch_hits = Kstat["kstat.zfs.misc.zfetchstats.hits"]
     output = {}
 
     zfetch_hits = Kstat["kstat.zfs.misc.zfetchstats.hits"]
@@ -771,6 +799,7 @@ def get_dmu_summary(Kstat):
 
 
 def _dmu_summary(Kstat):
 
 
 def _dmu_summary(Kstat):
+    """Print information on the DMU"""
 
     arc = get_dmu_summary(Kstat)
 
 
     arc = get_dmu_summary(Kstat)
 
@@ -792,6 +821,8 @@ def _dmu_summary(Kstat):
 
 
 def get_vdev_summary(Kstat):
 
 
 def get_vdev_summary(Kstat):
+    """Collect information on the VDEVs"""
+
     output = {}
 
     vdev_cache_delegations = \
     output = {}
 
     vdev_cache_delegations = \
@@ -822,6 +853,8 @@ def get_vdev_summary(Kstat):
 
 
 def _vdev_summary(Kstat):
 
 
 def _vdev_summary(Kstat):
+    """Print information on the VDEVs"""
+
     arc = get_vdev_summary(Kstat)
 
     if arc['vdev_cache_total'] > 0:
     arc = get_vdev_summary(Kstat)
 
     if arc['vdev_cache_total'] > 0:
@@ -841,10 +874,12 @@ def _vdev_summary(Kstat):
 
 
 def _tunable_summary(Kstat):
 
 
 def _tunable_summary(Kstat):
+    """Print information on tunables, including descriptions if requested"""
+
     global show_tunable_descriptions
     global alternate_tunable_layout
 
     global show_tunable_descriptions
     global alternate_tunable_layout
 
-    names = listdir("/sys/module/zfs/parameters/")
+    names = os.listdir("/sys/module/zfs/parameters/")
 
     values = {}
     for name in names:
 
     values = {}
     for name in names:
@@ -855,13 +890,21 @@ def _tunable_summary(Kstat):
     descriptions = {}
 
     if show_tunable_descriptions:
     descriptions = {}
 
     if show_tunable_descriptions:
+
+        command = ["/sbin/modinfo", "zfs", "-0"]
+
         try:
         try:
-            command = ["/sbin/modinfo", "zfs", "-0"]
             p = Popen(command, stdin=PIPE, stdout=PIPE,
                       stderr=PIPE, shell=False, close_fds=True)
             p.wait()
 
             p = Popen(command, stdin=PIPE, stdout=PIPE,
                       stderr=PIPE, shell=False, close_fds=True)
             p.wait()
 
-            description_list = p.communicate()[0].strip().split('\0')
+            # By default, Python 2 returns a string as the first element of the
+            # tuple from p.communicate(), while Python 3 returns bytes which
+            # must be decoded first. The better way to do this would be with
+            # subprocess.run() or at least .check_output(), but this fails on
+            # CentOS 6 because of its old version of Python 2
+            desc = bytes.decode(p.communicate()[0])
+            description_list = desc.strip().split('\0')
 
             if p.returncode == 0:
                 for tunable in description_list:
 
             if p.returncode == 0:
                 for tunable in description_list:
@@ -880,19 +923,23 @@ def _tunable_summary(Kstat):
                              (sys.argv[0], command[0], e.strerror))
             sys.stderr.write("Tunable descriptions will be disabled.\n")
 
                              (sys.argv[0], command[0], e.strerror))
             sys.stderr.write("Tunable descriptions will be disabled.\n")
 
-    sys.stdout.write("ZFS Tunable:\n")
+    sys.stdout.write("ZFS Tunables:\n")
+    names.sort()
+
+    if alternate_tunable_layout:
+        fmt = "\t%s=%s\n"
+    else:
+        fmt = "\t%-50s%s\n"
+
     for name in names:
     for name in names:
+
         if not name:
             continue
 
         if not name:
             continue
 
-        format = "\t%-50s%s\n"
-        if alternate_tunable_layout:
-            format = "\t%s=%s\n"
-
         if show_tunable_descriptions and name in descriptions:
             sys.stdout.write("\t# %s\n" % descriptions[name])
 
         if show_tunable_descriptions and name in descriptions:
             sys.stdout.write("\t# %s\n" % descriptions[name])
 
-        sys.stdout.write(format % (name, values[name]))
+        sys.stdout.write(fmt % (name, values[name]))
 
 
 unSub = [
 
 
 unSub = [
@@ -906,14 +953,18 @@ unSub = [
 
 
 def zfs_header():
 
 
 def zfs_header():
-    daydate = time.strftime("%a %b %d %H:%M:%S %Y")
+    """Print title string with date"""
+
+    daydate = time.strftime('%a %b %d %H:%M:%S %Y')
 
 
-    div1()
-    sys.stdout.write("ZFS Subsystem Report\t\t\t\t%s" % daydate)
-    div2()
+    sys.stdout.write('\n'+'-'*72+'\n')
+    sys.stdout.write('ZFS Subsystem Report\t\t\t\t%s' % daydate)
+    sys.stdout.write('\n')
 
 
 def usage():
 
 
 def usage():
+    """Print usage information"""
+
     sys.stdout.write("Usage: arc_summary.py [-h] [-a] [-d] [-p PAGE]\n\n")
     sys.stdout.write("\t -h, --help           : "
                      "Print this help message and exit\n")
     sys.stdout.write("Usage: arc_summary.py [-h] [-a] [-d] [-p PAGE]\n\n")
     sys.stdout.write("\t -h, --help           : "
                      "Print this help message and exit\n")
@@ -934,12 +985,20 @@ def usage():
 
 
 def main():
 
 
 def main():
+    """Main function"""
+
     global show_tunable_descriptions
     global alternate_tunable_layout
 
     global show_tunable_descriptions
     global alternate_tunable_layout
 
-    opts, args = getopt.getopt(
-        sys.argv[1:], "adp:h", ["alternate", "description", "page=", "help"]
-    )
+    try:
+        opts, args = getopt.getopt(
+            sys.argv[1:],
+            "adp:h", ["alternate", "description", "page=", "help"]
+        )
+    except getopt.error as e:
+        sys.stderr.write("Error: %s\n" % e.msg)
+        usage()
+        sys.exit(1)
 
     args = {}
     for opt, arg in opts:
 
     args = {}
     for opt, arg in opts:
@@ -951,7 +1010,7 @@ def main():
             args['p'] = arg
         if opt in ('-h', '--help'):
             usage()
             args['p'] = arg
         if opt in ('-h', '--help'):
             usage()
-            sys.exit()
+            sys.exit(0)
 
     Kstat = get_Kstat()
 
 
     Kstat = get_Kstat()
 
@@ -966,14 +1025,14 @@ def main():
         except IndexError:
             sys.stderr.write('the argument to -p must be between 1 and ' +
                              str(len(unSub)) + '\n')
         except IndexError:
             sys.stderr.write('the argument to -p must be between 1 and ' +
                              str(len(unSub)) + '\n')
-            sys.exit()
+            sys.exit(1)
     else:
         pages = unSub
 
     zfs_header()
     for page in pages:
         page(Kstat)
     else:
         pages = unSub
 
     zfs_header()
     for page in pages:
         page(Kstat)
-        div2()
+        sys.stdout.write("\n")
 
 
 if __name__ == '__main__':
 
 
 if __name__ == '__main__':
index b7de5104f09df59491d0d1be60fe2947dcf5f387..ed6a95914ee6232b0f02901d7f7b736396022185 100644 (file)
@@ -397,7 +397,7 @@ zed_rate_limit()
 
     zed_lock "${lockfile}" "${lockfile_fd}"
     time_now="$(date +%s)"
 
     zed_lock "${lockfile}" "${lockfile_fd}"
     time_now="$(date +%s)"
-    time_prev="$(egrep "^[0-9]+;${tag}\$" "${statefile}" 2>/dev/null \
+    time_prev="$(grep -E "^[0-9]+;${tag}\$" "${statefile}" 2>/dev/null \
         | tail -1 | cut -d\; -f1)"
 
     if [ -n "${time_prev}" ] \
         | tail -1 | cut -d\; -f1)"
 
     if [ -n "${time_prev}" ] \
@@ -406,7 +406,7 @@ zed_rate_limit()
     else
         umask_bak="$(umask)"
         umask 077
     else
         umask_bak="$(umask)"
         umask 077
-        egrep -v "^[0-9]+;${tag}\$" "${statefile}" 2>/dev/null \
+        grep -E -v "^[0-9]+;${tag}\$" "${statefile}" 2>/dev/null \
             > "${statefile}.$$"
         echo "${time_now};${tag}" >> "${statefile}.$$"
         mv -f "${statefile}.$$" "${statefile}"
             > "${statefile}.$$"
         echo "${time_now};${tag}" >> "${statefile}.$$"
         mv -f "${statefile}.$$" "${statefile}"
index 70f88fc6987469d1341d8ff36367ce7ba0abf23a..e15af8f4ea02eb207c5f3cd89b9bbd79d1f39c44 100644 (file)
@@ -268,7 +268,7 @@ zhack_feature_enable_sync(void *arg, dmu_tx_t *tx)
 static void
 zhack_do_feature_enable(int argc, char **argv)
 {
 static void
 zhack_do_feature_enable(int argc, char **argv)
 {
-       char c;
+       int c;
        char *desc, *target;
        spa_t *spa;
        objset_t *mos;
        char *desc, *target;
        spa_t *spa;
        objset_t *mos;
@@ -363,7 +363,7 @@ feature_decr_sync(void *arg, dmu_tx_t *tx)
 static void
 zhack_do_feature_ref(int argc, char **argv)
 {
 static void
 zhack_do_feature_ref(int argc, char **argv)
 {
-       char c;
+       int c;
        char *target;
        boolean_t decr = B_FALSE;
        spa_t *spa;
        char *target;
        boolean_t decr = B_FALSE;
        spa_t *spa;
@@ -483,7 +483,7 @@ main(int argc, char **argv)
        char *path[MAX_NUM_PATHS];
        const char *subcommand;
        int rv = 0;
        char *path[MAX_NUM_PATHS];
        const char *subcommand;
        int rv = 0;
-       char c;
+       int c;
 
        g_importargs.path = path;
 
 
        g_importargs.path = path;
 
index 97faa5f9bee121644ddcf4fcac50c27a4e14475b..fd6bd9e7677d1554da2c7e2ca5662987876d1993 100644 (file)
@@ -860,9 +860,11 @@ get_replication(nvlist_t *nvroot, boolean_t fatal)
 
                                /*
                                 * If this is a replacing or spare vdev, then
 
                                /*
                                 * If this is a replacing or spare vdev, then
-                                * get the real first child of the vdev.
+                                * get the real first child of the vdev: do this
+                                * in a loop because replacing and spare vdevs
+                                * can be nested.
                                 */
                                 */
-                               if (strcmp(childtype,
+                               while (strcmp(childtype,
                                    VDEV_TYPE_REPLACING) == 0 ||
                                    strcmp(childtype, VDEV_TYPE_SPARE) == 0) {
                                        nvlist_t **rchild;
                                    VDEV_TYPE_REPLACING) == 0 ||
                                    strcmp(childtype, VDEV_TYPE_SPARE) == 0) {
                                        nvlist_t **rchild;
index 98e98e45f40233fd2bb142107ccd78c81e827e5a..1b51f93163a0299c47a26a43c2d8738d461191bb 100644 (file)
@@ -18,8 +18,9 @@ deb-kmod: deb-local rpm-kmod
        name=${PACKAGE}; \
        version=${VERSION}-${RELEASE}; \
        arch=`$(RPM) -qp $${name}-kmod-$${version}.src.rpm --qf %{arch} | tail -1`; \
        name=${PACKAGE}; \
        version=${VERSION}-${RELEASE}; \
        arch=`$(RPM) -qp $${name}-kmod-$${version}.src.rpm --qf %{arch} | tail -1`; \
+       debarch=`$(DPKG) --print-architecture`; \
        pkg1=kmod-$${name}*$${version}.$${arch}.rpm; \
        pkg1=kmod-$${name}*$${version}.$${arch}.rpm; \
-       fakeroot $(ALIEN) --bump=0 --scripts --to-deb $$pkg1; \
+       fakeroot $(ALIEN) --bump=0 --scripts --to-deb --target=$$debarch $$pkg1; \
        $(RM) $$pkg1
 
 
        $(RM) $$pkg1
 
 
@@ -27,14 +28,16 @@ deb-dkms: deb-local rpm-dkms
        name=${PACKAGE}; \
        version=${VERSION}-${RELEASE}; \
        arch=`$(RPM) -qp $${name}-dkms-$${version}.src.rpm --qf %{arch} | tail -1`; \
        name=${PACKAGE}; \
        version=${VERSION}-${RELEASE}; \
        arch=`$(RPM) -qp $${name}-dkms-$${version}.src.rpm --qf %{arch} | tail -1`; \
+       debarch=`$(DPKG) --print-architecture`; \
        pkg1=$${name}-dkms-$${version}.$${arch}.rpm; \
        pkg1=$${name}-dkms-$${version}.$${arch}.rpm; \
-       fakeroot $(ALIEN) --bump=0 --scripts --to-deb $$pkg1; \
+       fakeroot $(ALIEN) --bump=0 --scripts --to-deb --target=$$debarch $$pkg1; \
        $(RM) $$pkg1
 
 deb-utils: deb-local rpm-utils
        name=${PACKAGE}; \
        version=${VERSION}-${RELEASE}; \
        arch=`$(RPM) -qp $${name}-$${version}.src.rpm --qf %{arch} | tail -1`; \
        $(RM) $$pkg1
 
 deb-utils: deb-local rpm-utils
        name=${PACKAGE}; \
        version=${VERSION}-${RELEASE}; \
        arch=`$(RPM) -qp $${name}-$${version}.src.rpm --qf %{arch} | tail -1`; \
+       debarch=`$(DPKG) --print-architecture`; \
        pkg1=$${name}-$${version}.$${arch}.rpm; \
        pkg2=libnvpair1-$${version}.$${arch}.rpm; \
        pkg3=libuutil1-$${version}.$${arch}.rpm; \
        pkg1=$${name}-$${version}.$${arch}.rpm; \
        pkg2=libnvpair1-$${version}.$${arch}.rpm; \
        pkg3=libuutil1-$${version}.$${arch}.rpm; \
@@ -57,7 +60,7 @@ deb-utils: deb-local rpm-utils
 ## which should NOT be mixed with the alien-generated debs created here
        chmod +x $${path_prepend}/dh_shlibdeps; \
        env PATH=$${path_prepend}:$${PATH} \
 ## which should NOT be mixed with the alien-generated debs created here
        chmod +x $${path_prepend}/dh_shlibdeps; \
        env PATH=$${path_prepend}:$${PATH} \
-       fakeroot $(ALIEN) --bump=0 --scripts --to-deb \
+       fakeroot $(ALIEN) --bump=0 --scripts --to-deb --target=$$debarch \
            $$pkg1 $$pkg2 $$pkg3 $$pkg4 $$pkg5 $$pkg6 $$pkg7 \
            $$pkg8 $$pkg9; \
        $(RM) $${path_prepend}/dh_shlibdeps; \
            $$pkg1 $$pkg2 $$pkg3 $$pkg4 $$pkg5 $$pkg6 $$pkg7 \
            $$pkg8 $$pkg9; \
        $(RM) $${path_prepend}/dh_shlibdeps; \
index 9f8fe6559fa3c1abd89f895e465a6285321e6751..ace54f70711f11cc65e7ff331b8d940702e5b257 100644 (file)
@@ -32,15 +32,23 @@ dnl #
 dnl # Linux 4.1 API
 dnl #
 AC_DEFUN([ZFS_AC_KERNEL_NEW_SYNC_READ],
 dnl # Linux 4.1 API
 dnl #
 AC_DEFUN([ZFS_AC_KERNEL_NEW_SYNC_READ],
-       [AC_MSG_CHECKING([whether new_sync_read() is available])
+       [AC_MSG_CHECKING([whether new_sync_read/write() are available])
        ZFS_LINUX_TRY_COMPILE([
                #include <linux/fs.h>
        ],[
        ZFS_LINUX_TRY_COMPILE([
                #include <linux/fs.h>
        ],[
-               new_sync_read(NULL, NULL, 0, NULL);
+                       ssize_t ret __attribute__ ((unused));
+                       struct file *filp = NULL;
+                       char __user *rbuf = NULL;
+                       const char __user *wbuf = NULL;
+                       size_t len = 0;
+                       loff_t ppos;
+
+                       ret = new_sync_read(filp, rbuf, len, &ppos);
+                       ret = new_sync_write(filp, wbuf, len, &ppos);
        ],[
                AC_MSG_RESULT(yes)
                AC_DEFINE(HAVE_NEW_SYNC_READ, 1,
        ],[
                AC_MSG_RESULT(yes)
                AC_DEFINE(HAVE_NEW_SYNC_READ, 1,
-                       [new_sync_read() is available])
+                       [new_sync_read()/new_sync_write() are available])
        ],[
                AC_MSG_RESULT(no)
        ])
        ],[
                AC_MSG_RESULT(no)
        ])
index f4e7983f642433fd01b1ddf6f10c5f4cb0e2e43a..f0c2f47d6f98f94205e96749ae2825a0e3cc211c 100755 (executable)
--- a/configure
+++ b/configure
@@ -1,6 +1,6 @@
 #! /bin/sh
 # Guess values for system-dependent variables and create Makefiles.
 #! /bin/sh
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.63 for zfs 0.7.5.
+# Generated by GNU Autoconf 2.63 for zfs 0.7.6.
 #
 # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
 # 2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
 #
 # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
 # 2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
@@ -743,8 +743,8 @@ SHELL=${CONFIG_SHELL-/bin/sh}
 # Identity of this package.
 PACKAGE_NAME='zfs'
 PACKAGE_TARNAME='zfs'
 # Identity of this package.
 PACKAGE_NAME='zfs'
 PACKAGE_TARNAME='zfs'
-PACKAGE_VERSION='0.7.5'
-PACKAGE_STRING='zfs 0.7.5'
+PACKAGE_VERSION='0.7.6'
+PACKAGE_STRING='zfs 0.7.6'
 PACKAGE_BUGREPORT=''
 
 # Factoring default headers for most tests.
 PACKAGE_BUGREPORT=''
 
 # Factoring default headers for most tests.
@@ -1599,7 +1599,7 @@ if test "$ac_init_help" = "long"; then
   # Omit some internal or obsolete options to make the list less imposing.
   # This message is too long to be a string in the A/UX 3.1 sh.
   cat <<_ACEOF
   # Omit some internal or obsolete options to make the list less imposing.
   # This message is too long to be a string in the A/UX 3.1 sh.
   cat <<_ACEOF
-\`configure' configures zfs 0.7.5 to adapt to many kinds of systems.
+\`configure' configures zfs 0.7.6 to adapt to many kinds of systems.
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
@@ -1670,7 +1670,7 @@ fi
 
 if test -n "$ac_init_help"; then
   case $ac_init_help in
 
 if test -n "$ac_init_help"; then
   case $ac_init_help in
-     short | recursive ) echo "Configuration of zfs 0.7.5:";;
+     short | recursive ) echo "Configuration of zfs 0.7.6:";;
    esac
   cat <<\_ACEOF
 
    esac
   cat <<\_ACEOF
 
@@ -1804,7 +1804,7 @@ fi
 test -n "$ac_init_help" && exit $ac_status
 if $ac_init_version; then
   cat <<\_ACEOF
 test -n "$ac_init_help" && exit $ac_status
 if $ac_init_version; then
   cat <<\_ACEOF
-zfs configure 0.7.5
+zfs configure 0.7.6
 generated by GNU Autoconf 2.63
 
 Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
 generated by GNU Autoconf 2.63
 
 Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
@@ -1818,7 +1818,7 @@ cat >config.log <<_ACEOF
 This file contains any messages produced by compilers while
 running configure, to aid debugging if configure makes a mistake.
 
 This file contains any messages produced by compilers while
 running configure, to aid debugging if configure makes a mistake.
 
-It was created by zfs $as_me 0.7.5, which was
+It was created by zfs $as_me 0.7.6, which was
 generated by GNU Autoconf 2.63.  Invocation command line was
 
   $ $0 $@
 generated by GNU Autoconf 2.63.  Invocation command line was
 
   $ $0 $@
@@ -2976,7 +2976,7 @@ fi
 
 # Define the identity of the package.
  PACKAGE='zfs'
 
 # Define the identity of the package.
  PACKAGE='zfs'
- VERSION='0.7.5'
+ VERSION='0.7.6'
 
 
 cat >>confdefs.h <<_ACEOF
 
 
 cat >>confdefs.h <<_ACEOF
@@ -25882,8 +25882,8 @@ cat >>confdefs.h <<\_ACEOF
 _ACEOF
 
 
 _ACEOF
 
 
-               { $as_echo "$as_me:$LINENO: checking whether new_sync_read() is available" >&5
-$as_echo_n "checking whether new_sync_read() is available... " >&6; }
+               { $as_echo "$as_me:$LINENO: checking whether new_sync_read/write() are available" >&5
+$as_echo_n "checking whether new_sync_read/write() are available... " >&6; }
 
 
 cat confdefs.h - <<_ACEOF >conftest.c
 
 
 cat confdefs.h - <<_ACEOF >conftest.c
@@ -25900,7 +25900,15 @@ int
 main (void)
 {
 
 main (void)
 {
 
-               new_sync_read(NULL, NULL, 0, NULL);
+                       ssize_t ret __attribute__ ((unused));
+                       struct file *filp = NULL;
+                       char __user *rbuf = NULL;
+                       const char __user *wbuf = NULL;
+                       size_t len = 0;
+                       loff_t ppos;
+
+                       ret = new_sync_read(filp, rbuf, len, &ppos);
+                       ret = new_sync_write(filp, wbuf, len, &ppos);
 
   ;
   return 0;
 
   ;
   return 0;
@@ -44184,8 +44192,8 @@ cat >>confdefs.h <<\_ACEOF
 _ACEOF
 
 
 _ACEOF
 
 
-               { $as_echo "$as_me:$LINENO: checking whether new_sync_read() is available" >&5
-$as_echo_n "checking whether new_sync_read() is available... " >&6; }
+               { $as_echo "$as_me:$LINENO: checking whether new_sync_read/write() are available" >&5
+$as_echo_n "checking whether new_sync_read/write() are available... " >&6; }
 
 
 cat confdefs.h - <<_ACEOF >conftest.c
 
 
 cat confdefs.h - <<_ACEOF >conftest.c
@@ -44202,7 +44210,15 @@ int
 main (void)
 {
 
 main (void)
 {
 
-               new_sync_read(NULL, NULL, 0, NULL);
+                       ssize_t ret __attribute__ ((unused));
+                       struct file *filp = NULL;
+                       char __user *rbuf = NULL;
+                       const char __user *wbuf = NULL;
+                       size_t len = 0;
+                       loff_t ppos;
+
+                       ret = new_sync_read(filp, rbuf, len, &ppos);
+                       ret = new_sync_write(filp, wbuf, len, &ppos);
 
   ;
   return 0;
 
   ;
   return 0;
@@ -46174,7 +46190,7 @@ exec 6>&1
 # report actual input values of CONFIG_FILES etc. instead of their
 # values after options handling.
 ac_log="
 # report actual input values of CONFIG_FILES etc. instead of their
 # values after options handling.
 ac_log="
-This file was extended by zfs $as_me 0.7.5, which was
+This file was extended by zfs $as_me 0.7.6, which was
 generated by GNU Autoconf 2.63.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
 generated by GNU Autoconf 2.63.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
@@ -46237,7 +46253,7 @@ Report bugs to <bug-autoconf@gnu.org>."
 _ACEOF
 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
 ac_cs_version="\\
 _ACEOF
 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
 ac_cs_version="\\
-zfs config.status 0.7.5
+zfs config.status 0.7.6
 configured by $0, generated by GNU Autoconf 2.63,
   with options \\"`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\"
 
 configured by $0, generated by GNU Autoconf 2.63,
   with options \\"`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\"
 
index 247db0aba82d1c5185c8a62d1a4ef96e65328f93..93432386a2c425e7230663b0cf95548699450077 100644 (file)
@@ -22,7 +22,7 @@ $(init_SCRIPTS) $(initconf_SCRIPTS) $(initcommon_SCRIPTS):%:%.in
                NFS_SRV=nfs; \
          fi; \
          if [ -e /sbin/openrc-run ]; then \
                NFS_SRV=nfs; \
          fi; \
          if [ -e /sbin/openrc-run ]; then \
-               SHELL=/sbin/runscript; \
+               SHELL=/sbin/openrc-run; \
          else \
                SHELL=/bin/sh; \
          fi; \
          else \
                SHELL=/bin/sh; \
          fi; \
index 3b5968142a27e0e83896b649baa8887482cbe9d0..4c48dbc5f0a5d00e8a97177909b4bcbbe4890982 100644 (file)
@@ -704,7 +704,7 @@ $(init_SCRIPTS) $(initconf_SCRIPTS) $(initcommon_SCRIPTS):%:%.in
                NFS_SRV=nfs; \
          fi; \
          if [ -e /sbin/openrc-run ]; then \
                NFS_SRV=nfs; \
          fi; \
          if [ -e /sbin/openrc-run ]; then \
-               SHELL=/sbin/runscript; \
+               SHELL=/sbin/openrc-run; \
          else \
                SHELL=/bin/sh; \
          fi; \
          else \
                SHELL=/bin/sh; \
          fi; \
index 66f37cf7102584295c8a068830ae716c817bf705..1ea4937bd451c997cbd72984cf0f791755f0d903 100644 (file)
@@ -221,6 +221,7 @@ void arc_buf_destroy(arc_buf_t *buf, void *tag);
 void arc_buf_info(arc_buf_t *buf, arc_buf_info_t *abi, int state_index);
 uint64_t arc_buf_size(arc_buf_t *buf);
 uint64_t arc_buf_lsize(arc_buf_t *buf);
 void arc_buf_info(arc_buf_t *buf, arc_buf_info_t *abi, int state_index);
 uint64_t arc_buf_size(arc_buf_t *buf);
 uint64_t arc_buf_lsize(arc_buf_t *buf);
+void arc_buf_access(arc_buf_t *buf);
 void arc_release(arc_buf_t *buf, void *tag);
 int arc_released(arc_buf_t *buf);
 void arc_buf_sigsegv(int sig, siginfo_t *si, void *unused);
 void arc_release(arc_buf_t *buf, void *tag);
 int arc_released(arc_buf_t *buf);
 void arc_buf_sigsegv(int sig, siginfo_t *si, void *unused);
index d24615262737912d1e88c18aecd30fc8c9105560..bcdf7d646fbc8073337a412c4ac1772753a2cc39 100644 (file)
@@ -713,11 +713,16 @@ void dmu_tx_mark_netfree(dmu_tx_t *tx);
  * to stable storage and will also be called if the dmu_tx is aborted.
  * If there is any error which prevents the transaction from being committed to
  * disk, the callback will be called with a value of error != 0.
  * to stable storage and will also be called if the dmu_tx is aborted.
  * If there is any error which prevents the transaction from being committed to
  * disk, the callback will be called with a value of error != 0.
+ *
+ * When multiple callbacks are registered to the transaction, the callbacks
+ * will be called in reverse order to let Lustre, the only user of commit
+ * callback currently, take the fast path of its commit callback handling.
  */
 typedef void dmu_tx_callback_func_t(void *dcb_data, int error);
 
 void dmu_tx_callback_register(dmu_tx_t *tx, dmu_tx_callback_func_t *dcb_func,
     void *dcb_data);
  */
 typedef void dmu_tx_callback_func_t(void *dcb_data, int error);
 
 void dmu_tx_callback_register(dmu_tx_t *tx, dmu_tx_callback_func_t *dcb_func,
     void *dcb_data);
+void dmu_tx_do_callbacks(list_t *cb_list, int error);
 
 /*
  * Free up the data blocks for a defined range of a file.  If size is
 
 /*
  * Free up the data blocks for a defined range of a file.  If size is
index f16e1e858041aa48ba51ccd602c3c9a0dbe04f98..d82a79310db69339f03da1ef684671382f7d2b9d 100644 (file)
@@ -145,10 +145,6 @@ uint64_t dmu_tx_get_txg(dmu_tx_t *tx);
 struct dsl_pool *dmu_tx_pool(dmu_tx_t *tx);
 void dmu_tx_wait(dmu_tx_t *tx);
 
 struct dsl_pool *dmu_tx_pool(dmu_tx_t *tx);
 void dmu_tx_wait(dmu_tx_t *tx);
 
-void dmu_tx_callback_register(dmu_tx_t *tx, dmu_tx_callback_func_t *dcb_func,
-    void *dcb_data);
-void dmu_tx_do_callbacks(list_t *cb_list, int error);
-
 /*
  * These routines are defined in dmu_spa.h, and are called by the SPA.
  */
 /*
  * These routines are defined in dmu_spa.h, and are called by the SPA.
  */
index 7157ef43f64dc6e12319e730450605d9a7477813..473d2691c947fcb7bb20444f735727597b4a726d 100644 (file)
@@ -125,8 +125,7 @@ extern zio_t *vdev_queue_io(zio_t *zio);
 extern void vdev_queue_io_done(zio_t *zio);
 
 extern int vdev_queue_length(vdev_t *vd);
 extern void vdev_queue_io_done(zio_t *zio);
 
 extern int vdev_queue_length(vdev_t *vd);
-extern uint64_t vdev_queue_lastoffset(vdev_t *vd);
-extern void vdev_queue_register_lastoffset(vdev_t *vd, zio_t *zio);
+extern uint64_t vdev_queue_last_offset(vdev_t *vd);
 
 extern void vdev_config_dirty(vdev_t *vd);
 extern void vdev_config_clean(vdev_t *vd);
 
 extern void vdev_config_dirty(vdev_t *vd);
 extern void vdev_config_clean(vdev_t *vd);
index 7c5e54b08e193ec33c8f1598219732d944b2eb73..4c2e3cd2e0af6f62053bbe275d11a4e6948f55d5 100644 (file)
@@ -127,7 +127,6 @@ struct vdev_queue {
        hrtime_t        vq_io_delta_ts;
        zio_t           vq_io_search; /* used as local for stack reduction */
        kmutex_t        vq_lock;
        hrtime_t        vq_io_delta_ts;
        zio_t           vq_io_search; /* used as local for stack reduction */
        kmutex_t        vq_lock;
-       uint64_t        vq_lastoffset;
 };
 
 /*
 };
 
 /*
index 4bd15e3d53c2b421b470bcf393fe73c71e50fd08..0799ed19dfc88bf68d67c4e1b087584008571fd2 100644 (file)
@@ -102,30 +102,30 @@ typedef struct raidz_impl_ops {
 } raidz_impl_ops_t;
 
 typedef struct raidz_col {
 } raidz_impl_ops_t;
 
 typedef struct raidz_col {
-       size_t rc_devidx;               /* child device index for I/O */
-       size_t rc_offset;               /* device offset */
-       size_t rc_size;                 /* I/O size */
+       uint64_t rc_devidx;             /* child device index for I/O */
+       uint64_t rc_offset;             /* device offset */
+       uint64_t rc_size;               /* I/O size */
        abd_t *rc_abd;                  /* I/O data */
        void *rc_gdata;                 /* used to store the "good" version */
        int rc_error;                   /* I/O error for this device */
        abd_t *rc_abd;                  /* I/O data */
        void *rc_gdata;                 /* used to store the "good" version */
        int rc_error;                   /* I/O error for this device */
-       unsigned int rc_tried;          /* Did we attempt this I/O column? */
-       unsigned int rc_skipped;        /* Did we skip this I/O column? */
+       uint8_t rc_tried;               /* Did we attempt this I/O column? */
+       uint8_t rc_skipped;             /* Did we skip this I/O column? */
 } raidz_col_t;
 
 typedef struct raidz_map {
 } raidz_col_t;
 
 typedef struct raidz_map {
-       size_t rm_cols;                 /* Regular column count */
-       size_t rm_scols;                /* Count including skipped columns */
-       size_t rm_bigcols;              /* Number of oversized columns */
-       size_t rm_asize;                /* Actual total I/O size */
-       size_t rm_missingdata;          /* Count of missing data devices */
-       size_t rm_missingparity;        /* Count of missing parity devices */
-       size_t rm_firstdatacol;         /* First data column/parity count */
-       size_t rm_nskip;                /* Skipped sectors for padding */
-       size_t rm_skipstart;            /* Column index of padding start */
+       uint64_t rm_cols;               /* Regular column count */
+       uint64_t rm_scols;              /* Count including skipped columns */
+       uint64_t rm_bigcols;            /* Number of oversized columns */
+       uint64_t rm_asize;              /* Actual total I/O size */
+       uint64_t rm_missingdata;        /* Count of missing data devices */
+       uint64_t rm_missingparity;      /* Count of missing parity devices */
+       uint64_t rm_firstdatacol;       /* First data column/parity count */
+       uint64_t rm_nskip;              /* Skipped sectors for padding */
+       uint64_t rm_skipstart;          /* Column index of padding start */
        abd_t *rm_abd_copy;             /* rm_asize-buffer of copied data */
        abd_t *rm_abd_copy;             /* rm_asize-buffer of copied data */
-       size_t rm_reports;              /* # of referencing checksum reports */
-       unsigned int rm_freed;          /* map no longer has referencing ZIO */
-       unsigned int rm_ecksuminjected; /* checksum error was injected */
+       uintptr_t rm_reports;           /* # of referencing checksum reports */
+       uint8_t rm_freed;               /* map no longer has referencing ZIO */
+       uint8_t rm_ecksuminjected;      /* checksum error was injected */
        raidz_impl_ops_t *rm_ops;       /* RAIDZ math operations */
        raidz_col_t rm_col[1];          /* Flexible array of I/O columns */
 } raidz_map_t;
        raidz_impl_ops_t *rm_ops;       /* RAIDZ math operations */
        raidz_col_t rm_col[1];          /* Flexible array of I/O columns */
 } raidz_map_t;
index aa565ca828622f6cc207288aee60cb9bf2f99c1e..022df016f26d895ea9fdd80aa2cbc7e898fc345b 100644 (file)
@@ -493,20 +493,10 @@ int
 sa_enable_share(sa_share_t share, char *protocol)
 {
        sa_share_impl_t impl_share = (sa_share_impl_t)share;
 sa_enable_share(sa_share_t share, char *protocol)
 {
        sa_share_impl_t impl_share = (sa_share_impl_t)share;
-       int rc, ret;
-       boolean_t found_protocol;
+       int rc, ret = SA_OK;
+       boolean_t found_protocol = B_FALSE;
        sa_fstype_t *fstype;
 
        sa_fstype_t *fstype;
 
-#ifdef DEBUG
-       fprintf(stderr, "sa_enable_share: share->sharepath=%s, protocol=%s\n",
-           impl_share->sharepath, protocol);
-#endif
-
-       assert(impl_share->handle != NULL);
-
-       ret = SA_OK;
-       found_protocol = B_FALSE;
-
        fstype = fstypes;
        while (fstype != NULL) {
                if (protocol == NULL || strcmp(fstype->name, protocol) == 0) {
        fstype = fstypes;
        while (fstype != NULL) {
                if (protocol == NULL || strcmp(fstype->name, protocol) == 0) {
@@ -534,18 +524,10 @@ int
 sa_disable_share(sa_share_t share, char *protocol)
 {
        sa_share_impl_t impl_share = (sa_share_impl_t)share;
 sa_disable_share(sa_share_t share, char *protocol)
 {
        sa_share_impl_t impl_share = (sa_share_impl_t)share;
-       int rc, ret;
-       boolean_t found_protocol;
+       int rc, ret = SA_OK;
+       boolean_t found_protocol = B_FALSE;
        sa_fstype_t *fstype;
 
        sa_fstype_t *fstype;
 
-#ifdef DEBUG
-       fprintf(stderr, "sa_disable_share: share->sharepath=%s, protocol=%s\n",
-           impl_share->sharepath, protocol);
-#endif
-
-       ret = SA_OK;
-       found_protocol = B_FALSE;
-
        fstype = fstypes;
        while (fstype != NULL) {
                if (protocol == NULL || strcmp(fstype->name, protocol) == 0) {
        fstype = fstypes;
        while (fstype != NULL) {
                if (protocol == NULL || strcmp(fstype->name, protocol) == 0) {
@@ -696,11 +678,6 @@ sa_parse_legacy_options(sa_group_t group, char *options, char *proto)
 {
        sa_fstype_t *fstype;
 
 {
        sa_fstype_t *fstype;
 
-#ifdef DEBUG
-       fprintf(stderr, "sa_parse_legacy_options: options=%s, proto=%s\n",
-           options, proto);
-#endif
-
        fstype = fstypes;
        while (fstype != NULL) {
                if (strcmp(fstype->name, proto) != 0) {
        fstype = fstypes;
        while (fstype != NULL) {
                if (strcmp(fstype->name, proto) != 0) {
@@ -787,12 +764,6 @@ sa_zfs_process_share(sa_handle_t handle, sa_group_t group, sa_share_t share,
        sa_handle_impl_t impl_handle = (sa_handle_impl_t)handle;
        sa_share_impl_t impl_share = (sa_share_impl_t)share;
 
        sa_handle_impl_t impl_handle = (sa_handle_impl_t)handle;
        sa_share_impl_t impl_share = (sa_share_impl_t)share;
 
-#ifdef DEBUG
-       fprintf(stderr, "sa_zfs_process_share: mountpoint=%s, proto=%s, "
-           "shareopts=%s, sourcestr=%s, dataset=%s\n", mountpoint, proto,
-           shareopts, sourcestr, dataset);
-#endif
-
        return (process_share(impl_handle, impl_share, mountpoint, NULL,
            proto, shareopts, NULL, dataset, B_FALSE));
 }
        return (process_share(impl_handle, impl_share, mountpoint, NULL,
            proto, shareopts, NULL, dataset, B_FALSE));
 }
index 981c5ae142742ae26c02dfa69b2179e4fb439224..55d8fd7ab3bfdd11697358a2bfc1b45517a43e55 100644 (file)
@@ -5,7 +5,7 @@ includedir=${prefix}/include
 
 Name: libzfs
 Description: LibZFS library
 
 Name: libzfs
 Description: LibZFS library
-Version: 0.7.5
+Version: 0.7.6
 URL: http://zfsonlinux.org
 Requires: libzfs_core
 Cflags: -I${includedir}/libzfs -I${includedir}/libspl
 URL: http://zfsonlinux.org
 Requires: libzfs_core
 Cflags: -I${includedir}/libzfs -I${includedir}/libspl
index d7e5433f247cdcd44f19ceb778f722f885d8b869..f57291a4f695dd7ad56cde6f24ccdf1a6780778b 100644 (file)
@@ -5,7 +5,7 @@ includedir=${prefix}/include
 
 Name: libzfs_core
 Description: LibZFS core library
 
 Name: libzfs_core
 Description: LibZFS core library
-Version: 0.7.5
+Version: 0.7.6
 URL: http://zfsonlinux.org
 Cflags: -I${includedir}/libzfs -I${includedir}/libspl
 Libs: -L${libdir} -lzfs_core
 URL: http://zfsonlinux.org
 Cflags: -I${includedir}/libzfs -I${includedir}/libspl
 Libs: -L${libdir} -lzfs_core
index d6e85024d55014ac9502218c1f69b045a57c6808..b65dbc826854a766c912c52d184d4db6c7a4f205 100644 (file)
@@ -2244,8 +2244,10 @@ static void
 get_source(zfs_handle_t *zhp, zprop_source_t *srctype, char *source,
     char *statbuf, size_t statlen)
 {
 get_source(zfs_handle_t *zhp, zprop_source_t *srctype, char *source,
     char *statbuf, size_t statlen)
 {
-       if (statbuf == NULL || *srctype == ZPROP_SRC_TEMPORARY)
+       if (statbuf == NULL ||
+           srctype == NULL || *srctype == ZPROP_SRC_TEMPORARY) {
                return;
                return;
+       }
 
        if (source == NULL) {
                *srctype = ZPROP_SRC_NONE;
 
        if (source == NULL) {
                *srctype = ZPROP_SRC_NONE;
index 8b52224758da034401995b5e5aad527ac3ca35c2..39c0672938eb72cfb0e038093d09b12dc456d239 100644 (file)
@@ -309,7 +309,7 @@ zpool_label_disk_wait(char *path, int timeout_ms)
                dev = udev_device_new_from_subsystem_sysname(udev,
                    "block", sysname);
                if ((dev != NULL) && udev_device_is_ready(dev)) {
                dev = udev_device_new_from_subsystem_sysname(udev,
                    "block", sysname);
                if ((dev != NULL) && udev_device_is_ready(dev)) {
-                       struct udev_list_entry *links, *link;
+                       struct udev_list_entry *links, *link = NULL;
 
                        ret = 0;
                        links = udev_device_get_devlinks_list_entry(dev);
 
                        ret = 0;
                        links = udev_device_get_devlinks_list_entry(dev);
index db8079fb3ec60558638cb55d466c4a2415453054..ec190022f0af73d25818d45b1adde5d7589900c9 100644 (file)
@@ -3252,7 +3252,7 @@ zfs_receive_one(libzfs_handle_t *hdl, int infd, const char *tosnap,
        nvlist_t *oxprops = NULL; /* override (-o) and exclude (-x) props */
        nvlist_t *origprops = NULL; /* original props (if destination exists) */
        zfs_type_t type;
        nvlist_t *oxprops = NULL; /* override (-o) and exclude (-x) props */
        nvlist_t *origprops = NULL; /* original props (if destination exists) */
        zfs_type_t type;
-       boolean_t toplevel;
+       boolean_t toplevel = B_FALSE;
        boolean_t zoned = B_FALSE;
 
        begin_time = time(NULL);
        boolean_t zoned = B_FALSE;
 
        begin_time = time(NULL);
@@ -3586,7 +3586,8 @@ zfs_receive_one(libzfs_handle_t *hdl, int infd, const char *tosnap,
                goto out;
        }
 
                goto out;
        }
 
-       toplevel = chopprefix[0] != '/';
+       if (top_zfs && *top_zfs == NULL)
+               toplevel = B_TRUE;
        if (drrb->drr_type == DMU_OST_ZVOL) {
                type = ZFS_TYPE_VOLUME;
        } else if (drrb->drr_type == DMU_OST_ZFS) {
        if (drrb->drr_type == DMU_OST_ZVOL) {
                type = ZFS_TYPE_VOLUME;
        } else if (drrb->drr_type == DMU_OST_ZFS) {
index 4c957029d8abda5af774d036a49b846ee02880d4..19e6becfd1c689ade04d6c3416a477c5dea5c3d6 100644 (file)
@@ -96,17 +96,6 @@ successfully compressed before writing. A value of 100 disables this feature.
 Default value: \fB200\fR.
 .RE
 
 Default value: \fB200\fR.
 .RE
 
-.sp
-.ne 2
-.na
-\fBl2arc_nocompress\fR (int)
-.ad
-.RS 12n
-Skip compressing L2ARC buffers
-.sp
-Use \fB1\fR for yes and \fB0\fR for no (default).
-.RE
-
 .sp
 .ne 2
 .na
 .sp
 .ne 2
 .na
index 765ac7fb72e6bea70a46050e2255e0feee9ca8fc..138b041c83cbecc5f00e92c8a372dd14c9b6b009 100644 (file)
@@ -250,7 +250,7 @@ abd_alloc_pages(abd_t *abd, size_t size)
        struct list_head pages;
        struct sg_table table;
        struct scatterlist *sg;
        struct list_head pages;
        struct sg_table table;
        struct scatterlist *sg;
-       struct page *page, *tmp_page;
+       struct page *page, *tmp_page = NULL;
        gfp_t gfp = __GFP_NOWARN | GFP_NOIO;
        gfp_t gfp_comp = (gfp | __GFP_NORETRY | __GFP_COMP) & ~__GFP_RECLAIM;
        int max_order = MIN(zfs_abd_scatter_max_order, MAX_ORDER - 1);
        gfp_t gfp = __GFP_NOWARN | GFP_NOIO;
        gfp_t gfp_comp = (gfp | __GFP_NORETRY | __GFP_COMP) & ~__GFP_RECLAIM;
        int max_order = MIN(zfs_abd_scatter_max_order, MAX_ORDER - 1);
@@ -334,12 +334,12 @@ abd_alloc_pages(abd_t *abd, size_t size)
 static void
 abd_alloc_pages(abd_t *abd, size_t size)
 {
 static void
 abd_alloc_pages(abd_t *abd, size_t size)
 {
-       struct scatterlist *sg;
+       struct scatterlist *sg = NULL;
        struct sg_table table;
        struct page *page;
        gfp_t gfp = __GFP_NOWARN | GFP_NOIO;
        int nr_pages = abd_chunkcnt_for_bytes(size);
        struct sg_table table;
        struct page *page;
        gfp_t gfp = __GFP_NOWARN | GFP_NOIO;
        int nr_pages = abd_chunkcnt_for_bytes(size);
-       int i;
+       int i = 0;
 
        while (sg_alloc_table(&table, nr_pages, gfp)) {
                ABDSTAT_BUMP(abdstat_scatter_sg_table_retry);
 
        while (sg_alloc_table(&table, nr_pages, gfp)) {
                ABDSTAT_BUMP(abdstat_scatter_sg_table_retry);
@@ -370,11 +370,11 @@ abd_alloc_pages(abd_t *abd, size_t size)
 static void
 abd_free_pages(abd_t *abd)
 {
 static void
 abd_free_pages(abd_t *abd)
 {
-       struct scatterlist *sg;
+       struct scatterlist *sg = NULL;
        struct sg_table table;
        struct page *page;
        int nr_pages = ABD_SCATTER(abd).abd_nents;
        struct sg_table table;
        struct page *page;
        int nr_pages = ABD_SCATTER(abd).abd_nents;
-       int order, i;
+       int order, i = 0;
 
        if (abd->abd_flags & ABD_FLAG_MULTI_ZONE)
                ABDSTAT_BUMPDOWN(abdstat_scatter_page_multi_zone);
 
        if (abd->abd_flags & ABD_FLAG_MULTI_ZONE)
                ABDSTAT_BUMPDOWN(abdstat_scatter_page_multi_zone);
@@ -543,8 +543,8 @@ abd_verify(abd_t *abd)
                ASSERT3P(abd->abd_u.abd_linear.abd_buf, !=, NULL);
        } else {
                size_t n;
                ASSERT3P(abd->abd_u.abd_linear.abd_buf, !=, NULL);
        } else {
                size_t n;
-               int i;
-               struct scatterlist *sg;
+               int i = 0;
+               struct scatterlist *sg = NULL;
 
                ASSERT3U(ABD_SCATTER(abd).abd_nents, >, 0);
                ASSERT3U(ABD_SCATTER(abd).abd_offset, <,
 
                ASSERT3U(ABD_SCATTER(abd).abd_nents, >, 0);
                ASSERT3U(ABD_SCATTER(abd).abd_offset, <,
@@ -749,8 +749,8 @@ abd_get_offset_impl(abd_t *sabd, size_t off, size_t size)
                abd->abd_u.abd_linear.abd_buf =
                    (char *)sabd->abd_u.abd_linear.abd_buf + off;
        } else {
                abd->abd_u.abd_linear.abd_buf =
                    (char *)sabd->abd_u.abd_linear.abd_buf + off;
        } else {
-               int i;
-               struct scatterlist *sg;
+               int i = 0;
+               struct scatterlist *sg = NULL;
                size_t new_offset = sabd->abd_u.abd_scatter.abd_offset + off;
 
                abd = abd_alloc_struct();
                size_t new_offset = sabd->abd_u.abd_scatter.abd_offset + off;
 
                abd = abd_alloc_struct();
index 2b0a78d4be4798a06be0f09cdc6916c34a4ef92a..264e677357439bb1da0ec63f685da99b01b95837 100644 (file)
@@ -429,9 +429,14 @@ typedef struct arc_stats {
         * by multiple buffers.
         */
        kstat_named_t arcstat_mutex_miss;
         * by multiple buffers.
         */
        kstat_named_t arcstat_mutex_miss;
+       /*
+        * Number of buffers skipped when updating the access state due to the
+        * header having already been released after acquiring the hash lock.
+        */
+       kstat_named_t arcstat_access_skip;
        /*
         * Number of buffers skipped because they have I/O in progress, are
        /*
         * Number of buffers skipped because they have I/O in progress, are
-        * indrect prefetch buffers that have not lived long enough, or are
+        * indirect prefetch buffers that have not lived long enough, or are
         * not from the spa we're trying to evict from.
         */
        kstat_named_t arcstat_evict_skip;
         * not from the spa we're trying to evict from.
         */
        kstat_named_t arcstat_evict_skip;
@@ -667,6 +672,7 @@ static arc_stats_t arc_stats = {
        { "mfu_ghost_hits",             KSTAT_DATA_UINT64 },
        { "deleted",                    KSTAT_DATA_UINT64 },
        { "mutex_miss",                 KSTAT_DATA_UINT64 },
        { "mfu_ghost_hits",             KSTAT_DATA_UINT64 },
        { "deleted",                    KSTAT_DATA_UINT64 },
        { "mutex_miss",                 KSTAT_DATA_UINT64 },
+       { "access_skip",                KSTAT_DATA_UINT64 },
        { "evict_skip",                 KSTAT_DATA_UINT64 },
        { "evict_not_enough",           KSTAT_DATA_UINT64 },
        { "evict_l2_cached",            KSTAT_DATA_UINT64 },
        { "evict_skip",                 KSTAT_DATA_UINT64 },
        { "evict_not_enough",           KSTAT_DATA_UINT64 },
        { "evict_l2_cached",            KSTAT_DATA_UINT64 },
@@ -4926,7 +4932,51 @@ arc_access(arc_buf_hdr_t *hdr, kmutex_t *hash_lock)
        }
 }
 
        }
 }
 
-/* a generic arc_done_func_t which you can use */
+/*
+ * This routine is called by dbuf_hold() to update the arc_access() state
+ * which otherwise would be skipped for entries in the dbuf cache.
+ */
+void
+arc_buf_access(arc_buf_t *buf)
+{
+       mutex_enter(&buf->b_evict_lock);
+       arc_buf_hdr_t *hdr = buf->b_hdr;
+
+       /*
+        * Avoid taking the hash_lock when possible as an optimization.
+        * The header must be checked again under the hash_lock in order
+        * to handle the case where it is concurrently being released.
+        */
+       if (hdr->b_l1hdr.b_state == arc_anon || HDR_EMPTY(hdr)) {
+               mutex_exit(&buf->b_evict_lock);
+               return;
+       }
+
+       kmutex_t *hash_lock = HDR_LOCK(hdr);
+       mutex_enter(hash_lock);
+
+       if (hdr->b_l1hdr.b_state == arc_anon || HDR_EMPTY(hdr)) {
+               mutex_exit(hash_lock);
+               mutex_exit(&buf->b_evict_lock);
+               ARCSTAT_BUMP(arcstat_access_skip);
+               return;
+       }
+
+       mutex_exit(&buf->b_evict_lock);
+
+       ASSERT(hdr->b_l1hdr.b_state == arc_mru ||
+           hdr->b_l1hdr.b_state == arc_mfu);
+
+       DTRACE_PROBE1(arc__hit, arc_buf_hdr_t *, hdr);
+       arc_access(hdr, hash_lock);
+       mutex_exit(hash_lock);
+
+       ARCSTAT_BUMP(arcstat_hits);
+       ARCSTAT_CONDSTAT(!HDR_PREFETCH(hdr), demand, prefetch,
+           !HDR_ISTYPE_METADATA(hdr), data, metadata, hits);
+}
+
+/* a generic arc_read_done_func_t which you can use */
 /* ARGSUSED */
 void
 arc_bcopy_func(zio_t *zio, arc_buf_t *buf, void *arg)
 /* ARGSUSED */
 void
 arc_bcopy_func(zio_t *zio, arc_buf_t *buf, void *arg)
index 60f52d29426b369b3df187261775eb80083854e7..4ee121f5a5fbfdcdf0ad0320eb6bf15d43151532 100644 (file)
@@ -2719,8 +2719,10 @@ __dbuf_hold_impl(struct dbuf_hold_impl_data *dh)
                return (SET_ERROR(ENOENT));
        }
 
                return (SET_ERROR(ENOENT));
        }
 
-       if (dh->dh_db->db_buf != NULL)
+       if (dh->dh_db->db_buf != NULL) {
+               arc_buf_access(dh->dh_db->db_buf);
                ASSERT3P(dh->dh_db->db.db_data, ==, dh->dh_db->db_buf->b_data);
                ASSERT3P(dh->dh_db->db.db_data, ==, dh->dh_db->db_buf->b_data);
+       }
 
        ASSERT(dh->dh_db->db_buf == NULL || arc_referenced(dh->dh_db->db_buf));
 
 
        ASSERT(dh->dh_db->db_buf == NULL || arc_referenced(dh->dh_db->db_buf));
 
index 9a7a6968d6319163b39ab2e5ea2be6f023ae731c..3425d542f98327bd51796e08d5336e724e889aa6 100644 (file)
@@ -1853,6 +1853,7 @@ dmu_objset_space_upgrade(objset_t *os)
                dmu_tx_hold_bonus(tx, obj);
                objerr = dmu_tx_assign(tx, TXG_WAIT);
                if (objerr != 0) {
                dmu_tx_hold_bonus(tx, obj);
                objerr = dmu_tx_assign(tx, TXG_WAIT);
                if (objerr != 0) {
+                       dmu_buf_rele(db, FTAG);
                        dmu_tx_abort(tx);
                        continue;
                }
                        dmu_tx_abort(tx);
                        continue;
                }
index 097fa774ad0650aab2597b8e6cb200009600e858..c3cc03a691a7776e0249c63c5798a830905bfae5 100644 (file)
@@ -1200,7 +1200,7 @@ dmu_tx_do_callbacks(list_t *cb_list, int error)
 {
        dmu_tx_callback_t *dcb;
 
 {
        dmu_tx_callback_t *dcb;
 
-       while ((dcb = list_head(cb_list)) != NULL) {
+       while ((dcb = list_tail(cb_list)) != NULL) {
                list_remove(cb_list, dcb);
                dcb->dcb_func(dcb->dcb_data, error);
                kmem_free(dcb, sizeof (dmu_tx_callback_t));
                list_remove(cb_list, dcb);
                dcb->dcb_func(dcb->dcb_data, error);
                kmem_free(dcb, sizeof (dmu_tx_callback_t));
index 1bf5c4e34d68dcfb819cae57bdd2532bd0f50b60..e72e9ef9cbef62d5f46fccb0ea0c659488741ced 100644 (file)
@@ -228,19 +228,33 @@ dmu_zfetch(zfetch_t *zf, uint64_t blkid, uint64_t nblks, boolean_t fetch_data)
 
        rw_enter(&zf->zf_rwlock, RW_READER);
 
 
        rw_enter(&zf->zf_rwlock, RW_READER);
 
+       /*
+        * Find matching prefetch stream.  Depending on whether the accesses
+        * are block-aligned, first block of the new access may either follow
+        * the last block of the previous access, or be equal to it.
+        */
        for (zs = list_head(&zf->zf_stream); zs != NULL;
            zs = list_next(&zf->zf_stream, zs)) {
        for (zs = list_head(&zf->zf_stream); zs != NULL;
            zs = list_next(&zf->zf_stream, zs)) {
-               if (blkid == zs->zs_blkid) {
+               if (blkid == zs->zs_blkid || blkid + 1 == zs->zs_blkid) {
                        mutex_enter(&zs->zs_lock);
                        /*
                         * zs_blkid could have changed before we
                         * acquired zs_lock; re-check them here.
                         */
                        mutex_enter(&zs->zs_lock);
                        /*
                         * zs_blkid could have changed before we
                         * acquired zs_lock; re-check them here.
                         */
-                       if (blkid != zs->zs_blkid) {
-                               mutex_exit(&zs->zs_lock);
-                               continue;
+                       if (blkid == zs->zs_blkid) {
+                               break;
+                       } else if (blkid + 1 == zs->zs_blkid) {
+                               blkid++;
+                               nblks--;
+                               if (nblks == 0) {
+                                       /* Already prefetched this before. */
+                                       mutex_exit(&zs->zs_lock);
+                                       rw_exit(&zf->zf_rwlock);
+                                       return;
+                               }
+                               break;
                        }
                        }
-                       break;
+                       mutex_exit(&zs->zs_lock);
                }
        }
 
                }
        }
 
index 0439e4b46f513363fb09829fa113b078cbdc3b10..d230b4db40ff5375f6bbd00d4f4c0a12ec6b88ff 100644 (file)
@@ -116,7 +116,8 @@ static const zio_vsd_ops_t vdev_mirror_vsd_ops = {
 static int
 vdev_mirror_load(mirror_map_t *mm, vdev_t *vd, uint64_t zio_offset)
 {
 static int
 vdev_mirror_load(mirror_map_t *mm, vdev_t *vd, uint64_t zio_offset)
 {
-       uint64_t lastoffset;
+       uint64_t last_offset;
+       int64_t offset_diff;
        int load;
 
        /* All DVAs have equal weight at the root. */
        int load;
 
        /* All DVAs have equal weight at the root. */
@@ -129,13 +130,17 @@ vdev_mirror_load(mirror_map_t *mm, vdev_t *vd, uint64_t zio_offset)
         * worse overall when resilvering with compared to without.
         */
 
         * worse overall when resilvering with compared to without.
         */
 
+       /* Fix zio_offset for leaf vdevs */
+       if (vd->vdev_ops->vdev_op_leaf)
+               zio_offset += VDEV_LABEL_START_SIZE;
+
        /* Standard load based on pending queue length. */
        load = vdev_queue_length(vd);
        /* Standard load based on pending queue length. */
        load = vdev_queue_length(vd);
-       lastoffset = vdev_queue_lastoffset(vd);
+       last_offset = vdev_queue_last_offset(vd);
 
        if (vd->vdev_nonrot) {
                /* Non-rotating media. */
 
        if (vd->vdev_nonrot) {
                /* Non-rotating media. */
-               if (lastoffset == zio_offset)
+               if (last_offset == zio_offset)
                        return (load + zfs_vdev_mirror_non_rotating_inc);
 
                /*
                        return (load + zfs_vdev_mirror_non_rotating_inc);
 
                /*
@@ -148,16 +153,16 @@ vdev_mirror_load(mirror_map_t *mm, vdev_t *vd, uint64_t zio_offset)
        }
 
        /* Rotating media I/O's which directly follow the last I/O. */
        }
 
        /* Rotating media I/O's which directly follow the last I/O. */
-       if (lastoffset == zio_offset)
+       if (last_offset == zio_offset)
                return (load + zfs_vdev_mirror_rotating_inc);
 
        /*
         * Apply half the seek increment to I/O's within seek offset
                return (load + zfs_vdev_mirror_rotating_inc);
 
        /*
         * Apply half the seek increment to I/O's within seek offset
-        * of the last I/O queued to this vdev as they should incur less
+        * of the last I/O issued to this vdev as they should incur less
         * of a seek increment.
         */
         * of a seek increment.
         */
-       if (ABS(lastoffset - zio_offset) <
-           zfs_vdev_mirror_rotating_seek_offset)
+       offset_diff = (int64_t)(last_offset - zio_offset);
+       if (ABS(offset_diff) < zfs_vdev_mirror_rotating_seek_offset)
                return (load + (zfs_vdev_mirror_rotating_seek_inc / 2));
 
        /* Apply the full seek increment to all other I/O's. */
                return (load + (zfs_vdev_mirror_rotating_seek_inc / 2));
 
        /* Apply the full seek increment to all other I/O's. */
@@ -382,29 +387,20 @@ vdev_mirror_child_select(zio_t *zio)
                mm->mm_preferred_cnt++;
        }
 
                mm->mm_preferred_cnt++;
        }
 
-       if (mm->mm_preferred_cnt == 1) {
-               vdev_queue_register_lastoffset(
-                   mm->mm_child[mm->mm_preferred[0]].mc_vd, zio);
+       if (mm->mm_preferred_cnt == 1)
                return (mm->mm_preferred[0]);
                return (mm->mm_preferred[0]);
-       }
 
 
-       if (mm->mm_preferred_cnt > 1) {
-               int c = vdev_mirror_preferred_child_randomize(zio);
 
 
-               vdev_queue_register_lastoffset(mm->mm_child[c].mc_vd, zio);
-               return (c);
-       }
+       if (mm->mm_preferred_cnt > 1)
+               return (vdev_mirror_preferred_child_randomize(zio));
 
        /*
         * Every device is either missing or has this txg in its DTL.
         * Look for any child we haven't already tried before giving up.
         */
        for (c = 0; c < mm->mm_children; c++) {
 
        /*
         * Every device is either missing or has this txg in its DTL.
         * Look for any child we haven't already tried before giving up.
         */
        for (c = 0; c < mm->mm_children; c++) {
-               if (!mm->mm_child[c].mc_tried) {
-                       vdev_queue_register_lastoffset(mm->mm_child[c].mc_vd,
-                           zio);
+               if (!mm->mm_child[c].mc_tried)
                        return (c);
                        return (c);
-               }
        }
 
        /*
        }
 
        /*
index 6b3e8729159009749b49c702726a3bc4a0c7d10c..40cba340aafd682d4f066fa7240d36869c3aff88 100644 (file)
@@ -393,7 +393,7 @@ vdev_queue_init(vdev_t *vd)
                    sizeof (zio_t), offsetof(struct zio, io_queue_node));
        }
 
                    sizeof (zio_t), offsetof(struct zio, io_queue_node));
        }
 
-       vq->vq_lastoffset = 0;
+       vq->vq_last_offset = 0;
 }
 
 void
 }
 
 void
@@ -699,9 +699,8 @@ again:
         */
        tree = vdev_queue_class_tree(vq, p);
        vq->vq_io_search.io_timestamp = 0;
         */
        tree = vdev_queue_class_tree(vq, p);
        vq->vq_io_search.io_timestamp = 0;
-       vq->vq_io_search.io_offset = vq->vq_last_offset + 1;
-       VERIFY3P(avl_find(tree, &vq->vq_io_search,
-           &idx), ==, NULL);
+       vq->vq_io_search.io_offset = vq->vq_last_offset - 1;
+       VERIFY3P(avl_find(tree, &vq->vq_io_search, &idx), ==, NULL);
        zio = avl_nearest(tree, idx, AVL_AFTER);
        if (zio == NULL)
                zio = avl_first(tree);
        zio = avl_nearest(tree, idx, AVL_AFTER);
        if (zio == NULL)
                zio = avl_first(tree);
@@ -728,7 +727,7 @@ again:
        }
 
        vdev_queue_pending_add(vq, zio);
        }
 
        vdev_queue_pending_add(vq, zio);
-       vq->vq_last_offset = zio->io_offset;
+       vq->vq_last_offset = zio->io_offset + zio->io_size;
 
        return (zio);
 }
 
        return (zio);
 }
@@ -806,7 +805,7 @@ vdev_queue_io_done(zio_t *zio)
 }
 
 /*
 }
 
 /*
- * As these three methods are only used for load calculations we're not
+ * As these two methods are only used for load calculations we're not
  * concerned if we get an incorrect value on 32bit platforms due to lack of
  * vq_lock mutex use here, instead we prefer to keep it lock free for
  * performance.
  * concerned if we get an incorrect value on 32bit platforms due to lack of
  * vq_lock mutex use here, instead we prefer to keep it lock free for
  * performance.
@@ -818,15 +817,9 @@ vdev_queue_length(vdev_t *vd)
 }
 
 uint64_t
 }
 
 uint64_t
-vdev_queue_lastoffset(vdev_t *vd)
+vdev_queue_last_offset(vdev_t *vd)
 {
 {
-       return (vd->vdev_queue.vq_lastoffset);
-}
-
-void
-vdev_queue_register_lastoffset(vdev_t *vd, zio_t *zio)
-{
-       vd->vdev_queue.vq_lastoffset = zio->io_offset + zio->io_size;
+       return (vd->vdev_queue.vq_last_offset);
 }
 
 #if defined(_KERNEL) && defined(HAVE_SPL)
 }
 
 #if defined(_KERNEL) && defined(HAVE_SPL)
index c6ee30291f7df550e340a8060dfbb74f45bcd373..9a8bbccd92d7a80b20b189fc9bf8bfad3633733f 100644 (file)
@@ -977,11 +977,25 @@ zfs_link_destroy(zfs_dirlock_t *dl, znode_t *zp, dmu_tx_t *tx, int flag,
  * Indicate whether the directory is empty.  Works with or without z_lock
  * held, but can only be consider a hint in the latter case.  Returns true
  * if only "." and ".." remain and there's no work in progress.
  * Indicate whether the directory is empty.  Works with or without z_lock
  * held, but can only be consider a hint in the latter case.  Returns true
  * if only "." and ".." remain and there's no work in progress.
+ *
+ * The internal ZAP size, rather than zp->z_size, needs to be checked since
+ * some consumers (Lustre) do not strictly maintain an accurate SA_ZPL_SIZE.
  */
 boolean_t
 zfs_dirempty(znode_t *dzp)
 {
  */
 boolean_t
 zfs_dirempty(znode_t *dzp)
 {
-       return (dzp->z_size == 2 && dzp->z_dirlocks == 0);
+       zfsvfs_t *zfsvfs = ZTOZSB(dzp);
+       uint64_t count;
+       int error;
+
+       if (dzp->z_dirlocks != NULL)
+               return (B_FALSE);
+
+       error = zap_count(zfsvfs->z_os, dzp->z_id, &count);
+       if (error != 0 || count != 0)
+               return (B_FALSE);
+
+       return (B_TRUE);
 }
 
 int
 }
 
 int
index d195eded76dc818f2f5da68677ce53915449ba41..f4f509a7efcaad5e617817be0e8e72b30bbf84bd 100644 (file)
@@ -5901,20 +5901,26 @@ static int
 zfs_ioc_pool_sync(const char *pool, nvlist_t *innvl, nvlist_t *onvl)
 {
        int err;
 zfs_ioc_pool_sync(const char *pool, nvlist_t *innvl, nvlist_t *onvl)
 {
        int err;
-       boolean_t force;
+       boolean_t force = B_FALSE;
        spa_t *spa;
 
        if ((err = spa_open(pool, &spa, FTAG)) != 0)
                return (err);
 
        spa_t *spa;
 
        if ((err = spa_open(pool, &spa, FTAG)) != 0)
                return (err);
 
-       force = fnvlist_lookup_boolean_value(innvl, "force");
+       if (innvl) {
+               if (nvlist_lookup_boolean_value(innvl, "force", &force) != 0) {
+                       err = SET_ERROR(EINVAL);
+                       goto out;
+               }
+       }
+
        if (force) {
                spa_config_enter(spa, SCL_CONFIG, FTAG, RW_WRITER);
                vdev_config_dirty(spa->spa_root_vdev);
                spa_config_exit(spa, SCL_CONFIG, FTAG);
        }
        txg_wait_synced(spa_get_dsl(spa), 0);
        if (force) {
                spa_config_enter(spa, SCL_CONFIG, FTAG, RW_WRITER);
                vdev_config_dirty(spa->spa_root_vdev);
                spa_config_exit(spa, SCL_CONFIG, FTAG);
        }
        txg_wait_synced(spa_get_dsl(spa), 0);
-
+out:
        spa_close(spa, FTAG);
 
        return (err);
        spa_close(spa, FTAG);
 
        return (err);
index 6a1dab5c984e9aef79c10a5745caf7ff1dd445fc..6f6ce79db20e92c66412387bd336e230c0143531 100644 (file)
@@ -836,6 +836,7 @@ zfs_write(struct inode *ip, uio_t *uio, int ioflag, cred_t *cr)
                            aiov->iov_base != abuf->b_data)) {
                                ASSERT(xuio);
                                dmu_write(zfsvfs->z_os, zp->z_id, woff,
                            aiov->iov_base != abuf->b_data)) {
                                ASSERT(xuio);
                                dmu_write(zfsvfs->z_os, zp->z_id, woff,
+                                   /* cppcheck-suppress nullPointer */
                                    aiov->iov_len, aiov->iov_base, tx);
                                dmu_return_arcbuf(abuf);
                                xuio_stat_wbuf_copied();
                                    aiov->iov_len, aiov->iov_base, tx);
                                dmu_return_arcbuf(abuf);
                                xuio_stat_wbuf_copied();
index 0c626b122193fde87444a6737ced0d27a733a913..ebb6e7be2cac5498e7ae1b57f04a8bab41733136 100644 (file)
@@ -333,7 +333,7 @@ zpl_xattr_get_sa(struct inode *ip, const char *name, void *value, size_t size)
        if (error)
                return (error);
 
        if (error)
                return (error);
 
-       if (!size)
+       if (size == 0 || value == NULL)
                return (nv_size);
 
        if (size < nv_size)
                return (nv_size);
 
        if (size < nv_size)
index 5293f95fb02014341a6c59122b89d07948a9c46a..aac4942098ad6e6bf2b461ffd084029e2cea194b 100644 (file)
@@ -202,7 +202,7 @@ static zvol_state_t *
 zvol_find_by_name_hash(const char *name, uint64_t hash, int mode)
 {
        zvol_state_t *zv;
 zvol_find_by_name_hash(const char *name, uint64_t hash, int mode)
 {
        zvol_state_t *zv;
-       struct hlist_node *p;
+       struct hlist_node *p = NULL;
 
        mutex_enter(&zvol_state_lock);
        hlist_for_each(p, ZVOL_HT_HEAD(hash)) {
 
        mutex_enter(&zvol_state_lock);
        hlist_for_each(p, ZVOL_HT_HEAD(hash)) {
index f4c92b9985749d414836714d2b4aa18de127b430..cb23b0a8f6e8b50f001706618520c76abcced8a9 100644 (file)
@@ -191,6 +191,9 @@ chmod u+x ${RPM_BUILD_ROOT}%{kmodinstdir_prefix}/*/extra/*/*/*
 rm -rf $RPM_BUILD_ROOT
 
 %changelog
 rm -rf $RPM_BUILD_ROOT
 
 %changelog
+* Thu Feb 01 2018 Tony Hutter <hutter2@llnl.gov> - 0.7.6-1
+- Released 0.7.6-1, detailed release notes are available at:
+- https://github.com/zfsonlinux/zfs/releases/tag/zfs-0.7.6
 * Mon Dec 18 2017 Tony Hutter <hutter2@llnl.gov> - 0.7.5-1
 - Released 0.7.5-1, detailed release notes are available at:
 - https://github.com/zfsonlinux/zfs/releases/tag/zfs-0.7.5
 * Mon Dec 18 2017 Tony Hutter <hutter2@llnl.gov> - 0.7.5-1
 - Released 0.7.5-1, detailed release notes are available at:
 - https://github.com/zfsonlinux/zfs/releases/tag/zfs-0.7.5
index afa45268a36b57a9426ab454cc6902f31fe9fe79..8df57fa46e465d27f92f1ab6b7fafde2890ca4f7 100644 (file)
@@ -333,6 +333,9 @@ exit 0
 %endif
 
 %changelog
 %endif
 
 %changelog
+* Thu Feb 01 2018 Tony Hutter <hutter2@llnl.gov> - 0.7.6-1
+- Released 0.7.6-1, detailed release notes are available at:
+- https://github.com/zfsonlinux/zfs/releases/tag/zfs-0.7.6
 * Mon Dec 18 2017 Tony Hutter <hutter2@llnl.gov> - 0.7.5-1
 - Released 0.7.5-1, detailed release notes are available at:
 - https://github.com/zfsonlinux/zfs/releases/tag/zfs-0.7.5
 * Mon Dec 18 2017 Tony Hutter <hutter2@llnl.gov> - 0.7.5-1
 - Released 0.7.5-1, detailed release notes are available at:
 - https://github.com/zfsonlinux/zfs/releases/tag/zfs-0.7.5
index afa45268a36b57a9426ab454cc6902f31fe9fe79..8df57fa46e465d27f92f1ab6b7fafde2890ca4f7 100644 (file)
@@ -333,6 +333,9 @@ exit 0
 %endif
 
 %changelog
 %endif
 
 %changelog
+* Thu Feb 01 2018 Tony Hutter <hutter2@llnl.gov> - 0.7.6-1
+- Released 0.7.6-1, detailed release notes are available at:
+- https://github.com/zfsonlinux/zfs/releases/tag/zfs-0.7.6
 * Mon Dec 18 2017 Tony Hutter <hutter2@llnl.gov> - 0.7.5-1
 - Released 0.7.5-1, detailed release notes are available at:
 - https://github.com/zfsonlinux/zfs/releases/tag/zfs-0.7.5
 * Mon Dec 18 2017 Tony Hutter <hutter2@llnl.gov> - 0.7.5-1
 - Released 0.7.5-1, detailed release notes are available at:
 - https://github.com/zfsonlinux/zfs/releases/tag/zfs-0.7.5
index 73c708c0b93ecc8eb1974988168357485e810d93..00b33dddfbcbb812923776544c6c6baabef49e24 100755 (executable)
@@ -383,7 +383,7 @@ line: while (<$filehandle>) {
 
        # is this the beginning or ending of a function?
        # (not if "struct foo\n{\n")
 
        # is this the beginning or ending of a function?
        # (not if "struct foo\n{\n")
-       if (/^{$/ && $prev =~ /\)\s*(const\s*)?(\/\*.*\*\/\s*)?\\?$/) {
+       if (/^\{$/ && $prev =~ /\)\s*(const\s*)?(\/\*.*\*\/\s*)?\\?$/) {
                $in_function = 1;
                $in_declaration = 1;
                $in_function_header = 0;
                $in_function = 1;
                $in_declaration = 1;
                $in_function_header = 0;
@@ -391,7 +391,7 @@ line: while (<$filehandle>) {
                $prev = $line;
                next line;
        }
                $prev = $line;
                next line;
        }
-       if (/^}\s*(\/\*.*\*\/\s*)*$/) {
+       if (/^\}\s*(\/\*.*\*\/\s*)*$/) {
                if ($prev =~ /^\s*return\s*;/) {
                        err_prev("unneeded return at end of function");
                }
                if ($prev =~ /^\s*return\s*;/) {
                        err_prev("unneeded return at end of function");
                }
@@ -401,7 +401,7 @@ line: while (<$filehandle>) {
                next line;
        }
        if ($in_function_header && ! /^    (\w|\.)/ ) {
                next line;
        }
        if ($in_function_header && ! /^    (\w|\.)/ ) {
-               if (/^{}$/ # empty functions
+               if (/^\{\}$/ # empty functions
                || /;/ #run function with multiline arguments
                || /#/ #preprocessor commands
                || /^[^\s\\]*\(.*\)$/ #functions without ; at the end
                || /;/ #run function with multiline arguments
                || /#/ #preprocessor commands
                || /^[^\s\\]*\(.*\)$/ #functions without ; at the end
@@ -431,7 +431,7 @@ line: while (<$filehandle>) {
                        $function_header_full_indent = 1;
                }
        }
                        $function_header_full_indent = 1;
                }
        }
-       if ($in_function_header && /^{$/) {
+       if ($in_function_header && /^\{$/) {
                $in_function_header = 0;
                $function_header_full_indent = 0;
                $in_function = 1;
                $in_function_header = 0;
                $function_header_full_indent = 0;
                $in_function = 1;
@@ -440,7 +440,7 @@ line: while (<$filehandle>) {
                $in_function_header = 0;
                $function_header_full_indent = 0;
        }
                $in_function_header = 0;
                $function_header_full_indent = 0;
        }
-       if ($in_function_header && /{$/ ) {
+       if ($in_function_header && /\{$/ ) {
                if ($picky) {
                        err("opening brace on same line as function header");
                }
                if ($picky) {
                        err("opening brace on same line as function header");
                }
@@ -670,14 +670,14 @@ line: while (<$filehandle>) {
        if (/\S\{/ && !/\{\{/) {
                err("missing space before left brace");
        }
        if (/\S\{/ && !/\{\{/) {
                err("missing space before left brace");
        }
-       if ($in_function && /^\s+{/ &&
+       if ($in_function && /^\s+\{/ &&
            ($prev =~ /\)\s*$/ || $prev =~ /\bstruct\s+\w+$/)) {
                err("left brace starting a line");
        }
            ($prev =~ /\)\s*$/ || $prev =~ /\bstruct\s+\w+$/)) {
                err("left brace starting a line");
        }
-       if (/}(else|while)/) {
+       if (/\}(else|while)/) {
                err("missing space after right brace");
        }
                err("missing space after right brace");
        }
-       if (/}\s\s+(else|while)/) {
+       if (/\}\s\s+(else|while)/) {
                err("extra space after right brace");
        }
        if (/\b_VOID\b|\bVOID\b|\bSTATIC\b/) {
                err("extra space after right brace");
        }
        if (/\b_VOID\b|\bVOID\b|\bSTATIC\b/) {
@@ -730,18 +730,18 @@ line: while (<$filehandle>) {
        if ($heuristic) {
                # cannot check this everywhere due to "struct {\n...\n} foo;"
                if ($in_function && !$in_declaration &&
        if ($heuristic) {
                # cannot check this everywhere due to "struct {\n...\n} foo;"
                if ($in_function && !$in_declaration &&
-                   /}./ && !/}\s+=/ && !/{.*}[;,]$/ && !/}(\s|\ 1)*$/ &&
-                   !/} (else|while)/ && !/}}/) {
+                   /\}./ && !/\}\s+=/ && !/\{.*\}[;,]$/ && !/\}(\s|\ 1)*$/ &&
+                   !/\} (else|while)/ && !/\}\}/) {
                        err("possible bad text following right brace");
                }
                # cannot check this because sub-blocks in
                # the middle of code are ok
                        err("possible bad text following right brace");
                }
                # cannot check this because sub-blocks in
                # the middle of code are ok
-               if ($in_function && /^\s+{/) {
+               if ($in_function && /^\s+\{/) {
                        err("possible left brace starting a line");
                }
        }
        if (/^\s*else\W/) {
                        err("possible left brace starting a line");
                }
        }
        if (/^\s*else\W/) {
-               if ($prev =~ /^\s*}$/) {
+               if ($prev =~ /^\s*\}$/) {
                        err_prefix($prev,
                            "else and right brace should be on same line");
                }
                        err_prefix($prev,
                            "else and right brace should be on same line");
                }
@@ -827,8 +827,8 @@ process_indent($)
 
        # skip over enumerations, array definitions, initializers, etc.
        if ($cont_off <= 0 && !/^\s*$special/ &&
 
        # skip over enumerations, array definitions, initializers, etc.
        if ($cont_off <= 0 && !/^\s*$special/ &&
-           (/(?:(?:\b(?:enum|struct|union)\s*[^\{]*)|(?:\s+=\s*)){/ ||
-           (/^\s*{/ && $prev =~ /=\s*(?:\/\*.*\*\/\s*)*$/))) {
+           (/(?:(?:\b(?:enum|struct|union)\s*[^\{]*)|(?:\s+=\s*))\{/ ||
+           (/^\s*\{/ && $prev =~ /=\s*(?:\/\*.*\*\/\s*)*$/))) {
                $cont_in = 0;
                $cont_off = tr/{/{/ - tr/}/}/;
                return;
                $cont_in = 0;
                $cont_off = tr/{/{/ - tr/}/}/;
                return;
@@ -851,14 +851,14 @@ process_indent($)
                return          if (/^\s*\}?$/);
                return          if (/^\s*\}?\s*else\s*\{?$/);
                return          if (/^\s*do\s*\{?$/);
                return          if (/^\s*\}?$/);
                return          if (/^\s*\}?\s*else\s*\{?$/);
                return          if (/^\s*do\s*\{?$/);
-               return          if (/{$/);
-               return          if (/}[,;]?$/);
+               return          if (/\{$/);
+               return          if (/\}[,;]?$/);
 
                # Allow macros on their own lines
                return          if (/^\s*[A-Z_][A-Z_0-9]*$/);
 
                # cases we don't deal with, generally non-kosher
 
                # Allow macros on their own lines
                return          if (/^\s*[A-Z_][A-Z_0-9]*$/);
 
                # cases we don't deal with, generally non-kosher
-               if (/{/) {
+               if (/\{/) {
                        err("stuff after {");
                        return;
                }
                        err("stuff after {");
                        return;
                }
@@ -927,7 +927,7 @@ process_indent($)
                        #
                        next            if (@cont_paren != 0);
                        if ($cont_special) {
                        #
                        next            if (@cont_paren != 0);
                        if ($cont_special) {
-                               if ($rest =~ /^\s*{?$/) {
+                               if ($rest =~ /^\s*\{?$/) {
                                        $cont_in = 0;
                                        last;
                                }
                                        $cont_in = 0;
                                        last;
                                }
index 854c2048a572ac3e896a21dbf6be14fe9967dbfd..f39e91ef9e955710e2d25b1acfd61c4f789da02a 100755 (executable)
@@ -52,6 +52,8 @@ function usage
            "    -s  Size of vdev devices.\n" \
            "    -f  Specify working directory for ztest vdev files.\n" \
            "    -c  Specify a core dump directory to use.\n" \
            "    -s  Size of vdev devices.\n" \
            "    -f  Specify working directory for ztest vdev files.\n" \
            "    -c  Specify a core dump directory to use.\n" \
+           "    -m  Max number of core dumps to allow before exiting.\n" \
+           "    -l  Create 'ztest.core.N' symlink to core directory.\n" \
            "    -h  Print this help message.\n" \
            "" >&2
 }
            "    -h  Print this help message.\n" \
            "" >&2
 }
@@ -70,12 +72,12 @@ function or_die
 
 # core file helpers
 origcorepattern="$(cat /proc/sys/kernel/core_pattern)"
 
 # core file helpers
 origcorepattern="$(cat /proc/sys/kernel/core_pattern)"
-coreglob="$(egrep -o '^([^|%[:space:]]*)' /proc/sys/kernel/core_pattern)*"
+coreglob="$(grep -E -o '^([^|%[:space:]]*)' /proc/sys/kernel/core_pattern)*"
 
 if [[ $coreglob = "*" ]]; then
         echo "Setting core file pattern..."
         echo "core" > /proc/sys/kernel/core_pattern
 
 if [[ $coreglob = "*" ]]; then
         echo "Setting core file pattern..."
         echo "core" > /proc/sys/kernel/core_pattern
-        coreglob="$(egrep -o '^([^|%[:space:]]*)' \
+        coreglob="$(grep -E -o '^([^|%[:space:]]*)' \
             /proc/sys/kernel/core_pattern)*"
 fi
 
             /proc/sys/kernel/core_pattern)*"
 fi
 
@@ -101,17 +103,28 @@ function store_core
 {
        core="$(core_file)"
        if [[ $ztrc -ne 0 ]] || [[ -f "$core" ]]; then
 {
        core="$(core_file)"
        if [[ $ztrc -ne 0 ]] || [[ -f "$core" ]]; then
+               df -h "$workdir" >>ztest.out
                coreid=$(date "+zloop-%y%m%d-%H%M%S")
                foundcrashes=$((foundcrashes + 1))
 
                coreid=$(date "+zloop-%y%m%d-%H%M%S")
                foundcrashes=$((foundcrashes + 1))
 
+               # zdb debugging
+               zdbcmd="$ZDB -U "$workdir/zpool.cache" -dddMmDDG ztest"
+               zdbdebug=$($zdbcmd 2>&1)
+               echo -e "$zdbcmd\n" >>ztest.zdb
+               echo "$zdbdebug" >>ztest.zdb
+
                dest=$coredir/$coreid
                or_die mkdir -p "$dest"
                or_die mkdir -p "$dest/vdev"
 
                dest=$coredir/$coreid
                or_die mkdir -p "$dest"
                or_die mkdir -p "$dest/vdev"
 
+               if [[ $symlink -ne 0 ]]; then
+                       or_die ln -sf "$dest" ztest.core.$foundcrashes
+               fi
+
                echo "*** ztest crash found - moving logs to $dest"
 
                or_die mv ztest.history "$dest/"
                echo "*** ztest crash found - moving logs to $dest"
 
                or_die mv ztest.history "$dest/"
-               or_die mv ztest.ddt "$dest/"
+               or_die mv ztest.zdb "$dest/"
                or_die mv ztest.out "$dest/"
                or_die mv "$workdir/ztest*" "$dest/vdev/"
                or_die mv "$workdir/zpool.cache" "$dest/vdev/"
                or_die mv ztest.out "$dest/"
                or_die mv "$workdir/ztest*" "$dest/vdev/"
                or_die mv "$workdir/zpool.cache" "$dest/vdev/"
@@ -119,7 +132,7 @@ function store_core
                # check for core
                if [[ -f "$core" ]]; then
                        coreprog=$(core_prog "$core")
                # check for core
                if [[ -f "$core" ]]; then
                        coreprog=$(core_prog "$core")
-                       corestatus=$($GDB --batch --quiet \
+                       coredebug=$($GDB --batch --quiet \
                            -ex "set print thread-events off" \
                            -ex "printf \"*\n* Backtrace \n*\n\"" \
                            -ex "bt" \
                            -ex "set print thread-events off" \
                            -ex "printf \"*\n* Backtrace \n*\n\"" \
                            -ex "bt" \
@@ -131,34 +144,45 @@ function store_core
                            -ex "thread apply all bt" \
                            -ex "printf \"*\n* Backtraces (full) \n*\n\"" \
                            -ex "thread apply all bt full" \
                            -ex "thread apply all bt" \
                            -ex "printf \"*\n* Backtraces (full) \n*\n\"" \
                            -ex "thread apply all bt full" \
-                           -ex "quit" "$coreprog" "$core" | grep -v "New LWP")
+                           -ex "quit" "$coreprog" "$core" 2>&1 | \
+                           grep -v "New LWP")
 
                        # Dump core + logs to stored directory
 
                        # Dump core + logs to stored directory
-                       echo "$corestatus" >>"$dest/status"
+                       echo "$coredebug" >>"$dest/ztest.gdb"
                        or_die mv "$core" "$dest/"
 
                        # Record info in cores logfile
                        echo "*** core @ $coredir/$coreid/$core:" | \
                            tee -a ztest.cores
                        or_die mv "$core" "$dest/"
 
                        # Record info in cores logfile
                        echo "*** core @ $coredir/$coreid/$core:" | \
                            tee -a ztest.cores
-                       echo "$corestatus" | tee -a ztest.cores
-                       echo "" | tee -a ztest.cores
                fi
                fi
-               echo "continuing..."
+
+               if [[ $coremax -gt 0 ]] &&
+                  [[ $foundcrashes -ge $coremax ]]; then
+                       echo "exiting... max $coremax allowed cores"
+                       exit 1
+               else
+                       echo "continuing..."
+               fi
        fi
 }
 
 # parse arguments
 # expected format: zloop [-t timeout] [-c coredir] [-- extra ztest args]
 coredir=$DEFAULTCOREDIR
        fi
 }
 
 # parse arguments
 # expected format: zloop [-t timeout] [-c coredir] [-- extra ztest args]
 coredir=$DEFAULTCOREDIR
-workdir=$DEFAULTWORKDIR
+basedir=$DEFAULTWORKDIR
+rundir="zloop-run"
 timeout=0
 size="512m"
 timeout=0
 size="512m"
-while getopts ":ht:s:c:f:" opt; do
+coremax=0
+symlink=0
+while getopts ":ht:m:s:c:f:l" opt; do
        case $opt in
                t ) [[ $OPTARG -gt 0 ]] && timeout=$OPTARG ;;
        case $opt in
                t ) [[ $OPTARG -gt 0 ]] && timeout=$OPTARG ;;
+               m ) [[ $OPTARG -gt 0 ]] && coremax=$OPTARG ;;
                s ) [[ $OPTARG ]] && size=$OPTARG ;;
                c ) [[ $OPTARG ]] && coredir=$OPTARG ;;
                s ) [[ $OPTARG ]] && size=$OPTARG ;;
                c ) [[ $OPTARG ]] && coredir=$OPTARG ;;
-               f ) [[ $OPTARG ]] && workdir=$(readlink -f "$OPTARG") ;;
+               f ) [[ $OPTARG ]] && basedir=$(readlink -f "$OPTARG") ;;
+               l ) symlink=1 ;;
                h ) usage
                    exit 2
                    ;;
                h ) usage
                    exit 2
                    ;;
@@ -176,6 +200,7 @@ ulimit -c unlimited
 if [[ -f "$(core_file)" ]]; then
        echo -n "There's a core dump here you might want to look at first... "
        core_file
 if [[ -f "$(core_file)" ]]; then
        echo -n "There's a core dump here you might want to look at first... "
        core_file
+       echo
        exit 1
 fi
 
        exit 1
 fi
 
@@ -190,7 +215,7 @@ if [[ ! -w $coredir ]]; then
 fi
 
 or_die rm -f ztest.history
 fi
 
 or_die rm -f ztest.history
-or_die rm -f ztest.ddt
+or_die rm -f ztest.zdb
 or_die rm -f ztest.cores
 
 ztrc=0         # ztest return value
 or_die rm -f ztest.cores
 
 ztrc=0         # ztest return value
@@ -202,6 +227,11 @@ curtime=$starttime
 while [[ $timeout -eq 0 ]] || [[ $curtime -le $((starttime + timeout)) ]]; do
        zopt="-VVVVV"
 
 while [[ $timeout -eq 0 ]] || [[ $curtime -le $((starttime + timeout)) ]]; do
        zopt="-VVVVV"
 
+       # start each run with an empty directory
+       workdir="$basedir/$rundir"
+       or_die rm -rf "$workdir"
+       or_die mkdir "$workdir"
+
        # switch between common arrangements & fully randomized
        if [[ $((RANDOM % 2)) -eq 0 ]]; then
                mirrors=2
        # switch between common arrangements & fully randomized
        if [[ $((RANDOM % 2)) -eq 0 ]]; then
                mirrors=2
@@ -235,8 +265,7 @@ while [[ $timeout -eq 0 ]] || [[ $curtime -le $((starttime + timeout)) ]]; do
        echo "$desc" >>ztest.out
        $cmd >>ztest.out 2>&1
        ztrc=$?
        echo "$desc" >>ztest.out
        $cmd >>ztest.out 2>&1
        ztrc=$?
-       egrep '===|WARNING' ztest.out >>ztest.history
-       $ZDB -U "$workdir/zpool.cache" -DD ztest >>ztest.ddt
+       grep -E '===|WARNING' ztest.out >>ztest.history
 
        store_core
 
 
        store_core
 
index 10bd110a63ffa53e10c6a1504b97fd719c8cdc85..303c275299d839afc12496f2746f045e88f26b86 100644 (file)
@@ -228,7 +228,7 @@ tests = ['zpool_add_001_pos', 'zpool_add_002_pos', 'zpool_add_003_pos',
     'zpool_add_004_pos', 'zpool_add_005_pos', 'zpool_add_006_pos',
     'zpool_add_007_neg', 'zpool_add_008_neg', 'zpool_add_009_neg',
     'zpool_add_010_pos',
     'zpool_add_004_pos', 'zpool_add_005_pos', 'zpool_add_006_pos',
     'zpool_add_007_neg', 'zpool_add_008_neg', 'zpool_add_009_neg',
     'zpool_add_010_pos',
-    'add-o_ashift', 'add_prop_ashift']
+    'add-o_ashift', 'add_prop_ashift', 'add_nested_replacing_spare']
 tags = ['functional', 'cli_root', 'zpool_add']
 
 [tests/functional/cli_root/zpool_attach]
 tags = ['functional', 'cli_root', 'zpool_add']
 
 [tests/functional/cli_root/zpool_attach]
@@ -366,7 +366,7 @@ tests = ['zdb_001_neg', 'zfs_001_neg', 'zfs_allow_001_neg',
     'zpool_offline_001_neg', 'zpool_online_001_neg', 'zpool_remove_001_neg',
     'zpool_replace_001_neg', 'zpool_scrub_001_neg', 'zpool_set_001_neg',
     'zpool_status_001_neg', 'zpool_upgrade_001_neg', 'arcstat_001_pos',
     'zpool_offline_001_neg', 'zpool_online_001_neg', 'zpool_remove_001_neg',
     'zpool_replace_001_neg', 'zpool_scrub_001_neg', 'zpool_set_001_neg',
     'zpool_status_001_neg', 'zpool_upgrade_001_neg', 'arcstat_001_pos',
-    'arc_summary_001_pos', 'dbufstat_001_pos']
+    'arc_summary_001_pos', 'arc_summary_002_neg', 'dbufstat_001_pos']
 user =
 tags = ['functional', 'cli_user', 'misc']
 
 user =
 tags = ['functional', 'cli_user', 'misc']
 
index 579e1356ed0e25ef613c20899e4b22c77b70bdce..24633ccc3405000f76fbfd318a4306b7cfbd4f09 100644 (file)
@@ -10,4 +10,4 @@ dist_pkgdata_SCRIPTS = \
 EXTRA_DIST=default.cfg.in
 
 distclean-local::
 EXTRA_DIST=default.cfg.in
 
 distclean-local::
-       -$(RM) $(dist_pkgdata_SCRIPTS)
+       -$(RM) default.cfg
index 5802136059c11861de0a0b22318be5808c63720f..16839f9f8bdd1dbc685aa86b053a1310af1fe9da 100644 (file)
@@ -623,7 +623,7 @@ uninstall-am: uninstall-dist_pkgdataSCRIPTS
 
 
 distclean-local::
 
 
 distclean-local::
-       -$(RM) $(dist_pkgdata_SCRIPTS)
+       -$(RM) default.cfg
 
 # Tell versions [3.59,3.63) of GNU make to not export all variables.
 # Otherwise a system limit (for SysV at least) may be exceeded.
 
 # Tell versions [3.59,3.63) of GNU make to not export all variables.
 # Otherwise a system limit (for SysV at least) may be exceeded.
index 345d1903de8daf42cc630695f59356a2cd66f563..86f172a6d348d767d911f4e6d21d79f25b53c926 100644 (file)
@@ -1988,6 +1988,31 @@ function check_hotspare_state # pool disk state{inuse,avail}
        return 0
 }
 
        return 0
 }
 
+#
+# Wait until a hotspare transitions to a given state or times out.
+#
+# Return 0 when  pool/disk matches expected state, 1 on timeout.
+#
+function wait_hotspare_state # pool disk state timeout
+{
+       typeset pool=$1
+       typeset disk=${2#$/DEV_DSKDIR/}
+       typeset state=$3
+       typeset timeout=${4:-60}
+       typeset -i i=0
+
+       while [[ $i -lt $timeout ]]; do
+               if check_hotspare_state $pool $disk $state; then
+                       return 0
+               fi
+
+               i=$((i+1))
+               sleep 1
+       done
+
+       return 1
+}
+
 #
 # Verify a given slog disk is inuse or avail
 #
 #
 # Verify a given slog disk is inuse or avail
 #
@@ -2026,6 +2051,31 @@ function check_vdev_state # pool disk state{online,offline,unavail}
        return 0
 }
 
        return 0
 }
 
+#
+# Wait until a vdev transitions to a given state or times out.
+#
+# Return 0 when  pool/disk matches expected state, 1 on timeout.
+#
+function wait_vdev_state # pool disk state timeout
+{
+       typeset pool=$1
+       typeset disk=${2#$/DEV_DSKDIR/}
+       typeset state=$3
+       typeset timeout=${4:-60}
+       typeset -i i=0
+
+       while [[ $i -lt $timeout ]]; do
+               if check_vdev_state $pool $disk $state; then
+                       return 0
+               fi
+
+               i=$((i+1))
+               sleep 1
+       done
+
+       return 1
+}
+
 #
 # Check the output of 'zpool status -v <pool>',
 # and to see if the content of <token> contain the <keyword> specified.
 #
 # Check the output of 'zpool status -v <pool>',
 # and to see if the content of <token> contain the <keyword> specified.
@@ -3394,13 +3444,25 @@ function zed_stop
        if [[ -f ${ZEDLET_DIR}/zed.pid ]]; then
                zedpid=$(cat ${ZEDLET_DIR}/zed.pid)
                kill $zedpid
        if [[ -f ${ZEDLET_DIR}/zed.pid ]]; then
                zedpid=$(cat ${ZEDLET_DIR}/zed.pid)
                kill $zedpid
-               wait $zedpid
+               while ps -p $zedpid > /dev/null; do
+                       sleep 1
+               done
                rm -f ${ZEDLET_DIR}/zed.pid
        fi
                rm -f ${ZEDLET_DIR}/zed.pid
        fi
-
        return 0
 }
 
        return 0
 }
 
+#
+# Drain all zevents
+#
+function zed_events_drain
+{
+       while [ $(zpool events -H | wc -l) -ne 0 ]; do
+              sleep 1
+              zpool events -c >/dev/null
+       done
+}
+
 #
 # Check is provided device is being active used as a swap device.
 #
 #
 # Check is provided device is being active used as a swap device.
 #
index def25d390919196f224b6b481b87b09b1415fb19..75bb824559c095098bd2f2713ea4e95c95c4c473 100644 (file)
@@ -410,7 +410,7 @@ function get_xattr #<obj>
        fi
 
        for xattr in `runat $obj ls | \
        fi
 
        for xattr in `runat $obj ls | \
-               /usr/xpg4/bin/egrep -v -e SUNWattr_ro -e SUNWattr_rw` ; do
+               grep -E -v -e SUNWattr_ro -e SUNWattr_rw` ; do
                runat $obj sum $xattr
        done
 }
                runat $obj sum $xattr
        done
 }
index 7137fe278f98b9de418d374e4f65444a94b6b2d4..e4e69851f3857e62b780c1c5fc8ac36bdf949ee2 100755 (executable)
@@ -371,6 +371,42 @@ log_must eval "check_prop_source $dest type filesystem -"
 log_must eval "check_prop_source $dest atime off local"
 log_must eval "check_prop_source $destsub type volume -"
 log_must eval "check_prop_source $destsub atime - -"
 log_must eval "check_prop_source $dest atime off local"
 log_must eval "check_prop_source $destsub type volume -"
 log_must eval "check_prop_source $destsub atime - -"
+# Cleanup
+log_must zfs destroy -r -f $orig
+log_must zfs destroy -r -f $dest
+
+#
+# 3.8 Verify 'zfs recv -x|-o' works correctly when used in conjunction with -d
+#     and -e options.
+#
+log_must zfs create -p $orig/1/2/3/4
+log_must eval "zfs set copies=2 $orig"
+log_must eval "zfs set atime=on $orig"
+log_must eval "zfs set '$userprop:orig'='oldval' $orig"
+log_must zfs snapshot -r $orig@snap1
+log_must eval "zfs send -R $orig/1/2@snap1 > $streamfile_repl"
+# Verify 'zfs recv -e'
+log_must zfs create $dest
+log_must eval "zfs receive -e -o copies=3 -x atime "\
+       "-o '$userprop:orig'='newval' $dest < $streamfile_repl"
+log_must datasetexists $dest/2/3/4
+log_must eval "check_prop_source $dest/2 copies 3 local"
+log_must eval "check_prop_inherit $dest/2/3/4 copies $dest/2"
+log_must eval "check_prop_source $dest/2/3/4 atime on default"
+log_must eval "check_prop_source $dest/2 '$userprop:orig' 'newval' local"
+log_must eval "check_prop_inherit $dest/2/3/4 '$userprop:orig' $dest/2"
+log_must zfs destroy -r -f $dest
+# Verify 'zfs recv -d'
+log_must zfs create $dest
+typeset fs="$(echo $orig | awk -F'/' '{print $NF}')"
+log_must eval "zfs receive -d -o copies=3 -x atime "\
+       "-o '$userprop:orig'='newval' $dest < $streamfile_repl"
+log_must datasetexists $dest/$fs/1/2/3/4
+log_must eval "check_prop_source $dest/$fs/1/2 copies 3 local"
+log_must eval "check_prop_inherit $dest/$fs/1/2/3/4 copies $dest/$fs/1/2"
+log_must eval "check_prop_source $dest/$fs/1/2/3/4 atime on default"
+log_must eval "check_prop_source $dest/$fs/1/2 '$userprop:orig' 'newval' local"
+log_must eval "check_prop_inherit $dest/$fs/1/2/3/4 '$userprop:orig' $dest/$fs/1/2"
 # We don't need to cleanup here
 
 log_pass "ZFS receive property override and exclude options passed."
 # We don't need to cleanup here
 
 log_pass "ZFS receive property override and exclude options passed."
index 4b6b533fecca407d06525c6a4af2a9268e1a9958..0620282992d5a0d78f94bf3d40c5360fb6913e2c 100644 (file)
@@ -15,4 +15,5 @@ dist_pkgdata_SCRIPTS = \
        zpool_add_009_neg.ksh \
        zpool_add_010_pos.ksh \
        add-o_ashift.ksh \
        zpool_add_009_neg.ksh \
        zpool_add_010_pos.ksh \
        add-o_ashift.ksh \
-       add_prop_ashift.ksh
+       add_prop_ashift.ksh \
+       add_nested_replacing_spare.ksh
index bfe9dbbc08b4425539645a65b198b771edf5ddce..e2e3735d0dff7138b688f817f221ad94ab90f384 100644 (file)
@@ -403,7 +403,8 @@ dist_pkgdata_SCRIPTS = \
        zpool_add_009_neg.ksh \
        zpool_add_010_pos.ksh \
        add-o_ashift.ksh \
        zpool_add_009_neg.ksh \
        zpool_add_010_pos.ksh \
        add-o_ashift.ksh \
-       add_prop_ashift.ksh
+       add_prop_ashift.ksh \
+       add_nested_replacing_spare.ksh
 
 all: all-am
 
 
 all: all-am
 
diff --git a/tests/zfs-tests/tests/functional/cli_root/zpool_add/add_nested_replacing_spare.ksh b/tests/zfs-tests/tests/functional/cli_root/zpool_add/add_nested_replacing_spare.ksh
new file mode 100755 (executable)
index 0000000..b380798
--- /dev/null
@@ -0,0 +1,111 @@
+#!/bin/ksh -p
+#
+# 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 2017, loli10K <ezomori.nozomu@gmail.com>. All rights reserved.
+#
+
+. $STF_SUITE/include/libtest.shlib
+. $STF_SUITE/tests/functional/cli_root/zpool_create/zpool_create.shlib
+
+#
+# DESCRIPTION:
+#      'zpool add' works with nested replacing/spare vdevs
+#
+# STRATEGY:
+#      1. Create a redundant pool with a spare device
+#      2. Manually fault a device, wait for the hot-spare and then replace it:
+#         this creates a situation where replacing and spare vdevs are nested.
+#      3. Verify 'zpool add' is able to add new devices to the pool.
+#
+
+verify_runnable "global"
+
+function cleanup
+{
+       zed_stop
+       zed_cleanup
+       log_must zinject -c all
+       destroy_pool $TESTPOOL
+       log_must rm -f $DATA_DEVS $SPARE_DEVS
+}
+
+log_assert "'zpool add' works with nested replacing/spare vdevs"
+log_onexit cleanup
+
+FAULT_DEV="$TEST_BASE_DIR/fault-dev"
+SAFE_DEV1="$TEST_BASE_DIR/safe-dev1"
+SAFE_DEV2="$TEST_BASE_DIR/safe-dev2"
+SAFE_DEV3="$TEST_BASE_DIR/safe-dev3"
+SAFE_DEVS="$SAFE_DEV1 $SAFE_DEV2 $SAFE_DEV3"
+REPLACE_DEV="$TEST_BASE_DIR/replace-dev"
+ADD_DEV="$TEST_BASE_DIR/add-dev"
+DATA_DEVS="$FAULT_DEV $SAFE_DEVS $REPLACE_DEV $ADD_DEV"
+SPARE_DEV1="$TEST_BASE_DIR/spare-dev1"
+SPARE_DEV2="$TEST_BASE_DIR/spare-dev2"
+SPARE_DEVS="$SPARE_DEV1 $SPARE_DEV2"
+
+# We need ZED running to work with spares
+zed_setup
+zed_start
+# Clear events from previous runs
+zed_events_drain
+
+for type in "mirror" "raidz1" "raidz2" "raidz3"
+do
+       # 1. Create a redundant pool with a spare device
+       truncate -s $SPA_MINDEVSIZE $DATA_DEVS $SPARE_DEVS
+       log_must zpool create $TESTPOOL $type $FAULT_DEV $SAFE_DEVS
+       log_must zpool add $TESTPOOL spare $SPARE_DEV1
+
+       # 2.1 Fault a device, verify the spare is kicked in
+       log_must zinject -d $FAULT_DEV -e nxio -T all -f 100 $TESTPOOL
+       log_must zpool scrub $TESTPOOL
+       log_must wait_vdev_state $TESTPOOL $FAULT_DEV "UNAVAIL" 60
+       log_must wait_vdev_state $TESTPOOL $SPARE_DEV1 "ONLINE" 60
+       log_must wait_hotspare_state $TESTPOOL $SPARE_DEV1 "INUSE"
+       log_must check_state $TESTPOOL "" "DEGRADED"
+
+       # 2.2 Replace the faulted device: this creates a replacing vdev inside a
+       #     spare vdev
+       log_must zpool replace $TESTPOOL $FAULT_DEV $REPLACE_DEV
+       log_must wait_vdev_state $TESTPOOL $REPLACE_DEV "ONLINE" 60
+       zpool status | awk -v poolname="$TESTPOOL" -v type="$type" 'BEGIN {s=""}
+           $1 ~ poolname {c=4}; (c && c--) { s=s$1":" }
+           END { if (s != poolname":"type"-0:spare-0:replacing-0:") exit 1; }'
+       if [[ $? -ne 0 ]]; then
+               log_fail "Pool does not contain nested replacing/spare vdevs"
+       fi
+
+       # 3. Verify 'zpool add' is able to add new devices
+       log_must zpool add $TESTPOOL spare $SPARE_DEV2
+       log_must wait_hotspare_state $TESTPOOL $SPARE_DEV2 "AVAIL"
+       log_must zpool add -f $TESTPOOL $ADD_DEV
+       log_must wait_vdev_state $TESTPOOL $ADD_DEV "ONLINE" 60
+
+       # Cleanup
+       log_must zinject -c all
+       destroy_pool $TESTPOOL
+       log_must rm -f $DATA_DEVS $SPARE_DEVS
+done
+
+log_pass "'zpool add' works with nested replacing/spare vdevs"
index cf7502c27eac5f0b89063697b5bdcc5030f05a33..75a3d0886f36f44ad34b92782baebbb94271fd15 100644 (file)
@@ -46,4 +46,5 @@ dist_pkgdata_SCRIPTS = \
        zpool_upgrade_001_neg.ksh \
        arcstat_001_pos.ksh \
        arc_summary_001_pos.ksh \
        zpool_upgrade_001_neg.ksh \
        arcstat_001_pos.ksh \
        arc_summary_001_pos.ksh \
+       arc_summary_002_neg.ksh \
        dbufstat_001_pos.ksh
        dbufstat_001_pos.ksh
index 942332bb0315aa2f05cd113b73d8d5bceaa0cb15..1f7be1fecae315c5f03140855a6bdc9c40c566c6 100644 (file)
@@ -434,6 +434,7 @@ dist_pkgdata_SCRIPTS = \
        zpool_upgrade_001_neg.ksh \
        arcstat_001_pos.ksh \
        arc_summary_001_pos.ksh \
        zpool_upgrade_001_neg.ksh \
        arcstat_001_pos.ksh \
        arc_summary_001_pos.ksh \
+       arc_summary_002_neg.ksh \
        dbufstat_001_pos.ksh
 
 all: all-am
        dbufstat_001_pos.ksh
 
 all: all-am
index 67c11c8ab673f1e961ca92226af1c70cbc1dbf94..6653b9c1ad35b7565c141ddba1c596a8fe7f545d 100755 (executable)
@@ -37,4 +37,7 @@ while [[ $i -lt ${#args[*]} ]]; do
         ((i = i + 1))
 done
 
         ((i = i + 1))
 done
 
+log_must eval "arc_summary.py | head > /dev/null"
+log_must eval "arc_summary.py | head -1 > /dev/null"
+
 log_pass "arc_summary.py generates output and doesn't return an error code"
 log_pass "arc_summary.py generates output and doesn't return an error code"
diff --git a/tests/zfs-tests/tests/functional/cli_user/misc/arc_summary_002_neg.ksh b/tests/zfs-tests/tests/functional/cli_user/misc/arc_summary_002_neg.ksh
new file mode 100755 (executable)
index 0000000..e63552f
--- /dev/null
@@ -0,0 +1,38 @@
+#!/bin/ksh -p
+#
+# 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) 2015 by Lawrence Livermore National Security, LLC.
+# All rights reserved.
+#
+
+. $STF_SUITE/include/libtest.shlib
+
+typeset args=("-x" "-r" "-5" "-p 7" "--err" "-@")
+
+log_assert "arc_summary.py generates an error code with invalid options"
+
+for arg in "${args[@]}"; do
+        log_mustnot eval "arc_summary.py $arg > /dev/null"
+done
+
+log_pass "arc_summary.py generates an error code with invalid options"
index cb0d91bac5043c2980149ba2e150e2a7f5aa24d0..61e96abf887852f02437466ed048588ab810ab5e 100644 (file)
 /* mount_nodev() is available */
 #undef HAVE_MOUNT_NODEV
 
 /* mount_nodev() is available */
 #undef HAVE_MOUNT_NODEV
 
-/* new_sync_read() is available */
+/* new_sync_read()/new_sync_write() are available */
 #undef HAVE_NEW_SYNC_READ
 
 /* sops->nr_cached_objects() exists */
 #undef HAVE_NEW_SYNC_READ
 
 /* sops->nr_cached_objects() exists */