]> 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
-Version:      0.7.5
+Version:      0.7.6
 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 --quiet --force --error-exitcode=2 \
+               cppcheck --quiet --force --error-exitcode=2 --inline-suppr \
                        --suppressions-list=.github/suppressions.txt \
-                       -UHAVE_SSE2 -UHAVE_AVX512F \
-                       ${top_srcdir}; \
+                       -UHAVE_SSE2 -UHAVE_AVX512F -UHAVE_UIO_ZEROCOPY \
+                       -UHAVE_DNLC ${top_srcdir}; \
        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`; \
+       debarch=`$(DPKG) --print-architecture`; \
        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`; \
+       debarch=`$(DPKG) --print-architecture`; \
        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`; \
+       debarch=`$(DPKG) --print-architecture`; \
        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} \
-       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; \
@@ -1251,10 +1254,10 @@ lint: cppcheck paxcheck
 
 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 \
-                       -UHAVE_SSE2 -UHAVE_AVX512F \
-                       ${top_srcdir}; \
+                       -UHAVE_SSE2 -UHAVE_AVX512F -UHAVE_UIO_ZEROCOPY \
+                       -UHAVE_DNLC ${top_srcdir}; \
        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.
 #
-# /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 getopt
-import re
-from os import listdir
+import errno
+
 from subprocess import Popen, PIPE
 from decimal import Decimal as D
 
-
-usetunable = True
 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():
+    """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):
+        """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()
-            name, unused, value = kstat.split()
+            name, _, value = kstat.split()
             Kstat[namespace + name] = D(value)
 
     Kstat = {}
@@ -77,82 +95,79 @@ def get_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:
-        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:
-        return str("%d" % Hits)
+
+        result = "%d" % hits
+
+    return result
 
 
 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:
@@ -160,6 +175,7 @@ def fPerc(lVal=0, rVal=0, Decimal=2):
 
 
 def get_arc_summary(Kstat):
+    """Collect general data on the ARC"""
 
     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"]
+    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)
-    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"]
@@ -261,6 +278,8 @@ def get_arc_summary(Kstat):
 
 
 def _arc_summary(Kstat):
+    """Print information on the ARC"""
+
     # 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" %
-                     arc['arc_misc']['mutex_miss'])
+                     arc['arc_misc']['evict_skips'])
     sys.stdout.write("\n")
 
     # ARC Sizing
@@ -335,6 +354,8 @@ def _arc_summary(Kstat):
 
 
 def get_arc_efficiency(Kstat):
+    """Collect information on the efficiency of the ARC"""
+
     output = {}
 
     arc_hits = Kstat["kstat.zfs.misc.arcstats.hits"]
@@ -458,6 +479,8 @@ def get_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" %
@@ -568,6 +591,8 @@ def _arc_efficiency(Kstat):
 
 
 def get_l2arc_summary(Kstat):
+    """Collection information on the L2ARC"""
+
     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):
+    """Print information on the L2ARC"""
 
     arc = get_l2arc_summary(Kstat)
 
@@ -746,6 +772,8 @@ def _l2arc_summary(Kstat):
 
 
 def get_dmu_summary(Kstat):
+    """Collect information on the DMU"""
+
     output = {}
 
     zfetch_hits = Kstat["kstat.zfs.misc.zfetchstats.hits"]
@@ -771,6 +799,7 @@ def get_dmu_summary(Kstat):
 
 
 def _dmu_summary(Kstat):
+    """Print information on the DMU"""
 
     arc = get_dmu_summary(Kstat)
 
@@ -792,6 +821,8 @@ def _dmu_summary(Kstat):
 
 
 def get_vdev_summary(Kstat):
+    """Collect information on the VDEVs"""
+
     output = {}
 
     vdev_cache_delegations = \
@@ -822,6 +853,8 @@ def get_vdev_summary(Kstat):
 
 
 def _vdev_summary(Kstat):
+    """Print information on the VDEVs"""
+
     arc = get_vdev_summary(Kstat)
 
     if arc['vdev_cache_total'] > 0:
@@ -841,10 +874,12 @@ def _vdev_summary(Kstat):
 
 
 def _tunable_summary(Kstat):
+    """Print information on tunables, including descriptions if requested"""
+
     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:
@@ -855,13 +890,21 @@ def _tunable_summary(Kstat):
     descriptions = {}
 
     if show_tunable_descriptions:
+
+        command = ["/sbin/modinfo", "zfs", "-0"]
+
         try:
-            command = ["/sbin/modinfo", "zfs", "-0"]
             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:
@@ -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.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:
+
         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])
 
-        sys.stdout.write(format % (name, values[name]))
+        sys.stdout.write(fmt % (name, values[name]))
 
 
 unSub = [
@@ -906,14 +953,18 @@ unSub = [
 
 
 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():
+    """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")
@@ -934,12 +985,20 @@ def usage():
 
 
 def main():
+    """Main function"""
+
     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:
@@ -951,7 +1010,7 @@ def main():
             args['p'] = arg
         if opt in ('-h', '--help'):
             usage()
-            sys.exit()
+            sys.exit(0)
 
     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')
-            sys.exit()
+            sys.exit(1)
     else:
         pages = unSub
 
     zfs_header()
     for page in pages:
         page(Kstat)
-        div2()
+        sys.stdout.write("\n")
 
 
 if __name__ == '__main__':
index b7de5104f09df59491d0d1be60fe2947dcf5f387..ed6a95914ee6232b0f02901d7f7b736396022185 100644 (file)
@@ -397,7 +397,7 @@ zed_rate_limit()
 
     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}" ] \
@@ -406,7 +406,7 @@ zed_rate_limit()
     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}"
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)
 {
-       char c;
+       int c;
        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)
 {
-       char c;
+       int c;
        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 c;
+       int c;
 
        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
-                                * 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;
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`; \
+       debarch=`$(DPKG) --print-architecture`; \
        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
 
 
