xref: /freebsd/sys/geom/vinum/geom_vinum_var.h (revision 9eb0e8326d0fe73ae947959c1df327238d3b2d53)
1 /*-
2  * SPDX-License-Identifier: BSD-4-Clause
3  *
4  * Copyright (c) 2004, 2007 Lukas Ertl
5  * Copyright (c) 1997, 1998, 1999
6  *      Nan Yang Computer Services Limited.  All rights reserved.
7  *
8  * Parts copyright (c) 1997, 1998 Cybernet Corporation, NetMAX project.
9  * Parts written by Greg Lehey.
10  *
11  *  This software is distributed under the so-called ``Berkeley
12  *  License'':                                                                    *
13  * Redistribution and use in source and binary forms, with or without
14  * modification, are permitted provided that the following conditions
15  * are met:
16  * 1. Redistributions of source code must retain the above copyright
17  *    notice, this list of conditions and the following disclaimer.
18  * 2. Redistributions in binary form must reproduce the above copyright
19  *    notice, this list of conditions and the following disclaimer in the
20  *    documentation and/or other materials provided with the distribution.
21  * 3. All advertising materials mentioning features or use of this software
22  *    must display the following acknowledgement:
23  *      This product includes software developed by Nan Yang Computer
24  *      Services Limited.
25  * 4. Neither the name of the Company nor the names of its contributors
26  *    may be used to endorse or promote products derived from this software
27  *    without specific prior written permission.
28  *
29  * This software is provided ``as is'', and any express or implied
30  * warranties, including, but not limited to, the implied warranties of
31  * merchantability and fitness for a particular purpose are disclaimed.
32  * In no event shall the company or contributors be liable for any
33  * direct, indirect, incidental, special, exemplary, or consequential
34  * damages (including, but not limited to, procurement of substitute
35  * goods or services; loss of use, data, or profits; or business
36  * interruption) however caused and on any theory of liability, whether
37  * in contract, strict liability, or tort (including negligence or
38  * otherwise) arising in any way out of the use of this software, even if
39  * advised of the possibility of such damage.
40  *
41  * $FreeBSD$
42  */
43 
44 #ifndef	_GEOM_VINUM_VAR_H_
45 #define	_GEOM_VINUM_VAR_H_
46 
47 /*
48  * Slice header
49  *
50  * Vinum drives start with this structure:
51  *
52  *\                                            Sector
53  * |--------------------------------------|
54  * |   PDP-11 memorial boot block         |      0
55  * |--------------------------------------|
56  * |   Disk label, maybe                  |      1
57  * |--------------------------------------|
58  * |   Slice definition  (vinum_hdr)      |      8
59  * |--------------------------------------|
60  * |                                      |
61  * |   Configuration info, first copy     |      9
62  * |                                      |
63  * |--------------------------------------|
64  * |                                      |
65  * |   Configuration info, second copy    |      9 + size of config
66  * |                                      |
67  * |--------------------------------------|
68  */
69 
70 /* Sizes and offsets of our information. */
71 #define	GV_HDR_OFFSET	4096	/* Offset of vinum header. */
72 #define	GV_HDR_LEN	512	/* Size of vinum header. */
73 #define	GV_CFG_OFFSET	4608	/* Offset of first config copy. */
74 #define	GV_CFG_LEN	65536	/* Size of config copy. */
75 
76 /* This is where the actual data starts. */
77 #define	GV_DATA_START	(GV_CFG_LEN * 2 + GV_CFG_OFFSET)
78 /* #define GV_DATA_START	(GV_CFG_LEN * 2 + GV_HDR_LEN) */
79 
80 #define	GV_MAXDRIVENAME	32	/* Maximum length of a device name. */
81 #define	GV_MAXSDNAME	64	/* Maximum length of a subdisk name. */
82 #define	GV_MAXPLEXNAME	64	/* Maximum length of a plex name. */
83 #define	GV_MAXVOLNAME	64	/* Maximum length of a volume name. */
84 
85 /* Command line flags. */
86 #define	GV_FLAG_R	0x01
87 #define	GV_FLAG_S	0x02
88 #define	GV_FLAG_V	0x04
89 #define	GV_FLAG_VV	0x08
90 #define	GV_FLAG_F	0x10
91 
92 /* Object types. */
93 #define	GV_TYPE_VOL	1
94 #define	GV_TYPE_PLEX	2
95 #define	GV_TYPE_SD	3
96 #define	GV_TYPE_DRIVE	4
97 
98 /* State changing flags. */
99 #define	GV_SETSTATE_FORCE	0x1
100 #define	GV_SETSTATE_CONFIG	0x2
101 
102 /* Subdisk state bitmaps for plexes. */
103 #define	GV_SD_DOWNSTATE		0x01	/* Subdisk is down. */
104 #define	GV_SD_STALESTATE	0x02	/* Subdisk is stale. */
105 #define	GV_SD_INITSTATE		0x04	/* Subdisk is initializing. */
106 #define	GV_SD_UPSTATE		0x08	/* Subdisk is up. */
107 
108 /* Synchronization/initialization request sizes. */
109 #define	GV_MIN_SYNCSIZE		512
110 #define	GV_MAX_SYNCSIZE		maxphys
111 #define	GV_DFLT_SYNCSIZE	65536
112 
113 /* Flags for BIOs, as they are processed within vinum. */
114 #define	GV_BIO_GROW	0x01
115 #define	GV_BIO_MALLOC	0x02
116 #define	GV_BIO_ONHOLD	0x04
117 #define	GV_BIO_SYNCREQ	0x08
118 #define	GV_BIO_INIT	0x10
119 #define	GV_BIO_REBUILD	0x20
120 #define	GV_BIO_CHECK	0x40
121 #define	GV_BIO_PARITY	0x80
122 #define GV_BIO_INTERNAL \
123     (GV_BIO_SYNCREQ | GV_BIO_INIT | GV_BIO_REBUILD | GV_BIO_CHECK | GV_BIO_GROW)
124 
125 /* Error codes to be used within gvinum. */
126 #define	GV_ERR_SETSTATE		(-1)	/* Error setting state. */
127 #define	GV_ERR_BADSIZE		(-2)	/* Object has wrong size. */
128 #define	GV_ERR_INVTYPE		(-3)    /* Invalid object type. */
129 #define	GV_ERR_CREATE		(-4)	/* Error creating gvinum object. */
130 #define	GV_ERR_ISBUSY		(-5)	/* Object is busy. */
131 #define	GV_ERR_ISATTACHED	(-6)	/* Object is attached to another. */
132 #define	GV_ERR_INVFLAG		(-7)	/* Invalid flag passed. */
133 #define	GV_ERR_INVSTATE		(-8)	/* Invalid state. */
134 #define	GV_ERR_NOTFOUND		(-9)	/* Object not found. */
135 #define	GV_ERR_NAMETAKEN	(-10)	/* Object name is taken. */
136 #define	GV_ERR_NOSPACE		(-11)	/* No space left on drive/subdisk. */
137 #define	GV_ERR_BADOFFSET	(-12)	/* Invalid offset specified. */
138 #define	GV_ERR_INVNAME		(-13)	/* Invalid object name. */
139 #define	GV_ERR_PLEXORG		(-14)	/* Invalid plex organization. */
140 
141 /*
142  * hostname is 256 bytes long, but we don't need to shlep multiple copies in
143  * vinum.  We use the host name just to identify this system, and 32 bytes
144  * should be ample for that purpose.
145  */
146 
147 #define	GV_HOSTNAME_LEN	32
148 struct gv_label {
149 	char	sysname[GV_HOSTNAME_LEN]; /* System name at creation time. */
150 	char	name[GV_MAXDRIVENAME];	/* Our name of the drive. */
151 	struct timeval	date_of_birth;	/* The time it was created ... */
152 	struct timeval	last_update;	/* ... and the time of last update. */
153 	off_t		drive_size;	/* Total size incl. headers. */
154 };
155 
156 /* The 'header' of each valid vinum drive. */
157 struct gv_hdr {
158 	uint64_t	magic;
159 #define GV_OLD_MAGIC	0x494E2056494E4F00LL
160 #define GV_OLD_NOMAGIC	0x4E4F2056494E4F00LL
161 #define GV_MAGIC	0x56494E554D2D3100LL
162 #define GV_NOMAGIC	0x56494E554D2D2D00LL
163 
164 	uint64_t	config_length;
165 	struct gv_label	label;
166 };
167 
168 /* A single freelist entry of a drive. */
169 struct gv_freelist {
170 	off_t size;				/* Size of this free slot. */
171 	off_t offset;				/* Offset on the drive. */
172 	LIST_ENTRY(gv_freelist) freelist;
173 };
174 
175 /*
176  * Since we share structures between userland and kernel, we need this helper
177  * struct instead of struct bio_queue_head and friends.  Maybe I find a proper
178  * solution some day.
179  */
180 struct gv_bioq {
181 	struct bio *bp;
182 	TAILQ_ENTRY(gv_bioq)	queue;
183 };
184 
185 #define	GV_EVENT_DRIVE_TASTED		1
186 #define	GV_EVENT_DRIVE_LOST		2
187 #define	GV_EVENT_THREAD_EXIT		3
188 #define	GV_EVENT_CREATE_DRIVE		4
189 #define	GV_EVENT_CREATE_VOLUME		5
190 #define	GV_EVENT_CREATE_PLEX		6
191 #define	GV_EVENT_CREATE_SD		7
192 #define	GV_EVENT_SAVE_CONFIG		8
193 #define	GV_EVENT_RM_VOLUME		9
194 #define	GV_EVENT_RM_PLEX		10
195 #define	GV_EVENT_RM_SD			11
196 #define	GV_EVENT_RM_DRIVE		12
197 #define	GV_EVENT_SET_SD_STATE		13
198 #define	GV_EVENT_SET_DRIVE_STATE	14
199 #define	GV_EVENT_SET_VOL_STATE		15
200 #define	GV_EVENT_SET_PLEX_STATE		16
201 #define	GV_EVENT_RESET_CONFIG		17
202 #define	GV_EVENT_PARITY_REBUILD		18
203 #define	GV_EVENT_PARITY_CHECK		19
204 #define	GV_EVENT_START_PLEX		20
205 #define	GV_EVENT_START_VOLUME		21
206 #define	GV_EVENT_ATTACH_PLEX		22
207 #define	GV_EVENT_ATTACH_SD		23
208 #define	GV_EVENT_DETACH_PLEX		24
209 #define	GV_EVENT_DETACH_SD		25
210 #define	GV_EVENT_RENAME_VOL		26
211 #define	GV_EVENT_RENAME_PLEX		27
212 #define	GV_EVENT_RENAME_SD		28
213 #define	GV_EVENT_RENAME_DRIVE		29
214 #define	GV_EVENT_MOVE_SD		30
215 #define	GV_EVENT_SETUP_OBJECTS		31
216 
217 #ifdef _KERNEL
218 struct gv_event {
219 	int	type;
220 	void	*arg1;
221 	void	*arg2;
222 	intmax_t arg3;
223 	intmax_t arg4;
224 	TAILQ_ENTRY(gv_event)	events;
225 };
226 
227 /* This struct contains the main vinum config. */
228 struct gv_softc {
229 	/* Linked lists of all objects in our setup. */
230 	LIST_HEAD(,gv_drive)	drives;		/* All drives. */
231 	LIST_HEAD(,gv_plex)	plexes;		/* All plexes. */
232 	LIST_HEAD(,gv_sd)	subdisks;	/* All subdisks. */
233 	LIST_HEAD(,gv_volume)	volumes;	/* All volumes. */
234 
235 	TAILQ_HEAD(,gv_event)	equeue;		/* Event queue. */
236 	struct mtx		equeue_mtx;	/* Event queue lock. */
237 	struct mtx		bqueue_mtx;	/* BIO queue lock. */
238 	struct mtx		config_mtx;	/* Configuration lock. */
239 	struct bio_queue_head	*bqueue_down;	/* BIO queue incoming
240 						   requests. */
241 	struct bio_queue_head	*bqueue_up;	/* BIO queue for completed
242 						   requests. */
243 	struct g_geom		*geom;		/* Pointer to our VINUM geom. */
244 	struct proc		*worker;	/* Worker process. */
245 };
246 #endif
247 
248 /* softc for a drive. */
249 struct gv_drive {
250 	char	name[GV_MAXDRIVENAME];		/* The name of this drive. */
251 	char	device[GV_MAXDRIVENAME];	/* Associated device. */
252 	int	state;				/* The state of this drive. */
253 #define	GV_DRIVE_DOWN	0
254 #define	GV_DRIVE_UP	1
255 
256 	off_t	size;				/* Size of this drive. */
257 	off_t	avail;				/* Available space. */
258 	int	sdcount;			/* Number of subdisks. */
259 
260 	int	flags;
261 #define	GV_DRIVE_REFERENCED	0x01	/* The drive isn't really existing,
262 					   but was referenced by a subdisk
263 					   during taste. */
264 #define	GV_DRIVE_ORPHANED	0x02	/* The drive was orphaned. */
265 
266 	struct gv_hdr	*hdr;		/* The drive header. */
267 
268 	struct g_consumer *consumer;	/* Consumer attached to this drive. */
269 	int	active;			/* Number of active requests. */
270 
271 	int freelist_entries;			/* Count of freelist entries. */
272 	LIST_HEAD(,gv_freelist)	freelist;	/* List of freelist entries. */
273 	LIST_HEAD(,gv_sd)	subdisks;	/* Subdisks on this drive. */
274 	LIST_ENTRY(gv_drive)	drive;		/* Entry in the vinum config. */
275 
276 	struct gv_softc	*vinumconf;		/* Pointer to the vinum conf. */
277 };
278 
279 /* softc for a subdisk. */
280 struct gv_sd {
281 	char	name[GV_MAXSDNAME];	/* The name of this subdisk. */
282 	off_t	size;			/* The size of this subdisk. */
283 	off_t	drive_offset;		/* Offset in the underlying drive. */
284 	off_t	plex_offset;		/* Offset in the associated plex. */
285 	int	state;			/* The state of this subdisk. */
286 #define	GV_SD_DOWN		0
287 #define	GV_SD_STALE		1
288 #define	GV_SD_INITIALIZING	2
289 #define	GV_SD_REVIVING		3
290 #define	GV_SD_UP		4
291 
292 	off_t	initialized;		/* Count of initialized bytes. */
293 
294 	int	init_size;		/* Initialization read/write size. */
295 	int	init_error;		/* Flag error on initialization. */
296 
297 	int	flags;
298 #define	GV_SD_NEWBORN		0x01	/* Subdisk is created by user. */
299 #define	GV_SD_TASTED		0x02	/* Subdisk is created during taste. */
300 #define	GV_SD_CANGOUP		0x04	/* Subdisk can go up immediately. */
301 #define GV_SD_GROW		0x08	/* Subdisk is added to striped plex. */
302 
303 	char drive[GV_MAXDRIVENAME];	/* Name of underlying drive. */
304 	char plex[GV_MAXPLEXNAME];	/* Name of associated plex. */
305 
306 	struct gv_drive	*drive_sc;	/* Pointer to underlying drive. */
307 	struct gv_plex	*plex_sc;	/* Pointer to associated plex. */
308 
309 	LIST_ENTRY(gv_sd) from_drive;	/* Subdisk list of underlying drive. */
310 	LIST_ENTRY(gv_sd) in_plex;	/* Subdisk list of associated plex. */
311 	LIST_ENTRY(gv_sd) sd;		/* Entry in the vinum config. */
312 
313 	struct gv_softc	*vinumconf;	/* Pointer to the vinum config. */
314 };
315 
316 /* softc for a plex. */
317 struct gv_plex {
318 	char	name[GV_MAXPLEXNAME];	/* The name of the plex. */
319 	off_t	size;			/* The size of the plex. */
320 	int	state;			/* The plex state. */
321 #define	GV_PLEX_DOWN		0
322 #define	GV_PLEX_INITIALIZING	1
323 #define	GV_PLEX_DEGRADED	2
324 #define GV_PLEX_GROWABLE	3
325 #define	GV_PLEX_UP		4
326 
327 	int	org;			/* The plex organisation. */
328 #define	GV_PLEX_DISORG	0
329 #define	GV_PLEX_CONCAT	1
330 #define	GV_PLEX_STRIPED	2
331 #define	GV_PLEX_RAID5	4
332 
333 	int	stripesize;		/* The stripe size of the plex. */
334 
335 	char	volume[GV_MAXVOLNAME];	/* Name of associated volume. */
336 	struct gv_volume *vol_sc;	/* Pointer to associated volume. */
337 
338 	int	sddetached;		/* Number of detached subdisks. */
339 	int	sdcount;		/* Number of subdisks in this plex. */
340 	int	sddown;			/* Number of subdisks that are down. */
341 	int	flags;
342 #define	GV_PLEX_ADDED		0x01	/* Added to an existing volume. */
343 #define	GV_PLEX_SYNCING		0x02	/* Plex is syncing from another plex. */
344 #define	GV_PLEX_NEWBORN		0x20	/* The plex was just created. */
345 #define GV_PLEX_REBUILDING	0x40	/* The plex is rebuilding. */
346 #define GV_PLEX_GROWING		0x80	/* The plex is growing. */
347 
348 	off_t	synced;			/* Count of synced bytes. */
349 
350 	TAILQ_HEAD(,gv_raid5_packet)	packets; /* RAID5 sub-requests. */
351 
352 	LIST_HEAD(,gv_sd)   subdisks;	/* List of attached subdisks. */
353 	LIST_ENTRY(gv_plex) in_volume;	/* Plex list of associated volume. */
354 	LIST_ENTRY(gv_plex) plex;	/* Entry in the vinum config. */
355 
356 #ifdef	_KERNEL
357 	struct bio_queue_head	*bqueue;	/* BIO queue. */
358 	struct bio_queue_head	*wqueue;	/* Waiting BIO queue. */
359 	struct bio_queue_head	*rqueue;	/* Rebuild waiting BIO queue. */
360 #else
361 	char			*bpad, *wpad, *rpad; /* Padding for userland. */
362 #endif
363 
364 	struct gv_softc	*vinumconf;	/* Pointer to the vinum config. */
365 };
366 
367 /* softc for a volume. */
368 struct gv_volume {
369 	char	name[GV_MAXVOLNAME];	/* The name of the volume. */
370 	off_t	size;			/* The size of the volume. */
371 	int	plexcount;		/* Number of plexes. */
372 	int	state;			/* The state of the volume. */
373 #define	GV_VOL_DOWN	0
374 #define	GV_VOL_UP	1
375 
376 	int	flags;
377 #define GV_VOL_NEWBORN		0x08	/* The volume was just created. */
378 
379 	LIST_HEAD(,gv_plex)	plexes;		/* List of attached plexes. */
380 	LIST_ENTRY(gv_volume)	volume;		/* Entry in vinum config. */
381 
382 	struct g_provider	*provider;	/* Provider of this volume. */
383 
384 #ifdef	_KERNEL
385 	struct bio_queue_head	*wqueue;	/* BIO delayed request queue. */
386 #else
387 	char			*wpad; /* Padding for userland. */
388 #endif
389 
390 	struct gv_plex	*last_read_plex;
391 	struct gv_softc	*vinumconf;	/* Pointer to the vinum config. */
392 };
393 
394 #endif /* !_GEOM_VINUM_VAR_H */
395