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  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  */
25 
26 #ifndef _GMEM_STATE_H
27 #define	_GMEM_STATE_H
28 
29 /*
30  * Case management and saved state restoration
31  */
32 
33 #include <gmem_util.h>
34 
35 #include <fm/fmd_api.h>
36 
37 #ifdef __cplusplus
38 extern "C" {
39 #endif
40 
41 /*
42  * Our maximum persistent buffer name length, used to allocate fixed-size
43  * arrays for name storage.
44  */
45 /*
46  * The current name DIMM_+serial number
47  */
48 #define	GMEM_BUFNMLEN		48
49 
50 /* gmem_evdisp_t, gmem_evdisp_stat_t, and gmem_evdisp_names must be in sync */
51 typedef enum gmem_evdisp {
52 	GMEM_EVD_OK,
53 	GMEM_EVD_BAD,
54 	GMEM_EVD_UNUSED,
55 	GMEM_EVD_REDUND
56 } gmem_evdisp_t;
57 
58 /*
59  * Each handled ereport type has four statistics, designed to indicate the
60  * eventual disposition of the ereport.
61  */
62 typedef struct gmem_evdisp_stat {
63 	fmd_stat_t evs_ok;		/* # of erpts processed successfully */
64 	fmd_stat_t evs_bad;		/* # of malformed ereports */
65 	fmd_stat_t evs_unused;		/* # of erpts unusable or not needed */
66 	fmd_stat_t evs_redund;		/* # of erpts already explained */
67 } gmem_evdisp_stat_t;
68 
69 /* Must be in sync with gmem_case_restorers */
70 typedef enum gmem_nodetype {
71 	GMEM_NT_DIMM = 1,
72 	GMEM_NT_PAGE
73 } gmem_nodetype_t;
74 
75 /*
76  * Must be in sync with gmem_case_closers.  Additional types must be
77  * appended to this enum otherwise interpretation of existing logs
78  * and checkpoints will be confused.
79  */
80 typedef enum gmem_ptrsubtype {
81 	GMEM_PTR_DIMM_CASE = 1,
82 	GMEM_PTR_PAGE_CASE
83 } gmem_ptrsubtype_t;
84 
85 /*
86  * There are three types of general-purpose buffers, used to track DIMMs,
87  * and pages.  Created on-demand as ereports arrive, one buffer is created for
88  * each thing tracked.  The general-purpose buffers are used to track common
89  * state, and are used to support case-specific buffers.  Each open case has
90  * a case-specific pointer buffer, used to aid in the rediscovery of the
91  * associated general-purpose buffer.  When restoration begins, we iterate
92  * through each of the open cases, restoring the case-specific pointer buffers
93  * for each.  The pointer buffers are then used to restore the general-purpose
94  * buffers.
95  */
96 
97 typedef	struct gmem_case_ptr {
98 	gmem_nodetype_t ptr_type;	/* The type of associated G.P. buffer */
99 	gmem_ptrsubtype_t ptr_subtype;	/* The case within the G.P. buffer */
100 	char ptr_name[GMEM_BUFNMLEN];	/* G.P. buffer name */
101 } gmem_case_ptr_t;
102 
103 /*
104  * All general-purpose buffers begin with a common header.  This header contains
105  * identification information used in the construction of new cases.
106  *
107  * Note that versioned structs depend upon the size of
108  * this struct remaining fixed.
109  */
110 typedef struct gmem_header {
111 	gmem_list_t hdr_list;		/* List of G.P. structs of this type */
112 	gmem_nodetype_t hdr_nodetype;	/* Type of this G.P. struct */
113 	char hdr_bufname[GMEM_BUFNMLEN]; /* G.P. buffer name */
114 } gmem_header_t;
115 
116 /*
117  * Per-case-subtype case closing routines.  Stored in per-case state when the
118  * case is generated, and regenerated from saved state upon restore.
119  */
120 typedef void gmem_case_closer_f(fmd_hdl_t *, void *);
121 typedef void *gmem_case_restorer_f(fmd_hdl_t *, fmd_case_t *,
122     gmem_case_ptr_t *);
123 
124 typedef struct gmem_case_closer {
125 	gmem_case_closer_f *cl_func;
126 	void *cl_arg;
127 } gmem_case_closer_t;
128 
129 typedef struct gmem_case {
130 	fmd_case_t *cc_cp;
131 	char *cc_serdnm;
132 } gmem_case_t;
133 
134 /*
135  * Utility functions which ease the management of cases.
136  */
137 extern fmd_case_t *gmem_case_create(fmd_hdl_t *, gmem_header_t *,
138     gmem_ptrsubtype_t, const char **);
139 extern void gmem_case_redirect(fmd_hdl_t *, fmd_case_t *, gmem_ptrsubtype_t);
140 extern void gmem_case_fini(fmd_hdl_t *, fmd_case_t *, int);
141 extern void gmem_case_restore(fmd_hdl_t *, gmem_case_t *, fmd_case_t *, char *);
142 
143 extern int gmem_state_restore(fmd_hdl_t *);
144 
145 #ifdef __cplusplus
146 }
147 #endif
148 
149 #endif /* _GMEM_STATE_H */
150