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