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