aboutsummaryrefslogtreecommitdiff
path: root/usr.sbin
diff options
context:
space:
mode:
Diffstat (limited to 'usr.sbin')
-rw-r--r--usr.sbin/bhyve/acpi.c124
-rw-r--r--usr.sbin/bhyve/acpi.h3
-rw-r--r--usr.sbin/bhyve/amd64/bhyverun_machdep.c14
-rw-r--r--usr.sbin/bhyve/amd64/xmsr.c9
-rw-r--r--usr.sbin/bhyve/bhyve.880
-rw-r--r--usr.sbin/bhyve/bhyverun.c174
-rw-r--r--usr.sbin/bhyve/bhyverun.h1
-rw-r--r--usr.sbin/bhyve/bootrom.c1
-rw-r--r--usr.sbin/bhyve/pci_emul.c1
-rw-r--r--usr.sbin/bhyve/pci_fbuf.c1
-rw-r--r--usr.sbin/bhyve/pci_passthru.c1
-rw-r--r--usr.sbin/bhyve/pci_xhci.c12
-rw-r--r--usr.sbin/bhyve/tpm_ppi_qemu.c2
-rw-r--r--usr.sbin/bhyve/usb_emul.h1
-rw-r--r--usr.sbin/bluetooth/sdpd/server.c12
-rw-r--r--usr.sbin/bsdinstall/Makefile5
-rw-r--r--usr.sbin/bsdinstall/bsdinstall.82
-rwxr-xr-xusr.sbin/bsdinstall/scripts/bootconfig2
-rwxr-xr-xusr.sbin/bsdinstall/scripts/pkgbase.in13
-rwxr-xr-xusr.sbin/bsdinstall/scripts/zfsboot143
-rw-r--r--usr.sbin/bsnmpd/bsnmpd/Makefile2
-rw-r--r--usr.sbin/bsnmpd/tools/libbsnmptools/bsnmptools.c5
-rw-r--r--usr.sbin/chroot/chroot.814
-rw-r--r--usr.sbin/chroot/chroot.c7
-rw-r--r--usr.sbin/ctladm/tests/port.sh16
-rw-r--r--usr.sbin/devinfo/devinfo.c13
-rw-r--r--usr.sbin/efitable/efitable.813
-rw-r--r--usr.sbin/efitable/efitable.c50
-rw-r--r--usr.sbin/getfmac/getfmac.83
-rw-r--r--usr.sbin/gssd/Makefile2
-rw-r--r--usr.sbin/jail/command.c38
-rw-r--r--usr.sbin/jail/config.c13
-rw-r--r--usr.sbin/jail/jail.c7
-rw-r--r--usr.sbin/jail/tests/commands.jail.conf2
-rwxr-xr-xusr.sbin/jail/tests/jail_basic_test.sh164
-rw-r--r--usr.sbin/jls/jls.820
-rw-r--r--usr.sbin/jls/jls.c56
-rw-r--r--usr.sbin/makefs/makefs.816
-rw-r--r--usr.sbin/makefs/tests/Makefile4
-rw-r--r--usr.sbin/makefs/tests/makefs_zfs_tests.sh92
-rw-r--r--usr.sbin/makefs/zfs.c6
-rw-r--r--usr.sbin/makefs/zfs/dsl.c65
-rw-r--r--usr.sbin/makefs/zfs/fs.c45
-rw-r--r--usr.sbin/makefs/zfs/objset.c1
-rw-r--r--usr.sbin/makefs/zfs/vdev.c1
-rw-r--r--usr.sbin/makefs/zfs/zap.c13
-rw-r--r--usr.sbin/mfiutil/Makefile2
-rw-r--r--usr.sbin/rpc.lockd/kern.c19
-rw-r--r--usr.sbin/rwhod/rwhod.c8
-rw-r--r--usr.sbin/spi/Makefile2
-rw-r--r--usr.sbin/trim/trim.818
-rw-r--r--usr.sbin/trim/trim.c11
-rw-r--r--usr.sbin/ypldap/ldapclient.c2
-rw-r--r--usr.sbin/ypldap/ypldap.c2
-rw-r--r--usr.sbin/ypldap/ypldap_dns.c2
55 files changed, 1031 insertions, 304 deletions
diff --git a/usr.sbin/bhyve/acpi.c b/usr.sbin/bhyve/acpi.c
index 85864da57af2..6ff8dd8e273b 100644
--- a/usr.sbin/bhyve/acpi.c
+++ b/usr.sbin/bhyve/acpi.c
@@ -37,9 +37,12 @@
*/
#include <sys/param.h>
+#include <sys/cpuset.h>
+#include <sys/domainset.h>
#include <sys/endian.h>
#include <sys/errno.h>
#include <sys/stat.h>
+#include <sys/tree.h>
#include <err.h>
#include <paths.h>
@@ -50,7 +53,9 @@
#include <string.h>
#include <unistd.h>
+#include <dev/vmm/vmm_mem.h>
#include <machine/vmm.h>
+#include <machine/vmm_dev.h>
#include <vmmapi.h>
#include "bhyverun.h"
@@ -79,6 +84,22 @@ static char basl_template[MAXPATHLEN];
static char basl_stemplate[MAXPATHLEN];
/*
+ * SRAT vCPU affinity info.
+ */
+struct acpi_vcpu_affinity_entry {
+ RB_ENTRY(acpi_vcpu_affinity_entry) entry;
+ int vcpuid;
+ int domain;
+};
+
+static int vcpu_affinity_cmp(struct acpi_vcpu_affinity_entry *const a1,
+ struct acpi_vcpu_affinity_entry *const a2);
+static RB_HEAD(vcpu_affinities,
+ acpi_vcpu_affinity_entry) aff_head = RB_INITIALIZER(&aff_head);
+RB_GENERATE_STATIC(vcpu_affinities, acpi_vcpu_affinity_entry, entry,
+ vcpu_affinity_cmp);
+
+/*
* State for dsdt_line(), dsdt_indent(), and dsdt_unindent().
*/
static FILE *dsdt_fp;
@@ -121,6 +142,31 @@ acpi_tables_add_device(const struct acpi_device *const dev)
return (0);
}
+static int
+vcpu_affinity_cmp(struct acpi_vcpu_affinity_entry *a1,
+ struct acpi_vcpu_affinity_entry *a2)
+{
+ return (a1->vcpuid < a2->vcpuid ? -1 : a1->vcpuid > a2->vcpuid);
+}
+
+int
+acpi_add_vcpu_affinity(int vcpuid, int domain)
+{
+ struct acpi_vcpu_affinity_entry *entry = calloc(1, sizeof(*entry));
+ if (entry == NULL) {
+ return (ENOMEM);
+ }
+
+ entry->vcpuid = vcpuid;
+ entry->domain = domain;
+ if (RB_INSERT(vcpu_affinities, &aff_head, entry) != NULL) {
+ free(entry);
+ return (EEXIST);
+ }
+
+ return (0);
+}
+
/*
* Helper routines for writing to the DSDT from other modules.
*/
@@ -726,6 +772,83 @@ build_spcr(struct vmctx *const ctx)
return (0);
}
+static int
+build_srat(struct vmctx *const ctx)
+{
+ ACPI_TABLE_SRAT srat;
+ ACPI_SRAT_MEM_AFFINITY srat_mem_affinity;
+ ACPI_SRAT_CPU_AFFINITY srat_cpu_affinity;
+
+ struct acpi_vcpu_affinity_entry *ep;
+ struct basl_table *table;
+ int segid, domain;
+ int _flags, _prot;
+ vm_ooffset_t _off;
+ size_t maplen;
+ uint64_t gpa;
+ int ret;
+
+ if (RB_EMPTY(&aff_head))
+ return (0);
+
+ memset(&srat, 0, sizeof(srat));
+ BASL_EXEC(basl_table_create(&table, ctx, ACPI_SIG_SRAT,
+ BASL_TABLE_ALIGNMENT));
+ BASL_EXEC(basl_table_append_header(table, ACPI_SIG_SRAT, 1, 1));
+ srat.TableRevision = 1;
+ BASL_EXEC(basl_table_append_content(table, &srat, sizeof(srat)));
+
+ /*
+ * Iterate over the VM's memory maps and add
+ * a 'Memory Affinity Structure' for each mapping.
+ */
+ gpa = 0;
+ while (1) {
+ ret = vm_mmap_getnext(ctx, &gpa, &segid, &_off, &maplen, &_prot,
+ &_flags);
+ if (ret) {
+ break;
+ }
+
+ if (segid >= VM_SYSMEM && segid < VM_BOOTROM) {
+ domain = segid - VM_SYSMEM;
+ } else {
+ /* Treat devmem segs as domain 0. */
+ domain = 0;
+ }
+ memset(&srat_mem_affinity, 0, sizeof(srat_mem_affinity));
+ srat_mem_affinity.Header.Type = ACPI_SRAT_TYPE_MEMORY_AFFINITY;
+ srat_mem_affinity.Header.Length = sizeof(srat_mem_affinity);
+ srat_mem_affinity.Flags |= ACPI_SRAT_MEM_ENABLED;
+ srat_mem_affinity.ProximityDomain = htole32(domain);
+ srat_mem_affinity.BaseAddress = htole64(gpa);
+ srat_mem_affinity.Length = htole64(maplen);
+ srat_mem_affinity.Flags = htole32(ACPI_SRAT_MEM_ENABLED);
+ BASL_EXEC(basl_table_append_bytes(table, &srat_mem_affinity,
+ sizeof(srat_mem_affinity)));
+ gpa += maplen;
+ }
+
+ /*
+ * Iterate over each "vCPUid to domain id" mapping and emit a
+ * 'Processor Local APIC/SAPIC Affinity Structure' for each entry.
+ */
+ RB_FOREACH(ep, vcpu_affinities, &aff_head) {
+ memset(&srat_cpu_affinity, 0, sizeof(srat_cpu_affinity));
+ srat_cpu_affinity.Header.Type = ACPI_SRAT_TYPE_CPU_AFFINITY;
+ srat_cpu_affinity.Header.Length = sizeof(srat_cpu_affinity);
+ srat_cpu_affinity.ProximityDomainLo = (uint8_t)ep->domain;
+ srat_cpu_affinity.ApicId = (uint8_t)ep->vcpuid;
+ srat_cpu_affinity.Flags = htole32(ACPI_SRAT_CPU_USE_AFFINITY);
+ BASL_EXEC(basl_table_append_bytes(table, &srat_cpu_affinity,
+ sizeof(srat_cpu_affinity)));
+ }
+
+ BASL_EXEC(basl_table_register_to_rsdt(table));
+
+ return (0);
+}
+
int
acpi_build(struct vmctx *ctx, int ncpu)
{
@@ -765,6 +888,7 @@ acpi_build(struct vmctx *ctx, int ncpu)
BASL_EXEC(build_mcfg(ctx));
BASL_EXEC(build_facs(ctx));
BASL_EXEC(build_spcr(ctx));
+ BASL_EXEC(build_srat(ctx));
/* Build ACPI device-specific tables such as a TPM2 table. */
const struct acpi_device_list_entry *entry;
diff --git a/usr.sbin/bhyve/acpi.h b/usr.sbin/bhyve/acpi.h
index 4b557993d67f..f4d24d63800e 100644
--- a/usr.sbin/bhyve/acpi.h
+++ b/usr.sbin/bhyve/acpi.h
@@ -56,7 +56,8 @@ struct vmctx;
int acpi_build(struct vmctx *ctx, int ncpu);
void acpi_raise_gpe(struct vmctx *ctx, unsigned bit);
int acpi_tables_add_device(const struct acpi_device *const dev);
-void dsdt_line(const char *fmt, ...);
+int acpi_add_vcpu_affinity(int vcpuid, int domain);
+void dsdt_line(const char *fmt, ...) __printflike(1, 2);
void dsdt_fixed_ioport(uint16_t iobase, uint16_t length);
void dsdt_fixed_irq(uint8_t irq);
void dsdt_fixed_mem32(uint32_t base, uint32_t length);
diff --git a/usr.sbin/bhyve/amd64/bhyverun_machdep.c b/usr.sbin/bhyve/amd64/bhyverun_machdep.c
index 85af124b5536..dad8f1e52e4e 100644
--- a/usr.sbin/bhyve/amd64/bhyverun_machdep.c
+++ b/usr.sbin/bhyve/amd64/bhyverun_machdep.c
@@ -91,6 +91,7 @@ bhyve_usage(int code)
" -K: PS2 keyboard layout\n"
" -l: LPC device configuration\n"
" -m: memory size\n"
+ " -n: NUMA domain specification\n"
" -o: set config 'var' to 'value'\n"
" -P: vmexit from the guest on pause\n"
" -p: pin 'vcpu' to 'hostcpu'\n"
@@ -117,9 +118,9 @@ bhyve_optparse(int argc, char **argv)
int c;
#ifdef BHYVE_SNAPSHOT
- optstr = "aehuwxACDHIPSWYk:f:o:p:G:c:s:m:l:K:U:r:";
+ optstr = "aehuwxACDHIPSWYk:f:o:p:G:c:s:m:n:l:K:U:r:";
#else
- optstr = "aehuwxACDHIPSWYk:f:o:p:G:c:s:m:l:K:U:";
+ optstr = "aehuwxACDHIPSWYk:f:o:p:G:c:s:m:n:l:K:U:";
#endif
while ((c = getopt(argc, argv, optstr)) != -1) {
switch (c) {
@@ -194,6 +195,15 @@ bhyve_optparse(int argc, char **argv)
case 'm':
set_config_value("memory.size", optarg);
break;
+ case 'n':
+ if (bhyve_numa_parse(optarg) != 0)
+ errx(EX_USAGE,
+ "invalid NUMA configuration "
+ "'%s'",
+ optarg);
+ if (!get_config_bool("acpi_tables"))
+ errx(EX_USAGE, "NUMA emulation requires ACPI");
+ break;
case 'o':
if (!bhyve_parse_config_option(optarg)) {
errx(EX_USAGE,
diff --git a/usr.sbin/bhyve/amd64/xmsr.c b/usr.sbin/bhyve/amd64/xmsr.c
index cd80e4ef782e..7c174728f4fa 100644
--- a/usr.sbin/bhyve/amd64/xmsr.c
+++ b/usr.sbin/bhyve/amd64/xmsr.c
@@ -204,6 +204,15 @@ emulate_rdmsr(struct vcpu *vcpu __unused, uint32_t num, uint64_t *val)
*val = 1;
break;
+ case MSR_VM_CR:
+ /*
+ * We currently don't support nested virt.
+ * Windows seems to ignore the cpuid bits and reads this
+ * MSR anyways.
+ */
+ *val = VM_CR_SVMDIS;
+ break;
+
default:
error = -1;
break;
diff --git a/usr.sbin/bhyve/bhyve.8 b/usr.sbin/bhyve/bhyve.8
index 62e567fd359d..89c0b23961a8 100644
--- a/usr.sbin/bhyve/bhyve.8
+++ b/usr.sbin/bhyve/bhyve.8
@@ -269,8 +269,56 @@ or
(either upper or lower case)
to indicate a multiple of kilobytes, megabytes, gigabytes, or terabytes.
If no suffix is given, the value is assumed to be in megabytes.
-.Pp
The default is 256M.
+.Pp
+.It Fl n Ar id Ns Cm \&, Ns Ar size Ns Cm \&, Ns Ar cpus Ns Op Cm \&, Ns Ar domain_policy
+Configure guest NUMA domains.
+This option applies only to the amd64 platform.
+.Pp
+The
+.Fl n
+option allows the guest physical address space to be partitioned into domains.
+The layout of each domain is encoded in an ACPI table
+visible to the guest operating system.
+The
+.Fl n
+option also allows the specification of a
+.Xr domainset 9
+memory allocation policy for the host memory backing a given NUMA domain.
+A guest can have up to 8 NUMA domains.
+This feature requires that the guest use a boot ROM, and in
+particular cannot be used if the guest was initialized using
+.Xr bhyveload 8 .
+.Pp
+Each domain is identified by a numerical
+.Em id .
+The domain memory
+.Em size
+is specified using the same format as the
+.Fl m
+flag.
+The sum of all
+.Em size
+parameters overrides the total VM memory size specified by the
+.Fl m
+flag.
+However, if at least one domain memory size parameter is
+missing, the total VM memory size will be equally distributed across
+all emulated domains.
+The
+.Em cpuset
+parameter specifies the set of CPUs that are part of the domain.
+The
+.Em domain_policy
+parameter may be optionally used to configure the
+.Xr domainset 9
+host NUMA memory allocation policy for an emulated
+domain.
+See the
+.Ar -n
+flag in
+.Xr cpuset 1
+for a list of valid NUMA memory allocation policies and their formats.
.It Fl o Ar var Ns Cm = Ns Ar value
Set the configuration variable
.Ar var
@@ -1202,6 +1250,33 @@ using this configuration file, use flag
.Bd -literal -offset indent
/usr/sbin/bhyve -k configfile vm0
.Ed
+.Pp
+Run a UEFI virtual machine with four CPUs and two emulated NUMA domains:
+.Bd -literal -offset indent
+bhyve -c 4 -w -H \\
+ -s 0,hostbridge \\
+ -s 4,ahci-hd,disk.img \\
+ -s 31,lpc -l com1,stdio \\
+ -l bootrom,/usr/local/share/uefi-firmware/BHYVE_UEFI.fd \\
+ -n id=0,size=4G,cpus=0-1 \\
+ -n id=1,size=4G,cpus=2-3 \\
+ numavm
+.Ed
+.Pp
+Assuming a host machine with two NUMA domains,
+run a UEFI virtual machine with four CPUs using a
+.Ar prefer
+.Xr domainset 9
+policy to allocate guest memory from the first host NUMA domain only.
+.Bd -literal -offset indent
+bhyve -c 2 -w -H \\
+ -s 0,hostbridge \\
+ -s 4,ahci-hd,disk.img \\
+ -s 31,lpc -l com1,stdio \\
+ -l bootrom,/usr/local/share/uefi-firmware/BHYVE_UEFI.fd \\
+ -n id=0,size=4G,cpus=0-1,domain_policy=prefer:0 \\
+ numavm
+.Ed
.Sh SEE ALSO
.Xr bhyve 4 ,
.Xr netgraph 4 ,
@@ -1211,7 +1286,8 @@ using this configuration file, use flag
.Xr bhyve_config 5 ,
.Xr ethers 5 ,
.Xr bhyvectl 8 ,
-.Xr bhyveload 8
+.Xr bhyveload 8 ,
+.Xr domainset 9
.Pp
.Rs
.%A Intel
diff --git a/usr.sbin/bhyve/bhyverun.c b/usr.sbin/bhyve/bhyverun.c
index be9cd1611700..9ead49582a7d 100644
--- a/usr.sbin/bhyve/bhyverun.c
+++ b/usr.sbin/bhyve/bhyverun.c
@@ -30,6 +30,8 @@
#ifndef WITHOUT_CAPSICUM
#include <sys/capsicum.h>
#endif
+#include <sys/cpuset.h>
+#include <sys/domainset.h>
#include <sys/mman.h>
#ifdef BHYVE_SNAPSHOT
#include <sys/socket.h>
@@ -54,6 +56,7 @@
#include <fcntl.h>
#endif
#include <libgen.h>
+#include <libutil.h>
#include <unistd.h>
#include <assert.h>
#include <pthread.h>
@@ -68,6 +71,7 @@
#include <libxo/xo.h>
#endif
+#include <dev/vmm/vmm_mem.h>
#include <vmmapi.h>
#include "acpi.h"
@@ -108,6 +112,9 @@ static const int BSP = 0;
static cpuset_t cpumask;
+static struct vm_mem_domain guest_domains[VM_MAXMEMDOM];
+static int guest_ndomains = 0;
+
static void vm_loop(struct vmctx *ctx, struct vcpu *vcpu);
static struct vcpu_info {
@@ -179,6 +186,118 @@ parse_int_value(const char *key, const char *value, int minval, int maxval)
return (lval);
}
+int
+bhyve_numa_parse(const char *opt)
+{
+ int id = -1;
+ nvlist_t *nvl;
+ char *cp, *str, *tofree;
+ char pathbuf[64] = { 0 };
+ char *size = NULL, *cpus = NULL, *domain_policy = NULL;
+
+ if (*opt == '\0') {
+ return (-1);
+ }
+
+ tofree = str = strdup(opt);
+ if (str == NULL)
+ errx(4, "Failed to allocate memory");
+
+ while ((cp = strsep(&str, ",")) != NULL) {
+ if (strncmp(cp, "id=", strlen("id=")) == 0)
+ id = parse_int_value("id", cp + strlen("id="), 0,
+ UINT8_MAX);
+ else if (strncmp(cp, "size=", strlen("size=")) == 0)
+ size = cp + strlen("size=");
+ else if (strncmp(cp,
+ "domain_policy=", strlen("domain_policy=")) == 0)
+ domain_policy = cp + strlen("domain_policy=");
+ else if (strncmp(cp, "cpus=", strlen("cpus=")) == 0)
+ cpus = cp + strlen("cpus=");
+ }
+
+ if (id == -1) {
+ EPRINTLN("Missing NUMA domain ID in '%s'", opt);
+ goto out;
+ }
+
+ snprintf(pathbuf, sizeof(pathbuf), "domains.%d", id);
+ nvl = find_config_node(pathbuf);
+ if (nvl == NULL)
+ nvl = create_config_node(pathbuf);
+ if (size != NULL)
+ set_config_value_node(nvl, "size", size);
+ if (domain_policy != NULL)
+ set_config_value_node(nvl, "domain_policy", domain_policy);
+ if (cpus != NULL)
+ set_config_value_node(nvl, "cpus", cpus);
+
+ free(tofree);
+ return (0);
+
+out:
+ free(tofree);
+ return (-1);
+}
+
+static void
+calc_mem_affinity(size_t vm_memsize)
+{
+ int i;
+ nvlist_t *nvl;
+ bool need_recalc;
+ const char *value;
+ struct vm_mem_domain *dom;
+ char pathbuf[64] = { 0 };
+
+ need_recalc = false;
+ for (i = 0; i < VM_MAXMEMDOM; i++) {
+ dom = &guest_domains[i];
+ snprintf(pathbuf, sizeof(pathbuf), "domains.%d", i);
+ nvl = find_config_node(pathbuf);
+ if (nvl == NULL) {
+ break;
+ }
+
+ value = get_config_value_node(nvl, "size");
+ need_recalc |= value == NULL;
+ if (value != NULL && vm_parse_memsize(value, &dom->size)) {
+ errx(EX_USAGE, "invalid memsize for domain %d: '%s'", i,
+ value);
+ }
+
+ dom->ds_mask = calloc(1, sizeof(domainset_t));
+ if (dom->ds_mask == NULL) {
+ errx(EX_OSERR, "Failed to allocate domainset mask");
+ }
+ dom->ds_size = sizeof(domainset_t);
+ value = get_config_value_node(nvl, "domain_policy");
+ if (value == NULL) {
+ dom->ds_policy = DOMAINSET_POLICY_INVALID;
+ DOMAINSET_ZERO(dom->ds_mask);
+ } else if (domainset_parselist(value, dom->ds_mask, &dom->ds_policy) !=
+ CPUSET_PARSE_OK) {
+ errx(EX_USAGE, "failed to parse domain policy '%s'", value);
+ }
+ }
+
+ guest_ndomains = i;
+ if (guest_ndomains == 0) {
+ /*
+ * No domains were specified - create domain
+ * 0 holding all CPUs and memory.
+ */
+ guest_ndomains = 1;
+ guest_domains[0].size = vm_memsize;
+ } else if (need_recalc) {
+ warnx("At least one domain memory size was not specified, distributing"
+ " total VM memory size across all domains");
+ for (i = 0; i < guest_ndomains; i++) {
+ guest_domains[i].size = vm_memsize / guest_ndomains;
+ }
+ }
+}
+
/*
* Set the sockets, cores, threads, and guest_cpus variables based on
* the configured topology.
@@ -340,6 +459,56 @@ build_vcpumaps(void)
}
}
+static void
+set_vcpu_affinities(void)
+{
+ int cpu, error;
+ nvlist_t *nvl = NULL;
+ cpuset_t cpus;
+ const char *value;
+ char pathbuf[64] = { 0 };
+
+ for (int dom = 0; dom < guest_ndomains; dom++) {
+ snprintf(pathbuf, sizeof(pathbuf), "domains.%d", dom);
+ nvl = find_config_node(pathbuf);
+ if (nvl == NULL)
+ break;
+
+ value = get_config_value_node(nvl, "cpus");
+ if (value == NULL) {
+ EPRINTLN("Missing CPU set for domain %d", dom);
+ exit(4);
+ }
+
+ parse_cpuset(dom, value, &cpus);
+ CPU_FOREACH_ISSET(cpu, &cpus) {
+ error = acpi_add_vcpu_affinity(cpu, dom);
+ if (error) {
+ EPRINTLN(
+ "Unable to set vCPU %d affinity for domain %d: %s",
+ cpu, dom, strerror(errno));
+ exit(4);
+ }
+ }
+ }
+ if (guest_ndomains > 1 || nvl != NULL)
+ return;
+
+ /*
+ * If we're dealing with one domain and no cpuset was provided, create a
+ * default one holding all cpus.
+ */
+ for (cpu = 0; cpu < guest_ncpus; cpu++) {
+ error = acpi_add_vcpu_affinity(cpu, 0);
+ if (error) {
+ EPRINTLN(
+ "Unable to set vCPU %d affinity for domain %d: %s",
+ cpu, 0, strerror(errno));
+ exit(4);
+ }
+ }
+}
+
void *
paddr_guest2host(struct vmctx *ctx, uintptr_t gaddr, size_t len)
{
@@ -713,18 +882,21 @@ main(int argc, char *argv[])
vcpu_info[vcpuid].vcpu = vm_vcpu_open(ctx, vcpuid);
}
+ calc_mem_affinity(memsize);
memflags = 0;
if (get_config_bool_default("memory.wired", false))
memflags |= VM_MEM_F_WIRED;
if (get_config_bool_default("memory.guest_in_core", false))
memflags |= VM_MEM_F_INCORE;
vm_set_memflags(ctx, memflags);
- error = vm_setup_memory(ctx, memsize, VM_MMAP_ALL);
+ error = vm_setup_memory_domains(ctx, VM_MMAP_ALL, guest_domains,
+ guest_ndomains);
if (error) {
fprintf(stderr, "Unable to setup memory (%d)\n", errno);
exit(4);
}
+ set_vcpu_affinities();
init_mem(guest_ncpus);
init_bootrom(ctx);
if (bhyve_init_platform(ctx, bsp) != 0)
diff --git a/usr.sbin/bhyve/bhyverun.h b/usr.sbin/bhyve/bhyverun.h
index 005de6dc5410..0a7bbd72a19c 100644
--- a/usr.sbin/bhyve/bhyverun.h
+++ b/usr.sbin/bhyve/bhyverun.h
@@ -73,6 +73,7 @@ void bhyve_parse_gdb_options(const char *opt);
#endif
int bhyve_pincpu_parse(const char *opt);
int bhyve_topology_parse(const char *opt);
+int bhyve_numa_parse(const char *opt);
void bhyve_init_vcpu(struct vcpu *vcpu);
void bhyve_start_vcpu(struct vcpu *vcpu, bool bsp);
diff --git a/usr.sbin/bhyve/bootrom.c b/usr.sbin/bhyve/bootrom.c
index e4adaca55947..339974cb2017 100644
--- a/usr.sbin/bhyve/bootrom.c
+++ b/usr.sbin/bhyve/bootrom.c
@@ -31,6 +31,7 @@
#include <sys/mman.h>
#include <sys/stat.h>
+#include <dev/vmm/vmm_mem.h>
#include <machine/vmm.h>
#include <err.h>
diff --git a/usr.sbin/bhyve/pci_emul.c b/usr.sbin/bhyve/pci_emul.c
index 2f04a488d9c1..9d6060e3e254 100644
--- a/usr.sbin/bhyve/pci_emul.c
+++ b/usr.sbin/bhyve/pci_emul.c
@@ -42,6 +42,7 @@
#include <stdbool.h>
#include <sysexits.h>
+#include <dev/vmm/vmm_mem.h>
#include <machine/vmm.h>
#include <machine/vmm_snapshot.h>
#include <vmmapi.h>
diff --git a/usr.sbin/bhyve/pci_fbuf.c b/usr.sbin/bhyve/pci_fbuf.c
index 125428e0b772..1e3ec77c15b0 100644
--- a/usr.sbin/bhyve/pci_fbuf.c
+++ b/usr.sbin/bhyve/pci_fbuf.c
@@ -29,6 +29,7 @@
#include <sys/types.h>
#include <sys/mman.h>
+#include <dev/vmm/vmm_mem.h>
#include <machine/vmm.h>
#include <machine/vmm_snapshot.h>
#include <vmmapi.h>
diff --git a/usr.sbin/bhyve/pci_passthru.c b/usr.sbin/bhyve/pci_passthru.c
index 9d38ae9168a1..a82078f6e036 100644
--- a/usr.sbin/bhyve/pci_passthru.c
+++ b/usr.sbin/bhyve/pci_passthru.c
@@ -38,6 +38,7 @@
#include <dev/io/iodev.h>
#include <dev/pci/pcireg.h>
+#include <dev/vmm/vmm_mem.h>
#include <vm/vm.h>
diff --git a/usr.sbin/bhyve/pci_xhci.c b/usr.sbin/bhyve/pci_xhci.c
index 5b21361f2823..0871bbb87fe5 100644
--- a/usr.sbin/bhyve/pci_xhci.c
+++ b/usr.sbin/bhyve/pci_xhci.c
@@ -2588,7 +2588,7 @@ pci_xhci_reset_port(struct pci_xhci_softc *sc, int portn, int warm)
if (dev) {
port->portsc &= ~(XHCI_PS_PLS_MASK | XHCI_PS_PR | XHCI_PS_PRC);
port->portsc |= XHCI_PS_PED |
- XHCI_PS_SPEED_SET(dev->dev_ue->ue_usbspeed);
+ XHCI_PS_SPEED_SET(dev->hci.hci_speed);
if (warm && dev->dev_ue->ue_usbver == 3) {
port->portsc |= XHCI_PS_WRC;
@@ -2622,11 +2622,11 @@ pci_xhci_init_port(struct pci_xhci_softc *sc, int portn)
if (dev->dev_ue->ue_usbver == 2) {
port->portsc |= XHCI_PS_PLS_SET(UPS_PORT_LS_POLL) |
- XHCI_PS_SPEED_SET(dev->dev_ue->ue_usbspeed);
+ XHCI_PS_SPEED_SET(dev->hci.hci_speed);
} else {
port->portsc |= XHCI_PS_PLS_SET(UPS_PORT_LS_U0) |
- XHCI_PS_PED | /* enabled */
- XHCI_PS_SPEED_SET(dev->dev_ue->ue_usbspeed);
+ XHCI_PS_PED | /* enabled */
+ XHCI_PS_SPEED_SET(dev->hci.hci_speed);
}
DPRINTF(("Init port %d 0x%x", portn, port->portsc));
@@ -2833,6 +2833,7 @@ pci_xhci_parse_devices(struct pci_xhci_softc *sc, nvlist_t *nvl)
dev->hci.hci_sc = dev;
dev->hci.hci_intr = pci_xhci_dev_intr;
dev->hci.hci_event = pci_xhci_dev_event;
+ dev->hci.hci_speed = USB_SPEED_MAX;
if (ue->ue_usbver == 2) {
if (usb2_port == sc->usb2_port_start +
@@ -2863,6 +2864,8 @@ pci_xhci_parse_devices(struct pci_xhci_softc *sc, nvlist_t *nvl)
dev->dev_ue = ue;
dev->dev_sc = devsc;
+ if (dev->hci.hci_speed == USB_SPEED_MAX)
+ dev->hci.hci_speed = ue->ue_usbspeed;
XHCI_SLOTDEV_PTR(sc, slot) = dev;
ndevices++;
@@ -3228,6 +3231,7 @@ pci_xhci_snapshot(struct vm_snapshot_meta *meta)
/* devices[i]->hci */
SNAPSHOT_VAR_OR_LEAVE(dev->hci.hci_address, meta, ret, done);
SNAPSHOT_VAR_OR_LEAVE(dev->hci.hci_port, meta, ret, done);
+ SNAPSHOT_VAR_OR_LEAVE(dev->hci.hci_speed, meta, ret, done);
}
SNAPSHOT_VAR_OR_LEAVE(sc->usb2_port_start, meta, ret, done);
diff --git a/usr.sbin/bhyve/tpm_ppi_qemu.c b/usr.sbin/bhyve/tpm_ppi_qemu.c
index 01b8493e7273..6974b574b983 100644
--- a/usr.sbin/bhyve/tpm_ppi_qemu.c
+++ b/usr.sbin/bhyve/tpm_ppi_qemu.c
@@ -207,7 +207,7 @@ tpm_ppi_write_dsdt_regions(void *sc __unused)
* Used for TCG Platform Reset Attack Mitigation
*/
dsdt_line("OperationRegion(TPP3, SystemMemory, 0x%8x, 1)",
- TPM_PPI_ADDRESS + sizeof(struct tpm_ppi_qemu));
+ TPM_PPI_ADDRESS + (uint32_t)sizeof(struct tpm_ppi_qemu));
dsdt_line("Field(TPP3, ByteAcc, NoLock, Preserve)");
dsdt_line("{");
dsdt_line(" MOVV, 8,");
diff --git a/usr.sbin/bhyve/usb_emul.h b/usr.sbin/bhyve/usb_emul.h
index 8e0afcb2878b..85dedfeacd3b 100644
--- a/usr.sbin/bhyve/usb_emul.h
+++ b/usr.sbin/bhyve/usb_emul.h
@@ -85,6 +85,7 @@ struct usb_hci {
/* controller managed fields */
int hci_address;
int hci_port;
+ int hci_speed;
};
/*
diff --git a/usr.sbin/bluetooth/sdpd/server.c b/usr.sbin/bluetooth/sdpd/server.c
index ab398cd9339f..05a4cb5f0236 100644
--- a/usr.sbin/bluetooth/sdpd/server.c
+++ b/usr.sbin/bluetooth/sdpd/server.c
@@ -345,14 +345,12 @@ server_accept_client(server_p srv, int32_t fd)
return;
}
} else {
- struct xucred cr;
+ uid_t uid;
+ gid_t gid;
struct passwd *pw;
/* Get peer's credentials */
- memset(&cr, 0, sizeof(cr));
- size = sizeof(cr);
-
- if (getsockopt(cfd, 0, LOCAL_PEERCRED, &cr, &size) < 0) {
+ if (getpeereid(cfd, &uid, &gid) < 0) {
log_err("Could not get peer's credentials. %s (%d)",
strerror(errno), errno);
close(cfd);
@@ -360,12 +358,12 @@ server_accept_client(server_p srv, int32_t fd)
}
/* Check credentials */
- pw = getpwuid(cr.cr_uid);
+ pw = getpwuid(uid);
if (pw != NULL)
priv = (strcmp(pw->pw_name, "root") == 0);
else
log_warning("Could not verify credentials for uid %d",
- cr.cr_uid);
+ uid);
memcpy(&srv->req_sa.l2cap_bdaddr, NG_HCI_BDADDR_ANY,
sizeof(srv->req_sa.l2cap_bdaddr));
diff --git a/usr.sbin/bsdinstall/Makefile b/usr.sbin/bsdinstall/Makefile
index 75db149b814b..e5bb3197fa05 100644
--- a/usr.sbin/bsdinstall/Makefile
+++ b/usr.sbin/bsdinstall/Makefile
@@ -22,8 +22,11 @@ REVISION?= ${_REVISION}
.if ${BRANCH} == CURRENT || ${BRANCH} == STABLE
SUBURL= base_latest
-.else
+.elif ${BRANCH} == RELEASE
SUBURL= base_release_${REVISION:C/[0-9]+\.//}
+.else
+.warning Invalid branch "${BRANCH}"
+SUBURL= base_latest
.endif
FreeBSD-base.conf: FreeBSD-base.conf.in
diff --git a/usr.sbin/bsdinstall/bsdinstall.8 b/usr.sbin/bsdinstall/bsdinstall.8
index 8fadacab9189..181abdcf9d05 100644
--- a/usr.sbin/bsdinstall/bsdinstall.8
+++ b/usr.sbin/bsdinstall/bsdinstall.8
@@ -451,7 +451,7 @@ Each option must be preceded by the -O flag to be taken into consideration
or the pool will not be created due to errors using the command
.Cm zpool .
Default:
-.Dq Li "-O compress=lz4 -O atime=off"
+.Dq Li "-O compression=on -O atime=off"
.It Ev ZFSBOOT_BEROOT_NAME
Name for the boot environment parent dataset.
This is a non-mountable dataset meant to be a parent dataset where different
diff --git a/usr.sbin/bsdinstall/scripts/bootconfig b/usr.sbin/bsdinstall/scripts/bootconfig
index 9b330801e409..41243ad14b9b 100755
--- a/usr.sbin/bsdinstall/scripts/bootconfig
+++ b/usr.sbin/bsdinstall/scripts/bootconfig
@@ -74,7 +74,7 @@ update_uefi_bootentry()
fi
$DIALOG --backtitle "$OSNAME Installer" --title 'Boot Configuration' \
- --yesno "There are multiple \"$OSNAME\" EFI boot entries. Would you like to remove them all and add a new one?" 0 0
+ --yesno "One or more \"$OSNAME\" EFI boot manager entries already exist. Would you like to remove them all and add a new one?" 0 0
if [ $? -eq $DIALOG_OK ]; then
for entry in $(efibootmgr | awk "\$NF == \"$EFI_LABEL_NAME\" { sub(/.*Boot/,\"\", \$1); sub(/\*/,\"\", \$1); print \$1 }"); do
efibootmgr -B -b ${entry}
diff --git a/usr.sbin/bsdinstall/scripts/pkgbase.in b/usr.sbin/bsdinstall/scripts/pkgbase.in
index 1ff93afe817b..cf8e84de6923 100755
--- a/usr.sbin/bsdinstall/scripts/pkgbase.in
+++ b/usr.sbin/bsdinstall/scripts/pkgbase.in
@@ -234,12 +234,17 @@ local function pkgbase()
local chroot = assert(os.getenv("BSDINSTALL_CHROOT"))
assert(os.execute("mkdir -p " .. chroot))
+ -- Always install the default FreeBSD-base.conf file to the chroot, even
+ -- if we don't actually fetch the packages from the repository specified
+ -- there (e.g. because we are performing an offline installation).
+ local chroot_repos_dir = chroot .. "/usr/local/etc/pkg/repos/"
+ assert(os.execute("mkdir -p " .. chroot_repos_dir))
+ assert(os.execute("cp /usr/share/bsdinstall/FreeBSD-base.conf " ..
+ chroot_repos_dir))
+
local repos_dir = os.getenv("BSDINSTALL_PKG_REPOS_DIR")
if not repos_dir then
- repos_dir = chroot .. "/usr/local/etc/pkg/repos/"
- assert(os.execute("mkdir -p " .. repos_dir))
- assert(os.execute("cp /usr/share/bsdinstall/FreeBSD-base.conf " .. repos_dir))
-
+ repos_dir = chroot_repos_dir
-- Since pkg always interprets fingerprints paths as relative to
-- the --rootdir we must copy the key from the host.
assert(os.execute("mkdir -p " .. chroot .. "/usr/share/keys"))
diff --git a/usr.sbin/bsdinstall/scripts/zfsboot b/usr.sbin/bsdinstall/scripts/zfsboot
index 493f137092ec..a3c1e2ddb89f 100755
--- a/usr.sbin/bsdinstall/scripts/zfsboot
+++ b/usr.sbin/bsdinstall/scripts/zfsboot
@@ -51,7 +51,7 @@ f_include $BSDCFG_SHARE/variable.subr
#
# Default options to use when creating zroot pool
#
-: ${ZFSBOOT_POOL_CREATE_OPTIONS:=-O compress=lz4 -O atime=off}
+: ${ZFSBOOT_POOL_CREATE_OPTIONS:=-O compression=on -O atime=off}
#
# Default name for the boot environment parent dataset
@@ -86,7 +86,7 @@ f_include $BSDCFG_SHARE/variable.subr
#
# Create a separate boot pool?
-# NB: Automatically set when using geli(8) or MBR
+# NB: Automatically set when using geli(8)
#
: ${ZFSBOOT_BOOT_POOL=}
@@ -96,12 +96,12 @@ f_include $BSDCFG_SHARE/variable.subr
: ${ZFSBOOT_BOOT_POOL_CREATE_OPTIONS:=}
#
-# Default name for boot pool when enabled (e.g., geli(8) or MBR)
+# Default name for boot pool when enabled (e.g., geli(8))
#
: ${ZFSBOOT_BOOT_POOL_NAME:=bootpool}
#
-# Default size for boot pool when enabled (e.g., geli(8) or MBR)
+# Default size for boot pool when enabled (e.g., geli(8))
#
: ${ZFSBOOT_BOOT_POOL_SIZE:=2g}
@@ -790,7 +790,7 @@ zfs_create_diskpart()
# Check for unknown partition scheme before proceeding further
case "$ZFSBOOT_PARTITION_SCHEME" in
- ""|MBR|GPT*) : known good ;;
+ ""|GPT*) : known good ;;
*)
f_dprintf "$funcname: %s is an unsupported partition scheme" \
"$ZFSBOOT_PARTITION_SCHEME"
@@ -825,14 +825,11 @@ zfs_create_diskpart()
#
# Lay down the desired type of partition scheme
#
- local setsize mbrindex align_small align_big
+ local setsize align_small align_big
#
# If user has requested 4 K alignment, add these params to the
# gpart add calls. With GPT, we align large partitions to 1 M for
- # improved performance on SSDs. MBR does not always play well with gaps
- # between partitions, so all alignment is only 4k for that case.
- # With MBR, we align the BSD partition that contains the MBR, otherwise
- # the system fails to boot.
+ # improved performance on SSDs.
#
if [ "$ZFSBOOT_FORCE_4K_SECTORS" ]; then
align_small="-a 4k"
@@ -974,90 +971,6 @@ zfs_create_diskpart()
/dev/$disk$targetpart
;;
- MBR) f_dprintf "$funcname: Creating MBR layout..."
- #
- # Enable boot pool if encryption is desired
- #
- [ "$ZFSBOOT_GELI_ENCRYPTION" ] && ZFSBOOT_BOOT_POOL=1
- #
- # 1. Create MBR layout (no labels)
- #
- f_eval_catch $funcname gpart "$GPART_CREATE" mbr $disk ||
- return $FAILURE
- f_eval_catch $funcname gpart "$GPART_BOOTCODE" /boot/mbr \
- $disk || return $FAILURE
-
- #
- # 2. Add freebsd slice with all available space
- #
- f_eval_catch $funcname gpart "$GPART_ADD_ALIGN" \
- "$align_small" freebsd $disk || return $FAILURE
- f_eval_catch $funcname gpart "$GPART_SET_ACTIVE" 1 $disk ||
- return $FAILURE
- # Pedantically nuke any old labels
- f_eval_catch -d $funcname zpool "$ZPOOL_LABELCLEAR_F" \
- /dev/${disk}s1
- # Pedantically nuke any old scheme
- f_eval_catch -d $funcname gpart "$GPART_DESTROY_F" ${disk}s1
-
- #
- # 3. Write BSD scheme to the freebsd slice
- #
- f_eval_catch $funcname gpart "$GPART_CREATE" BSD ${disk}s1 ||
- return $FAILURE
-
- # NB: ZFS pools will use s1a (no labels)
- bootpart=s1a swappart=s1b targetpart=s1d mbrindex=4
-
- #
- # Always prepare a boot pool on MBR
- # Do not align this partition, there must not be a gap
- #
- ZFSBOOT_BOOT_POOL=1
- f_eval_catch $funcname gpart \
- "$GPART_ADD_ALIGN_INDEX_WITH_SIZE" \
- "" 1 freebsd-zfs ${bootsize}b ${disk}s1 ||
- return $FAILURE
- # Pedantically nuke any old labels
- f_eval_catch -d $funcname zpool "$ZPOOL_LABELCLEAR_F" \
- /dev/$disk$bootpart
- if [ "$ZFSBOOT_GELI_ENCRYPTION" ]; then
- # Pedantically detach targetpart for later
- f_eval_catch -d $funcname geli \
- "$GELI_DETACH_F" \
- /dev/$disk$targetpart
- fi
-
- #
- # 4. Add freebsd-swap partition
- #
- if [ ${swapsize:-0} -gt 0 ]; then
- f_eval_catch $funcname gpart \
- "$GPART_ADD_ALIGN_INDEX_WITH_SIZE" \
- "$align_small" 2 freebsd-swap \
- ${swapsize}b ${disk}s1 || return $FAILURE
- # Pedantically nuke any old labels on the swap
- f_eval_catch -d $funcname zpool "$ZPOOL_LABELCLEAR_F" \
- /dev/${disk}s1b
- fi
-
- #
- # 5. Add freebsd-zfs partition for zroot
- #
- if [ "$ZFSBOOT_POOL_SIZE" ]; then
- f_eval_catch $funcname gpart "$GPART_ADD_ALIGN_INDEX_WITH_SIZE" \
- "$align_small" $mbrindex freebsd-zfs $ZFSBOOT_POOL_SIZE ${disk}s1 || return $FAILURE
- else
- f_eval_catch $funcname gpart "$GPART_ADD_ALIGN_INDEX" \
- "$align_small" $mbrindex freebsd-zfs ${disk}s1 || return $FAILURE
- fi
- f_eval_catch -d $funcname zpool "$ZPOOL_LABELCLEAR_F" \
- /dev/$disk$targetpart # Pedantic
- f_eval_catch $funcname dd "$DD_WITH_OPTIONS" \
- /boot/zfsboot /dev/${disk}s1 count=1 ||
- return $FAILURE
- ;;
-
esac # $ZFSBOOT_PARTITION_SCHEME
# Update fstab(5)
@@ -1102,7 +1015,7 @@ zfs_create_boot()
local zroot_vdevtype="$2"
local zroot_vdevs= # Calculated below
local swap_devs= # Calculated below
- local boot_vdevs= # Used for geli(8) and/or MBR layouts
+ local boot_vdevs= # Used for geli(8) layouts
shift 2 # poolname vdev_type
local disks="$*" disk
local isswapmirror
@@ -1191,7 +1104,6 @@ zfs_create_boot()
f_dprintf "$funcname: With 4K sectors..."
f_eval_catch $funcname sysctl "$SYSCTL_ZFS_MIN_ASHIFT_12" \
|| return $FAILURE
- sysctl kern.geom.part.mbr.enforce_chs=0
fi
local n=0
for disk in $disks; do
@@ -1415,40 +1327,6 @@ zfs_create_boot()
"bootfs=\"$zroot_name/$zroot_bootfs\"" "$zroot_name" ||
return $FAILURE
- # MBR boot loader touch-up
- if [ "$ZFSBOOT_PARTITION_SCHEME" = "MBR" ]; then
- # Export the pool(s)
- f_dprintf "$funcname: Temporarily exporting ZFS pool(s)..."
- f_eval_catch $funcname zpool "$ZPOOL_EXPORT" "$zroot_name" ||
- return $FAILURE
- if [ "$ZFSBOOT_BOOT_POOL" ]; then
- f_eval_catch $funcname zpool "$ZPOOL_EXPORT" \
- "$bootpool_name" || return $FAILURE
- fi
-
- f_dprintf "$funcname: Updating MBR boot loader on disks..."
- # Stick the ZFS boot loader in the "convenient hole" after
- # the ZFS internal metadata
- for disk in $disks; do
- f_eval_catch $funcname dd "$DD_WITH_OPTIONS" \
- /boot/zfsboot /dev/$disk$bootpart \
- "skip=1 seek=1024" || return $FAILURE
- done
-
- # Re-import the ZFS pool(s)
- f_dprintf "$funcname: Re-importing ZFS pool(s)..."
- f_eval_catch $funcname zpool "$ZPOOL_IMPORT_WITH_OPTIONS" \
- "-o altroot=\"$BSDINSTALL_CHROOT\"" \
- "$zroot_name" || return $FAILURE
- if [ "$ZFSBOOT_BOOT_POOL" ]; then
- # Import the bootpool, but do not mount it yet
- f_eval_catch $funcname zpool \
- "$ZPOOL_IMPORT_WITH_OPTIONS" \
- "-o altroot=\"$BSDINSTALL_CHROOT\" -N" \
- "$bootpool_name" || return $FAILURE
- fi
- fi
-
# Remount bootpool and create symlink(s)
if [ "$ZFSBOOT_BOOT_POOL" ]; then
f_eval_catch $funcname zfs "$ZFS_MOUNT" "$bootpool_name" ||
@@ -1793,7 +1671,7 @@ while :; do
fi
;;
?" $msg_partition_scheme")
- # Toggle between GPT (BIOS), GPT (UEFI) and MBR
+ # Toggle between partition schemes
if [ "$ZFSBOOT_PARTITION_SCHEME" = "GPT" -a \
"$ZFSBOOT_BOOT_TYPE" = "BIOS" ]
then
@@ -1805,9 +1683,6 @@ while :; do
ZFSBOOT_PARTITION_SCHEME="GPT"
ZFSBOOT_BOOT_TYPE="BIOS+UEFI"
elif [ "$ZFSBOOT_PARTITION_SCHEME" = "GPT" ]; then
- ZFSBOOT_PARTITION_SCHEME="MBR"
- ZFSBOOT_BOOT_TYPE="BIOS"
- elif [ "$ZFSBOOT_PARTITION_SCHEME" = "MBR" ]; then
ZFSBOOT_PARTITION_SCHEME="GPT + Active"
ZFSBOOT_BOOT_TYPE="BIOS"
elif [ "$ZFSBOOT_PARTITION_SCHEME" = "GPT + Active" ]; then
diff --git a/usr.sbin/bsnmpd/bsnmpd/Makefile b/usr.sbin/bsnmpd/bsnmpd/Makefile
index e7c7a87eec7c..601fc31ec475 100644
--- a/usr.sbin/bsnmpd/bsnmpd/Makefile
+++ b/usr.sbin/bsnmpd/bsnmpd/Makefile
@@ -9,7 +9,7 @@ CONTRIB=${SRCTOP}/contrib/bsnmp
CONFS= snmpd.config
CONFSMODE= 600
PROG= bsnmpd
-SRCS= main.c action.c config.c export.c trap.c trans_udp.c trans_lsock.c
+SRCS= main.c action.c config.c export.c trap.c trans_lsock.c
SRCS+= trans_inet.c oid.h tree.c tree.h
XSYM= snmpMIB begemotSnmpdModuleTable begemotSnmpd begemotTrapSinkTable \
sysUpTime snmpTrapOID coldStart authenticationFailure \
diff --git a/usr.sbin/bsnmpd/tools/libbsnmptools/bsnmptools.c b/usr.sbin/bsnmpd/tools/libbsnmptools/bsnmptools.c
index b4613763fff5..d8fbb55290a8 100644
--- a/usr.sbin/bsnmpd/tools/libbsnmptools/bsnmptools.c
+++ b/usr.sbin/bsnmpd/tools/libbsnmptools/bsnmptools.c
@@ -881,12 +881,11 @@ parse_local_path(char *opt_arg)
{
assert(opt_arg != NULL);
- if (sizeof(opt_arg) > sizeof(SNMP_LOCAL_PATH)) {
+ if (strlcpy(snmp_client.local_path, opt_arg,
+ sizeof(snmp_client.local_path)) >= sizeof(snmp_client.local_path)) {
warnx("Filename too long - %s", opt_arg);
return (-1);
}
-
- strlcpy(snmp_client.local_path, opt_arg, sizeof(SNMP_LOCAL_PATH));
return (2);
}
diff --git a/usr.sbin/chroot/chroot.8 b/usr.sbin/chroot/chroot.8
index f26b7e937da9..4a1a5a396631 100644
--- a/usr.sbin/chroot/chroot.8
+++ b/usr.sbin/chroot/chroot.8
@@ -25,7 +25,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.Dd July 20, 2021
+.Dd July 25, 2025
.Dt CHROOT 8
.Os
.Sh NAME
@@ -52,13 +52,15 @@ or an interactive copy of the user's login shell.
The options are as follows:
.Bl -tag -width "-G group[,group ...]"
.It Fl G Ar group Ns Op Cm \&, Ns Ar group ...
-Run the command with the permissions of the specified groups.
+Run the command with the specified groups as supplementary groups.
.It Fl g Ar group
-Run the command with the permissions of the specified
-.Ar group .
+Run the command with the specified
+.Ar group
+as the real, effective and saved groups.
.It Fl u Ar user
-Run the command as the
-.Ar user .
+Run the command with the specified
+.Ar user
+as the real, effective and saved users.
.It Fl n
Use the
.Dv PROC_NO_NEW_PRIVS_CTL
diff --git a/usr.sbin/chroot/chroot.c b/usr.sbin/chroot/chroot.c
index 32becaf12588..bd4932ee9b48 100644
--- a/usr.sbin/chroot/chroot.c
+++ b/usr.sbin/chroot/chroot.c
@@ -111,7 +111,12 @@ main(int argc, char *argv[])
ngroups_max = sysconf(_SC_NGROUPS_MAX) + 1;
if ((gidlist = malloc(sizeof(gid_t) * ngroups_max)) == NULL)
err(1, "malloc");
- for (gids = 0;
+ /* Populate the egid slot in our groups to avoid accidents. */
+ if (gid == 0)
+ gidlist[0] = getegid();
+ else
+ gidlist[0] = gid;
+ for (gids = 1;
(p = strsep(&grouplist, ",")) != NULL && gids < ngroups_max; ) {
if (*p == '\0')
continue;
diff --git a/usr.sbin/ctladm/tests/port.sh b/usr.sbin/ctladm/tests/port.sh
index 5bc5d879c983..d966529a85ae 100644
--- a/usr.sbin/ctladm/tests/port.sh
+++ b/usr.sbin/ctladm/tests/port.sh
@@ -38,12 +38,6 @@
# PGTAG,TARGET pair must be globally unique.
PGTAG=30257
-load_cfiscsi() {
- if ! kldstat -q -m cfiscsi; then
- kldload cfiscsi || atf_skip "could not load cfscsi kernel mod"
- fi
-}
-
skip_if_ctld() {
if service ctld onestatus > /dev/null; then
# If ctld is running on this server, let's not interfere.
@@ -118,11 +112,11 @@ create_iscsi_head()
atf_set "descr" "ctladm can create a new iscsi port"
atf_set "require.user" "root"
atf_set "require.progs" ctladm
+ atf_set "require.kmods" "cfiscsi"
}
create_iscsi_body()
{
skip_if_ctld
- load_cfiscsi
TARGET=iqn.2018-10.myhost.create_iscsi
atf_check -o save:port-create.txt ctladm port -c -d "iscsi" -O cfiscsi_portal_group_tag=$PGTAG -O cfiscsi_target="$TARGET"
@@ -146,11 +140,11 @@ create_iscsi_alias_head()
atf_set "descr" "ctladm can create a new iscsi port with a target alias"
atf_set "require.user" "root"
atf_set "require.progs" ctladm
+ atf_set "require.kmods" "cfiscsi"
}
create_iscsi_alias_body()
{
skip_if_ctld
- load_cfiscsi
TARGET=iqn.2018-10.myhost.create_iscsi_alias
ALIAS="foobar"
@@ -173,11 +167,11 @@ create_iscsi_without_required_args_head()
atf_set "descr" "ctladm will gracefully fail to create an iSCSI target if required arguments are missing"
atf_set "require.user" "root"
atf_set "require.progs" ctladm
+ atf_set "require.kmods" "cfiscsi"
}
create_iscsi_without_required_args_body()
{
skip_if_ctld
- load_cfiscsi
TARGET=iqn.2018-10.myhost.create_iscsi
atf_check -s exit:1 -e match:"Missing required argument: cfiscsi_target" ctladm port -c -d "iscsi" -O cfiscsi_portal_group_tag=$PGTAG
@@ -288,11 +282,11 @@ remove_iscsi_head()
atf_set "descr" "ctladm can remove an iscsi port"
atf_set "require.user" "root"
atf_set "require.progs" ctladm
+ atf_set "require.kmods" "cfiscsi"
}
remove_iscsi_body()
{
skip_if_ctld
- load_cfiscsi
TARGET=iqn.2018-10.myhost.remove_iscsi
atf_check -o save:port-create.txt ctladm port -c -d "iscsi" -O cfiscsi_portal_group_tag=$PGTAG -O cfiscsi_target="$TARGET"
@@ -314,11 +308,11 @@ remove_iscsi_without_required_args_head()
atf_set "descr" "ctladm will gracefully fail to remove an iSCSI target if required arguments are missing"
atf_set "require.user" "root"
atf_set "require.progs" ctladm
+ atf_set "require.kmods" "cfiscsi"
}
remove_iscsi_without_required_args_body()
{
skip_if_ctld
- load_cfiscsi
TARGET=iqn.2018-10.myhost.remove_iscsi_without_required_args
atf_check -o save:port-create.txt ctladm port -c -d "iscsi" -O cfiscsi_portal_group_tag=$PGTAG -O cfiscsi_target="$TARGET"
diff --git a/usr.sbin/devinfo/devinfo.c b/usr.sbin/devinfo/devinfo.c
index 629a04ba6687..4163151ec840 100644
--- a/usr.sbin/devinfo/devinfo.c
+++ b/usr.sbin/devinfo/devinfo.c
@@ -100,7 +100,7 @@ print_kvlist(char *s)
while ((kv = strsep(&copy, " ")) != NULL) {
char* k = strsep(&kv, "=");
- xo_emit("{ea:%s/%s} {d:%s}={d:%s}", k, kv, k, kv);
+ xo_emit("{ea:%s/%s} {d:key/%s}={d:value/%s}", k, kv, k, kv);
}
free(copy);
}
@@ -200,7 +200,7 @@ print_device_rman_resources(struct devinfo_rman *rman, void *arg)
/* there are, print header */
safe_desc = xml_safe_string(rman->dm_desc);
print_indent(indent);
- xo_emit("{d:%s}:\n", rman->dm_desc);
+ xo_emit("<{:description/%s}>\n", rman->dm_desc);
xo_open_list(safe_desc);
/* print resources */
@@ -220,8 +220,7 @@ print_device_props(struct devinfo_dev *dev)
{
if (vflag) {
if (*dev->dd_desc) {
- xo_emit(" <{d:%s}>", dev->dd_desc);
- xo_emit("{e:description/%s}", dev->dd_desc);
+ xo_emit("<{:description/%s}>", dev->dd_desc);
}
if (*dev->dd_pnpinfo) {
xo_open_container("pnpinfo");
@@ -273,7 +272,7 @@ print_device(struct devinfo_dev *dev, void *arg)
print_indent(indent);
xo_open_container(devname);
- xo_emit("{d:%s}", devname);
+ xo_emit("{d:devicename/%s}", devname);
print_device_props(dev);
xo_emit("\n");
@@ -367,7 +366,7 @@ print_rman(struct devinfo_rman *rman, void *arg __unused)
{
char* safe_desc = xml_safe_string(rman->dm_desc);
- xo_emit("{d:%s}:\n", rman->dm_desc);
+ xo_emit("<{:description/%s}\n>", rman->dm_desc);
xo_open_container(safe_desc);
devinfo_foreach_rman_resource(rman, print_rman_resource, 0);
@@ -385,7 +384,7 @@ print_device_path_entry(struct devinfo_dev *dev)
xo_open_container(devname);
open_tag_count++;
- xo_emit("{d:%s }", devname);
+ xo_emit("{:devicename/%s} ", devname);
print_device_props(dev);
if (vflag)
xo_emit("\n");
diff --git a/usr.sbin/efitable/efitable.8 b/usr.sbin/efitable/efitable.8
index bb8a9cc3d0e1..52949abcb853 100644
--- a/usr.sbin/efitable/efitable.8
+++ b/usr.sbin/efitable/efitable.8
@@ -1,4 +1,6 @@
.\"
+.\" SPDX-License-Identifier: BSD-2-Clause
+.\"
.\" Copyright (c) 2021 3mdeb Embedded Systems Consulting <contact@3mdeb.com>
.\"
.\" Redistribution and use in source and binary forms, with or without
@@ -27,7 +29,7 @@
.Os
.Sh NAME
.Nm efitable
-.Nd Dump UEFI tables
+.Nd dump UEFI tables
.Sh SYNOPSIS
.Nm
.Op Fl u Ar uuid | Fl t Ar name
@@ -39,7 +41,7 @@ This program prints data from
tables.
.Pp
The following options are available:
-.Bl -tag -width 20m
+.Bl -tag -width "-t name | --table name"
.It Fl -libxo
Generate output via
.Xr libxo 3
@@ -47,20 +49,21 @@ in a selection of different human and machine readable formats.
See
.Xr xo_options 7
for details on command line arguments.
-.It Fl t Ar name Fl -table Ar name
+.It Fl t Ar name | Fl -table Ar name
Specify the name of the table to print.
Currently supported tables:
.Pp
.Bl -tag -width indent -compact
.It Cm esrt
EFI System Resource Table
+.It Cm memory
+EFI Memory Attributes Table
.It Cm prop
EFI Properties Table
.El
-.It Fl u Ar uuid Fl -uuid Ar uuid
+.It Fl u Ar uuid | Fl -uuid Ar uuid
Specify the UUID of the table to print.
.El
-.Pp
.Sh HISTORY
The
.Nm
diff --git a/usr.sbin/efitable/efitable.c b/usr.sbin/efitable/efitable.c
index 0eee72801592..a506b4dea311 100644
--- a/usr.sbin/efitable/efitable.c
+++ b/usr.sbin/efitable/efitable.c
@@ -44,6 +44,7 @@
static void efi_table_print_esrt(const void *data);
static void efi_table_print_prop(const void *data);
+static void efi_table_print_memory(const void *data);
static void usage(void) __dead2;
struct efi_table_op {
@@ -56,7 +57,9 @@ static const struct efi_table_op efi_table_ops[] = {
{ .name = "esrt", .parse = efi_table_print_esrt,
.guid = EFI_TABLE_ESRT },
{ .name = "prop", .parse = efi_table_print_prop,
- .guid = EFI_PROPERTIES_TABLE }
+ .guid = EFI_PROPERTIES_TABLE },
+ { .name = "memory", .parse = efi_table_print_memory,
+ .guid = EFI_MEMORY_ATTRIBUTES_TABLE }
};
int
@@ -239,6 +242,51 @@ efi_table_print_prop(const void *data)
xo_err(EX_IOERR, "stdout");
}
+static void
+efi_table_print_memory(const void *data)
+{
+ const struct efi_memory_attribute_table *attr =
+ (const struct efi_memory_attribute_table *)data;
+ const struct efi_memory_descriptor *desc;
+ int i, nentries;
+
+ nentries = attr->num_ents;
+ desc = attr->tables;
+
+ xo_set_version(EFITABLE_XO_VERSION);
+
+ xo_open_container("memory");
+ xo_emit("{Lwc:Version}{:version/%#x}\n", attr->version);
+ xo_emit("{Lwc:Length}{:length/%u}\n", attr->descriptor_size);
+ xo_emit("{Lwc:Entries}{:entries/%u}\n", attr->num_ents);
+
+ xo_open_container("attributes");
+
+ /*
+ * According to https://forum.osdev.org/viewtopic.php?t=32953, the size
+ * of records into the attribute table never equals to
+ * sizeof(efi_memory_descriptor). The correct one for indexing the array
+ * resides in the attributet table.
+ */
+ for (i = 0; i < nentries; i++) {
+ xo_emit("{Lwc:ID}{:id/%#x}\n", i);
+ xo_emit("{Lwc:Attributes}{:attributes/%#x}\n", desc->attrs);
+ xo_emit("{Lwc:Type}{:type/%#x}\n", desc->type);
+ xo_emit("{Lwc:Pages}{:pages/%#x}\n", desc->pages);
+ xo_emit("{Lwc:Phyaddr}{:phyaddr/%#p}\n", desc->phy_addr);
+ xo_emit("{Lwc:Virtaddr}{:virtaddr/%#p}\n", desc->virt_addr);
+ desc = (const struct efi_memory_descriptor *)(const void *)
+ ((const char *)desc + attr->descriptor_size);
+ }
+
+ xo_close_container("attributes");
+
+ xo_close_container("memory");
+
+ if (xo_finish() < 0)
+ xo_err(EX_IOERR, "stdout");
+}
+
static void usage(void)
{
xo_error("usage: efitable [-g guid | -t name] [--libxo]\n");
diff --git a/usr.sbin/getfmac/getfmac.8 b/usr.sbin/getfmac/getfmac.8
index eb930e0044f9..6176bfa09271 100644
--- a/usr.sbin/getfmac/getfmac.8
+++ b/usr.sbin/getfmac/getfmac.8
@@ -51,5 +51,8 @@ specified files.
.Xr mac 3 ,
.Xr mac_get_file 3 ,
.Xr mac 4 ,
+.Xr maclabel 7 ,
+.Xr getpmac 8 ,
.Xr setfmac 8 ,
+.Xr setpmac 8 ,
.Xr mac 9
diff --git a/usr.sbin/gssd/Makefile b/usr.sbin/gssd/Makefile
index 7ad1cae7eb55..569e2c7e18f5 100644
--- a/usr.sbin/gssd/Makefile
+++ b/usr.sbin/gssd/Makefile
@@ -1,6 +1,6 @@
.include <src.opts.mk>
-PACKAGE= kerberos
+PACKAGE= gssd
PROG= gssd
MAN= gssd.8
diff --git a/usr.sbin/jail/command.c b/usr.sbin/jail/command.c
index 8ea3f3ee8795..9da4fe51673a 100644
--- a/usr.sbin/jail/command.c
+++ b/usr.sbin/jail/command.c
@@ -290,7 +290,7 @@ run_command(struct cfjail *j)
const struct cfstring *comstring, *s;
login_cap_t *lcap;
const char **argv;
- char *acs, *ajidstr, *cs, *comcs, *devpath;
+ char *acs, *cs, *comcs, *devpath;
const char *jidstr, *conslog, *fmt, *path, *ruleset, *term, *username;
enum intparam comparam;
size_t comlen, ret;
@@ -332,6 +332,25 @@ run_command(struct cfjail *j)
printf("%d\n", j->jid);
if (verbose >= 0 && (j->name || verbose > 0))
jail_note(j, "created\n");
+
+ /*
+ * Populate our jid and name parameters if they were not
+ * provided. This simplifies later logic that wants to
+ * use the jid or name to be able to do so reliably.
+ */
+ if (j->intparams[KP_JID] == NULL) {
+ char ljidstr[16];
+
+ (void)snprintf(ljidstr, sizeof(ljidstr), "%d",
+ j->jid);
+ add_param(j, NULL, KP_JID, ljidstr);
+ }
+
+ /* This matches the kernel behavior. */
+ if (j->intparams[KP_NAME] == NULL)
+ add_param(j, j->intparams[KP_JID], KP_NAME,
+ NULL);
+
dep_done(j, DF_LIGHT);
}
return 0;
@@ -456,8 +475,7 @@ run_command(struct cfjail *j)
argv[0] = _PATH_IFCONFIG;
argv[1] = comstring->s;
argv[2] = down ? "-vnet" : "vnet";
- jidstr = string_param(j->intparams[KP_JID]);
- argv[3] = jidstr ? jidstr : string_param(j->intparams[KP_NAME]);
+ argv[3] = string_param(j->intparams[KP_JID]);
argv[4] = NULL;
break;
@@ -592,9 +610,7 @@ run_command(struct cfjail *j)
case IP_ZFS_DATASET:
argv = alloca(4 * sizeof(char *));
- jidstr = string_param(j->intparams[KP_JID]) ?
- string_param(j->intparams[KP_JID]) :
- string_param(j->intparams[KP_NAME]);
+ jidstr = string_param(j->intparams[KP_JID]);
fmt = "if [ $(/sbin/zfs get -H -o value jailed %s) = on ]; then /sbin/zfs jail %s %s || echo error, attaching %s to jail %s failed; else echo error, you need to set jailed=on for dataset %s; fi";
comlen = strlen(fmt)
+ 2 * strlen(jidstr)
@@ -796,14 +812,10 @@ run_command(struct cfjail *j)
endpwent();
}
if (!injail) {
- if (asprintf(&ajidstr, "%d", j->jid) == -1) {
- jail_warnx(j, "asprintf jid=%d: %s", j->jid,
- strerror(errno));
- exit(1);
- }
- setenv("JID", ajidstr, 1);
- free(ajidstr);
+ if (string_param(j->intparams[KP_JID]))
+ setenv("JID", string_param(j->intparams[KP_JID]), 1);
setenv("JNAME", string_param(j->intparams[KP_NAME]), 1);
+
path = string_param(j->intparams[KP_PATH]);
setenv("JPATH", path ? path : "", 1);
}
diff --git a/usr.sbin/jail/config.c b/usr.sbin/jail/config.c
index 3af0088626c9..70de82e662e7 100644
--- a/usr.sbin/jail/config.c
+++ b/usr.sbin/jail/config.c
@@ -156,11 +156,14 @@ load_config(const char *cfname)
TAILQ_CONCAT(&opp, &j->params, tq);
/*
* The jail name implies its "name" or "jid" parameter,
- * though they may also be explicitly set later on.
+ * though they may also be explicitly set later on. After we
+ * collect other parameters, we'll go back and ensure they're
+ * both set if we need to do so here.
*/
add_param(j, NULL,
strtol(j->name, &ep, 10) && !*ep ? KP_JID : KP_NAME,
j->name);
+
/*
* Collect parameters for the jail, global parameters/variables,
* and any matching wildcard jails.
@@ -180,6 +183,14 @@ load_config(const char *cfname)
TAILQ_FOREACH(p, &opp, tq)
add_param(j, p, 0, NULL);
+ /*
+ * We only backfill if it's the name that wasn't set; if it was
+ * the jid, we can assume that will be populated later when the
+ * jail is created or found.
+ */
+ if (j->intparams[KP_NAME] == NULL)
+ add_param(j, j->intparams[KP_JID], KP_NAME, NULL);
+
/* Resolve any variable substitutions. */
pgen = 0;
TAILQ_FOREACH(p, &j->params, tq) {
diff --git a/usr.sbin/jail/jail.c b/usr.sbin/jail/jail.c
index 27769cc14958..46cabf76ae11 100644
--- a/usr.sbin/jail/jail.c
+++ b/usr.sbin/jail/jail.c
@@ -890,7 +890,14 @@ running_jid(struct cfjail *j)
j->jid = -1;
return;
}
+
j->jid = jail_get(jiov, 2, 0);
+ if (j->jid > 0 && j->intparams[KP_JID] == NULL) {
+ char jidstr[16];
+
+ (void)snprintf(jidstr, sizeof(jidstr), "%d", j->jid);
+ add_param(j, NULL, KP_JID, jidstr);
+ }
}
static void
diff --git a/usr.sbin/jail/tests/commands.jail.conf b/usr.sbin/jail/tests/commands.jail.conf
index afd56d1fa5d6..ad152a28b7fe 100644
--- a/usr.sbin/jail/tests/commands.jail.conf
+++ b/usr.sbin/jail/tests/commands.jail.conf
@@ -4,6 +4,4 @@ exec.prestart = "echo START";
exec.poststart = "env";
persist;
-path = "/tmp/test_${name}_root";
-
basejail {}
diff --git a/usr.sbin/jail/tests/jail_basic_test.sh b/usr.sbin/jail/tests/jail_basic_test.sh
index 6498eb1c1fdc..509900e8569c 100755
--- a/usr.sbin/jail/tests/jail_basic_test.sh
+++ b/usr.sbin/jail/tests/jail_basic_test.sh
@@ -129,36 +129,168 @@ commands_head()
{
atf_set descr 'Commands jail test'
atf_set require.user root
- mkdir /tmp/test_basejail_root
}
commands_body()
{
+ cp "$(atf_get_srcdir)/commands.jail.conf" jail.conf
+ echo "path = \"$PWD\";" >> jail.conf
+
# exec.prestart (START) and exec.poststart (env)
- atf_check -s exit:0 -o save:stdout -e empty \
- jail -f $(atf_get_srcdir)/commands.jail.conf -qc basejail
- grep -E '^START$' stdout || atf_fail "exec.prestart output not found"
- grep -E '^JID=[0-9]+' stdout || atf_fail "JID not found in exec.poststart env output"
- grep -E '^JNAME=basejail$' stdout || atf_fail "JNAME not found in exec.poststart env output"
- grep -E '^JPATH=/tmp/test_basejail_root$' stdout || atf_fail "JPATH not found in exec.poststart env output"
+ atf_check -o save:stdout -e empty \
+ jail -f jail.conf -qc basejail
+
+ # exec.prestart output is missing
+ atf_check grep -qE '^START$' stdout
+ # JID was not set in the exec.poststart env
+ atf_check grep -qE '^JID=[0-9]+' stdout
+ # JNAME was not set in the exec.poststart env
+ atf_check grep -qE '^JNAME=basejail$' stdout
+ # JPATH was not set in the exec.poststart env
+ atf_check grep -qE "^JPATH=$PWD$" stdout
# exec.prestop by jailname
atf_check -s exit:0 -o inline:"STOP\n" \
- jail -f $(atf_get_srcdir)/commands.jail.conf -qr basejail
+ jail -f jail.conf -qr basejail
# exec.prestop by jid
- jail -f $(atf_get_srcdir)/commands.jail.conf -qc basejail
+ jail -f jail.conf -qc basejail
atf_check -s exit:0 -o inline:"STOP\n" \
- jail -f $(atf_get_srcdir)/commands.jail.conf -qr `jls -j basejail jid`
+ jail -f jail.conf -qr `jls -j basejail jid`
}
-commands_cleanup()
+commands_cleanup()
{
- jls -j basejail > /dev/null 2>&1
- if [ $? -e 0 ]
- then
+ if jls -j basejail > /dev/null 2>&1; then
jail -r basejail
fi
- rmdir /tmp/test_basejail_root
+}
+
+atf_test_case "jid_name_set" "cleanup"
+jid_name_set_head()
+{
+ atf_set descr 'Test that one can set both the jid and name in a config file'
+ atf_set require.user root
+}
+
+find_unused_jid()
+{
+ : ${JAIL_MAX=999999}
+
+ # We'll start at a higher jid number and roll through the space until
+ # we find one that isn't taken. We start high to avoid racing parallel
+ # activity for the 'next available', though ideally we don't have a lot
+ # of parallel jail activity like that.
+ jid=5309
+ while jls -cj "$jid"; do
+ if [ "$jid" -eq "$JAIL_MAX" ]; then
+ atf_skip "System has too many jail, cannot find free slot"
+ fi
+
+ jid=$((jid + 1))
+ done
+
+ echo "$jid" | tee -a jails.lst
+}
+clean_jails()
+{
+ if [ ! -s jails.lst ]; then
+ return 0
+ fi
+
+ while read jail; do
+ if jls -e -j "$jail"; then
+ jail -r "$jail"
+ fi
+ done < jails.lst
+}
+
+jid_name_set_body()
+{
+ local jid=$(find_unused_jid)
+
+ echo "basejail" >> jails.lst
+ echo "$jid { name = basejail; persist; }" > jail.conf
+ atf_check -o match:"$jid: created" jail -f jail.conf -c "$jid"
+ atf_check -o match:"$jid: removed" jail -f jail.conf -r "$jid"
+
+ echo "basejail { jid = $jid; persist; }" > jail.conf
+ atf_check -o match:"basejail: created" jail -f jail.conf -c basejail
+ atf_check -o match:"basejail: removed" jail -f jail.conf -r basejail
+}
+
+jid_name_set_cleanup()
+{
+ clean_jails
+}
+
+atf_test_case "param_consistency" "cleanup"
+param_consistency_head()
+{
+ atf_set descr 'Test for consistency in jid/name params being set implicitly'
+ atf_set require.user root
+}
+
+param_consistency_body()
+{
+ local iface jid
+
+ echo "basejail" >> jails.lst
+
+ # Most basic test: exec.poststart running a command without a jail
+ # config. This would previously crash as we only had the jid and name
+ # as populated at creation time.
+ atf_check jail -c path=/ exec.poststart="true" command=/usr/bin/true
+
+ iface=$(ifconfig lo create)
+ atf_check test -n "$iface"
+ echo "$iface" >> interfaces.lst
+
+ # Now do it again but exercising IP_VNET_INTERFACE, which is an
+ # implied command that wants to use the jid or name. This would crash
+ # as neither KP_JID or KP_NAME are populated when a jail is created,
+ # just as above- just at a different spot.
+ atf_check jail -c \
+ path=/ vnet=new vnet.interface="$iface" command=/usr/bin/true
+
+ # Test that a jail that we only know by name will have its jid resolved
+ # and added to its param set.
+ echo "basejail {path = /; exec.prestop = 'echo STOP'; persist; }" > jail.conf
+
+ atf_check -o ignore jail -f jail.conf -c basejail
+ atf_check -o match:"STOP" jail -f jail.conf -r basejail
+
+ # Do the same sequence as above, but use a jail with a jid-ish name.
+ jid=$(find_unused_jid)
+ echo "$jid {path = /; exec.prestop = 'echo STOP'; persist; }" > jail.conf
+
+ atf_check -o ignore jail -f jail.conf -c "$jid"
+ atf_check -o match:"STOP" jail -f jail.conf -r "$jid"
+
+ # Ditto, but now we set a name for that jid-jail.
+ echo "$jid {name = basejail; path = /; exec.prestop = 'echo STOP'; persist; }" > jail.conf
+
+ atf_check -o ignore jail -f jail.conf -c "$jid"
+ atf_check -o match:"STOP" jail -f jail.conf -r "$jid"
+
+ # Confirm that we have a valid jid available in exec.poststop. It's
+ # probably debatable whether we should or not.
+ echo "basejail {path = /; exec.poststop = 'echo JID=\$JID'; persist; }" > jail.conf
+ atf_check -o ignore jail -f jail.conf -c basejail
+ jid=$(jls -j basejail jid)
+
+ atf_check -o match:"JID=$jid" jail -f jail.conf -r basejail
+
+}
+
+param_consistency_cleanup()
+{
+ clean_jails
+
+ if [ -f "interfaces.lst" ]; then
+ while read iface; do
+ ifconfig "$iface" destroy
+ done < interfaces.lst
+ fi
}
atf_init_test_cases()
@@ -167,4 +299,6 @@ atf_init_test_cases()
atf_add_test_case "list"
atf_add_test_case "nested"
atf_add_test_case "commands"
+ atf_add_test_case "jid_name_set"
+ atf_add_test_case "param_consistency"
}
diff --git a/usr.sbin/jls/jls.8 b/usr.sbin/jls/jls.8
index f7a5eeb321ef..715033082963 100644
--- a/usr.sbin/jls/jls.8
+++ b/usr.sbin/jls/jls.8
@@ -23,7 +23,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.Dd February 13, 2025
+.Dd July 25, 2025
.Dt JLS 8
.Os
.Sh NAME
@@ -35,6 +35,10 @@
.Op Fl dhNnqsv
.Op Fl j Ar jail
.Op Ar parameter ...
+.Nm
+.Fl c
+.Op Fl d
+.Fl j Ar jail
.Sh DESCRIPTION
The
.Nm
@@ -54,11 +58,21 @@ for a description of some core parameters.
If no
.Ar parameters
or any of the options
-.Fl hns
+.Fl chns
are given, the following four columns will be printed:
jail identifier (jid), IP address (ip4.addr), hostname (host.hostname),
and path (path).
.Pp
+When the
+.Fl c
+option is used,
+.Nm
+will not emit any output except for usage errors.
+This mode is intended solely to check for a single jail's existence, and it does
+not accept any
+.Ar parameter
+or print-option flags.
+.Pp
The following options are available:
.Bl -tag -width indent
.It Fl -libxo
@@ -68,6 +82,8 @@ in a selection of different human and machine readable formats.
See
.Xr xo_options 7
for details on command line arguments.
+.It Fl c
+Only check for the jail's existence.
.It Fl d
List
.Va dying
diff --git a/usr.sbin/jls/jls.c b/usr.sbin/jls/jls.c
index bd193a69c458..4f697a5bb382 100644
--- a/usr.sbin/jls/jls.c
+++ b/usr.sbin/jls/jls.c
@@ -37,6 +37,7 @@
#include <arpa/inet.h>
#include <netinet/in.h>
+#include <assert.h>
#include <ctype.h>
#include <errno.h>
#include <jail.h>
@@ -59,6 +60,7 @@
#define PRINT_SKIP 0x10
#define PRINT_VERBOSE 0x20
#define PRINT_JAIL_NAME 0x40
+#define PRINT_EXISTS 0x80
static struct jailparam *params;
static int *param_parent;
@@ -81,6 +83,14 @@ static void quoted_print(int pflags, char *name, char *value);
static void emit_ip_addr_list(int af_family, const char *list_name,
struct jailparam *param);
+static void
+usage(void)
+{
+ xo_errx(1,
+ "usage: jls [-dhNnqv] [-j jail] [param ...]\n"
+ " jls -c [-d] -j jail");
+}
+
int
main(int argc, char **argv)
{
@@ -94,12 +104,15 @@ main(int argc, char **argv)
xo_set_version(JLS_XO_VERSION);
jname = NULL;
pflags = jflags = jid = 0;
- while ((c = getopt(argc, argv, "adj:hNnqsv")) >= 0)
+ while ((c = getopt(argc, argv, "acdj:hNnqsv")) >= 0)
switch (c) {
case 'a':
case 'd':
jflags |= JAIL_DYING;
break;
+ case 'c':
+ pflags |= PRINT_EXISTS;
+ break;
case 'j':
jid = strtoul(optarg, &ep, 10);
if (!jid || *ep) {
@@ -130,7 +143,7 @@ main(int argc, char **argv)
PRINT_VERBOSE;
break;
default:
- xo_errx(1, "usage: jls [-dhNnqv] [-j jail] [param ...]");
+ usage();
}
#ifdef INET6
@@ -140,8 +153,28 @@ main(int argc, char **argv)
ip4_ok = feature_present("inet");
#endif
+ argc -= optind;
+ argv += optind;
+
/* Add the parameters to print. */
- if (optind == argc) {
+ if ((pflags & PRINT_EXISTS) != 0) {
+ if ((pflags & ~PRINT_EXISTS) != 0) {
+ xo_warnx("-c is incompatible with other print options");
+ usage();
+ } else if (argc != 0) {
+ xo_warnx("-c does not accept non-option arguments");
+ usage();
+ } else if (jid == 0 && jname == NULL) {
+ xo_warnx("-j jail to check must be provided for -c");
+ usage();
+ }
+
+ /*
+ * Force libxo to be silent, as well -- we're only wanting our
+ * exit status.
+ */
+ xo_set_style(NULL, XO_STYLE_TEXT);
+ } else if (argc == 0) {
if (pflags & (PRINT_HEADER | PRINT_NAMEVAL))
add_param("all", NULL, (size_t)0, NULL, JP_USER);
else if (pflags & PRINT_VERBOSE) {
@@ -179,9 +212,8 @@ main(int argc, char **argv)
}
} else {
pflags &= ~PRINT_VERBOSE;
- while (optind < argc)
- add_param(argv[optind++], NULL, (size_t)0, NULL,
- JP_USER);
+ for (i = 0; i < argc; i++)
+ add_param(argv[i], NULL, (size_t)0, NULL, JP_USER);
}
if (pflags & PRINT_SKIP) {
@@ -237,9 +269,17 @@ main(int argc, char **argv)
xo_open_list("jail");
/* Fetch the jail(s) and print the parameters. */
if (jid != 0 || jname != NULL) {
- if (print_jail(pflags, jflags) < 0)
+ if (print_jail(pflags, jflags) < 0) {
+ /*
+ * We omit errors from existential issues if we're just
+ * doing a -c check that the jail exists.
+ */
+ if (pflags & PRINT_EXISTS)
+ exit(1);
xo_errx(1, "%s", jail_errmsg);
+ }
} else {
+ assert((pflags & PRINT_EXISTS) == 0);
for (lastjid = 0;
(lastjid = print_jail(pflags, jflags)) >= 0; )
;
@@ -390,6 +430,8 @@ print_jail(int pflags, int jflags)
jid = jailparam_get(params, nparams, jflags);
if (jid < 0)
return jid;
+ else if (pflags & PRINT_EXISTS)
+ return 0;
xo_open_instance("jail");
diff --git a/usr.sbin/makefs/makefs.8 b/usr.sbin/makefs/makefs.8
index a11eaf8206e9..d20f69d87559 100644
--- a/usr.sbin/makefs/makefs.8
+++ b/usr.sbin/makefs/makefs.8
@@ -33,8 +33,7 @@
.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
.\" POSSIBILITY OF SUCH DAMAGE.
.\"
-.Dd January 19, 2024
-
+.Dd July 19, 2025
.Dt MAKEFS 8
.Os
.Sh NAME
@@ -551,6 +550,12 @@ This option allows the default heuristic to be overridden.
.It verify-txgs
Prompt OpenZFS to verify pool metadata during import.
This is disabled by default as it may significantly increase import times.
+.It poolguid
+Use the specified 64-bit integer as the pool GUID.
+If this option is not specified, the pool GUID will be random but fixed
+across multiple identical invocations of
+.Nm .
+This option is useful for testing but not required for reproducibility.
.It poolname
The name of the ZFS pool.
This option must be specified.
@@ -596,10 +601,17 @@ The following properties may be set for a dataset:
.Bl -tag -compact -offset indent
.It atime
.It canmount
+.It compression
.It exec
.It mountpoint
.It setuid
.El
+Note that
+.Nm
+does not implement compression of files included in the image,
+regardless of the value of the
+.Dv compression
+property.
.El
.Sh SEE ALSO
.Xr mtree 5 ,
diff --git a/usr.sbin/makefs/tests/Makefile b/usr.sbin/makefs/tests/Makefile
index 345b728651d6..748bafa06211 100644
--- a/usr.sbin/makefs/tests/Makefile
+++ b/usr.sbin/makefs/tests/Makefile
@@ -7,10 +7,6 @@ ATF_TESTS_SH+= makefs_msdos_tests
TEST_METADATA.makefs_msdos_tests+= required_files="/sbin/mount_msdosfs"
.if ${MK_ZFS} != "no"
ATF_TESTS_SH+= makefs_zfs_tests
-# ZFS pools created by makefs always have the same GUID, so OpenZFS
-# refuses to import more than one at a time. Thus the ZFS tests cannot
-# be run in parallel for now.
-TEST_METADATA.makefs_zfs_tests+= is_exclusive="true"
.endif
BINDIR= ${TESTSDIR}
diff --git a/usr.sbin/makefs/tests/makefs_zfs_tests.sh b/usr.sbin/makefs/tests/makefs_zfs_tests.sh
index 520d1f211ac3..2fafce85b347 100644
--- a/usr.sbin/makefs/tests/makefs_zfs_tests.sh
+++ b/usr.sbin/makefs/tests/makefs_zfs_tests.sh
@@ -28,7 +28,7 @@
# SUCH DAMAGE.
#
-MAKEFS="makefs -t zfs -o verify-txgs=true"
+MAKEFS="makefs -t zfs -o verify-txgs=true -o poolguid=$$"
ZFS_POOL_NAME="makefstest$$"
TEST_ZFS_POOL_NAME="$TMPDIR/poolname"
@@ -124,6 +124,95 @@ basic_cleanup()
common_cleanup
}
+#
+# Try configuring various compression algorithms.
+#
+atf_test_case compression cleanup
+compression_body()
+{
+ create_test_inputs
+
+ cd $TEST_INPUTS_DIR
+ mkdir dir
+ mkdir dir2
+ cd -
+
+ for alg in off on lzjb gzip gzip-1 gzip-2 gzip-3 gzip-4 \
+ gzip-5 gzip-6 gzip-7 gzip-8 gzip-9 zle lz4 zstd; do
+ atf_check $MAKEFS -s 1g -o rootpath=/ \
+ -o poolname=$ZFS_POOL_NAME \
+ -o fs=${ZFS_POOL_NAME}\;compression=$alg \
+ -o fs=${ZFS_POOL_NAME}/dir \
+ -o fs=${ZFS_POOL_NAME}/dir2\;compression=off \
+ $TEST_IMAGE $TEST_INPUTS_DIR
+
+ import_image
+
+ check_image_contents
+
+ if [ $alg = gzip-6 ]; then
+ # ZFS reports gzip-6 as just gzip since it uses
+ # a default compression level of 6.
+ alg=gzip
+ fi
+ # The "dir" dataset's compression algorithm should be
+ # inherited from the root dataset.
+ atf_check -o inline:$alg\\n -e empty -s exit:0 \
+ zfs get -H -o value compression ${ZFS_POOL_NAME}
+ atf_check -o inline:$alg\\n -e empty -s exit:0 \
+ zfs get -H -o value compression ${ZFS_POOL_NAME}/dir
+ atf_check -o inline:off\\n -e empty -s exit:0 \
+ zfs get -H -o value compression ${ZFS_POOL_NAME}/dir2
+
+ atf_check -e ignore dd if=/dev/random \
+ of=${TEST_MOUNT_DIR}/dir/random bs=1M count=10
+ atf_check -e ignore dd if=/dev/zero \
+ of=${TEST_MOUNT_DIR}/dir/zero bs=1M count=10
+ atf_check -e ignore dd if=/dev/zero \
+ of=${TEST_MOUNT_DIR}/dir2/zero bs=1M count=10
+
+ # Export and reimport to ensure that everything is
+ # flushed to disk.
+ atf_check zpool export ${ZFS_POOL_NAME}
+ atf_check -o ignore -e empty -s exit:0 \
+ zdb -e -p /dev/$(cat $TEST_MD_DEVICE_FILE) -mmm -ddddd \
+ $ZFS_POOL_NAME
+ atf_check zpool import -R $TEST_MOUNT_DIR $ZFS_POOL_NAME
+
+ if [ $alg = off ]; then
+ # If compression is off, the files should be the
+ # same size as the input.
+ atf_check -o match:"^11[[:space:]]+${TEST_MOUNT_DIR}/dir/random" \
+ du -m ${TEST_MOUNT_DIR}/dir/random
+ atf_check -o match:"^11[[:space:]]+${TEST_MOUNT_DIR}/dir/zero" \
+ du -m ${TEST_MOUNT_DIR}/dir/zero
+ atf_check -o match:"^11[[:space:]]+${TEST_MOUNT_DIR}/dir2/zero" \
+ du -m ${TEST_MOUNT_DIR}/dir2/zero
+ else
+ # If compression is on, the dir/zero file ought
+ # to be smaller.
+ atf_check -o match:"^1[[:space:]]+${TEST_MOUNT_DIR}/dir/zero" \
+ du -m ${TEST_MOUNT_DIR}/dir/zero
+ atf_check -o match:"^11[[:space:]]+${TEST_MOUNT_DIR}/dir/random" \
+ du -m ${TEST_MOUNT_DIR}/dir/random
+ atf_check -o match:"^11[[:space:]]+${TEST_MOUNT_DIR}/dir2/zero" \
+ du -m ${TEST_MOUNT_DIR}/dir2/zero
+ fi
+
+ atf_check zpool destroy ${ZFS_POOL_NAME}
+ atf_check rm -f ${TEST_ZFS_POOL_NAME}
+ atf_check mdconfig -d -u $(cat ${TEST_MD_DEVICE_FILE})
+ atf_check rm -f ${TEST_MD_DEVICE_FILE}
+ done
+}
+compression_cleanup()
+{
+ common_cleanup
+}
+
+#
+# Try destroying a dataset that was created by makefs.
+#
atf_test_case dataset_removal cleanup
dataset_removal_body()
{
@@ -939,6 +1028,7 @@ atf_init_test_cases()
{
atf_add_test_case autoexpand
atf_add_test_case basic
+ atf_add_test_case compression
atf_add_test_case dataset_removal
atf_add_test_case devfs
atf_add_test_case empty_dir
diff --git a/usr.sbin/makefs/zfs.c b/usr.sbin/makefs/zfs.c
index 66e7f8dafc9c..8d50c450541b 100644
--- a/usr.sbin/makefs/zfs.c
+++ b/usr.sbin/makefs/zfs.c
@@ -38,6 +38,7 @@
#include <stdalign.h>
#include <stdbool.h>
#include <stddef.h>
+#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
@@ -85,6 +86,8 @@ zfs_prep_opts(fsinfo_t *fsopts)
0, 0, "Bootable dataset" },
{ '\0', "mssize", &zfs->mssize, OPT_INT64,
MINMSSIZE, MAXMSSIZE, "Metaslab size" },
+ { '\0', "poolguid", &zfs->poolguid, OPT_INT64,
+ 0, INT64_MAX, "ZFS pool GUID" },
{ '\0', "poolname", &zfs->poolname, OPT_STRPTR,
0, 0, "ZFS pool name" },
{ '\0', "rootpath", &zfs->rootpath, OPT_STRPTR,
@@ -547,7 +550,8 @@ pool_init(zfs_opt_t *zfs)
{
uint64_t dnid;
- zfs->poolguid = randomguid();
+ if (zfs->poolguid == 0)
+ zfs->poolguid = randomguid();
zfs->vdevguid = randomguid();
zfs->mos = objset_alloc(zfs, DMU_OST_META);
diff --git a/usr.sbin/makefs/zfs/dsl.c b/usr.sbin/makefs/zfs/dsl.c
index f7264b9d2ca7..1977521d7f92 100644
--- a/usr.sbin/makefs/zfs/dsl.c
+++ b/usr.sbin/makefs/zfs/dsl.c
@@ -119,7 +119,7 @@ dsl_dir_get_mountpoint(zfs_opt_t *zfs, zfs_dsl_dir_t *dir)
if (nvlist_find_string(pdir->propsnv, "mountpoint",
&tmp) == 0) {
- easprintf(&mountpoint, "%s%s%s", tmp,
+ (void)easprintf(&mountpoint, "%s%s%s", tmp,
tmp[strlen(tmp) - 1] == '/' ? "" : "/",
origmountpoint);
free(tmp);
@@ -127,7 +127,7 @@ dsl_dir_get_mountpoint(zfs_opt_t *zfs, zfs_dsl_dir_t *dir)
break;
}
- easprintf(&mountpoint, "%s/%s", pdir->name,
+ (void)easprintf(&mountpoint, "%s/%s", pdir->name,
origmountpoint);
free(origmountpoint);
}
@@ -175,24 +175,57 @@ dsl_dir_set_prop(zfs_opt_t *zfs, zfs_dsl_dir_t *dir, const char *key,
"the root path `%s'", val, zfs->rootpath);
}
}
- nvlist_add_string(nvl, key, val);
+ (void)nvlist_add_string(nvl, key, val);
} else if (strcmp(key, "atime") == 0 || strcmp(key, "exec") == 0 ||
strcmp(key, "setuid") == 0) {
if (strcmp(val, "on") == 0)
- nvlist_add_uint64(nvl, key, 1);
+ (void)nvlist_add_uint64(nvl, key, 1);
else if (strcmp(val, "off") == 0)
- nvlist_add_uint64(nvl, key, 0);
+ (void)nvlist_add_uint64(nvl, key, 0);
else
errx(1, "invalid value `%s' for %s", val, key);
} else if (strcmp(key, "canmount") == 0) {
if (strcmp(val, "noauto") == 0)
- nvlist_add_uint64(nvl, key, 2);
+ (void)nvlist_add_uint64(nvl, key, 2);
else if (strcmp(val, "on") == 0)
- nvlist_add_uint64(nvl, key, 1);
+ (void)nvlist_add_uint64(nvl, key, 1);
else if (strcmp(val, "off") == 0)
- nvlist_add_uint64(nvl, key, 0);
+ (void)nvlist_add_uint64(nvl, key, 0);
else
errx(1, "invalid value `%s' for %s", val, key);
+ } else if (strcmp(key, "compression") == 0) {
+ size_t i;
+
+ const struct zfs_compression_algorithm {
+ const char *name;
+ enum zio_compress alg;
+ } compression_algorithms[] = {
+ { "off", ZIO_COMPRESS_OFF },
+ { "on", ZIO_COMPRESS_ON },
+ { "lzjb", ZIO_COMPRESS_LZJB },
+ { "gzip", ZIO_COMPRESS_GZIP_6 },
+ { "gzip-1", ZIO_COMPRESS_GZIP_1 },
+ { "gzip-2", ZIO_COMPRESS_GZIP_2 },
+ { "gzip-3", ZIO_COMPRESS_GZIP_3 },
+ { "gzip-4", ZIO_COMPRESS_GZIP_4 },
+ { "gzip-5", ZIO_COMPRESS_GZIP_5 },
+ { "gzip-6", ZIO_COMPRESS_GZIP_6 },
+ { "gzip-7", ZIO_COMPRESS_GZIP_7 },
+ { "gzip-8", ZIO_COMPRESS_GZIP_8 },
+ { "gzip-9", ZIO_COMPRESS_GZIP_9 },
+ { "zle", ZIO_COMPRESS_ZLE },
+ { "lz4", ZIO_COMPRESS_LZ4 },
+ { "zstd", ZIO_COMPRESS_ZSTD },
+ };
+ for (i = 0; i < nitems(compression_algorithms); i++) {
+ if (strcmp(val, compression_algorithms[i].name) == 0) {
+ nvlist_add_uint64(nvl, key,
+ compression_algorithms[i].alg);
+ break;
+ }
+ }
+ if (i == nitems(compression_algorithms))
+ errx(1, "invalid compression algorithm `%s'", val);
} else {
errx(1, "unknown property `%s'", key);
}
@@ -204,7 +237,7 @@ dsl_metadir_alloc(zfs_opt_t *zfs, const char *name)
zfs_dsl_dir_t *dir;
char *path;
- easprintf(&path, "%s/%s", zfs->poolname, name);
+ (void)easprintf(&path, "%s/%s", zfs->poolname, name);
dir = dsl_dir_alloc(zfs, path);
free(path);
return (dir);
@@ -236,9 +269,6 @@ dsl_init(zfs_opt_t *zfs)
zfs->rootdsldir = dsl_dir_alloc(zfs, NULL);
- nvlist_add_uint64(zfs->rootdsldir->propsnv, "compression",
- ZIO_COMPRESS_OFF);
-
zfs->rootds = dsl_dataset_alloc(zfs, zfs->rootdsldir);
zfs->rootdsldir->headds = zfs->rootds;
@@ -288,11 +318,15 @@ dsl_init(zfs_opt_t *zfs)
}
/*
- * Set the root dataset's mount point if the user didn't override the
- * default.
+ * Set the root dataset's mount point and compression strategy if the
+ * user didn't override the defaults.
*/
+ if (nvpair_find(zfs->rootdsldir->propsnv, "compression") == NULL) {
+ (void)nvlist_add_uint64(zfs->rootdsldir->propsnv,
+ "compression", ZIO_COMPRESS_OFF);
+ }
if (nvpair_find(zfs->rootdsldir->propsnv, "mountpoint") == NULL) {
- nvlist_add_string(zfs->rootdsldir->propsnv, "mountpoint",
+ (void)nvlist_add_string(zfs->rootdsldir->propsnv, "mountpoint",
zfs->rootpath);
}
}
@@ -397,6 +431,7 @@ dsl_dir_alloc(zfs_opt_t *zfs, const char *name)
STAILQ_INIT(&l);
STAILQ_INSERT_HEAD(&l, zfs->rootdsldir, next);
origname = dirname = nextdir = estrdup(name);
+ parent = NULL;
for (lp = &l;; lp = &parent->children) {
dirname = strsep(&nextdir, "/");
if (nextdir == NULL)
diff --git a/usr.sbin/makefs/zfs/fs.c b/usr.sbin/makefs/zfs/fs.c
index 073dce3ce697..75f6e30e1500 100644
--- a/usr.sbin/makefs/zfs/fs.c
+++ b/usr.sbin/makefs/zfs/fs.c
@@ -28,6 +28,7 @@
* SUCH DAMAGE.
*/
+#include <sys/param.h>
#include <sys/stat.h>
#include <assert.h>
@@ -383,22 +384,34 @@ fs_populate_sattrs(struct fs_populate_arg *arg, const fsnode *cur,
links = 1; /* .. */
objsize = 1; /* .. */
- /*
- * The size of a ZPL directory is the number of entries
- * (including "." and ".."), and the link count is the number of
- * entries which are directories (including "." and "..").
- */
- for (fsnode *c = fsnode_isroot(cur) ? cur->next : cur->child;
- c != NULL; c = c->next) {
- switch (c->type) {
- case S_IFDIR:
- links++;
- /* FALLTHROUGH */
- case S_IFREG:
- case S_IFLNK:
- objsize++;
- break;
+ if ((cur->inode->flags & FI_ROOT) == 0 ) {
+ /*
+ * The size of a ZPL directory is the number of entries
+ * (including "." and ".."), and the link count is the
+ * number of entries which are directories
+ * (including "." and "..").
+ */
+ for (fsnode *c =
+ fsnode_isroot(cur) ? cur->next : cur->child;
+ c != NULL; c = c->next) {
+ switch (c->type) {
+ case S_IFDIR:
+ links++;
+ /* FALLTHROUGH */
+ case S_IFREG:
+ case S_IFLNK:
+ objsize++;
+ break;
+ }
}
+ } else {
+ /*
+ * Root directory children do belong to
+ * different dataset and this directory is
+ * empty in the current objset.
+ */
+ links++; /* . */
+ objsize++; /* . */
}
/* The root directory is its own parent. */
@@ -734,7 +747,7 @@ fs_add_zpl_attr_layout(zfs_zap_t *zap, unsigned int index,
assert(sizeof(layout[0]) == 2);
- snprintf(ti, sizeof(ti), "%u", index);
+ (void)snprintf(ti, sizeof(ti), "%u", index);
zap_add(zap, ti, sizeof(sa_attr_type_t), sacnt,
(const uint8_t *)layout);
}
diff --git a/usr.sbin/makefs/zfs/objset.c b/usr.sbin/makefs/zfs/objset.c
index 6be732db477a..f47953ac4339 100644
--- a/usr.sbin/makefs/zfs/objset.c
+++ b/usr.sbin/makefs/zfs/objset.c
@@ -28,6 +28,7 @@
* SUCH DAMAGE.
*/
+#include <sys/param.h>
#include <assert.h>
#include <stdlib.h>
#include <string.h>
diff --git a/usr.sbin/makefs/zfs/vdev.c b/usr.sbin/makefs/zfs/vdev.c
index ef9e681af2da..afcce402cb13 100644
--- a/usr.sbin/makefs/zfs/vdev.c
+++ b/usr.sbin/makefs/zfs/vdev.c
@@ -28,6 +28,7 @@
* SUCH DAMAGE.
*/
+#include <sys/param.h>
#include <assert.h>
#include <fcntl.h>
#include <stdlib.h>
diff --git a/usr.sbin/makefs/zfs/zap.c b/usr.sbin/makefs/zfs/zap.c
index decf5fc6a473..316d1446cecf 100644
--- a/usr.sbin/makefs/zfs/zap.c
+++ b/usr.sbin/makefs/zfs/zap.c
@@ -28,7 +28,7 @@
* SUCH DAMAGE.
*/
-#include <sys/types.h>
+#include <sys/param.h>
#include <sys/endian.h>
#include <assert.h>
@@ -172,14 +172,14 @@ zap_add_uint64_self(zfs_zap_t *zap, uint64_t val)
{
char name[32];
- snprintf(name, sizeof(name), "%jx", (uintmax_t)val);
+ (void)snprintf(name, sizeof(name), "%jx", (uintmax_t)val);
zap_add(zap, name, sizeof(uint64_t), 1, (uint8_t *)&val);
}
void
zap_add_string(zfs_zap_t *zap, const char *name, const char *val)
{
- zap_add(zap, name, 1, strlen(val) + 1, val);
+ zap_add(zap, name, 1, strlen(val) + 1, (const uint8_t *)val);
}
bool
@@ -221,7 +221,8 @@ zap_micro_write(zfs_opt_t *zfs, zfs_zap_t *zap)
STAILQ_FOREACH(ent, &zap->kvps, next) {
memcpy(&ment->mze_value, ent->valp, ent->intsz * ent->intcnt);
ment->mze_cd = cd++;
- strlcpy(ment->mze_name, ent->name, sizeof(ment->mze_name));
+ (void)strlcpy(ment->mze_name, ent->name,
+ sizeof(ment->mze_name));
ment++;
}
@@ -247,6 +248,7 @@ zap_fat_write_array_chunk(zap_leaf_t *l, uint16_t li, size_t sz,
struct zap_leaf_array *la;
assert(sz <= ZAP_MAXVALUELEN);
+ assert(sz > 0);
for (uint16_t n, resid = sz; resid > 0; resid -= n, val += n, li++) {
n = MIN(resid, ZAP_LEAF_ARRAY_BYTES);
@@ -503,7 +505,8 @@ zap_fat_write(zfs_opt_t *zfs, zfs_zap_t *zap)
le->le_value_intlen = ent->intsz;
le->le_value_numints = ent->intcnt;
le->le_hash = ent->hash;
- zap_fat_write_array_chunk(&l, *lptr + 1, namelen, ent->name);
+ zap_fat_write_array_chunk(&l, *lptr + 1, namelen,
+ (uint8_t *)ent->name);
zap_fat_write_array_chunk(&l, *lptr + 1 + nnamechunks,
ent->intcnt * ent->intsz, ent->valp);
}
diff --git a/usr.sbin/mfiutil/Makefile b/usr.sbin/mfiutil/Makefile
index 85b66d4b6f49..49c0e688e8e2 100644
--- a/usr.sbin/mfiutil/Makefile
+++ b/usr.sbin/mfiutil/Makefile
@@ -4,7 +4,7 @@ LINKS= ${BINDIR}/mfiutil ${BINDIR}/mrsasutil
SRCS= mfiutil.c mfi_bbu.c mfi_cmd.c mfi_config.c mfi_drive.c mfi_evt.c \
mfi_flash.c mfi_patrol.c mfi_show.c mfi_volume.c mfi_foreign.c \
mfi_properties.c
-MAN8= mfiutil.8
+MAN= mfiutil.8
MLINKS= mfiutil.8 mrsasutil.8
CFLAGS.gcc+= -fno-builtin-strftime
diff --git a/usr.sbin/rpc.lockd/kern.c b/usr.sbin/rpc.lockd/kern.c
index c24b81159ea5..1945bd68328a 100644
--- a/usr.sbin/rpc.lockd/kern.c
+++ b/usr.sbin/rpc.lockd/kern.c
@@ -39,6 +39,7 @@
#include <netinet/in.h>
#include <arpa/inet.h>
+#include <assert.h>
#include <err.h>
#include <errno.h>
#include <fcntl.h>
@@ -232,17 +233,29 @@ void
set_auth(CLIENT *cl, struct xucred *xucred)
{
int ngroups;
+ gid_t *groups;
- ngroups = xucred->cr_ngroups - 1;
+ /*
+ * Exclude the first element if it is actually the egid, but account for
+ * the possibility that we could eventually exclude the egid from the
+ * exported group list some day.
+ */
+ ngroups = xucred->cr_ngroups;
+ groups = &xucred->cr_groups[0];
+ if (groups == &xucred->cr_gid) {
+ assert(ngroups > 0);
+ ngroups--;
+ groups++;
+ }
if (ngroups > NGRPS)
ngroups = NGRPS;
if (cl->cl_auth != NULL)
cl->cl_auth->ah_ops->ah_destroy(cl->cl_auth);
cl->cl_auth = authunix_create(hostname,
xucred->cr_uid,
- xucred->cr_groups[0],
+ xucred->cr_gid,
ngroups,
- &xucred->cr_groups[1]);
+ groups);
}
diff --git a/usr.sbin/rwhod/rwhod.c b/usr.sbin/rwhod/rwhod.c
index 237663eef74d..b99e4ea74b5a 100644
--- a/usr.sbin/rwhod/rwhod.c
+++ b/usr.sbin/rwhod/rwhod.c
@@ -246,12 +246,12 @@ main(int argc, char *argv[])
syslog(LOG_ERR, "bind: %m");
exit(1);
}
- if (setgid(unpriv_gid) != 0) {
- syslog(LOG_ERR, "setgid: %m");
+ if (setgroups(0, NULL) != 0) {
+ syslog(LOG_ERR, "setgroups: %m");
exit(1);
}
- if (setgroups(1, &unpriv_gid) != 0) { /* XXX BOGUS groups[0] = egid */
- syslog(LOG_ERR, "setgroups: %m");
+ if (setgid(unpriv_gid) != 0) {
+ syslog(LOG_ERR, "setgid: %m");
exit(1);
}
if (setuid(unpriv_uid) != 0) {
diff --git a/usr.sbin/spi/Makefile b/usr.sbin/spi/Makefile
index 73f5af6fc3cc..fee967f6a234 100644
--- a/usr.sbin/spi/Makefile
+++ b/usr.sbin/spi/Makefile
@@ -2,6 +2,6 @@
PROG= spi
-MAN8= spi.8
+MAN= spi.8
.include <bsd.prog.mk>
diff --git a/usr.sbin/trim/trim.8 b/usr.sbin/trim/trim.8
index 1ac10d7e3d46..a4874c54c183 100644
--- a/usr.sbin/trim/trim.8
+++ b/usr.sbin/trim/trim.8
@@ -23,7 +23,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.Dd January 18, 2019
+.Dd July 20, 2025
.Dt TRIM 8
.Os
.Sh NAME
@@ -36,7 +36,7 @@
.Bk -words
.Sm off
.Ar offset
-.Op Cm K | k | M | m | G | g | T | t ]
+.Op Cm K | k | M | m | G | g | T | t | P | p | E | e ]
.Sm on
.Xc
.Ek
@@ -68,13 +68,13 @@ Overrides
.It Fl l Xo
.Sm off
.Ar offset
-.Op Cm K | k | M | m | G | g | T | t
+.Op Cm K | k | M | m | G | g | T | t | P | p | E | e
.Sm on
.Xc
.It Fl o Xo
.Sm off
.Ar offset
-.Op Cm K | k | M | m | G | g | T | t
+.Op Cm K | k | M | m | G | g | T | t | P | p | E | e
.Sm on
.Xc
Specify the length
@@ -88,12 +88,14 @@ unless one or both of these options are presented.
The argument may be suffixed with one of
.Cm K ,
.Cm M ,
-.Cm G
+.Cm G ,
+.Cm T ,
+.Cm P
or
-.Cm T
+.Cm E
(either upper or lower case) to indicate a multiple of
-Kilobytes, Megabytes, Gigabytes or Terabytes
-respectively.
+Kilobytes, Megabytes, Gigabytes, Terabytes, Petabytes or
+Exabytes, respectively.
.It Fl q
Do not output anything except of possible error messages (quiet mode).
Overrides
diff --git a/usr.sbin/trim/trim.c b/usr.sbin/trim/trim.c
index 3e187faa0fb3..27f57ac2fb72 100644
--- a/usr.sbin/trim/trim.c
+++ b/usr.sbin/trim/trim.c
@@ -114,7 +114,7 @@ main(int argc, char **argv)
*
* trim -f -- /dev/da0 -r rfile
*/
-
+
if (strcmp(argv[optind-1], "--") != 0) {
for (ch = optind; ch < argc; ch++)
if (argv[ch][0] == '-')
@@ -127,6 +127,9 @@ main(int argc, char **argv)
if (argc < 1)
usage(name);
+ if (dryrun)
+ printf("dry run: add -f to actually perform the operation\n");
+
while ((fname = *argv++) != NULL)
if (trim(fname, offset, length, dryrun, verbose) < 0)
error++;
@@ -213,10 +216,8 @@ trim(const char *path, off_t offset, off_t length, bool dryrun, bool verbose)
printf("trim %s offset %ju length %ju\n",
path, (uintmax_t)offset, (uintmax_t)length);
- if (dryrun) {
- printf("dry run: add -f to actually perform the operation\n");
+ if (dryrun)
return (0);
- }
fd = opendev(path, O_RDWR | O_DIRECT);
arg[0] = offset;
@@ -237,7 +238,7 @@ static void
usage(const char *name)
{
(void)fprintf(stderr,
- "usage: %s [-[lo] offset[K|k|M|m|G|g|T|t]] [-r rfile] [-Nfqv] device ...\n",
+ "usage: %s [-[lo] offset[K|k|M|m|G|g|T|t|P|p|E|e]] [-r rfile] [-Nfqv] device ...\n",
name);
exit(EX_USAGE);
}
diff --git a/usr.sbin/ypldap/ldapclient.c b/usr.sbin/ypldap/ldapclient.c
index acd4410d939f..a246a25a9605 100644
--- a/usr.sbin/ypldap/ldapclient.c
+++ b/usr.sbin/ypldap/ldapclient.c
@@ -385,7 +385,7 @@ ldapclient(int pipe_main2client[2])
ypldap_process = PROC_CLIENT;
#ifndef DEBUG
- if (setgroups(1, &pw->pw_gid) ||
+ if (setgroups(0, NULL) ||
setresgid(pw->pw_gid, pw->pw_gid, pw->pw_gid) ||
setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid))
fatal("cannot drop privileges");
diff --git a/usr.sbin/ypldap/ypldap.c b/usr.sbin/ypldap/ypldap.c
index 01b5955aa822..b9e938227831 100644
--- a/usr.sbin/ypldap/ypldap.c
+++ b/usr.sbin/ypldap/ypldap.c
@@ -602,7 +602,7 @@ main(int argc, char *argv[])
fatal("getpwnam");
#ifndef DEBUG
- if (setgroups(1, &pw->pw_gid) ||
+ if (setgroups(0, NULL) ||
setresgid(pw->pw_gid, pw->pw_gid, pw->pw_gid) ||
setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid))
fatal("cannot drop privileges");
diff --git a/usr.sbin/ypldap/ypldap_dns.c b/usr.sbin/ypldap/ypldap_dns.c
index 09ce636ebdc8..9dbbf26d237b 100644
--- a/usr.sbin/ypldap/ypldap_dns.c
+++ b/usr.sbin/ypldap/ypldap_dns.c
@@ -91,7 +91,7 @@ ypldap_dns(int pipe_ntp[2], struct passwd *pw)
setproctitle("dns engine");
close(pipe_ntp[0]);
- if (setgroups(1, &pw->pw_gid) ||
+ if (setgroups(0, NULL) ||
setresgid(pw->pw_gid, pw->pw_gid, pw->pw_gid) ||
setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid))
fatal("can't drop privileges");