Ejemplo n.º 1
0
/*
 * If an asru has a unum string that is an hc path string then return
 * a new nvl (to be freed by the caller) that is a duplicate of the
 * original but with an additional member of a reconstituted hc fmri.
 */
int
mem_unum_rewrite(nvlist_t *nvl, nvlist_t **rnvl)
{
	int err;
	char *unumstr;
	nvlist_t *unum;
	struct topo_hdl *thp;

	if (nvlist_lookup_string(nvl, FM_FMRI_MEM_UNUM, &unumstr) != 0 ||
	    !ISHCUNUM(unumstr))
		return (0);

	if ((thp = fmd_fmri_topo_hold(TOPO_VERSION)) == NULL)
		return (EINVAL);

	if (topo_fmri_str2nvl(thp, unumstr, &unum, &err) != 0) {
		fmd_fmri_topo_rele(thp);
		return (EINVAL);
	}

	fmd_fmri_topo_rele(thp);

	if ((err = nvlist_dup(nvl, rnvl, 0)) != 0) {
		nvlist_free(unum);
		return (err);
	}

	err = nvlist_add_nvlist(*rnvl, FM_FMRI_MEM_UNUM "-fmri", unum);
	nvlist_free(unum);

	if (err != 0)
		nvlist_free(*rnvl);

	return (err);
}
Ejemplo n.º 2
0
/*
 * Convert a shorthand svc FMRI into a full svc FMRI nvlist
 */
