xref: /onnv-gate/usr/src/lib/libdscfg/common/cfg_impl.h (revision 7836:4e95154b5b7a)
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