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 5*37fbbce5Scth * Common Development and Distribution License (the "License"). 6*37fbbce5Scth * 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 /* 22*37fbbce5Scth * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 237c478bd9Sstevel@tonic-gate * Use is subject to license terms. 247c478bd9Sstevel@tonic-gate */ 257c478bd9Sstevel@tonic-gate 267c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 277c478bd9Sstevel@tonic-gate 287c478bd9Sstevel@tonic-gate #include "statcommon.h" 297c478bd9Sstevel@tonic-gate 307c478bd9Sstevel@tonic-gate #include <string.h> 317c478bd9Sstevel@tonic-gate #include <errno.h> 327c478bd9Sstevel@tonic-gate 337c478bd9Sstevel@tonic-gate /* max size of report change annotations */ 347c478bd9Sstevel@tonic-gate #define LIST_SIZE 512 357c478bd9Sstevel@tonic-gate 367c478bd9Sstevel@tonic-gate static char cpus_added[LIST_SIZE]; 377c478bd9Sstevel@tonic-gate static char cpus_removed[LIST_SIZE]; 387c478bd9Sstevel@tonic-gate 397c478bd9Sstevel@tonic-gate static int 407c478bd9Sstevel@tonic-gate cpu_walk(struct snapshot *old, struct snapshot *new, 417c478bd9Sstevel@tonic-gate snapshot_cb cb, void *data) 427c478bd9Sstevel@tonic-gate { 437c478bd9Sstevel@tonic-gate int changed = 0; 447c478bd9Sstevel@tonic-gate int i; 457c478bd9Sstevel@tonic-gate 467c478bd9Sstevel@tonic-gate /* CPUs can change state but not re-order */ 477c478bd9Sstevel@tonic-gate for (i = 0; i < new->s_nr_cpus; i++) { 487c478bd9Sstevel@tonic-gate struct cpu_snapshot *cpu = NULL; 497c478bd9Sstevel@tonic-gate struct cpu_snapshot *newcpu = &new->s_cpus[i]; 507c478bd9Sstevel@tonic-gate if (old) 517c478bd9Sstevel@tonic-gate cpu = &old->s_cpus[i]; 527c478bd9Sstevel@tonic-gate cb(cpu, newcpu, data); 537c478bd9Sstevel@tonic-gate if (cpu == NULL) 547c478bd9Sstevel@tonic-gate changed = 1; 557c478bd9Sstevel@tonic-gate else { 567c478bd9Sstevel@tonic-gate /* 577c478bd9Sstevel@tonic-gate * We only care about off/on line transitions 587c478bd9Sstevel@tonic-gate */ 597c478bd9Sstevel@tonic-gate if ((CPU_ACTIVE(cpu) && !CPU_ACTIVE(newcpu)) || 607c478bd9Sstevel@tonic-gate (!CPU_ACTIVE(cpu) && CPU_ACTIVE(newcpu))) 617c478bd9Sstevel@tonic-gate changed = 1; 627c478bd9Sstevel@tonic-gate if ((new->s_types & SNAP_PSETS) && 637c478bd9Sstevel@tonic-gate cpu->cs_pset_id != newcpu->cs_pset_id) 647c478bd9Sstevel@tonic-gate changed = 1; 657c478bd9Sstevel@tonic-gate } 667c478bd9Sstevel@tonic-gate 677c478bd9Sstevel@tonic-gate } 687c478bd9Sstevel@tonic-gate 697c478bd9Sstevel@tonic-gate return (changed); 707c478bd9Sstevel@tonic-gate } 717c478bd9Sstevel@tonic-gate 727c478bd9Sstevel@tonic-gate static int 737c478bd9Sstevel@tonic-gate pset_walk(struct snapshot *old, struct snapshot *new, 747c478bd9Sstevel@tonic-gate snapshot_cb cb, void *data) 757c478bd9Sstevel@tonic-gate { 767c478bd9Sstevel@tonic-gate int i = 0; 777c478bd9Sstevel@tonic-gate int j = 0; 787c478bd9Sstevel@tonic-gate int changed = 0; 797c478bd9Sstevel@tonic-gate 807c478bd9Sstevel@tonic-gate while (old && i < old->s_nr_psets && j < new->s_nr_psets) { 817c478bd9Sstevel@tonic-gate if (old->s_psets[i].ps_id < new->s_psets[j].ps_id) { 827c478bd9Sstevel@tonic-gate cb(&old->s_psets[i], NULL, data); 837c478bd9Sstevel@tonic-gate i++; 847c478bd9Sstevel@tonic-gate changed = 1; 857c478bd9Sstevel@tonic-gate } else if (old->s_psets[i].ps_id > new->s_psets[j].ps_id) { 867c478bd9Sstevel@tonic-gate cb(NULL, &new->s_psets[j], data); 877c478bd9Sstevel@tonic-gate j++; 887c478bd9Sstevel@tonic-gate changed = 1; 897c478bd9Sstevel@tonic-gate } else { 907c478bd9Sstevel@tonic-gate cb(&old->s_psets[i], &new->s_psets[j], data); 917c478bd9Sstevel@tonic-gate i++; 927c478bd9Sstevel@tonic-gate j++; 937c478bd9Sstevel@tonic-gate } 947c478bd9Sstevel@tonic-gate } 957c478bd9Sstevel@tonic-gate 967c478bd9Sstevel@tonic-gate while (old && i < old->s_nr_psets) { 977c478bd9Sstevel@tonic-gate cb(&old->s_psets[i], NULL, data); 987c478bd9Sstevel@tonic-gate i++; 997c478bd9Sstevel@tonic-gate changed = 1; 1007c478bd9Sstevel@tonic-gate } 1017c478bd9Sstevel@tonic-gate 1027c478bd9Sstevel@tonic-gate while (j < new->s_nr_psets) { 1037c478bd9Sstevel@tonic-gate cb(NULL, &new->s_psets[j], data); 1047c478bd9Sstevel@tonic-gate j++; 1057c478bd9Sstevel@tonic-gate changed = 1; 1067c478bd9Sstevel@tonic-gate } 1077c478bd9Sstevel@tonic-gate 1087c478bd9Sstevel@tonic-gate return (changed); 1097c478bd9Sstevel@tonic-gate } 1107c478bd9Sstevel@tonic-gate 1117c478bd9Sstevel@tonic-gate static int 1127c478bd9Sstevel@tonic-gate iodev_walk(struct iodev_snapshot *d1, struct iodev_snapshot *d2, 1137c478bd9Sstevel@tonic-gate snapshot_cb cb, void *data) 1147c478bd9Sstevel@tonic-gate { 1157c478bd9Sstevel@tonic-gate int changed = 0; 1167c478bd9Sstevel@tonic-gate 1177c478bd9Sstevel@tonic-gate while (d1 && d2) { 1187c478bd9Sstevel@tonic-gate if (strcmp(d1->is_name, d2->is_name) < 0) { 1197c478bd9Sstevel@tonic-gate changed = 1; 1207c478bd9Sstevel@tonic-gate cb(d1, NULL, data); 1217c478bd9Sstevel@tonic-gate (void) iodev_walk(d1->is_children, NULL, cb, data); 1227c478bd9Sstevel@tonic-gate d1 = d1->is_next; 1237c478bd9Sstevel@tonic-gate } else if (strcmp(d1->is_name, d2->is_name) > 0) { 1247c478bd9Sstevel@tonic-gate changed = 1; 1257c478bd9Sstevel@tonic-gate cb(NULL, d2, data); 1267c478bd9Sstevel@tonic-gate (void) iodev_walk(NULL, d2->is_children, cb, data); 1277c478bd9Sstevel@tonic-gate d2 = d2->is_next; 1287c478bd9Sstevel@tonic-gate } else { 1297c478bd9Sstevel@tonic-gate cb(d1, d2, data); 1307c478bd9Sstevel@tonic-gate changed |= iodev_walk(d1->is_children, 1317c478bd9Sstevel@tonic-gate d2->is_children, cb, data); 1327c478bd9Sstevel@tonic-gate d1 = d1->is_next; 1337c478bd9Sstevel@tonic-gate d2 = d2->is_next; 1347c478bd9Sstevel@tonic-gate } 1357c478bd9Sstevel@tonic-gate } 1367c478bd9Sstevel@tonic-gate 1377c478bd9Sstevel@tonic-gate while (d1) { 1387c478bd9Sstevel@tonic-gate changed = 1; 1397c478bd9Sstevel@tonic-gate cb(d1, NULL, data); 1407c478bd9Sstevel@tonic-gate (void) iodev_walk(d1->is_children, NULL, cb, data); 1417c478bd9Sstevel@tonic-gate d1 = d1->is_next; 1427c478bd9Sstevel@tonic-gate } 1437c478bd9Sstevel@tonic-gate 1447c478bd9Sstevel@tonic-gate while (d2) { 1457c478bd9Sstevel@tonic-gate changed = 1; 1467c478bd9Sstevel@tonic-gate cb(NULL, d2, data); 1477c478bd9Sstevel@tonic-gate (void) iodev_walk(NULL, d2->is_children, cb, data); 1487c478bd9Sstevel@tonic-gate d2 = d2->is_next; 1497c478bd9Sstevel@tonic-gate } 1507c478bd9Sstevel@tonic-gate 1517c478bd9Sstevel@tonic-gate return (changed); 1527c478bd9Sstevel@tonic-gate } 1537c478bd9Sstevel@tonic-gate 1547c478bd9Sstevel@tonic-gate int 1557c478bd9Sstevel@tonic-gate snapshot_walk(enum snapshot_types type, struct snapshot *old, 1567c478bd9Sstevel@tonic-gate struct snapshot *new, snapshot_cb cb, void *data) 1577c478bd9Sstevel@tonic-gate { 1587c478bd9Sstevel@tonic-gate int changed = 0; 1597c478bd9Sstevel@tonic-gate 1607c478bd9Sstevel@tonic-gate switch (type) { 1617c478bd9Sstevel@tonic-gate case SNAP_CPUS: 1627c478bd9Sstevel@tonic-gate changed = cpu_walk(old, new, cb, data); 1637c478bd9Sstevel@tonic-gate break; 1647c478bd9Sstevel@tonic-gate 1657c478bd9Sstevel@tonic-gate case SNAP_PSETS: 1667c478bd9Sstevel@tonic-gate changed = pset_walk(old, new, cb, data); 1677c478bd9Sstevel@tonic-gate break; 1687c478bd9Sstevel@tonic-gate 1697c478bd9Sstevel@tonic-gate case SNAP_CONTROLLERS: 1707c478bd9Sstevel@tonic-gate case SNAP_IODEVS: 171*37fbbce5Scth case SNAP_IOPATHS_LI: 172*37fbbce5Scth case SNAP_IOPATHS_LTI: 1737c478bd9Sstevel@tonic-gate changed = iodev_walk(old ? old->s_iodevs : NULL, 1747c478bd9Sstevel@tonic-gate new->s_iodevs, cb, data); 1757c478bd9Sstevel@tonic-gate break; 1767c478bd9Sstevel@tonic-gate 1777c478bd9Sstevel@tonic-gate default: 1787c478bd9Sstevel@tonic-gate break; 1797c478bd9Sstevel@tonic-gate } 1807c478bd9Sstevel@tonic-gate 1817c478bd9Sstevel@tonic-gate return (changed); 1827c478bd9Sstevel@tonic-gate } 1837c478bd9Sstevel@tonic-gate 1847c478bd9Sstevel@tonic-gate static void 1857c478bd9Sstevel@tonic-gate add_nr_to_list(char *buf, unsigned long nr) 1867c478bd9Sstevel@tonic-gate { 1877c478bd9Sstevel@tonic-gate char tmp[LIST_SIZE]; 1887c478bd9Sstevel@tonic-gate 1897c478bd9Sstevel@tonic-gate (void) snprintf(tmp, LIST_SIZE, "%lu", nr); 1907c478bd9Sstevel@tonic-gate 1917c478bd9Sstevel@tonic-gate if (strlen(buf)) 1927c478bd9Sstevel@tonic-gate (void) strlcat(buf, ", ", LIST_SIZE); 1937c478bd9Sstevel@tonic-gate 1947c478bd9Sstevel@tonic-gate (void) strlcat(buf, tmp, LIST_SIZE); 1957c478bd9Sstevel@tonic-gate } 1967c478bd9Sstevel@tonic-gate 1977c478bd9Sstevel@tonic-gate static void 1987c478bd9Sstevel@tonic-gate cpu_report(void *v1, void *v2, void *data) 1997c478bd9Sstevel@tonic-gate { 2007c478bd9Sstevel@tonic-gate int *pset = (int *)data; 2017c478bd9Sstevel@tonic-gate struct cpu_snapshot *c1 = (struct cpu_snapshot *)v1; 2027c478bd9Sstevel@tonic-gate struct cpu_snapshot *c2 = (struct cpu_snapshot *)v2; 2037c478bd9Sstevel@tonic-gate 2047c478bd9Sstevel@tonic-gate if (*pset && c1->cs_pset_id != c2->cs_pset_id) { 2057c478bd9Sstevel@tonic-gate (void) printf("<<processor %d moved from pset: %d to: %d>>\n", 2067c478bd9Sstevel@tonic-gate c1->cs_id, c1->cs_pset_id, c2->cs_pset_id); 2077c478bd9Sstevel@tonic-gate } 2087c478bd9Sstevel@tonic-gate 2097c478bd9Sstevel@tonic-gate if (c1->cs_state == c2->cs_state) 2107c478bd9Sstevel@tonic-gate return; 2117c478bd9Sstevel@tonic-gate 2127c478bd9Sstevel@tonic-gate if (CPU_ONLINE(c1->cs_state) && !CPU_ONLINE(c2->cs_state)) 2137c478bd9Sstevel@tonic-gate add_nr_to_list(cpus_removed, c1->cs_id); 2147c478bd9Sstevel@tonic-gate 2157c478bd9Sstevel@tonic-gate if (!CPU_ONLINE(c1->cs_state) && CPU_ONLINE(c2->cs_state)) 2167c478bd9Sstevel@tonic-gate add_nr_to_list(cpus_added, c2->cs_id); 2177c478bd9Sstevel@tonic-gate } 2187c478bd9Sstevel@tonic-gate 2197c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 2207c478bd9Sstevel@tonic-gate static void 2217c478bd9Sstevel@tonic-gate pset_report(void *v1, void *v2, void *data) 2227c478bd9Sstevel@tonic-gate { 2237c478bd9Sstevel@tonic-gate struct pset_snapshot *p1 = (struct pset_snapshot *)v1; 2247c478bd9Sstevel@tonic-gate struct pset_snapshot *p2 = (struct pset_snapshot *)v2; 2257c478bd9Sstevel@tonic-gate 2267c478bd9Sstevel@tonic-gate if (p2 == NULL) { 2277c478bd9Sstevel@tonic-gate (void) printf("<<pset destroyed: %u>>\n", p1->ps_id); 2287c478bd9Sstevel@tonic-gate return; 2297c478bd9Sstevel@tonic-gate } 2307c478bd9Sstevel@tonic-gate 2317c478bd9Sstevel@tonic-gate if (p1 == NULL) 2327c478bd9Sstevel@tonic-gate (void) printf("<<pset created: %u>>\n", p2->ps_id); 2337c478bd9Sstevel@tonic-gate } 2347c478bd9Sstevel@tonic-gate 2357c478bd9Sstevel@tonic-gate static void 2367c478bd9Sstevel@tonic-gate get_child_list(struct iodev_snapshot *iodev, char *buf) 2377c478bd9Sstevel@tonic-gate { 2387c478bd9Sstevel@tonic-gate char tmp[LIST_SIZE]; 2397c478bd9Sstevel@tonic-gate struct iodev_snapshot *pos = iodev->is_children; 2407c478bd9Sstevel@tonic-gate 2417c478bd9Sstevel@tonic-gate while (pos) { 2427c478bd9Sstevel@tonic-gate if (pos->is_type == IODEV_PARTITION) { 2437c478bd9Sstevel@tonic-gate add_nr_to_list(buf, pos->is_id.id); 2447c478bd9Sstevel@tonic-gate } else if (pos->is_type == IODEV_DISK) { 2457c478bd9Sstevel@tonic-gate if (strlen(buf)) 2467c478bd9Sstevel@tonic-gate (void) strlcat(buf, ", ", LIST_SIZE); 2477c478bd9Sstevel@tonic-gate (void) strlcat(buf, "t", LIST_SIZE); 2487c478bd9Sstevel@tonic-gate (void) strlcat(buf, pos->is_id.tid, LIST_SIZE); 2497c478bd9Sstevel@tonic-gate (void) strlcat(buf, "d", LIST_SIZE); 2507c478bd9Sstevel@tonic-gate *tmp = '\0'; 2517c478bd9Sstevel@tonic-gate add_nr_to_list(tmp, pos->is_id.id); 2527c478bd9Sstevel@tonic-gate (void) strlcat(buf, tmp, LIST_SIZE); 2537c478bd9Sstevel@tonic-gate } 2547c478bd9Sstevel@tonic-gate pos = pos->is_next; 2557c478bd9Sstevel@tonic-gate } 2567c478bd9Sstevel@tonic-gate } 2577c478bd9Sstevel@tonic-gate 2587c478bd9Sstevel@tonic-gate static void 2597c478bd9Sstevel@tonic-gate iodev_changed(struct iodev_snapshot *iodev, int added) 2607c478bd9Sstevel@tonic-gate { 2617c478bd9Sstevel@tonic-gate char tmp[LIST_SIZE]; 2627c478bd9Sstevel@tonic-gate int is_disk = iodev->is_type == IODEV_DISK; 2637c478bd9Sstevel@tonic-gate char *name = iodev->is_name; 2647c478bd9Sstevel@tonic-gate 2657c478bd9Sstevel@tonic-gate if (iodev->is_pretty) 2667c478bd9Sstevel@tonic-gate name = iodev->is_pretty; 2677c478bd9Sstevel@tonic-gate 2687c478bd9Sstevel@tonic-gate switch (iodev->is_type) { 269*37fbbce5Scth case IODEV_IOPATH_LT: 270*37fbbce5Scth case IODEV_IOPATH_LI: 271*37fbbce5Scth case IODEV_IOPATH_LTI: 2727c478bd9Sstevel@tonic-gate (void) printf("<<multi-path %s: %s>>\n", 2737c478bd9Sstevel@tonic-gate added ? "added" : "removed", name); 2747c478bd9Sstevel@tonic-gate break; 2757c478bd9Sstevel@tonic-gate case IODEV_PARTITION: 2767c478bd9Sstevel@tonic-gate (void) printf("<<partition %s: %s>>\n", 2777c478bd9Sstevel@tonic-gate added ? "added" : "removed", name); 2787c478bd9Sstevel@tonic-gate break; 2797c478bd9Sstevel@tonic-gate case IODEV_NFS: 2807c478bd9Sstevel@tonic-gate (void) printf("<<NFS %s: %s>>\n", 2817c478bd9Sstevel@tonic-gate added ? "mounted" : "unmounted", name); 2827c478bd9Sstevel@tonic-gate break; 2837c478bd9Sstevel@tonic-gate case IODEV_TAPE: 2847c478bd9Sstevel@tonic-gate (void) printf("<<device %s: %s>>\n", 2857c478bd9Sstevel@tonic-gate added ? "added" : "removed", name); 2867c478bd9Sstevel@tonic-gate break; 2877c478bd9Sstevel@tonic-gate case IODEV_CONTROLLER: 2887c478bd9Sstevel@tonic-gate case IODEV_DISK: 2897c478bd9Sstevel@tonic-gate *tmp = '\0'; 2907c478bd9Sstevel@tonic-gate get_child_list(iodev, tmp); 2917c478bd9Sstevel@tonic-gate (void) printf("<<%s %s: %s", is_disk ? "disk" : "controller", 2927c478bd9Sstevel@tonic-gate added ? "added" : "removed", name); 2937c478bd9Sstevel@tonic-gate if (!*tmp) { 2947c478bd9Sstevel@tonic-gate (void) printf(">>\n"); 2957c478bd9Sstevel@tonic-gate return; 2967c478bd9Sstevel@tonic-gate } 2977c478bd9Sstevel@tonic-gate (void) printf(" (%s %s)>>\n", is_disk ? "slices" : "disks", 2987c478bd9Sstevel@tonic-gate tmp); 2997c478bd9Sstevel@tonic-gate break; 3007c478bd9Sstevel@tonic-gate }; 3017c478bd9Sstevel@tonic-gate } 3027c478bd9Sstevel@tonic-gate 3037c478bd9Sstevel@tonic-gate static void 3047c478bd9Sstevel@tonic-gate iodev_report(struct iodev_snapshot *d1, struct iodev_snapshot *d2) 3057c478bd9Sstevel@tonic-gate { 3067c478bd9Sstevel@tonic-gate while (d1 && d2) { 3077c478bd9Sstevel@tonic-gate if (iodev_cmp(d1, d2) < 0) { 3087c478bd9Sstevel@tonic-gate iodev_changed(d1, 0); 3097c478bd9Sstevel@tonic-gate d1 = d1->is_next; 3107c478bd9Sstevel@tonic-gate } else if (iodev_cmp(d1, d2) > 0) { 3117c478bd9Sstevel@tonic-gate iodev_changed(d2, 1); 3127c478bd9Sstevel@tonic-gate d2 = d2->is_next; 3137c478bd9Sstevel@tonic-gate } else { 3147c478bd9Sstevel@tonic-gate iodev_report(d1->is_children, d2->is_children); 3157c478bd9Sstevel@tonic-gate d1 = d1->is_next; 3167c478bd9Sstevel@tonic-gate d2 = d2->is_next; 3177c478bd9Sstevel@tonic-gate } 3187c478bd9Sstevel@tonic-gate } 3197c478bd9Sstevel@tonic-gate 3207c478bd9Sstevel@tonic-gate while (d1) { 3217c478bd9Sstevel@tonic-gate iodev_changed(d1, 0); 3227c478bd9Sstevel@tonic-gate d1 = d1->is_next; 3237c478bd9Sstevel@tonic-gate } 3247c478bd9Sstevel@tonic-gate 3257c478bd9Sstevel@tonic-gate while (d2) { 3267c478bd9Sstevel@tonic-gate iodev_changed(d2, 1); 3277c478bd9Sstevel@tonic-gate d2 = d2->is_next; 3287c478bd9Sstevel@tonic-gate } 3297c478bd9Sstevel@tonic-gate } 3307c478bd9Sstevel@tonic-gate 3317c478bd9Sstevel@tonic-gate void 3327c478bd9Sstevel@tonic-gate snapshot_report_changes(struct snapshot *old, struct snapshot *new) 3337c478bd9Sstevel@tonic-gate { 3347c478bd9Sstevel@tonic-gate int pset; 3357c478bd9Sstevel@tonic-gate 3367c478bd9Sstevel@tonic-gate if (old == NULL || new == NULL) 3377c478bd9Sstevel@tonic-gate return; 3387c478bd9Sstevel@tonic-gate 3397c478bd9Sstevel@tonic-gate if (old->s_types != new->s_types) 3407c478bd9Sstevel@tonic-gate return; 3417c478bd9Sstevel@tonic-gate 3427c478bd9Sstevel@tonic-gate pset = old->s_types & SNAP_PSETS; 3437c478bd9Sstevel@tonic-gate 3447c478bd9Sstevel@tonic-gate cpus_removed[0] = '\0'; 3457c478bd9Sstevel@tonic-gate cpus_added[0] = '\0'; 3467c478bd9Sstevel@tonic-gate 3477c478bd9Sstevel@tonic-gate if (old->s_types & SNAP_CPUS) 3487c478bd9Sstevel@tonic-gate (void) snapshot_walk(SNAP_CPUS, old, new, cpu_report, &pset); 3497c478bd9Sstevel@tonic-gate 3507c478bd9Sstevel@tonic-gate if (cpus_added[0]) { 3517c478bd9Sstevel@tonic-gate (void) printf("<<processors added: %s>>\n", 3527c478bd9Sstevel@tonic-gate cpus_added); 3537c478bd9Sstevel@tonic-gate } 3547c478bd9Sstevel@tonic-gate if (cpus_removed[0]) { 3557c478bd9Sstevel@tonic-gate (void) printf("<<processors removed: %s>>\n", 3567c478bd9Sstevel@tonic-gate cpus_removed); 3577c478bd9Sstevel@tonic-gate } 3587c478bd9Sstevel@tonic-gate if (pset) { 3597c478bd9Sstevel@tonic-gate (void) snapshot_walk(SNAP_PSETS, old, new, 3607c478bd9Sstevel@tonic-gate pset_report, NULL); 3617c478bd9Sstevel@tonic-gate } 3627c478bd9Sstevel@tonic-gate 3637c478bd9Sstevel@tonic-gate iodev_report(old->s_iodevs, new->s_iodevs); 3647c478bd9Sstevel@tonic-gate } 3657c478bd9Sstevel@tonic-gate 3667c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 3677c478bd9Sstevel@tonic-gate static void 3687c478bd9Sstevel@tonic-gate dummy_cb(void *v1, void *v2, void *data) 3697c478bd9Sstevel@tonic-gate { 3707c478bd9Sstevel@tonic-gate } 3717c478bd9Sstevel@tonic-gate 3727c478bd9Sstevel@tonic-gate int 3737c478bd9Sstevel@tonic-gate snapshot_has_changed(struct snapshot *old, struct snapshot *new) 3747c478bd9Sstevel@tonic-gate { 3757c478bd9Sstevel@tonic-gate int ret = 0; 3767c478bd9Sstevel@tonic-gate int cpu_mask = SNAP_CPUS | SNAP_PSETS | SNAP_SYSTEM; 377*37fbbce5Scth int iodev_mask = SNAP_CONTROLLERS | SNAP_IODEVS | 378*37fbbce5Scth SNAP_IOPATHS_LI | SNAP_IOPATHS_LTI; 3797c478bd9Sstevel@tonic-gate 3807c478bd9Sstevel@tonic-gate if (old == NULL) 3817c478bd9Sstevel@tonic-gate return (1); 3827c478bd9Sstevel@tonic-gate 3837c478bd9Sstevel@tonic-gate if (new == NULL) 3847c478bd9Sstevel@tonic-gate return (EINVAL); 3857c478bd9Sstevel@tonic-gate 3867c478bd9Sstevel@tonic-gate if (old->s_types != new->s_types) 3877c478bd9Sstevel@tonic-gate return (EINVAL); 3887c478bd9Sstevel@tonic-gate 3897c478bd9Sstevel@tonic-gate if (!ret && (old->s_types & cpu_mask)) 3907c478bd9Sstevel@tonic-gate ret = snapshot_walk(SNAP_CPUS, old, new, dummy_cb, NULL); 3917c478bd9Sstevel@tonic-gate if (!ret && (old->s_types & SNAP_PSETS)) 3927c478bd9Sstevel@tonic-gate ret = snapshot_walk(SNAP_PSETS, old, new, dummy_cb, NULL); 3937c478bd9Sstevel@tonic-gate if (!ret && (old->s_types & iodev_mask)) 3947c478bd9Sstevel@tonic-gate ret = snapshot_walk(SNAP_IODEVS, old, new, dummy_cb, NULL); 3957c478bd9Sstevel@tonic-gate 3967c478bd9Sstevel@tonic-gate return (ret); 3977c478bd9Sstevel@tonic-gate } 398