static nvlist_t *
shortfmri_to_fmri(fmd_hdl_t *hdl, const char *shortfmristr)
{
	nvlist_t *ret, *fmri;
	topo_hdl_t *thp;
	char *fmristr;
	int err;

	if ((fmristr = shortfmri_to_fmristr(hdl, shortfmristr)) == NULL)
		return (NULL);

	thp = fmd_hdl_topo_hold(hdl, TOPO_VERSION);

	if (topo_fmri_str2nvl(thp, fmristr, &fmri, &err) != 0) {
		fmd_hdl_error(hdl, "failed to convert '%s' to nvlist\n",
		    fmristr);
		fmd_hdl_strfree(hdl, fmristr);
		fmd_hdl_topo_rele(hdl, thp);
		return (NULL);
	}

	fmd_hdl_strfree(hdl, fmristr);

	if ((ret = fmd_nvl_dup(hdl, fmri, FMD_SLEEP)) == NULL) {
		fmd_hdl_error(hdl, "failed to dup fmri\n");
		nvlist_free(fmri);
		fmd_hdl_topo_rele(hdl, thp);
		return (NULL);
	}

	nvlist_free(fmri);
	fmd_hdl_topo_rele(hdl, thp);

	return (ret);
}
Ejemplo n.º 3
0
static void
set_prop(topo_hdl_t *thp, tnode_t *node, nvlist_t *fmri, struct prop_args *pp)
{
	int ret, err = 0;
	topo_type_t type;
	nvlist_t *nvl, *f = NULL;
	char *end;

	if (pp->prop == NULL || pp->type == NULL || pp->value == NULL)
		return;

	if ((type = str2type(pp->type)) == TOPO_TYPE_INVALID) {
		(void) fprintf(stderr, "%s: invalid property type %s for %s\n",
		    g_pname, pp->type, pp->prop);
		return;
	}

	if (nvlist_alloc(&nvl, NV_UNIQUE_NAME, 0) != 0) {
		(void) fprintf(stderr, "%s: nvlist allocation failed for "
		    "%s=%s:%s\n", g_pname, pp->prop, pp->type, pp->value);
		return;
	}
	ret = nvlist_add_string(nvl, TOPO_PROP_VAL_NAME, pp->prop);
	ret |= nvlist_add_uint32(nvl, TOPO_PROP_VAL_TYPE, type);
	if (ret != 0) {
		(void) fprintf(stderr, "%s: invalid property type %s for %s\n",
		    g_pname, pp->type, pp->prop);
		nvlist_free(nvl);
		return;
	}

	errno = 0;
	switch (type) {
		case TOPO_TYPE_INT32:
		{
			int32_t val;

			val = strtol(pp->value, &end, 0);
			if (errno == ERANGE) {
				ret = -1;
				break;
			}
			ret = nvlist_add_int32(nvl, TOPO_PROP_VAL_VAL, val);
			break;
		}
		case TOPO_TYPE_UINT32:
		{
			uint32_t val;

			val = strtoul(pp->value, &end, 0);
			if (errno == ERANGE) {
				ret = -1;
				break;
			}
			ret = nvlist_add_uint32(nvl, TOPO_PROP_VAL_VAL, val);
			break;
		}
		case TOPO_TYPE_INT64:
		{
			int64_t val;

			val = strtoll(pp->value, &end, 0);
			if (errno == ERANGE) {
				ret = -1;
				break;
			}
			ret = nvlist_add_int64(nvl, TOPO_PROP_VAL_VAL, val);
			break;
		}
		case TOPO_TYPE_UINT64:
		{
			uint64_t val;

			val = strtoull(pp->value, &end, 0);
			if (errno == ERANGE) {
				ret = -1;
				break;
			}
			ret = nvlist_add_uint64(nvl, TOPO_PROP_VAL_VAL, val);
			break;
		}
		case TOPO_TYPE_STRING:
		{
			ret = nvlist_add_string(nvl, TOPO_PROP_VAL_VAL,
			    pp->value);
			break;
		}
		case TOPO_TYPE_FMRI:
		{
			if ((ret = topo_fmri_str2nvl(thp, pp->value, &f, &err))
			    < 0)
				break;

			if ((ret = nvlist_add_nvlist(nvl, TOPO_PROP_VAL_VAL,
			    f)) != 0)
				err = ETOPO_PROP_NVL;
			break;
		}
		default:
			ret = -1;
	}

	if (ret != 0) {
		(void) fprintf(stderr, "%s: unable to set property value for "
		    "%s: %s\n", g_pname, pp->prop,  topo_strerror(err));
		nvlist_free(nvl);
		return;
	}

	if (node != NULL) {
		if (topo_prop_setprop(node, pp->group, nvl, TOPO_PROP_MUTABLE,
		    f, &ret) < 0) {
			(void) fprintf(stderr, "%s: unable to set property "
			    "value for " "%s=%s:%s: %s\n", g_pname, pp->prop,
			    pp->type, pp->value, topo_strerror(ret));
			nvlist_free(nvl);
			nvlist_free(f);
			return;
		}
	} else {
		if (topo_fmri_setprop(thp, fmri,  pp->group, nvl,
		    TOPO_PROP_MUTABLE, f, &ret) < 0) {
			(void) fprintf(stderr, "%s: unable to set property "
			    "value for " "%s=%s:%s: %s\n", g_pname, pp->prop,
			    pp->type, pp->value, topo_strerror(ret));
			nvlist_free(nvl);
			nvlist_free(f);
			return;
		}
	}

	nvlist_free(nvl);

	/*
	 * Now, get the property back for printing
	 */
	if (node != NULL) {
		if (topo_prop_getprop(node, pp->group, pp->prop, f, &nvl,
		    &err) < 0) {
			(void) fprintf(stderr, "%s: failed to get %s.%s: %s\n",
			    g_pname, pp->group, pp->prop, topo_strerror(err));
			nvlist_free(f);
			return;
		}
	} else {
		if (topo_fmri_getprop(thp, fmri, pp->group, pp->prop,
		    f, &nvl, &err) < 0) {
			(void) fprintf(stderr, "%s: failed to get %s.%s: %s\n",
			    g_pname, pp->group, pp->prop, topo_strerror(err));
			nvlist_free(f);
			return;
		}
	}

	print_pgroup(thp, node, pp->group, NULL, NULL, 0);
	print_prop_nameval(thp, node, nvl);
	nvlist_free(nvl);

	nvlist_free(f);
}
Ejemplo n.º 4
0
void
print_fmri(topo_hdl_t *thp, char *uuid)
{
	int ret, err;
	nvlist_t *nvl;
	char buf[32];
	time_t tod = time(NULL);

	if (topo_fmri_str2nvl(thp, g_fmri, &nvl, &err) < 0) {
		(void) fprintf(stderr, "%s: failed to convert %s to nvlist: "
		    "%s\n", g_pname, g_fmri, topo_strerror(err));
		return;
	}

	(void) printf("TIME                 UUID\n");
	(void) strftime(buf, sizeof (buf), "%b %d %T", localtime(&tod));
	(void) printf("%-15s %-32s\n", buf, uuid);
	(void) printf("\n");

	(void) printf("%s\n", (char *)g_fmri);

	if (opt_p && !(pcnt > 0 || opt_V || opt_all)) {
		char *aname = NULL, *fname = NULL, *lname = NULL;
		nvlist_t *asru = NULL;
		nvlist_t *fru = NULL;

		if (topo_fmri_asru(thp, nvl, &asru, &err) == 0)
			(void) topo_fmri_nvl2str(thp, asru, &aname, &err);
		if (topo_fmri_fru(thp, nvl, &fru, &err) == 0)
			(void) topo_fmri_nvl2str(thp, fru, &fname, &err);
		(void) topo_fmri_label(thp, nvl, &lname, &err);

		nvlist_free(fru);
		nvlist_free(asru);

		if (aname != NULL) {
			(void) printf("\tASRU: %s\n", aname);
			topo_hdl_strfree(thp, aname);
		} else {
			(void) printf("\tASRU: -\n");
		}
		if (fname != NULL) {
			(void) printf("\tFRU: %s\n", fname);
			topo_hdl_strfree(thp, fname);
		} else {
			(void) printf("\tFRU: -\n");
		}
		if (lname != NULL) {
			(void) printf("\tLabel: %s\n", lname);
			topo_hdl_strfree(thp, lname);
		} else {
			(void) printf("\tLabel: -\n");
		}
	}

	if (opt_S) {
		if (topo_fmri_str2nvl(thp, g_fmri, &nvl, &err) < 0) {
			(void) printf("\tPresent: -\n");
			(void) printf("\tUnusable: -\n");
			return;
		}

		if ((ret = topo_fmri_present(thp, nvl, &err)) < 0)
			(void) printf("\tPresent: -\n");
		else
			(void) printf("\tPresent: %s\n",
			    ret ? "true" : "false");

		if ((ret = topo_fmri_unusable(thp, nvl, &err)) < 0)
			(void) printf("\tUnusable: -\n");
		else
			(void) printf("\tUnusable: %s\n",
			    ret ? "true" : "false");

		nvlist_free(nvl);
	}

	if (pargs && pcnt > 0)
		print_fmri_props(thp, nvl);
}
Ejemplo n.º 5
0
/*
 * Solve a given ZFS case.  This first checks to make sure the diagnosis is
 * still valid, as well as cleaning up any pending timer associated with the
 * case.
 */
