Exemplo n.º 1
0
/**
 * Create a led objects
 * @param par pointer to an object, it will be the parent of the new led
 * @param copy pointer to a led object, if not NULL then the new object will be copied from it
 * @return pointer to the created led
 */
lv_obj_t * lv_led_create(lv_obj_t * par, lv_obj_t * copy)
{
    /*Create the ancestor basic object*/
	lv_obj_t * new_led = lv_obj_create(par, copy);
    dm_assert(new_led);
    
    /*Allocate the object type specific extended data*/
    lv_led_ext_t * ext = lv_obj_alloc_ext(new_led, sizeof(lv_led_ext_t));
    dm_assert(ext);
    ext->bright = LV_LED_BRIGHT_ON;

    if(ancestor_design_f == NULL) ancestor_design_f = lv_obj_get_design_f(new_led);

    lv_obj_set_signal_f(new_led, lv_led_signal);
    lv_obj_set_design_f(new_led, lv_led_design);

    /*Init the new led object*/
    if(copy == NULL) {
    	lv_obj_set_style(new_led, lv_style_get(LV_STYLE_PRETTY_COLOR, NULL));
    	lv_obj_set_size(new_led, LV_LED_WIDTH_DEF, LV_LED_HEIGHT_DEF);
    }
    /*Copy an existing object*/
    else {
    	lv_led_ext_t * copy_ext = lv_obj_get_ext(copy);
    	ext->bright = copy_ext->bright;

        /*Refresh the style with new signal function*/
        lv_obj_refr_style(new_led);
    }
    
    return new_led;
}
Exemplo n.º 2
0
static dm_plugin_t *
protocol_to_dm_plugin(const char *protocol)
{
	dm_plugin_t *plugin;

	/*
	 * Traversing the plugin list must be atomic with
	 * respect to plugin loads
	 */
	dm_assert(pthread_mutex_lock(&plugin_list_mutex) == 0);

	plugin = plugin_list;

	while (plugin != NULL) {
		if (strcmp(plugin->protocol, protocol) == 0) {
			break;
		}

		plugin = plugin->next;
	}

	/* Wasn't found -- load, initialize, and return it */
	plugin = (plugin == NULL) ? load_and_init_dm_plugin(protocol) :
	    plugin;

	dm_assert(pthread_mutex_unlock(&plugin_list_mutex) == 0);

	return (plugin);
}
Exemplo n.º 3
0
/**
 * Create a template objects
 * @param par pointer to an object, it will be the parent of the new template
 * @param copy pointer to a template object, if not NULL then the new object will be copied from it
 * @return pointer to the created template
 */
