Ejemplo n.º 1
0
static int
set_svc_enable_cb(void *data, scf_walkinfo_t *wip)
{
	uint8_t			desired = *(uint8_t *)data;
	const char		*instname = wip->fmri;

	if (desired) {
		if (smf_enable_instance(instname, 0) == 0)
			return (0);
	} else {
		if (smf_disable_instance(instname, 0) == 0)
			return (0);
	}

	switch (scf_error()) {
	case SCF_ERROR_INVALID_ARGUMENT:
		uu_die(gettext("Error: \"%s\" is not a valid service "
		    "instance.\n"), instname);
		break;
	case SCF_ERROR_NOT_FOUND:
		uu_die(gettext("Error: Service instance \"%s\" not found.\n"),
		    instname);
		break;
	default:
		scfdie();
	}

	return (0);
}
Ejemplo n.º 2
0
void
internal_init()
{
	if ((entity_pool = uu_list_pool_create("entities", sizeof (entity_t),
	    offsetof(entity_t, sc_node), entity_cmp, 0)) == NULL)
		uu_die(gettext("entity list pool creation failed: %s\n"),
		    uu_strerror(uu_error()));

	if ((pgroup_pool = uu_list_pool_create("property_groups",
	    sizeof (pgroup_t), offsetof(pgroup_t, sc_node), pgroup_cmp, 0)) ==
	    NULL)
		uu_die(
		    gettext("property group list pool creation failed: %s\n"),
		    uu_strerror(uu_error()));

	if ((property_pool = uu_list_pool_create("properties",
	    sizeof (property_t), offsetof(property_t, sc_node), property_cmp,
	    0)) == NULL)
		uu_die(gettext("property list pool creation failed: %s\n"),
		    uu_strerror(uu_error()));

	if ((value_pool = uu_list_pool_create("property_values",
	    sizeof (value_t), offsetof(value_t, sc_node), value_cmp, 0)) ==
	    NULL)
		uu_die(
		    gettext("property value list pool creation failed: %s\n"),
		    uu_strerror(uu_error()));
}
Ejemplo n.º 3
0
/*
 * Add the proto list contained in array 'plist' to entry 'entry', storing
 * aside the scf_value_t's created and added to the entry in a list that the
 * pointer referenced by sv_list is made to point at.
 */
