Author: mav
Date: Fri Nov 13 09:39:55 2015
New Revision: 290758
URL: https://svnweb.freebsd.org/changeset/base/290758

Log:
  MFC r289497: 5745 zfs set allows only one dataset property to be set at a time
  
  Reviewed by: Christopher Siden <christopher.si...@delphix.com>
  Reviewed by: George Wilson <geo...@delphix.com>
  Reviewed by: Matthew Ahrens <mahr...@delphix.com>
  Reviewed by: Bayard Bell <buffer.g.overf...@gmail.com>
  Reviewed by: Richard PALO <rich...@netbsd.org>
  Reviewed by: Steven Hartland <kill...@multiplay.co.uk>
  Approved by: Rich Lowe <richl...@richlowe.net>
  Author: Chris Williamson <chris.william...@delphix.com>
  
  illumos/illumos-gate@30925561c223021e91d15899cbe75f80e54d8889

Modified:
  stable/10/cddl/contrib/opensolaris/cmd/zfs/zfs.8
  stable/10/cddl/contrib/opensolaris/cmd/zfs/zfs_main.c
  stable/10/cddl/contrib/opensolaris/lib/libzfs/common/libzfs.h
  stable/10/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_dataset.c
  stable/10/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_util.c
Directory Properties:
  stable/10/   (props changed)

Modified: stable/10/cddl/contrib/opensolaris/cmd/zfs/zfs.8
==============================================================================
--- stable/10/cddl/contrib/opensolaris/cmd/zfs/zfs.8    Fri Nov 13 09:32:04 
2015        (r290757)
+++ stable/10/cddl/contrib/opensolaris/cmd/zfs/zfs.8    Fri Nov 13 09:39:55 
2015        (r290758)
@@ -18,7 +18,7 @@
 .\" information: Portions Copyright [yyyy] [name of copyright owner]
 .\"
 .\" Copyright (c) 2010, Sun Microsystems, Inc. All Rights Reserved.
-.\" Copyright (c) 2014 by Delphix. All rights reserved.
+.\" Copyright (c) 2011, 2014 by Delphix. All rights reserved.
 .\" Copyright (c) 2011, Pawel Jakub Dawidek <p...@freebsd.org>
 .\" Copyright (c) 2012, Glen Barber <g...@freebsd.org>
 .\" Copyright (c) 2012, Bryan Drewery <bdrew...@freebsd.org>
@@ -117,7 +117,7 @@
 .Ar filesystem Ns | Ns Ar volume Ns | Ns Ar snapshot
 .Nm
 .Cm set
-.Ar property Ns = Ns Ar value
+.Ar property Ns = Ns Ar value Oc ...
 .Ar filesystem Ns | Ns Ar volume Ns | Ns Ar snapshot Ns ...
 .Nm
 .Cm get
@@ -2121,14 +2121,14 @@ option, but sorts by property in descend
 .It Xo
 .Nm
 .Cm set
-.Ar property Ns = Ns Ar value
+.Ar property Ns = Ns Ar value Oc ...
 .Ar filesystem Ns | Ns Ar volume Ns | Ns Ar snapshot
 .Xc
 .Pp
-Sets the property to the given value for each dataset. Only some properties can
-be edited. See the "Properties" section for more information on what properties
-can be set and acceptable values. Numeric values can be specified as exact
-values, or in a human-readable form with a suffix of
+Sets the property or list of properties to the given value(s) for each dataset.
+Only some properties can be edited. See the "Properties" section for more
+information on what properties can be set and acceptable values. Numeric values
+can be specified as exact values, or in a human-readable form with a suffix of
 .Sy B , K , M , G , T , P , E , Z
 (for bytes, kilobytes, megabytes, gigabytes, terabytes, petabytes, exabytes, or
 zettabytes, respectively). User properties can be set on snapshots. For more

