/*ARGSUSED*/ int uu_open_tmp(const char *dir, uint_t uflags) { int f; char *fname = uu_zalloc(PATH_MAX); if (fname == NULL) return (-1); for (;;) { (void) snprintf(fname, PATH_MAX, "%s/uu%lld", dir, gethrtime()); f = open(fname, O_CREAT | O_EXCL | O_RDWR, 0600); if (f >= 0 || errno != EEXIST) break; } if (f >= 0) (void) unlink(fname); uu_free(fname); return (f); }
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); }
/* * Initialize svccfg state. We recognize four environment variables: * * SVCCFG_REPOSITORY Create a private instance of svc.configd(1M) to answer * requests for the specified repository file. * SVCCFG_DOOR_PATH Directory for door creation. * * SVCCFG_DOOR Rendezvous via an alternative repository door. * * SVCCFG_CONFIGD_PATH Resolvable path to alternative svc.configd(1M) binary. */ void engine_init() { const char *cp; est = uu_zalloc(sizeof (engine_state_t)); est->sc_cmd_lineno = 1; est->sc_repo_pid = -1; cp = getenv("SVCCFG_REPOSITORY"); est->sc_repo_filename = cp ? safe_strdup(cp) : NULL; cp = getenv("SVCCFG_DOOR_PATH"); est->sc_repo_doordir = cp ? cp : "/var/run"; cp = getenv("SVCCFG_DOOR"); if (cp != NULL) { if (est->sc_repo_filename != NULL) { uu_warn(gettext("SVCCFG_DOOR unused when " "SVCCFG_REPOSITORY specified\n")); } else { est->sc_repo_doorname = safe_strdup(cp); } } cp = getenv("SVCCFG_CONFIGD_PATH"); est->sc_repo_server = cp ? cp : "/lib/svc/bin/svc.configd"; }
uu_dprintf_t * uu_dprintf_create(const char *name, uu_dprintf_severity_t severity, uint_t flags) { uu_dprintf_t *D; if (uu_check_name(name, UU_NAME_DOMAIN) == -1) { uu_set_error(UU_ERROR_INVALID_ARGUMENT); return (NULL); } if ((D = uu_zalloc(sizeof (uu_dprintf_t))) == NULL) return (NULL); if (name != NULL) { D->uud_name = strdup(name); if (D->uud_name == NULL) { uu_free(D); return (NULL); } } else { D->uud_name = NULL; } D->uud_severity = severity; D->uud_flags = flags; return (D); }
/* * Parse the data of a REP_PROTOCOL_PROPERTYGRP_TX_COMMIT message into a * more useful form. The data in the message will be represented by a * tx_commit_data_t structure which is allocated by this function. The * address of the allocated structure is returned to *tx_data and must be * freed by calling tx_commit_data_free(). * * Parameters: * cmds_arg Address of the commands in the * REP_PROTOCOL_PROPERTYGRP_TX_COMMIT message. * * cmds_sz Number of message bytes at cmds_arg. * * tx_data Points to the place to receive the address of the * allocated memory. * * Fails with * _BAD_REQUEST * _NO_RESOURCES */ int tx_commit_data_new(const void *cmds_arg, size_t cmds_sz, tx_commit_data_t **tx_data) { const struct rep_protocol_transaction_cmd *cmds; tx_commit_data_t *data; uintptr_t loc; uint32_t count; uint32_t sz; int ret; /* * First, verify that the reported sizes make sense, and count * the number of commands. */ count = 0; loc = (uintptr_t)cmds_arg; while (cmds_sz > 0) { cmds = (struct rep_protocol_transaction_cmd *)loc; if (cmds_sz <= REP_PROTOCOL_TRANSACTION_CMD_MIN_SIZE) return (REP_PROTOCOL_FAIL_BAD_REQUEST); sz = cmds->rptc_size; if (sz <= REP_PROTOCOL_TRANSACTION_CMD_MIN_SIZE) return (REP_PROTOCOL_FAIL_BAD_REQUEST); sz = TX_SIZE(sz); if (sz > cmds_sz) return (REP_PROTOCOL_FAIL_BAD_REQUEST); loc += sz; cmds_sz -= sz; count++; } data = uu_zalloc(TX_COMMIT_DATA_SIZE(count)); if (data == NULL) return (REP_PROTOCOL_FAIL_NO_RESOURCES); /* * verify that everything looks okay, and set up our command * datastructures. */ data->txc_count = count; ret = tx_check_and_setup(data, cmds_arg, count); if (ret == REP_PROTOCOL_SUCCESS) { *tx_data = data; } else { *tx_data = NULL; uu_free(data); } return (ret); }
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); }
static rc_snapshot_t * snapshot_alloc(void) { rc_snapshot_t *sp; sp = uu_zalloc(sizeof (*sp)); (void) pthread_mutex_init(&sp->rs_lock, NULL); (void) pthread_cond_init(&sp->rs_cv, NULL); sp->rs_refcnt++; return (sp); }
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); }
uu_list_t * uu_list_create(uu_list_pool_t *pp, void *parent, uint32_t flags) { uu_list_t *lp, *next, *prev; if (flags & ~(UU_LIST_DEBUG | UU_LIST_SORTED)) { uu_set_error(UU_ERROR_UNKNOWN_FLAG); return (NULL); } if ((flags & UU_LIST_SORTED) && pp->ulp_cmp == NULL) { if (pp->ulp_debug) uu_panic("uu_list_create(%p, ...): requested " "UU_LIST_SORTED, but pool has no comparison func\n", (void *)pp); uu_set_error(UU_ERROR_NOT_SUPPORTED); return (NULL); } lp = uu_zalloc(sizeof (*lp)); if (lp == NULL) { uu_set_error(UU_ERROR_NO_MEMORY); return (NULL); } lp->ul_pool = pp; lp->ul_parent_enc = UU_PTR_ENCODE(parent); lp->ul_offset = pp->ulp_nodeoffset; lp->ul_debug = pp->ulp_debug || (flags & UU_LIST_DEBUG); lp->ul_sorted = (flags & UU_LIST_SORTED); lp->ul_numnodes = 0; lp->ul_index = (pp->ulp_last_index = INDEX_NEXT(pp->ulp_last_index)); lp->ul_null_node.uln_next = &lp->ul_null_node; lp->ul_null_node.uln_prev = &lp->ul_null_node; lp->ul_null_walk.ulw_next = &lp->ul_null_walk; lp->ul_null_walk.ulw_prev = &lp->ul_null_walk; (void) pthread_mutex_lock(&pp->ulp_lock); next = &pp->ulp_null_list; prev = UU_PTR_DECODE(next->ul_prev_enc); lp->ul_next_enc = UU_PTR_ENCODE(next); lp->ul_prev_enc = UU_PTR_ENCODE(prev); next->ul_prev_enc = UU_PTR_ENCODE(lp); prev->ul_next_enc = UU_PTR_ENCODE(lp); (void) pthread_mutex_unlock(&pp->ulp_lock); return (lp); }
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); }
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); }
uu_avl_pool_t * uu_avl_pool_create(const char *name, size_t objsize, size_t nodeoffset, uu_compare_fn_t *compare_func, uint32_t flags) { uu_avl_pool_t *pp, *next, *prev; if (name == NULL || uu_check_name(name, UU_NAME_DOMAIN) == -1 || nodeoffset + sizeof (uu_avl_node_t) > objsize || compare_func == NULL) { uu_set_error(UU_ERROR_INVALID_ARGUMENT); return (NULL); } if (flags & ~UU_AVL_POOL_DEBUG) { uu_set_error(UU_ERROR_UNKNOWN_FLAG); return (NULL); } pp = uu_zalloc(sizeof (uu_avl_pool_t)); if (pp == NULL) { uu_set_error(UU_ERROR_NO_MEMORY); return (NULL); } (void) strlcpy(pp->uap_name, name, sizeof (pp->uap_name)); pp->uap_nodeoffset = nodeoffset; pp->uap_objsize = objsize; pp->uap_cmp = compare_func; if (flags & UU_AVL_POOL_DEBUG) pp->uap_debug = 1; pp->uap_last_index = 0; (void) pthread_mutex_init(&pp->uap_lock, NULL); pp->uap_null_avl.ua_next_enc = UU_PTR_ENCODE(&pp->uap_null_avl); pp->uap_null_avl.ua_prev_enc = UU_PTR_ENCODE(&pp->uap_null_avl); (void) pthread_mutex_lock(&uu_apool_list_lock); pp->uap_next = next = &uu_null_apool; pp->uap_prev = prev = next->uap_prev; next->uap_prev = pp; prev->uap_next = pp; (void) pthread_mutex_unlock(&uu_apool_list_lock); return (pp); }
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); }
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); }
uu_avl_walk_t * uu_avl_walk_start(uu_avl_t *ap, uint32_t flags) { uu_avl_walk_t *wp; if (flags & ~(UU_WALK_ROBUST | UU_WALK_REVERSE)) { uu_set_error(UU_ERROR_UNKNOWN_FLAG); return (NULL); } wp = uu_zalloc(sizeof (*wp)); if (wp == NULL) { uu_set_error(UU_ERROR_NO_MEMORY); return (NULL); } _avl_walk_init(wp, ap, flags); return (wp); }
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); }
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); }
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); }
uu_avl_t * uu_avl_create(uu_avl_pool_t *pp, void *parent, uint32_t flags) { uu_avl_t *ap, *next, *prev; if (flags & ~UU_AVL_DEBUG) { uu_set_error(UU_ERROR_UNKNOWN_FLAG); return (NULL); } ap = uu_zalloc(sizeof (*ap)); if (ap == NULL) { uu_set_error(UU_ERROR_NO_MEMORY); return (NULL); } ap->ua_pool = pp; ap->ua_parent_enc = UU_PTR_ENCODE(parent); ap->ua_debug = pp->uap_debug || (flags & UU_AVL_DEBUG); ap->ua_index = (pp->uap_last_index = INDEX_NEXT(pp->uap_last_index)); avl_create(&ap->ua_tree, &uu_avl_node_compare, pp->uap_objsize, pp->uap_nodeoffset); ap->ua_null_walk.uaw_next = &ap->ua_null_walk; ap->ua_null_walk.uaw_prev = &ap->ua_null_walk; (void) pthread_mutex_lock(&pp->uap_lock); next = &pp->uap_null_avl; prev = UU_PTR_DECODE(next->ua_prev_enc); ap->ua_next_enc = UU_PTR_ENCODE(next); ap->ua_prev_enc = UU_PTR_ENCODE(prev); next->ua_prev_enc = UU_PTR_ENCODE(ap); prev->ua_next_enc = UU_PTR_ENCODE(ap); (void) pthread_mutex_unlock(&pp->uap_lock); return (ap); }
/* * 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); }
int engine_source(const char *name, boolean_t dont_exit) { engine_state_t *old = est; struct stat st; int ret; est = uu_zalloc(sizeof (engine_state_t)); /* first, copy the stuff set up in engine_init */ est->sc_repo_pid = old->sc_repo_pid; if (old->sc_repo_filename != NULL) est->sc_repo_filename = safe_strdup(old->sc_repo_filename); if (old->sc_repo_doordir != NULL) est->sc_repo_doordir = safe_strdup(old->sc_repo_doordir); if (old->sc_repo_doorname != NULL) est->sc_repo_doorname = safe_strdup(old->sc_repo_doorname); if (old->sc_repo_server != NULL) est->sc_repo_server = safe_strdup(old->sc_repo_server); /* set up the new guy */ est->sc_cmd_lineno = 1; if (dont_exit) est->sc_cmd_flags |= SC_CMD_DONT_EXIT; if (strcmp(name, "-") == 0) { est->sc_cmd_file = stdin; est->sc_cmd_filename = "<stdin>"; } else { errno = 0; est->sc_cmd_filename = name; est->sc_cmd_file = fopen(name, "r"); if (est->sc_cmd_file == NULL) { if (errno == 0) semerr(gettext("No free stdio streams.\n")); else semerr(gettext("Could not open %s"), name); ret = -1; goto fail; } do ret = fstat(fileno(est->sc_cmd_file), &st); while (ret != 0 && errno == EINTR); if (ret != 0) { (void) fclose(est->sc_cmd_file); est->sc_cmd_file = NULL; /* for semerr() */ semerr(gettext("Could not stat %s"), name); ret = -1; goto fail; } if (!S_ISREG(st.st_mode)) { (void) fclose(est->sc_cmd_file); est->sc_cmd_file = NULL; /* for semerr() */ semerr(gettext("%s is not a regular file.\n"), name); ret = -1; goto fail; } } (void) yyparse(); if (est->sc_cmd_file != stdin) (void) fclose(est->sc_cmd_file); ret = 0; fail: if (est->sc_repo_pid != old->sc_repo_pid) lscf_cleanup(); /* clean up any new repository */ if (est->sc_repo_filename != NULL) free((void *)est->sc_repo_filename); if (est->sc_repo_doordir != NULL) free((void *)est->sc_repo_doordir); if (est->sc_repo_doorname != NULL) free((void *)est->sc_repo_doorname); if (est->sc_repo_server != NULL) free((void *)est->sc_repo_server); free(est); est = old; return (ret); }