static void
zfs_case_solve(fmd_hdl_t *hdl, zfs_case_t *zcp, const char *faultname,
    boolean_t checkunusable)
{
	libzfs_handle_t *zhdl = fmd_hdl_getspecific(hdl);
	nvlist_t *detector, *fault;
	boolean_t serialize;
	nvlist_t *fmri, *fru;
	topo_hdl_t *thp;
	int err;

	/*
	 * Construct the detector from the case data.  The detector is in the
	 * ZFS scheme, and is either the pool or the vdev, depending on whether
	 * this is a vdev or pool fault.
	 */
	detector = fmd_nvl_alloc(hdl, FMD_SLEEP);

	(void) nvlist_add_uint8(detector, FM_VERSION, ZFS_SCHEME_VERSION0);
	(void) nvlist_add_string(detector, FM_FMRI_SCHEME, FM_FMRI_SCHEME_ZFS);
	(void) nvlist_add_uint64(detector, FM_FMRI_ZFS_POOL,
	    zcp->zc_data.zc_pool_guid);
	if (zcp->zc_data.zc_vdev_guid != 0) {
		(void) nvlist_add_uint64(detector, FM_FMRI_ZFS_VDEV,
		    zcp->zc_data.zc_vdev_guid);
	}

	/*
	 * We also want to make sure that the detector (pool or vdev) properly
	 * reflects the diagnosed state, when the fault corresponds to internal
	 * ZFS state (i.e. not checksum or I/O error-induced).  Otherwise, a
	 * device which was unavailable early in boot (because the driver/file
	 * wasn't available) and is now healthy will be mis-diagnosed.
	 */
	if (!fmd_nvl_fmri_present(hdl, detector) ||
	    (checkunusable && !fmd_nvl_fmri_unusable(hdl, detector))) {
		fmd_case_close(hdl, zcp->zc_case);
		nvlist_free(detector);
		return;
	}


	fru = NULL;
	if (zcp->zc_fru != NULL &&
	    (thp = fmd_hdl_topo_hold(hdl, TOPO_VERSION)) != NULL) {
		/*
		 * If the vdev had an associated FRU, then get the FRU nvlist
		 * from the topo handle and use that in the suspect list.  We
		 * explicitly lookup the FRU because the fmri reported from the
		 * kernel may not have up to date details about the disk itself
		 * (serial, part, etc).
		 */
		if (topo_fmri_str2nvl(thp, zcp->zc_fru, &fmri, &err) == 0) {
			/*
			 * If the disk is part of the system chassis, but the
			 * FRU indicates a different chassis ID than our
			 * current system, then ignore the error.  This
			 * indicates that the device was part of another
			 * cluster head, and for obvious reasons cannot be
			 * imported on this system.
			 */
			if (libzfs_fru_notself(zhdl, zcp->zc_fru)) {
				fmd_case_close(hdl, zcp->zc_case);
				nvlist_free(fmri);
				fmd_hdl_topo_rele(hdl, thp);
				nvlist_free(detector);
				return;
			}

			/*
			 * If the device is no longer present on the system, or
			 * topo_fmri_fru() fails for other reasons, then fall
			 * back to the fmri specified in the vdev.
			 */
			if (topo_fmri_fru(thp, fmri, &fru, &err) != 0)
				fru = fmd_nvl_dup(hdl, fmri, FMD_SLEEP);
			nvlist_free(fmri);
		}

		fmd_hdl_topo_rele(hdl, thp);
	}

	fault = fmd_nvl_create_fault(hdl, faultname, 100, detector,
	    fru, detector);
	fmd_case_add_suspect(hdl, zcp->zc_case, fault);

	nvlist_free(fru);

	fmd_case_solve(hdl, zcp->zc_case);

	serialize = B_FALSE;
	if (zcp->zc_data.zc_has_remove_timer) {
		fmd_timer_remove(hdl, zcp->zc_remove_timer);
		zcp->zc_data.zc_has_remove_timer = 0;
		serialize = B_TRUE;
	}
	if (serialize)
		zfs_case_serialize(hdl, zcp);

	nvlist_free(detector);
}