Beispiel #1
0
static int
sysev_evc_handler(sysevent_t *ev, void *cookie)
{
  char *name, *zonename, *oldstate, *newstate;
  nvlist_t *nvlist;
  nvpair_t *curr, *next;

  cookie = cookie; // SILENCE!

  if (sysevent_get_attr_list(ev, &nvlist) != 0) {
    // XXX Error
    return (1);
  }

  // loop through event nvpairs to get our interesting values
  curr = nvlist_next_nvpair(nvlist, NULL);
  while (curr != NULL) {
    // all fields we're interested in are strings
    if (nvpair_type(curr) == DATA_TYPE_STRING) {
      name = nvpair_name(curr);

      if (strcmp(name, ZONE_CB_NAME) == 0) {
        nvpair_value_string(curr, &zonename);
      } else if (strcmp(name, ZONE_CB_NEWSTATE) == 0) {
        nvpair_value_string(curr, &newstate);
      } else if (strcmp(name, ZONE_CB_OLDSTATE) == 0) {
        nvpair_value_string(curr, &oldstate);
      }
    }

    next = nvlist_next_nvpair(nvlist, curr);
    curr = next;
  }

  // if it is a boot into running we need to enable the gate
  if (strcmp(oldstate, ZONE_EVENT_READY) == 0 &&
      strcmp(newstate, ZONE_EVENT_RUNNING) == 0) {
    gate_attach(zonename);
  }

  // ignore multiple shutting_down -> shutting_down transitions
  if (strcmp(oldstate, newstate) != 0) {
    char zonebrand[MAXNAMELEN];

    // get brand for zone
    if (zone_get_brand(zonename, zonebrand, sizeof (zonebrand)) == Z_OK) {
      request_send_state_event(zonename, zonebrand, oldstate, newstate);
    } else {
      request_send_state_event(zonename, NULL, oldstate, newstate);
    }
  }

  return (0);
}
Beispiel #2
0
static void
get_slice_use(dm_descriptor_t slice, char *name, char **used_name,
              char **used_by, int *error)
{
    /* Get slice use statistics */
    nvlist_t *stats = dm_get_stats(slice, DM_SLICE_STAT_USE, error);
    if (*error != 0) {
        handle_error("could not get stats of slice %s", name);
    } else {

        *used_name = NULL;
        *used_by = NULL;

        if (stats != NULL) {
            char *tmp;
            nvpair_t *match;

            /* Get the type of usage for this slice */
            match = zjni_nvlist_walk_nvpair(
                        stats, DM_USED_BY, DATA_TYPE_STRING, NULL);

            if (match != NULL &&
                    nvpair_value_string(match, &tmp) == 0) {

                *used_name = strdup(tmp);
                if (*used_name == NULL) {
                    *error = -1;
                    handle_error("out of memory");
                } else {

                    /* Get the object using this slice */
                    match =
                        zjni_nvlist_walk_nvpair(stats,
                                                DM_USED_NAME, DATA_TYPE_STRING,
                                                NULL);

                    if (match != NULL &&
                            nvpair_value_string(match, &tmp) ==
                            0) {
                        *used_by = strdup(tmp);
                        if (*used_by == NULL) {
                            *error = -1;
                            handle_error(
                                "out of memory");
                        }
                    }
                }
            }
            nvlist_free(stats);
        }
    }
}
Beispiel #3
0
static void
prof_make_maps(struct sdev_node *dir)
{
	nvpair_t *nvp = NULL;
	nvlist_t *nvl = dir->sdev_prof.dev_map;
	int rv;

	ASSERT(RW_WRITE_HELD(&dir->sdev_contents));

	if (nvl == NULL)
		return;

	while (nvp = nvlist_next_nvpair(nvl, nvp)) {
		char *name;
		char *rename = nvpair_name(nvp);
		rv = nvpair_value_string(nvp, &name);
		if (rv != 0) {
			cmn_err(CE_WARN, sdev_nvp_val_err,
			    rv, nvpair_name(nvp));
			break;
		}
		sdcmn_err10(("map %s -> %s\n", name, rename));
		(void) prof_lookup_globaldev(dir, sdev_origins->sdev_root,
		    name, rename);
	}
}
Beispiel #4
0
static void
apply_glob_pattern(struct sdev_node *pdir, struct sdev_node *cdir)
{
	char *name;
	nvpair_t *nvp = NULL;
	nvlist_t *nvl;
	struct vnode *vp = SDEVTOV(cdir);
	int rv = 0;

	if (vp->v_type != VDIR)
		return;
	name = cdir->sdev_name;
	nvl = pdir->sdev_prof.dev_glob_incdir;
	while (nvp = nvlist_next_nvpair(nvl, nvp)) {
		char *pathleft;
		char *expr = nvpair_name(nvp);
		if (!gmatch(name, expr))
			continue;
		rv = nvpair_value_string(nvp, &pathleft);
		if (rv != 0) {
			cmn_err(CE_WARN, sdev_nvp_val_err,
			    rv, nvpair_name(nvp));
			break;
		}
		process_rule(cdir, cdir->sdev_origin,
		    pathleft, NULL, PROFILE_TYPE_INCLUDE);
	}
}
Beispiel #5
0
char *
fnvpair_value_string(nvpair_t *nvp)
{
	char *rv;
	VERIFY0(nvpair_value_string(nvp, &rv));
	return (rv);
}
Beispiel #6
0
/*
 * Use the supplied nvpair_t to set the name, type and value of the
 * supplied pool_value_t.
 *
 * Return: PO_SUCCESS/PO_FAIL
 */
int
pool_value_from_nvpair(pool_value_t *pv, nvpair_t *pn)
{
	uchar_t bval;
	uint64_t uval;
	int64_t ival;
	double dval;
	uint_t nelem;
	uchar_t *dval_b;
	char *sval;

	if (pool_value_set_name(pv, nvpair_name(pn)) != PO_SUCCESS)
		return (PO_FAIL);
	switch (nvpair_type(pn)) {
	case DATA_TYPE_BYTE:
		if (nvpair_value_byte(pn, &bval) != 0) {
			pool_seterror(POE_SYSTEM);
			return (PO_FAIL);
		}
		pool_value_set_bool(pv, bval);
		break;
	case DATA_TYPE_BYTE_ARRAY:
		if (nvpair_value_byte_array(pn, &dval_b, &nelem) != 0) {
			pool_seterror(POE_SYSTEM);
			return (PO_FAIL);
		}
		(void) memcpy(&dval, dval_b, sizeof (double));
		pool_value_set_double(pv, dval);
		break;
	case DATA_TYPE_INT64:
		if (nvpair_value_int64(pn, &ival) != 0) {
			pool_seterror(POE_SYSTEM);
			return (PO_FAIL);
		}
		pool_value_set_int64(pv, ival);
		break;
	case DATA_TYPE_UINT64:
		if (nvpair_value_uint64(pn, &uval) != 0) {
			pool_seterror(POE_SYSTEM);
			return (PO_FAIL);
		}
		pool_value_set_uint64(pv, uval);
		break;
	case DATA_TYPE_STRING:
		if (nvpair_value_string(pn, &sval) != 0) {
			pool_seterror(POE_SYSTEM);
			return (PO_FAIL);
		}
		if (pool_value_set_string(pv, sval) != PO_SUCCESS)
			return (PO_FAIL);
		break;
	default:
		pool_seterror(POE_SYSTEM);
		return (PO_FAIL);
	}
	return (PO_SUCCESS);
}
Beispiel #7
0
/*
 * Goes through the ini property list and validates
 * each entry.  If errs is non-NULL, will return explicit errors
 * for each property that fails validation.
 */
static int
it_validate_iniprops(nvlist_t *nvl, nvlist_t *errs)
{
	int				errcnt = 0;
	nvpair_t			*nvp = NULL;
	data_type_t			nvtype;
	char				*name;
	char				*val;

	if (!nvl) {
		return (0);
	}

	while ((nvp = nvlist_next_nvpair(nvl, nvp)) != NULL) {
		name = nvpair_name(nvp);
		nvtype = nvpair_type(nvp);

		if (!name) {
			continue;
		}

		if (strcmp(name, PROP_CHAP_USER) == 0) {
			if (nvtype != DATA_TYPE_STRING) {
				PROPERR(errs, name,
				    gettext("must be a string value"));
				errcnt++;
				continue;
			}
		} else if (strcmp(name, PROP_CHAP_SECRET) == 0) {
			/*
			 * must be between 12 and 255 chars in cleartext.
			 * will be base64 encoded when it's set.
			 */
			if (nvtype == DATA_TYPE_STRING) {
				val = NULL;
				(void) nvpair_value_string(nvp, &val);
			}

			if (!val) {
				PROPERR(errs, name,
				    gettext("must be a string value"));
				errcnt++;
				continue;
			}
		} else {
			/* unrecognized property */
			PROPERR(errs, name, gettext("unrecognized property"));
			errcnt++;
		}
	}

	if (errcnt) {
		return (EINVAL);
	}

	return (0);
}
Beispiel #8
0
static PyObject *
nvl2py(nvlist_t *nvl)
{
	PyObject *pyo;
	nvpair_t *nvp;

	pyo = PyDict_New();

	for (nvp = nvlist_next_nvpair(nvl, NULL); nvp;
	    nvp = nvlist_next_nvpair(nvl, nvp)) {
		PyObject *pyval;
		char *sval;
		uint64_t ival;
		boolean_t bval;
		nvlist_t *nval;

		switch (nvpair_type(nvp)) {
		case DATA_TYPE_STRING:
			(void) nvpair_value_string(nvp, &sval);
			pyval = Py_BuildValue("s", sval);
			break;

		case DATA_TYPE_UINT64:
			(void) nvpair_value_uint64(nvp, &ival);
			pyval = Py_BuildValue("K", ival);
			break;

		case DATA_TYPE_NVLIST:
			(void) nvpair_value_nvlist(nvp, &nval);
			pyval = nvl2py(nval);
			break;

		case DATA_TYPE_BOOLEAN:
			Py_INCREF(Py_None);
			pyval = Py_None;
			break;

		case DATA_TYPE_BOOLEAN_VALUE:
			(void) nvpair_value_boolean_value(nvp, &bval);
			pyval = Py_BuildValue("i", bval);
			break;

		default:
			PyErr_SetNone(PyExc_ValueError);
			Py_DECREF(pyo);
			return (NULL);
		}

		PyDict_SetItemString(pyo, nvpair_name(nvp), pyval);
		Py_DECREF(pyval);
	}

	return (pyo);
}
Beispiel #9
0
/* Check if name passes matching rules */
int
prof_name_matched(char *name, struct sdev_node *dir)
{
	int type, match = 0;
	char *expr;
	nvlist_t *nvl;
	nvpair_t *nvp = NULL;
	int rv;

	/* check against nvlist for leaf include/exclude */
	nvl = dir->sdev_prof.dev_name;
	while (nvp = nvlist_next_nvpair(nvl, nvp)) {
		expr = nvpair_name(nvp);
		rv = nvpair_value_int32(nvp, &type);
		if (rv != 0) {
			cmn_err(CE_WARN, sdev_nvp_val_err,
			    rv, nvpair_name(nvp));
			break;
		}

		if (type == PROFILE_TYPE_EXCLUDE) {
			if (gmatch(name, expr))
				return (0);	/* excluded */
		} else if (!match) {
			match = gmatch(name, expr);
		}
	}
	if (match) {
		sdcmn_err10(("prof_name_matched: %s\n", name));
		return (match);
	}

	/* check for match against directory globbing pattern */
	nvl = dir->sdev_prof.dev_glob_incdir;
	while (nvp = nvlist_next_nvpair(nvl, nvp)) {
		char *pathleft;
		expr = nvpair_name(nvp);
		if (gmatch(name, expr) == 0)
			continue;
		rv = nvpair_value_string(nvp, &pathleft);
		if (rv != 0) {
			cmn_err(CE_WARN, sdev_nvp_val_err,
			    rv, nvpair_name(nvp));
			break;
		}
		if (is_nonempty_dir(name, pathleft, dir)) {
			sdcmn_err10(("prof_name_matched: dir %s\n", name));
			return (1);
		}
	}

	return (0);
}
Beispiel #10
0
static int
dsl_dataset_user_hold_check(void *arg, dmu_tx_t *tx)
{
	dsl_dataset_user_hold_arg_t *dduha = arg;
	dsl_pool_t *dp = dmu_tx_pool(tx);
	nvpair_t *pair;

	if (spa_version(dp->dp_spa) < SPA_VERSION_USERREFS)
		return (SET_ERROR(ENOTSUP));

	if (!dmu_tx_is_syncing(tx))
		return (0);

	for (pair = nvlist_next_nvpair(dduha->dduha_holds, NULL);
	    pair != NULL; pair = nvlist_next_nvpair(dduha->dduha_holds, pair)) {
		dsl_dataset_t *ds;
		int error = 0;
		char *htag, *name;

		/* must be a snapshot */
		name = nvpair_name(pair);
		if (strchr(name, '@') == NULL)
			error = SET_ERROR(EINVAL);

		if (error == 0)
			error = nvpair_value_string(pair, &htag);

		if (error == 0)
			error = dsl_dataset_hold(dp, name, FTAG, &ds);

		if (error == 0) {
			error = dsl_dataset_user_hold_check_one(ds, htag,
			    dduha->dduha_minor != 0, tx);
			dsl_dataset_rele(ds, FTAG);
		}

		if (error == 0) {
			fnvlist_add_string(dduha->dduha_chkholds, name, htag);
		} else {
			/*
			 * We register ENOENT errors so they can be correctly
			 * reported if needed, such as when all holds fail.
			 */
			fnvlist_add_int32(dduha->dduha_errlist, name, error);
			if (error != ENOENT)
				return (error);
		}
	}

	return (0);
}
Beispiel #11
0
/*
 * This is invoked after a new filesystem is mounted to define the
 * name space. It is also invoked during normal system operation
 * to update the name space.
 *
 * Applications call di_prof_commit() in libdevinfo, which invokes
 * modctl(). modctl calls this function. The input is a packed nvlist.
 */