@@ -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`; \
+       debarch=`$(DPKG) --print-architecture`; \
        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`; \
+       debarch=`$(DPKG) --print-architecture`; \
        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} \
-       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; \
index 9f8fe6559fa3c1abd89f895e465a6285321e6751..ace54f70711f11cc65e7ff331b8d940702e5b257 100644 (file)
@@ -32,15 +32,23 @@ dnl #
 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>
        ],[
-               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,
-                       [new_sync_read() is available])
+                       [new_sync_read()/new_sync_write() are available])
        ],[
                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.
-# 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.
@@ -743,8 +743,8 @@ SHELL=${CONFIG_SHELL-/bin/sh}
 # 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.
@@ -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
-\`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]...
 
@@ -1670,7 +1670,7 @@ fi
 
 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
 
@@ -1804,7 +1804,7 @@ fi
 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,
@@ -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.
 
-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 $@
@@ -2976,7 +2976,7 @@ fi
 
 # Define the identity of the package.
  PACKAGE='zfs'
- VERSION='0.7.5'
+ VERSION='0.7.6'
 
 
 cat >>confdefs.h <<_ACEOF
@@ -25882,8 +25882,8 @@ cat >>confdefs.h <<\_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
@@ -25900,7 +25900,15 @@ int
 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;
@@ -44184,8 +44192,8 @@ cat >>confdefs.h <<\_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
@@ -44202,7 +44210,15 @@ int
 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;
@@ -46174,7 +46190,7 @@ exec 6>&1
 # 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
@@ -46237,7 +46253,7 @@ Report bugs to <bug-autoconf@gnu.org>."
 _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'`\\"
 
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 \
-               SHELL=/sbin/runscript; \
+               SHELL=/sbin/openrc-run; \
          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 \
-               SHELL=/sbin/runscript; \
+               SHELL=/sbin/openrc-run; \
          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_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);
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.
+ *
+ * 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);
+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
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);
 
-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.
  */
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 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);
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;
-       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 {
-       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 */
-       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 {
-       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 */
-       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;
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;
-       int rc, ret;
-       boolean_t found_protocol;
+       int rc, ret = SA_OK;
+       boolean_t found_protocol = B_FALSE;
        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) {
@@ -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;
-       int rc, ret;
-       boolean_t found_protocol;
+       int rc, ret = SA_OK;
+       boolean_t found_protocol = B_FALSE;
        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) {
@@ -696,11 +678,6 @@ sa_parse_legacy_options(sa_group_t group, char *options, char *proto)
 {
        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) {
@@ -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;
 
-#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));
 }
index 981c5ae142742ae26c02dfa69b2179e4fb439224..55d8fd7ab3bfdd11697358a2bfc1b45517a43e55 100644 (file)
@@ -5,7 +5,7 @@ includedir=${prefix}/include
 
 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
index d7e5433f247cdcd44f19ceb778f722f885d8b869..f57291a4f695dd7ad56cde6f24ccdf1a6780778b 100644 (file)
@@ -5,7 +5,7 @@ includedir=${prefix}/include
 
 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
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)
 {
-       if (statbuf == NULL || *srctype == ZPROP_SRC_TEMPORARY)
+       if (statbuf == NULL ||
+           srctype == NULL || *srctype == ZPROP_SRC_TEMPORARY) {
                return;
+       }
 
        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)) {
-                       struct udev_list_entry *links, *link;
+                       struct udev_list_entry *links, *link = NULL;
 
                        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;
-       boolean_t toplevel;
+       boolean_t toplevel = B_FALSE;
        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;
        }
 
