static pgroup_t *
internal_pgroup_create_common(entity_t *e, const char *name, const char *type,
	boolean_t unique)
{
	pgroup_t *pg;

	pg = internal_pgroup_find(e, name, type);
	if (pg != NULL) {
		if (unique == B_TRUE) {
			return (NULL);
		} else {
			return (pg);
		}
	}

	pg = internal_pgroup_new();
	(void) internal_attach_pgroup(e, pg);
	pg->sc_pgroup_name = strdup(name);
	pg->sc_pgroup_flags = 0;
	if (type != NULL) {
		pg->sc_pgroup_type = strdup(type);
	} else {
		est->sc_miss_type = B_TRUE;
		pg->sc_pgroup_type = NULL;
	}

	if (pg->sc_pgroup_name == NULL ||
	    (e->sc_op != SVCCFG_OP_APPLY && pg->sc_pgroup_type == NULL))
		uu_die(gettext("Could not duplicate string"));

	return (pg);
}
Esempio n. 2
0
pgroup_t *
internal_pgroup_find_or_create(entity_t *e, const char *name, const char *type)
{
	pgroup_t *pg;

	pg = internal_pgroup_find(e, name, type);
	if (pg != NULL)
		return (pg);

	pg = internal_pgroup_new();
	(void) internal_attach_pgroup(e, pg);
	pg->sc_pgroup_name = strdup(name);
	pg->sc_pgroup_type = strdup(type);
	pg->sc_pgroup_flags = 0;

	if (pg->sc_pgroup_name == NULL || pg->sc_pgroup_type == NULL)
		uu_die(gettext("Could not duplicate string"));

	return (pg);
}
/*
 * Load the instance for fmri from the repository into memory.  The
 * property groups that define the instances pg_patterns and prop_patterns
 * are also loaded.
 *
 * Returns 0 on success and non-zero on failure.
 */
int
load_instance(const char *fmri, const char *name, entity_t **inst_ptr)
{
	entity_t *e = NULL;
	scf_instance_t *inst;
	pgroup_t *ipg;
	int rc;
	char *type = NULL;
	ssize_t tsize;

	assert(inst_ptr != NULL);

	if ((inst = scf_instance_create(g_hndl)) == NULL) {
		switch (scf_error()) {
		case SCF_ERROR_NO_MEMORY:
		case SCF_ERROR_NO_RESOURCES:
			rc = EAGAIN;
			goto errout;
		default:
			bad_error("scf_instance_create", scf_error());
		}
	}
	if (scf_handle_decode_fmri(g_hndl, fmri, NULL, NULL, inst, NULL, NULL,
	    SCF_DECODE_FMRI_EXACT|SCF_DECODE_FMRI_REQUIRE_INSTANCE) != 0) {
		switch (scf_error()) {
		case SCF_ERROR_CONNECTION_BROKEN:
			rc = ECONNABORTED;
			goto errout;
		case SCF_ERROR_DELETED:
		case SCF_ERROR_NOT_FOUND:
			rc = ENOENT;
			goto errout;
		case SCF_ERROR_INVALID_ARGUMENT:
			rc = EINVAL;
			goto errout;
		case SCF_ERROR_CONSTRAINT_VIOLATED:
			rc = ENOTSUP;
			goto errout;
		default:
			bad_error("scf_handle_decode_fmri", scf_error());
		}
	}
	if (scf_iter_instance_pgs_composed(load_pgiter, inst, NULL) != 0) {
		switch (scf_error()) {
		case SCF_ERROR_DELETED:
			rc = ECANCELED;
			goto errout;
		case SCF_ERROR_CONNECTION_BROKEN:
			rc = ECONNABORTED;
			goto errout;
		default:
			bad_error("scf_iter_instance_pgs_composed",
			    scf_error());
		}
	}

	tsize = scf_limit(SCF_LIMIT_MAX_PG_TYPE_LENGTH);
	type = uu_zalloc(tsize);
	if (type == NULL) {
		rc = ENOMEM;
		goto errout;
	}

	/*
	 * Initialize our entity structure.
	 */
	e = internal_instance_new(name);
	if (e == NULL) {
		rc = ENOMEM;
		goto errout;
	}
	e->sc_fmri = uu_strdup(fmri);
	if (e->sc_fmri == NULL) {
		rc = ENOMEM;
		goto errout;
	}

	/*
	 * Walk through the property group's of the instance and capture
	 * the property groups that are of type
	 * SCF_GROUP_TEMPLATE_PG_PATTERN and
	 * SCF_GROUP_TEMPLATE_PROP_PATTERN.  In other words grab the
	 * pg_pattern and prop_pattern property groups.
	 */
	while ((rc = scf_iter_next_pg(load_pgiter, load_pgroup)) == 1) {
		if (scf_pg_get_type(load_pgroup, type, tsize) <= 0) {
			switch (scf_error()) {
			case SCF_ERROR_DELETED:
				rc = ENOENT;
				break;
			case SCF_ERROR_CONNECTION_BROKEN:
				rc = ECONNABORTED;
				break;
			default:
				bad_error("scf_pg_get_type", scf_error());
			}
			goto errout;
		}
		if ((strcmp(type, SCF_GROUP_TEMPLATE_PG_PATTERN) != 0) &&
		    (strcmp(type, SCF_GROUP_TEMPLATE_PROP_PATTERN) != 0)) {
			continue;
		}
		if ((rc = load_pg(load_pgroup, &ipg, fmri, NULL)) != 0) {
			switch (rc) {
			case ECANCELED:
			case ECONNABORTED:
			case EACCES:
			case ENOMEM:
				break;
			default:
				bad_error("load_pg", rc);
			}
			goto errout;
		}
		if (internal_attach_pgroup(e, ipg) != 0) {
			rc = EBADF;
			goto errout;
		}
	}
	if (rc == -1) {
		/* Error in iteration. */
		switch (scf_error()) {
		case SCF_ERROR_CONNECTION_BROKEN:
			rc = ECONNABORTED;
			break;
		case SCF_ERROR_DELETED:
			rc = ENOENT;
			break;
		case SCF_ERROR_NO_RESOURCES:
			rc = EAGAIN;
			break;
		default:
			bad_error("scf_iter_next_pg", scf_error());
		}
		goto errout;
	}

	*inst_ptr = e;
	scf_instance_destroy(inst);
	return (0);

errout:
	if (type != NULL)
		uu_free(type);
	if (inst != NULL)
		scf_instance_destroy(inst);
	if (e != NULL)
		internal_instance_free(e);
	return (rc);
}