int
devname_profile_update(char *packed, size_t packed_sz)
{
	char *mntpt;
	nvlist_t *nvl;
	nvpair_t *nvp;
	struct sdev_data *mntinfo;
	int err;
	int rv;

	nvl = NULL;
	if ((err = copyin_nvlist(packed, packed_sz, &nvl)) != 0)
		return (err);
	ASSERT(nvl);

	/* The first nvpair must be the mount point */
	nvp = nvlist_next_nvpair(nvl, NULL);
	if (strcmp(nvpair_name(nvp), SDEV_NVNAME_MOUNTPT) != 0) {
		cmn_err(CE_NOTE,
		    "devname_profile_update: mount point not specified");
		nvlist_free(nvl);
		return (EINVAL);
	}

	/* find the matching filesystem instance */
	rv = nvpair_value_string(nvp, &mntpt);
	if (rv != 0) {
		cmn_err(CE_WARN, sdev_nvp_val_err,
		    rv, nvpair_name(nvp));
	} else {
		mntinfo = sdev_find_mntinfo(mntpt);
		if (mntinfo == NULL) {
			cmn_err(CE_NOTE, "devname_profile_update: "
			    " mount point %s not found", mntpt);
			nvlist_free(nvl);
			return (EINVAL);
		}

		/* now do the hardwork to process the profile */
		sdev_process_profile(mntinfo, nvl);

		sdev_mntinfo_rele(mntinfo);
	}

	nvlist_free(nvl);
	return (0);
}
Beispiel #12
0
/*
 * Put new CPU property.
 * Handle special case of "cpu.status".
 */
int
pool_cpu_propput(processorid_t cpuid, nvpair_t *pair)
{
	int ret = 0;
	cpu_t *cpu;

	ASSERT(pool_lock_held());
	ASSERT(INGLOBALZONE(curproc));

	if (nvpair_type(pair) == DATA_TYPE_STRING &&
	    strcmp(nvpair_name(pair), "cpu.status") == 0) {
		char *val;
		int status;
		int old_status;
		(void) nvpair_value_string(pair, &val);
		if (strcmp(val, PS_OFFLINE) == 0)
			status = P_OFFLINE;
		else if (strcmp(val, PS_ONLINE) == 0)
			status = P_ONLINE;
		else if (strcmp(val, PS_NOINTR) == 0)
			status = P_NOINTR;
		else if (strcmp(val, PS_FAULTED) == 0)
			status = P_FAULTED;
		else if (strcmp(val, PS_SPARE) == 0)
			status = P_SPARE;
		else
			return (EINVAL);
		ret = p_online_internal(cpuid, status, &old_status);
	} else {
		mutex_enter(&cpu_lock);
		if ((cpu = cpu_get(cpuid)) == NULL)
			ret = EINVAL;
		if (cpu->cpu_props == NULL) {
			(void) nvlist_alloc(&cpu->cpu_props,
			    NV_UNIQUE_NAME, KM_SLEEP);
			(void) nvlist_add_string(cpu->cpu_props,
			    "cpu.comment", "");
		}
		ret = pool_propput_common(cpu->cpu_props, pair, pool_cpu_props);
		if (ret == 0)
			pool_cpu_mod = gethrtime();
		mutex_exit(&cpu_lock);
	}
	return (ret);
}
Beispiel #13
0
/* Ensure that "None" is an option in the digest list, and select it */
static kv_status_t
iser_handle_digest(nvpair_t *choices, const idm_kv_xlate_t *ikvx,
                   nvlist_t *request_nvl, nvlist_t *response_nvl, nvlist_t *negotiated_nvl)
{
    kv_status_t		kvrc = KV_VALUE_ERROR;
    int			nvrc = 0;
    nvpair_t		*digest_choice;
    char			*digest_choice_string;

    /*
     * Loop through all digest choices.  We need to enforce no
     * "None" for both header and data digest.  If we find our
     * required value, add the value to our negotiated values list
     * and respond with that value in the login response. If not,
     * indicate a value error for the iSCSI layer to work with.
     */
    digest_choice = idm_get_next_listvalue(choices, NULL);
    while (digest_choice != NULL) {
        nvrc = nvpair_value_string(digest_choice,
                                   &digest_choice_string);
        ASSERT(nvrc == 0);

        if (strcasecmp(digest_choice_string, "none") == 0) {

            /* Add to negotiated values list */
            nvrc = nvlist_add_string(negotiated_nvl,
                                     ikvx->ik_key_name, digest_choice_string);
            kvrc = idm_nvstat_to_kvstat(nvrc);
            if (nvrc == 0) {
                /* Add to login response list */
                nvrc = nvlist_add_string(response_nvl,
                                         ikvx->ik_key_name, digest_choice_string);
                kvrc = idm_nvstat_to_kvstat(nvrc);
                /* Remove from the request (we've handled it) */
                (void) nvlist_remove_all(request_nvl,
                                         ikvx->ik_key_name);
            }
            break;
        }
        digest_choice = idm_get_next_listvalue(choices,
                                               digest_choice);
    }

    return (kvrc);
}
Beispiel #14
0
/*
 * Get the named string from the given nvlist_t.
 *
 * @param       attrs
 *              the nvlist_t to search
 *
 * @param       which
 *              the string key for this element in the list
 *
 * @param       str
 *              RETURN: the requested string
 *
 * @return      0
 *              if successful
 *
 * @return      ENOENT
 *              if no matching name-value pair is found
 */
int
get_string(
    nvlist_t *attrs,
    char *which,
    char **str)
{
    int error;
    nvpair_t *match =
        nvlist_walk_nvpair(attrs, which, DATA_TYPE_STRING, NULL);

    if (match == NULL) {
        error = ENOENT;
    } else {
        error = nvpair_value_string(match, str);
    }

    return (error);
}
Beispiel #15
0
static int
dsl_dataset_user_hold_check(void *arg, dmu_tx_t *tx)
{
	dsl_dataset_user_hold_arg_t *dduha = arg;
	dsl_pool_t *dp = dmu_tx_pool(tx);
	nvpair_t *pair;
	int rv = 0;

	if (spa_version(dp->dp_spa) < SPA_VERSION_USERREFS)
		return (ENOTSUP);

	for (pair = nvlist_next_nvpair(dduha->dduha_holds, NULL); pair != NULL;
	    pair = nvlist_next_nvpair(dduha->dduha_holds, pair)) {
		int error = 0;
		dsl_dataset_t *ds;
		char *htag;

		/* must be a snapshot */
		if (strchr(nvpair_name(pair), '@') == NULL)
			error = EINVAL;

		if (error == 0)
			error = nvpair_value_string(pair, &htag);
		if (error == 0) {
			error = dsl_dataset_hold(dp,
			    nvpair_name(pair), FTAG, &ds);
		}
		if (error == 0) {
			error = dsl_dataset_user_hold_check_one(ds, htag,
			    dduha->dduha_minor != 0, tx);
			dsl_dataset_rele(ds, FTAG);
		}

		if (error != 0) {
			rv = error;
			fnvlist_add_int32(dduha->dduha_errlist,
			    nvpair_name(pair), error);
		}
	}
	return (rv);
}
Beispiel #16
0
static void cvt_string(nvlist_t *nvl, nvpair_t *pair, data_type_t tgt)
{
	const char *name = nvpair_name(pair);
	uint64_t intval;
	char *str;
	int ret;

	ASSERT3U(nvpair_type(pair), ==, DATA_TYPE_STRING);

	ret = nvpair_value_string(pair, &str);
	if (ret)
		return;

	switch (tgt) {
		case DATA_TYPE_UINT64:
			ret = str2u64(str, &intval);
			if (!ret)
				nvl_set_int(nvl, name, intval);
			break;
		default:
			panic("unexpected target type");
	}
}
Beispiel #17
0
/*
 * This method builds values for "sharesmb" property from the
 * nvlist argument. The values are returned in sharesmb_val variable.
 */
static int
sa_zfs_sprintf_new_prop(nvlist_t *nvl, char *sharesmb_val)
{
	char cur_val[MAXPATHLEN];
	char *name, *val;
	nvpair_t *cur;
	int err = 0;

	cur = nvlist_next_nvpair(nvl, NULL);
	while (cur != NULL) {
		name = nvpair_name(cur);
		err = nvpair_value_string(cur, &val);
		if ((err != 0) || (name == NULL) || (val == NULL))
			return (-1);

		(void) snprintf(cur_val, MAXPATHLEN, "%s=%s,", name, val);
		(void) strlcat(sharesmb_val, cur_val, MAXPATHLEN);

		cur = nvlist_next_nvpair(nvl, cur);
	}

	return (0);
}
Beispiel #18
0
/*
 * Create symlinks in the current directory based on profile
 */