static void
add_proto_list(scf_transaction_entry_t *entry, scf_handle_t *hdl,
    char **plist, uu_list_t **sv_list)
{
	scf_val_el_t		*sv_el;
	int			i;

	static uu_list_pool_t	*sv_pool = NULL;

	if ((sv_pool == NULL) &&
	    ((sv_pool = uu_list_pool_create("sv_pool",
	    sizeof (scf_val_el_t), offsetof(scf_val_el_t, link), NULL,
	    UU_LIST_POOL_DEBUG)) == NULL))
		uu_die(gettext("Error: %s.\n"), uu_strerror(uu_error()));

	if ((*sv_list = uu_list_create(sv_pool, NULL, 0)) == NULL)
		uu_die(gettext("Error: %s.\n"), uu_strerror(uu_error()));

	for (i = 0; plist[i] != NULL; i++) {
		if ((sv_el = malloc(sizeof (scf_val_el_t))) == NULL)
			uu_die(gettext("Error:"));

		if (((sv_el->val = scf_value_create(hdl)) == NULL) ||
		    (scf_value_set_astring(sv_el->val, plist[i]) != 0) ||
		    (scf_entry_add_value(entry, sv_el->val) != 0))
			scfdie();

		uu_list_node_init(sv_el, &sv_el->link, sv_pool);
		(void) uu_list_insert_after(*sv_list, NULL, sv_el);
	}
}
Ejemplo n.º 4
0
entity_t *
internal_service_new(const char *name)
{
	entity_t *s;

	if ((s = uu_zalloc(sizeof (entity_t))) == NULL)
		uu_die(gettext("couldn't allocate memory"));

	uu_list_node_init(s, &s->sc_node, entity_pool);

	s->sc_name = name;
	s->sc_fmri = uu_msprintf("svc:/%s", name);
	if (s->sc_fmri == NULL)
		uu_die(gettext("couldn't allocate memory"));

	s->sc_etype = SVCCFG_SERVICE_OBJECT;
	s->sc_pgroups = uu_list_create(pgroup_pool, s, 0);
	s->sc_dependents = uu_list_create(pgroup_pool, s, 0);

	s->sc_u.sc_service.sc_service_type = SVCCFG_UNKNOWN_SERVICE;
	s->sc_u.sc_service.sc_service_instances = uu_list_create(entity_pool, s,
	    0);

	return (s);
}
Ejemplo n.º 5
0
int
internal_attach_entity(entity_t *svc, entity_t *ent)
{
	if (ent->sc_etype == SVCCFG_TEMPLATE_OBJECT) {
		svc->sc_u.sc_service.sc_service_template = ent;
		return (0);
	}

	if (svc->sc_etype != SVCCFG_SERVICE_OBJECT)
		uu_die(gettext("bad entity attach: %s is not a service\n"),
		    svc->sc_name);

	if (uu_list_find(svc->sc_u.sc_service.sc_service_instances, ent, NULL,
	    NULL) != NULL) {
		semerr(gettext("Multiple definitions of entity %s in service "
		    "%s.\n"), ent->sc_name, svc->sc_name);
		return (-1);
	}

	(void) uu_list_prepend(svc->sc_u.sc_service.sc_service_instances, ent);
	ent->sc_parent = svc;
	ent->sc_fmri = uu_msprintf("%s:%s", svc->sc_fmri, ent->sc_name);
	if (ent->sc_fmri == NULL)
		uu_die(gettext("couldn't allocate memory"));

	return (0);
}
Ejemplo n.º 6
0
entity_t *
internal_service_new(const char *name)
{
	entity_t *s;

	s = internal_entity_new(SVCCFG_SERVICE_OBJECT);

	s->sc_name = name;
	s->sc_fmri = uu_msprintf("svc:/%s", name);
	if (s->sc_fmri == NULL)
		uu_die(gettext("couldn't allocate memory"));

	s->sc_dependents = uu_list_create(pgroup_pool, s, 0);
	if (s->sc_dependents == NULL) {
		uu_die(gettext("Unable to create list for service dependents.  "
		    "%s\n"), uu_strerror(uu_error()));
	}

	s->sc_u.sc_service.sc_service_type = SVCCFG_UNKNOWN_SERVICE;
	s->sc_u.sc_service.sc_service_instances = uu_list_create(entity_pool, s,
	    0);
	if (s->sc_u.sc_service.sc_service_instances == NULL) {
		uu_die(gettext("Unable to create list for service instances.  "
		    "%s\n"), uu_strerror(uu_error()));
	}

	return (s);
}
Ejemplo n.º 7
0
void
wait_init()
{
	struct rlimit fd_new;

	(void) getrlimit(RLIMIT_NOFILE, &init_fd_rlimit);
	(void) getrlimit(RLIMIT_NOFILE, &fd_new);

	fd_new.rlim_max = fd_new.rlim_cur = WAIT_FILES;

	(void) setrlimit(RLIMIT_NOFILE, &fd_new);

	if ((port_fd = port_create()) == -1)
		uu_die("wait_init couldn't port_create");

	wait_info_pool = uu_list_pool_create("wait_info", sizeof (wait_info_t),
	    offsetof(wait_info_t, wi_link), NULL, UU_LIST_POOL_DEBUG);
	if (wait_info_pool == NULL)
		uu_die("wait_init couldn't create wait_info_pool");

	wait_info_list = uu_list_create(wait_info_pool, wait_info_list, 0);
	if (wait_info_list == NULL)
		uu_die("wait_init couldn't create wait_info_list");

	(void) pthread_mutex_init(&wait_info_lock, &mutex_attrs);
}
Ejemplo n.º 8
0
static void
delete_prop(const scf_instance_t *inst, const char *pg, const char *prop)
{
	scf_transaction_t		*tx;
	scf_transaction_entry_t		*ent;
	scf_propertygroup_t		*gpg;
	scf_property_t			*eprop;
	int				ret;

	if ((gpg = scf_pg_create(h)) == NULL ||
	    (eprop = scf_property_create(h)) == NULL ||
	    (tx = scf_transaction_create(h)) == NULL ||
	    (ent = scf_entry_create(h)) == NULL)
		scfdie();

	if (scf_instance_get_pg(inst, pg, gpg) != SCF_SUCCESS) {
		if (scf_error() != SCF_ERROR_NOT_FOUND)
			scfdie();

		uu_die(gettext("Error: \"%s\" property group missing.\n"), pg);
	}

	do {
		if (scf_transaction_start(tx, gpg) != SCF_SUCCESS) {
			if (scf_error() != SCF_ERROR_PERMISSION_DENIED)
				scfdie();

			uu_die(gettext("Error: Permission denied.\n"));
		}

		if (scf_transaction_property_delete(tx, ent,
		    prop) != SCF_SUCCESS) {
			if (scf_error() != SCF_ERROR_NOT_FOUND)
				scfdie();

			uu_die(
			    gettext("Error: \"%s\" property does not exist.\n"),
			    prop);
		}

		ret = scf_transaction_commit(tx);
		if (ret < 0) {
			if (scf_error() != SCF_ERROR_PERMISSION_DENIED)
				scfdie();

			uu_die(gettext("Error: Permission denied.\n"));
		}
		if (ret == 0) {
			scf_transaction_reset(tx);
			if (scf_pg_update(gpg) == -1)
				scfdie();
		}
	} while (ret == 0);

	(void) scf_entry_destroy(ent);
	scf_transaction_destroy(tx);
	scf_property_destroy(eprop);
	scf_pg_destroy(gpg);
}
Ejemplo n.º 9
0
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);
}
Ejemplo n.º 10
0
bundle_t *
internal_bundle_new()
{
	bundle_t	*b;

	if ((b = uu_zalloc(sizeof (bundle_t))) == NULL)
		uu_die(gettext("couldn't allocate memory"));

	b->sc_bundle_type = SVCCFG_UNKNOWN_BUNDLE;
	b->sc_bundle_services = uu_list_create(entity_pool, b, 0);
	if (b->sc_bundle_services == NULL) {
		uu_die(gettext("Unable to create list for bundle services.  "
		    "%s\n"), uu_strerror(uu_error()));
	}

	return (b);
}
Ejemplo n.º 11
0
void *
safe_malloc(size_t sz)
{
	void *p;

	if ((p = calloc(1, sz)) == NULL)
		uu_die(gettext("Out of memory.\n"));

	return (p);
}
Ejemplo n.º 12
0
entity_t *
internal_entity_new(entity_type_t entity)
{
	entity_t *e;

	if ((e = uu_zalloc(sizeof (entity_t))) == NULL)
		uu_die(gettext("couldn't allocate memory"));

	uu_list_node_init(e, &e->sc_node, entity_pool);

	e->sc_etype = entity;
	e->sc_pgroups = uu_list_create(pgroup_pool, e, 0);
	e->sc_op = SVCCFG_OP_NONE;
	if (e->sc_pgroups == NULL) {
		uu_die(gettext("Unable to create list for entity property "
		    "groups.  %s\n"), uu_strerror(uu_error()));
	}

	return (e);
}
Ejemplo n.º 13
0
pgroup_t *
internal_pgroup_new()
{
	pgroup_t *p;

	if ((p = uu_zalloc(sizeof (pgroup_t))) == NULL)
		uu_die(gettext("couldn't allocate memory"));

	uu_list_node_init(p, &p->sc_node, pgroup_pool);

	p->sc_pgroup_props = uu_list_create(property_pool, p, UU_LIST_SORTED);
	if (p->sc_pgroup_props == NULL) {
		uu_die(gettext("Unable to create list for properties.  %s\n"),
		    uu_strerror(uu_error()));
	}
	p->sc_pgroup_name = "<unset>";
	p->sc_pgroup_type = "<unset>";

	return (p);
}
Ejemplo n.º 14
0
char *
safe_strdup(const char *cp)
{
	char *result;

	result = strdup(cp);
	if (result == NULL)
		uu_die(gettext("Out of memory.\n"));

	return (result);
}
Ejemplo n.º 15
0
value_t *
internal_value_new()
{
	value_t *v;

	if ((v = uu_zalloc(sizeof (value_t))) == NULL)
		uu_die(gettext("couldn't allocate memory"));

	uu_list_node_init(v, &v->sc_node, value_pool);

	return (v);
}
Ejemplo n.º 16
0
property_t *
internal_property_new()
{
	property_t *p;

	if ((p = uu_zalloc(sizeof (property_t))) == NULL)
		uu_die(gettext("couldn't allocate memory"));

	uu_list_node_init(p, &p->sc_node, property_pool);

	p->sc_property_values = uu_list_create(value_pool, p, 0);
	if (p->sc_property_values == NULL) {
		uu_die(gettext("Unable to create list for property values.  "
		    "%s\n"), uu_strerror(uu_error()));
	}
	p->sc_property_name = "<unset>";

	tmpl_property_init(p);

	return (p);
}
Ejemplo n.º 17
0
bundle_t *
internal_bundle_new()
{
	bundle_t	*b;

	if ((b = uu_zalloc(sizeof (bundle_t))) == NULL)
		uu_die(gettext("couldn't allocate memory"));

	b->sc_bundle_type = SVCCFG_UNKNOWN_BUNDLE;
	b->sc_bundle_services = uu_list_create(entity_pool, b, 0);

	return (b);
}
Ejemplo n.º 18
0
property_t *
internal_property_create(const char *name, scf_type_t vtype, uint_t nvals, ...)
{
	va_list args;
	property_t *p;
	value_t *v;

	p = internal_property_new();

	p->sc_property_name = (char *)name;
	p->sc_value_type = vtype;

	va_start(args, nvals);
	for (; nvals > 0; nvals--) {

		v = internal_value_new();
		v->sc_type = vtype;

		switch (vtype) {
		case SCF_TYPE_BOOLEAN:
		case SCF_TYPE_COUNT:
			v->sc_u.sc_count = va_arg(args, uint64_t);
			break;
		case SCF_TYPE_INTEGER:
			v->sc_u.sc_integer = va_arg(args, int64_t);
			break;
		case SCF_TYPE_ASTRING:
		case SCF_TYPE_FMRI:
		case SCF_TYPE_HOST:
		case SCF_TYPE_HOSTNAME:
		case SCF_TYPE_NET_ADDR_V4:
		case SCF_TYPE_NET_ADDR_V6:
		case SCF_TYPE_OPAQUE:
		case SCF_TYPE_TIME:
		case SCF_TYPE_URI:
		case SCF_TYPE_USTRING:
			v->sc_u.sc_string = (char *)va_arg(args, uchar_t *);
			break;
		default:
			va_end(args);
			uu_die(gettext("unknown property type (%d)\n"), vtype);
			break;
		}

		internal_attach_value(p, v);
	}
	va_end(args);

	return (p);
}
Ejemplo n.º 19
0
property_t *
internal_property_new()
{
	property_t *p;

	if ((p = uu_zalloc(sizeof (property_t))) == NULL)
		uu_die(gettext("couldn't allocate memory"));

	uu_list_node_init(p, &p->sc_node, property_pool);

	p->sc_property_values = uu_list_create(value_pool, p, UU_LIST_SORTED);
	p->sc_property_name = "<unset>";

	return (p);
}
Ejemplo n.º 20
0
entity_t *
internal_template_new()
{
	entity_t *t;

	if ((t = uu_zalloc(sizeof (entity_t))) == NULL)
		uu_die(gettext("couldn't allocate memory"));

	uu_list_node_init(t, &t->sc_node, entity_pool);

	t->sc_etype = SVCCFG_TEMPLATE_OBJECT;
	t->sc_pgroups = uu_list_create(pgroup_pool, t, 0);

	return (t);
}
Ejemplo n.º 21
0
int
engine_set(uu_list_t *args)
{
	uu_list_walk_t *walk;
	string_list_t *slp;

	if (uu_list_first(args) == NULL) {
		/* Display current options. */
		if (!g_verbose)
			(void) fputs("no", stdout);
		(void) puts("verbose");

		return (0);
	}

	walk = uu_list_walk_start(args, UU_DEFAULT);
	if (walk == NULL)
		uu_die(gettext("Couldn't read arguments"));

	/* Use getopt? */
	for (slp = uu_list_walk_next(walk);
	    slp != NULL;
	    slp = uu_list_walk_next(walk)) {
		if (slp->str[0] == '-') {
			char *op;

			for (op = &slp->str[1]; *op != '\0'; ++op) {
				switch (*op) {
				case 'v':
					g_verbose = 1;
					break;

				case 'V':
					g_verbose = 0;
					break;

				default:
					warn(gettext("Unknown option -%c.\n"),
					    *op);
				}
			}
		} else {
			warn(gettext("No non-flag arguments defined.\n"));
		}
	}

	return (0);
}
Ejemplo n.º 22
0
entity_t *
internal_instance_new(const char *name)
{
	entity_t *i;

	i = internal_entity_new(SVCCFG_INSTANCE_OBJECT);
	i->sc_name = name;
	/* Can't set i->sc_fmri until we're attached to a service. */
	i->sc_dependents = uu_list_create(pgroup_pool, i, 0);
	if (i->sc_dependents == NULL) {
		uu_die(gettext("Unable to create list for instance "
		    "dependents.  %s\n"), uu_strerror(uu_error()));
	}

	return (i);
}
Ejemplo n.º 23
0
entity_t *
internal_instance_new(const char *name)
{
	entity_t *i;

	if ((i = uu_zalloc(sizeof (entity_t))) == NULL)
		uu_die(gettext("couldn't allocate memory"));

	uu_list_node_init(i, &i->sc_node, entity_pool);

	i->sc_name = name;
	/* Can't set i->sc_fmri until we're attached to a service. */
	i->sc_etype = SVCCFG_INSTANCE_OBJECT;
	i->sc_pgroups = uu_list_create(pgroup_pool, i, 0);
	i->sc_dependents = uu_list_create(pgroup_pool, i, 0);

	return (i);
}
Ejemplo n.º 24
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);
}
Ejemplo n.º 25
0
/*
 * Send a message to the user.  If we're interactive, send it to stdout.
 * Otherwise send it to stderr.
 */
