1*7c478bd9Sstevel@tonic-gate /* 2*7c478bd9Sstevel@tonic-gate * CDDL HEADER START 3*7c478bd9Sstevel@tonic-gate * 4*7c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*7c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 6*7c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 7*7c478bd9Sstevel@tonic-gate * with the License. 8*7c478bd9Sstevel@tonic-gate * 9*7c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*7c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 11*7c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 12*7c478bd9Sstevel@tonic-gate * and limitations under the License. 13*7c478bd9Sstevel@tonic-gate * 14*7c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 15*7c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*7c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 17*7c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 18*7c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 19*7c478bd9Sstevel@tonic-gate * 20*7c478bd9Sstevel@tonic-gate * CDDL HEADER END 21*7c478bd9Sstevel@tonic-gate */ 22*7c478bd9Sstevel@tonic-gate /* 23*7c478bd9Sstevel@tonic-gate * Copyright 2004 Sun Microsystems, Inc. All rights reserved. 24*7c478bd9Sstevel@tonic-gate * Use is subject to license terms. 25*7c478bd9Sstevel@tonic-gate */ 26*7c478bd9Sstevel@tonic-gate 27*7c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 28*7c478bd9Sstevel@tonic-gate 29*7c478bd9Sstevel@tonic-gate /* 30*7c478bd9Sstevel@tonic-gate * dict.c - simple dictionary facility 31*7c478bd9Sstevel@tonic-gate * 32*7c478bd9Sstevel@tonic-gate * We maintain a dictionary, sorted by name to facilitate rapid id lookup by 33*7c478bd9Sstevel@tonic-gate * name. It is used by both the restarter and graph code. 34*7c478bd9Sstevel@tonic-gate * 35*7c478bd9Sstevel@tonic-gate * Right now, the dictionary is implemented as a sorted linked list which maps 36*7c478bd9Sstevel@tonic-gate * instance names to graph vertex ids. It should eventually be converted to a 37*7c478bd9Sstevel@tonic-gate * better representation for quick lookups. 38*7c478bd9Sstevel@tonic-gate * 39*7c478bd9Sstevel@tonic-gate * For now, FMRIs are never deleted from the dictionary. A service deletion 40*7c478bd9Sstevel@tonic-gate * and insertion of the same instance FMRI will result in reuse of the same 41*7c478bd9Sstevel@tonic-gate * id. To implement dictionary entry delete, the locking strategy for graph 42*7c478bd9Sstevel@tonic-gate * vertex dependency linking must be checked for accuracy, as assumptions may 43*7c478bd9Sstevel@tonic-gate * exist that FMRI to id mapping is retained even after an instance is deleted. 44*7c478bd9Sstevel@tonic-gate */ 45*7c478bd9Sstevel@tonic-gate 46*7c478bd9Sstevel@tonic-gate #include <sys/time.h> 47*7c478bd9Sstevel@tonic-gate 48*7c478bd9Sstevel@tonic-gate #include <assert.h> 49*7c478bd9Sstevel@tonic-gate #include <libuutil.h> 50*7c478bd9Sstevel@tonic-gate #include <string.h> 51*7c478bd9Sstevel@tonic-gate 52*7c478bd9Sstevel@tonic-gate #include "startd.h" 53*7c478bd9Sstevel@tonic-gate 54*7c478bd9Sstevel@tonic-gate static uu_list_pool_t *dict_pool; 55*7c478bd9Sstevel@tonic-gate dictionary_t *dictionary; 56*7c478bd9Sstevel@tonic-gate 57*7c478bd9Sstevel@tonic-gate static u_longlong_t dictionary_lookups; /* number of lookups */ 58*7c478bd9Sstevel@tonic-gate static u_longlong_t dictionary_ns_total; /* nanoseconds spent */ 59*7c478bd9Sstevel@tonic-gate 60*7c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 61*7c478bd9Sstevel@tonic-gate static int 62*7c478bd9Sstevel@tonic-gate dict_compare(const void *lc_arg, const void *rc_arg, void *private) 63*7c478bd9Sstevel@tonic-gate { 64*7c478bd9Sstevel@tonic-gate const char *lc_name = ((const dict_entry_t *)lc_arg)->de_name; 65*7c478bd9Sstevel@tonic-gate const char *rc_name = ((const dict_entry_t *)rc_arg)->de_name; 66*7c478bd9Sstevel@tonic-gate 67*7c478bd9Sstevel@tonic-gate return (strcmp(lc_name, rc_name)); 68*7c478bd9Sstevel@tonic-gate } 69*7c478bd9Sstevel@tonic-gate 70*7c478bd9Sstevel@tonic-gate int 71*7c478bd9Sstevel@tonic-gate dict_lookup_byname(const char *name) 72*7c478bd9Sstevel@tonic-gate { 73*7c478bd9Sstevel@tonic-gate int id; 74*7c478bd9Sstevel@tonic-gate dict_entry_t *entry, tmp; 75*7c478bd9Sstevel@tonic-gate hrtime_t now = gethrtime(); 76*7c478bd9Sstevel@tonic-gate 77*7c478bd9Sstevel@tonic-gate tmp.de_name = name; 78*7c478bd9Sstevel@tonic-gate 79*7c478bd9Sstevel@tonic-gate (void) pthread_mutex_lock(&dictionary->dict_lock); 80*7c478bd9Sstevel@tonic-gate if ((entry = uu_list_find(dictionary->dict_list, &tmp, NULL, 81*7c478bd9Sstevel@tonic-gate NULL)) == NULL) 82*7c478bd9Sstevel@tonic-gate id = -1; 83*7c478bd9Sstevel@tonic-gate else 84*7c478bd9Sstevel@tonic-gate id = entry->de_id; 85*7c478bd9Sstevel@tonic-gate 86*7c478bd9Sstevel@tonic-gate (void) pthread_mutex_unlock(&dictionary->dict_lock); 87*7c478bd9Sstevel@tonic-gate 88*7c478bd9Sstevel@tonic-gate dictionary_lookups++; 89*7c478bd9Sstevel@tonic-gate dictionary_ns_total += gethrtime() - now; 90*7c478bd9Sstevel@tonic-gate 91*7c478bd9Sstevel@tonic-gate return (id); 92*7c478bd9Sstevel@tonic-gate } 93*7c478bd9Sstevel@tonic-gate 94*7c478bd9Sstevel@tonic-gate /* 95*7c478bd9Sstevel@tonic-gate * int dict_insert(char *) 96*7c478bd9Sstevel@tonic-gate * Returns the ID for name. 97*7c478bd9Sstevel@tonic-gate */ 98*7c478bd9Sstevel@tonic-gate int 99*7c478bd9Sstevel@tonic-gate dict_insert(const char *name) 100*7c478bd9Sstevel@tonic-gate { 101*7c478bd9Sstevel@tonic-gate dict_entry_t *entry, tmp; 102*7c478bd9Sstevel@tonic-gate uu_list_index_t idx; 103*7c478bd9Sstevel@tonic-gate 104*7c478bd9Sstevel@tonic-gate assert(name != NULL); 105*7c478bd9Sstevel@tonic-gate 106*7c478bd9Sstevel@tonic-gate tmp.de_name = name; 107*7c478bd9Sstevel@tonic-gate 108*7c478bd9Sstevel@tonic-gate (void) pthread_mutex_lock(&dictionary->dict_lock); 109*7c478bd9Sstevel@tonic-gate 110*7c478bd9Sstevel@tonic-gate if ((entry = uu_list_find(dictionary->dict_list, &tmp, NULL, 111*7c478bd9Sstevel@tonic-gate &idx)) != NULL) { 112*7c478bd9Sstevel@tonic-gate (void) pthread_mutex_unlock(&dictionary->dict_lock); 113*7c478bd9Sstevel@tonic-gate return (entry->de_id); 114*7c478bd9Sstevel@tonic-gate } 115*7c478bd9Sstevel@tonic-gate 116*7c478bd9Sstevel@tonic-gate entry = startd_alloc(sizeof (dict_entry_t)); 117*7c478bd9Sstevel@tonic-gate 118*7c478bd9Sstevel@tonic-gate entry->de_id = dictionary->dict_new_id++; 119*7c478bd9Sstevel@tonic-gate entry->de_name = startd_alloc(strlen(name) + 1); 120*7c478bd9Sstevel@tonic-gate (void) strcpy((char *)entry->de_name, name); 121*7c478bd9Sstevel@tonic-gate 122*7c478bd9Sstevel@tonic-gate uu_list_node_init(entry, &entry->de_link, dict_pool); 123*7c478bd9Sstevel@tonic-gate 124*7c478bd9Sstevel@tonic-gate uu_list_insert(dictionary->dict_list, entry, idx); 125*7c478bd9Sstevel@tonic-gate (void) pthread_mutex_unlock(&dictionary->dict_lock); 126*7c478bd9Sstevel@tonic-gate 127*7c478bd9Sstevel@tonic-gate return (entry->de_id); 128*7c478bd9Sstevel@tonic-gate } 129*7c478bd9Sstevel@tonic-gate 130*7c478bd9Sstevel@tonic-gate void 131*7c478bd9Sstevel@tonic-gate dict_init() 132*7c478bd9Sstevel@tonic-gate { 133*7c478bd9Sstevel@tonic-gate dictionary = startd_zalloc(sizeof (dictionary_t)); 134*7c478bd9Sstevel@tonic-gate 135*7c478bd9Sstevel@tonic-gate (void) pthread_mutex_init(&dictionary->dict_lock, NULL); 136*7c478bd9Sstevel@tonic-gate 137*7c478bd9Sstevel@tonic-gate dict_pool = startd_list_pool_create("dict", sizeof (dict_entry_t), 138*7c478bd9Sstevel@tonic-gate offsetof(dict_entry_t, de_link), dict_compare, UU_LIST_POOL_DEBUG); 139*7c478bd9Sstevel@tonic-gate assert(dict_pool != NULL); 140*7c478bd9Sstevel@tonic-gate 141*7c478bd9Sstevel@tonic-gate dictionary->dict_new_id = 0; 142*7c478bd9Sstevel@tonic-gate dictionary->dict_list = startd_list_create(dict_pool, dictionary, 143*7c478bd9Sstevel@tonic-gate UU_LIST_SORTED); 144*7c478bd9Sstevel@tonic-gate assert(dictionary->dict_list != NULL); 145*7c478bd9Sstevel@tonic-gate } 146