swde_case.c revision f6e214c7418f43af38bd8c3a557e3d0a1d311cfa
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
*/
#include <stddef.h>
#include <strings.h>
/*
* We maintain a single list of all active cases across all
* subsidary diagnosis "modules". We also offer some serialization
* services to them.
*
* To open a new case a subsidiary engine should use swde_case_open
* indicating the subsidiary id (from which we lookup the enum sw_casetype)
* and, optionally, a pointer to a structure for serialization and its size.
*
* For each case opened with swde_case_open we maintain an swde_case_t
* structure in-core. Embedded in this is the swde_case_data_t with
* information we need to keep track of and manage this case - it's
* case type, buffer name used for the sub-de-private data (if any)
* and the size of the sub-de-private structure. It is this
* embedded structure which is serialized as the "casedata" buffer,
* while the subsidiary-private structure is serialized into another buffer
* "casedata_<casetype-in-hex>".
*
* The subsidiary-private data structure, if any, is required to start
* with a uint32_t recording the data structure version. This
* version is also specified as an argument to swde_case_open, and
* we note it in the "casedata" buffer we write out and require
* a match on restore.
*
* When we unserialize we restore our management structure as well as
* the sub-de-private structure.
*
* Here's how serialization works:
*
* In swde_case_open we create a case data buffer for the case named
* SW_CASE_DATA_BUFNAME. We write the buffer out after filling in the
* structure version and recording the type of case this is, and if there
* is data for the subsidiary then we call swde_subdata to note the
* size and version of that data in the case data buf and then to create
* and write the subdata in a buffer named SW_CASE_DATA_BUFNAME_<casetype>.
*
* If the subsidiary updates its case data it is required to call
* swde_case_data_write. This just calls fmd_buf_write for the subsidiary
* buffer name.
*
* A subsidiary can retrieve its private data buffer for a case using
* swde_case_data. This also fills a uint32_t with the version of the
* buffer that we have for this subsidiary; if that is an old version
* below.
*
* When the host module is reloaded it calls swde_case_init to iterate
* through all cases we own. For each we call swde_case_unserialize
* which restores our case tracking data and any subsidiary-private
* data that our case data notes. We then call swde_case_verify which
* calls any registered verify function in the subsidiary owner, and if this
* returns 0 the case is closed.
*
* After initial write, we don't usually have to update the
* SW_CASE_DATA_BUFNAME buffer unless the subsidiary changes the size or
* version of its private buffer. To do that the subsidiary must call
* swde_case_data_upgrade. In that function we destroy the old subsidiary
* buffer and, if there is still a subsidiary data structure, create a
* new buffer appropriately sized and call swde_subdata to write it out
* after updating our case structure with new size etc. Finally we write
* out our updated case data structure.
*/
#define SW_CASE_DATA_BUFNAME "casedata"
#define SW_CASE_DATA_VERSION_INITIAL 1
typedef struct swde_case_data {
/*
* In-core case structure.
*/
typedef struct swde_case {
void *swc_subdata; /* subsidiary data for serialization */
} swde_case_t;
static void
void *subdata)
{
}
static void
{
void *subdata;
return;
}
"version %u but received %u\n",
}
}
}
static void
{
"does not match argument\n");
}
{
fmd_case_t *cp;
if (ct == SW_CASE_NONE)
} else {
return (NULL);
}
}
if (subdata)
return (cp);
}
/*
* fmdo_close entry point for software-diagnosis
*/
void
{
/*
* Now that the sub-de has had a chance to clean up, do some ourselves.
* Note that we free the sub-de-private subdata structure.
*/
if (scp->swc_subdata) {
}
}
{
fmd_case_t *cp;
if (ct == SW_CASE_NONE)
break;
}
return (cp);
}
{
fmd_case_t *cp;
int ct;
break;
}
return (cp);
}
void *
{
return (scp->swc_subdata);
}
void
{
return;
}
void
{
if (scp->swc_subdata) {
datap->sc_sub_bufsz = 0;
}
}
}
static void
{
}
}
void
{
fmd_case_t *cp;
}
}
/*ARGSUSED*/
void
{
}