static void
prof_make_symlinks(struct sdev_node *dir)
{
	char *tgt, *lnm;
	nvpair_t *nvp = NULL;
	nvlist_t *nvl = dir->sdev_prof.dev_symlink;
	int rv;

	ASSERT(RW_WRITE_HELD(&dir->sdev_contents));

	if (nvl == NULL)
		return;

	while (nvp = nvlist_next_nvpair(nvl, nvp)) {
		lnm = nvpair_name(nvp);
		rv = nvpair_value_string(nvp, &tgt);
		if (rv != 0) {
			cmn_err(CE_WARN, sdev_nvp_val_err,
			    rv, nvpair_name(nvp));
			break;
		}
		prof_make_sym(dir, lnm, tgt);
	}
}
Beispiel #19
0
/*
 * Determine if string 'value' matches 'nvp' value.  The 'value' string is
 * converted, depending on the type of 'nvp', prior to match.  For numeric
 * types, a radix independent sscanf conversion of 'value' is used. If 'nvp'
 * is an array type, 'ai' is the index into the array against which we are
 * checking for match. If nvp is of DATA_TYPE_STRING*, the caller can pass
 * in a regex_t compilation of value in 'value_regex' to trigger regular
 * expression string match instead of simple strcmp().
 *
 * Return 1 on match, 0 on no-match, and -1 on error.  If the error is
 * related to value syntax error and 'ep' is non-NULL, *ep will point into
 * the 'value' string at the location where the error exists.
 *
 * NOTE: It may be possible to move the non-regex_t version of this into
 * common code used by library/kernel/boot.
 */
int
nvpair_value_match_regex(nvpair_t *nvp, int ai,
    char *value, regex_t *value_regex, char **ep)
{
	char	*evalue;
	uint_t	a_len;
	int	sr;

	if (ep)
		*ep = NULL;

	if ((nvp == NULL) || (value == NULL))
		return (-1);		/* error fail match - invalid args */

	/* make sure array and index combination make sense */
	if ((nvpair_type_is_array(nvp) && (ai < 0)) ||
	    (!nvpair_type_is_array(nvp) && (ai >= 0)))
		return (-1);		/* error fail match - bad index */

	/* non-string values should be single 'chunk' */
	if ((nvpair_type(nvp) != DATA_TYPE_STRING) &&
	    (nvpair_type(nvp) != DATA_TYPE_STRING_ARRAY)) {
		value += strspn(value, " \t");
		evalue = value + strcspn(value, " \t");
		if (*evalue) {
			if (ep)
				*ep = evalue;
			return (-1);	/* error fail match - syntax */
		}
	}

	sr = EOF;
	switch (nvpair_type(nvp)) {
	case DATA_TYPE_STRING: {
		char	*val;

		/* check string value for match */
		if (nvpair_value_string(nvp, &val) == 0) {
			if (value_regex) {
				if (regexec(value_regex, val,
				    (size_t)0, NULL, 0) == 0)
					return (1);	/* match */
			} else {
				if (strcmp(value, val) == 0)
					return (1);	/* match */
			}
		}
		break;
	}
	case DATA_TYPE_STRING_ARRAY: {
		char **val_array;

		/* check indexed string value of array for match */
		if ((nvpair_value_string_array(nvp, &val_array, &a_len) == 0) &&
		    (ai < a_len)) {
			if (value_regex) {
				if (regexec(value_regex, val_array[ai],
				    (size_t)0, NULL, 0) == 0)
					return (1);
			} else {
				if (strcmp(value, val_array[ai]) == 0)
					return (1);
			}
		}
		break;
	}
	case DATA_TYPE_BYTE: {
		uchar_t val, val_arg;

		/* scanf uchar_t from value and check for match */
		sr = sscanf(value, "%c", &val_arg);
		if ((sr == 1) && (nvpair_value_byte(nvp, &val) == 0) &&
		    (val == val_arg))
			return (1);
		break;
	}
	case DATA_TYPE_BYTE_ARRAY: {
		uchar_t *val_array, val_arg;


		/* check indexed value of array for match */
		sr = sscanf(value, "%c", &val_arg);
		if ((sr == 1) &&
		    (nvpair_value_byte_array(nvp, &val_array, &a_len) == 0) &&
		    (ai < a_len) &&
		    (val_array[ai] == val_arg))
			return (1);
		break;
	}
	case DATA_TYPE_INT8: {
		int8_t val, val_arg;

		/* scanf int8_t from value and check for match */
		sr = sscanf(value, "%"SCNi8, &val_arg);
		if ((sr == 1) &&
		    (nvpair_value_int8(nvp, &val) == 0) &&
		    (val == val_arg))
			return (1);
		break;
	}
	case DATA_TYPE_INT8_ARRAY: {
		int8_t *val_array, val_arg;

		/* check indexed value of array for match */
		sr = sscanf(value, "%"SCNi8, &val_arg);
		if ((sr == 1) &&
		    (nvpair_value_int8_array(nvp, &val_array, &a_len) == 0) &&
		    (ai < a_len) &&
		    (val_array[ai] == val_arg))
			return (1);
		break;
	}
	case DATA_TYPE_UINT8: {
		uint8_t val, val_arg;

		/* scanf uint8_t from value and check for match */
		sr = sscanf(value, "%"SCNi8, (int8_t *)&val_arg);
		if ((sr == 1) &&
		    (nvpair_value_uint8(nvp, &val) == 0) &&
		    (val == val_arg))
			return (1);
		break;
	}
	case DATA_TYPE_UINT8_ARRAY: {
		uint8_t *val_array, val_arg;

		/* check indexed value of array for match */
		sr = sscanf(value, "%"SCNi8, (int8_t *)&val_arg);
		if ((sr == 1) &&
		    (nvpair_value_uint8_array(nvp, &val_array, &a_len) == 0) &&
		    (ai < a_len) &&
		    (val_array[ai] == val_arg))
			return (1);
		break;
	}
	case DATA_TYPE_INT16: {
		int16_t val, val_arg;

		/* scanf int16_t from value and check for match */
		sr = sscanf(value, "%"SCNi16, &val_arg);
		if ((sr == 1) &&
		    (nvpair_value_int16(nvp, &val) == 0) &&
		    (val == val_arg))
			return (1);
		break;
	}
	case DATA_TYPE_INT16_ARRAY: {
		int16_t *val_array, val_arg;

		/* check indexed value of array for match */
		sr = sscanf(value, "%"SCNi16, &val_arg);
		if ((sr == 1) &&
		    (nvpair_value_int16_array(nvp, &val_array, &a_len) == 0) &&
		    (ai < a_len) &&
		    (val_array[ai] == val_arg))
			return (1);
		break;
	}
	case DATA_TYPE_UINT16: {
		uint16_t val, val_arg;

		/* scanf uint16_t from value and check for match */
		sr = sscanf(value, "%"SCNi16, (int16_t *)&val_arg);
		if ((sr == 1) &&
		    (nvpair_value_uint16(nvp, &val) == 0) &&
		    (val == val_arg))
			return (1);
		break;
	}
	case DATA_TYPE_UINT16_ARRAY: {
		uint16_t *val_array, val_arg;

		/* check indexed value of array for match */
		sr = sscanf(value, "%"SCNi16, (int16_t *)&val_arg);
		if ((sr == 1) &&
		    (nvpair_value_uint16_array(nvp, &val_array, &a_len) == 0) &&
		    (ai < a_len) &&
		    (val_array[ai] == val_arg))
			return (1);
		break;
	}
	case DATA_TYPE_INT32: {
		int32_t val, val_arg;

		/* scanf int32_t from value and check for match */
		sr = sscanf(value, "%"SCNi32, &val_arg);
		if ((sr == 1) &&
		    (nvpair_value_int32(nvp, &val) == 0) &&
		    (val == val_arg))
			return (1);
		break;
	}
	case DATA_TYPE_INT32_ARRAY: {
		int32_t *val_array, val_arg;

		/* check indexed value of array for match */
		sr = sscanf(value, "%"SCNi32, &val_arg);
		if ((sr == 1) &&
		    (nvpair_value_int32_array(nvp, &val_array, &a_len) == 0) &&
		    (ai < a_len) &&
		    (val_array[ai] == val_arg))
			return (1);
		break;
	}
	case DATA_TYPE_UINT32: {
		uint32_t val, val_arg;

		/* scanf uint32_t from value and check for match */
		sr = sscanf(value, "%"SCNi32, (int32_t *)&val_arg);
		if ((sr == 1) &&
		    (nvpair_value_uint32(nvp, &val) == 0) &&
		    (val == val_arg))
			return (1);
		break;
	}
	case DATA_TYPE_UINT32_ARRAY: {
		uint32_t *val_array, val_arg;

		/* check indexed value of array for match */
		sr = sscanf(value, "%"SCNi32, (int32_t *)&val_arg);
		if ((sr == 1) &&
		    (nvpair_value_uint32_array(nvp, &val_array, &a_len) == 0) &&
		    (ai < a_len) &&
		    (val_array[ai] == val_arg))
			return (1);
		break;
	}
	case DATA_TYPE_INT64: {
		int64_t val, val_arg;

		/* scanf int64_t from value and check for match */
		sr = sscanf(value, "%"SCNi64, &val_arg);
		if ((sr == 1) &&
		    (nvpair_value_int64(nvp, &val) == 0) &&
		    (val == val_arg))
			return (1);
		break;
	}
	case DATA_TYPE_INT64_ARRAY: {
		int64_t *val_array, val_arg;

		/* check indexed value of array for match */
		sr = sscanf(value, "%"SCNi64, &val_arg);
		if ((sr == 1) &&
		    (nvpair_value_int64_array(nvp, &val_array, &a_len) == 0) &&
		    (ai < a_len) &&
		    (val_array[ai] == val_arg))
				return (1);
		break;
	}
	case DATA_TYPE_UINT64: {
		uint64_t val_arg, val;

		/* scanf uint64_t from value and check for match */
		sr = sscanf(value, "%"SCNi64, (int64_t *)&val_arg);
		if ((sr == 1) &&
		    (nvpair_value_uint64(nvp, &val) == 0) &&
		    (val == val_arg))
			return (1);
		break;
	}
	case DATA_TYPE_UINT64_ARRAY: {
		uint64_t *val_array, val_arg;

		/* check indexed value of array for match */
		sr = sscanf(value, "%"SCNi64, (int64_t *)&val_arg);
		if ((sr == 1) &&
		    (nvpair_value_uint64_array(nvp, &val_array, &a_len) == 0) &&
		    (ai < a_len) &&
		    (val_array[ai] == val_arg))
			return (1);
		break;
	}
	case DATA_TYPE_BOOLEAN_VALUE: {
		boolean_t val, val_arg;

		/* scanf boolean_t from value and check for match */
		sr = sscanf(value, "%"SCNi32, &val_arg);
		if ((sr == 1) &&
		    (nvpair_value_boolean_value(nvp, &val) == 0) &&
		    (val == val_arg))
			return (1);
		break;
	}
	case DATA_TYPE_BOOLEAN_ARRAY: {
		boolean_t *val_array, val_arg;

		/* check indexed value of array for match */
		sr = sscanf(value, "%"SCNi32, &val_arg);
		if ((sr == 1) &&
		    (nvpair_value_boolean_array(nvp,
		    &val_array, &a_len) == 0) &&
		    (ai < a_len) &&
		    (val_array[ai] == val_arg))
			return (1);
		break;
	}
	case DATA_TYPE_HRTIME:
	case DATA_TYPE_NVLIST:
	case DATA_TYPE_NVLIST_ARRAY:
	case DATA_TYPE_BOOLEAN:
	case DATA_TYPE_DOUBLE:
	case DATA_TYPE_UNKNOWN:
	default:
		/*
		 * unknown/unsupported data type
		 */
		return (-1);		/* error fail match */
	}

	/*
	 * check to see if sscanf failed conversion, return approximate
	 * pointer to problem
	 */
	if (sr != 1) {
		if (ep)
			*ep = value;
		return (-1);		/* error fail match  - syntax */
	}

	return (0);			/* fail match */
}
Beispiel #20
0
static void
rcm_print_nvlist(nvlist_t *nvl)
{
	uchar_t data_byte;
	int16_t data_int16;
	uint16_t data_uint16;
	int32_t data_int32;
	uint32_t data_uint32;
	int64_t data_int64;
	uint64_t data_uint64;
	char *data_string;
	char **data_strings;
	uint_t data_nstrings;
	nvpair_t *nvp = NULL;
	int i;
	char *name;
	data_type_t type;

	rcm_log_message(RCM_TRACE3, "event attributes:\n");

	while (nvp = nvlist_next_nvpair(nvl, nvp)) {
		type = nvpair_type(nvp);
		name = nvpair_name(nvp);
		rcm_log_message(RCM_TRACE3, "\t%s(%d)=", name, type);

		switch (type) {
		case DATA_TYPE_BOOLEAN:
			rcm_log_message(RCM_TRACE3, "True (boolean)\n");
			break;

		case DATA_TYPE_BYTE:
			(void) nvpair_value_byte(nvp, &data_byte);
			rcm_log_message(RCM_TRACE3, "0x%x (byte)\n",
			    data_byte);
			break;

		case DATA_TYPE_INT16:
			(void) nvpair_value_int16(nvp, &data_int16);
			rcm_log_message(RCM_TRACE3, "0x%x (int16)\n",
			    data_int16);
			break;

		case DATA_TYPE_UINT16:
			(void) nvpair_value_uint16(nvp, &data_uint16);
			rcm_log_message(RCM_TRACE3, "0x%x (uint16)\n",
			    data_uint16);
			break;

		case DATA_TYPE_INT32:
			(void) nvpair_value_int32(nvp, &data_int32);
			rcm_log_message(RCM_TRACE3, "0x%x (int32)\n",
			    data_int32);
			break;

		case DATA_TYPE_UINT32:
			(void) nvpair_value_uint32(nvp, &data_uint32);
			rcm_log_message(RCM_TRACE3, "0x%x (uint32)\n",
			    data_uint32);
			break;

		case DATA_TYPE_INT64:
			(void) nvpair_value_int64(nvp, &data_int64);
			rcm_log_message(RCM_TRACE3, "0x%lx (int64)\n",
			    data_int64);
			break;

		case DATA_TYPE_UINT64:
			(void) nvpair_value_uint64(nvp, &data_uint64);
			rcm_log_message(RCM_TRACE3, "0x%lx (uint64)\n",
			    data_uint64);
			break;

		case DATA_TYPE_STRING:
			(void) nvpair_value_string(nvp, &data_string);
			rcm_log_message(RCM_TRACE3, "\"%s\" (string)\n",
			    data_string);
			break;

		case DATA_TYPE_STRING_ARRAY:
			(void) nvpair_value_string_array(nvp, &data_strings,
			    &data_nstrings);
			for (i = 0; i < data_nstrings; i++) {
				rcm_log_message(RCM_TRACE3,
				    "\t\"%s\" (string)\n", data_strings[i]);
				if (i < (data_nstrings - 1))
					rcm_log_message(RCM_TRACE3, "\t\t\t");
			}
			break;

		default:
			rcm_log_message(RCM_TRACE3, "<not dumped>\n");
			break;
		}
	}
}
Beispiel #21
0
static int
build_jailcmd(char ***argvp, bool interactive, int argc, char *argv[])
{
	char *cmd, **jargv, *name, *val;
	nvpair_t *nvp;
	size_t i, iarg, nargv;

	cmd = NULL;
	nvp = NULL;
	iarg = i = 0;
	if (nvlist_size(jailparams, &nargv, NV_ENCODE_NATIVE) != 0)
		return (1);

	/*
	 * Number of args + "/usr/sbin/jail", "-c", and ending NULL.
	 * If interactive also include command.
	 */
	nargv += 3;
	if (interactive) {
		if (argc == 0)
			nargv++;
		else
			nargv += argc;
	}

	jargv = *argvp = calloc(nargv, sizeof(jargv));
	if (jargv == NULL)
		err(2, "calloc");

	jargv[iarg++] = strdup("/usr/sbin/jail");
	jargv[iarg++] = strdup("-c");
	while ((nvp = nvlist_next_nvpair(jailparams, nvp)) != NULL) {
		name = nvpair_name(nvp);
		if (nvpair_value_string(nvp, &val) != 0)
			continue;

		if (asprintf(&jargv[iarg++], "%s=%s", name, val) < 0)
			goto error;
	}
	if (interactive) {
		if (argc < 1)
			cmd = strdup("/bin/sh");
		else {
			cmd = argv[0];
			argc--;
			argv++;
		}

		if (asprintf(&jargv[iarg++], "command=%s", cmd) < 0) {
			goto error;
		}
		if (argc < 1) {
			free(cmd);
			cmd = NULL;
		}

		for (; argc > 0; argc--) {
			if (asprintf(&jargv[iarg++], "%s", argv[0]) < 0)
				goto error;
			argv++;
		}
	}

	return (0);

error:
	if (interactive && argc < 1)
		free(cmd);
	for (; i < iarg - 1; i++) {
		free(jargv[i]);
	}
	free(jargv);
	return (1);
}
Beispiel #22
0
/*
 * Copy in a packed nvlist from the user and create a request set out of it.
 * If successful, return 0 and store a pointer to the set we've created. Returns
 * error code on error.
 */
