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