diff --git a/sys/contrib/openzfs/lib/libshare/os/freebsd/nfs.c.sav b/sys/contrib/openzfs/lib/libshare/os/freebsd/nfs.c --- a/sys/contrib/openzfs/lib/libshare/os/freebsd/nfs.c.sav +++ b/sys/contrib/openzfs/lib/libshare/os/freebsd/nfs.c @@ -106,19 +106,34 @@ if (strcmp(shareopts, "on") == 0) shareopts = ""; - boolean_t need_free; - char *mp; + boolean_t need_free, fnd_semi; + char *mp, lineopts[OPTSSIZE], *exportopts, *s; + size_t whitelen; int rc = nfs_escape_mountpoint(impl_share->sa_mountpoint, &mp, &need_free); if (rc != SA_OK) return (rc); - if (fputs(mp, tmpfile) == EOF || - fputc('\t', tmpfile) == EOF || - translate_opts(shareopts, tmpfile) == EOF || - fputc('\n', tmpfile) == EOF) { - fprintf(stderr, "failed to write to temporary file\n"); - rc = SA_SYSTEM_ERR; + strlcpy(lineopts, shareopts, sizeof(lineopts)); + s = lineopts; + fnd_semi = B_FALSE; + while ((exportopts = strsep(&s, ";")) != NULL) { + if (s != NULL) + fnd_semi = B_TRUE; + /* Ignore only whitespace between ';' separated option sets. */ + if (fnd_semi) { + whitelen = strspn(exportopts, "\t "); + if (exportopts[whitelen] == '\0') + continue; + } + if (fputs(mp, tmpfile) == EOF || + fputc('\t', tmpfile) == EOF || + translate_opts(exportopts, tmpfile) == EOF || + fputc('\n', tmpfile) == EOF) { + fprintf(stderr, "failed to write to temporary file\n"); + rc = SA_SYSTEM_ERR; + break; + } } if (need_free) diff --git a/sys/contrib/openzfs/man/man7/zfsprops.7.sav b/sys/contrib/openzfs/man/man7/zfsprops.7 --- a/sys/contrib/openzfs/man/man7/zfsprops.7.sav +++ b/sys/contrib/openzfs/man/man7/zfsprops.7 @@ -38,7 +38,7 @@ .\" Copyright (c) 2019, Kjeld Schouten-Lebbing .\" Copyright (c) 2022 Hewlett Packard Enterprise Development LP. .\" -.Dd August 8, 2023 +.Dd June 29, 2024 .Dt ZFSPROPS 7 .Os . @@ -1726,6 +1726,13 @@ .Xr exports 5 . This is done to negate the need for quoting, as well as to make parsing with scripts easier. +.Pp +For FreeBSD, there may be multiple sets of options separated by semicolon(s). +Each set of options must apply to different hosts or networks and each +set of options will create a separate line for +.Xr exports 5 . +Any semicolon separated option set that consists entirely of whitespace +will be ignored. .Pp See .Xr exports 5