xref: /titanic_50/usr/src/lib/libdscfg/common/cfg_impl.h (revision 4297a3b0d0a35d80f86fff155e288e885a100e6d)
1 /*
2  * CDDL HEADER START
3  *
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.
7  *
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.
12  *
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]
18  *
19  * CDDL HEADER END
20  */
21 /*
22  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  */
25 
26 #ifndef	_CFG_IMPL_H
27 #define	_CFG_IMPL_H
28 
29 #ifdef __cplusplus
30 extern "C" {
31 #endif
32 
33 #define	MAX_CFG		16	/* Max. number of lines in /etc/dscfg_format */
34 
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
40 
41 /*
42  * Parser and file handling routines for Configuration parser.
43  *
44  *      General layout on disk
45  *
46  *      header                          cfgheader_t
47  *      parser configuration            tag.field1.field2\n
48  *      configuration data copy1        freeform strings
49  *      configuration data copy2        freeform strings
50  *
51  * Strings in freeform fields are seperated by whitespace.
52  * End of entry seperated by null.
53  */
54 
55 struct lookup {
56 	char		l_word[CFG_MAX_KEY];
57 	int		l_value;
58 	struct lookup	*l_next;
59 };
60 
61 struct parser {
62 	struct lookup	tag;
63 	struct lookup	*fld;
64 	struct parser	*next;
65 };
66 
67 
68 /*
69  * cfglist description
70  *
71  *                         ________
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.
75  *                        |________|
76  *        cfgfile-mapped->|        |
77  * CFG_DEFAULT_PARSE_SIZE | parser | cache_hint.device.wrthru.nordcache.cnode
78  *                        |        |
79  *                        |________|
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
87  *                        |________|
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
95  *                        |________|
96  *
97  *
98  *
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]).
112  *
113  *
114  *
115  *
116  *		  h_cfgs        h_cfgs[3]
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)
125  *
126  *
127  *
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]
147  *
148  */
149 
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 */
158 } cfglist_t;
159 
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 */
163 
164 
165 typedef struct cfgheader {
166 	int32_t	h_magic;
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 */
188 } cfgheader_t;
189 
190 #define	CFG_HDR_GOOD	0x1
191 #define	CFG_HDR_INVALID	0x2
192 #define	CFG_HDR_RDLOCK	0x4
193 #define	CFG_HDR_WRLOCK	0x8
194 
195 struct cfg_io_s;		/* forward reference */
196 typedef	struct cfp {
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 */
205 } cfp_t;
206 
207 typedef struct cfgfile {
208 	void	*cf_node;	/* node filter */
209 	cfp_t	cf[2];		/* local & optional cluster file */
210 } CFGFILE;
211 
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 */
224 } cfg_io_t;
225 
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 */
230 
231 /*
232  * constants
233  */
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))
243 #ifdef	__cplusplus
244 }
245 #endif
246 
247 #endif	/* _CFG_IMPL_H */
248