int
kcpc_copyin_set(kcpc_set_t **inset, void *ubuf, size_t len)
{
	kcpc_set_t	*set;
	int		i;
	int		j;
	char		*packbuf;

	nvlist_t	*nvl;
	nvpair_t	*nvp = NULL;

	nvlist_t	*attrs;
	nvpair_t	*nvp_attr;
	kcpc_attr_t	*attrp;

	nvlist_t	**reqlist;
	uint_t		nreqs;
	uint64_t	uint64;
	uint32_t	uint32;
	uint32_t	setflags = (uint32_t)-1;
	char		*string;
	char		*name;

	if (len < CPC_MIN_PACKSIZE || len > CPC_MAX_PACKSIZE)
		return (EINVAL);

	packbuf = kmem_alloc(len, KM_SLEEP);

	if (copyin(ubuf, packbuf, len) == -1) {
		kmem_free(packbuf, len);
		return (EFAULT);
	}

	if (nvlist_unpack(packbuf, len, &nvl, KM_SLEEP) != 0) {
		kmem_free(packbuf, len);
		return (EINVAL);
	}

	/*
	 * The nvlist has been unpacked so there is no need for the packed
	 * representation from this point on.
	 */
	kmem_free(packbuf, len);

	i = 0;
	while ((nvp = nvlist_next_nvpair(nvl, nvp)) != NULL) {
		switch (nvpair_type(nvp)) {
		case DATA_TYPE_UINT32:
			if (strcmp(nvpair_name(nvp), "flags") != 0 ||
			    nvpair_value_uint32(nvp, &setflags) != 0) {
				nvlist_free(nvl);
				return (EINVAL);
			}
			break;
		case DATA_TYPE_NVLIST_ARRAY:
			if (strcmp(nvpair_name(nvp), "reqs") != 0 ||
			    nvpair_value_nvlist_array(nvp, &reqlist,
			    &nreqs) != 0) {
				nvlist_free(nvl);
				return (EINVAL);
			}
			break;
		default:
			nvlist_free(nvl);
			return (EINVAL);
		}
		i++;
	}

	/*
	 * There should be two members in the top-level nvlist:
	 * an array of nvlists consisting of the requests, and flags.
	 * Anything else is an invalid set.
	 */
	if (i != 2) {
		nvlist_free(nvl);
		return (EINVAL);
	}

	if (nreqs > CPC_MAX_NREQS) {
		nvlist_free(nvl);
		return (EINVAL);
	}

	/*
	 * The requests are now stored in the nvlist array at reqlist.
	 * Note that the use of kmem_zalloc() to alloc the kcpc_set_t means
	 * we don't need to call the init routines for ks_lock and ks_condv.
	 */
	set = kmem_zalloc(sizeof (kcpc_set_t), KM_SLEEP);
	set->ks_req = (kcpc_request_t *)kmem_zalloc(sizeof (kcpc_request_t) *
	    nreqs, KM_SLEEP);
	set->ks_nreqs = nreqs;
	/*
	 * If the nvlist didn't contain a flags member, setflags was initialized
	 * with an illegal value and this set will fail sanity checks later on.
	 */
	set->ks_flags = setflags;
	/*
	 * Initialize bind/unbind set synchronization.
	 */
	set->ks_state &= ~KCPC_SET_BOUND;

	/*
	 * Build the set up one request at a time, always keeping it self-
	 * consistent so we can give it to kcpc_free_set() if we need to back
	 * out and return and error.
	 */
	for (i = 0; i < nreqs; i++) {
		nvp = NULL;
		set->ks_req[i].kr_picnum = -1;
		while ((nvp = nvlist_next_nvpair(reqlist[i], nvp)) != NULL) {
			name = nvpair_name(nvp);
			switch (nvpair_type(nvp)) {
			case DATA_TYPE_UINT32:
				if (nvpair_value_uint32(nvp, &uint32) == EINVAL)
					goto inval;
				if (strcmp(name, "cr_flags") == 0)
					set->ks_req[i].kr_flags = uint32;
				if (strcmp(name, "cr_index") == 0)
					set->ks_req[i].kr_index = uint32;
				break;
			case DATA_TYPE_UINT64:
				if (nvpair_value_uint64(nvp, &uint64) == EINVAL)
					goto inval;
				if (strcmp(name, "cr_preset") == 0)
					set->ks_req[i].kr_preset = uint64;
				break;
			case DATA_TYPE_STRING:
				if (nvpair_value_string(nvp, &string) == EINVAL)
					goto inval;
				if (strcmp(name, "cr_event") == 0)
					(void) strncpy(set->ks_req[i].kr_event,
					    string, CPC_MAX_EVENT_LEN);
				break;
			case DATA_TYPE_NVLIST:
				if (strcmp(name, "cr_attr") != 0)
					goto inval;
				if (nvpair_value_nvlist(nvp, &attrs) == EINVAL)
					goto inval;
				nvp_attr = NULL;
				/*
				 * If the picnum has been specified as an
				 * attribute, consume that attribute here and
				 * remove it from the list of attributes.
				 */
				if (nvlist_lookup_uint64(attrs, "picnum",
				    &uint64) == 0) {
					if (nvlist_remove(attrs, "picnum",
					    DATA_TYPE_UINT64) != 0)
						panic("nvlist %p faulty",
						    (void *)attrs);
					set->ks_req[i].kr_picnum = uint64;
				}

				if ((set->ks_req[i].kr_nattrs =
				    kcpc_nvlist_npairs(attrs)) == 0)
					break;

				if (set->ks_req[i].kr_nattrs > CPC_MAX_ATTRS)
					goto inval;

				set->ks_req[i].kr_attr =
				    kmem_alloc(set->ks_req[i].kr_nattrs *
				    sizeof (kcpc_attr_t), KM_SLEEP);
				j = 0;

				while ((nvp_attr = nvlist_next_nvpair(attrs,
				    nvp_attr)) != NULL) {
					attrp = &set->ks_req[i].kr_attr[j];

					if (nvpair_type(nvp_attr) !=
					    DATA_TYPE_UINT64)
						goto inval;

					(void) strncpy(attrp->ka_name,
					    nvpair_name(nvp_attr),
					    CPC_MAX_ATTR_LEN);

					if (nvpair_value_uint64(nvp_attr,
					    &(attrp->ka_val)) == EINVAL)
						goto inval;
					j++;
				}
				ASSERT(j == set->ks_req[i].kr_nattrs);
			default:
				break;
			}
		}
	}

	nvlist_free(nvl);
	*inset = set;
	return (0);

inval:
	nvlist_free(nvl);
	kcpc_free_set(set);
	return (EINVAL);
}
/*
 * It's up to the caller to do any sorting or pretty-printing of the device
 * mappings we report. Since we're storing the device links as just the cXtYdZ
 * part, we'll add /dev/rdsk/ back on when we print the listing so we maintain
 * compatibility with previous versions of this tool. There's a little bit
 * of footwork involved to make sure that we show all the paths to a device
 * rather than just the first one we stashed away.
 */
static void
list_devs(int listguids, int ctrl)
{
	nvlist_t *thisdevnvl;
	nvpair_t *pair;
	char *diskpath, *livepath, *key, *querydev;
	char *matchctrl = NULL;
	char checkctrl[MAXPATHLEN];
	int rv;

	if (!mpxenabled) {
		if (mpxprop) {
			logmsg(MSG_ERROR, gettext("MPXIO disabled\n"));
		} else {
			logmsg(MSG_ERROR, gettext("No STMS devices have "
			    "been found\n"));
		}
		return;
	}

	if (listguids) {
		(void) printf(gettext("non-STMS device name\t\t\tGUID\n"
		    "------------------------------------------"
		    "------------------------\n"));
	} else {
		(void) printf(gettext("non-STMS device name\t\t\t"
		    "STMS device name\n"
		    "------------------------------------------"
		    "------------------------\n"));
	}

	bzero(checkctrl, MAXPATHLEN);
	pair = NULL;
	while ((pair = nvlist_next_nvpair(mapnvl, pair))
	    != NULL) {
		boolean_t livescsivhcip = B_FALSE;

		if ((((rv = nvpair_value_string(pair, &querydev)) < 0) ||
		    ((key = nvpair_name(pair)) == NULL)) ||
		    ((strstr(key, "/pci") != NULL) ||
		    (strstr(key, "/sbus") != NULL) ||
		    (strstr(key, "/scsi_vhci") != NULL) ||
		    (strncmp(key, "id1", 3) == 0))) {
			logmsg(MSG_INFO,
			    "list_devs: rv = %d; (%s) is not a devlink, "
			    "continuing.\n", rv,
			    (key != NULL) ? key : "null");
			querydev = NULL;
			continue;
		}

		(void) nvlist_lookup_nvlist(mapnvl, querydev, &thisdevnvl);
		(void) nvlist_lookup_boolean_value(thisdevnvl, NVL_MPXEN,
		    &livescsivhcip);
		(void) nvlist_lookup_string(thisdevnvl, NVL_MPXPATH,
		    &livepath);

		if ((!livescsivhcip) ||
		    (livescsivhcip &&
		    (strncmp(key, livepath, strlen(key)) == 0)))
			continue;

		(void) nvlist_lookup_string(thisdevnvl, NVL_PATH,
		    &diskpath);

		logmsg(MSG_INFO,
		    "list_devs: %s :: %s ::%s :: MPXEN (%s)\n",
		    key, diskpath, livepath,
		    ((livescsivhcip) ? "TRUE" : "FALSE"));

		if (ctrl > -1) {
			(void) sprintf(checkctrl, "c%dt", ctrl);
			matchctrl = strstr(key, checkctrl);
			if (matchctrl == NULL)
				continue;
		}
		if (listguids != 0) {
			char *tempguid;
			ddi_devid_t curdevid;
			int rv;

			rv = devid_str_decode(querydev, &curdevid, NULL);
			if (rv == -1) {
				logmsg(MSG_INFO, "Unable to decode devid %s\n",
				    key);
				continue;
			}
			tempguid = devid_to_guid(curdevid);
			if (tempguid != NULL)
				(void) printf("/dev/rdsk/%s\t%s\n",
				    diskpath, tempguid);

			devid_free_guid(tempguid);
			devid_free(curdevid);
			continue;
		}

		(void) printf("/dev/rdsk/%s\t/dev/rdsk/%s\n",
		    (strstr(key, diskpath) == NULL) ? key : diskpath,
		    livepath);
	}
}
Beispiel #24
0
static void
print_prop_nameval(topo_hdl_t *thp, tnode_t *node, nvlist_t *nvl)
{
	int err;
	topo_type_t type;
	char *tstr, *propn, buf[48], *factype;
	nvpair_t *pv_nvp;
	int i;
	uint_t nelem;

	if ((pv_nvp = nvlist_next_nvpair(nvl, NULL)) == NULL)
		return;

	/* Print property name */
	if ((pv_nvp = nvlist_next_nvpair(nvl, NULL)) == NULL ||
	    nvpair_name(pv_nvp) == NULL ||
	    strcmp(TOPO_PROP_VAL_NAME, nvpair_name(pv_nvp)) != 0) {
		(void) fprintf(stderr, "%s: malformed property name\n",
		    g_pname);
		return;
	} else {
		(void) nvpair_value_string(pv_nvp, &propn);
	}

	if ((pv_nvp = nvlist_next_nvpair(nvl, pv_nvp)) == NULL ||
	    nvpair_name(pv_nvp) == NULL ||
	    strcmp(nvpair_name(pv_nvp), TOPO_PROP_VAL_TYPE) != 0 ||
	    nvpair_type(pv_nvp) != DATA_TYPE_UINT32)  {
		(void) fprintf(stderr, "%s: malformed property type for %s\n",
		    g_pname, propn);
		return;
	} else {
		(void) nvpair_value_uint32(pv_nvp, (uint32_t *)&type);
	}

	switch (type) {
		case TOPO_TYPE_BOOLEAN: tstr = "boolean"; break;
		case TOPO_TYPE_INT32: tstr = "int32"; break;
		case TOPO_TYPE_UINT32: tstr = "uint32"; break;
		case TOPO_TYPE_INT64: tstr = "int64"; break;
		case TOPO_TYPE_UINT64: tstr = "uint64"; break;
		case TOPO_TYPE_DOUBLE: tstr = "double"; break;
		case TOPO_TYPE_STRING: tstr = "string"; break;
		case TOPO_TYPE_FMRI: tstr = "fmri"; break;
		case TOPO_TYPE_INT32_ARRAY: tstr = "int32[]"; break;
		case TOPO_TYPE_UINT32_ARRAY: tstr = "uint32[]"; break;
		case TOPO_TYPE_INT64_ARRAY: tstr = "int64[]"; break;
		case TOPO_TYPE_UINT64_ARRAY: tstr = "uint64[]"; break;
		case TOPO_TYPE_STRING_ARRAY: tstr = "string[]"; break;
		case TOPO_TYPE_FMRI_ARRAY: tstr = "fmri[]"; break;
		default: tstr = "unknown type";
	}

	(void) printf("    %-17s %-8s ", propn, tstr);

	/*
	 * Get property value
	 */
	if (nvpair_name(pv_nvp) == NULL ||
	    (pv_nvp = nvlist_next_nvpair(nvl, pv_nvp)) == NULL) {
		(void) fprintf(stderr, "%s: malformed property value\n",
		    g_pname);
		return;
	}

	switch (nvpair_type(pv_nvp)) {
		case DATA_TYPE_INT32: {
			int32_t val;
			(void) nvpair_value_int32(pv_nvp, &val);
			(void) printf(" %d", val);
			break;
		}
		case DATA_TYPE_UINT32: {
			uint32_t val, type;
			char val_str[49];
			nvlist_t *fac, *rsrc = NULL;

			(void) nvpair_value_uint32(pv_nvp, &val);
			if (node == NULL || topo_node_flags(node) !=
			    TOPO_NODE_FACILITY)
				goto uint32_def;

			if (topo_node_resource(node, &rsrc, &err) != 0)
				goto uint32_def;

			if (nvlist_lookup_nvlist(rsrc, "facility", &fac) != 0)
				goto uint32_def;

			if (nvlist_lookup_string(fac, FM_FMRI_FACILITY_TYPE,
			    &factype) != 0)
				goto uint32_def;

			nvlist_free(rsrc);
			rsrc = NULL;

			/*
			 * Special case code to do friendlier printing of
			 * facility node properties
			 */
			if ((strcmp(propn, TOPO_FACILITY_TYPE) == 0) &&
			    (strcmp(factype, TOPO_FAC_TYPE_SENSOR) == 0)) {
				topo_sensor_type_name(val, val_str, 48);
				(void) printf(" 0x%x (%s)", val, val_str);
				break;
			} else if ((strcmp(propn, TOPO_FACILITY_TYPE) == 0) &&
			    (strcmp(factype, TOPO_FAC_TYPE_INDICATOR) == 0)) {
				topo_led_type_name(val, val_str, 48);
				(void) printf(" 0x%x (%s)", val, val_str);
				break;
			} else if (strcmp(propn, TOPO_SENSOR_UNITS) == 0) {
				topo_sensor_units_name(val, val_str, 48);
				(void) printf(" 0x%x (%s)", val, val_str);
				break;
			} else if (strcmp(propn, TOPO_LED_MODE) == 0) {
				topo_led_state_name(val, val_str, 48);
				(void) printf(" 0x%x (%s)", val, val_str);
				break;
			} else if ((strcmp(propn, TOPO_SENSOR_STATE) == 0) &&
			    (strcmp(factype, TOPO_FAC_TYPE_SENSOR) == 0)) {
				if (topo_prop_get_uint32(node,
				    TOPO_PGROUP_FACILITY, TOPO_FACILITY_TYPE,
				    &type, &err) != 0) {
					goto uint32_def;
				}
				topo_sensor_state_name(type, val, val_str, 48);
				(void) printf(" 0x%x (%s)", val, val_str);
				break;
			}
uint32_def:
			(void) printf(" 0x%x", val);
			if (rsrc != NULL)
				nvlist_free(rsrc);
			break;
		}
		case DATA_TYPE_INT64: {
			int64_t val;
			(void) nvpair_value_int64(pv_nvp, &val);
			(void) printf(" %lld", (longlong_t)val);
			break;
		}
		case DATA_TYPE_UINT64: {
			uint64_t val;
			(void) nvpair_value_uint64(pv_nvp, &val);
			(void) printf(" 0x%llx", (u_longlong_t)val);
			break;
		}
		case DATA_TYPE_DOUBLE: {
			double val;
			(void) nvpair_value_double(pv_nvp, &val);
			(void) printf(" %lf", (double)val);
			break;
		}
		case DATA_TYPE_STRING: {
			char *val;
			(void) nvpair_value_string(pv_nvp, &val);
			if (!opt_V && strlen(val) > 48) {
				(void) snprintf(buf, 48, "%s...", val);
				(void) printf(" %s", buf);
			} else {
				(void) printf(" %s", val);
			}
			break;
		}
		case DATA_TYPE_NVLIST: {
			nvlist_t *val;
			char *fmri;
			(void) nvpair_value_nvlist(pv_nvp, &val);
			if (topo_fmri_nvl2str(thp, val, &fmri, &err) != 0) {
				if (opt_V)
					nvlist_print(stdout, nvl);
				break;
			}

			if (!opt_V && strlen(fmri) > 48) {
				(void) snprintf(buf, 48, "%s", fmri);
				(void) snprintf(&buf[45], 4, "%s", DOTS);
				(void) printf(" %s", buf);
			} else {
				(void) printf(" %s", fmri);
			}

			topo_hdl_strfree(thp, fmri);
			break;
		}
		case DATA_TYPE_INT32_ARRAY: {
			int32_t *val;

			(void) nvpair_value_int32_array(pv_nvp, &val, &nelem);
			(void) printf(" [ ");
			for (i = 0; i < nelem; i++)
				(void) printf("%d ", val[i]);
			(void) printf("]");
			break;
		}
		case DATA_TYPE_UINT32_ARRAY: {
			uint32_t *val;

			(void) nvpair_value_uint32_array(pv_nvp, &val, &nelem);
			(void) printf(" [ ");
			for (i = 0; i < nelem; i++)
				(void) printf("%u ", val[i]);
			(void) printf("]");
			break;
		}
		case DATA_TYPE_INT64_ARRAY: {
			int64_t *val;

			(void) nvpair_value_int64_array(pv_nvp, &val, &nelem);
			(void) printf(" [ ");
			for (i = 0; i < nelem; i++)
				(void) printf("%lld ", val[i]);
			(void) printf("]");
			break;
		}
		case DATA_TYPE_UINT64_ARRAY: {
			uint64_t *val;

			(void) nvpair_value_uint64_array(pv_nvp, &val, &nelem);
			(void) printf(" [ ");
			for (i = 0; i < nelem; i++)
				(void) printf("%llu ", val[i]);
			(void) printf("]");
			break;
		}
		case DATA_TYPE_STRING_ARRAY: {
			char **val;

			(void) nvpair_value_string_array(pv_nvp, &val, &nelem);
			(void) printf(" [ ");
			for (i = 0; i < nelem; i++)
				(void) printf("\"%s\" ", val[i]);
			(void) printf("]");
			break;
		}
		default:
			(void) fprintf(stderr, " unknown data type (%d)",
			    nvpair_type(pv_nvp));
			break;
		}
		(void) printf("\n");
}
Beispiel #25
0
/*ARGSUSED*/
static int
sw_fmri_nvl2str(topo_mod_t *mod, tnode_t *node, topo_version_t version,
    nvlist_t *nvl, nvlist_t **out)
{
	nvlist_t *object, *site = NULL, *anvl = NULL;
	char *file, *func, *token;
	uint8_t scheme_version;
	char *path, *root;
	nvlist_t *fmristr;
	size_t buflen = 0;
	int linevalid = 0;
	char *buf = NULL;
	ssize_t size = 0;
	char linebuf[32];
	int64_t line;
	int pass;
	int err;

	if (version > TOPO_METH_NVL2STR_VERSION)
		return (topo_mod_seterrno(mod, EMOD_VER_NEW));

	if (nvlist_lookup_uint8(nvl, FM_VERSION, &scheme_version) != 0 ||
	    scheme_version > FM_SW_SCHEME_VERSION)
		return (topo_mod_seterrno(mod, EMOD_FMRI_NVL));

	/* Get authority, if present */
	err = nvlist_lookup_nvlist(nvl, FM_FMRI_AUTHORITY, &anvl);
	if (err != 0 && err != ENOENT)
		return (topo_mod_seterrno(mod, EMOD_FMRI_NVL));

	/*
	 * The 'object' nvlist is required. It must include the path,
	 * but the root is optional.
	 */
	if (nvlist_lookup_nvlist(nvl, FM_FMRI_SW_OBJ, &object) != 0 ||
	    !lookup_string(object, FM_FMRI_SW_OBJ_PATH, &path, B_TRUE) ||
	    !lookup_string(object, FM_FMRI_SW_OBJ_ROOT, &root, B_FALSE))
		return (topo_mod_seterrno(mod, EMOD_FMRI_NVL));

	/* The 'site' nvlist is optional */
	file = func = token = NULL;
	linevalid = 0;
	if ((err = nvlist_lookup_nvlist(nvl, FM_FMRI_SW_SITE, &site)) == 0) {
		/*
		 * Prefer 'token' to file/func/line
		 */
		if (lookup_string(site, FM_FMRI_SW_SITE_TOKEN, &token,
		    B_FALSE) <= 0) {
			/*
			 * If no token then try file, func, line - but
			 * func and line are meaningless without file.
			 */
			if (lookup_string(site, FM_FMRI_SW_SITE_FILE,
			    &file, B_FALSE) == 1) {
				(void) lookup_string(site, FM_FMRI_SW_SITE_FUNC,
				    &func, B_FALSE);
				if (nvlist_lookup_int64(site,
				    FM_FMRI_SW_SITE_LINE, &line) == 0)
					linevalid = 1;
			}
		}
	} else if (err != ENOENT) {
		return (topo_mod_seterrno(mod, EMOD_FMRI_NVL));
	}

	/* On the first pass buf is NULL and size and buflen are 0 */
	pass = 1;
again:
	/*
	 * sw://[<authority>]/
	 *	[:root=<object.root]
	 *	:path=<object.path>
	 *	[#<fragment-identifier>]
	 *
	 *	<fragment-identifier> is one of
	 *
	 *		:token=<site.token>
	 *	or
	 *		:file=<site.file>[:func=<site.func>][:line=<site.line>]
	 */

	/* sw:// */
	topo_fmristr_build(&size, buf, buflen, FM_FMRI_SCHEME_SW,
	    NULL, "://");

	/* authority, if any */
	if (anvl != NULL) {
		nvpair_t *apair;
		char *aname, *aval;

		for (apair = nvlist_next_nvpair(anvl, NULL);
		    apair != NULL; apair = nvlist_next_nvpair(anvl, apair)) {
			if (nvpair_type(apair) != DATA_TYPE_STRING ||
			    nvpair_value_string(apair, &aval) != 0)
				continue;
			aname = nvpair_name(apair);
			topo_fmristr_build(&size, buf, buflen, ":", NULL, NULL);
			topo_fmristr_build(&size, buf, buflen, "=",
			    aname, aval);
		}
	}

	/* separating slash */
	topo_fmristr_build(&size, buf, buflen, "/", NULL, NULL);

	/* :root=... */
	if (root) {
		topo_fmristr_build(&size, buf, buflen, root,
		    ":" FM_FMRI_SW_OBJ_ROOT "=", NULL);
	}

	/* :path=... */
	topo_fmristr_build(&size, buf, buflen, path,
	    ":" FM_FMRI_SW_OBJ_PATH "=", NULL);

	if (token) {
		/* #:token=... */
		topo_fmristr_build(&size, buf, buflen, token,
		    "#:" FM_FMRI_SW_SITE_TOKEN "=", NULL);
	} else if (file) {
		/* #:file=... */
		topo_fmristr_build(&size, buf, buflen, file,
		    "#:" FM_FMRI_SW_SITE_FILE "=", NULL);

		/* :func=... */
		if (func) {
			topo_fmristr_build(&size, buf, buflen, func,
			    ":" FM_FMRI_SW_SITE_FUNC "=", NULL);
		}

		/* :line=... */
		if (linevalid) {
			if (pass == 1)
				(void) snprintf(linebuf, sizeof (linebuf),
				    "%lld", line);

			topo_fmristr_build(&size, buf, buflen, linebuf,
			    ":" FM_FMRI_SW_SITE_LINE "=", NULL);
		}
	}

	if (buf == NULL) {
		if ((buf = topo_mod_alloc(mod, size + 1)) == NULL)
			return (topo_mod_seterrno(mod, EMOD_NOMEM));

		buflen = size + 1;
		size = 0;
		pass = 2;
		goto again;
	}

	/*
	 * Construct the nvlist to return as the result.
	 */
	if (topo_mod_nvalloc(mod, &fmristr, NV_UNIQUE_NAME) != 0) {
		topo_mod_strfree(mod, buf);
		return (topo_mod_seterrno(mod, EMOD_NOMEM));
	}

	if (nvlist_add_string(fmristr, "fmri-string", buf) != 0) {
		topo_mod_strfree(mod, buf);
		nvlist_free(fmristr);
		return (topo_mod_seterrno(mod, EMOD_NOMEM));
	}
	topo_mod_strfree(mod, buf);
	*out = fmristr;

	return (0);
}
Beispiel #26
0
static void
print_all_props(topo_hdl_t *thp, tnode_t *node, nvlist_t *p_nv,
    const char *group)
{
	char *pgn = NULL, *dstab = NULL, *nstab = NULL;
	int32_t version;
	nvlist_t *pg_nv, *pv_nv;
	nvpair_t *nvp, *pg_nvp;
	int pg_done, match, all = strcmp(group, ALL) == 0;

	for (nvp = nvlist_next_nvpair(p_nv, NULL); nvp != NULL;
	    nvp = nvlist_next_nvpair(p_nv, nvp)) {
		if (strcmp(TOPO_PROP_GROUP, nvpair_name(nvp)) != 0 ||
		    nvpair_type(nvp) != DATA_TYPE_NVLIST)
			continue;

		nstab = NULL;
		dstab = NULL;
		version = -1;
		pg_done = match = 0;
		(void) nvpair_value_nvlist(nvp, &pg_nv);
		for (pg_nvp = nvlist_next_nvpair(pg_nv, NULL); pg_nvp != NULL;
		    pg_nvp = nvlist_next_nvpair(pg_nv, pg_nvp)) {
			/*
			 * Print property group name and stability levels
			 */
			if (strcmp(TOPO_PROP_GROUP_NAME, nvpair_name(pg_nvp))
			    == 0 && nvpair_type(pg_nvp) == DATA_TYPE_STRING) {
				(void) nvpair_value_string(pg_nvp, &pgn);
				match = strcmp(group, pgn) == 0;
				continue;
			}

			if (strcmp(TOPO_PROP_GROUP_NSTAB,
			    nvpair_name(pg_nvp)) == 0 &&
			    nvpair_type(pg_nvp) == DATA_TYPE_STRING) {
				(void) nvpair_value_string(pg_nvp, &nstab);
				continue;
			}

			if (strcmp(TOPO_PROP_GROUP_DSTAB,
			    nvpair_name(pg_nvp)) == 0 &&
			    nvpair_type(pg_nvp) == DATA_TYPE_STRING) {
				(void) nvpair_value_string(pg_nvp, &dstab);
				continue;
			}

			if (strcmp(TOPO_PROP_GROUP_VERSION,
			    nvpair_name(pg_nvp)) == 0 &&
			    nvpair_type(pg_nvp) == DATA_TYPE_INT32) {
				(void) nvpair_value_int32(pg_nvp, &version);
				continue;
			}

			if ((match || all) && !pg_done) {
				print_pgroup(thp, node, pgn, dstab, nstab,
				    version);
				pg_done++;
			}

			/*
			 * Print property group and property name-value pair
			 */
			if (strcmp(TOPO_PROP_VAL, nvpair_name(pg_nvp))
			    == 0 && nvpair_type(pg_nvp) == DATA_TYPE_NVLIST) {
				(void) nvpair_value_nvlist(pg_nvp, &pv_nv);
				if ((match || all) && pg_done) {
					print_prop_nameval(thp, node, pv_nv);
				}

			}

		}
		if (match && !all)
			return;
	}
}
Beispiel #27
0
/*
 * Process profile passed down from libdevinfo. There are four types
 * of matching rules:
 *  include: export a name or names matching a pattern
 *  exclude: exclude a name or names matching a pattern
 *  symlink: create a local symlink
 *  map:     export a device with a name different from the global zone
 * Note: We may consider supporting VOP_SYMLINK in non-global instances,
 *	because it does not present any security risk. For now, the fs
 *	instance is read only.
 */