Modified: stable/10/cddl/contrib/opensolaris/cmd/zfs/zfs_main.c
==============================================================================
--- stable/10/cddl/contrib/opensolaris/cmd/zfs/zfs_main.c       Fri Nov 13 
09:32:04 2015        (r290757)
+++ stable/10/cddl/contrib/opensolaris/cmd/zfs/zfs_main.c       Fri Nov 13 
09:39:55 2015        (r290758)
@@ -283,7 +283,7 @@ get_usage(zfs_help_t idx)
                    "<filesystem|volume|snapshot>\n"
                    "\tsend [-nvPe] -t <receive_resume_token>\n"));
        case HELP_SET:
-               return (gettext("\tset <property=value> "
+               return (gettext("\tset <property=value> ... "
                    "<filesystem|volume|snapshot> ...\n"));
        case HELP_SHARE:
                return (gettext("\tshare <-a | filesystem>\n"));
@@ -498,6 +498,10 @@ usage(boolean_t requested)
        exit(requested ? 0 : 2);
 }
 
+/*
+ * Take a property=value argument string and add it to the given nvlist.
+ * Modifies the argument inplace.
+ */
 static int
 parseprop(nvlist_t *props, char *propname)
 {
@@ -505,7 +509,7 @@ parseprop(nvlist_t *props, char *propnam
 
        if ((propval = strchr(propname, '=')) == NULL) {
                (void) fprintf(stderr, gettext("missing "
-                   "'=' for -o option\n"));
+                   "'=' for property=value argument\n"));
                return (-1);
        }
        *propval = '\0';
@@ -632,7 +636,7 @@ zfs_do_clone(int argc, char **argv)
        while ((c = getopt(argc, argv, "o:p")) != -1) {
                switch (c) {
                case 'o':
-                       if (parseprop(props, optarg))
+                       if (parseprop(props, optarg) != 0)
                                return (1);
                        break;
                case 'p':
@@ -3532,21 +3536,17 @@ out:
 }
 
 /*
- * zfs set property=value { fs | snap | vol } ...
+ * zfs set property=value ... { fs | snap | vol } ...
  *
- * Sets the given property for all datasets specified on the command line.
+ * Sets the given properties for all datasets specified on the command line.
  */
-typedef struct set_cbdata {
-       char            *cb_propname;
-       char            *cb_value;
-} set_cbdata_t;
 
 static int
 set_callback(zfs_handle_t *zhp, void *data)
 {
-       set_cbdata_t *cbp = data;
+       nvlist_t *props = data;
 
-       if (zfs_prop_set(zhp, cbp->cb_propname, cbp->cb_value) != 0) {
+       if (zfs_prop_set_list(zhp, props) != 0) {
                switch (libzfs_errno(g_zfs)) {
                case EZFS_MOUNTFAILED:
                        (void) fprintf(stderr, gettext("property may be set "
@@ -3565,7 +3565,8 @@ set_callback(zfs_handle_t *zhp, void *da
 static int
 zfs_do_set(int argc, char **argv)
 {
-       set_cbdata_t cb;
+       nvlist_t *props = NULL;
+       int ds_start = -1; /* argv idx of first dataset arg */
        int ret = 0;
 
        /* check for options */
@@ -3577,36 +3578,51 @@ zfs_do_set(int argc, char **argv)
 
        /* check number of arguments */
        if (argc < 2) {
-               (void) fprintf(stderr, gettext("missing property=value "
-                   "argument\n"));
+               (void) fprintf(stderr, gettext("missing arguments\n"));
                usage(B_FALSE);
        }
        if (argc < 3) {
-               (void) fprintf(stderr, gettext("missing dataset name\n"));
+               if (strchr(argv[1], '=') == NULL) {
+                       (void) fprintf(stderr, gettext("missing property=value "
+                           "argument(s)\n"));
+               } else {
+                       (void) fprintf(stderr, gettext("missing dataset "
+                           "name(s)\n"));
+               }
                usage(B_FALSE);
        }
 
-       /* validate property=value argument */
-       cb.cb_propname = argv[1];
-       if (((cb.cb_value = strchr(cb.cb_propname, '=')) == NULL) ||
-           (cb.cb_value[1] == '\0')) {
-               (void) fprintf(stderr, gettext("missing value in "
-                   "property=value argument\n"));
+       /* validate argument order:  prop=val args followed by dataset args */
+       for (int i = 1; i < argc; i++) {
+               if (strchr(argv[i], '=') != NULL) {
+                       if (ds_start > 0) {
+                               /* out-of-order prop=val argument */
+                               (void) fprintf(stderr, gettext("invalid "
+                                   "argument order\n"), i);
+                               usage(B_FALSE);
+                       }
+               } else if (ds_start < 0) {
+                       ds_start = i;
+               }
+       }
+       if (ds_start < 0) {
+               (void) fprintf(stderr, gettext("missing dataset name(s)\n"));
                usage(B_FALSE);
        }
 
-       *cb.cb_value = '\0';
-       cb.cb_value++;
-
-       if (*cb.cb_propname == '\0') {
-               (void) fprintf(stderr,
-                   gettext("missing property in property=value argument\n"));
-               usage(B_FALSE);
+       /* Populate a list of property settings */
+       if (nvlist_alloc(&props, NV_UNIQUE_NAME, 0) != 0)
+               nomem();
+       for (int i = 1; i < ds_start; i++) {
+               if ((ret = parseprop(props, argv[i])) != 0)
+                       goto error;
        }
 
-       ret = zfs_for_each(argc - 2, argv + 2, 0,
-           ZFS_TYPE_DATASET, NULL, NULL, 0, set_callback, &cb);
+       ret = zfs_for_each(argc - ds_start, argv + ds_start, 0,
+           ZFS_TYPE_DATASET, NULL, NULL, 0, set_callback, props);
 
+error:
+       nvlist_free(props);
        return (ret);
 }
 

Modified: stable/10/cddl/contrib/opensolaris/lib/libzfs/common/libzfs.h
==============================================================================
--- stable/10/cddl/contrib/opensolaris/lib/libzfs/common/libzfs.h       Fri Nov 
13 09:32:04 2015        (r290757)
+++ stable/10/cddl/contrib/opensolaris/lib/libzfs/common/libzfs.h       Fri Nov 
13 09:39:55 2015        (r290758)
@@ -23,7 +23,7 @@
  * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
  * Copyright (c) 2011 Pawel Jakub Dawidek <pa...@dawidek.net>.
  * All rights reserved.
- * Copyright (c) 2013 by Delphix. All rights reserved.
+ * Copyright (c) 2011, 2014 by Delphix. All rights reserved.
  * Copyright (c) 2012, Joyent, Inc. All rights reserved.
  * Copyright (c) 2012 Martin Matuska <m...@freebsd.org>. All rights reserved.
  * Copyright (c) 2013 Steven Hartland. All rights reserved.
@@ -430,6 +430,7 @@ extern nvlist_t *zfs_valid_proplist(libz
 
 extern const char *zfs_prop_to_name(zfs_prop_t);
 extern int zfs_prop_set(zfs_handle_t *, const char *, const char *);
+extern int zfs_prop_set_list(zfs_handle_t *, nvlist_t *);
 extern int zfs_prop_get(zfs_handle_t *, zfs_prop_t, char *, size_t,
     zprop_source_t *, char *, size_t, boolean_t);
 extern int zfs_prop_get_recvd(zfs_handle_t *, const char *, char *, size_t,

Modified: stable/10/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_dataset.c
==============================================================================
--- stable/10/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_dataset.c       
Fri Nov 13 09:32:04 2015        (r290757)
+++ stable/10/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_dataset.c       
Fri Nov 13 09:39:55 2015        (r290758)
@@ -1528,15 +1528,10 @@ zfs_setprop_error(libzfs_handle_t *hdl, 
 int
 zfs_prop_set(zfs_handle_t *zhp, const char *propname, const char *propval)
 {
-       zfs_cmd_t zc = { 0 };
        int ret = -1;
-       prop_changelist_t *cl = NULL;
        char errbuf[1024];
        libzfs_handle_t *hdl = zhp->zfs_hdl;
-       nvlist_t *nvl = NULL, *realprops;
-       zfs_prop_t prop;
-       boolean_t do_prefix = B_TRUE;
-       int added_resv;
+       nvlist_t *nvl = NULL;
 
        (void) snprintf(errbuf, sizeof (errbuf),
            dgettext(TEXT_DOMAIN, "cannot set property for '%s'"),
@@ -1548,79 +1543,148 @@ zfs_prop_set(zfs_handle_t *zhp, const ch
                goto error;
        }
 
-       if ((realprops = zfs_valid_proplist(hdl, zhp->zfs_type, nvl,
-           zfs_prop_get_int(zhp, ZFS_PROP_ZONED), zhp, errbuf)) == NULL)
-               goto error;
+       ret = zfs_prop_set_list(zhp, nvl);
 
+error:
        nvlist_free(nvl);
-       nvl = realprops;
+       return (ret);
+}
 
-       prop = zfs_name_to_prop(propname);
 
-       /* We don't support those properties on FreeBSD. */
-       switch (prop) {
-       case ZFS_PROP_DEVICES:
-       case ZFS_PROP_ISCSIOPTIONS:
-       case ZFS_PROP_XATTR:
-       case ZFS_PROP_VSCAN:
-       case ZFS_PROP_NBMAND:
-       case ZFS_PROP_MLSLABEL:
-               (void) snprintf(errbuf, sizeof (errbuf),
-                   "property '%s' not supported on FreeBSD", propname);
-               ret = zfs_error(hdl, EZFS_PERM, errbuf);
-               goto error;
-       }
 
-       if (prop == ZFS_PROP_VOLSIZE) {
-               if ((added_resv = zfs_add_synthetic_resv(zhp, nvl)) == -1)
-                       goto error;
-       }
+/*
+ * Given an nvlist of property names and values, set the properties for the
+ * given dataset.
+ */
+int
+zfs_prop_set_list(zfs_handle_t *zhp, nvlist_t *props)
+{
+       zfs_cmd_t zc = { 0 };
+       int ret = -1;
+       prop_changelist_t **cls = NULL;
+       int cl_idx;
+       char errbuf[1024];
+       libzfs_handle_t *hdl = zhp->zfs_hdl;
+       nvlist_t *nvl;
+       int nvl_len;
+       int added_resv;
 
-       if ((cl = changelist_gather(zhp, prop, 0, 0)) == NULL)
-               goto error;
+       (void) snprintf(errbuf, sizeof (errbuf),
+           dgettext(TEXT_DOMAIN, "cannot set property for '%s'"),
+           zhp->zfs_name);
 
-       if (prop == ZFS_PROP_MOUNTPOINT && changelist_haszonedchild(cl)) {
-               zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
-                   "child dataset with inherited mountpoint is used "
-                   "in a non-global zone"));
-               ret = zfs_error(hdl, EZFS_ZONED, errbuf);
+       if ((nvl = zfs_valid_proplist(hdl, zhp->zfs_type, props,
+           zfs_prop_get_int(zhp, ZFS_PROP_ZONED), zhp, errbuf)) == NULL)
                goto error;
-       }
 
        /*
-        * We don't want to unmount & remount the dataset when changing
-        * its canmount property to 'on' or 'noauto'.  We only use
-        * the changelist logic to unmount when setting canmount=off.
-        */
-       if (prop == ZFS_PROP_CANMOUNT) {
-               uint64_t idx;
-               int err = zprop_string_to_index(prop, propval, &idx,
-                   ZFS_TYPE_DATASET);
-               if (err == 0 && idx != ZFS_CANMOUNT_OFF)
-                       do_prefix = B_FALSE;
+        * We have to check for any extra properties which need to be added
+        * before computing the length of the nvlist.
+        */
+       for (nvpair_t *elem = nvlist_next_nvpair(nvl, NULL);
+           elem != NULL;
+           elem = nvlist_next_nvpair(nvl, elem)) {
+               if (zfs_name_to_prop(nvpair_name(elem)) == ZFS_PROP_VOLSIZE &&
+                   (added_resv = zfs_add_synthetic_resv(zhp, nvl)) == -1) {
+                       goto error;
+               }
        }
-
-       if (do_prefix && (ret = changelist_prefix(cl)) != 0)
+       /*
+        * Check how many properties we're setting and allocate an array to
+        * store changelist pointers for postfix().
+        */
+       nvl_len = 0;
+       for (nvpair_t *elem = nvlist_next_nvpair(nvl, NULL);
+           elem != NULL;
+           elem = nvlist_next_nvpair(nvl, elem))
+               nvl_len++;
+       if ((cls = calloc(nvl_len, sizeof (prop_changelist_t *))) == NULL)
                goto error;
 
+       cl_idx = 0;
+       for (nvpair_t *elem = nvlist_next_nvpair(nvl, NULL);
+           elem != NULL;
+           elem = nvlist_next_nvpair(nvl, elem)) {
+
+               zfs_prop_t prop = zfs_name_to_prop(nvpair_name(elem));
+
+               assert(cl_idx < nvl_len);
+               /*
+                * We don't want to unmount & remount the dataset when changing
+                * its canmount property to 'on' or 'noauto'.  We only use
+                * the changelist logic to unmount when setting canmount=off.
+                */
+               if (!(prop == ZFS_PROP_CANMOUNT &&
+                   fnvpair_value_uint64(elem) != ZFS_CANMOUNT_OFF)) {
+                       cls[cl_idx] = changelist_gather(zhp, prop, 0, 0);
+                       if (cls[cl_idx] == NULL)
+                               goto error;
+               }
+
+               if (prop == ZFS_PROP_MOUNTPOINT &&
+                   changelist_haszonedchild(cls[cl_idx])) {
+                       zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+                           "child dataset with inherited mountpoint is used "
+                           "in a non-global zone"));
+                       ret = zfs_error(hdl, EZFS_ZONED, errbuf);
+                       goto error;
+               }
+
+               /* We don't support those properties on FreeBSD. */
+               switch (prop) {
+               case ZFS_PROP_DEVICES:
+               case ZFS_PROP_ISCSIOPTIONS:
+               case ZFS_PROP_XATTR:
+               case ZFS_PROP_VSCAN:
+               case ZFS_PROP_NBMAND:
+               case ZFS_PROP_MLSLABEL:
+                       (void) snprintf(errbuf, sizeof (errbuf),
+                           "property '%s' not supported on FreeBSD",
+                           nvpair_name(elem));
+                       ret = zfs_error(hdl, EZFS_PERM, errbuf);
+                       goto error;
+               }
+
+               if (cls[cl_idx] != NULL &&
+                   (ret = changelist_prefix(cls[cl_idx])) != 0)
+                       goto error;
+
+               cl_idx++;
+       }
+       assert(cl_idx == nvl_len);
+
        /*
-        * Execute the corresponding ioctl() to set this property.
+        * Execute the corresponding ioctl() to set this list of properties.
         */
        (void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
 
-       if (zcmd_write_src_nvlist(hdl, &zc, nvl) != 0)
+       if ((ret = zcmd_write_src_nvlist(hdl, &zc, nvl)) != 0 ||
+           (ret = zcmd_alloc_dst_nvlist(hdl, &zc, 0)) != 0)
                goto error;
 
        ret = zfs_ioctl(hdl, ZFS_IOC_SET_PROP, &zc);
 
        if (ret != 0) {
-               zfs_setprop_error(hdl, prop, errno, errbuf);
+               /* Get the list of unset properties back and report them. */
+               nvlist_t *errorprops = NULL;
+               if (zcmd_read_dst_nvlist(hdl, &zc, &errorprops) != 0)
+                       goto error;
+               for (nvpair_t *elem = nvlist_next_nvpair(nvl, NULL);
+                   elem != NULL;
+                   elem = nvlist_next_nvpair(nvl, elem)) {
+                       zfs_prop_t prop = zfs_name_to_prop(nvpair_name(elem));
+                       zfs_setprop_error(hdl, prop, errno, errbuf);
+               }
+               nvlist_free(errorprops);
+
                if (added_resv && errno == ENOSPC) {
                        /* clean up the volsize property we tried to set */
                        uint64_t old_volsize = zfs_prop_get_int(zhp,
                            ZFS_PROP_VOLSIZE);
                        nvlist_free(nvl);
+                       nvl = NULL;
                        zcmd_free_nvlists(&zc);
+
                        if (nvlist_alloc(&nvl, NV_UNIQUE_NAME, 0) != 0)
                                goto error;
                        if (nvlist_add_uint64(nvl,
@@ -1632,8 +1696,13 @@ zfs_prop_set(zfs_handle_t *zhp, const ch
                        (void) zfs_ioctl(hdl, ZFS_IOC_SET_PROP, &zc);
                }
        } else {
-               if (do_prefix)
-                       ret = changelist_postfix(cl);
+               for (cl_idx = 0; cl_idx < nvl_len; cl_idx++) {
+                       if (cls[cl_idx] != NULL) {
+                               int clp_err = changelist_postfix(cls[cl_idx]);
+                               if (clp_err != 0)
+                                       ret = clp_err;
+                       }
+               }
 
                /*
                 * Refresh the statistics so the new property value
@@ -1646,8 +1715,13 @@ zfs_prop_set(zfs_handle_t *zhp, const ch
 error:
        nvlist_free(nvl);
        zcmd_free_nvlists(&zc);
-       if (cl)
-               changelist_free(cl);
+       if (cls != NULL) {
+               for (cl_idx = 0; cl_idx < nvl_len; cl_idx++) {
+                       if (cls[cl_idx] != NULL)
+                               changelist_free(cls[cl_idx]);
+               }
+               free(cls);
+       }
        return (ret);
 }
 
@@ -4197,7 +4271,7 @@ zfs_smb_acl_mgmt(libzfs_handle_t *hdl, c
        if (cmd == ZFS_SMB_ACL_RENAME) {
                if (nvlist_alloc(&nvlist, NV_UNIQUE_NAME, 0) != 0) {
                        (void) no_memory(hdl);
-                       return (NULL);
+                       return (0);
                }
        }
 

Modified: stable/10/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_util.c
==============================================================================
--- stable/10/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_util.c  Fri Nov 
13 09:32:04 2015        (r290757)
+++ stable/10/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_util.c  Fri Nov 
13 09:39:55 2015        (r290758)
@@ -22,7 +22,7 @@
 /*
  * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
  * Copyright (c) 2013, Joyent, Inc. All rights reserved.
- * Copyright (c) 2012 by Delphix. All rights reserved.
+ * Copyright (c) 2011, 2014 by Delphix. All rights reserved.
  */
 
 /*
@@ -782,8 +782,9 @@ zcmd_alloc_dst_nvlist(libzfs_handle_t *h
        if (len == 0)
                len = 16 * 1024;
        zc->zc_nvlist_dst_size = len;
-       if ((zc->zc_nvlist_dst = (uint64_t)(uintptr_t)
-           zfs_alloc(hdl, zc->zc_nvlist_dst_size)) == 0)
+       zc->zc_nvlist_dst =
+           (uint64_t)(uintptr_t)zfs_alloc(hdl, zc->zc_nvlist_dst_size);
+       if (zc->zc_nvlist_dst == 0)
                return (-1);
 
        return (0);
@@ -798,9 +799,9 @@ int
 zcmd_expand_dst_nvlist(libzfs_handle_t *hdl, zfs_cmd_t *zc)
 {
        free((void *)(uintptr_t)zc->zc_nvlist_dst);
-       if ((zc->zc_nvlist_dst = (uint64_t)(uintptr_t)
-           zfs_alloc(hdl, zc->zc_nvlist_dst_size))
-           == 0)
+       zc->zc_nvlist_dst =
+           (uint64_t)(uintptr_t)zfs_alloc(hdl, zc->zc_nvlist_dst_size);
+       if (zc->zc_nvlist_dst == 0)
                return (-1);
 
        return (0);
@@ -815,6 +816,9 @@ zcmd_free_nvlists(zfs_cmd_t *zc)
        free((void *)(uintptr_t)zc->zc_nvlist_conf);
        free((void *)(uintptr_t)zc->zc_nvlist_src);
        free((void *)(uintptr_t)zc->zc_nvlist_dst);
+       zc->zc_nvlist_conf = NULL;
+       zc->zc_nvlist_src = NULL;
+       zc->zc_nvlist_dst = NULL;
 }
 
 static int
_______________________________________________
svn-src-stable-10@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-stable-10
To unsubscribe, send any mail to "svn-src-stable-10-unsubscr...@freebsd.org"

Reply via email to