static void
vmessage(const char *fmt, va_list va)
{
	int interactive = est->sc_cmd_flags & SC_CMD_IACTIVE;
	FILE *strm = interactive ? stdout : stderr;
	const char *ptr;

	if (!interactive) {
		if (est->sc_cmd_file == NULL)
			(void) fprintf(stderr, "%s: ", myname);
		else
			(void) fprintf(stderr, "%s (%s, line %d): ", myname,
			    est->sc_cmd_filename, est->sc_cmd_lineno - 1);
	}

	if (vfprintf(strm, fmt, va) < 0 && interactive)
		uu_die(gettext("printf() error"));

	ptr = strchr(fmt, '\0');
	if (*(ptr - 1) != '\n')
		(void) fprintf(strm, ": %s.\n", strerror(errno));
}
Ejemplo n.º 26
0
/*ARGSUSED*/
static int
internal_value_dump(void *v, void *pvt)
{
	value_t *val = v;

	switch (val->sc_type) {
	case SCF_TYPE_BOOLEAN:
		(void) printf("	value = %s\n",
		    val->sc_u.sc_count ? "true" : "false");
		break;
	case SCF_TYPE_COUNT:
		(void) printf("	value = %llu\n", val->sc_u.sc_count);
		break;
	case SCF_TYPE_INTEGER:
		(void) printf("	value = %lld\n", val->sc_u.sc_integer);
		break;
	case SCF_TYPE_ASTRING:
	case SCF_TYPE_FMRI:
	case SCF_TYPE_HOST:
	case SCF_TYPE_HOSTNAME:
	case SCF_TYPE_NET_ADDR_V4:
	case SCF_TYPE_NET_ADDR_V6:
	case SCF_TYPE_OPAQUE:
	case SCF_TYPE_TIME:
	case SCF_TYPE_URI:
	case SCF_TYPE_USTRING:
		(void) printf("	value = %s\n",
		    val->sc_u.sc_string ? val->sc_u.sc_string : "(nil)");
		break;
	default:
		uu_die(gettext("unknown value type (%d)\n"), val->sc_type);
		break;
	}

	return (UU_WALK_NEXT);
}
Ejemplo n.º 27
0
static void
list_defaults()
{
	scf_handle_t		*h;
	scf_error_t		err;
	int			i;
	inetd_prop_t		*proptable;
	size_t			numprops;

	if (((h = scf_handle_create(SCF_VERSION)) == NULL) ||
	    (scf_handle_bind(h) == -1))
		scfdie();

	if ((proptable = read_default_props(h, &numprops, &err)) == NULL) {
		uu_die(gettext("Unexpected libscf error: %s.  Exiting.\n"),
		    scf_strerror(err));
	}

	(void) printf("NAME=VALUE\n");

	for (i = 0; i < numprops; i++) {
		if (!proptable[i].ip_default)
			continue;

		if (proptable[i].ip_error == IVE_UNSET) {
			(void) uu_warn(gettext("Error: Default property %s "
			    "missing.\n"), proptable[i].ip_name);
			continue;
		}

		(void) printf("%s=", proptable[i].ip_name);
		print_prop_val(&proptable[i]);
	}

	free_instance_props(proptable);
}
Ejemplo n.º 28
0
/*
 * void method_store_contract()
 *   Store the newly created contract id into local structures and
 *   the repository.  If the repository connection is broken it is rebound.
 */
