Home | History | Annotate | Download | only in diskomizer
      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 /*
     23  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
     24  * Use is subject to license terms.
     25  */
     26 
     27 #pragma ident	"@(#)bufs.h	1.31	09/05/26 SMI"
     28 
     29 #ifndef _DISKOMIZER_BUFS_H
     30 #define	_DISKOMIZER_BUFS_H
     31 
     32 #ifdef	__cplusplus
     33 extern "C" {
     34 #endif
     35 
     36 typedef struct {
     37 	uint_t BUF_EXECUTABLE : 1;
     38 	uint_t BUF_BAD_HDR : 1;
     39 	uint_t BUF_BAD_CHKSUM : 1;
     40 	uint_t BUF_READ_ONLY : 1;
     41 	uint_t BUF_READY : 1; /* If not zero then it needs initalizing */
     42 	/* Write sequence number. The same size as in the blks structure */
     43 	uint_t sequence: SEQUENCE_BITS;
     44 	/*
     45 	 * the spare bits we have, the 5 is the count of those sinle bits
     46 	 * above
     47 	 */
     48 	uint_t padding: (WORD_BIT - 5) - SEQUENCE_BITS;
     49 } buf_data_type;
     50 
     51 typedef int64_t time64_t;
     52 /*
     53  * Size of the string in the buffer header that is used to store
     54  * the serial number and hardware provider information.
     55  */
     56 #define	SIZEOF_SERIAL_AND_PROVIDER 32
     57 
     58 /*
     59  * There are 2 buffer headers.  Every time a buffer gets used it should
     60  * change it's header type. This prevents the same bytes being written
     61  * to the same part of a disk over and over again.
     62  *
     63  * There is also an attempt to get the constant parts of this header in
     64  * one header where the volatile parts are in the other.  This means that
     65  * if 2 different header types are XORd together as part of a RAID 5
     66  * volume you can more easily decode what the 2 blocks were. Seems mad
     67  * but has been proven to be useful when hardware RAID engines go mad.
     68  *
     69  * If you change this then be sure to change the PRINT_A_HDR and PRINT_B_HDR
     70  * macros in bufs.c
     71  */
     72 struct bufhdr_a {
     73 	char serial_and_provider[SIZEOF_SERIAL_AND_PROVIDER];	/* +32 */
     74 	struct device_id devid;					/* +8 */
     75 	uint32_t hdrchksum;					/* +4 */
     76 	buf_data_type	type;					/* +4 */
     77 	check_t chksum;						/* +8 */
     78 	pid_t did;						/* +4 */
     79 	uint32_t len;						/* +4 */
     80 	ullong_t off;						/* +8 */
     81 	time64_t time;						/* +8 */
     82 };
     83 struct bufhdr_b {
     84 	ullong_t off;						/* +8 */
     85 	time64_t time;						/* +8 */
     86 	uint32_t len;						/* +4 */
     87 	pid_t did;						/* +4 */
     88 	struct device_id devid;					/* +8 */
     89 	uint32_t hdrchksum;					/* +4 */
     90 	buf_data_type	type;					/* +4 */
     91 	check_t chksum;						/* +8 */
     92 	char serial_and_provider[SIZEOF_SERIAL_AND_PROVIDER];	/* +32 */
     93 };
     94 struct shadow_hdr {
     95 	buf_data_type type;
     96 	check_t chksums[1];
     97 };
     98 #define	BUF_TYPE_A 0xAAAAAAAAAAAAAAAAULL
     99 #define	BUF_TYPE_B 0x5555555555555555ULL
    100 struct bufhdr {
    101 	uint64_t start;
    102 	union {
    103 		struct bufhdr_a a;
    104 		struct bufhdr_b b;
    105 		/*
    106 		 * This pad forces sizeof bufhdr.ab to be everything that is
    107 		 * bettween start and end. So that ZERO_OBJ(bufhdr.ab)
    108 		 * clears everything.
    109 		 */
    110 		uint64_t pad[(1 ? 0 : sizeof (struct bufhdr_a) %
    111 			sizeof (uint64_t)) +
    112 			sizeof (struct bufhdr_a) / sizeof (uint64_t)];
    113 	} ab;
    114 	uint64_t end;
    115 };
    116 #define	SIZEOF_BUFHDR sizeof (struct bufhdr)
    117 #define	SIZEOF_BUF 512
    118 union data {
    119 	uchar_t c[(SIZEOF_BUF - SIZEOF_BUFHDR)/sizeof (uchar_t)];
    120 	uint32_t i[(SIZEOF_BUF - SIZEOF_BUFHDR)/sizeof (uint32_t)];
    121 	uint64_t l[(SIZEOF_BUF - SIZEOF_BUFHDR)/sizeof (uint64_t)];
    122 };
    123 struct buf {
    124 	struct bufhdr hdr;
    125 	union data data;
    126 };
    127 extern void init_all_write_bufs(struct aio_str *aio, struct device *devices);
    128 extern struct bufhdr_a conv_bufhdr(struct bufhdr *in);
    129 extern void toggle_bufhdr(uchar_t *buf);
    130 extern struct bufhdr get_bufhdr(uchar_t *buf);
    131 extern struct bufhdr_a get_bufhdr_a(uchar_t *buf);
    132 extern ushort16_t get_bufhdr_hdrchksum(uchar_t *buf);
    133 extern ushort16_t set_hdrchksum(struct bufhdr *hdr);
    134 extern ushort16_t set_buf_hdrchksum(uchar_t *buf);
    135 extern void set_bufhdr_dev(uchar_t *buf, struct device_id devid);
    136 extern void set_bufhdr_off(uchar_t *buf, ullong_t off);
    137 extern ushort16_t check_hdr(struct bufhdr *hdr, ushort16_t hdrchksum);
    138 extern ushort16_t check_bufhdr(uchar_t *buf, ushort16_t hdrchksum);
    139 extern check_t check_aiobuf(struct aio_str *aiop);
    140 extern check_t check_buf(uchar_t *buf, int len, struct error *error);
    141 extern uchar_t *get_read_buf(void);
    142 extern void return_read_buf(uchar_t *buf);
    143 extern uchar_t *get_write_buf(void);
    144 extern int get_write_buf_id(uchar_t *b);
    145 extern void return_write_buf(uchar_t *buf);
    146 extern struct shadow_hdr const * get_shadow_hdr(uchar_t *buf);
    147 extern int is_read_io(struct aio_str *aiop);
    148 extern int is_write_io(struct aio_str *aiop);
    149 extern void decode_header(FILE *out, uchar_t *good, uchar_t *bad);
    150 extern void print_bufhdr_offsets(FILE *out);
    151 extern void init_read_bufs(struct device *devices);
    152 extern uchar_t *get_buf_data(uchar_t *buf);
    153 extern check_t check_bufbody(uchar_t *buf, ulong_t size);
    154 extern char is_executable(uchar_t *buf);
    155 extern void set_bufhdr_all(uchar_t *buf, check_t chksum, uint32_t len,
    156 	struct device_id devid, ullong_t off, buf_data_type type,
    157 	char sequence, time_t time);
    158 extern void set_bufhdr_chksum(uchar_t *buf, ulong_t chksum);
    159 extern void set_bufhdr_len(uchar_t *buf, uint32_t len);
    160 extern void set_bufhdr_type(uchar_t *buf, buf_data_type type);
    161 extern void init_block_str(struct device *device);
    162 extern void init_buf(uchar_t *buf);
    163 extern void save_data_bufs(void);
    164 extern void (*protect_buf)(uchar_t *b);
    165 extern void (*unprotect_buf)(uchar_t *b);
    166 extern time_t get_buf_time(uchar_t *b);
    167 extern pid_t get_buf_did(uchar_t *b);
    168 extern void set_serial_and_provider(void);
    169 extern void get_serial_and_provider(char *buf, int len);
    170 extern const char *get_buf_serial_and_provider(const uchar_t *b);
    171 extern int cmp_serial_and_provider(const char *buf);
    172 extern void print_serial_and_provider(FILE *out);
    173 
    174 #ifdef	__cplusplus
    175 }
    176 #endif
    177 
    178 #endif /* _DISKOMIZER_BUFS_H */
    179