From 4837313c99a7d59b1241728101760485b74f8d2b Mon Sep 17 00:00:00 2001 From: Toomas Soome Date: Thu, 13 Sep 2018 20:05:48 +0300 Subject: 9837 nfs_dlinet: allow nfs:// urls Reviewed by: Peter Tribble Reviewed by: Andy Fiddaman Approved by: Robert Mustacchi --- usr/src/uts/common/fs/nfs/nfs_dlinet.c | 39 ++++++++++++++++++++++++++++------ 1 file changed, 33 insertions(+), 6 deletions(-) diff --git a/usr/src/uts/common/fs/nfs/nfs_dlinet.c b/usr/src/uts/common/fs/nfs/nfs_dlinet.c index 8ac4c84d17..34658b161f 100644 --- a/usr/src/uts/common/fs/nfs/nfs_dlinet.c +++ b/usr/src/uts/common/fs/nfs/nfs_dlinet.c @@ -1201,11 +1201,38 @@ cacheinit(void) if (doptp == NULL) doptp = pl->opts[CD_ROOT_PATH]; if (doptp != NULL) { - int len; + int len, size; + uint8_t c, *source; + str = NULL; - for (len = 0; len < doptp->len; len++) { - if (doptp->value[len] == ':') { - str = (char *)(&doptp->value[++len]); + source = doptp->value; + size = doptp->len; + c = ':'; + + /* + * We have to consider three cases for root path: + * "nfs://server_ip/path" + * "server_ip:/path" + * "/path" + */ + if (bcmp(source, "nfs://", 6) == 0) { + source += 6; + size -= 6; + c = '/'; + } + /* + * Search for next char after ':' or first '/'. + * Note, the '/' is part of the path, but we do + * not need to preserve the ':'. + */ + for (len = 0; len < size; len++) { + if (source[len] == c) { + if (c == ':') { + str = (char *)(&source[++len]); + } else { + str = (char *)(&source[len++]); + size++; + } break; } } @@ -1213,7 +1240,7 @@ cacheinit(void) /* Do not override server_ip from property. */ if ((*(uint_t *)server_ip) == 0) { char *ip = kmem_alloc(len, KM_SLEEP); - bcopy(doptp->value, ip, len); + bcopy(source, ip, len); ip[len - 1] = '\0'; if (inet_aton((ip), server_ip) != 0) { cmn_err(CE_NOTE, @@ -1228,7 +1255,7 @@ cacheinit(void) server_ip)); } } - len = doptp->len - len; + len = size - len; } else { str = (char *)doptp->value; len = doptp->len; -- cgit v1.2.3 From c952f9c1bd80512c5c1db6f7c8c4b49d40154098 Mon Sep 17 00:00:00 2001 From: Toomas Soome Date: Thu, 9 Aug 2018 08:27:05 +0300 Subject: 9844 libi386: Fix typo in pxe.h Reviewed by: Andy Fiddaman Reviewed by: Peter Tribble Approved by: Robert Mustacchi --- usr/src/boot/sys/boot/i386/libi386/pxe.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/usr/src/boot/sys/boot/i386/libi386/pxe.h b/usr/src/boot/sys/boot/i386/libi386/pxe.h index 1afc23bf4b..67e2c643d8 100644 --- a/usr/src/boot/sys/boot/i386/libi386/pxe.h +++ b/usr/src/boot/sys/boot/i386/libi386/pxe.h @@ -145,7 +145,7 @@ typedef struct { PXENV_STATUS_t Status; ADDR32_t ProtocolIni; /* Phys addr of a copy of the driver module */ uint8_t reserved[8]; -} PACKED t_PXENV_UNDI_INITALIZE; +} PACKED t_PXENV_UNDI_INITIALIZE; #define MAXNUM_MCADDR 8 -- cgit v1.2.3 From 00d7a6fb939233ed021b823016c33fcae1dac964 Mon Sep 17 00:00:00 2001 From: Rob Johnston Date: Wed, 12 Sep 2018 14:55:55 -0700 Subject: 9455 Expose drive speed and temperature on disk topo node Reviewed by: Yuri Pankov Reviewed by: Igor Kozhukhov Approved by: Dan McDonald --- usr/src/lib/fm/topo/modules/common/disk/Makefile | 4 +- usr/src/lib/fm/topo/modules/common/disk/disk.h | 3 +- .../lib/fm/topo/modules/common/disk/disk_common.c | 196 ++++++++++++++++++--- usr/src/lib/fm/topo/modules/common/ses/Makefile | 3 +- .../lib/fm/topo/modules/common/ses/ses_facility.c | 54 +++--- 5 files changed, 210 insertions(+), 50 deletions(-) diff --git a/usr/src/lib/fm/topo/modules/common/disk/Makefile b/usr/src/lib/fm/topo/modules/common/disk/Makefile index 4b4c965050..8e8935be65 100644 --- a/usr/src/lib/fm/topo/modules/common/disk/Makefile +++ b/usr/src/lib/fm/topo/modules/common/disk/Makefile @@ -22,6 +22,8 @@ # Copyright 2008 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # +# Copyright (c) 2018, Joyent, Inc. +# MODULE = disk CLASS = common @@ -32,5 +34,5 @@ include ../../Makefile.plugin CPPFLAGS += -I$(SRC)/uts/common -LDLIBS += -ldevinfo -ldevid -lcfgadm -ldiskstatus +LDLIBS += -ldevinfo -ldevid -lcfgadm -ldiskstatus -ldiskmgt diff --git a/usr/src/lib/fm/topo/modules/common/disk/disk.h b/usr/src/lib/fm/topo/modules/common/disk/disk.h index d597df27b1..02aa7efc87 100644 --- a/usr/src/lib/fm/topo/modules/common/disk/disk.h +++ b/usr/src/lib/fm/topo/modules/common/disk/disk.h @@ -23,7 +23,7 @@ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. */ /* - * Copyright (c) 2017, Joyent, Inc. + * Copyright (c) 2018, Joyent, Inc. */ #ifndef _DISK_H @@ -50,6 +50,7 @@ extern "C" { #define TOPO_STORAGE_SERIAL_NUM "serial-number" #define TOPO_STORAGE_FIRMWARE_REV "firmware-revision" #define TOPO_STORAGE_CAPACITY "capacity-in-bytes" +#define TOPO_STORAGE_RPM "speed-in-rpm" /* * Properties for binding group: The binding group required in platform diff --git a/usr/src/lib/fm/topo/modules/common/disk/disk_common.c b/usr/src/lib/fm/topo/modules/common/disk/disk_common.c index 123e86f44f..3eebb3ee20 100644 --- a/usr/src/lib/fm/topo/modules/common/disk/disk_common.c +++ b/usr/src/lib/fm/topo/modules/common/disk/disk_common.c @@ -21,7 +21,7 @@ /* * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2017, Joyent, Inc. + * Copyright (c) 2018, Joyent, Inc. */ /* @@ -38,6 +38,7 @@ #include #include #include +#include #include #include #include @@ -86,6 +87,20 @@ static const topo_method_t disk_methods[] = { { NULL } }; +static int disk_temp_reading(topo_mod_t *, tnode_t *, topo_version_t, + nvlist_t *, nvlist_t **); + +#define TOPO_METH_DISK_TEMP "disk_temp_reading" +#define TOPO_METH_DISK_TEMP_DESC "Disk Temperature Reading" +#define TOPO_METH_DISK_TEMP_VERSION 0 + +static const topo_method_t disk_fac_methods[] = { + { TOPO_METH_DISK_TEMP, TOPO_METH_DISK_TEMP_DESC, + TOPO_METH_DISK_TEMP_VERSION, TOPO_STABILITY_INTERNAL, + disk_temp_reading }, + { NULL } +}; + static const topo_pgroup_info_t io_pgroup = { TOPO_PGROUP_IO, TOPO_STABILITY_PRIVATE, @@ -125,9 +140,11 @@ static int disk_set_props(topo_mod_t *mod, tnode_t *parent, tnode_t *dtn, dev_di_node_t *dnode) { - nvlist_t *asru = NULL; + nvlist_t *asru = NULL, *drive_attrs; char *label = NULL; nvlist_t *fmri = NULL; + dm_descriptor_t drive_descr = NULL; + uint32_t rpm; int err; /* pull the label property down from our parent 'bay' node */ @@ -265,9 +282,29 @@ disk_set_props(topo_mod_t *mod, tnode_t *parent, "set cap error %s\n", topo_strerror(err)); goto error; } + + if (dnode->ddn_devid == NULL || + (drive_descr = dm_get_descriptor_by_name(DM_DRIVE, + dnode->ddn_devid, &err)) == NULL || + (drive_attrs = dm_get_attributes(drive_descr, &err)) == NULL) + goto out; + + if (nvlist_lookup_boolean(drive_attrs, DM_SOLIDSTATE) == 0 || + nvlist_lookup_uint32(drive_attrs, DM_RPM, &rpm) != 0) + goto out; + + if (topo_prop_set_uint32(dtn, TOPO_PGROUP_STORAGE, TOPO_STORAGE_RPM, + TOPO_PROP_IMMUTABLE, rpm, &err) != 0) { + topo_mod_dprintf(mod, "disk_set_props: " + "set rpm error %s\n", topo_strerror(err)); + dm_free_descriptor(drive_descr); + goto error; + } err = 0; out: + if (drive_descr != NULL) + dm_free_descriptor(drive_descr); nvlist_free(fmri); if (label) topo_mod_strfree(mod, label); @@ -307,26 +344,134 @@ disk_trim_whitespace(topo_mod_t *mod, const char *begin) return (buf); } -/* - * Manufacturing strings can contain characters that are invalid for use in hc - * authority names. This trims leading and trailing whitespace, and - * substitutes any characters known to be bad. - */ -char * -disk_auth_clean(topo_mod_t *mod, const char *str) +/*ARGSUSED*/ +static int +disk_temp_reading(topo_mod_t *mod, tnode_t *node, topo_version_t vers, + nvlist_t *in, nvlist_t **out) { - char *buf, *p; + char *devid; + uint32_t temp; + dm_descriptor_t drive_descr = NULL; + nvlist_t *drive_stats, *pargs, *nvl; + int err; + + if (vers > TOPO_METH_DISK_TEMP_VERSION) + return (topo_mod_seterrno(mod, ETOPO_METHOD_VERNEW)); + + if (nvlist_lookup_nvlist(in, TOPO_PROP_ARGS, &pargs) != 0 || + nvlist_lookup_string(pargs, TOPO_IO_DEVID, &devid) != 0) { + topo_mod_dprintf(mod, "Failed to lookup %s arg", + TOPO_IO_DEVID); + return (topo_mod_seterrno(mod, EMOD_NVL_INVAL)); + } - if (str == NULL) - return (NULL); + if ((drive_descr = dm_get_descriptor_by_name(DM_DRIVE, devid, + &err)) == NULL) { + topo_mod_dprintf(mod, "failed to get drive decriptor for %s", + devid); + return (topo_mod_seterrno(mod, EMOD_UNKNOWN)); + } - if ((buf = topo_mod_strdup(mod, str)) == NULL) - return (NULL); + if ((drive_stats = dm_get_stats(drive_descr, DM_DRV_STAT_TEMPERATURE, + &err)) == NULL || + nvlist_lookup_uint32(drive_stats, DM_TEMPERATURE, &temp) != 0) { + topo_mod_dprintf(mod, "failed to read disk temp for %s", + devid); + dm_free_descriptor(drive_descr); + return (topo_mod_seterrno(mod, EMOD_UNKNOWN)); + } + dm_free_descriptor(drive_descr); + + if (topo_mod_nvalloc(mod, &nvl, NV_UNIQUE_NAME) != 0 || + nvlist_add_string(nvl, TOPO_PROP_VAL_NAME, + TOPO_SENSOR_READING) != 0 || + nvlist_add_uint32(nvl, TOPO_PROP_VAL_TYPE, TOPO_TYPE_DOUBLE) != + 0 || nvlist_add_double(nvl, TOPO_PROP_VAL_VAL, (double)temp) != 0) { + topo_mod_dprintf(mod, "Failed to allocate 'out' nvlist\n"); + nvlist_free(nvl); + return (topo_mod_seterrno(mod, EMOD_NOMEM)); + } + *out = nvl; - while ((p = strpbrk(buf, " :=")) != NULL) - *p = '-'; + return (0); +} - return (buf); +static int +disk_add_temp_sensor(topo_mod_t *mod, tnode_t *pnode, const char *devid) +{ + tnode_t *fnode; + topo_pgroup_info_t pgi; + nvlist_t *arg_nvl = NULL; + int err; + + if ((fnode = topo_node_facbind(mod, pnode, "temp", + TOPO_FAC_TYPE_SENSOR)) == NULL) { + topo_mod_dprintf(mod, "failed to bind facility node"); + /* errno set */ + return (-1); + } + + /* + * Set props: + * - facility/sensor-class + * - facility/sensor-type + * - facility/units + */ + pgi.tpi_name = TOPO_PGROUP_FACILITY; + pgi.tpi_namestab = TOPO_STABILITY_PRIVATE; + pgi.tpi_datastab = TOPO_STABILITY_PRIVATE; + pgi.tpi_version = 1; + if (topo_pgroup_create(fnode, &pgi, &err) != 0) { + if (err != ETOPO_PROP_DEFD) { + topo_mod_dprintf(mod, "pgroups create failure (%s)\n", + topo_strerror(err)); + /* errno set */ + goto err; + } + } + if (topo_prop_set_string(fnode, TOPO_PGROUP_FACILITY, + TOPO_SENSOR_CLASS, TOPO_PROP_IMMUTABLE, + TOPO_SENSOR_CLASS_THRESHOLD, &err) != 0 || + topo_prop_set_uint32(fnode, TOPO_PGROUP_FACILITY, + TOPO_FACILITY_TYPE, TOPO_PROP_IMMUTABLE, TOPO_SENSOR_TYPE_TEMP, + &err) != 0 || + topo_prop_set_uint32(fnode, TOPO_PGROUP_FACILITY, + TOPO_SENSOR_UNITS, TOPO_PROP_IMMUTABLE, + TOPO_SENSOR_UNITS_DEGREES_C, &err) != 0) { + topo_mod_dprintf(mod, "Failed to set props on facnode (%s)", + topo_strerror(err)); + /* errno set */ + goto err; + } + + /* + * Register a property method for facility/reading + */ + if (topo_method_register(mod, fnode, disk_fac_methods) < 0) { + topo_mod_dprintf(mod, "failed to register facility methods"); + goto err; + } + if (topo_mod_nvalloc(mod, &arg_nvl, NV_UNIQUE_NAME) < 0 || + nvlist_add_string(arg_nvl, TOPO_IO_DEVID, devid) != 0) { + topo_mod_dprintf(mod, "Failed build arg nvlist\n"); + (void) topo_mod_seterrno(mod, EMOD_NOMEM); + goto err; + } + if (topo_prop_method_register(fnode, TOPO_PGROUP_FACILITY, + TOPO_SENSOR_READING, TOPO_TYPE_DOUBLE, "disk_temp_reading", + arg_nvl, &err) != 0) { + topo_mod_dprintf(mod, "Failed to register %s propmeth " + "on fac node %s (%s)\n", TOPO_SENSOR_READING, + topo_node_name(fnode), topo_strerror(err)); + /* errno set */ + goto err; + } + nvlist_free(arg_nvl); + return (0); +err: + topo_node_unbind(fnode); + nvlist_free(arg_nvl); + return (-1); } /* create the disk topo node */ @@ -343,10 +488,10 @@ disk_tnode_create(topo_mod_t *mod, tnode_t *parent, *rval = NULL; if (dnode != NULL) { - mfg = disk_auth_clean(mod, dnode->ddn_mfg); - model = disk_auth_clean(mod, dnode->ddn_model); - firm = disk_auth_clean(mod, dnode->ddn_firm); - serial = disk_auth_clean(mod, dnode->ddn_serial); + mfg = topo_mod_clean_str(mod, dnode->ddn_mfg); + model = topo_mod_clean_str(mod, dnode->ddn_model); + firm = topo_mod_clean_str(mod, dnode->ddn_firm); + serial = topo_mod_clean_str(mod, dnode->ddn_serial); } else { mfg = model = firm = serial = NULL; } @@ -404,6 +549,13 @@ disk_tnode_create(topo_mod_t *mod, tnode_t *parent, topo_node_unbind(dtn); return (-1); } + + if (dnode->ddn_devid != NULL && + disk_add_temp_sensor(mod, dtn, dnode->ddn_devid) != 0) { + topo_mod_dprintf(mod, "disk_tnode_create: failed to create " + "temperature sensor node on bay=%d/disk=0", + topo_node_instance(parent)); + } *rval = dtn; return (0); } @@ -624,7 +776,7 @@ dev_di_node_add(di_node_t node, char *devid, disk_cbdata_t *cbp) char lentry[MAXPATHLEN]; int pathcount; int *inq_dtype, itype; - int i; + int i; if (devid) { /* diff --git a/usr/src/lib/fm/topo/modules/common/ses/Makefile b/usr/src/lib/fm/topo/modules/common/ses/Makefile index 578b5bf493..acd772c92f 100644 --- a/usr/src/lib/fm/topo/modules/common/ses/Makefile +++ b/usr/src/lib/fm/topo/modules/common/ses/Makefile @@ -20,6 +20,7 @@ # # # Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2018, Joyent, Inc. # MODULE = ses @@ -34,6 +35,6 @@ include ../../Makefile.plugin CPPFLAGS += -I../disk LDLIBS += -L$(ROOTLIBDIR)/scsi -R/usr/lib/scsi -lses -LDLIBS += -ldevinfo -ldevid -ldiskstatus -lcontract -lsysevent +LDLIBS += -ldevinfo -ldevid -ldiskstatus -lcontract -lsysevent -ldiskmgt CLOBBERFILES += disk_common.ln diff --git a/usr/src/lib/fm/topo/modules/common/ses/ses_facility.c b/usr/src/lib/fm/topo/modules/common/ses/ses_facility.c index 08a4a569ee..2c4a1314e3 100644 --- a/usr/src/lib/fm/topo/modules/common/ses/ses_facility.c +++ b/usr/src/lib/fm/topo/modules/common/ses/ses_facility.c @@ -28,38 +28,42 @@ * Copyright 2015 Nexenta Systems, Inc. All rights reserved. */ +/* + * Copyright (c) 2018, Joyent, Inc. + */ + /* * Facility node support for SES enclosures. We support the following facility * nodes, based on the node type: * - * bay - * indicator=ident - * indicator=fail - * indicator=ok2rm - * sensor=fault + * bay + * indicator=ident + * indicator=fail + * indicator=ok2rm + * sensor=fault * - * controller - * indicator=ident - * indicator=fail + * controller + * indicator=ident + * indicator=fail * - * fan - * indicator=ident - * indicator=fail - * sensor=speed - * sensor=fault + * fan + * indicator=ident + * indicator=fail + * sensor=speed + * sensor=fault * - * psu - * indicator=ident - * indicator=fail - * sensor=status + * psu + * indicator=ident + * indicator=fail + * sensor=status * - * ses-enclosure - * indicator=ident - * indicator=fail - * sensor=fault - * sensor= (temperature) - * sensor= (voltage) - * sensor= (current) + * ses-enclosure + * indicator=ident + * indicator=fail + * sensor=fault + * sensor= (temperature) + * sensor= (voltage) + * sensor= (current) * * Most of these are handled by a single method that supports getting and * setting boolean properties on the node. The fan speed sensor requires a @@ -930,7 +934,7 @@ ses_add_enclosure_sensors(topo_mod_t *mod, tnode_t *tn, ses_node_t *agg, "%.*s %llu", len, desc, index); } - if ((name = disk_auth_clean(mod, rawname)) == NULL) + if ((name = topo_mod_clean_str(mod, rawname)) == NULL) return (-1); if (ses_add_sensor(mod, tn, nodeid, name, &sd) != 0) { -- cgit v1.2.3 From cbb9248e66a77c6382c6f48aebae5fd0ee60fa69 Mon Sep 17 00:00:00 2001 From: Rob Johnston Date: Wed, 12 Sep 2018 14:56:30 -0700 Subject: 9835 ses topo module should use topo_mod_clean_str() Reviewed by: Yuri Pankov Reviewed by: Igor Kozhukhov Approved by: Dan McDonald --- usr/src/lib/fm/topo/modules/common/ses/ses.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/usr/src/lib/fm/topo/modules/common/ses/ses.c b/usr/src/lib/fm/topo/modules/common/ses/ses.c index 681c47f005..9a183c9845 100644 --- a/usr/src/lib/fm/topo/modules/common/ses/ses.c +++ b/usr/src/lib/fm/topo/modules/common/ses/ses.c @@ -23,7 +23,7 @@ * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright 2012 Milan Jurik. All rights reserved. * Copyright 2015 Nexenta Systems, Inc. All rights reserved. - * Copyright (c) 2017, Joyent, Inc. + * Copyright (c) 2018, Joyent, Inc. */ #include @@ -1452,9 +1452,9 @@ ses_create_generic(ses_enum_data_t *sdp, ses_enum_node_t *snp, tnode_t *pnode, /* * For the node label, we look for the following in order: * - * - * - * + * + * + * */ if (nvlist_lookup_string(props, SES_PROP_DESCRIPTION, &desc) != 0 || desc[0] == '\0') { @@ -2837,9 +2837,9 @@ ses_create_chassis(ses_enum_data_t *sdp, tnode_t *pnode, ses_enum_chassis_t *cp) /* * We use the following property mappings: * - * manufacturer vendor-id - * model product-id - * serial-number libses-chassis-serial + * manufacturer vendor-id + * model product-id + * serial-number libses-chassis-serial */ verify(nvlist_lookup_string(props, SES_EN_PROP_VID, &raw_manufacturer) == 0); @@ -2854,9 +2854,9 @@ ses_create_chassis(ses_enum_data_t *sdp, tnode_t *pnode, ses_enum_chassis_t *cp) * 'product-id', we use a concatenation of 'manufacturer-model'. We * also take the numerical serial number and convert it to a string. */ - if ((manufacturer = disk_auth_clean(mod, raw_manufacturer)) == NULL || - (model = disk_auth_clean(mod, raw_model)) == NULL || - (revision = disk_auth_clean(mod, raw_revision)) == NULL) { + if ((manufacturer = topo_mod_clean_str(mod, raw_manufacturer)) == + NULL || (model = topo_mod_clean_str(mod, raw_model)) == NULL || + (revision = topo_mod_clean_str(mod, raw_revision)) == NULL) { goto error; } -- cgit v1.2.3 From 837327673cfef3fa0e815ea9377af002d7b1e01b Mon Sep 17 00:00:00 2001 From: Toomas Soome Date: Thu, 13 Sep 2018 11:29:25 +0300 Subject: 9839 unix: add translation for netboot properties Reviewed by: Peter Tribble Reviewed by: Andy Fiddaman Approved by: Robert Mustacchi --- usr/src/uts/i86pc/os/fakebop.c | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/usr/src/uts/i86pc/os/fakebop.c b/usr/src/uts/i86pc/os/fakebop.c index ff5e4ea7a4..f381504e39 100644 --- a/usr/src/uts/i86pc/os/fakebop.c +++ b/usr/src/uts/i86pc/os/fakebop.c @@ -1314,6 +1314,42 @@ process_boot_environment(struct boot_modules *benv) if (do_bsys_getproplen(NULL, name) >= 0) continue; + /* Translate netboot variables */ + if (strcmp(name, "boot.netif.gateway") == 0) { + bsetprops(BP_ROUTER_IP, value); + continue; + } + if (strcmp(name, "boot.netif.hwaddr") == 0) { + bsetprops(BP_BOOT_MAC, value); + continue; + } + if (strcmp(name, "boot.netif.ip") == 0) { + bsetprops(BP_HOST_IP, value); + continue; + } + if (strcmp(name, "boot.netif.netmask") == 0) { + bsetprops(BP_SUBNET_MASK, value); + continue; + } + if (strcmp(name, "boot.netif.server") == 0) { + bsetprops(BP_SERVER_IP, value); + continue; + } + if (strcmp(name, "boot.netif.server") == 0) { + if (do_bsys_getproplen(NULL, BP_SERVER_IP) < 0) + bsetprops(BP_SERVER_IP, value); + continue; + } + if (strcmp(name, "boot.nfsroot.server") == 0) { + if (do_bsys_getproplen(NULL, BP_SERVER_IP) < 0) + bsetprops(BP_SERVER_IP, value); + continue; + } + if (strcmp(name, "boot.nfsroot.path") == 0) { + bsetprops(BP_SERVER_PATH, value); + continue; + } + if (name_is_blacklisted(name) == B_TRUE) continue; -- cgit v1.2.3 From f62db44dbcda5dd786bb821f1e6fd3ca2e6d4391 Mon Sep 17 00:00:00 2001 From: Andrew Stormont Date: Sun, 17 Jun 2018 11:53:29 +0100 Subject: 9616 Bogus error when attempting to set property on read-only pool Reviewed by: Paul Dagnelie Reviewed by: Matt Ahrens Approved by: Robert Mustacchi --- usr/src/lib/libzfs/common/libzfs_dataset.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/usr/src/lib/libzfs/common/libzfs_dataset.c b/usr/src/lib/libzfs/common/libzfs_dataset.c index 243565f463..c0fd0cec32 100644 --- a/usr/src/lib/libzfs/common/libzfs_dataset.c +++ b/usr/src/lib/libzfs/common/libzfs_dataset.c @@ -30,7 +30,7 @@ * Copyright (c) 2014 Integros [integros.com] * Copyright 2017 Nexenta Systems, Inc. * Copyright 2016 Igor Kozhukhov - * Copyright 2017 RackTop Systems. + * Copyright 2017-2018 RackTop Systems. */ #include @@ -1808,13 +1808,18 @@ zfs_prop_set_list(zfs_handle_t *zhp, nvlist_t *props) ret = zfs_ioctl(hdl, ZFS_IOC_SET_PROP, &zc); if (ret != 0) { + if (zc.zc_nvlist_dst_filled == B_FALSE) { + (void) zfs_standard_error(hdl, errno, errbuf); + goto error; + } + /* 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); + for (nvpair_t *elem = nvlist_next_nvpair(errorprops, NULL); elem != NULL; - elem = nvlist_next_nvpair(nvl, elem)) { + elem = nvlist_next_nvpair(errorprops, elem)) { zfs_prop_t prop = zfs_name_to_prop(nvpair_name(elem)); zfs_setprop_error(hdl, prop, errno, errbuf); } -- cgit v1.2.3 From 7341a7de4f0489193e0cfe11049a7bcf1596a4db Mon Sep 17 00:00:00 2001 From: Brad Lewis Date: Thu, 15 Mar 2018 13:47:26 -0600 Subject: 9677 panic from zio_write_gang_block() when creating dump device on fragmented rpool Reviewed by: Matt Ahrens Reviewed by: George Wilson Reviewed by: Prashanth Sreenivasa Approved by: Robert Mustacchi --- usr/src/uts/common/fs/zfs/zio.c | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/usr/src/uts/common/fs/zfs/zio.c b/usr/src/uts/common/fs/zfs/zio.c index dc14ad07c2..b7e11f922a 100644 --- a/usr/src/uts/common/fs/zfs/zio.c +++ b/usr/src/uts/common/fs/zfs/zio.c @@ -2192,7 +2192,13 @@ zio_write_gang_member_ready(zio_t *zio) static void zio_write_gang_done(zio_t *zio) { - abd_put(zio->io_abd); + /* + * The io_abd field will be NULL for a zio with no data. The io_flags + * will initially have the ZIO_FLAG_NODATA bit flag set, but we can't + * check for it here as it is cleared in zio_ready. + */ + if (zio->io_abd != NULL) + abd_put(zio->io_abd); } static int @@ -2213,11 +2219,12 @@ zio_write_gang_block(zio_t *pio) int gbh_copies = MIN(copies + 1, spa_max_replication(spa)); zio_prop_t zp; int error; + boolean_t has_data = !(pio->io_flags & ZIO_FLAG_NODATA); int flags = METASLAB_HINTBP_FAVOR | METASLAB_GANG_HEADER; if (pio->io_flags & ZIO_FLAG_IO_ALLOCATING) { ASSERT(pio->io_priority == ZIO_PRIORITY_ASYNC_WRITE); - ASSERT(!(pio->io_flags & ZIO_FLAG_NODATA)); + ASSERT(has_data); flags |= METASLAB_ASYNC_ALLOC; VERIFY(refcount_held(&mc->mc_alloc_slots[pio->io_allocator], @@ -2241,7 +2248,7 @@ zio_write_gang_block(zio_t *pio) if (error) { if (pio->io_flags & ZIO_FLAG_IO_ALLOCATING) { ASSERT(pio->io_priority == ZIO_PRIORITY_ASYNC_WRITE); - ASSERT(!(pio->io_flags & ZIO_FLAG_NODATA)); + ASSERT(has_data); /* * If we failed to allocate the gang block header then @@ -2294,14 +2301,15 @@ zio_write_gang_block(zio_t *pio) zp.zp_nopwrite = B_FALSE; zio_t *cio = zio_write(zio, spa, txg, &gbh->zg_blkptr[g], - abd_get_offset(pio->io_abd, pio->io_size - resid), lsize, - lsize, &zp, zio_write_gang_member_ready, NULL, NULL, + has_data ? abd_get_offset(pio->io_abd, pio->io_size - + resid) : NULL, lsize, lsize, &zp, + zio_write_gang_member_ready, NULL, NULL, zio_write_gang_done, &gn->gn_child[g], pio->io_priority, ZIO_GANG_CHILD_FLAGS(pio), &pio->io_bookmark); if (pio->io_flags & ZIO_FLAG_IO_ALLOCATING) { ASSERT(pio->io_priority == ZIO_PRIORITY_ASYNC_WRITE); - ASSERT(!(pio->io_flags & ZIO_FLAG_NODATA)); + ASSERT(has_data); /* * Gang children won't throttle but we should -- cgit v1.2.3 From 1946268f4b5e55d1de5a354a87463d24be6991ca Mon Sep 17 00:00:00 2001 From: George Wilson Date: Tue, 1 May 2018 12:35:48 -0600 Subject: 9680 dsl_dataset_hold_obj can leak bookmarks Reviewed by: Matt Ahrens Reviewed by: Prakash Surya Approved by: Robert Mustacchi --- usr/src/uts/common/fs/zfs/dsl_dataset.c | 1 + 1 file changed, 1 insertion(+) diff --git a/usr/src/uts/common/fs/zfs/dsl_dataset.c b/usr/src/uts/common/fs/zfs/dsl_dataset.c index a08477e29d..fd51f851c4 100644 --- a/usr/src/uts/common/fs/zfs/dsl_dataset.c +++ b/usr/src/uts/common/fs/zfs/dsl_dataset.c @@ -559,6 +559,7 @@ dsl_dataset_hold_obj(dsl_pool_t *dp, uint64_t dsobj, void *tag, dsl_deadlist_close(&ds->ds_deadlist); if (dsl_deadlist_is_open(&ds->ds_remap_deadlist)) dsl_deadlist_close(&ds->ds_remap_deadlist); + dsl_bookmark_fini_ds(ds); if (ds->ds_prev) dsl_dataset_rele(ds->ds_prev, ds); dsl_dir_rele(ds->ds_dir, ds); -- cgit v1.2.3 From e19b450bec203d8be04447ea476d7a86b36d63a1 Mon Sep 17 00:00:00 2001 From: John Gallagher Date: Thu, 28 Sep 2017 08:15:45 -0700 Subject: 8601 memory leak in get_special_prop() Reviewed by: Serapheim Dimitropoulos Reviewed by: Sara Hartse Reviewed by: Pavel Zakharov Reviewed by: Matt Ahrens Reviewed by: Robert Mustacchi Approved by: Dan McDonald --- usr/src/uts/common/fs/zfs/zcp_get.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/usr/src/uts/common/fs/zfs/zcp_get.c b/usr/src/uts/common/fs/zfs/zcp_get.c index 54e141d967..85e00a0f93 100644 --- a/usr/src/uts/common/fs/zfs/zcp_get.c +++ b/usr/src/uts/common/fs/zfs/zcp_get.c @@ -14,7 +14,7 @@ */ /* - * Copyright (c) 2016 by Delphix. All rights reserved. + * Copyright (c) 2016, 2017 by Delphix. All rights reserved. */ #include "lua.h" @@ -422,16 +422,21 @@ get_special_prop(lua_State *state, dsl_dataset_t *ds, const char *dsname, case ZFS_PROP_INCONSISTENT: numval = dsl_get_inconsistent(ds); break; - case ZFS_PROP_RECEIVE_RESUME_TOKEN: - VERIFY3U(strlcpy(strval, get_receive_resume_stats_impl(ds), - ZAP_MAXVALUELEN), <, ZAP_MAXVALUELEN); + case ZFS_PROP_RECEIVE_RESUME_TOKEN: { + char *token = get_receive_resume_stats_impl(ds); + VERIFY3U(strlcpy(strval, token, ZAP_MAXVALUELEN), <, + ZAP_MAXVALUELEN); + strfree(token); if (strcmp(strval, "") == 0) { - VERIFY3U(strlcpy(strval, get_child_receive_stats(ds), - ZAP_MAXVALUELEN), <, ZAP_MAXVALUELEN); + token = get_child_receive_stats(ds); + VERIFY3U(strlcpy(strval, token, ZAP_MAXVALUELEN), <, + ZAP_MAXVALUELEN); + strfree(token); if (strcmp(strval, "") == 0) error = ENOENT; } break; + } case ZFS_PROP_VOLSIZE: ASSERT(ds_type == ZFS_TYPE_VOLUME); error = dmu_objset_from_ds(ds, &os); -- cgit v1.2.3 From 7928f4baf4ab3230557eb6289be68aa7a3003f38 Mon Sep 17 00:00:00 2001 From: Matthew Ahrens Date: Tue, 12 Dec 2017 15:46:58 -0800 Subject: 9617 too-frequent TXG sync causes excessive write inflation Reviewed by: Serapheim Dimitropoulos Reviewed by: Brad Lewis Reviewed by: George Wilson Reviewed by: Andrew Stormont Approved by: Robert Mustacchi --- usr/src/uts/common/fs/zfs/dsl_pool.c | 10 +++++++--- usr/src/uts/common/fs/zfs/sys/dsl_pool.h | 2 +- usr/src/uts/common/fs/zfs/txg.c | 4 +++- 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/usr/src/uts/common/fs/zfs/dsl_pool.c b/usr/src/uts/common/fs/zfs/dsl_pool.c index 9f9111efa2..2a9ec5585a 100644 --- a/usr/src/uts/common/fs/zfs/dsl_pool.c +++ b/usr/src/uts/common/fs/zfs/dsl_pool.c @@ -103,9 +103,11 @@ uint64_t zfs_dirty_data_max_max = 4ULL * 1024 * 1024 * 1024; int zfs_dirty_data_max_percent = 10; /* - * If there is at least this much dirty data, push out a txg. + * If there's at least this much dirty data (as a percentage of + * zfs_dirty_data_max), push out a txg. This should be less than + * zfs_vdev_async_write_active_min_dirty_percent. */ -uint64_t zfs_dirty_data_sync = 64 * 1024 * 1024; +uint64_t zfs_dirty_data_sync_pct = 20; /* * Once there is this amount of dirty data, the dmu_tx_delay() will kick in @@ -824,10 +826,12 @@ dsl_pool_need_dirty_delay(dsl_pool_t *dp) { uint64_t delay_min_bytes = zfs_dirty_data_max * zfs_delay_min_dirty_percent / 100; + uint64_t dirty_min_bytes = + zfs_dirty_data_max * zfs_dirty_data_sync_pct / 100; boolean_t rv; mutex_enter(&dp->dp_lock); - if (dp->dp_dirty_total > zfs_dirty_data_sync) + if (dp->dp_dirty_total > dirty_min_bytes) txg_kick(dp); rv = (dp->dp_dirty_total > delay_min_bytes); mutex_exit(&dp->dp_lock); diff --git a/usr/src/uts/common/fs/zfs/sys/dsl_pool.h b/usr/src/uts/common/fs/zfs/sys/dsl_pool.h index 2df0f21f98..c79c5bf735 100644 --- a/usr/src/uts/common/fs/zfs/sys/dsl_pool.h +++ b/usr/src/uts/common/fs/zfs/sys/dsl_pool.h @@ -53,7 +53,7 @@ struct dsl_scan; extern uint64_t zfs_dirty_data_max; extern uint64_t zfs_dirty_data_max_max; -extern uint64_t zfs_dirty_data_sync; +extern uint64_t zfs_dirty_data_sync_pct; extern int zfs_dirty_data_max_percent; extern int zfs_delay_min_dirty_percent; extern uint64_t zfs_delay_scale; diff --git a/usr/src/uts/common/fs/zfs/txg.c b/usr/src/uts/common/fs/zfs/txg.c index 743b914a20..48e1c682cb 100644 --- a/usr/src/uts/common/fs/zfs/txg.c +++ b/usr/src/uts/common/fs/zfs/txg.c @@ -484,6 +484,8 @@ txg_sync_thread(void *arg) uint64_t timeout = zfs_txg_timeout * hz; uint64_t timer; uint64_t txg; + uint64_t dirty_min_bytes = + zfs_dirty_data_max * zfs_dirty_data_sync_pct / 100; /* * We sync when we're scanning, there's someone waiting @@ -495,7 +497,7 @@ txg_sync_thread(void *arg) !tx->tx_exiting && timer > 0 && tx->tx_synced_txg >= tx->tx_sync_txg_waiting && !txg_has_quiesced_to_sync(dp) && - dp->dp_dirty_total < zfs_dirty_data_sync) { + dp->dp_dirty_total < dirty_min_bytes) { dprintf("waiting; tx_synced=%llu waiting=%llu dp=%p\n", tx->tx_synced_txg, tx->tx_sync_txg_waiting, dp); txg_thread_wait(tx, &cpr, &tx->tx_sync_more_cv, timer); -- cgit v1.2.3