1139778Simp/*-
2190507Slulf * Copyright (c) 2004, 2007 Lukas Ertl
3130389Sle * Copyright (c) 1997, 1998, 1999
4130389Sle *      Nan Yang Computer Services Limited.  All rights reserved.
5130389Sle *
6130389Sle * Parts copyright (c) 1997, 1998 Cybernet Corporation, NetMAX project.
7130389Sle * Parts written by Greg Lehey.
8130389Sle *
9130389Sle *  This software is distributed under the so-called ``Berkeley
10130389Sle *  License'':                                                                   *
11130389Sle * Redistribution and use in source and binary forms, with or without
12130389Sle * modification, are permitted provided that the following conditions
13130389Sle * are met:
14130389Sle * 1. Redistributions of source code must retain the above copyright
15130389Sle *    notice, this list of conditions and the following disclaimer.
16130389Sle * 2. Redistributions in binary form must reproduce the above copyright
17130389Sle *    notice, this list of conditions and the following disclaimer in the
18130389Sle *    documentation and/or other materials provided with the distribution.
19130389Sle * 3. All advertising materials mentioning features or use of this software
20130389Sle *    must display the following acknowledgement:
21130389Sle *      This product includes software developed by Nan Yang Computer
22130389Sle *      Services Limited.
23130389Sle * 4. Neither the name of the Company nor the names of its contributors
24130389Sle *    may be used to endorse or promote products derived from this software
25130389Sle *    without specific prior written permission.
26130389Sle *
27130389Sle * This software is provided ``as is'', and any express or implied
28130389Sle * warranties, including, but not limited to, the implied warranties of
29130389Sle * merchantability and fitness for a particular purpose are disclaimed.
30130389Sle * In no event shall the company or contributors be liable for any               * direct, indirect, incidental, special, exemplary, or consequential
31130389Sle * damages (including, but not limited to, procurement of substitute
32130389Sle * goods or services; loss of use, data, or profits; or business
33130389Sle * interruption) however caused and on any theory of liability, whether
34130389Sle * in contract, strict liability, or tort (including negligence or
35130389Sle * otherwise) arising in any way out of the use of this software, even if
36130389Sle * advised of the possibility of such damage.
37130389Sle *
38130389Sle * $FreeBSD$
39130389Sle */
40130389Sle
41130389Sle#ifndef	_GEOM_VINUM_VAR_H_
42130389Sle#define	_GEOM_VINUM_VAR_H_
43130389Sle
44130389Sle/*
45130389Sle * Slice header
46130389Sle *
47130389Sle * Vinum drives start with this structure:
48130389Sle *
49130389Sle *\                                            Sector
50130389Sle * |--------------------------------------|
51130389Sle * |   PDP-11 memorial boot block         |      0
52130389Sle * |--------------------------------------|
53130389Sle * |   Disk label, maybe                  |      1
54130389Sle * |--------------------------------------|
55130389Sle * |   Slice definition  (vinum_hdr)      |      8
56130389Sle * |--------------------------------------|
57130389Sle * |                                      |
58130389Sle * |   Configuration info, first copy     |      9
59130389Sle * |                                      |
60130389Sle * |--------------------------------------|
61130389Sle * |                                      |
62130389Sle * |   Configuration info, second copy    |      9 + size of config
63130389Sle * |                                      |
64130389Sle * |--------------------------------------|
65130389Sle */
66130389Sle
67130389Sle/* Sizes and offsets of our information. */
68130389Sle#define	GV_HDR_OFFSET	4096	/* Offset of vinum header. */
69130389Sle#define	GV_HDR_LEN	512	/* Size of vinum header. */
70130389Sle#define	GV_CFG_OFFSET	4608	/* Offset of first config copy. */
71130389Sle#define	GV_CFG_LEN	65536	/* Size of config copy. */
72130389Sle
73130389Sle/* This is where the actual data starts. */
74130389Sle#define	GV_DATA_START	(GV_CFG_LEN * 2 + GV_CFG_OFFSET)
75130389Sle/* #define GV_DATA_START	(GV_CFG_LEN * 2 + GV_HDR_LEN) */
76130389Sle
77130389Sle#define	GV_MAXDRIVENAME	32	/* Maximum length of a device name. */
78130389Sle#define	GV_MAXSDNAME	64	/* Maximum length of a subdisk name. */
79130389Sle#define	GV_MAXPLEXNAME	64	/* Maximum length of a plex name. */
80130389Sle#define	GV_MAXVOLNAME	64	/* Maximum length of a volume name. */
81130389Sle
82130389Sle/* Command line flags. */
83130389Sle#define	GV_FLAG_R	0x01
84130389Sle#define	GV_FLAG_S	0x02
85130389Sle#define	GV_FLAG_V	0x04
86130389Sle#define	GV_FLAG_VV	0x08
87130389Sle#define	GV_FLAG_F	0x10
88130389Sle
89130389Sle/* Object types. */
90130389Sle#define	GV_TYPE_VOL	1
91130389Sle#define	GV_TYPE_PLEX	2
92130389Sle#define	GV_TYPE_SD	3
93130389Sle#define	GV_TYPE_DRIVE	4
94130389Sle
95130389Sle/* State changing flags. */
96130389Sle#define	GV_SETSTATE_FORCE	0x1
97130389Sle#define	GV_SETSTATE_CONFIG	0x2
98130389Sle
99130389Sle/* Subdisk state bitmaps for plexes. */
100130389Sle#define	GV_SD_DOWNSTATE		0x01	/* Subdisk is down. */
101130389Sle#define	GV_SD_STALESTATE	0x02	/* Subdisk is stale. */
102130389Sle#define	GV_SD_INITSTATE		0x04	/* Subdisk is initializing. */
103130389Sle#define	GV_SD_UPSTATE		0x08	/* Subdisk is up. */
104130389Sle
105130389Sle/* Synchronization/initialization request sizes. */
106130389Sle#define	GV_MIN_SYNCSIZE		512
107130389Sle#define	GV_MAX_SYNCSIZE		MAXPHYS
108130389Sle#define	GV_DFLT_SYNCSIZE	65536
109130389Sle
110135173Sle/* Flags for BIOs, as they are processed within vinum. */
111191856Slulf#define	GV_BIO_GROW	0x01
112135173Sle#define	GV_BIO_MALLOC	0x02
113135173Sle#define	GV_BIO_ONHOLD	0x04
114135426Sle#define	GV_BIO_SYNCREQ	0x08
115190507Slulf#define	GV_BIO_INIT	0x10
116135966Sle#define	GV_BIO_REBUILD	0x20
117138110Sle#define	GV_BIO_CHECK	0x40
118138110Sle#define	GV_BIO_PARITY	0x80
119190507Slulf#define GV_BIO_INTERNAL \
120191856Slulf    (GV_BIO_SYNCREQ | GV_BIO_INIT | GV_BIO_REBUILD | GV_BIO_CHECK | GV_BIO_GROW)
121135173Sle
122190507Slulf/* Error codes to be used within gvinum. */
123190507Slulf#define	GV_ERR_SETSTATE		(-1)	/* Error setting state. */
124190507Slulf#define	GV_ERR_BADSIZE		(-2)	/* Object has wrong size. */
125190507Slulf#define	GV_ERR_INVTYPE		(-3)    /* Invalid object type. */
126190507Slulf#define	GV_ERR_CREATE		(-4)	/* Error creating gvinum object. */
127190507Slulf#define	GV_ERR_ISBUSY		(-5)	/* Object is busy. */
128190507Slulf#define	GV_ERR_ISATTACHED	(-6)	/* Object is attached to another. */
129190507Slulf#define	GV_ERR_INVFLAG		(-7)	/* Invalid flag passed. */
130190507Slulf#define	GV_ERR_INVSTATE		(-8)	/* Invalid state. */
131190507Slulf#define	GV_ERR_NOTFOUND		(-9)	/* Object not found. */
132190507Slulf#define	GV_ERR_NAMETAKEN	(-10)	/* Object name is taken. */
133190507Slulf#define	GV_ERR_NOSPACE		(-11)	/* No space left on drive/subdisk. */
134190507Slulf#define	GV_ERR_BADOFFSET	(-12)	/* Invalid offset specified. */
135190507Slulf#define	GV_ERR_INVNAME		(-13)	/* Invalid object name. */
136190507Slulf#define	GV_ERR_PLEXORG		(-14)	/* Invalid plex organization. */
137190507Slulf
138130389Sle/*
139130389Sle * hostname is 256 bytes long, but we don't need to shlep multiple copies in
140130389Sle * vinum.  We use the host name just to identify this system, and 32 bytes
141130389Sle * should be ample for that purpose.
142130389Sle */
143130389Sle
144130389Sle#define	GV_HOSTNAME_LEN	32
145130389Slestruct gv_label {
146130389Sle	char	sysname[GV_HOSTNAME_LEN]; /* System name at creation time. */
147130389Sle	char	name[GV_MAXDRIVENAME];	/* Our name of the drive. */
148130389Sle	struct timeval	date_of_birth;	/* The time it was created ... */
149130389Sle	struct timeval	last_update;	/* ... and the time of last update. */
150130389Sle	off_t		drive_size;	/* Total size incl. headers. */
151130389Sle};
152130389Sle
153130389Sle/* The 'header' of each valid vinum drive. */
154130389Slestruct gv_hdr {
155130389Sle	uint64_t	magic;
156183514Slulf#define GV_OLD_MAGIC	0x494E2056494E4F00LL
157183514Slulf#define GV_OLD_NOMAGIC	0x4E4F2056494E4F00LL
158183514Slulf#define GV_MAGIC	0x56494E554D2D3100LL
159183514Slulf#define GV_NOMAGIC	0x56494E554D2D2D00LL
160130389Sle
161183514Slulf	uint64_t	config_length;
162130389Sle	struct gv_label	label;
163130389Sle};
164130389Sle
165130389Sle/* A single freelist entry of a drive. */
166130389Slestruct gv_freelist {
167130389Sle	off_t size;				/* Size of this free slot. */
168130389Sle	off_t offset;				/* Offset on the drive. */
169130389Sle	LIST_ENTRY(gv_freelist) freelist;
170130389Sle};
171130389Sle
172135173Sle/*
173135173Sle * Since we share structures between userland and kernel, we need this helper
174135173Sle * struct instead of struct bio_queue_head and friends.  Maybe I find a proper
175135173Sle * solution some day.
176135173Sle */
177135173Slestruct gv_bioq {
178135173Sle	struct bio *bp;
179135173Sle	TAILQ_ENTRY(gv_bioq)	queue;
180135173Sle};
181135173Sle
182190507Slulf#define	GV_EVENT_DRIVE_TASTED		1
183190507Slulf#define	GV_EVENT_DRIVE_LOST		2
184190507Slulf#define	GV_EVENT_THREAD_EXIT		3
185190507Slulf#define	GV_EVENT_CREATE_DRIVE		4
186190507Slulf#define	GV_EVENT_CREATE_VOLUME		5
187190507Slulf#define	GV_EVENT_CREATE_PLEX		6
188190507Slulf#define	GV_EVENT_CREATE_SD		7
189190507Slulf#define	GV_EVENT_SAVE_CONFIG		8
190190507Slulf#define	GV_EVENT_RM_VOLUME		9
191190507Slulf#define	GV_EVENT_RM_PLEX		10
192190507Slulf#define	GV_EVENT_RM_SD			11
193190507Slulf#define	GV_EVENT_RM_DRIVE		12
194190507Slulf#define	GV_EVENT_SET_SD_STATE		13
195190507Slulf#define	GV_EVENT_SET_DRIVE_STATE	14
196190507Slulf#define	GV_EVENT_SET_VOL_STATE		15
197190507Slulf#define	GV_EVENT_SET_PLEX_STATE		16
198190507Slulf#define	GV_EVENT_RESET_CONFIG		17
199190507Slulf#define	GV_EVENT_PARITY_REBUILD		18
200190507Slulf#define	GV_EVENT_PARITY_CHECK		19
201190507Slulf#define	GV_EVENT_START_PLEX		20
202190507Slulf#define	GV_EVENT_START_VOLUME		21
203190507Slulf#define	GV_EVENT_ATTACH_PLEX		22
204190507Slulf#define	GV_EVENT_ATTACH_SD		23
205190507Slulf#define	GV_EVENT_DETACH_PLEX		24
206190507Slulf#define	GV_EVENT_DETACH_SD		25
207190507Slulf#define	GV_EVENT_RENAME_VOL		26
208190507Slulf#define	GV_EVENT_RENAME_PLEX		27
209190507Slulf#define	GV_EVENT_RENAME_SD		28
210190507Slulf#define	GV_EVENT_RENAME_DRIVE		29
211190507Slulf#define	GV_EVENT_MOVE_SD		30
212190507Slulf#define	GV_EVENT_SETUP_OBJECTS		31
213190507Slulf
214190507Slulf#ifdef _KERNEL
215190507Slulfstruct gv_event {
216190507Slulf	int	type;
217190507Slulf	void	*arg1;
218190507Slulf	void	*arg2;
219190507Slulf	intmax_t arg3;
220190507Slulf	intmax_t arg4;
221190507Slulf	TAILQ_ENTRY(gv_event)	events;
222190507Slulf};
223190507Slulf
224130389Sle/* This struct contains the main vinum config. */
225130389Slestruct gv_softc {
226130389Sle	/* Linked lists of all objects in our setup. */
227130389Sle	LIST_HEAD(,gv_drive)	drives;		/* All drives. */
228130389Sle	LIST_HEAD(,gv_plex)	plexes;		/* All plexes. */
229130389Sle	LIST_HEAD(,gv_sd)	subdisks;	/* All subdisks. */
230130389Sle	LIST_HEAD(,gv_volume)	volumes;	/* All volumes. */
231130389Sle
232190507Slulf	TAILQ_HEAD(,gv_event)	equeue;		/* Event queue. */
233191849Slulf	struct mtx		equeue_mtx;	/* Event queue lock. */
234191849Slulf	struct mtx		bqueue_mtx;	/* BIO queue lock. */
235190507Slulf	struct mtx		config_mtx;	/* Configuration lock. */
236191856Slulf	struct bio_queue_head	*bqueue_down;	/* BIO queue incoming
237191856Slulf						   requests. */
238191856Slulf	struct bio_queue_head	*bqueue_up;	/* BIO queue for completed
239191856Slulf						   requests. */
240130389Sle	struct g_geom		*geom;		/* Pointer to our VINUM geom. */
241207878Sjh	struct proc		*worker;	/* Worker process. */
242130389Sle};
243191787Slulf#endif
244130389Sle
245130389Sle/* softc for a drive. */
246130389Slestruct gv_drive {
247130389Sle	char	name[GV_MAXDRIVENAME];		/* The name of this drive. */
248130389Sle	char	device[GV_MAXDRIVENAME];	/* Associated device. */
249130389Sle	int	state;				/* The state of this drive. */
250130389Sle#define	GV_DRIVE_DOWN	0
251130389Sle#define	GV_DRIVE_UP	1
252130389Sle
253130389Sle	off_t	size;				/* Size of this drive. */
254130389Sle	off_t	avail;				/* Available space. */
255130389Sle	int	sdcount;			/* Number of subdisks. */
256130389Sle
257135173Sle	int	flags;
258190507Slulf#define	GV_DRIVE_REFERENCED	0x01	/* The drive isn't really existing,
259190507Slulf					   but was referenced by a subdisk
260190507Slulf					   during taste. */
261135173Sle
262190507Slulf	struct gv_hdr	*hdr;		/* The drive header. */
263130389Sle
264190507Slulf	struct g_consumer *consumer;	/* Consumer attached to this drive. */
265190507Slulf
266130389Sle	int freelist_entries;			/* Count of freelist entries. */
267130389Sle	LIST_HEAD(,gv_freelist)	freelist;	/* List of freelist entries. */
268130389Sle	LIST_HEAD(,gv_sd)	subdisks;	/* Subdisks on this drive. */
269130389Sle	LIST_ENTRY(gv_drive)	drive;		/* Entry in the vinum config. */
270130389Sle
271130389Sle	struct gv_softc	*vinumconf;		/* Pointer to the vinum conf. */
272130389Sle};
273130389Sle
274130389Sle/* softc for a subdisk. */
275130389Slestruct gv_sd {
276130389Sle	char	name[GV_MAXSDNAME];	/* The name of this subdisk. */
277130389Sle	off_t	size;			/* The size of this subdisk. */
278130389Sle	off_t	drive_offset;		/* Offset in the underlying drive. */
279130389Sle	off_t	plex_offset;		/* Offset in the associated plex. */
280130389Sle	int	state;			/* The state of this subdisk. */
281130389Sle#define	GV_SD_DOWN		0
282130389Sle#define	GV_SD_STALE		1
283130389Sle#define	GV_SD_INITIALIZING	2
284130389Sle#define	GV_SD_REVIVING		3
285130389Sle#define	GV_SD_UP		4
286130389Sle
287130389Sle	off_t	initialized;		/* Count of initialized bytes. */
288130389Sle
289130389Sle	int	init_size;		/* Initialization read/write size. */
290130389Sle	int	init_error;		/* Flag error on initialization. */
291130389Sle
292130389Sle	int	flags;
293190507Slulf#define	GV_SD_NEWBORN		0x01	/* Subdisk is created by user. */
294190507Slulf#define	GV_SD_TASTED		0x02	/* Subdisk is created during taste. */
295190507Slulf#define	GV_SD_CANGOUP		0x04	/* Subdisk can go up immediately. */
296190507Slulf#define GV_SD_GROW		0x08	/* Subdisk is added to striped plex. */
297130389Sle
298130389Sle	char drive[GV_MAXDRIVENAME];	/* Name of underlying drive. */
299130389Sle	char plex[GV_MAXPLEXNAME];	/* Name of associated plex. */
300130389Sle
301130389Sle	struct gv_drive	*drive_sc;	/* Pointer to underlying drive. */
302130389Sle	struct gv_plex	*plex_sc;	/* Pointer to associated plex. */
303130389Sle
304130389Sle	LIST_ENTRY(gv_sd) from_drive;	/* Subdisk list of underlying drive. */
305130389Sle	LIST_ENTRY(gv_sd) in_plex;	/* Subdisk list of associated plex. */
306130389Sle	LIST_ENTRY(gv_sd) sd;		/* Entry in the vinum config. */
307130389Sle
308130389Sle	struct gv_softc	*vinumconf;	/* Pointer to the vinum config. */
309130389Sle};
310130389Sle
311130389Sle/* softc for a plex. */
312130389Slestruct gv_plex {
313130389Sle	char	name[GV_MAXPLEXNAME];	/* The name of the plex. */
314130389Sle	off_t	size;			/* The size of the plex. */
315130389Sle	int	state;			/* The plex state. */
316130389Sle#define	GV_PLEX_DOWN		0
317130389Sle#define	GV_PLEX_INITIALIZING	1
318130389Sle#define	GV_PLEX_DEGRADED	2
319190507Slulf#define GV_PLEX_GROWABLE	3
320190507Slulf#define	GV_PLEX_UP		4
321130389Sle
322130389Sle	int	org;			/* The plex organisation. */
323130389Sle#define	GV_PLEX_DISORG	0
324130389Sle#define	GV_PLEX_CONCAT	1
325130389Sle#define	GV_PLEX_STRIPED	2
326130389Sle#define	GV_PLEX_RAID5	4
327130389Sle
328130389Sle	int	stripesize;		/* The stripe size of the plex. */
329130389Sle
330130389Sle	char	volume[GV_MAXVOLNAME];	/* Name of associated volume. */
331130389Sle	struct gv_volume *vol_sc;	/* Pointer to associated volume. */
332130389Sle
333190507Slulf	int	sddetached;		/* Number of detached subdisks. */
334130389Sle	int	sdcount;		/* Number of subdisks in this plex. */
335130389Sle	int	sddown;			/* Number of subdisks that are down. */
336130389Sle	int	flags;
337130389Sle#define	GV_PLEX_ADDED		0x01	/* Added to an existing volume. */
338130389Sle#define	GV_PLEX_SYNCING		0x02	/* Plex is syncing from another plex. */
339130389Sle#define	GV_PLEX_NEWBORN		0x20	/* The plex was just created. */
340190507Slulf#define GV_PLEX_REBUILDING	0x40	/* The plex is rebuilding. */
341190507Slulf#define GV_PLEX_GROWING		0x80	/* The plex is growing. */
342130389Sle
343130389Sle	off_t	synced;			/* Count of synced bytes. */
344130389Sle
345135426Sle	TAILQ_HEAD(,gv_raid5_packet)	packets; /* RAID5 sub-requests. */
346130389Sle
347130389Sle	LIST_HEAD(,gv_sd)   subdisks;	/* List of attached subdisks. */
348130389Sle	LIST_ENTRY(gv_plex) in_volume;	/* Plex list of associated volume. */
349130389Sle	LIST_ENTRY(gv_plex) plex;	/* Entry in the vinum config. */
350130389Sle
351190507Slulf#ifdef	_KERNEL
352190507Slulf	struct bio_queue_head	*bqueue;	/* BIO queue. */
353190507Slulf	struct bio_queue_head	*wqueue;	/* Waiting BIO queue. */
354190507Slulf	struct bio_queue_head	*rqueue;	/* Rebuild waiting BIO queue. */
355190507Slulf#else
356190507Slulf	char			*bpad, *wpad, *rpad; /* Padding for userland. */
357190507Slulf#endif
358130389Sle
359130389Sle	struct gv_softc	*vinumconf;	/* Pointer to the vinum config. */
360130389Sle};
361130389Sle
362130389Sle/* softc for a volume. */
363130389Slestruct gv_volume {
364130389Sle	char	name[GV_MAXVOLNAME];	/* The name of the volume. */
365130389Sle	off_t	size;			/* The size of the volume. */
366130389Sle	int	plexcount;		/* Number of plexes. */
367130389Sle	int	state;			/* The state of the volume. */
368130389Sle#define	GV_VOL_DOWN	0
369130389Sle#define	GV_VOL_UP	1
370130389Sle
371135426Sle	int	flags;
372190507Slulf#define GV_VOL_NEWBORN		0x08	/* The volume was just created. */
373135426Sle
374190507Slulf	LIST_HEAD(,gv_plex)	plexes;		/* List of attached plexes. */
375190507Slulf	LIST_ENTRY(gv_volume)	volume;		/* Entry in vinum config. */
376190507Slulf
377190507Slulf	struct g_provider	*provider;	/* Provider of this volume. */
378190507Slulf
379190507Slulf#ifdef	_KERNEL
380190507Slulf	struct bio_queue_head	*wqueue;	/* BIO delayed request queue. */
381154075Sle#else
382190507Slulf	char			*wpad; /* Padding for userland. */
383154075Sle#endif
384135426Sle
385148048Sle	struct gv_plex	*last_read_plex;
386130389Sle	struct gv_softc	*vinumconf;	/* Pointer to the vinum config. */
387130389Sle};
388130389Sle
389130389Sle#endif /* !_GEOM_VINUM_VAR_H */
390