static void
sdev_process_profile(struct sdev_data *sdev_data, nvlist_t *profile)
{
	nvpair_t *nvpair;
	char *nvname, *dname;
	struct sdev_node *dir, *gdir;
	char **pair;				/* for symlinks and maps */
	uint_t nelem;
	int rv;

	gdir = sdev_origins->sdev_root;	/* root of global /dev */
	dir = sdev_data->sdev_root;	/* root of current instance */

	ASSERT(profile);

	/* process nvpairs in the list */
	nvpair = NULL;
	while (nvpair = nvlist_next_nvpair(profile, nvpair)) {
		nvname = nvpair_name(nvpair);
		ASSERT(nvname != NULL);

		if (strcmp(nvname, SDEV_NVNAME_INCLUDE) == 0) {
			rv = nvpair_value_string(nvpair, &dname);
			if (rv != 0) {
				cmn_err(CE_WARN, sdev_nvp_val_err,
				    rv, nvpair_name(nvpair));
				break;
			}
			process_rule(dir, gdir, dname, NULL,
			    PROFILE_TYPE_INCLUDE);
		} else if (strcmp(nvname, SDEV_NVNAME_EXCLUDE) == 0) {
			rv = nvpair_value_string(nvpair, &dname);
			if (rv != 0) {
				cmn_err(CE_WARN, sdev_nvp_val_err,
				    rv, nvpair_name(nvpair));
				break;
			}
			process_rule(dir, gdir, dname, NULL,
			    PROFILE_TYPE_EXCLUDE);
		} else if (strcmp(nvname, SDEV_NVNAME_SYMLINK) == 0) {
			rv = nvpair_value_string_array(nvpair, &pair, &nelem);
			if (rv != 0) {
				cmn_err(CE_WARN, sdev_nvp_val_err,
				    rv, nvpair_name(nvpair));
				break;
			}
			ASSERT(nelem == 2);
			process_rule(dir, gdir, pair[0], pair[1],
			    PROFILE_TYPE_SYMLINK);
		} else if (strcmp(nvname, SDEV_NVNAME_MAP) == 0) {
			rv = nvpair_value_string_array(nvpair, &pair, &nelem);
			if (rv != 0) {
				cmn_err(CE_WARN, sdev_nvp_val_err,
				    rv, nvpair_name(nvpair));
				break;
			}
			process_rule(dir, gdir, pair[1], pair[0],
			    PROFILE_TYPE_MAP);
		} else if (strcmp(nvname, SDEV_NVNAME_MOUNTPT) != 0) {
			cmn_err(CE_WARN, "sdev_process_profile: invalid "
			    "nvpair %s\n", nvname);
		}
	}
}
Beispiel #28
0
/*
 * Convert the nvpair [nvp] to a string which is added to the environment
 * of the child process.
 * Return 0 on success, -1 on error.
 *
 * FIXME: Refactor with cmd/zpool/zpool_main.c:zpool_do_events_nvprint()?
 */
