Print this page
NEX-3729 KRRP changes mess up iostat(1M)
Reviewed by: Alek Pinchuk <alek.pinchuk@nexenta.com>
Reviewed by: Roman Strashkin <roman.strashkin@nexenta.com>
| Split |
Close |
| Expand all |
| Collapse all |
--- old/usr/src/cmd/stat/common/walkers.c
+++ new/usr/src/cmd/stat/common/walkers.c
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License (the "License").
6 6 * You may not use this file except in compliance with the License.
7 7 *
8 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 * or http://www.opensolaris.org/os/licensing.
10 10 * See the License for the specific language governing permissions
11 11 * and limitations under the License.
12 12 *
13 13 * When distributing Covered Code, include this CDDL HEADER in each
14 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 15 * If applicable, add the following below this CDDL HEADER, with the
16 16 * fields enclosed by brackets "[]" replaced with your own identifying
17 17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 18 *
19 19 * CDDL HEADER END
20 20 */
21 21 /*
22 22 * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
23 23 * Use is subject to license terms.
24 24 */
25 25
26 26 #pragma ident "%Z%%M% %I% %E% SMI"
27 27
28 28 #include "statcommon.h"
29 29
30 30 #include <string.h>
31 31 #include <errno.h>
32 32
33 33 /* max size of report change annotations */
34 34 #define LIST_SIZE 512
35 35
36 36 static char cpus_added[LIST_SIZE];
37 37 static char cpus_removed[LIST_SIZE];
38 38
39 39 static int
40 40 cpu_walk(struct snapshot *old, struct snapshot *new,
41 41 snapshot_cb cb, void *data)
42 42 {
43 43 int changed = 0;
44 44 int i;
45 45
46 46 /* CPUs can change state but not re-order */
47 47 for (i = 0; i < new->s_nr_cpus; i++) {
48 48 struct cpu_snapshot *cpu = NULL;
49 49 struct cpu_snapshot *newcpu = &new->s_cpus[i];
50 50 if (old)
51 51 cpu = &old->s_cpus[i];
52 52 cb(cpu, newcpu, data);
53 53 if (cpu == NULL)
54 54 changed = 1;
55 55 else {
56 56 /*
57 57 * We only care about off/on line transitions
58 58 */
59 59 if ((CPU_ACTIVE(cpu) && !CPU_ACTIVE(newcpu)) ||
60 60 (!CPU_ACTIVE(cpu) && CPU_ACTIVE(newcpu)))
61 61 changed = 1;
62 62 if ((new->s_types & SNAP_PSETS) &&
63 63 cpu->cs_pset_id != newcpu->cs_pset_id)
64 64 changed = 1;
65 65 }
66 66
67 67 }
68 68
69 69 return (changed);
70 70 }
71 71
72 72 static int
73 73 pset_walk(struct snapshot *old, struct snapshot *new,
74 74 snapshot_cb cb, void *data)
75 75 {
76 76 int i = 0;
77 77 int j = 0;
78 78 int changed = 0;
79 79
80 80 while (old && i < old->s_nr_psets && j < new->s_nr_psets) {
81 81 if (old->s_psets[i].ps_id < new->s_psets[j].ps_id) {
82 82 cb(&old->s_psets[i], NULL, data);
83 83 i++;
84 84 changed = 1;
85 85 } else if (old->s_psets[i].ps_id > new->s_psets[j].ps_id) {
86 86 cb(NULL, &new->s_psets[j], data);
87 87 j++;
88 88 changed = 1;
89 89 } else {
90 90 cb(&old->s_psets[i], &new->s_psets[j], data);
91 91 i++;
92 92 j++;
93 93 }
94 94 }
95 95
96 96 while (old && i < old->s_nr_psets) {
97 97 cb(&old->s_psets[i], NULL, data);
98 98 i++;
99 99 changed = 1;
100 100 }
101 101
102 102 while (j < new->s_nr_psets) {
103 103 cb(NULL, &new->s_psets[j], data);
104 104 j++;
105 105 changed = 1;
106 106 }
107 107
108 108 return (changed);
109 109 }
110 110
111 111 static int
112 112 iodev_walk(struct iodev_snapshot *d1, struct iodev_snapshot *d2,
113 113 snapshot_cb cb, void *data)
114 114 {
115 115 int changed = 0;
116 116
117 117 while (d1 && d2) {
118 118 if (strcmp(d1->is_name, d2->is_name) < 0) {
119 119 changed = 1;
120 120 cb(d1, NULL, data);
121 121 (void) iodev_walk(d1->is_children, NULL, cb, data);
122 122 d1 = d1->is_next;
123 123 } else if (strcmp(d1->is_name, d2->is_name) > 0) {
124 124 changed = 1;
125 125 cb(NULL, d2, data);
126 126 (void) iodev_walk(NULL, d2->is_children, cb, data);
127 127 d2 = d2->is_next;
128 128 } else {
129 129 cb(d1, d2, data);
130 130 changed |= iodev_walk(d1->is_children,
131 131 d2->is_children, cb, data);
132 132 d1 = d1->is_next;
133 133 d2 = d2->is_next;
134 134 }
135 135 }
136 136
137 137 while (d1) {
138 138 changed = 1;
139 139 cb(d1, NULL, data);
140 140 (void) iodev_walk(d1->is_children, NULL, cb, data);
141 141 d1 = d1->is_next;
142 142 }
143 143
144 144 while (d2) {
145 145 changed = 1;
146 146 cb(NULL, d2, data);
147 147 (void) iodev_walk(NULL, d2->is_children, cb, data);
148 148 d2 = d2->is_next;
149 149 }
150 150
151 151 return (changed);
152 152 }
153 153
154 154 int
155 155 snapshot_walk(enum snapshot_types type, struct snapshot *old,
156 156 struct snapshot *new, snapshot_cb cb, void *data)
157 157 {
158 158 int changed = 0;
159 159
160 160 switch (type) {
161 161 case SNAP_CPUS:
162 162 changed = cpu_walk(old, new, cb, data);
163 163 break;
164 164
165 165 case SNAP_PSETS:
166 166 changed = pset_walk(old, new, cb, data);
167 167 break;
168 168
169 169 case SNAP_CONTROLLERS:
170 170 case SNAP_IODEVS:
171 171 case SNAP_IOPATHS_LI:
172 172 case SNAP_IOPATHS_LTI:
173 173 changed = iodev_walk(old ? old->s_iodevs : NULL,
174 174 new->s_iodevs, cb, data);
175 175 break;
176 176
177 177 default:
178 178 break;
179 179 }
180 180
181 181 return (changed);
182 182 }
183 183
184 184 static void
185 185 add_nr_to_list(char *buf, unsigned long nr)
186 186 {
187 187 char tmp[LIST_SIZE];
188 188
189 189 (void) snprintf(tmp, LIST_SIZE, "%lu", nr);
190 190
191 191 if (strlen(buf))
192 192 (void) strlcat(buf, ", ", LIST_SIZE);
193 193
194 194 (void) strlcat(buf, tmp, LIST_SIZE);
195 195 }
196 196
197 197 static void
198 198 cpu_report(void *v1, void *v2, void *data)
199 199 {
200 200 int *pset = (int *)data;
201 201 struct cpu_snapshot *c1 = (struct cpu_snapshot *)v1;
202 202 struct cpu_snapshot *c2 = (struct cpu_snapshot *)v2;
203 203
204 204 if (*pset && c1->cs_pset_id != c2->cs_pset_id) {
205 205 (void) printf("<<processor %d moved from pset: %d to: %d>>\n",
206 206 c1->cs_id, c1->cs_pset_id, c2->cs_pset_id);
207 207 }
208 208
209 209 if (c1->cs_state == c2->cs_state)
210 210 return;
211 211
212 212 if (CPU_ONLINE(c1->cs_state) && !CPU_ONLINE(c2->cs_state))
213 213 add_nr_to_list(cpus_removed, c1->cs_id);
214 214
215 215 if (!CPU_ONLINE(c1->cs_state) && CPU_ONLINE(c2->cs_state))
216 216 add_nr_to_list(cpus_added, c2->cs_id);
217 217 }
218 218
219 219 /*ARGSUSED*/
220 220 static void
221 221 pset_report(void *v1, void *v2, void *data)
222 222 {
223 223 struct pset_snapshot *p1 = (struct pset_snapshot *)v1;
224 224 struct pset_snapshot *p2 = (struct pset_snapshot *)v2;
225 225
226 226 if (p2 == NULL) {
227 227 (void) printf("<<pset destroyed: %u>>\n", p1->ps_id);
228 228 return;
229 229 }
230 230
231 231 if (p1 == NULL)
232 232 (void) printf("<<pset created: %u>>\n", p2->ps_id);
233 233 }
234 234
235 235 static void
236 236 get_child_list(struct iodev_snapshot *iodev, char *buf)
237 237 {
238 238 char tmp[LIST_SIZE];
239 239 struct iodev_snapshot *pos = iodev->is_children;
240 240
241 241 while (pos) {
242 242 if (pos->is_type == IODEV_PARTITION) {
243 243 add_nr_to_list(buf, pos->is_id.id);
244 244 } else if (pos->is_type == IODEV_DISK) {
245 245 if (strlen(buf))
246 246 (void) strlcat(buf, ", ", LIST_SIZE);
247 247 (void) strlcat(buf, "t", LIST_SIZE);
248 248 (void) strlcat(buf, pos->is_id.tid, LIST_SIZE);
249 249 (void) strlcat(buf, "d", LIST_SIZE);
250 250 *tmp = '\0';
251 251 add_nr_to_list(tmp, pos->is_id.id);
252 252 (void) strlcat(buf, tmp, LIST_SIZE);
253 253 }
254 254 pos = pos->is_next;
255 255 }
256 256 }
257 257
258 258 static void
259 259 iodev_changed(struct iodev_snapshot *iodev, int added)
260 260 {
261 261 char tmp[LIST_SIZE];
262 262 int is_disk = iodev->is_type == IODEV_DISK;
263 263 char *name = iodev->is_name;
264 264
265 265 if (iodev->is_pretty)
266 266 name = iodev->is_pretty;
267 267
268 268 switch (iodev->is_type) {
|
↓ open down ↓ |
268 lines elided |
↑ open up ↑ |
269 269 case IODEV_IOPATH_LT:
270 270 case IODEV_IOPATH_LI:
271 271 case IODEV_IOPATH_LTI:
272 272 (void) printf("<<multi-path %s: %s>>\n",
273 273 added ? "added" : "removed", name);
274 274 break;
275 275 case IODEV_PARTITION:
276 276 (void) printf("<<partition %s: %s>>\n",
277 277 added ? "added" : "removed", name);
278 278 break;
279 + case IODEV_ZFS:
280 + (void) printf("<<ZFS %s %s: %s>>\n",
281 + strchr(name, '/') ? "vdev" : "pool",
282 + added ? "added" : "removed", name);
283 + break;
279 284 case IODEV_NFS:
280 285 (void) printf("<<NFS %s: %s>>\n",
281 286 added ? "mounted" : "unmounted", name);
282 287 break;
283 288 case IODEV_TAPE:
284 289 (void) printf("<<device %s: %s>>\n",
285 290 added ? "added" : "removed", name);
286 291 break;
287 292 case IODEV_CONTROLLER:
288 293 case IODEV_DISK:
289 294 *tmp = '\0';
290 295 get_child_list(iodev, tmp);
291 296 (void) printf("<<%s %s: %s", is_disk ? "disk" : "controller",
292 297 added ? "added" : "removed", name);
293 298 if (!*tmp) {
294 299 (void) printf(">>\n");
295 300 return;
296 301 }
297 302 (void) printf(" (%s %s)>>\n", is_disk ? "slices" : "disks",
298 303 tmp);
299 304 break;
300 305 };
301 306 }
302 307
303 308 static void
304 309 iodev_report(struct iodev_snapshot *d1, struct iodev_snapshot *d2)
305 310 {
306 311 while (d1 && d2) {
307 312 if (iodev_cmp(d1, d2) < 0) {
308 313 iodev_changed(d1, 0);
309 314 d1 = d1->is_next;
310 315 } else if (iodev_cmp(d1, d2) > 0) {
311 316 iodev_changed(d2, 1);
312 317 d2 = d2->is_next;
313 318 } else {
314 319 iodev_report(d1->is_children, d2->is_children);
315 320 d1 = d1->is_next;
316 321 d2 = d2->is_next;
317 322 }
318 323 }
319 324
320 325 while (d1) {
321 326 iodev_changed(d1, 0);
322 327 d1 = d1->is_next;
323 328 }
324 329
325 330 while (d2) {
326 331 iodev_changed(d2, 1);
327 332 d2 = d2->is_next;
328 333 }
329 334 }
330 335
331 336 void
332 337 snapshot_report_changes(struct snapshot *old, struct snapshot *new)
333 338 {
334 339 int pset;
335 340
336 341 if (old == NULL || new == NULL)
337 342 return;
338 343
339 344 if (old->s_types != new->s_types)
340 345 return;
341 346
342 347 pset = old->s_types & SNAP_PSETS;
343 348
344 349 cpus_removed[0] = '\0';
345 350 cpus_added[0] = '\0';
346 351
347 352 if (old->s_types & SNAP_CPUS)
348 353 (void) snapshot_walk(SNAP_CPUS, old, new, cpu_report, &pset);
349 354
350 355 if (cpus_added[0]) {
351 356 (void) printf("<<processors added: %s>>\n",
352 357 cpus_added);
353 358 }
354 359 if (cpus_removed[0]) {
355 360 (void) printf("<<processors removed: %s>>\n",
356 361 cpus_removed);
357 362 }
358 363 if (pset) {
359 364 (void) snapshot_walk(SNAP_PSETS, old, new,
360 365 pset_report, NULL);
361 366 }
362 367
363 368 iodev_report(old->s_iodevs, new->s_iodevs);
364 369 }
365 370
366 371 /*ARGSUSED*/
367 372 static void
368 373 dummy_cb(void *v1, void *v2, void *data)
369 374 {
370 375 }
371 376
372 377 int
373 378 snapshot_has_changed(struct snapshot *old, struct snapshot *new)
374 379 {
375 380 int ret = 0;
376 381 int cpu_mask = SNAP_CPUS | SNAP_PSETS | SNAP_SYSTEM;
377 382 int iodev_mask = SNAP_CONTROLLERS | SNAP_IODEVS |
378 383 SNAP_IOPATHS_LI | SNAP_IOPATHS_LTI;
379 384
380 385 if (old == NULL)
381 386 return (1);
382 387
383 388 if (new == NULL)
384 389 return (EINVAL);
385 390
386 391 if (old->s_types != new->s_types)
387 392 return (EINVAL);
388 393
389 394 if (!ret && (old->s_types & cpu_mask))
390 395 ret = snapshot_walk(SNAP_CPUS, old, new, dummy_cb, NULL);
391 396 if (!ret && (old->s_types & SNAP_PSETS))
392 397 ret = snapshot_walk(SNAP_PSETS, old, new, dummy_cb, NULL);
393 398 if (!ret && (old->s_types & iodev_mask))
394 399 ret = snapshot_walk(SNAP_IODEVS, old, new, dummy_cb, NULL);
395 400
396 401 return (ret);
397 402 }
|
↓ open down ↓ |
109 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX