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.
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.
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]
22 * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
26 #pragma ident "%Z%%M% %I% %E% SMI"
28 #include "statcommon.h"
33 /* max size of report change annotations */
36 static char cpus_added
[LIST_SIZE
];
37 static char cpus_removed
[LIST_SIZE
];
40 cpu_walk(struct snapshot
*old
, struct snapshot
*new,
41 snapshot_cb cb
, void *data
)
46 /* CPUs can change state but not re-order */
47 for (i
= 0; i
< new->s_nr_cpus
; i
++) {
48 struct cpu_snapshot
*cpu
= NULL
;
49 struct cpu_snapshot
*newcpu
= &new->s_cpus
[i
];
51 cpu
= &old
->s_cpus
[i
];
52 cb(cpu
, newcpu
, data
);
57 * We only care about off/on line transitions
59 if ((CPU_ACTIVE(cpu
) && !CPU_ACTIVE(newcpu
)) ||
60 (!CPU_ACTIVE(cpu
) && CPU_ACTIVE(newcpu
)))
62 if ((new->s_types
& SNAP_PSETS
) &&
63 cpu
->cs_pset_id
!= newcpu
->cs_pset_id
)
73 pset_walk(struct snapshot
*old
, struct snapshot
*new,
74 snapshot_cb cb
, void *data
)
80 while (old
&& i
< old
->s_nr_psets
&& j
< new->s_nr_psets
) {
81 if (old
->s_psets
[i
].ps_id
< new->s_psets
[j
].ps_id
) {
82 cb(&old
->s_psets
[i
], NULL
, data
);
85 } else if (old
->s_psets
[i
].ps_id
> new->s_psets
[j
].ps_id
) {
86 cb(NULL
, &new->s_psets
[j
], data
);
90 cb(&old
->s_psets
[i
], &new->s_psets
[j
], data
);
96 while (old
&& i
< old
->s_nr_psets
) {
97 cb(&old
->s_psets
[i
], NULL
, data
);
102 while (j
< new->s_nr_psets
) {
103 cb(NULL
, &new->s_psets
[j
], data
);
112 iodev_walk(struct iodev_snapshot
*d1
, struct iodev_snapshot
*d2
,
113 snapshot_cb cb
, void *data
)
118 if (strcmp(d1
->is_name
, d2
->is_name
) < 0) {
121 (void) iodev_walk(d1
->is_children
, NULL
, cb
, data
);
123 } else if (strcmp(d1
->is_name
, d2
->is_name
) > 0) {
126 (void) iodev_walk(NULL
, d2
->is_children
, cb
, data
);
130 changed
|= iodev_walk(d1
->is_children
,
131 d2
->is_children
, cb
, data
);
140 (void) iodev_walk(d1
->is_children
, NULL
, cb
, data
);
147 (void) iodev_walk(NULL
, d2
->is_children
, cb
, data
);
155 snapshot_walk(enum snapshot_types type
, struct snapshot
*old
,
156 struct snapshot
*new, snapshot_cb cb
, void *data
)
162 changed
= cpu_walk(old
, new, cb
, data
);
166 changed
= pset_walk(old
, new, cb
, data
);
169 case SNAP_CONTROLLERS
:
171 case SNAP_IOPATHS_LI
:
172 case SNAP_IOPATHS_LTI
:
173 changed
= iodev_walk(old
? old
->s_iodevs
: NULL
,
174 new->s_iodevs
, cb
, data
);
185 add_nr_to_list(char *buf
, unsigned long nr
)
189 (void) snprintf(tmp
, LIST_SIZE
, "%lu", nr
);
192 (void) strlcat(buf
, ", ", LIST_SIZE
);
194 (void) strlcat(buf
, tmp
, LIST_SIZE
);
198 cpu_report(void *v1
, void *v2
, void *data
)
200 int *pset
= (int *)data
;
201 struct cpu_snapshot
*c1
= (struct cpu_snapshot
*)v1
;
202 struct cpu_snapshot
*c2
= (struct cpu_snapshot
*)v2
;
204 if (*pset
&& c1
->cs_pset_id
!= c2
->cs_pset_id
) {
205 (void) printf("<<processor %d moved from pset: %d to: %d>>\n",
206 c1
->cs_id
, c1
->cs_pset_id
, c2
->cs_pset_id
);
209 if (c1
->cs_state
== c2
->cs_state
)
212 if (CPU_ONLINE(c1
->cs_state
) && !CPU_ONLINE(c2
->cs_state
))
213 add_nr_to_list(cpus_removed
, c1
->cs_id
);
215 if (!CPU_ONLINE(c1
->cs_state
) && CPU_ONLINE(c2
->cs_state
))
216 add_nr_to_list(cpus_added
, c2
->cs_id
);
221 pset_report(void *v1
, void *v2
, void *data
)
223 struct pset_snapshot
*p1
= (struct pset_snapshot
*)v1
;
224 struct pset_snapshot
*p2
= (struct pset_snapshot
*)v2
;
227 (void) printf("<<pset destroyed: %u>>\n", p1
->ps_id
);
232 (void) printf("<<pset created: %u>>\n", p2
->ps_id
);
236 get_child_list(struct iodev_snapshot
*iodev
, char *buf
)
239 struct iodev_snapshot
*pos
= iodev
->is_children
;
242 if (pos
->is_type
== IODEV_PARTITION
) {
243 add_nr_to_list(buf
, pos
->is_id
.id
);
244 } else if (pos
->is_type
== IODEV_DISK
) {
246 (void) strlcat(buf
, ", ", LIST_SIZE
);
247 (void) strlcat(buf
, "t", LIST_SIZE
);
248 (void) strlcat(buf
, pos
->is_id
.tid
, LIST_SIZE
);
249 (void) strlcat(buf
, "d", LIST_SIZE
);
251 add_nr_to_list(tmp
, pos
->is_id
.id
);
252 (void) strlcat(buf
, tmp
, LIST_SIZE
);
259 iodev_changed(struct iodev_snapshot
*iodev
, int added
)
262 int is_disk
= iodev
->is_type
== IODEV_DISK
;
263 char *name
= iodev
->is_name
;
265 if (iodev
->is_pretty
)
266 name
= iodev
->is_pretty
;
268 switch (iodev
->is_type
) {
269 case IODEV_IOPATH_LT
:
270 case IODEV_IOPATH_LI
:
271 case IODEV_IOPATH_LTI
:
272 (void) printf("<<multi-path %s: %s>>\n",
273 added
? "added" : "removed", name
);
275 case IODEV_PARTITION
:
276 (void) printf("<<partition %s: %s>>\n",
277 added
? "added" : "removed", name
);
280 (void) printf("<<NFS %s: %s>>\n",
281 added
? "mounted" : "unmounted", name
);
284 (void) printf("<<device %s: %s>>\n",
285 added
? "added" : "removed", name
);
287 case IODEV_CONTROLLER
:
290 get_child_list(iodev
, tmp
);
291 (void) printf("<<%s %s: %s", is_disk
? "disk" : "controller",
292 added
? "added" : "removed", name
);
294 (void) printf(">>\n");
297 (void) printf(" (%s %s)>>\n", is_disk
? "slices" : "disks",
304 iodev_report(struct iodev_snapshot
*d1
, struct iodev_snapshot
*d2
)
307 if (iodev_cmp(d1
, d2
) < 0) {
308 iodev_changed(d1
, 0);
310 } else if (iodev_cmp(d1
, d2
) > 0) {
311 iodev_changed(d2
, 1);
314 iodev_report(d1
->is_children
, d2
->is_children
);
321 iodev_changed(d1
, 0);
326 iodev_changed(d2
, 1);
332 snapshot_report_changes(struct snapshot
*old
, struct snapshot
*new)
336 if (old
== NULL
|| new == NULL
)
339 if (old
->s_types
!= new->s_types
)
342 pset
= old
->s_types
& SNAP_PSETS
;
344 cpus_removed
[0] = '\0';
345 cpus_added
[0] = '\0';
347 if (old
->s_types
& SNAP_CPUS
)
348 (void) snapshot_walk(SNAP_CPUS
, old
, new, cpu_report
, &pset
);
351 (void) printf("<<processors added: %s>>\n",
354 if (cpus_removed
[0]) {
355 (void) printf("<<processors removed: %s>>\n",
359 (void) snapshot_walk(SNAP_PSETS
, old
, new,
363 iodev_report(old
->s_iodevs
, new->s_iodevs
);
368 dummy_cb(void *v1
, void *v2
, void *data
)
373 snapshot_has_changed(struct snapshot
*old
, struct snapshot
*new)
376 int cpu_mask
= SNAP_CPUS
| SNAP_PSETS
| SNAP_SYSTEM
;
377 int iodev_mask
= SNAP_CONTROLLERS
| SNAP_IODEVS
|
378 SNAP_IOPATHS_LI
| SNAP_IOPATHS_LTI
;
386 if (old
->s_types
!= new->s_types
)
389 if (!ret
&& (old
->s_types
& cpu_mask
))
390 ret
= snapshot_walk(SNAP_CPUS
, old
, new, dummy_cb
, NULL
);
391 if (!ret
&& (old
->s_types
& SNAP_PSETS
))
392 ret
= snapshot_walk(SNAP_PSETS
, old
, new, dummy_cb
, NULL
);
393 if (!ret
&& (old
->s_types
& iodev_mask
))
394 ret
= snapshot_walk(SNAP_IODEVS
, old
, new, dummy_cb
, NULL
);