static void
_zed_event_add_nvpair(uint64_t eid, zed_strings_t *zsp, nvpair_t *nvp)
{
	const char *name;
	data_type_t type;
	const char *prefix = ZEVENT_VAR_PREFIX;
	boolean_t b;
	double d;
	uint8_t i8;
	uint16_t i16;
	uint32_t i32;
	uint64_t i64;
	char *str;

	assert(zsp != NULL);
	assert(nvp != NULL);

	name = nvpair_name(nvp);
	type = nvpair_type(nvp);

	switch (type) {
	case DATA_TYPE_BOOLEAN:
		_zed_event_add_var(eid, zsp, prefix, name, "%s", "1");
		break;
	case DATA_TYPE_BOOLEAN_VALUE:
		(void) nvpair_value_boolean_value(nvp, &b);
		_zed_event_add_var(eid, zsp, prefix, name, "%s", b ? "1" : "0");
		break;
	case DATA_TYPE_BYTE:
		(void) nvpair_value_byte(nvp, &i8);
		_zed_event_add_var(eid, zsp, prefix, name, "%d", i8);
		break;
	case DATA_TYPE_INT8:
		(void) nvpair_value_int8(nvp, (int8_t *) &i8);
		_zed_event_add_var(eid, zsp, prefix, name, "%d", i8);
		break;
	case DATA_TYPE_UINT8:
		(void) nvpair_value_uint8(nvp, &i8);
		_zed_event_add_var(eid, zsp, prefix, name, "%u", i8);
		break;
	case DATA_TYPE_INT16:
		(void) nvpair_value_int16(nvp, (int16_t *) &i16);
		_zed_event_add_var(eid, zsp, prefix, name, "%d", i16);
		break;
	case DATA_TYPE_UINT16:
		(void) nvpair_value_uint16(nvp, &i16);
		_zed_event_add_var(eid, zsp, prefix, name, "%u", i16);
		break;
	case DATA_TYPE_INT32:
		(void) nvpair_value_int32(nvp, (int32_t *) &i32);
		_zed_event_add_var(eid, zsp, prefix, name, "%d", i32);
		break;
	case DATA_TYPE_UINT32:
		(void) nvpair_value_uint32(nvp, &i32);
		_zed_event_add_var(eid, zsp, prefix, name, "%u", i32);
		break;
	case DATA_TYPE_INT64:
		(void) nvpair_value_int64(nvp, (int64_t *) &i64);
		_zed_event_add_var(eid, zsp, prefix, name,
		    "%lld", (longlong_t) i64);
		break;
	case DATA_TYPE_UINT64:
		(void) nvpair_value_uint64(nvp, &i64);
		_zed_event_add_var(eid, zsp, prefix, name,
		    (_zed_event_value_is_hex(name) ? "0x%.16llX" : "%llu"),
		    (u_longlong_t) i64);
		/*
		 * shadow readable strings for vdev state pairs
		 */
		if (strcmp(name, FM_EREPORT_PAYLOAD_ZFS_VDEV_STATE) == 0 ||
		    strcmp(name, FM_EREPORT_PAYLOAD_ZFS_VDEV_LASTSTATE) == 0) {
			char alt[32];

			(void) snprintf(alt, sizeof (alt), "%s_str", name);
			_zed_event_add_var(eid, zsp, prefix, alt, "%s",
			    zpool_state_to_name(i64, VDEV_AUX_NONE));
		}
		break;
	case DATA_TYPE_DOUBLE:
		(void) nvpair_value_double(nvp, &d);
		_zed_event_add_var(eid, zsp, prefix, name, "%g", d);
		break;
	case DATA_TYPE_HRTIME:
		(void) nvpair_value_hrtime(nvp, (hrtime_t *) &i64);
		_zed_event_add_var(eid, zsp, prefix, name,
		    "%llu", (u_longlong_t) i64);
		break;
	case DATA_TYPE_NVLIST:
		_zed_event_add_var(eid, zsp, prefix, name,
		    "%s", "_NOT_IMPLEMENTED_");			/* FIXME */
		break;
	case DATA_TYPE_STRING:
		(void) nvpair_value_string(nvp, &str);
		_zed_event_add_var(eid, zsp, prefix, name,
		    "%s", (str ? str : "<NULL>"));
		break;
	case DATA_TYPE_BOOLEAN_ARRAY:
		_zed_event_add_var(eid, zsp, prefix, name,
		    "%s", "_NOT_IMPLEMENTED_");			/* FIXME */
		break;
	case DATA_TYPE_BYTE_ARRAY:
		_zed_event_add_var(eid, zsp, prefix, name,
		    "%s", "_NOT_IMPLEMENTED_");			/* FIXME */
		break;
	case DATA_TYPE_INT8_ARRAY:
		_zed_event_add_int8_array(eid, zsp, prefix, nvp);
		break;
	case DATA_TYPE_UINT8_ARRAY:
		_zed_event_add_uint8_array(eid, zsp, prefix, nvp);
		break;
	case DATA_TYPE_INT16_ARRAY:
		_zed_event_add_int16_array(eid, zsp, prefix, nvp);
		break;
	case DATA_TYPE_UINT16_ARRAY:
		_zed_event_add_uint16_array(eid, zsp, prefix, nvp);
		break;
	case DATA_TYPE_INT32_ARRAY:
		_zed_event_add_int32_array(eid, zsp, prefix, nvp);
		break;
	case DATA_TYPE_UINT32_ARRAY:
		_zed_event_add_uint32_array(eid, zsp, prefix, nvp);
		break;
	case DATA_TYPE_INT64_ARRAY:
		_zed_event_add_int64_array(eid, zsp, prefix, nvp);
		break;
	case DATA_TYPE_UINT64_ARRAY:
		_zed_event_add_uint64_array(eid, zsp, prefix, nvp);
		break;
	case DATA_TYPE_STRING_ARRAY:
		_zed_event_add_string_array(eid, zsp, prefix, nvp);
		break;
	case DATA_TYPE_NVLIST_ARRAY:
		_zed_event_add_var(eid, zsp, prefix, name,
		    "%s", "_NOT_IMPLEMENTED_");			/* FIXME */
		break;
	default:
		errno = EINVAL;
		zed_log_msg(LOG_WARNING,
		    "Failed to convert nvpair \"%s\" for eid=%llu: "
		    "Unrecognized type=%u", name, eid, (unsigned int) type);
		break;
	}
}
Beispiel #29
0
/*
 * nvlist_print - Prints elements in an event buffer
 */
