diff options
Diffstat (limited to 'usr/src/cmd/isns/isnsd/cache.c')
-rw-r--r-- | usr/src/cmd/isns/isnsd/cache.c | 469 |
1 files changed, 469 insertions, 0 deletions
diff --git a/usr/src/cmd/isns/isnsd/cache.c b/usr/src/cmd/isns/isnsd/cache.c new file mode 100644 index 0000000000..45d40c2c10 --- /dev/null +++ b/usr/src/cmd/isns/isnsd/cache.c @@ -0,0 +1,469 @@ +/* + * 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 2008 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "isns_server.h" +#include "isns_cache.h" +#include "isns_msgq.h" +#include "isns_obj.h" +#include "isns_htab.h" + +/* + * external variables + */ +extern msg_queue_t *sys_q; + +#ifdef DEBUG +extern int verbose_lock; +#endif + +/* + * global data + */ +int cache_flag = 0; + +/* + * local variables + */ +static cache_t *imc; + +/* + * local functions. + */ + +/* + * **************************************************************************** + * cache_init: + * create the cache data initially, including to invoke individual + * functions for creating the hash tables for object storage and + * discovery domain membership matrix. + * + * return - 0: no error; 1: otherwise. + * + * **************************************************************************** + */ +int +cache_init( +) +{ + /* + * allocate global cache memory. + */ + imc = (cache_t *)calloc(sizeof (cache_t), 1); + if (imc == NULL || + obj_tab_init(imc) != 0 || + dd_matrix_init(imc) != 0) { + cache_destroy(); + return (1); /* no memory */ + } + + /* + * initialize global cache rwlock. + */ + (void) rwlock_init(&imc->l, NULL, NULL); + + /* + * inintialize global cache functions. + */ + imc->get_hval = obj_hval; + imc->get_uid = get_obj_uid; + imc->set_uid = set_obj_uid; + imc->timestamp = get_timestamp; + imc->add_hook = add_object; + imc->replace_hook = replace_object; + imc->cmp = obj_cmp; + imc->clone = assoc_clone; + imc->ddd = update_ddd; +#ifdef DEBUG + imc->dump = obj_dump; +#endif + + return (0); +} + +/* + * **************************************************************************** + * cache_destroy: + * destroy the cache data. + * + * **************************************************************************** + */ +void +cache_destroy( +) +{ + /* do nothing */ +} + +/* + * **************************************************************************** + * cache_lock: + * grab the lock on the cache data. + * + * mode - the read/write mode of the lock. + * return - error code. + * + * **************************************************************************** + */ +int +cache_lock( + int mode +) +{ + int ret = 0; + + switch (mode) { + case CACHE_WRITE: + ret = rw_wrlock(&imc->l); +#ifdef DEBUG + if (verbose_lock) { + printf("cache locked for writing.\n"); + } +#endif + break; + case CACHE_READ: + ret = rw_rdlock(&imc->l); +#ifdef DEBUG + if (verbose_lock) { + printf("cache locked for reading.\n"); + } +#endif + break; + case CACHE_TRY_READ: + ret = rw_tryrdlock(&imc->l); +#ifdef DEBUG + if (verbose_lock) { + if (ret == 0) { + printf("cache locked for reading.\n"); + } else { + printf("cache locked for reading failed.\n"); + } + } +#endif + break; + default: + break; + } + + return (ret); +} + +/* + * **************************************************************************** + * cache_unlock: + * release the lock on the cache data. + * if the cache was locked for writing, a synchronization between + * the cache and persistent data store needs to be performed. + * + * mode - the read/write mode which the cache data was locked for. + * ec - 0: commit the cache update; otherwise retreat it. + * return - error code. + * + * **************************************************************************** + */ +int +cache_unlock( + int mode, + int ec +) +{ + if (mode != CACHE_NO_ACTION) { + /* sync between cache and data store */ + if (mode == CACHE_WRITE) { + if (sys_q) { + ec = data_sync(ec); + } + + /* rest the cache update flag */ + RESET_CACHE_UPDATED(); + } + + ASSERT(!IS_CACHE_UPDATED()); + + /* unlock it */ + (void) rw_unlock(&imc->l); +#ifdef DEBUG + if (verbose_lock) { + printf("cache unlocked.\n"); + } +#endif + } + + return (ec); +} + +/* + * **************************************************************************** + * cache_lock_read: + * grab the read lock on the cache. + * + * return - error code. + * + * **************************************************************************** + */ +int +cache_lock_read( +) +{ + return (cache_lock(CACHE_READ)); +} + +/* + * **************************************************************************** + * cache_lock_write: + * grab the write lock on the cache. + * + * return - error code. + * + * **************************************************************************** + */ +int +cache_lock_write( +) +{ + return (cache_lock(CACHE_WRITE)); +} + +/* + * **************************************************************************** + * cache_unlock_sync: + * synchronize the cache with persistent data store and + * release the lock. + * + * ec - 0: commit the cache update; otherwise retreat it. + * return - error code. + * + * **************************************************************************** + */ +int +cache_unlock_sync( + int ec +) +{ + return (cache_unlock(CACHE_WRITE, ec)); +} + +/* + * **************************************************************************** + * cache_unlock_nosync: + * release the lock, no need to sync the data between cache and + * data store. + * if the cache has been updated, do not call this function, call + * cache_unlock_sync() with non-zero error code to indicate the + * sync action. + * + * return - error code. + * + * **************************************************************************** + */ +int +cache_unlock_nosync( +) +{ + return (cache_unlock(CACHE_READ, 0)); +} + +/* + * **************************************************************************** + * cache_get_htab: + * get the hash table for individual type of object. + * + * type - the object type. + * return - the hash table. + * + * **************************************************************************** + */ +htab_t * +cache_get_htab( + isns_type_t type +) +{ + if (type > 0 && type < MAX_OBJ_TYPE) { + return (imc->t[type]); + } + + return (NULL); +} + +/* + * **************************************************************************** + * cache_get_matrix: + * get the membership matrix for a discovery domain or a + * discovery domain set. + * + * type - the discovery domain or discovery domain set object type. + * return - the matrix. + * + * **************************************************************************** + */ +matrix_t * +cache_get_matrix( + isns_type_t type +) +{ + matrix_t *x = NULL; + + switch (type) { + case OBJ_DD: + x = imc->x[0]; + break; + case OBJ_DDS: + x = imc->x[1]; + break; + default: + break; + } + + return (x); +} + +/* + * **************************************************************************** + * cache_lookup: + * invoke the hash table lookup for looking up a specific object and + * perform the callback function on the object. + * + * lcp - the object lookup control data. + * uid_p - the pointer of object UID for returning. + * callback - the callback function for the object. + * return - error code. + * + * **************************************************************************** + */ +int +cache_lookup( + lookup_ctrl_t *lcp, + uint32_t *uid_p, + int (*callback)(void *, void *) +) +{ + return (htab_lookup(imc->t[lcp->type], + lcp, + (lcp->op[0] == OP_INTEGER) ? lcp->data[0].ui : 0, + uid_p, + callback, + 0)); +} + +/* + * **************************************************************************** + * cache_lookup: + * invoke the hash table lookup for looking up a specific object, + * the callback function is going to change the key of the object. + * + * lcp - the object lookup control data. + * uid_p - the pointer of object UID for returning. + * callback - the callback function for the object. + * return - error code. + * + * **************************************************************************** + */ +int +cache_rekey( + lookup_ctrl_t *lcp, + uint32_t *uid_p, + int (*callback)(void *, void *) +) +{ + return (htab_lookup(imc->t[lcp->type], + lcp, + (lcp->op[0] == OP_INTEGER) ? lcp->data[0].ui : 0, + uid_p, + callback, + 1)); +} + +/* + * **************************************************************************** + * cache_add: + * invoke hash table add to add an object. + * + * obj - the object being added. + * flag - 0: a real object; + * otherwise an association object for discovery domain membership. + * uid_p - the pointer of object UID for returning. + * update_p - the pointer of flag (update object or newly register) + * for returning. + * return - error code. + * + * **************************************************************************** + */ +int +cache_add( + isns_obj_t *obj, + int flag, + uint32_t *uid_p, + int *update_p +) +{ + return (htab_add(imc->t[obj->type], obj, flag, uid_p, update_p)); +} + +/* + * **************************************************************************** + * cache_remove: + * invoke hash table remove to remove an object. + * + * lcp - the lookup control data for the object being removed. + * flag - 0: a real object; + * otherwise an association object for discovery domain membership. + * return - the removed object. + * + * **************************************************************************** + */ +isns_obj_t * +cache_remove( + lookup_ctrl_t *lcp, + int flag +) +{ + return (htab_remove(imc->t[lcp->type], + lcp, + (lcp->op[0] == OP_INTEGER) ? lcp->data[0].ui : 0, + flag)); +} + +/* + * **************************************************************************** + * cache_dump_htab: + * dump the hash table for debugging purpose. + * + * type - the object type. + * + * **************************************************************************** + */ +#ifdef DEBUG +void +cache_dump_htab( + isns_type_t type +) +{ + (void) htab_dump(imc->t[type]); +} +#endif |