lv_obj_t * lv_templ_create(lv_obj_t * par, lv_obj_t * copy)
{
    /*Create the ancestor of template*/
	/*TODO modify it to the ancestor create function */
    lv_obj_t * new_templ = lv_ANCESTOR_create(par, copy);
    dm_assert(new_templ);
    
    /*Allocate the template type specific extended data*/
    lv_templ_ext_t * ext = lv_obj_alloc_ext(new_templ, sizeof(lv_templ_ext_t));
    dm_assert(ext);

    /*Initialize the allocated 'ext' */
    ext->xyz = 0;

    /*The signal and design functions are not copied so set them here*/
    lv_obj_set_signal_f(new_templ, lv_templ_signal);
    lv_obj_set_design_f(new_templ, lv_templ_design);

    /*Init the new template template*/
    if(copy == NULL) {
        lv_obj_set_style(new_templ, lv_style_get(LV_STYLE_PRETTY, NULL));
    }
    /*Copy an existing template*/
    else {
    	lv_templ_ext_t * copy_ext = lv_obj_get_ext(copy);

        /*Refresh the style with new signal function*/
        lv_obj_refr_style(new_templ);
    }
    
    return new_templ;
}
Exemplo n.º 4
0
dm_plugin_error_t
dm_pm_indicator_execute(const char *action)
{
	dm_plugin_t *dmpip;
	char *protocol = extract_protocol(action); /* memory allocated here */
	char *actionp = extract_action(action);
	dm_plugin_action_handle_impl_t *hip;

	dmpip = protocol_to_dm_plugin(protocol);
	dstrfree(protocol);

	if (dmpip != NULL) {

		if ((hip = lookup_handle_by_action(actionp)) == NULL) {
			if (bind_action_handle(dmpip, actionp,
			    (dm_plugin_action_handle_t *)&hip) != DMPE_SUCCESS)
				return (DMPE_FAILURE);
		}

		dm_assert(dmpip->state == DMPS_INITED);
		if (dmpip->ops->indicator_execute)
			return (dmpip->ops->indicator_execute(hip->handle));
	}

	return (DMPE_FAILURE);
}
Exemplo n.º 5
0
dm_plugin_error_t
dm_pm_update_fru(const char *action, dm_fru_t *frup)
{
	char *protocol = extract_protocol(action);	/* mem alloced here */
	char *actionp = extract_action(action);
	dm_plugin_t *dmpip;

	if (protocol == NULL) {
		log_warn("FRU update: Invalid protocol specified in action "
		    "`%s'\n", action);
		return (DMPE_FAILURE);
	}

	dmpip = protocol_to_dm_plugin(protocol);
	dstrfree(protocol);

	if (dmpip != NULL) {
		dm_assert(dmpip->state == DMPS_INITED);
		if (dmpip->ops->indicator_fru_update)
			return (dmpip->ops->indicator_fru_update(actionp,
			    frup));
	}

	return (DMPE_FAILURE);
}
Exemplo n.º 6
0
static dm_plugin_t *
load_dm_plugin(const char *protocol)
{
	dm_plugin_t *dmpip = NULL;
	boolean_t plugin_loaded = B_FALSE;

	/*
	 * Validate the protocol string -- if there are any non-alphanumeric
	 * characters, it's not a valid protocol string.
	 */
	if (safe_protocol_string(protocol) == B_FALSE) {
		log_warn("Invalid characters in plugin protocol `%s'.\n",
		    protocol);
		goto fpi_out;
	}

	dmpip = new_dm_plugin(protocol);

	plugin_loaded = do_load_dm_plugin(dmpip);

fpi_out:
	if (plugin_loaded) {
		dm_assert(dmpip != NULL);
		dmpip->state = DMPS_LOADED;
	} else if (!plugin_loaded && dmpip != NULL)
		free_dm_plugin(&dmpip);

	return (dmpip);
}
Exemplo n.º 7
0
static nvlist_t *
find_disk_monitor_private_pgroup(tnode_t *node)
{
	int err;
	nvlist_t *list_of_lists, *nvlp, *dupnvlp;
	nvlist_t *disk_monitor_pgrp = NULL;
	nvpair_t *nvp = NULL;
	char *pgroup_name;

	/*
	 * topo_prop_get_all() returns an nvlist that contains other
	 * nvlists (some of which are property groups).  Since the private
	 * property group we need will be among the list of property
	 * groups returned (hopefully), we need to walk the list of nvlists
	 * in the topo node's properties to find the property groups, then
	 * check inside each embedded nvlist to see if it's the pgroup we're
	 * looking for.
	 */
	if ((list_of_lists = topo_prop_getprops(node, &err)) != NULL) {
		/*
		 * Go through the list of nvlists, looking for the
		 * property group we need.
		 */
		while ((nvp = nvlist_next_nvpair(list_of_lists, nvp)) != NULL) {

			if (nvpair_type(nvp) != DATA_TYPE_NVLIST ||
			    strcmp(nvpair_name(nvp), TOPO_PROP_GROUP) != 0 ||
			    nvpair_value_nvlist(nvp, &nvlp) != 0)
				continue;

			dm_assert(nvlp != NULL);
			pgroup_name = NULL;

			if (nonunique_nvlist_lookup_string(nvlp,
			    TOPO_PROP_GROUP_NAME, &pgroup_name) != 0 ||
			    strcmp(pgroup_name, DISK_MONITOR_PROPERTIES) != 0)
				continue;
			else {
				/*
				 * Duplicate the nvlist so that when the
				 * master nvlist is freed (below), we will
				 * still refer to allocated memory.
				 */
				if (nvlist_dup(nvlp, &dupnvlp, 0) == 0)
					disk_monitor_pgrp = dupnvlp;
				else
					disk_monitor_pgrp = NULL;
				break;
			}
		}

		nvlist_free(list_of_lists);
	}

	return (disk_monitor_pgrp);
}
Exemplo n.º 8
0
static dm_plugin_action_handle_impl_t *
lookup_handle_by_action(const char *action)
{
	dm_plugin_action_handle_impl_t *handle;

	dm_assert(pthread_mutex_lock(&handle_list_mutex) == 0);

	handle = handle_list;

	while (handle != NULL) {
		if (strcmp(handle->actionString, action) == 0)
			break;

		handle = handle->next;
	}

	dm_assert(pthread_mutex_unlock(&handle_list_mutex) == 0);

	return (handle);
}
Exemplo n.º 9
0
static dm_plugin_action_handle_impl_t *
new_action_handle(const char *action, dm_plugin_t *pluginp)
{
	dm_plugin_action_handle_impl_t *hip;

	hip = (dm_plugin_action_handle_impl_t *)dmalloc(
	    sizeof (dm_plugin_action_handle_impl_t));

	hip->actionString = dstrdup(action);
	hip->plugin = pluginp;
	hip->handle = (dm_plugin_action_handle_t)NULL;

	/* Add the handle to the global list */
	dm_assert(pthread_mutex_lock(&handle_list_mutex) == 0);
	hip->next = handle_list;
	handle_list = hip;
	dm_assert(pthread_mutex_unlock(&handle_list_mutex) == 0);

	return (hip);
}
Exemplo n.º 10
0
static dm_plugin_error_t
bind_action_handle(dm_plugin_t *dmpip, const char *action,
    dm_plugin_action_handle_t *hdlp)
{
	dm_plugin_action_handle_impl_t *hip;

	hip = new_action_handle(action, dmpip);
	*hdlp = hip;

	dm_assert(dmpip->state == DMPS_INITED);
	if (dmpip->ops->indicator_bind_handle)
		return (dmpip->ops->indicator_bind_handle(action,
		    &hip->handle));

	return (DMPE_FAILURE);
}
Exemplo n.º 11
0
static int
topo_add_bay(topo_hdl_t *thp, tnode_t *node, walk_diskmon_t *wdp)
{
	diskmon_t *target_diskp = wdp->target;
	nvlist_t	*nvlp = find_disk_monitor_private_pgroup(node);
	nvlist_t	*prop_nvlp;
	nvpair_t	*nvp = NULL;
	char		*prop_name, *prop_value;
#define	PNAME_MAX 128
	char		pname[PNAME_MAX];
	char		msgbuf[MAX_CONF_MSG_LEN];
	char		*indicator_name, *indicator_action;
	char		*indrule_states, *indrule_actions;
	int		err = 0, i;
	conf_err_t	conferr;
	boolean_t	conf_failure = B_FALSE;
	char		*unadj_physid = NULL;
	char		physid[MAXPATHLEN];
	char		*label;
	nvlist_t	*diskprops = NULL;
	char		*cstr = NULL;
	indicator_t	*indp = NULL;
	indrule_t	*indrp = NULL;
	void		*p;
	diskmon_t	*diskp;
	void		*ptr;

	/* No private properties -- just ignore the port */
	if (nvlp == NULL)
		return (0);

	/*
	 * Look for a diskmon based on this node's FMRI string.
	 * Once a diskmon has been created, it's not re-created.  This is
	 * essential for the times when the tree-walk is called after a
	 * disk is inserted (or removed) -- in that case, the disk node
	 * handler simply updates the FRU information in the diskmon.
	 */
	if ((p = fmri2ptr(thp, node, &cstr, &err)) != NULL) {

		diskp = (diskmon_t *)p;

		/*
		 * Delete the FRU information from the diskmon.  If a disk
		 * is connected, its FRU information will be refreshed by
		 * the disk node code.
		 */
		if (diskp->frup && (target_diskp == NULL ||
		    diskp == target_diskp)) {
			dm_assert(pthread_mutex_lock(&diskp->fru_mutex) == 0);
			dmfru_free(diskp->frup);
			diskp->frup = NULL;
			dm_assert(pthread_mutex_unlock(&diskp->fru_mutex) == 0);
		}

		wdp->pfmri = cstr;
		nvlist_free(nvlp);
		return (0);
	}

	/*
	 * Determine the physical path to the attachment point
	 */
	if (topo_prop_get_string(node, TOPO_PGROUP_IO,
	    TOPO_IO_AP_PATH, &unadj_physid, &err) == 0) {

		adjust_dynamic_ap(unadj_physid, physid);
		topo_hdl_strfree(thp, unadj_physid);
	} else {

		/* unadj_physid cannot have been allocated */
		if (cstr)
			dstrfree(cstr);
		nvlist_free(nvlp);
		return (-1);
	}

	/*
	 */

	/*
	 * Process the properties.  If we encounter a property that
	 * is not an indicator name, action, or rule, add it to the
	 * disk's props list.
	 */

	/* Process indicators */
	i = 0;
	indicator_name = NULL;
	indicator_action = NULL;
	do {
		if (indicator_name != NULL && indicator_action != NULL) {

			if (topoprop_indicator_add(&indp, indicator_name,
			    indicator_action) != 0) {

				conf_failure = B_TRUE;
			}

			topo_hdl_strfree(thp, indicator_name);
			topo_hdl_strfree(thp, indicator_action);
		}

		(void) snprintf(pname, PNAME_MAX, BAY_IND_NAME "-%d", i);
		if (topo_prop_get_string(node, DISK_MONITOR_PROPERTIES,
		    pname, &indicator_name, &err) != 0)
			break;

		(void) snprintf(pname, PNAME_MAX, BAY_IND_ACTION "-%d", i);
		if (topo_prop_get_string(node, DISK_MONITOR_PROPERTIES,
		    pname, &indicator_action, &err) != 0)
			break;

		i++;
	} while (!conf_failure && indicator_name != NULL &&
	    indicator_action != NULL);

	if (!conf_failure && indp != NULL &&
	    (conferr = check_inds(indp)) != E_NO_ERROR) {
		conf_error_msg(conferr, msgbuf, MAX_CONF_MSG_LEN, NULL);
		log_msg(MM_CONF, "%s: Not adding disk to list\n", msgbuf);
		conf_failure = B_TRUE;
	}

	/* Process state rules and indicator actions */
	i = 0;
	indrule_states = NULL;
	indrule_actions = NULL;
	do {
		if (indrule_states != NULL && indrule_actions != NULL) {

			if (topoprop_indrule_add(&indrp, indrule_states,
			    indrule_actions) != 0) {

				conf_failure = B_TRUE;
			}

			topo_hdl_strfree(thp, indrule_states);
			topo_hdl_strfree(thp, indrule_actions);
		}

		(void) snprintf(pname, PNAME_MAX, BAY_INDRULE_STATES "-%d", i);
		if (topo_prop_get_string(node, DISK_MONITOR_PROPERTIES,
		    pname, &indrule_states, &err) != 0)
			break;

		(void) snprintf(pname, PNAME_MAX, BAY_INDRULE_ACTIONS "-%d",
		    i);
		if (topo_prop_get_string(node, DISK_MONITOR_PROPERTIES,
		    pname, &indrule_actions, &err) != 0)
			break;

		i++;
	} while (!conf_failure && indrule_states != NULL &&
	    indrule_actions != NULL);

	if (!conf_failure && indrp != NULL && indp != NULL &&
	    ((conferr = check_indrules(indrp, (state_transition_t **)&ptr))
	    != E_NO_ERROR ||
	    (conferr = check_consistent_ind_indrules(indp, indrp,
	    (ind_action_t **)&ptr)) != E_NO_ERROR)) {

		conf_error_msg(conferr, msgbuf, MAX_CONF_MSG_LEN, ptr);
		log_msg(MM_CONF, "%s: Not adding disk to list\n", msgbuf);
		conf_failure = B_TRUE;

	}

	/*
	 * Now collect miscellaneous properties.
	 * Each property is stored as an embedded nvlist named
	 * TOPO_PROP_VAL.  The property name is stored in the value for
	 * key=TOPO_PROP_VAL_NAME and the property's value is
	 * stored in the value for key=TOPO_PROP_VAL_VAL.  This is all
	 * necessary so we can subtractively decode the properties that
	 * we do not directly handle (so that these properties are added to
	 * the per-disk properties nvlist), increasing flexibility.
	 */
	(void) nvlist_alloc(&diskprops, NV_UNIQUE_NAME, 0);
	while ((nvp = nvlist_next_nvpair(nvlp, nvp)) != NULL) {
		/* Only care about embedded nvlists named TOPO_PROP_VAL */
		if (nvpair_type(nvp) != DATA_TYPE_NVLIST ||
		    strcmp(nvpair_name(nvp), TOPO_PROP_VAL) != 0 ||
		    nvpair_value_nvlist(nvp, &prop_nvlp) != 0)
			continue;

		if (nonunique_nvlist_lookup_string(prop_nvlp,
		    TOPO_PROP_VAL_NAME, &prop_name) != 0)
			continue;

		/* Filter out indicator properties */
		if (strstr(prop_name, BAY_IND_NAME) != NULL ||
		    strstr(prop_name, BAY_IND_ACTION) != NULL ||
		    strstr(prop_name, BAY_INDRULE_STATES) != NULL ||
		    strstr(prop_name, BAY_INDRULE_ACTIONS) != NULL)
			continue;

		if (nonunique_nvlist_lookup_string(prop_nvlp, TOPO_PROP_VAL_VAL,
		    &prop_value) != 0)
			continue;

		/* Add the property to the disk's prop list: */
		if (nvlist_add_string(diskprops, prop_name, prop_value) != 0)
			log_msg(MM_TOPO,
			    "Could not add disk property `%s' with "
			    "value `%s'\n", prop_name, prop_value);
	}

	nvlist_free(nvlp);

	if (cstr != NULL) {
		namevalpr_t nvpr;
		nvlist_t *dmap_nvl;

		nvpr.name = DISK_AP_PROP_APID;
		nvpr.value = strncmp(physid, "/devices", 8) == 0 ?
		    (physid + 8) : physid;

		/*
		 * Set the diskmon's location to the value in this port's label.
		 * If there's a disk plugged in, the location will be updated
		 * to be the disk label (e.g. HD_ID_00).  Until a disk is
		 * inserted, though, there won't be a disk libtopo node
		 * created.
		 */

		/* Pass physid without the leading "/devices": */
		dmap_nvl = namevalpr_to_nvlist(&nvpr);

		diskp = new_diskmon(dmap_nvl, indp, indrp, diskprops);

		if (topo_node_label(node, &label, &err) == 0) {
			diskp->location = dstrdup(label);
			topo_hdl_strfree(thp, label);
		} else
			diskp->location = dstrdup("unknown location");

		if (!conf_failure && diskp != NULL) {
			/* Add this diskmon to the disk list */
			cfgdata_add_diskmon(config_data, diskp);
			if (nvlist_add_uint64(g_topo2diskmon, cstr,
			    (uint64_t)(uintptr_t)diskp) != 0) {
				log_msg(MM_TOPO,
				    "Could not add pointer to nvlist "
				    "for `%s'!\n", cstr);
			}
		} else if (diskp != NULL) {
			diskmon_free(diskp);
		} else {
			if (dmap_nvl)
				nvlist_free(dmap_nvl);
			if (indp)
				ind_free(indp);
			if (indrp)
				indrule_free(indrp);
			if (diskprops)
				nvlist_free(diskprops);
		}

		wdp->pfmri = cstr;
	}


	return (0);
}
Exemplo n.º 12
0
static int
topoprop_indrule_add(indrule_t **indrp, char *sts, char *acts)
{
	ind_action_t		*indactp = NULL;
	ind_state_t		state;
	char			*name, *lasts, *p;
	int			stateslen = strlen(sts) + 1;
	int			actionslen = strlen(acts) + 1;
	char			*states = dstrdup(sts);
	char			*actions = dstrdup(acts);
	state_transition_t	strans;
	boolean_t		failed = B_FALSE;
	conf_err_t		err;
	char			msgbuf[MAX_CONF_MSG_LEN];

	/* The state string is of the form "{STATE}>{STATE}" */
	p = strchr(states, '>');
	dm_assert(p != NULL);
	*p = 0;
	strans.begin = str2dmstate(states);
	*p = '>';
	strans.end = str2dmstate(p + 1);

	if (strans.begin == HPS_UNKNOWN || strans.end == HPS_UNKNOWN) {
		log_msg(MM_CONF, "Invalid states property `%s'\n", sts);
		failed = B_TRUE;
	} else if ((err = check_state_transition(strans.begin, strans.end))
	    != E_NO_ERROR) {
		conf_error_msg(err, msgbuf, MAX_CONF_MSG_LEN, &strans);
		log_msg(MM_CONF, "%s: Not adding disk to list!\n", msgbuf);
		failed = B_TRUE;
	}

	/* Actions are of the form "{ACTION}[&{ACTION}]" */
	if (!failed && (p = strtok_r(actions, "&", &lasts)) != NULL) {
		/* At least 2 tokens */
		do {
			if (indicator_breakup(p, &state, &name) != 0) {
				failed = B_TRUE;
				break;
			}

			link_indaction(&indactp, new_indaction(state, name));

		} while ((p = strtok_r(NULL, "&", &lasts)) != NULL);
	} else if (!failed) {
		/* One token */
		if (indicator_breakup(actions, &state, &name) != 0)
			return (-1);
		indactp = new_indaction(state, name);
	}

	dfree(states, stateslen);
	dfree(actions, actionslen);

	if (!failed && (err = check_indactions(indactp)) != E_NO_ERROR) {
		conf_error_msg(err, msgbuf, MAX_CONF_MSG_LEN, NULL);
		log_msg(MM_CONF, "%s: Not adding disk to list!\n", msgbuf);
		failed = B_TRUE;
	}

	if (failed) {
		indaction_free(indactp);
		return (-1);
	} else
		link_indrule(indrp, new_indrule(&strans, indactp));
	return (0);
}
Exemplo n.º 13
0
static int
topo_add_disk(topo_hdl_t *thp, tnode_t *node, walk_diskmon_t *wdp)
{
	diskmon_t *target_diskp = wdp->target;
	char		*devpath = NULL;
	char		*capacity = NULL;
	char		*firmrev = NULL;
	char		*serial = NULL;
	char		*manuf = NULL;
	char		*model = NULL;
	char		*label;
	uint64_t	ptr = 0;
	int		err;
	dm_fru_t	*frup;
	diskmon_t	*diskp;

	if (wdp->pfmri == NULL) {
		log_msg(MM_TOPO, "No diskmon for parent of node %p.\n", node);
		return (0);
	}

	if (nvlist_lookup_uint64(g_topo2diskmon, wdp->pfmri, &ptr) != 0) {
		log_msg(MM_TOPO, "No diskmon for %s: parent of node %p.\n",
		    wdp->pfmri, node);
		dstrfree(wdp->pfmri);
		/* Skip this disk: */
		return (0);
	}

	dstrfree(wdp->pfmri);
	wdp->pfmri = NULL;

	diskp = (diskmon_t *)(uintptr_t)ptr;

	/* If we were called upon to update a particular disk, do it */
	if (target_diskp != NULL && diskp != target_diskp) {
		return (0);
	}

	/*
	 * Update the diskmon's location field with the disk's label
	 */
	if (diskp->location)
		dstrfree(diskp->location);
	if (topo_node_label(node, &label, &err) == 0) {
		diskp->location = dstrdup(label);
		topo_hdl_strfree(thp, label);
	} else
		diskp->location = dstrdup("unknown location");

	/*
	 * Check for a device path property (if the disk is configured,
	 * it will be present) and add it to the diskmon's properties)
	 */
	if (topo_prop_get_string(node, TOPO_PGROUP_IO, TOPO_IO_DEV_PATH,
	    &devpath, &err) == 0) {
		char devp[PATH_MAX];
		/*
		 * Consumers of the DISK_PROP_DEVPATH property expect a raw
		 * minor device node
		 */
		(void) snprintf(devp, PATH_MAX, "%s:q,raw", devpath);
		(void) nvlist_add_string(diskp->props, DISK_PROP_DEVPATH,
		    devp);
		topo_hdl_strfree(thp, devpath);
	}

	/*
	 * Add the logical disk node, if it exists
	 */
	if (topo_prop_get_string(node, TOPO_STORAGE_PGROUP,
	    TOPO_STORAGE_LOGICAL_DISK_NAME, &devpath, &err) == 0) {
		(void) nvlist_add_string(diskp->props, DISK_PROP_LOGNAME,
		    devpath);
		topo_hdl_strfree(thp, devpath);
	}

	/*
	 * Add the FRU information (if present in the node) to the diskmon's
	 * fru data structure:
	 */
	(void) topo_prop_get_string(node, TOPO_STORAGE_PGROUP,
	    TOPO_STORAGE_MODEL, &model, &err);

	(void) topo_prop_get_string(node, TOPO_STORAGE_PGROUP,
	    TOPO_STORAGE_MANUFACTURER, &manuf, &err);

	(void) topo_prop_get_string(node, TOPO_STORAGE_PGROUP,
	    TOPO_STORAGE_SERIAL_NUM, &serial, &err);

	(void) topo_prop_get_string(node, TOPO_STORAGE_PGROUP,
	    TOPO_STORAGE_FIRMWARE_REV, &firmrev, &err);

	(void) topo_prop_get_string(node, TOPO_STORAGE_PGROUP,
	    TOPO_STORAGE_CAPACITY, &capacity, &err);

	frup = new_dmfru(manuf, model, firmrev, serial,
	    capacity == NULL ? 0 : strtoull(capacity, 0, 0));

	if (model)
		topo_hdl_strfree(thp, model);
	if (manuf)
		topo_hdl_strfree(thp, manuf);
	if (serial)
		topo_hdl_strfree(thp, serial);
	if (firmrev)
		topo_hdl_strfree(thp, firmrev);
	if (capacity)
		topo_hdl_strfree(thp, capacity);

	/* Add the fru information to the diskmon: */
	dm_assert(pthread_mutex_lock(&diskp->fru_mutex) == 0);
	dm_assert(diskp->frup == NULL);
	diskp->frup = frup;
	dm_assert(pthread_mutex_unlock(&diskp->fru_mutex) == 0);

	return (0);
}
Exemplo n.º 14
0
static int
topo_add_disk(topo_hdl_t *thp, tnode_t *node, diskmon_t *target_diskp)
{
	nvlist_t	*fmri = NULL;
	nvlist_t	*asru_fmri;
	nvlist_t	*fru_fmri;
	char		*devpath = NULL;
	char		*capacity = NULL;
	char		*firmrev = NULL;
	char		*serial = NULL;
	char		*manuf = NULL;
	char		*model = NULL;
	char		*cstr = NULL;
	char		*buf;
	char		*label;
	char		*p;
	uint64_t	ptr = 0;
	int		buflen;
	int		err;
	int		orig_cstr_len;
	dm_fru_t	*frup;
	diskmon_t	*diskp;

	/*
	 * Match this node to a disk in the configuration by looking at
	 * our parent's fmri (and do that by getting our FMRI and chopping
	 * off the last part).
	 */
	if (topo_node_resource(node, &fmri, &err) != 0) {
		log_msg(MM_TOPO, "topo_add_disk: Could not generate FMRI for "
		    "node %p!\n", (void *)node);
		return (-1);
	}

	if (topo_fmri_nvl2str(thp, fmri, &cstr, &err) != 0) {
		log_msg(MM_TOPO, "topo_add_disk: Could not create string for "
		    "node %p's FMRI!\n", (void *)node);
		nvlist_free(fmri);
		return (-1);
	}

	nvlist_free(fmri);

	/*
	 * Chop off all but last path (since there's no way to get
	 * the node's parent in the libtopo API).
	 */
	orig_cstr_len = strlen(cstr) + 1;
	p = strrchr(cstr, '/');
	dm_assert(p != NULL);
	*p = 0;
	if (nvlist_lookup_uint64(g_topo2diskmon, cstr, &ptr) != 0) {
		log_msg(MM_TOPO, "No diskmon for parent of node %p.\n", node);
		topo_hdl_free(thp, cstr, orig_cstr_len);
		/* Skip this disk: */
		return (0);
	}

	topo_hdl_free(thp, cstr, orig_cstr_len);

	diskp = (diskmon_t *)(uintptr_t)ptr;

	/* If we were called upon to update a particular disk, do it */
	if (target_diskp != NULL && diskp != target_diskp) {
		return (0);
	}

	/*
	 * Update the diskmon's ASRU and FRU with our information (this
	 * information is cached in the diskmon so we don't have to do a
	 * time-consuming topo traversal when we get an ereport).
	 */
	if (topo_prop_get_fmri(node, TOPO_PGROUP_PROTOCOL, TOPO_PROP_ASRU,
	    &asru_fmri, &err) == 0) {
		diskmon_add_asru(diskp, asru_fmri);
		nvlist_free(asru_fmri);
	}
	if (topo_prop_get_fmri(node, TOPO_PGROUP_PROTOCOL, TOPO_PROP_FRU,
	    &fru_fmri, &err) == 0) {
		diskmon_add_fru(diskp, fru_fmri);
		nvlist_free(fru_fmri);
	}
	if (topo_node_resource(node, &fmri, &err) == 0) {
		diskmon_add_disk_fmri(diskp, fmri);
		nvlist_free(fmri);
	}

	/*
	 * Update the diskmon's location field with the disk's label
	 */
	if (diskp->location)
		dstrfree(diskp->location);
	if (topo_node_label(node, &label, &err) == 0) {
		diskp->location = dstrdup(label);
		topo_hdl_strfree(thp, label);
	} else
		diskp->location = dstrdup("unknown location");

	/*
	 * Check for a device path property (if the disk is configured,
	 * it will be present) and add it to the diskmon's properties)
	 */
	if (topo_prop_get_string(node, TOPO_PGROUP_IO, TOPO_IO_DEV_PATH,
	    &devpath, &err) == 0) {
		char devp[PATH_MAX];
		/*
		 * Consumers of the DISK_PROP_DEVPATH property expect a raw
		 * minor device node
		 */
		(void) snprintf(devp, PATH_MAX, "%s:q,raw", devpath);
		(void) nvlist_add_string(diskp->props, DISK_PROP_DEVPATH,
		    devp);
		topo_hdl_strfree(thp, devpath);
	}

	/*
	 * Add the logical disk node, if it exists
	 */
	if (topo_prop_get_string(node, TOPO_STORAGE_PGROUP,
	    TOPO_STORAGE_LOGICAL_DISK_NAME, &devpath, &err) == 0) {
		(void) nvlist_add_string(diskp->props, DISK_PROP_LOGNAME,
		    devpath);
		topo_hdl_strfree(thp, devpath);
	}

	/*
	 * Add the FRU information (if present in the node) to the diskmon's
	 * fru data structure:
	 */
	(void) topo_prop_get_string(node, TOPO_STORAGE_PGROUP,
	    TOPO_STORAGE_MODEL, &model, &err);

	(void) topo_prop_get_string(node, TOPO_STORAGE_PGROUP,
	    TOPO_STORAGE_MANUFACTURER, &manuf, &err);

	(void) topo_prop_get_string(node, TOPO_STORAGE_PGROUP,
	    TOPO_STORAGE_SERIAL_NUM, &serial, &err);

	(void) topo_prop_get_string(node, TOPO_STORAGE_PGROUP,
	    TOPO_STORAGE_FIRMWARE_REV, &firmrev, &err);

	(void) topo_prop_get_string(node, TOPO_STORAGE_PGROUP,
	    TOPO_STORAGE_CAPACITY, &capacity, &err);

	frup = new_dmfru(manuf, model, firmrev, serial,
	    capacity == NULL ? 0 : strtoull(capacity, 0, 0));

	/*
	 * Update the disk's resource FMRI with the
	 * SunService-required members:
	 * FM_FMRI_HC_SERIAL_ID, FM_FMRI_HC_PART, and
	 * FM_FMRI_HC_REVISION
	 */
	(void) nvlist_add_string(diskp->disk_res_fmri,
	    FM_FMRI_HC_SERIAL_ID, serial);

	transform_model_string(manuf, model, &buf, &buflen);

	(void) nvlist_add_string(diskp->disk_res_fmri,
	    FM_FMRI_HC_PART, buf);

	/*
	 * Add the serial number to the ASRU so that when the resource
	 * is marked faulty in the fmd resource cache, the hc scheme
	 * plugin can detect when the disk is no longer installed (and so,
	 * can clear the faulty state automatically across fmd restarts).
	 *
	 * The serial number is only updated when a disk comes online
	 * because that's when the disk node exists in the topo tree.
	 * It's ok to keep a stale value in the ASRU when the disk is removed
	 * because it's only used as part of fault creation when the disk
	 * is configured (online), at which point it will be updated with
	 * the (current) serial number of the disk inserted.
	 */
	(void) nvlist_add_string(diskp->asru_fmri,
	    FM_FMRI_HC_SERIAL_ID, serial);

	dfree(buf, buflen);

	(void) nvlist_add_string(diskp->disk_res_fmri,
	    FM_FMRI_HC_REVISION, firmrev);

	if (model) {
		topo_hdl_strfree(thp, model);
	}

	if (manuf) {
		topo_hdl_strfree(thp, manuf);
	}

	if (serial) {
		topo_hdl_strfree(thp, serial);
	}

	if (firmrev) {
		topo_hdl_strfree(thp, firmrev);
	}

	if (capacity) {
		topo_hdl_strfree(thp, capacity);
	}

	/* Add the fru information to the diskmon: */
	dm_assert(pthread_mutex_lock(&diskp->fru_mutex) == 0);
	dm_assert(diskp->frup == NULL);
	diskp->frup = frup;
	dm_assert(pthread_mutex_unlock(&diskp->fru_mutex) == 0);

	return (0);
}
Exemplo n.º 15
0
static void XMLCALL
startElement(void *userData, const char *name, const char **atts)
{
	const struct dm_element *kw = NULL;
	DM_VALUE *val = NULL;

	struct XMLstate **state = userData;

	const char *base = (*state)->base;
	int valid = ((*state)->flags & XML_VALID) == XML_VALID;
	int is_root = ((*state)->flags & XML_ROOT) == XML_ROOT;
	const struct dm_element *element = (*state)->element;
	DM_VALUE *value = (*state)->value;

	int xid = 0;
	int ntfy = 0;
	dm_id id;

	for (int i = 0; atts[i]; i += 2) {
		if (strcasecmp("instance", atts[i]) == 0) {
			xml_debug("%s: instance: %s\n", name, atts[i + 1]);
			xid = atoi(atts[i + 1]);
			break;
		}
		else if (strcasecmp("notify", atts[i]) == 0) {
			xml_debug("%s: notify: %s\n", name, atts[i + 1]);
			ntfy = dm_enum2int( &notify_attr, atts[i + 1]);
		}
		else if (strcasecmp("encoding", atts[i]) == 0) {
			xml_debug("%s: encoding: %s\n", name, atts[i + 1]);
			if (strcasecmp(atts[i+1], "escaped") == 0)
				(*state)->flags |= XML_ESCAPED;
		}
		else if (strcasecmp("version", atts[i]) == 0) {
			xml_debug("%s: config version: %s\n", name, atts[i + 1]);
			dm_set_cfg_version(atoi(atts[i + 1]));
		}
	}

	(*state)++;

	if (is_root) {
		if (flags & DS_VERSIONCHECK &&
		    dm_get_cfg_version() != CFG_VERSION) {
			(*state)->flags |= XML_UPGRADE;

			lua_pushinteger(lua_environment, CFG_VERSION);
			lua_pushinteger(lua_environment, dm_get_cfg_version());
			if (fp_Lua_function("fncPreVersionCheck", 2))
				debug("(): Error during Lua function execution");
		}
	} else {
		memset(*state, 0, sizeof(struct XMLstate));

		if (xid != 0)
			asprintf(&(*state)->base, "%s.%s.%d", base, name, xid);
		else
			asprintf(&(*state)->base, "%s.%s", base, name);

		if (valid) {
			const struct dm_table *table = element->u.t.table;

			id = dm_get_element_id_by_name(name, strlen(name), table);
			if (id != DM_ERR) {
				kw = &(table->table[id - 1]);
				val = dm_get_value_ref_by_id(DM_TABLE(*value), id);
				(*state)->flags |= XML_VALID;
			} else {
				printf("Element '%s' not found in table '%s'\n", name, element->key);
				valid = 0;
			}
		}

		if (!valid || !((*state)->flags & XML_VALID)) {
			debug("enter invalid: %s\n", (*state)->base);
			return;
		}

		xml_debug("enter: %s = %p, (%p, %p)\n", name, *state, kw, val);

		(*state)->element = kw;
		if (kw->type == T_OBJECT) {
			struct dm_instance *inst = DM_INSTANCE(*val);
			struct dm_instance_node *node = NULL;

			/** FIXME: this should be easier */
			if (xid > 0)
				node = dm_get_instance_node_by_id(inst, xid);
			if (!node) {
				dm_selector basesel;

				dm_selcpy(basesel, DM_TABLE(*value)->id);
				dm_selcat(basesel, id);

				node = dm_add_instance(kw, inst, basesel, xid);
				dm_assert(node);

				if (flags & DS_USERCONFIG) {
					val->flags |= DV_UPDATED;
					DM_parity_update(*val);
					node->table.flags |= DV_UPDATED;
					DM_parity_update(node->table);
				}
			}

			val = &node->table;

			(*state)->inst = inst;
			(*state)->node = node;

		} else if (kw->type == T_TOKEN) {
			if (DM_TABLE(*val) == NULL) {
				set_DM_TABLE(*val, dm_alloc_table(kw->u.t.table, DM_TABLE(*value)->id, id));

				if (flags & DS_USERCONFIG)
					val->flags |= DV_UPDATED;
				xml_debug("adding table for token \"%s\" with %d elements: %p\n", name,
					  kw->u.t.table->size, DM_TABLE(*val));
				DM_parity_update(*val);
			}
		}
		(*state)->value = val;
		if (ntfy >= 0)
			set_notify_single_slot_element(kw, (*state)->value, 0, ntfy);
	}
}