static
void
nvlist_print_with_indent(FILE *fp, nvlist_t *nvl, int depth)
{
	int i;
	char *name;
	uint_t nelem;
	nvpair_t *nvp;

	if (nvl == NULL)
		return;

	indent(fp, depth);
	(void) fprintf(fp, "nvlist version: %d\n", NVL_VERSION(nvl));

	nvp = nvlist_next_nvpair(nvl, NULL);

	while (nvp) {
		data_type_t type = nvpair_type(nvp);

		indent(fp, depth);
		name = nvpair_name(nvp);
		(void) fprintf(fp, "\t%s =", name);
		nelem = 0;
		switch (type) {
		case DATA_TYPE_BOOLEAN: {
			(void) fprintf(fp, " 1");
			break;
		}
		case DATA_TYPE_BOOLEAN_VALUE: {
			boolean_t val;
			(void) nvpair_value_boolean_value(nvp, &val);
			(void) fprintf(fp, " %d", val);
			break;
		}
		case DATA_TYPE_BYTE: {
			uchar_t val;
			(void) nvpair_value_byte(nvp, &val);
			(void) fprintf(fp, " 0x%2.2x", val);
			break;
		}
		case DATA_TYPE_INT8: {
			int8_t val;
			(void) nvpair_value_int8(nvp, &val);
			(void) fprintf(fp, " %d", val);
			break;
		}
		case DATA_TYPE_UINT8: {
			uint8_t val;
			(void) nvpair_value_uint8(nvp, &val);
			(void) fprintf(fp, " 0x%x", val);
			break;
		}
		case DATA_TYPE_INT16: {
			int16_t val;
			(void) nvpair_value_int16(nvp, &val);
			(void) fprintf(fp, " %d", val);
			break;
		}
		case DATA_TYPE_UINT16: {
			uint16_t val;
			(void) nvpair_value_uint16(nvp, &val);
			(void) fprintf(fp, " 0x%x", val);
			break;
		}
		case DATA_TYPE_INT32: {
			int32_t val;
			(void) nvpair_value_int32(nvp, &val);
			(void) fprintf(fp, " %d", val);
			break;
		}
		case DATA_TYPE_UINT32: {
			uint32_t val;
			(void) nvpair_value_uint32(nvp, &val);
			(void) fprintf(fp, " 0x%x", val);
			break;
		}
		case DATA_TYPE_INT64: {
			int64_t val;
			(void) nvpair_value_int64(nvp, &val);
			(void) fprintf(fp, " %lld", (longlong_t)val);
			break;
		}
		case DATA_TYPE_UINT64: {
			uint64_t val;
			(void) nvpair_value_uint64(nvp, &val);
			(void) fprintf(fp, " 0x%llx", (u_longlong_t)val);
			break;
		}
		case DATA_TYPE_DOUBLE: {
			double val;
			(void) nvpair_value_double(nvp, &val);
			(void) fprintf(fp, " 0x%llf", val);
			break;
		}
		case DATA_TYPE_STRING: {
			char *val;
			(void) nvpair_value_string(nvp, &val);
			(void) fprintf(fp, " %s", val);
			break;
		}
		case DATA_TYPE_BOOLEAN_ARRAY: {
			boolean_t *val;
			(void) nvpair_value_boolean_array(nvp, &val, &nelem);
			for (i = 0; i < nelem; i++)
				(void) fprintf(fp, " %d", val[i]);
			break;
		}
		case DATA_TYPE_BYTE_ARRAY: {
			uchar_t *val;
			(void) nvpair_value_byte_array(nvp, &val, &nelem);
			for (i = 0; i < nelem; i++)
				(void) fprintf(fp, " 0x%2.2x", val[i]);
			break;
		}
		case DATA_TYPE_INT8_ARRAY: {
			int8_t *val;
			(void) nvpair_value_int8_array(nvp, &val, &nelem);
			for (i = 0; i < nelem; i++)
				(void) fprintf(fp, " %d", val[i]);
			break;
		}
		case DATA_TYPE_UINT8_ARRAY: {
			uint8_t *val;
			(void) nvpair_value_uint8_array(nvp, &val, &nelem);
			for (i = 0; i < nelem; i++)
				(void) fprintf(fp, " 0x%x", val[i]);
			break;
		}
		case DATA_TYPE_INT16_ARRAY: {
			int16_t *val;
			(void) nvpair_value_int16_array(nvp, &val, &nelem);
			for (i = 0; i < nelem; i++)
				(void) fprintf(fp, " %d", val[i]);
			break;
		}
		case DATA_TYPE_UINT16_ARRAY: {
			uint16_t *val;
			(void) nvpair_value_uint16_array(nvp, &val, &nelem);
			for (i = 0; i < nelem; i++)
				(void) fprintf(fp, " 0x%x", val[i]);
			break;
		}
		case DATA_TYPE_INT32_ARRAY: {
			int32_t *val;
			(void) nvpair_value_int32_array(nvp, &val, &nelem);
			for (i = 0; i < nelem; i++)
				(void) fprintf(fp, " %d", val[i]);
			break;
		}
		case DATA_TYPE_UINT32_ARRAY: {
			uint32_t *val;
			(void) nvpair_value_uint32_array(nvp, &val, &nelem);
			for (i = 0; i < nelem; i++)
				(void) fprintf(fp, " 0x%x", val[i]);
			break;
		}
		case DATA_TYPE_INT64_ARRAY: {
			int64_t *val;
			(void) nvpair_value_int64_array(nvp, &val, &nelem);
			for (i = 0; i < nelem; i++)
				(void) fprintf(fp, " %lld", (longlong_t)val[i]);
			break;
		}
		case DATA_TYPE_UINT64_ARRAY: {
			uint64_t *val;
			(void) nvpair_value_uint64_array(nvp, &val, &nelem);
			for (i = 0; i < nelem; i++)
				(void) fprintf(fp, " 0x%llx",
				    (u_longlong_t)val[i]);
			break;
		}
		case DATA_TYPE_STRING_ARRAY: {
			char **val;
			(void) nvpair_value_string_array(nvp, &val, &nelem);
			for (i = 0; i < nelem; i++)
				(void) fprintf(fp, " %s", val[i]);
			break;
		}
		case DATA_TYPE_HRTIME: {
			hrtime_t val;
			(void) nvpair_value_hrtime(nvp, &val);
			(void) fprintf(fp, " 0x%llx", val);
			break;
		}
		case DATA_TYPE_NVLIST: {
			nvlist_t *val;
			(void) nvpair_value_nvlist(nvp, &val);
			(void) fprintf(fp, " (embedded nvlist)\n");
			nvlist_print_with_indent(fp, val, depth + 1);
			indent(fp, depth + 1);
			(void) fprintf(fp, "(end %s)\n", name);
			break;
		}
		case DATA_TYPE_NVLIST_ARRAY: {
			nvlist_t **val;
			(void) nvpair_value_nvlist_array(nvp, &val, &nelem);
			(void) fprintf(fp, " (array of embedded nvlists)\n");
			for (i = 0; i < nelem; i++) {
				indent(fp, depth + 1);
				(void) fprintf(fp,
				    "(start %s[%d])\n", name, i);
				nvlist_print_with_indent(fp, val[i], depth + 1);
				indent(fp, depth + 1);
				(void) fprintf(fp, "(end %s[%d])\n", name, i);
			}
			break;
		}
		default:
			(void) fprintf(fp, " unknown data type (%d)", type);
			break;
		}
		(void) fprintf(fp, "\n");
		nvp = nvlist_next_nvpair(nvl, nvp);
	}
}
Beispiel #30
0
/*
 * Returns 'in use' details, if found, about a specific dev_name,
 * based on the caller(who). It is important to note that it is possible
 * for there to be more than one 'in use' statistic regarding a dev_name.
 * The **msg parameter returns a list of 'in use' details. This message
 * is formatted via gettext().
 */
int
dm_inuse(char *dev_name, char **msg, dm_who_type_t who, int *errp)
{
	nvlist_t *dev_stats = NULL;
	char *by, *data;
	nvpair_t *nvwhat = NULL;
	nvpair_t *nvdesc = NULL;
	int	found = 0;
	int	err;
	char	*dname = NULL;

	*errp = 0;
	*msg = NULL;

	/*
	 * If the user doesn't want to do in use checking, return.
	 */

	if (NOINUSE_SET)
		return (0);

	dname = getfullblkname(dev_name);
	/*
	 * If we cannot find the block name, we cannot check the device
	 * for in use statistics. So, return found, which is == 0.
	 */
	if (dname == NULL || *dname == '\0') {
		return (found);
	}

	/*
	 * Slice stats for swap devices are only returned if mounted
	 * (e.g. /tmp).  Other devices or files being used for swap
	 * are ignored, so we add a special check here to use swapctl(2)
	 * to perform in-use checking.
	 */
	if (ANY_ZPOOL_USE(who) && (err = dm_inuse_swap(dname, errp))) {

		/* on error, dm_inuse_swap sets errp */
		if (err < 0) {
			free(dname);
			return (err);
		}

		/* simulate a mounted swap device */
		(void) build_usage_string(dname, DM_USE_MOUNT, "swap", msg,
		    &found, errp);

		/* if this fails, dm_get_usage_string changed */
		ASSERT(found == 1);

		free(dname);
		return (found);
	}

	dm_get_slice_stats(dname, &dev_stats, errp);
	if (dev_stats == NULL) {
		/*
		 * If there is an error, but it isn't a no device found error
		 * return the error as recorded. Otherwise, with a full
		 * block name, we might not be able to get the slice
		 * associated, and will get an ENODEV error. For example,
		 * an SVM metadevice will return a value from getfullblkname()
		 * but libdiskmgt won't be able to find this device for
		 * statistics gathering. This is expected and we should not
		 * report errnoneous errors.
		 */
		if (*errp) {
			if (*errp == ENODEV) {
				*errp = 0;
			}
		}
		free(dname);
		return (found);
	}

	for (;;) {

		nvwhat = nvlist_next_nvpair(dev_stats, nvdesc);
		nvdesc = nvlist_next_nvpair(dev_stats, nvwhat);

		/*
		 * End of the list found.
		 */
		if (nvwhat == NULL || nvdesc == NULL) {
			break;
		}
		/*
		 * Otherwise, we check to see if this client(who) cares
		 * about this in use scenario
		 */

		ASSERT(strcmp(nvpair_name(nvwhat), DM_USED_BY) == 0);
		ASSERT(strcmp(nvpair_name(nvdesc), DM_USED_NAME) == 0);
		/*
		 * If we error getting the string value continue on
		 * to the next pair(if there is one)
		 */
		if (nvpair_value_string(nvwhat, &by)) {
			continue;
		}
		if (nvpair_value_string(nvdesc, &data)) {
			continue;
		}

		switch (who) {
			case DM_WHO_MKFS:
				/*
				 * mkfs is not in use for these cases.
				 * All others are in use.
				 */
				if (strcmp(by, DM_USE_LU) == 0 ||
				    strcmp(by, DM_USE_FS) == 0 ||
				    strcmp(by, DM_USE_EXPORTED_ZPOOL) == 0) {
					break;
				}
				if (build_usage_string(dname,
				    by, data, msg, &found, errp) != 0) {
					if (*errp) {
						goto out;
					}
				}
				break;
			case DM_WHO_SWAP:
				/*
				 * Not in use for this.
				 */
				if (strcmp(by, DM_USE_DUMP) == 0 ||
				    strcmp(by, DM_USE_FS) == 0 ||
				    strcmp(by, DM_USE_EXPORTED_ZPOOL) == 0) {
					break;
				}
				if (strcmp(by, DM_USE_LU) == 0 &&
				    strcmp(data, "-") == 0) {
					break;
				}
				if (strcmp(by, DM_USE_VFSTAB) == 0 &&
				    strcmp(data, "") == 0) {
					break;
				}
				if (build_usage_string(dname,
				    by, data, msg, &found, errp) != 0) {
					if (*errp) {
						goto out;
					}
				}
				break;
			case DM_WHO_DUMP:
				/*
				 * Not in use for this.
				 */
				if ((strcmp(by, DM_USE_MOUNT) == 0 &&
				    strcmp(data, "swap") == 0) ||
				    strcmp(by, DM_USE_DUMP) == 0 ||
				    strcmp(by, DM_USE_FS) == 0 ||
				    strcmp(by, DM_USE_EXPORTED_ZPOOL) == 0) {
					break;
				}
				if (build_usage_string(dname,
				    by, data, msg, &found, errp)) {
					if (*errp) {
						goto out;
					}
				}
				break;

			case DM_WHO_FORMAT:
				if (strcmp(by, DM_USE_FS) == 0 ||
				    strcmp(by, DM_USE_EXPORTED_ZPOOL) == 0)
					break;
				if (build_usage_string(dname,
				    by, data, msg, &found, errp) != 0) {
					if (*errp) {
						goto out;
					}
				}
				break;

			case DM_WHO_ZPOOL_FORCE:
				if (strcmp(by, DM_USE_FS) == 0 ||
				    strcmp(by, DM_USE_EXPORTED_ZPOOL) == 0)
					break;
				/* FALLTHROUGH */
			case DM_WHO_ZPOOL:
				if (build_usage_string(dname,
				    by, data, msg, &found, errp) != 0) {
					if (*errp)
						goto out;
				}
				break;

			case DM_WHO_ZPOOL_SPARE:
				if (strcmp(by, DM_USE_SPARE_ZPOOL) != 0) {
					if (build_usage_string(dname, by,
					    data, msg, &found, errp) != 0) {
						if (*errp)
							goto out;
					}
				}
				break;

			default:
				/*
				 * nothing found in use for this client
				 * of libdiskmgt. Default is 'not in use'.
				 */
				break;
		}
	}
out:
	if (dname != NULL)
		free(dname);
	if (dev_stats != NULL)
		nvlist_free(dev_stats);

	return (found);
}