-       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) {
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
 
-.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
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 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);
@@ -334,12 +334,12 @@ 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);
-       int i;
+       int i = 0;
 
        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)
 {
-       struct scatterlist *sg;
+       struct scatterlist *sg = NULL;
        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);
@@ -543,8 +543,8 @@ abd_verify(abd_t *abd)
                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, <,
@@ -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 {
-               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();
index 2b0a78d4be4798a06be0f09cdc6916c34a4ef92a..264e677357439bb1da0ec63f685da99b01b95837 100644 (file)
@@ -429,9 +429,14 @@ typedef struct arc_stats {
         * 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
-        * 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;
@@ -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 },
+       { "access_skip",                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)
index 60f52d29426b369b3df187261775eb80083854e7..4ee121f5a5fbfdcdf0ad0320eb6bf15d43151532 100644 (file)
@@ -2719,8 +2719,10 @@ __dbuf_hold_impl(struct dbuf_hold_impl_data *dh)
                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);
+       }
 
        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_buf_rele(db, FTAG);
                        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;
 
-       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));
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);
 
+       /*
+        * 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)) {
-               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.
                         */
-                       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)
 {
-       uint64_t lastoffset;
+       uint64_t last_offset;
+       int64_t offset_diff;
        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.
         */
 
+       /* 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);
-       lastoffset = vdev_queue_lastoffset(vd);
+       last_offset = vdev_queue_last_offset(vd);
 
        if (vd->vdev_nonrot) {
                /* Non-rotating media. */
-               if (lastoffset == zio_offset)
+               if (last_offset == zio_offset)
                        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. */
-       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
-        * 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.
         */
-       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. */
@@ -382,29 +387,20 @@ vdev_mirror_child_select(zio_t *zio)
                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]);
-       }
 
-       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++) {
-               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);
-               }
        }
 
        /*
index 6b3e8729159009749b49c702726a3bc4a0c7d10c..40cba340aafd682d4f066fa7240d36869c3aff88 100644 (file)
@@ -393,7 +393,7 @@ vdev_queue_init(vdev_t *vd)
                    sizeof (zio_t), offsetof(struct zio, io_queue_node));
        }
 
-       vq->vq_lastoffset = 0;
+       vq->vq_last_offset = 0;
 }
 
 void
@@ -699,9 +699,8 @@ again:
         */
        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);
@@ -728,7 +727,7 @@ again:
        }
 
        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);
 }
@@ -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.
@@ -818,15 +817,9 @@ vdev_queue_length(vdev_t *vd)
 }
 
 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)
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.
+ *
+ * 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)
 {
-       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
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;
-       boolean_t force;
+       boolean_t force = B_FALSE;
        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);
-
+out:
        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,
+                                   /* cppcheck-suppress nullPointer */
                                    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 (!size)
+       if (size == 0 || value == NULL)
                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;
-       struct hlist_node *p;
+       struct hlist_node *p = NULL;
 
        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
+* 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
index afa45268a36b57a9426ab454cc6902f31fe9fe79..8df57fa46e465d27f92f1ab6b7fafde2890ca4f7 100644 (file)
@@ -333,6 +333,9 @@ exit 0
 %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
