/*
* 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
*/
/*
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/*
* Description:
* Checkpoint the ereport events for persitence across fmd restart.
*
* Each ereport is stored in a named buffer. Each ereport is uniquely
* indentified by a id which is consists of a number of ereport fields. The
* name of the buffer is derived from the id.
*
* All ereport ids are stored in the circular list which is saved in a
* separate buffer.
*/
#include <assert.h>
#include <stdio.h>
#include <pthread.h>
#include <strings.h>
#include "etm_etm_proto.h"
#include "etm_iosvc.h"
#include "etm_ckpt.h"
#include "etm_filter.h"
/*
* -------------------------- private variables ------------------------------
*/
/*
* -------------------------- functions --------------------------------------
*/
/*
* etm_ckpt_str_hash()
* Description:
* Hash a class name to a number
*/
static uint_t
{
return (0);
while (*str != '\0')
return (hash);
}
/*
* etm_ckpt_id2str()
* Description:
* Get the string of an ereport id. It is used as the named buffer that
* store the ereport.
*/
static void
}
/*
* etm_ckpt_erpt2id()
* Description:
* Get the buffer name and ereport id of a given ereport
*/
static int
/* ena */
return (-1);
}
/* class name */
return (-1);
}
return (-1);
}
/* tod[1]: fractional of a second */
if (sz >= 2) {
}
}
/* primary flag */
}
return (0);
}
/*
* etm_ckpt_il_equal()
* Description:
* Test if two ereport ids are equal.
*/
static boolean_t
{
}
/*
* etm_ckpt_il_resize()
* Description:
* Increase the size of the circular list and pack its entries.
*/
static void
{
if (factor == 0)
return;
/* the present queue */
il1 = etm_id_lst;
/* Create an empty queue with a new size */
/* pointers to the two arrays of entries */
s1 = (etm_ckpt_erpt_id_t *)
s2 = (etm_ckpt_erpt_id_t *)
/* copy non-empty ereport ids from list il1 to il2. Toss the blank. */
/* copy non-empty entries */
}
}
}
if (factor == 1) {
/* both lists have the same size, update the present list */
} else {
/* replace the present list */
etm_id_lst = il2;
/* write to new buffer */
}
}
/*
* etm_ckpt_il_find()
* Description:
* Find the ereport id in the list.
*/
/* ARGSUSED */
static int
{
etm_ckpt_erpt_id_t *p, *s; /* temp erpt id */
/* empty list */
return (-1);
}
sizeof (etm_ckpt_id_list_t));
p = s + next;
if (etm_ckpt_il_equal(p, id))
return (i);
}
return (-1);
}
/*
* etm_ckpt_il_add()
* Description:
* Add an ereport id in the list.
*/
static int
int next;
etm_ckpt_erpt_id_t *p, *s; /* temp id */
/*
* resize the q if it is full.
* If the capacity is less 80%, purge the emtpy entries to make more
* room for new entries. Otherwise, double the queue size.
*/
} else {
}
/* test if the list again */
}
}
/* Add the id entry at the head */
sizeof (etm_ckpt_id_list_t));
p = s + etm_id_lst->il_tail;
*p = *id;
etm_id_lst->il_cnt++;
return (etm_id_lst->il_tail);
}
/*
* etm_ckpt_il_delete()
* Description:
* Delete an ereport id from the list.
*/
int
etm_ckpt_erpt_id_t *p, *s; /* temp id pointers */
/* empty list */
return (-1);
}
sizeof (etm_ckpt_id_list_t));
/* delete leading empty entries */
p = s + next;
if (!etm_ckpt_il_equal(p, &blank)) {
break;
}
etm_id_lst->il_cnt--;
}
/* empty queue */
return (-1);
}
/* find the entry and clear it */
p = s + next;
if (etm_ckpt_il_equal(p, id)) {
/* clear the entry */
*p = blank;
etm_id_lst->il_cnt--;
/* remove the entry if it is the last one */
if (i == etm_id_lst->il_head) {
}
return (i);
}
}
return (-1);
}
/*
* etm_ckpt_il_restore()
* Description:
* Restore the idlist named buffer which is the circular list of the
* the ereport ids.
*/
void
{
/* get the buffer of the id list */
if (size < sizeof (etm_ckpt_id_list_t)) {
return;
}
/* check version */
etm_id_lst->il_ver);
etm_id_lst = NULL;
return;
}
/* check the length */
etm_id_lst = NULL;
return;
}
}
/*
* etm_ckpt_recover()
* Description:
* Recover ereports from the checkpointed data and dispatch them to the
* ldom queue(s).
*/
void
{
etm_ckpt_erpt_id_t *p, *s; /* temp ereport id */
/*
* restore the circular list of ereport ids
*/
if (etm_id_lst == NULL) {
size = sizeof (etm_ckpt_id_list_t) +
ETM_CKPT_IL_MIN_SIZE * sizeof (etm_ckpt_erpt_id_t);
etm_id_lst->il_head = 0;
etm_id_lst->il_tail = 0;
ETM_CKPT_IL_MIN_SIZE * sizeof (etm_ckpt_erpt_id_t);
size);
/* commit */
return;
}
/* Empty list */
(etm_id_lst->il_cnt == 0)) {
return;
}
/* Visit all the entries in the list */
sizeof (etm_ckpt_id_list_t));
p = s + next;
if (etm_ckpt_il_equal(p, &blank)) {
continue;
}
*p = blank;
continue;
}
continue;
}
*p = blank;
continue;
}
/*
* Find the queue of the ldom, create it if not exist.
* Then insert this event into the queue.
*/
}
}
if (dirty) {
/* update the buffer of the queue */
size);
/* commit */
}
} /* etm_ckpt_recover */
/*
* etm_ckpt_add_entry()
* Description:
* Save an ereport for persistence.
*/
int
/* map ereport to id */
if (rc != 0) {
return (rc);
}
/*
* check for a duplicate entry in the id list
* find the ereport buffer and search for the id
*/
return (-1);
}
/* Create the ereport buffer */
return (-1);
}
return (-1);
}
/* Insert the ereport id into the id list */
return (-1);
}
/* update the buffer of the queue */
/* commit */
return (0);
}
/*
* etm_ckpt_delete_entry()
* Description:
* Delete an ereport id in the list.
*/
static int
/* get id, id name */
return (-1);
}
/* delete the ereport buffer */
}
if (rc < 0) {
return (rc);
}
/* update the buffer of the queue */
/* commit */
return (rc);
}
int
(void) pthread_mutex_lock(&etm_id_lst_lock);
(void) pthread_mutex_unlock(&etm_id_lst_lock);
}
int
(void) pthread_mutex_lock(&etm_id_lst_lock);
(void) pthread_mutex_unlock(&etm_id_lst_lock);
}
/* ARGSUSED */
void
etm_id_lst = NULL;
}
void
if (etm_id_lst != NULL) {
}
(void) pthread_mutex_destroy(&etm_id_lst_lock);
}