diff -r 7546c836fd87 -r 4888f6212f94 components/visual-panels/smf/src/cmd/rad/mod/smf/mod_smf.c --- a/components/visual-panels/smf/src/cmd/rad/mod/smf/mod_smf.c Mon Oct 28 17:52:58 2013 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,422 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ - -/* - * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include -#include - -#include "api_smf.h" -#include "rhandle.h" -#include "smfutil.h" -#include "datatype.h" - -/* - * The SMF rad module. - * - * This module is atypically involved due to the sheer size of the - * exported API, the complexity of consuming SMF, and the fact - * the exported API represents a significant abstraction of the - * underlying functionality. - * - * This file (mod_smf.c) contains the rad module linkage, the dynamic - * namespace callbacks, and the implementation of the master object. - * - * smfutil.c and rhandle.c contain a variety of routines that factor - * common combinations of libscf operations into more manageable - * chunks. - * - * datatype.c contains routines that map a libscf type or object into - * the appropriate ADR type. - * - * common.c contains the implementation of attributes and methods - * common to instances and services. - * - * service.c and instance.c contain the implementation of attributes - * and methods specific to services and instances, respectively. - */ - -/* - * "Master" object implementation. - */ - -struct read_services_data { - adr_data_t *rsd_result; - adr_data_t *rsd_insts; -}; - -/* - * Master.service instance iteration callback. Adds the name of the - * instance to the current service's instance list. - */ -/*ARGSUSED*/ -static svcerr_t -read_services_inst_cb(scf_handle_t *scfhandle, scf_instance_t *instance, - const char *sname, const char *iname, void *arg) -{ - struct read_services_data *rsd = arg; - - assert(rsd->rsd_insts != NULL); - (void) adr_array_add(rsd->rsd_insts, - adr_data_new_string(iname, LT_COPY)); - - return (SE_OK); -} - -/* - * master.service service iteration callback. Constructs a service and - * adds it to the list. Stores a pointer to the service's instance - * list in the iteration data for use by the instance iteration - * callback. - */ -/*ARGSUSED*/ -static svcerr_t -read_services_svc_cb(scf_handle_t *scfhandle, scf_service_t *service, - const char *sname, void *arg) -{ - struct read_services_data *rsd = arg; - - rsd->rsd_insts = adr_data_new_array(&adr_t_array_string, 5); - - adr_data_t *sdata = adr_data_new_struct(&t__Service); - adr_struct_set(sdata, "fmri", - adr_data_new_string(smfu_fmri_alloc(sname, NULL), LT_FREE)); - adr_struct_set(sdata, "objectName", - adr_data_new_name(smfu_name_alloc(sname, NULL))); - adr_struct_set(sdata, "instances", rsd->rsd_insts); - (void) adr_array_add(rsd->rsd_result, sdata); - - return (SE_OK); -} - -/*ARGSUSED*/ -static svcerr_t -rt_read_services(scf_handle_t *h, void *arg, adr_data_t **ret, - adr_data_t **error) -{ - adr_data_t *result = adr_data_new_array(&t_array__Service, 200); - struct read_services_data rsd = { result, NULL }; - - svcerr_t se = smfu_iter_svcs(h, read_services_svc_cb, - read_services_inst_cb, &rsd); - - *ret = result; - return (se); -} - -/* ARGSUSED */ -conerr_t -interface_Master_read_services(rad_instance_t *inst, adr_attribute_t *attr, - adr_data_t **data, adr_data_t **error) -{ - return (smfu_rtrun(rt_read_services, NULL, data, error)); -} - -struct read_instances_data { - adr_data_t *rid_result; - - /* - * For efficiency, reuse a single set of objects. - */ - scf_propertygroup_t *rid_pg; - scf_property_t *rid_prop; - scf_value_t *rid_val; -}; - -/* - * master.instances instance iteration callback. Constructs an - * Instance and adds it to the list. - */ -/*ARGSUSED*/ -static svcerr_t -read_instances_cb(scf_handle_t *scfhandle, scf_instance_t *instance, - const char *sname, const char *iname, void *arg) -{ - if (!scf_instance_is_complete(instance)) - return (SE_OK); - - struct read_instances_data *rid = arg; - svcerr_t se; - - adr_data_t *inst = NULL; - if ((se = create_Instance(instance, sname, iname, &inst, - rid->rid_pg, rid->rid_prop, rid->rid_val)) == SE_OK) - (void) adr_array_add(rid->rid_result, inst); - - return (se == SE_NOTFOUND ? SE_OK : se); -} - -/* - * master.instances read callback. Iterates over all instances, - * constructing a list of Instance objects that are returned to the - * caller. - */ -/*ARGSUSED*/ -static svcerr_t -rt_read_instances(scf_handle_t *h, void *arg, adr_data_t **ret, - adr_data_t **error) -{ - struct read_instances_data rid; - svcerr_t se; - - rid.rid_pg = scf_pg_create(h); - rid.rid_prop = scf_property_create(h); - rid.rid_val = scf_value_create(h); - - if (rid.rid_pg == NULL || rid.rid_prop == NULL || rid.rid_val == NULL) { - se = SE_FATAL; - goto out; - } - - rid.rid_result = adr_data_new_array(&t_array__Instance, 200); - se = smfu_iter_svcs(h, NULL, read_instances_cb, &rid); - -out: - scf_value_destroy(rid.rid_val); - scf_property_destroy(rid.rid_prop); - scf_pg_destroy(rid.rid_pg); - - *ret = rid.rid_result; - return (se); -} - -/* ARGSUSED */ -conerr_t -interface_Master_read_instances(rad_instance_t *inst, adr_attribute_t *attr, - adr_data_t **data, adr_data_t **error) -{ - return (smfu_rtrun(rt_read_instances, NULL, data, error)); -} - -struct listdata { - adr_name_t *ld_pattern; - adr_data_t *ld_result; -}; - -/* - * Module linkage & dynamic namespace callbacks. - */ - -/* - * Dynamic list instance iteration callback. Compares the instance with - * the pattern; if it matches adds the instance's name to the list. - */ -/*ARGSUSED*/ -static svcerr_t -list_insts(scf_handle_t *scfhandle, scf_instance_t *instance, const char *sname, - const char *iname, void *arg) -{ - if (!scf_instance_is_complete(instance)) - return (SE_OK); - - struct listdata *ld = arg; - adr_name_t *name = smfu_name_alloc(sname, iname); - if (name == NULL) - return (SE_FATAL); - - if (adr_name_match(name, ld->ld_pattern)) - (void) adr_array_add(ld->ld_result, - adr_data_new_string(adr_name_tostr(name), LT_FREE)); - adr_name_rele(name); - - return (SE_OK); -} - -/* - * Dynamic list service iteration callback. Compares the service with - * the pattern; if it matches adds the service's name to the list. - */ -/*ARGSUSED*/ -static svcerr_t -list_svcs(scf_handle_t *scfhandle, scf_service_t *service, const char *sname, - void *arg) -{ - struct listdata *ld = arg; - adr_name_t *name = smfu_name_alloc(sname, NULL); - if (name == NULL) - return (SE_FATAL); - - if (adr_name_match(name, ld->ld_pattern)) - (void) adr_array_add(ld->ld_result, - adr_data_new_string(adr_name_tostr(name), LT_FREE)); - adr_name_rele(name); - - return (SE_OK); -} - -struct arg_listf { - adr_name_t *pattern; - boolean_t instance; -}; - -/* - * Dynamic namespace list callback. Iterates over all services or - * instances, accumulating their object names. - */ -/*ARGSUSED*/ -static svcerr_t -rt_listf(scf_handle_t *h, void *arg, adr_data_t **ret, adr_data_t **error) -{ - struct arg_listf *rtarg = (struct arg_listf *)arg; - adr_data_t *result = adr_data_new_array(&adr_t_array_string, 300); - struct listdata ld = { rtarg->pattern, result }; - - svcerr_t se = smfu_iter_svcs(h, rtarg->instance ? NULL : list_svcs, - rtarg->instance ? list_insts : NULL, &ld); - - *ret = result; - return (se); -} - -/* - * Dynamic namespace list handler. - */ -static conerr_t -smf_listf(adr_name_t *pattern, adr_data_t **names, void *arg) -{ - struct arg_listf rtarg = { pattern, (boolean_t)arg }; - - conerr_t ce = smfu_rtrun(rt_listf, &rtarg, names, NULL); - return (ce == ce_object ? ce_system : ce); -} - -/* - * Dynamic namespace lookup handler. - */ -static conerr_t -smf_lookupf(adr_name_t **name, rad_instance_t **inst, void *arg) -{ - const char *sname = adr_name_key(*name, SMF_KEY_SERVICE); - const char *iname = adr_name_key(*name, SMF_KEY_INSTANCE); - const char *scope = adr_name_key(*name, SMF_KEY_SCOPE); - boolean_t instance = (boolean_t)arg; - int kcount = scope != NULL ? 3 : 2; /* type, service, [scope] */ - - if (instance) { - /* Instances must specify an instance */ - if (iname == NULL) - return (ce_notfound); - kcount += 1; - } else { - /* Services may not specify an instance */ - if (iname != NULL) - return (ce_notfound); - } - - /* Reject names with bad keys/values */ - if (sname == NULL || kcount != adr_name_nkeys(*name)) - return (ce_notfound); - - /* - * Reject non-localhost scopes and remap localhost scopes to a - * canonical non-scoped form. - */ - if (scope != NULL) { - if (strcmp(scope, SCF_SCOPE_LOCAL) != 0) - return (ce_notfound); - adr_name_t *newname = smfu_name_alloc(sname, iname); - if (newname == NULL) - return (ce_nomem); - adr_name_rele(*name); - *name = newname; - assert(*inst == NULL); - return (ce_ok); - } - - /* Fail if the service/instance doesn't exist */ - if (smfu_test(sname, iname) != SE_OK) - return (ce_notfound); - - /* Create and return new rad instance for the service/instance */ - - smfobj_t *smfo; - if ((smfo = smfu_obj_alloc(sname, iname)) == NULL) - return (ce_nomem); - - *inst = instance_create(adr_name_hold(*name), - instance ? &interface_Instance_svr : &interface_Service_svr, - smfo, (void(*)(void *))smfu_obj_free); - - return (ce_ok); -} - -static rad_modinfo_t modinfo = { "smf", "SMF module" }; - -int -_rad_init(void *handle) -{ - adr_name_t *spat, *ipat, *mpat; - - if (rad_module_register(handle, RAD_MODVERSION, &modinfo) == -1) - return (-1); - - if (rad_isproxy) - return (0); - - smfu_init(); - - /* - * Create singleton, static master object. - */ - - mpat = adr_name_vcreate(SMF_DOMAIN, 1, SMF_KEY_TYPE, SMF_TYPE_MASTER); - rad_instance_t *agg_inst = - instance_create(mpat, &interface_Master_svr, NULL, NULL); - if (agg_inst != NULL) - (void) cont_insert(rad_container, agg_inst, INST_ID_PICK); - - /* - * Register dynamic namespace handlers for services and instances. - * We must register twice: once for type=service and once for - * type=instance. We use the same callbacks for both. - */ - spat = adr_name_vcreate(SMF_DOMAIN, 1, SMF_KEY_TYPE, SMF_TYPE_SERVICE); - if (spat != NULL) { - (void) cont_register_dynamic(rad_container, spat, smf_listf, - smf_lookupf, (void *)B_FALSE); - adr_name_rele(spat); - } - - ipat = adr_name_vcreate(SMF_DOMAIN, 1, SMF_KEY_TYPE, SMF_TYPE_INSTANCE); - if (ipat != NULL) { - (void) cont_register_dynamic(rad_container, ipat, smf_listf, - smf_lookupf, (void *)B_TRUE); - adr_name_rele(ipat); - } - - return (0); -}