index afa45268a36b57a9426ab454cc6902f31fe9fe79..8df57fa46e465d27f92f1ab6b7fafde2890ca4f7 100644 (file)
@@ -333,6 +333,9 @@ exit 0
 %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
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")
-       if (/^{$/ && $prev =~ /\)\s*(const\s*)?(\/\*.*\*\/\s*)?\\?$/) {
+       if (/^\{$/ && $prev =~ /\)\s*(const\s*)?(\/\*.*\*\/\s*)?\\?$/) {
                $in_function = 1;
                $in_declaration = 1;
                $in_function_header = 0;
@@ -391,7 +391,7 @@ line: while (<$filehandle>) {
                $prev = $line;
                next line;
        }
-       if (/^}\s*(\/\*.*\*\/\s*)*$/) {
+       if (/^\}\s*(\/\*.*\*\/\s*)*$/) {
                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|\.)/ ) {
-               if (/^{}$/ # empty functions
+               if (/^\{\}$/ # empty functions
                || /;/ #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;
                }
        }
-       if ($in_function_header && /^{$/) {
+       if ($in_function_header && /^\{$/) {
                $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;
        }
-       if ($in_function_header && /{$/ ) {
+       if ($in_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 ($in_function && /^\s+{/ &&
+       if ($in_function && /^\s+\{/ &&
            ($prev =~ /\)\s*$/ || $prev =~ /\bstruct\s+\w+$/)) {
                err("left brace starting a line");
        }
-       if (/}(else|while)/) {
+       if (/\}(else|while)/) {
                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/) {
@@ -730,18 +730,18 @@ line: while (<$filehandle>) {
        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
-               if ($in_function && /^\s+{/) {
+               if ($in_function && /^\s+\{/) {
                        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");
                }
@@ -827,8 +827,8 @@ process_indent($)
 
        # 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;
@@ -851,14 +851,14 @@ process_indent($)
                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
-               if (/{/) {
+               if (/\{/) {
                        err("stuff after {");
                        return;
                }
@@ -927,7 +927,7 @@ process_indent($)
                        #
                        next            if (@cont_paren != 0);
                        if ($cont_special) {
-                               if ($rest =~ /^\s*{?$/) {
+                               if ($rest =~ /^\s*\{?$/) {
                                        $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" \
+           "    -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
 }
@@ -70,12 +72,12 @@ function or_die
 
 # 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
-        coreglob="$(egrep -o '^([^|%[:space:]]*)' \
+        coreglob="$(grep -E -o '^([^|%[:space:]]*)' \
             /proc/sys/kernel/core_pattern)*"
 fi
 
@@ -101,17 +103,28 @@ function store_core
 {
        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))
 
+               # 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"
 
+               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/"
-               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/"
@@ -119,7 +132,7 @@ function store_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" \
@@ -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 "quit" "$coreprog" "$core" | grep -v "New LWP")
+                           -ex "quit" "$coreprog" "$core" 2>&1 | \
+                           grep -v "New LWP")
 
                        # 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
-                       echo "$corestatus" | tee -a ztest.cores
-                       echo "" | tee -a ztest.cores
                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
-workdir=$DEFAULTWORKDIR
+basedir=$DEFAULTWORKDIR
+rundir="zloop-run"
 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 ;;
+               m ) [[ $OPTARG -gt 0 ]] && coremax=$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
                    ;;
@@ -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
+       echo
        exit 1
 fi
 
@@ -190,7 +215,7 @@ if [[ ! -w $coredir ]]; then
 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
@@ -202,6 +227,11 @@ curtime=$starttime
 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
@@ -235,8 +265,7 @@ while [[ $timeout -eq 0 ]] || [[ $curtime -le $((starttime + timeout)) ]]; do
        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
 
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',
-    '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]
@@ -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',
-    'arc_summary_001_pos', 'dbufstat_001_pos']
+    'arc_summary_001_pos', 'arc_summary_002_neg', 'dbufstat_001_pos']
 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::
-       -$(RM) $(dist_pkgdata_SCRIPTS)
+       -$(RM) default.cfg
index 5802136059c11861de0a0b22318be5808c63720f..16839f9f8bdd1dbc685aa86b053a1310af1fe9da 100644 (file)
@@ -623,7 +623,7 @@ uninstall-am: uninstall-dist_pkgdataSCRIPTS
 
 
 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.
index 345d1903de8daf42cc630695f59356a2cd66f563..86f172a6d348d767d911f4e6d21d79f25b53c926 100644 (file)
@@ -1988,6 +1988,31 @@ function check_hotspare_state # pool disk state{inuse,avail}
        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
 #
@@ -2026,6 +2051,31 @@ function check_vdev_state # pool disk state{online,offline,unavail}
        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.
@@ -3394,13 +3444,25 @@ function zed_stop
        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
-
        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.
 #
index def25d390919196f224b6b481b87b09b1415fb19..75bb824559c095098bd2f2713ea4e95c95c4c473 100644 (file)
@@ -410,7 +410,7 @@ function get_xattr #<obj>
        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
 }
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 - -"
+# 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."
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 \
-       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 \
-       add_prop_ashift.ksh
+       add_prop_ashift.ksh \
+       add_nested_replacing_spare.ksh
 
 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 \
+       arc_summary_002_neg.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 \
+       arc_summary_002_neg.ksh \
        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
 
+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"
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
 
-/* new_sync_read() is available */
+/* new_sync_read()/new_sync_write() are available */
 #undef HAVE_NEW_SYNC_READ
 
 /* sops->nr_cached_objects() exists */