17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate * CDDL HEADER START
37c478bd9Sstevel@tonic-gate *
47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the
5724365f7Ssethg * Common Development and Distribution License (the "License").
6724365f7Ssethg * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate *
87c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate * and limitations under the License.
127c478bd9Sstevel@tonic-gate *
137c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate *
197c478bd9Sstevel@tonic-gate * CDDL HEADER END
207c478bd9Sstevel@tonic-gate */
217c478bd9Sstevel@tonic-gate /*
222a417b23SRobert Johnston * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
237c478bd9Sstevel@tonic-gate */
247c478bd9Sstevel@tonic-gate
257c478bd9Sstevel@tonic-gate /*
267c478bd9Sstevel@tonic-gate * FMD Dynamic Reconfiguration (DR) Event Handling
277c478bd9Sstevel@tonic-gate *
287c478bd9Sstevel@tonic-gate * Fault manager scheme plug-ins must track characteristics of individual
297c478bd9Sstevel@tonic-gate * pieces of hardware. As these components can be added or removed by a DR
307c478bd9Sstevel@tonic-gate * operation, we need to provide a means by which plug-ins can determine when
317c478bd9Sstevel@tonic-gate * they need to re-examine the current configuration. We provide a simple
327c478bd9Sstevel@tonic-gate * mechanism whereby this task can be implemented using lazy evaluation: a
337c478bd9Sstevel@tonic-gate * simple 64-bit generation counter is maintained and incremented on *any* DR.
347c478bd9Sstevel@tonic-gate * Schemes can store the generation number in scheme-specific data structures,
357c478bd9Sstevel@tonic-gate * and then revalidate their contents if the current generation number has
367c478bd9Sstevel@tonic-gate * changed since the resource information was cached. This method saves time,
377c478bd9Sstevel@tonic-gate * avoids the complexity of direct participation in DR, avoids the need for
387c478bd9Sstevel@tonic-gate * resource-specific processing of DR events, and is relatively easy to port
397c478bd9Sstevel@tonic-gate * to other systems that support dynamic reconfiguration.
4024db4641Seschrock *
4124db4641Seschrock * The dr generation is only incremented in response to hardware changes. Since
4224db4641Seschrock * ASRUs can be in any scheme, including the device scheme, we must also be
4324db4641Seschrock * aware of software configuration changes which may affect the resource cache.
4424db4641Seschrock * In addition, we take a snapshot of the topology whenever a reconfiguration
4524db4641Seschrock * event occurs and notify any modules of the change.
467c478bd9Sstevel@tonic-gate */
477c478bd9Sstevel@tonic-gate
487c478bd9Sstevel@tonic-gate #include <sys/types.h>
4924db4641Seschrock #include <sys/sunddi.h>
507c478bd9Sstevel@tonic-gate #include <sys/sysevent/dr.h>
517c478bd9Sstevel@tonic-gate #include <sys/sysevent/eventdefs.h>
527c478bd9Sstevel@tonic-gate
537c478bd9Sstevel@tonic-gate #include <stdio.h>
5424db4641Seschrock #include <string.h>
55d9638e54Smws #include <unistd.h>
567c478bd9Sstevel@tonic-gate #include <libsysevent.h>
577c478bd9Sstevel@tonic-gate
587c478bd9Sstevel@tonic-gate #undef MUTEX_HELD
597c478bd9Sstevel@tonic-gate #undef RW_READ_HELD
607c478bd9Sstevel@tonic-gate #undef RW_WRITE_HELD
617c478bd9Sstevel@tonic-gate
62724365f7Ssethg #include <fmd_asru.h>
637c478bd9Sstevel@tonic-gate #include <fmd_error.h>
6424db4641Seschrock #include <fmd_event.h>
65724365f7Ssethg #include <fmd_fmri.h>
6624db4641Seschrock #include <fmd_module.h>
677c478bd9Sstevel@tonic-gate #include <fmd_subr.h>
6824db4641Seschrock #include <fmd_topo.h>
697c478bd9Sstevel@tonic-gate #include <fmd.h>
707c478bd9Sstevel@tonic-gate
719af3851aSeschrock void
fmd_dr_event(sysevent_t * sep)727c478bd9Sstevel@tonic-gate fmd_dr_event(sysevent_t *sep)
737c478bd9Sstevel@tonic-gate {
747c478bd9Sstevel@tonic-gate uint64_t gen;
7524db4641Seschrock fmd_event_t *e;
7624db4641Seschrock const char *class = sysevent_get_class_name(sep);
779af3851aSeschrock const char *subclass = sysevent_get_subclass_name(sep);
7824db4641Seschrock hrtime_t evtime;
7924db4641Seschrock fmd_topo_t *ftp, *prev;
807c478bd9Sstevel@tonic-gate
8124db4641Seschrock if (strcmp(class, EC_DR) == 0) {
829af3851aSeschrock if (strcmp(subclass, ESC_DR_AP_STATE_CHANGE) != 0 &&
839af3851aSeschrock strcmp(subclass, ESC_DR_TARGET_STATE_CHANGE) != 0)
849af3851aSeschrock return;
852a417b23SRobert Johnston /* LINTED: E_NOP_IF_STMT */
869af3851aSeschrock } else if (strcmp(class, EC_DEVFS) == 0) {
879af3851aSeschrock /*
889af3851aSeschrock * A devfs configuration event can change the topology,
899af3851aSeschrock * as disk nodes only exist when the device is configured.
909af3851aSeschrock */
91e5dcf7beSRobert Johnston } else if (strcmp(class, EC_PLATFORM) == 0) {
92e5dcf7beSRobert Johnston /*
93e5dcf7beSRobert Johnston * Since we rely on the SP to enumerate fans,
94e5dcf7beSRobert Johnston * power-supplies and sensors/leds, it would be prudent
95e5dcf7beSRobert Johnston * to take a new snapshot if the SP resets.
96e5dcf7beSRobert Johnston */
972a417b23SRobert Johnston if (strcmp(subclass, ESC_PLATFORM_SP_RESET) != 0)
989af3851aSeschrock return;
999af3851aSeschrock } else if (strcmp(class, EC_DEV_ADD) == 0 ||
1009af3851aSeschrock strcmp(class, EC_DEV_REMOVE) == 0) {
1019af3851aSeschrock if (strcmp(subclass, ESC_DISK) != 0)
1029af3851aSeschrock return;
1032a417b23SRobert Johnston } else
1042a417b23SRobert Johnston return;
10524db4641Seschrock
10624db4641Seschrock /*
10724db4641Seschrock * Take a topo snapshot and notify modules of the change. Picking an
10824db4641Seschrock * accurate time here is difficult. On one hand, we have the timestamp
10924db4641Seschrock * of the underlying sysevent, indicating when the reconfiguration event
11024db4641Seschrock * occurred. On the other hand, we are taking the topo snapshot
11124db4641Seschrock * asynchronously, and hence the timestamp of the snapshot is the
11224db4641Seschrock * current time. Pretending this topo snapshot was valid at the time
11324db4641Seschrock * the sysevent was posted seems wrong, so we instead opt for the
11424db4641Seschrock * current time as an upper bound on the snapshot validity.
11524db4641Seschrock *
11624db4641Seschrock * Along these lines, we keep track of the last time we dispatched a
11724db4641Seschrock * topo snapshot. If the sysevent occurred before the last topo
11824db4641Seschrock * snapshot, then don't bother dispatching another topo change event.
11924db4641Seschrock * We've already indicated (to the best of our ability) the change in
12024db4641Seschrock * topology. This prevents endless topo snapshots in response to a
12124db4641Seschrock * flurry of sysevents.
12224db4641Seschrock */
12324db4641Seschrock sysevent_get_time(sep, &evtime);
12424db4641Seschrock prev = fmd_topo_hold();
12507312882SEric Schrock if (evtime <= prev->ft_time_begin &&
12624db4641Seschrock fmd.d_clockops == &fmd_timeops_native) {
12724db4641Seschrock fmd_topo_rele(prev);
12824db4641Seschrock return;
12924db4641Seschrock }
13024db4641Seschrock fmd_topo_rele(prev);
13124db4641Seschrock
1322a417b23SRobert Johnston (void) pthread_mutex_lock(&fmd.d_stats_lock);
1332a417b23SRobert Johnston gen = fmd.d_stats->ds_dr_gen.fmds_value.ui64++;
1342a417b23SRobert Johnston (void) pthread_mutex_unlock(&fmd.d_stats_lock);
1352a417b23SRobert Johnston
1362a417b23SRobert Johnston TRACE((FMD_DBG_XPRT, "dr event %p, gen=%llu", (void *)sep, gen));
137*8393544eSHyon Kim fmd_topo_update();
13824db4641Seschrock
13924db4641Seschrock ftp = fmd_topo_hold();
14007312882SEric Schrock e = fmd_event_create(FMD_EVT_TOPO, ftp->ft_time_end, NULL, ftp);
14124db4641Seschrock fmd_modhash_dispatch(fmd.d_mod_hash, e);
1427c478bd9Sstevel@tonic-gate }
143