static void
method_store_contract(restarter_inst_t *inst, int type, ctid_t *cid)
{
	int r;
	boolean_t primary;

	if (errno = contract_latest(cid))
		uu_die("%s: Couldn't get new contract's id", inst->ri_i.i_fmri);

	primary = !method_is_transient(inst, type);

	if (!primary) {
		if (inst->ri_i.i_transient_ctid != 0) {
			log_framework(LOG_INFO,
			    "%s: transient ctid expected to be 0 but "
			    "was set to %ld\n", inst->ri_i.i_fmri,
			    inst->ri_i.i_transient_ctid);
		}

		inst->ri_i.i_transient_ctid = *cid;
	} else {
		if (inst->ri_i.i_primary_ctid != 0) {
			/*
			 * There was an old contract that we transferred.
			 * Remove it.
			 */
			method_remove_contract(inst, B_TRUE, B_FALSE);
		}

		if (inst->ri_i.i_primary_ctid != 0) {
			log_framework(LOG_INFO,
			    "%s: primary ctid expected to be 0 but "
			    "was set to %ld\n", inst->ri_i.i_fmri,
			    inst->ri_i.i_primary_ctid);
		}

		inst->ri_i.i_primary_ctid = *cid;
		inst->ri_i.i_primary_ctid_stopped = 0;

		contract_hash_store(*cid, inst->ri_id);
	}

again:
	if (inst->ri_mi_deleted)
		return;

	r = restarter_store_contract(inst->ri_m_inst, *cid, primary ?
	    RESTARTER_CONTRACT_PRIMARY : RESTARTER_CONTRACT_TRANSIENT);
	switch (r) {
	case 0:
		break;

	case ECANCELED:
		inst->ri_mi_deleted = B_TRUE;
		break;

	case ECONNABORTED:
		libscf_handle_rebind(scf_instance_handle(inst->ri_m_inst));
		/* FALLTHROUGH */

	case EBADF:
		libscf_reget_instance(inst);
		goto again;

	case ENOMEM:
	case EPERM:
	case EACCES:
	case EROFS:
		uu_die("%s: Couldn't store contract id %ld",
		    inst->ri_i.i_fmri, *cid);
		/* NOTREACHED */

	case EINVAL:
	default:
		bad_error("restarter_store_contract", r);
	}
}
Ejemplo n.º 29
0
int
main(int argc, char *argv[])
{
	int c;
	scf_walk_callback callback;
	int flags;
	int err;

	(void) setlocale(LC_ALL, "");
	(void) textdomain(TEXT_DOMAIN);

	return_code = UU_EXIT_OK;

	(void) uu_setpname(argv[0]);

	prop_pool = uu_list_pool_create("properties",
	    sizeof (svcprop_prop_node_t),
	    offsetof(svcprop_prop_node_t, spn_list_node), NULL, 0);
	if (prop_pool == NULL)
		uu_die("%s\n", uu_strerror(uu_error()));

	prop_list = uu_list_create(prop_pool, NULL, 0);

	hndl = scf_handle_create(SCF_VERSION);
	if (hndl == NULL)
		scfdie();

	while ((c = getopt(argc, argv, "Ccfp:qs:tvwz:")) != -1) {
		switch (c) {
		case 'C':
			if (cflag || sflag || wait)
				usage();	/* Not with -c, -s or -w */
			Cflag++;
			snapshot = NULL;
			break;

		case 'c':
			if (Cflag || sflag || wait)
				usage();	/* Not with -C, -s or -w */
			cflag++;
			snapshot = NULL;
			break;

		case 'f':
			types = 1;
			fmris = 1;
			break;

		case 'p':
			add_prop(optarg);
			break;

		case 'q':
			quiet = 1;
			warn = quiet_warn;
			die = quiet_die;
			break;

		case 's':
			if (Cflag || cflag || wait)
				usage();	/* Not with -C, -c or -w */
			snapshot = optarg;
			sflag++;
			break;

		case 't':
			types = 1;
			break;

		case 'v':
			verbose = 1;
			break;

		case 'w':
			if (Cflag || cflag || sflag)
				usage();	/* Not with -C, -c or -s */
			wait = 1;
			break;

		case 'z': {
			scf_value_t *zone;
			scf_handle_t *h = hndl;

			if (getzoneid() != GLOBAL_ZONEID)
				uu_die(gettext("svcprop -z may only be used "
				    "from the global zone\n"));

			if ((zone = scf_value_create(h)) == NULL)
				scfdie();

			if (scf_value_set_astring(zone, optarg) != SCF_SUCCESS)
				scfdie();

			if (scf_handle_decorate(h, "zone", zone) != SCF_SUCCESS)
				uu_die(gettext("invalid zone '%s'\n"), optarg);

			scf_value_destroy(zone);
			break;
		}

		case '?':
			switch (optopt) {
			case 'p':
				usage();

			default:
				break;
			}

			/* FALLTHROUGH */

		default:
			usage();
		}
	}

	if (optind == argc)
		usage();

	max_scf_name_length = scf_limit(SCF_LIMIT_MAX_NAME_LENGTH);
	max_scf_value_length = scf_limit(SCF_LIMIT_MAX_VALUE_LENGTH);
	max_scf_fmri_length = scf_limit(SCF_LIMIT_MAX_FMRI_LENGTH);
	if (max_scf_name_length == -1 || max_scf_value_length == -1 ||
	    max_scf_fmri_length == -1)
		scfdie();

	if (scf_handle_bind(hndl) == -1)
		die(gettext("Could not connect to configuration repository: "
		    "%s.\n"), scf_strerror(scf_error()));

	flags = SCF_WALK_PROPERTY | SCF_WALK_SERVICE | SCF_WALK_EXPLICIT;

	if (wait) {
		if (uu_list_numnodes(prop_list) > 1)
			usage();

		if (argc - optind > 1)
			usage();

		callback = do_wait;

	} else {
		callback = process_fmri;

		flags |= SCF_WALK_MULTIPLE;
	}

	if ((err = scf_walk_fmri(hndl, argc - optind, argv + optind, flags,
	    callback, NULL, &return_code, warn)) != 0) {
		warn(gettext("failed to iterate over instances: %s\n"),
		    scf_strerror(err));
		return_code = UU_EXIT_FATAL;
	}

	scf_handle_destroy(hndl);

	return (return_code);
}
Ejemplo n.º 30
0
/*
 * int method_ready_contract(restarter_inst_t *, int, method_restart_t, int)
 *
 *   Activate a contract template for the type method of inst.  type,
 *   restart_on, and cte_mask dictate the critical events term of the contract.
 *   Returns
 *     0 - success
 *     ECANCELED - inst has been deleted from the repository
 */
