1*7836SJohn.Forte@Sun.COM /* 2*7836SJohn.Forte@Sun.COM * CDDL HEADER START 3*7836SJohn.Forte@Sun.COM * 4*7836SJohn.Forte@Sun.COM * The contents of this file are subject to the terms of the 5*7836SJohn.Forte@Sun.COM * Common Development and Distribution License (the "License"). 6*7836SJohn.Forte@Sun.COM * You may not use this file except in compliance with the License. 7*7836SJohn.Forte@Sun.COM * 8*7836SJohn.Forte@Sun.COM * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9*7836SJohn.Forte@Sun.COM * or http://www.opensolaris.org/os/licensing. 10*7836SJohn.Forte@Sun.COM * See the License for the specific language governing permissions 11*7836SJohn.Forte@Sun.COM * and limitations under the License. 12*7836SJohn.Forte@Sun.COM * 13*7836SJohn.Forte@Sun.COM * When distributing Covered Code, include this CDDL HEADER in each 14*7836SJohn.Forte@Sun.COM * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15*7836SJohn.Forte@Sun.COM * If applicable, add the following below this CDDL HEADER, with the 16*7836SJohn.Forte@Sun.COM * fields enclosed by brackets "[]" replaced with your own identifying 17*7836SJohn.Forte@Sun.COM * information: Portions Copyright [yyyy] [name of copyright owner] 18*7836SJohn.Forte@Sun.COM * 19*7836SJohn.Forte@Sun.COM * CDDL HEADER END 20*7836SJohn.Forte@Sun.COM */ 21*7836SJohn.Forte@Sun.COM /* 22*7836SJohn.Forte@Sun.COM * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 23*7836SJohn.Forte@Sun.COM * Use is subject to license terms. 24*7836SJohn.Forte@Sun.COM */ 25*7836SJohn.Forte@Sun.COM 26*7836SJohn.Forte@Sun.COM #ifndef _CFG_IMPL_H 27*7836SJohn.Forte@Sun.COM #define _CFG_IMPL_H 28*7836SJohn.Forte@Sun.COM 29*7836SJohn.Forte@Sun.COM #ifdef __cplusplus 30*7836SJohn.Forte@Sun.COM extern "C" { 31*7836SJohn.Forte@Sun.COM #endif 32*7836SJohn.Forte@Sun.COM 33*7836SJohn.Forte@Sun.COM #define MAX_CFG 16 /* Max. number of lines in /etc/dscfg_format */ 34*7836SJohn.Forte@Sun.COM 35*7836SJohn.Forte@Sun.COM #define CFG_MAX_KEY 256 36*7836SJohn.Forte@Sun.COM #define CFG_MAX_BUF 1024 37*7836SJohn.Forte@Sun.COM #define CFG_BLOCK_SIZE 512 38*7836SJohn.Forte@Sun.COM #define CFG_VTOC_SIZE 16 39*7836SJohn.Forte@Sun.COM #define CFG_VTOC_SKIP CFG_VTOC_SIZE * CFG_BLOCK_SIZE 40*7836SJohn.Forte@Sun.COM 41*7836SJohn.Forte@Sun.COM /* 42*7836SJohn.Forte@Sun.COM * Parser and file handling routines for Configuration parser. 43*7836SJohn.Forte@Sun.COM * 44*7836SJohn.Forte@Sun.COM * General layout on disk 45*7836SJohn.Forte@Sun.COM * 46*7836SJohn.Forte@Sun.COM * header cfgheader_t 47*7836SJohn.Forte@Sun.COM * parser configuration tag.field1.field2\n 48*7836SJohn.Forte@Sun.COM * configuration data copy1 freeform strings 49*7836SJohn.Forte@Sun.COM * configuration data copy2 freeform strings 50*7836SJohn.Forte@Sun.COM * 51*7836SJohn.Forte@Sun.COM * Strings in freeform fields are seperated by whitespace. 52*7836SJohn.Forte@Sun.COM * End of entry seperated by null. 53*7836SJohn.Forte@Sun.COM */ 54*7836SJohn.Forte@Sun.COM 55*7836SJohn.Forte@Sun.COM struct lookup { 56*7836SJohn.Forte@Sun.COM char l_word[CFG_MAX_KEY]; 57*7836SJohn.Forte@Sun.COM int l_value; 58*7836SJohn.Forte@Sun.COM struct lookup *l_next; 59*7836SJohn.Forte@Sun.COM }; 60*7836SJohn.Forte@Sun.COM 61*7836SJohn.Forte@Sun.COM struct parser { 62*7836SJohn.Forte@Sun.COM struct lookup tag; 63*7836SJohn.Forte@Sun.COM struct lookup *fld; 64*7836SJohn.Forte@Sun.COM struct parser *next; 65*7836SJohn.Forte@Sun.COM }; 66*7836SJohn.Forte@Sun.COM 67*7836SJohn.Forte@Sun.COM 68*7836SJohn.Forte@Sun.COM /* 69*7836SJohn.Forte@Sun.COM * cfglist description 70*7836SJohn.Forte@Sun.COM * 71*7836SJohn.Forte@Sun.COM * ________ 72*7836SJohn.Forte@Sun.COM * | | the header has (with other things) an array 73*7836SJohn.Forte@Sun.COM * | header | of h_cfg[n].l_size entries. index 4 74*7836SJohn.Forte@Sun.COM * disk layout | | contains cfp->cf_head->h_cfg[4].l_size. 75*7836SJohn.Forte@Sun.COM * |________| 76*7836SJohn.Forte@Sun.COM * cfgfile-mapped->| | 77*7836SJohn.Forte@Sun.COM * CFG_DEFAULT_PARSE_SIZE | parser | cache_hint.device.wrthru.nordcache.cnode 78*7836SJohn.Forte@Sun.COM * | | 79*7836SJohn.Forte@Sun.COM * |________| 80*7836SJohn.Forte@Sun.COM * cfp->cf_head->h_ccopy1>| | 81*7836SJohn.Forte@Sun.COM * CFG_DEFAULT_SSIZE | data | null terminated strings grouped together 82*7836SJohn.Forte@Sun.COM * | copy 1 | in order of cfglist offset. ie data at 83*7836SJohn.Forte@Sun.COM * |________| offset 0 is from h_cfgs[0].l_entry 84*7836SJohn.Forte@Sun.COM * cfp->cf_head->h_ccopy2>| | 85*7836SJohn.Forte@Sun.COM * CFG_DEFAULT_SSIZE | data | 86*7836SJohn.Forte@Sun.COM * | copy 2 | same as above, used for two stage commit 87*7836SJohn.Forte@Sun.COM * |________| 88*7836SJohn.Forte@Sun.COM * cfp->cf_head->h_sizes1>| | here is where lists of sizes go for each 89*7836SJohn.Forte@Sun.COM * CFG_DEFAULT_PSIZE | sizes | cfglist. each array is preceded by the num 90*7836SJohn.Forte@Sun.COM * | copy 1 | of entries. |5|120|130|140|103|125|10|25 is 91*7836SJohn.Forte@Sun.COM * |________| a list with 5 entries 120,130,140,103,125 92*7836SJohn.Forte@Sun.COM * cfp->cf_head->h_sizes2>| | these numbers are used to rebuild l_nentry 93*7836SJohn.Forte@Sun.COM * CFG_DEFAULT_PSIZE | sizes | and l_esiz fields in h_cfg[n] 94*7836SJohn.Forte@Sun.COM * | copy 2 | this list is done as a two stage commit 95*7836SJohn.Forte@Sun.COM * |________| 96*7836SJohn.Forte@Sun.COM * 97*7836SJohn.Forte@Sun.COM * 98*7836SJohn.Forte@Sun.COM * 99*7836SJohn.Forte@Sun.COM * Data is read into cfp->cf_head->h_ccopy1 and cfp->cf_head->h_ccopy2 100*7836SJohn.Forte@Sun.COM * along with thier corresponding size metadata in cfp->cf_head->h_sizes1 101*7836SJohn.Forte@Sun.COM * and cfp->cf_head->h_sizes2. This infomation is used to rebuild the 102*7836SJohn.Forte@Sun.COM * cfglist structures seen below. The data in the cfglist structure is then 103*7836SJohn.Forte@Sun.COM * the ONLY valid data. Additions and/or deletions to the database is done 104*7836SJohn.Forte@Sun.COM * by moving around the cfglists and doing the right things with the size 105*7836SJohn.Forte@Sun.COM * arrays, the actual entries, total list sizes, the total of all the sizes of 106*7836SJohn.Forte@Sun.COM * all the cfglists and memory allocation. After addition/deletions are done, 107*7836SJohn.Forte@Sun.COM * and cfg_close is called, all of the lists are placed back into h_cparse 108*7836SJohn.Forte@Sun.COM * (which is really h_ccopy1 or h_ccopy2) the persistent lists are placed 109*7836SJohn.Forte@Sun.COM * into h_sizes (which is really h_sizes1 or h_sizes2). 110*7836SJohn.Forte@Sun.COM * A copy of each cfglist[n].l_size is kept in the header 111*7836SJohn.Forte@Sun.COM * (cfgheader->cfgsizes[n]). 112*7836SJohn.Forte@Sun.COM * 113*7836SJohn.Forte@Sun.COM * 114*7836SJohn.Forte@Sun.COM * 115*7836SJohn.Forte@Sun.COM * 116*7836SJohn.Forte@Sun.COM * h_cfgs h_cfgs[3] 117*7836SJohn.Forte@Sun.COM * head |-[0]- /|-l_name == sndr 118*7836SJohn.Forte@Sun.COM * |- /|-[1]- / |-l_entry == host dev bmap host..ip sync '\0' ... 119*7836SJohn.Forte@Sun.COM * file |- / |-[2]- / |-l_esiz[0..l_nentry - 1] == [130, 132, 135, 133,..] 120*7836SJohn.Forte@Sun.COM * |--|---------|-[3]---- |-l_enabled[0..l_nentry - 1] == [1,0,0,1,1] 121*7836SJohn.Forte@Sun.COM * |- \ |-[4]- \ |-l_nentry == 5 122*7836SJohn.Forte@Sun.COM * |- \|-[5]- \ |-l_index == 3 123*7836SJohn.Forte@Sun.COM * |-[n]- \|-l_free == 50537 124*7836SJohn.Forte@Sun.COM * |-l_size == 663 (130 + 132 + 135 + 133 + 133) 125*7836SJohn.Forte@Sun.COM * 126*7836SJohn.Forte@Sun.COM * 127*7836SJohn.Forte@Sun.COM * 128*7836SJohn.Forte@Sun.COM * l_name - is set when the parser is read. 129*7836SJohn.Forte@Sun.COM * It is the first tag of a line of parser text. 130*7836SJohn.Forte@Sun.COM * l_entry - is a pointer to the beginning of the null terminated string 131*7836SJohn.Forte@Sun.COM * list that belongs to the cfglist tagged with l_name. 132*7836SJohn.Forte@Sun.COM * l_esiz - is a list of sizes of the strings contained in l_entry. 133*7836SJohn.Forte@Sun.COM * l_esiz[0] tells the size of the string at l_entry[0]. 134*7836SJohn.Forte@Sun.COM * l_esiz[n] is the size of the string that begins 135*7836SJohn.Forte@Sun.COM * at l_entry + l_esiz[0] + l_esiz[1]..+ l_esize[n - 1] 136*7836SJohn.Forte@Sun.COM * l_enabled - is a list of ones and zeros telling if this entry is alive 137*7836SJohn.Forte@Sun.COM * in the kernel. indexing is the same as l_esiz. (not implemented) 138*7836SJohn.Forte@Sun.COM * l_index - is the index of the parser tree that corresponds to l_name 139*7836SJohn.Forte@Sun.COM * and is set when the parser tree is built 140*7836SJohn.Forte@Sun.COM * l_free - is how memory is managed. Memory is allocated on a 141*7836SJohn.Forte@Sun.COM * DEFAULT_ENTRY_SIZE boundry. 142*7836SJohn.Forte@Sun.COM * the size of the balance of available memory at the end of l_entry 143*7836SJohn.Forte@Sun.COM * is kept here. when this number is lower than the string we need to add, 144*7836SJohn.Forte@Sun.COM * another block of memory is allocated for l_entry and the balance of 145*7836SJohn.Forte@Sun.COM * the size is added to l_free. 146*7836SJohn.Forte@Sun.COM * l_size - is size of this list. It is the summation of l_esiz[0..n] 147*7836SJohn.Forte@Sun.COM * 148*7836SJohn.Forte@Sun.COM */ 149*7836SJohn.Forte@Sun.COM 150*7836SJohn.Forte@Sun.COM typedef struct cfglist { 151*7836SJohn.Forte@Sun.COM char *l_name; /* name of list sndr, ii.. */ 152*7836SJohn.Forte@Sun.COM char *l_entry; /* start of list */ 153*7836SJohn.Forte@Sun.COM int *l_esiz; /* array of sizes of entries */ 154*7836SJohn.Forte@Sun.COM int l_nentry; /* number of entries */ 155*7836SJohn.Forte@Sun.COM int l_index; /* index in relation to parser position */ 156*7836SJohn.Forte@Sun.COM uint_t l_free; /* num of characters available */ 157*7836SJohn.Forte@Sun.COM int l_size; /* size of list */ 158*7836SJohn.Forte@Sun.COM } cfglist_t; 159*7836SJohn.Forte@Sun.COM 160*7836SJohn.Forte@Sun.COM /* note: this does not imply DEFAULT_NENTRIES * DEFAULT_ENTRY_SIZE */ 161*7836SJohn.Forte@Sun.COM #define DEFAULT_NENTRIES 100 /* value for l_esiz sizes array */ 162*7836SJohn.Forte@Sun.COM #define DEFAULT_ENTRY_SIZE (50 * CFG_MAX_BUF) /* 50K for each l_entry */ 163*7836SJohn.Forte@Sun.COM 164*7836SJohn.Forte@Sun.COM 165*7836SJohn.Forte@Sun.COM typedef struct cfgheader { 166*7836SJohn.Forte@Sun.COM int32_t h_magic; 167*7836SJohn.Forte@Sun.COM int h_state; /* State flag see below */ 168*7836SJohn.Forte@Sun.COM time_t h_stamp; /* time stamp of last update */ 169*7836SJohn.Forte@Sun.COM long h_lock; /* lock for update */ 170*7836SJohn.Forte@Sun.COM long h_size; /* total file size */ 171*7836SJohn.Forte@Sun.COM int h_parseoff; /* parser config offset */ 172*7836SJohn.Forte@Sun.COM int h_parsesize; /* parser config size */ 173*7836SJohn.Forte@Sun.COM char *h_cparse; /* start of configuration */ 174*7836SJohn.Forte@Sun.COM int h_csize; /* size of config section */ 175*7836SJohn.Forte@Sun.COM int h_acsize; /* size of alternate config section */ 176*7836SJohn.Forte@Sun.COM int *h_sizes; /* sizes of lists */ 177*7836SJohn.Forte@Sun.COM int h_psize; /* size of persistent section */ 178*7836SJohn.Forte@Sun.COM int h_apsize; /* size of alternate persistent section */ 179*7836SJohn.Forte@Sun.COM char *h_ccopy1; /* base of config section 1 */ 180*7836SJohn.Forte@Sun.COM char *h_ccopy2; /* base of config section 2 */ 181*7836SJohn.Forte@Sun.COM int *h_sizes1; /* sizes of lists on disk 1 */ 182*7836SJohn.Forte@Sun.COM int *h_sizes2; /* sizes of lists on disk 2 */ 183*7836SJohn.Forte@Sun.COM int h_seq1; /* Sequenece number copy 1 both sections */ 184*7836SJohn.Forte@Sun.COM int h_seq2; /* Sequenece number copy 2 both sections */ 185*7836SJohn.Forte@Sun.COM char h_ncfgs; /* number of cfgs */ 186*7836SJohn.Forte@Sun.COM cfglist_t *h_cfgs; /* start of cfg lists */ 187*7836SJohn.Forte@Sun.COM int h_cfgsizes[MAX_CFG]; /* Sizes of configs */ 188*7836SJohn.Forte@Sun.COM } cfgheader_t; 189*7836SJohn.Forte@Sun.COM 190*7836SJohn.Forte@Sun.COM #define CFG_HDR_GOOD 0x1 191*7836SJohn.Forte@Sun.COM #define CFG_HDR_INVALID 0x2 192*7836SJohn.Forte@Sun.COM #define CFG_HDR_RDLOCK 0x4 193*7836SJohn.Forte@Sun.COM #define CFG_HDR_WRLOCK 0x8 194*7836SJohn.Forte@Sun.COM 195*7836SJohn.Forte@Sun.COM struct cfg_io_s; /* forward reference */ 196*7836SJohn.Forte@Sun.COM typedef struct cfp { 197*7836SJohn.Forte@Sun.COM int cf_fd; /* file descriptor */ 198*7836SJohn.Forte@Sun.COM int cf_flag; /* flags - see below */ 199*7836SJohn.Forte@Sun.COM long cf_size; /* size of file in fbas */ 200*7836SJohn.Forte@Sun.COM int cf_lock; /* lock file descriptor */ 201*7836SJohn.Forte@Sun.COM char *cf_mapped; /* mapped location via mmap */ 202*7836SJohn.Forte@Sun.COM char *cf_name; /* file name */ 203*7836SJohn.Forte@Sun.COM cfgheader_t *cf_head; /* header */ 204*7836SJohn.Forte@Sun.COM struct cfg_io_s *cf_pp; /* i/o provider */ 205*7836SJohn.Forte@Sun.COM } cfp_t; 206*7836SJohn.Forte@Sun.COM 207*7836SJohn.Forte@Sun.COM typedef struct cfgfile { 208*7836SJohn.Forte@Sun.COM void *cf_node; /* node filter */ 209*7836SJohn.Forte@Sun.COM cfp_t cf[2]; /* local & optional cluster file */ 210*7836SJohn.Forte@Sun.COM } CFGFILE; 211*7836SJohn.Forte@Sun.COM 212*7836SJohn.Forte@Sun.COM typedef struct cfg_io_s { 213*7836SJohn.Forte@Sun.COM struct cfg_io_s *next; /* Link to next module */ 214*7836SJohn.Forte@Sun.COM char *name; /* name of provider */ 215*7836SJohn.Forte@Sun.COM cfp_t *(*open)(cfp_t *, char *); /* Open device */ 216*7836SJohn.Forte@Sun.COM void (*close)(cfp_t *); /* Close device */ 217*7836SJohn.Forte@Sun.COM int (*seek)(cfp_t *, int, int); /* Seek */ 218*7836SJohn.Forte@Sun.COM int (*read)(cfp_t *, void *, int); /* read */ 219*7836SJohn.Forte@Sun.COM int (*write)(cfp_t *, void *, int); /* write */ 220*7836SJohn.Forte@Sun.COM char *(*readcf)(cfp_t *, char *, int, int); /* Read mem config */ 221*7836SJohn.Forte@Sun.COM int (*addcf)(cfp_t *, char *, int); /* add to mem config */ 222*7836SJohn.Forte@Sun.COM int (*remcf)(cfp_t *, int, int); /* remove an entry */ 223*7836SJohn.Forte@Sun.COM int (*replacecf)(cfp_t *, char *, int, int); /* replace entry */ 224*7836SJohn.Forte@Sun.COM } cfg_io_t; 225*7836SJohn.Forte@Sun.COM 226*7836SJohn.Forte@Sun.COM #define CFG_FILE 0x1 /* database is in a regular file */ 227*7836SJohn.Forte@Sun.COM #define CFG_NOREWIND 0x4 /* don't rewind for each get_string */ 228*7836SJohn.Forte@Sun.COM #define CFG_NOWRVTOC 0x8 /* sector starts in vtoc land, skip it */ 229*7836SJohn.Forte@Sun.COM #define CFG_RDONLY 0x10 /* database is read only */ 230*7836SJohn.Forte@Sun.COM 231*7836SJohn.Forte@Sun.COM /* 232*7836SJohn.Forte@Sun.COM * constants 233*7836SJohn.Forte@Sun.COM */ 234*7836SJohn.Forte@Sun.COM #define CFG_RDEV_LOCKFILE "/var/tmp/.dscfg.lck" 235*7836SJohn.Forte@Sun.COM #define CFG_NEW_MAGIC 0x4d414749 /* MAGI */ 236*7836SJohn.Forte@Sun.COM #define CFG_DEFAULT_PARSE_SIZE (16 * 1024) 237*7836SJohn.Forte@Sun.COM #define CFG_DEFAULT_SSIZE (2 * 1024 * 1024) 238*7836SJohn.Forte@Sun.COM #define CFG_DEFAULT_PSIZE (512 * 1024) 239*7836SJohn.Forte@Sun.COM #define CFG_DEFAULT_OLDSIZE (96 * 1024) 240*7836SJohn.Forte@Sun.COM #define CFG_CONFIG_SIZE (CFG_DEFAULT_PARSE_SIZE + \ 241*7836SJohn.Forte@Sun.COM (2 * CFG_DEFAULT_SSIZE) + \ 242*7836SJohn.Forte@Sun.COM (2 * CFG_DEFAULT_PSIZE)) 243*7836SJohn.Forte@Sun.COM #ifdef __cplusplus 244*7836SJohn.Forte@Sun.COM } 245*7836SJohn.Forte@Sun.COM #endif 246*7836SJohn.Forte@Sun.COM 247*7836SJohn.Forte@Sun.COM #endif /* _CFG_IMPL_H */ 248