static int
method_ready_contract(restarter_inst_t *inst, int type,
    method_restart_t restart_on, uint_t cte_mask)
{
	int tmpl, err, istrans, iswait, ret;
	uint_t cevents, fevents;

	/*
	 * Correctly supporting wait-style services is tricky without
	 * rearchitecting startd to cope with multiple event sources
	 * simultaneously trying to stop an instance.  Until a better
	 * solution is implemented, we avoid this problem for
	 * wait-style services by making contract events fatal and
	 * letting the wait code alone handle stopping the service.
	 */
	iswait = instance_is_wait_style(inst);
	istrans = method_is_transient(inst, type);

	tmpl = open64(CTFS_ROOT "/process/template", O_RDWR);
	if (tmpl == -1)
		uu_die("Could not create contract template");

	/*
	 * We assume non-login processes are unlikely to create
	 * multiple process groups, and set CT_PR_PGRPONLY for all
	 * wait-style services' contracts.
	 */
	err = ct_pr_tmpl_set_param(tmpl, CT_PR_INHERIT | CT_PR_REGENT |
	    (iswait ? CT_PR_PGRPONLY : 0));
	assert(err == 0);

	if (istrans) {
		cevents = 0;
		fevents = 0;
	} else {
		assert(restart_on >= 0);
		assert(restart_on <= METHOD_RESTART_ANY_FAULT);
		cevents = method_events[restart_on] & ~cte_mask;
		fevents = iswait ?
		    (method_events[restart_on] & ~cte_mask & CT_PR_ALLFATAL) :
		    0;
	}

	err = ct_tmpl_set_critical(tmpl, cevents);
	assert(err == 0);

	err = ct_tmpl_set_informative(tmpl, 0);
	assert(err == 0);
	err = ct_pr_tmpl_set_fatal(tmpl, fevents);
	assert(err == 0);

	err = ct_tmpl_set_cookie(tmpl, istrans ?  METHOD_OTHER_COOKIE :
	    METHOD_START_COOKIE);
	assert(err == 0);

	if (type == METHOD_START && inst->ri_i.i_primary_ctid != 0) {
		ret = ct_pr_tmpl_set_transfer(tmpl, inst->ri_i.i_primary_ctid);
		switch (ret) {
		case 0:
			break;

		case ENOTEMPTY:
			/* No contracts for you! */
			method_remove_contract(inst, B_TRUE, B_TRUE);
			if (inst->ri_mi_deleted) {
				ret = ECANCELED;
				goto out;
			}
			break;

		case EINVAL:
		case ESRCH:
		case EACCES:
		default:
			bad_error("ct_pr_tmpl_set_transfer", ret);
		}
	}

	err = ct_tmpl_activate(tmpl);
	assert(err == 0);

	ret = 0;

out:
	err = close(tmpl);
	assert(err == 0);

	return (ret);
}