Print this page
NEX-17829 libfmd_snmp and snmp-notify should provide FMRIs for all fault types
Reviewed by: Cynthia Eastham <cynthia.eastham@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
NEX-17772 libfmd_snmp should learn about new FmProblem fields
Reviewed by: Rick McNeal <rick.mcneal@nexenta.com>
Reviewed by: Roman Strashkin <roman.strashkin@nexenta.com>
re #13388 rb4382 fmd_api.h uses bool which is a C99/C++ keyword
| Split |
Close |
| Expand all |
| Collapse all |
--- old/usr/src/lib/fm/libfmd_adm/common/fmd_adm.c
+++ new/usr/src/lib/fm/libfmd_adm/common/fmd_adm.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
|
↓ open down ↓ |
16 lines elided |
↑ open up ↑ |
17 17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 18 *
19 19 * CDDL HEADER END
20 20 */
21 21
22 22 /*
23 23 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
24 24 * Use is subject to license terms.
25 25 */
26 26
27 -#include <strings.h>
28 -#include <stdlib.h>
29 -#include <netdir.h>
30 -#include <errno.h>
27 +/*
28 + * Copyright 2018 Nexenta Systems, Inc.
29 + */
30 +
31 +#include <sys/fm/protocol.h>
32 +
31 33 #include <alloca.h>
34 +#include <errno.h>
32 35 #include <locale.h>
36 +#include <netdir.h>
37 +#include <stdlib.h>
38 +#include <strings.h>
33 39 #include <uuid/uuid.h>
34 40
35 -#include <sys/fm/protocol.h>
36 41 #include <fmd_adm_impl.h>
37 42 #include <fmd_rpc_adm.h>
38 43
39 44 static const uint_t _fmd_adm_bufsize = 128 * 1024;
40 45 static const char _url_fallback[] = "http://illumos.org/msg/";
41 46
42 47 fmd_adm_t *
43 48 fmd_adm_open(const char *host, uint32_t prog, int version)
44 49 {
45 50 fmd_adm_t *ap;
46 51 CLIENT *c;
47 52 rpcvers_t v;
48 53
49 54 if (version != FMD_ADM_VERSION) {
50 55 errno = ENOTSUP;
51 56 return (NULL);
52 57 }
53 58
54 59 if (host == NULL)
55 60 host = HOST_SELF;
56 61
57 62 if (prog == FMD_ADM_PROGRAM)
58 63 prog = FMD_ADM;
59 64
60 65 if ((ap = malloc(sizeof (fmd_adm_t))) == NULL)
61 66 return (NULL);
62 67
63 68 if (strcmp(host, HOST_SELF) == 0) {
64 69 c = clnt_door_create(prog, FMD_ADM_VERSION_1, _fmd_adm_bufsize);
65 70 ap->adm_maxretries = 1;
66 71 } else {
67 72 c = clnt_create_vers(host, prog, &v,
68 73 FMD_ADM_VERSION_1, FMD_ADM_VERSION_1, NULL);
69 74 ap->adm_maxretries = 0;
70 75 }
71 76
72 77 if (c == NULL) {
73 78 errno = EPROTO;
74 79 free(ap);
75 80 return (NULL);
76 81 }
77 82
78 83 ap->adm_prog = prog;
79 84 ap->adm_clnt = c;
80 85 ap->adm_version = version;
81 86 ap->adm_svcerr = 0;
82 87 ap->adm_errno = 0;
83 88
84 89 return (ap);
85 90 }
86 91
87 92 void
88 93 fmd_adm_close(fmd_adm_t *ap)
89 94 {
90 95 if (ap == NULL)
91 96 return; /* permit NULL to simply caller code */
92 97
93 98 clnt_destroy(ap->adm_clnt);
94 99 free(ap);
95 100 }
96 101
97 102 static const char *
98 103 fmd_adm_svc_errmsg(enum fmd_adm_error err)
99 104 {
100 105 switch (err) {
101 106 case FMD_ADM_ERR_NOMEM:
102 107 return ("unable to perform request due to allocation failure");
103 108 case FMD_ADM_ERR_PERM:
104 109 return ("operation requires additional privilege");
105 110 case FMD_ADM_ERR_MODSRCH:
106 111 return ("specified module is not loaded in fault manager");
107 112 case FMD_ADM_ERR_MODBUSY:
108 113 return ("module is in use and cannot be unloaded");
109 114 case FMD_ADM_ERR_MODFAIL:
110 115 return ("module failed and can no longer export statistics");
111 116 case FMD_ADM_ERR_MODNOENT:
112 117 return ("file missing or cannot be accessed by fault manager");
113 118 case FMD_ADM_ERR_MODEXIST:
114 119 return ("module using same name is already loaded");
115 120 case FMD_ADM_ERR_MODINIT:
116 121 return ("module failed to initialize (consult fmd(1M) log)");
117 122 case FMD_ADM_ERR_MODLOAD:
118 123 return ("module failed to load (consult fmd(1M) log)");
119 124 case FMD_ADM_ERR_RSRCSRCH:
120 125 return ("specified resource is not cached by fault manager");
121 126 case FMD_ADM_ERR_RSRCNOTF:
122 127 return ("specified resource is not known to be faulty");
123 128 case FMD_ADM_ERR_SERDSRCH:
124 129 return ("specified serd engine not present in module");
125 130 case FMD_ADM_ERR_SERDFIRED:
126 131 return ("specified serd engine has already fired");
127 132 case FMD_ADM_ERR_ROTSRCH:
128 133 return ("invalid log file name");
129 134 case FMD_ADM_ERR_ROTFAIL:
130 135 return ("failed to rotate log file (consult fmd(1M) log)");
131 136 case FMD_ADM_ERR_ROTBUSY:
132 137 return ("log file is too busy to rotate (try again later)");
133 138 case FMD_ADM_ERR_CASESRCH:
134 139 return ("specified UUID is invalid or has been repaired");
135 140 case FMD_ADM_ERR_CASEOPEN:
136 141 return ("specified UUID is still being diagnosed");
137 142 case FMD_ADM_ERR_XPRTSRCH:
138 143 return ("specified transport ID is invalid or has been closed");
139 144 case FMD_ADM_ERR_CASEXPRT:
140 145 return ("specified UUID is owned by a different fault manager");
141 146 case FMD_ADM_ERR_RSRCNOTR:
142 147 return ("specified resource has not been replaced");
143 148 default:
144 149 return ("unknown fault manager error");
145 150 }
146 151 }
147 152
148 153 const char *
149 154 fmd_adm_errmsg(fmd_adm_t *ap)
150 155 {
151 156 if (ap == NULL) {
152 157 switch (errno) {
153 158 case ENOTSUP:
154 159 return ("client requires newer libfmd_adm version");
155 160 case EPROTO:
156 161 return (clnt_spcreateerror("failed to connect to fmd"));
157 162 }
158 163 }
159 164
160 165 switch (ap ? ap->adm_errno : errno) {
161 166 case EPROTO:
162 167 return (clnt_sperror(ap->adm_clnt, "rpc call failed"));
163 168 case EREMOTE:
164 169 return (fmd_adm_svc_errmsg(ap->adm_svcerr));
165 170 default:
166 171 return (strerror(ap->adm_errno));
167 172 }
168 173 }
169 174
170 175 static int
171 176 fmd_adm_set_svcerr(fmd_adm_t *ap, enum fmd_adm_error err)
172 177 {
173 178 if (err != 0) {
174 179 ap->adm_svcerr = err;
175 180 ap->adm_errno = EREMOTE;
176 181 return (-1);
177 182 } else {
178 183 ap->adm_svcerr = err;
179 184 ap->adm_errno = 0;
180 185 return (0);
181 186 }
182 187 }
183 188
184 189 static int
185 190 fmd_adm_set_errno(fmd_adm_t *ap, int err)
186 191 {
187 192 ap->adm_errno = err;
188 193 errno = err;
189 194 return (-1);
190 195 }
191 196
192 197 static int
193 198 fmd_adm_stats_cmp(const void *lp, const void *rp)
194 199 {
195 200 return (strcmp(((fmd_stat_t *)lp)->fmds_name,
196 201 ((fmd_stat_t *)rp)->fmds_name));
197 202 }
198 203
199 204 /*
200 205 * If the server (fmd) is restarted, this will cause all future door calls to
201 206 * fail. Unfortunately, once the server comes back up, we have no way of
202 207 * reestablishing the connection. To get around this, if the error indicates
203 208 * that the RPC call failed, we reopen the client handle and try again. For
204 209 * simplicity we only deal with the door case, as it's unclear whether the
205 210 * remote case suffers from the same pathology.
206 211 */
207 212 boolean_t
208 213 fmd_adm_retry(fmd_adm_t *ap, enum clnt_stat cs, uint_t *retries)
209 214 {
210 215 CLIENT *c;
211 216 struct rpc_err err;
212 217
213 218 if (cs == RPC_SUCCESS || *retries == ap->adm_maxretries)
214 219 return (B_FALSE);
215 220
216 221 clnt_geterr(ap->adm_clnt, &err);
217 222 if (err.re_status != RPC_CANTSEND)
218 223 return (B_FALSE);
219 224
220 225 if ((c = clnt_door_create(ap->adm_prog, FMD_ADM_VERSION_1,
221 226 _fmd_adm_bufsize)) == NULL)
222 227 return (B_FALSE);
223 228
224 229 (*retries)++;
225 230
226 231 clnt_destroy(ap->adm_clnt);
227 232 ap->adm_clnt = c;
228 233
229 234 return (B_TRUE);
230 235 }
231 236
232 237 int
233 238 fmd_adm_stats_read(fmd_adm_t *ap, const char *name, fmd_adm_stats_t *sp)
234 239 {
235 240 struct fmd_rpc_modstat rms;
236 241 enum clnt_stat cs;
237 242 uint_t retries = 0;
238 243
239 244 if (sp == NULL)
240 245 return (fmd_adm_set_errno(ap, EINVAL));
241 246
242 247 bzero(&rms, sizeof (rms)); /* tell xdr to allocate memory for us */
243 248
244 249 do {
245 250 if (name != NULL)
246 251 cs = fmd_adm_modcstat_1((char *)name, &rms,
247 252 ap->adm_clnt);
248 253 else
249 254 cs = fmd_adm_modgstat_1(&rms, ap->adm_clnt);
250 255 } while (fmd_adm_retry(ap, cs, &retries));
251 256
252 257 if (cs != RPC_SUCCESS)
253 258 return (fmd_adm_set_errno(ap, EPROTO));
254 259
255 260 if (rms.rms_err != 0) {
256 261 xdr_free(xdr_fmd_rpc_modstat, (char *)&rms);
257 262 return (fmd_adm_set_svcerr(ap, rms.rms_err));
258 263 }
259 264
260 265 sp->ams_buf = rms.rms_buf.rms_buf_val;
261 266 sp->ams_len = rms.rms_buf.rms_buf_len;
262 267
263 268 if (sp->ams_len != 0) {
264 269 qsort(sp->ams_buf, sp->ams_len,
265 270 sizeof (fmd_stat_t), fmd_adm_stats_cmp);
266 271 }
267 272
268 273 return (0);
269 274 }
270 275
271 276 int
272 277 fmd_adm_stats_free(fmd_adm_t *ap, fmd_adm_stats_t *sp)
273 278 {
274 279 struct fmd_rpc_modstat rms;
275 280
276 281 if (sp == NULL)
277 282 return (fmd_adm_set_errno(ap, EINVAL));
278 283
279 284 rms.rms_buf.rms_buf_val = sp->ams_buf;
280 285 rms.rms_buf.rms_buf_len = sp->ams_len;
281 286 rms.rms_err = 0;
282 287
283 288 xdr_free(xdr_fmd_rpc_modstat, (char *)&rms);
284 289 bzero(sp, sizeof (fmd_adm_stats_t));
285 290
286 291 return (0);
287 292 }
288 293
289 294 static int
290 295 fmd_adm_module_cmp(const void *lp, const void *rp)
291 296 {
292 297 return (strcmp((*(struct fmd_rpc_modinfo **)lp)->rmi_name,
293 298 (*(struct fmd_rpc_modinfo **)rp)->rmi_name));
294 299 }
295 300
296 301 int
297 302 fmd_adm_module_iter(fmd_adm_t *ap, fmd_adm_module_f *func, void *arg)
298 303 {
299 304 struct fmd_rpc_modinfo *rmi, **rms, **rmp;
300 305 struct fmd_rpc_modlist rml;
301 306 fmd_adm_modinfo_t ami;
302 307 enum clnt_stat cs;
303 308 uint_t retries = 0;
304 309
305 310 bzero(&rml, sizeof (rml)); /* tell xdr to allocate memory for us */
306 311
307 312 do {
308 313 cs = fmd_adm_modinfo_1(&rml, ap->adm_clnt);
309 314 } while (fmd_adm_retry(ap, cs, &retries));
310 315
311 316 if (cs != RPC_SUCCESS)
312 317 return (fmd_adm_set_errno(ap, EPROTO));
313 318
314 319 if (rml.rml_err != 0 || rml.rml_len == 0) {
315 320 xdr_free(xdr_fmd_rpc_modlist, (char *)&rml);
316 321 return (fmd_adm_set_svcerr(ap, rml.rml_err));
317 322 }
318 323
319 324 if ((rms = rmp = malloc(sizeof (void *) * rml.rml_len)) == NULL) {
320 325 xdr_free(xdr_fmd_rpc_modlist, (char *)&rml);
321 326 return (fmd_adm_set_errno(ap, EAGAIN));
322 327 }
323 328
324 329 for (rmi = rml.rml_list; rmi != NULL; rmi = rmi->rmi_next)
325 330 *rmp++ = rmi; /* store copy of pointer in array for sorting */
326 331
327 332 qsort(rms, rml.rml_len, sizeof (void *), fmd_adm_module_cmp);
328 333
329 334 for (rmp = rms; rmp < rms + rml.rml_len; rmp++) {
330 335 rmi = *rmp;
331 336
332 337 ami.ami_name = rmi->rmi_name;
333 338 ami.ami_desc = rmi->rmi_desc;
334 339 ami.ami_vers = rmi->rmi_vers;
335 340 ami.ami_flags = 0;
336 341
337 342 if (rmi->rmi_faulty)
338 343 ami.ami_flags |= FMD_ADM_MOD_FAILED;
339 344
340 345 if (func(&ami, arg) != 0)
341 346 break;
342 347 }
343 348
344 349 free(rms);
345 350 xdr_free(xdr_fmd_rpc_modlist, (char *)&rml);
346 351 return (0);
347 352 }
348 353
349 354 int
350 355 fmd_adm_module_load(fmd_adm_t *ap, const char *path)
351 356 {
352 357 char *str = (char *)path;
353 358 int err;
354 359 enum clnt_stat cs;
355 360 uint_t retries = 0;
356 361
357 362 if (path == NULL || path[0] != '/')
358 363 return (fmd_adm_set_errno(ap, EINVAL));
359 364
360 365 do {
361 366 cs = fmd_adm_modload_1(str, &err, ap->adm_clnt);
362 367 } while (fmd_adm_retry(ap, cs, &retries));
363 368
364 369 if (cs != RPC_SUCCESS)
365 370 return (fmd_adm_set_errno(ap, EPROTO));
366 371
367 372 return (fmd_adm_set_svcerr(ap, err));
368 373 }
369 374
370 375 int
371 376 fmd_adm_module_unload(fmd_adm_t *ap, const char *name)
372 377 {
373 378 char *str = (char *)name;
374 379 int err;
375 380 enum clnt_stat cs;
376 381 uint_t retries = 0;
377 382
378 383 if (name == NULL || strchr(name, '/') != NULL)
379 384 return (fmd_adm_set_errno(ap, EINVAL));
380 385
381 386 do {
382 387 cs = fmd_adm_modunload_1(str, &err, ap->adm_clnt);
383 388 } while (fmd_adm_retry(ap, cs, &retries));
384 389
385 390 if (cs != RPC_SUCCESS)
386 391 return (fmd_adm_set_errno(ap, EPROTO));
387 392
388 393 return (fmd_adm_set_svcerr(ap, err));
389 394 }
390 395
391 396 int
392 397 fmd_adm_module_reset(fmd_adm_t *ap, const char *name)
393 398 {
394 399 char *str = (char *)name;
395 400 int err;
396 401 enum clnt_stat cs;
397 402 uint_t retries = 0;
398 403
399 404 if (name == NULL || strchr(name, '/') != NULL)
400 405 return (fmd_adm_set_errno(ap, EINVAL));
401 406
402 407 do {
403 408 cs = fmd_adm_modreset_1(str, &err, ap->adm_clnt);
404 409 } while (fmd_adm_retry(ap, cs, &retries));
405 410
406 411 if (cs != RPC_SUCCESS)
407 412 return (fmd_adm_set_errno(ap, EPROTO));
408 413
409 414 return (fmd_adm_set_svcerr(ap, err));
410 415 }
411 416
412 417 int
413 418 fmd_adm_module_gc(fmd_adm_t *ap, const char *name)
414 419 {
415 420 char *str = (char *)name;
416 421 int err;
417 422 enum clnt_stat cs;
418 423 uint_t retries = 0;
419 424
420 425 if (name == NULL || strchr(name, '/') != NULL)
421 426 return (fmd_adm_set_errno(ap, EINVAL));
422 427
423 428 do {
424 429 cs = fmd_adm_modgc_1(str, &err, ap->adm_clnt);
425 430 } while (fmd_adm_retry(ap, cs, &retries));
426 431
427 432 if (cs != RPC_SUCCESS)
428 433 return (fmd_adm_set_errno(ap, EPROTO));
429 434
430 435 return (fmd_adm_set_svcerr(ap, err));
431 436 }
432 437
433 438 int
434 439 fmd_adm_module_stats(fmd_adm_t *ap, const char *name, fmd_adm_stats_t *sp)
435 440 {
436 441 struct fmd_rpc_modstat rms;
437 442 enum clnt_stat cs;
438 443 uint_t retries = 0;
439 444
440 445 if (name == NULL || sp == NULL)
441 446 return (fmd_adm_set_errno(ap, EINVAL));
442 447
443 448 bzero(&rms, sizeof (rms)); /* tell xdr to allocate memory for us */
444 449
445 450 do {
446 451 cs = fmd_adm_moddstat_1((char *)name, &rms, ap->adm_clnt);
447 452 } while (fmd_adm_retry(ap, cs, &retries));
448 453
449 454 if (cs != RPC_SUCCESS)
450 455 return (fmd_adm_set_errno(ap, EPROTO));
451 456
452 457 if (rms.rms_err != 0) {
453 458 xdr_free(xdr_fmd_rpc_modstat, (char *)&rms);
454 459 return (fmd_adm_set_svcerr(ap, rms.rms_err));
455 460 }
456 461
457 462 sp->ams_buf = rms.rms_buf.rms_buf_val;
458 463 sp->ams_len = rms.rms_buf.rms_buf_len;
459 464
460 465 return (0);
461 466 }
462 467
463 468 int
464 469 fmd_adm_rsrc_count(fmd_adm_t *ap, int all, uint32_t *rcp)
465 470 {
466 471 struct fmd_rpc_rsrclist rrl;
467 472 enum clnt_stat cs;
468 473 uint_t retries = 0;
469 474
470 475 if (rcp == NULL)
471 476 return (fmd_adm_set_errno(ap, EINVAL));
472 477
473 478 bzero(&rrl, sizeof (rrl)); /* tell xdr to allocate memory for us */
474 479
475 480 do {
476 481 cs = fmd_adm_rsrclist_1(all, &rrl, ap->adm_clnt);
477 482 } while (fmd_adm_retry(ap, cs, &retries));
478 483
479 484 if (cs != RPC_SUCCESS)
480 485 return (fmd_adm_set_errno(ap, EPROTO));
481 486
482 487 if (rrl.rrl_err != 0) {
483 488 xdr_free(xdr_fmd_rpc_rsrclist, (char *)&rrl);
484 489 return (fmd_adm_set_svcerr(ap, rrl.rrl_err));
485 490 }
486 491
487 492 *rcp = rrl.rrl_cnt;
488 493 xdr_free(xdr_fmd_rpc_rsrclist, (char *)&rrl);
489 494 return (0);
490 495 }
491 496
492 497 static int
493 498 fmd_adm_rsrc_cmp(const void *lp, const void *rp)
494 499 {
495 500 return (strcmp(*(char **)lp, *(char **)rp));
496 501 }
497 502
498 503 int
499 504 fmd_adm_rsrc_iter(fmd_adm_t *ap, int all, fmd_adm_rsrc_f *func, void *arg)
500 505 {
501 506 struct fmd_rpc_rsrclist rrl;
502 507 struct fmd_rpc_rsrcinfo rri;
503 508 fmd_adm_rsrcinfo_t ari;
504 509 char **fmris, *p;
505 510 int i, rv;
506 511 enum clnt_stat cs;
507 512 uint_t retries = 0;
508 513
509 514 bzero(&rrl, sizeof (rrl)); /* tell xdr to allocate memory for us */
510 515
511 516 do {
512 517 cs = fmd_adm_rsrclist_1(all, &rrl, ap->adm_clnt);
513 518 } while (fmd_adm_retry(ap, cs, &retries));
514 519
515 520 if (cs != RPC_SUCCESS)
516 521 return (fmd_adm_set_errno(ap, EPROTO));
517 522
518 523 if (rrl.rrl_err != 0) {
519 524 xdr_free(xdr_fmd_rpc_rsrclist, (char *)&rrl);
520 525 return (fmd_adm_set_svcerr(ap, rrl.rrl_err));
521 526 }
522 527
523 528 if ((fmris = malloc(sizeof (char *) * rrl.rrl_cnt)) == NULL) {
524 529 xdr_free(xdr_fmd_rpc_rsrclist, (char *)&rrl);
525 530 return (fmd_adm_set_errno(ap, EAGAIN));
526 531 }
527 532
528 533 /*
529 534 * The fmd_adm_rsrclist_1 request returns an opaque XDR buffer that is
530 535 * a string table of FMRIs (e.g. "fmriA\0fmriB\0...") where rrl_cnt is
531 536 * the number of strings in the table and rrl_buf_val is its address.
532 537 * We construct an array of pointers into the string table and sort it.
533 538 */
534 539 p = rrl.rrl_buf.rrl_buf_val;
535 540
536 541 for (i = 0; i < rrl.rrl_cnt; i++, p += strlen(p) + 1)
537 542 fmris[i] = p; /* store fmri pointer in array for sorting */
538 543
539 544 qsort(fmris, rrl.rrl_cnt, sizeof (char *), fmd_adm_rsrc_cmp);
540 545
541 546 /*
542 547 * For each FMRI in the resource cache snapshot, use fmd_adm_rsrcinfo_1
543 548 * to get more information and the invoke the callback function. If
544 549 * FMD_ADM_ERR_RSRCSRCH is returned, the FMRI has been purged from the
545 550 * cache since our snapshot: this error is therefore silently ignored.
546 551 */
547 552 for (i = 0; i < rrl.rrl_cnt; i++) {
548 553 bzero(&rri, sizeof (rri));
549 554
550 555 retries = 0;
551 556 do {
552 557 cs = fmd_adm_rsrcinfo_1(fmris[i], &rri, ap->adm_clnt);
553 558 } while (fmd_adm_retry(ap, cs, &retries));
554 559
555 560 if (cs != RPC_SUCCESS) {
556 561 free(fmris);
557 562 xdr_free(xdr_fmd_rpc_rsrclist, (char *)&rrl);
558 563 return (fmd_adm_set_errno(ap, EPROTO));
559 564 }
560 565
561 566 if (rri.rri_err != 0 && rri.rri_err != FMD_ADM_ERR_RSRCSRCH) {
562 567 xdr_free(xdr_fmd_rpc_rsrcinfo, (char *)&rri);
563 568 free(fmris);
564 569 xdr_free(xdr_fmd_rpc_rsrclist, (char *)&rrl);
565 570 return (fmd_adm_set_svcerr(ap, rri.rri_err));
566 571 }
567 572
568 573 if (rri.rri_err == FMD_ADM_ERR_RSRCSRCH) {
569 574 xdr_free(xdr_fmd_rpc_rsrcinfo, (char *)&rri);
570 575 continue;
571 576 }
572 577
573 578 ari.ari_fmri = rri.rri_fmri;
574 579 ari.ari_uuid = rri.rri_uuid;
575 580 ari.ari_case = rri.rri_case;
576 581 ari.ari_flags = 0;
577 582
578 583 if (rri.rri_faulty)
579 584 ari.ari_flags |= FMD_ADM_RSRC_FAULTY;
580 585 if (rri.rri_unusable)
581 586 ari.ari_flags |= FMD_ADM_RSRC_UNUSABLE;
582 587 if (rri.rri_invisible)
583 588 ari.ari_flags |= FMD_ADM_RSRC_INVISIBLE;
584 589
585 590 rv = func(&ari, arg);
586 591 xdr_free(xdr_fmd_rpc_rsrcinfo, (char *)&rri);
587 592
588 593 if (rv != 0)
589 594 break;
590 595 }
591 596
592 597 free(fmris);
593 598 xdr_free(xdr_fmd_rpc_rsrclist, (char *)&rrl);
594 599 return (0);
595 600 }
596 601
597 602 int
598 603 fmd_adm_rsrc_flush(fmd_adm_t *ap, const char *fmri)
599 604 {
600 605 char *str = (char *)fmri;
601 606 int err;
602 607 enum clnt_stat cs;
603 608 uint_t retries = 0;
604 609
605 610 if (fmri == NULL)
606 611 return (fmd_adm_set_errno(ap, EINVAL));
607 612
608 613 do {
609 614 cs = fmd_adm_rsrcflush_1(str, &err, ap->adm_clnt);
610 615 } while (fmd_adm_retry(ap, cs, &retries));
611 616
612 617 if (cs != RPC_SUCCESS)
613 618 return (fmd_adm_set_errno(ap, EPROTO));
614 619
615 620 return (fmd_adm_set_svcerr(ap, err));
616 621 }
617 622
618 623 int
619 624 fmd_adm_rsrc_repaired(fmd_adm_t *ap, const char *fmri)
620 625 {
621 626 char *str = (char *)fmri;
622 627 int err;
623 628 enum clnt_stat cs;
624 629 uint_t retries = 0;
625 630
626 631 if (fmri == NULL)
627 632 return (fmd_adm_set_errno(ap, EINVAL));
628 633
629 634 do {
630 635 cs = fmd_adm_rsrcrepaired_1(str, &err, ap->adm_clnt);
631 636 } while (fmd_adm_retry(ap, cs, &retries));
632 637
633 638 if (cs != RPC_SUCCESS)
634 639 return (fmd_adm_set_errno(ap, EPROTO));
635 640
636 641 return (fmd_adm_set_svcerr(ap, err));
637 642 }
638 643
639 644 int
640 645 fmd_adm_rsrc_replaced(fmd_adm_t *ap, const char *fmri)
641 646 {
642 647 char *str = (char *)fmri;
643 648 int err;
644 649 enum clnt_stat cs;
645 650 uint_t retries = 0;
646 651
647 652 if (fmri == NULL)
648 653 return (fmd_adm_set_errno(ap, EINVAL));
649 654
650 655 do {
651 656 cs = fmd_adm_rsrcreplaced_1(str, &err, ap->adm_clnt);
652 657 } while (fmd_adm_retry(ap, cs, &retries));
653 658
654 659 if (cs != RPC_SUCCESS)
655 660 return (fmd_adm_set_errno(ap, EPROTO));
656 661
657 662 return (fmd_adm_set_svcerr(ap, err));
658 663 }
659 664
660 665 int
661 666 fmd_adm_rsrc_acquit(fmd_adm_t *ap, const char *fmri, const char *uuid)
662 667 {
663 668 char *str = (char *)fmri;
664 669 char *str2 = (char *)uuid;
665 670 int err;
666 671 enum clnt_stat cs;
667 672 uint_t retries = 0;
668 673
669 674 if (fmri == NULL)
670 675 return (fmd_adm_set_errno(ap, EINVAL));
671 676
672 677 do {
673 678 cs = fmd_adm_rsrcacquit_1(str, str2, &err, ap->adm_clnt);
674 679 } while (fmd_adm_retry(ap, cs, &retries));
675 680
676 681 if (cs != RPC_SUCCESS)
677 682 return (fmd_adm_set_errno(ap, EPROTO));
678 683
679 684 return (fmd_adm_set_svcerr(ap, err));
680 685 }
681 686
682 687 int
683 688 fmd_adm_case_repair(fmd_adm_t *ap, const char *uuid)
684 689 {
685 690 char *str = (char *)uuid;
686 691 int err;
687 692 enum clnt_stat cs;
688 693 uint_t retries = 0;
689 694
690 695 if (uuid == NULL)
691 696 return (fmd_adm_set_errno(ap, EINVAL));
692 697
693 698 do {
694 699 cs = fmd_adm_caserepair_1(str, &err, ap->adm_clnt);
695 700 } while (fmd_adm_retry(ap, cs, &retries));
696 701
697 702 if (cs != RPC_SUCCESS)
698 703 return (fmd_adm_set_errno(ap, EPROTO));
699 704
700 705 return (fmd_adm_set_svcerr(ap, err));
701 706 }
702 707
703 708 int
704 709 fmd_adm_case_acquit(fmd_adm_t *ap, const char *uuid)
705 710 {
706 711 char *str = (char *)uuid;
707 712 int err;
708 713 enum clnt_stat cs;
709 714 uint_t retries = 0;
710 715
711 716 if (uuid == NULL)
712 717 return (fmd_adm_set_errno(ap, EINVAL));
713 718
714 719 do {
715 720 cs = fmd_adm_caseacquit_1(str, &err, ap->adm_clnt);
716 721 } while (fmd_adm_retry(ap, cs, &retries));
717 722
718 723 if (cs != RPC_SUCCESS)
719 724 return (fmd_adm_set_errno(ap, EPROTO));
720 725
721 726 return (fmd_adm_set_svcerr(ap, err));
722 727 }
723 728
724 729 static int
725 730 fmd_adm_case_cmp(const void *lp, const void *rp)
726 731 {
727 732 return (strcmp(*(char **)lp, *(char **)rp));
728 733 }
729 734
730 735 static int
731 736 fmd_adm_case_one(fmd_adm_caseinfo_t *acp, const char *url_token,
732 737 fmd_adm_case_f *func, void *arg)
733 738 {
734 739 char *p, *urlcode, *dict, *olang;
735 740 const char *url;
736 741 size_t len;
737 742
738 743 if ((p = strchr(acp->aci_code, '-')) == NULL ||
739 744 p == acp->aci_code) {
740 745 acp->aci_url = NULL;
741 746 } else {
742 747 dict = alloca((size_t)(p - acp->aci_code) + 1);
743 748 (void) strncpy(dict, acp->aci_code,
744 749 (size_t)(p - acp->aci_code));
745 750 dict[(size_t)(p - acp->aci_code)] = '\0';
746 751
747 752 /*
748 753 * If we're given a token to use in looking up the URL, try
749 754 * to use it. Otherwise, or if we don't find it that way,
750 755 * use the fallback.
751 756 */
752 757 if (url_token == NULL) {
753 758 url = _url_fallback;
754 759 } else if ((url = dgettext(dict, url_token)) == url_token) {
755 760 /*
756 761 * We didn't find a translation in the
757 762 * dictionary for the current language. Fall
758 763 * back to C and try again.
759 764 */
760 765 olang = setlocale(LC_MESSAGES, NULL);
761 766 (void) setlocale(LC_MESSAGES, "C");
762 767 if ((url = dgettext(dict, url_token)) == url_token)
763 768 url = _url_fallback;
764 769 (void) setlocale(LC_MESSAGES, olang);
765 770 }
766 771 len = strlen(url);
767 772 if (url[len - 1] == '/') {
768 773 len += strlen(acp->aci_code) + 1;
769 774 urlcode = alloca(len);
770 775 (void) snprintf(urlcode, len, "%s%s", url,
771 776 acp->aci_code);
772 777 } else {
773 778 urlcode = (char *)url;
774 779 }
775 780 acp->aci_url = urlcode;
776 781 }
777 782
778 783 return (func(acp, arg));
779 784 }
780 785
781 786 /*
782 787 * Our approach to cases is the same as for resources: we first obtain a
783 788 * list of UUIDs, sort them, then obtain the case information for each.
784 789 */
785 790 int
786 791 fmd_adm_case_iter(fmd_adm_t *ap, const char *url_token, fmd_adm_case_f *func,
787 792 void *arg)
788 793 {
789 794 struct fmd_rpc_caselist rcl;
790 795 struct fmd_rpc_caseinfo rci;
791 796 fmd_adm_caseinfo_t aci;
792 797 char **uuids, *p;
793 798 int i, rv;
794 799 enum clnt_stat cs;
795 800 uint_t retries = 0;
796 801
797 802 bzero(&rcl, sizeof (rcl)); /* tell xdr to allocate memory for us */
798 803
799 804 do {
800 805 cs = fmd_adm_caselist_1(&rcl, ap->adm_clnt);
801 806 } while (fmd_adm_retry(ap, cs, &retries));
802 807
803 808 if (cs != RPC_SUCCESS)
804 809 return (fmd_adm_set_errno(ap, EPROTO));
805 810
806 811 if (rcl.rcl_err != 0) {
807 812 xdr_free(xdr_fmd_rpc_caselist, (char *)&rcl);
808 813 return (fmd_adm_set_svcerr(ap, rcl.rcl_err));
809 814 }
810 815
811 816 if ((uuids = malloc(sizeof (char *) * rcl.rcl_cnt)) == NULL) {
812 817 xdr_free(xdr_fmd_rpc_caselist, (char *)&rcl);
813 818 return (fmd_adm_set_errno(ap, EAGAIN));
814 819 }
815 820
816 821 p = rcl.rcl_buf.rcl_buf_val;
817 822
818 823 for (i = 0; i < rcl.rcl_cnt; i++, p += strlen(p) + 1)
819 824 uuids[i] = p;
820 825
821 826 qsort(uuids, rcl.rcl_cnt, sizeof (char *), fmd_adm_case_cmp);
822 827
823 828 for (i = 0; i < rcl.rcl_cnt; i++) {
824 829 bzero(&rci, sizeof (rci));
825 830
826 831 retries = 0;
827 832 do {
828 833 cs = fmd_adm_caseinfo_1(uuids[i], &rci, ap->adm_clnt);
829 834 } while (fmd_adm_retry(ap, cs, &retries));
830 835
831 836 if (cs != RPC_SUCCESS) {
832 837 free(uuids);
833 838 xdr_free(xdr_fmd_rpc_caselist, (char *)&rcl);
834 839 return (fmd_adm_set_errno(ap, EPROTO));
835 840 }
836 841
837 842 if (rci.rci_err != 0 && rci.rci_err != FMD_ADM_ERR_CASESRCH) {
838 843 xdr_free(xdr_fmd_rpc_caseinfo, (char *)&rci);
839 844 free(uuids);
840 845 xdr_free(xdr_fmd_rpc_caselist, (char *)&rcl);
841 846 return (fmd_adm_set_svcerr(ap, rci.rci_err));
842 847 }
843 848
844 849 if (rci.rci_err == FMD_ADM_ERR_CASESRCH) {
845 850 xdr_free(xdr_fmd_rpc_caseinfo, (char *)&rci);
846 851 continue;
847 852 }
848 853
849 854 bzero(&aci, sizeof (aci));
850 855
851 856 if ((rv = nvlist_unpack(rci.rci_evbuf.rci_evbuf_val,
852 857 rci.rci_evbuf.rci_evbuf_len, &aci.aci_event, 0)) != 0) {
853 858 xdr_free(xdr_fmd_rpc_caseinfo, (char *)&rci);
854 859 free(uuids);
855 860 xdr_free(xdr_fmd_rpc_caselist, (char *)&rcl);
856 861 return (fmd_adm_set_errno(ap, rv));
857 862 }
858 863
859 864 if ((rv = nvlist_lookup_string(aci.aci_event, FM_SUSPECT_UUID,
860 865 (char **)&aci.aci_uuid)) != 0) {
861 866 xdr_free(xdr_fmd_rpc_caseinfo, (char *)&rci);
862 867 free(uuids);
863 868 xdr_free(xdr_fmd_rpc_caselist, (char *)&rcl);
864 869 nvlist_free(aci.aci_event);
865 870 return (fmd_adm_set_errno(ap, rv));
|
↓ open down ↓ |
820 lines elided |
↑ open up ↑ |
866 871 }
867 872 if ((rv = nvlist_lookup_string(aci.aci_event,
868 873 FM_SUSPECT_DIAG_CODE, (char **)&aci.aci_code)) != 0) {
869 874 xdr_free(xdr_fmd_rpc_caseinfo, (char *)&rci);
870 875 free(uuids);
871 876 xdr_free(xdr_fmd_rpc_caselist, (char *)&rcl);
872 877 nvlist_free(aci.aci_event);
873 878 return (fmd_adm_set_errno(ap, rv));
874 879 }
875 880
881 + /*
882 + * Don't treat absence of type, severity, or description as
883 + * fatal error.
884 + */
885 + (void) nvlist_lookup_string(aci.aci_event, FM_SUSPECT_TYPE,
886 + (char **)&aci.aci_type);
887 + (void) nvlist_lookup_string(aci.aci_event, FM_SUSPECT_SEVERITY,
888 + (char **)&aci.aci_severity);
889 + (void) nvlist_lookup_string(aci.aci_event, FM_SUSPECT_DESC,
890 + (char **)&aci.aci_desc);
891 +
876 892 rv = fmd_adm_case_one(&aci, url_token, func, arg);
877 893
878 894 xdr_free(xdr_fmd_rpc_caseinfo, (char *)&rci);
879 895 nvlist_free(aci.aci_event);
880 896
881 897 if (rv != 0)
882 898 break;
883 899 }
884 900
885 901 free(uuids);
886 902 xdr_free(xdr_fmd_rpc_caselist, (char *)&rcl);
887 903 return (0);
888 904 }
889 905
890 906 static int
891 907 fmd_adm_serd_cmp(const void *lp, const void *rp)
892 908 {
893 909 return (strcmp(*(char **)lp, *(char **)rp));
894 910 }
895 911
896 912 int
897 913 fmd_adm_serd_iter(fmd_adm_t *ap, const char *name,
898 914 fmd_adm_serd_f *func, void *arg)
899 915 {
900 916 struct fmd_rpc_serdlist rsl;
901 917 struct fmd_rpc_serdinfo rsi;
902 918 char **serds, *p;
903 919 fmd_adm_serdinfo_t asi;
904 920 enum clnt_stat cs;
905 921 uint_t retries = 0;
906 922 int i, rv;
907 923
908 924 bzero(&rsl, sizeof (rsl)); /* tell xdr to allocate memory for us */
909 925
910 926 do {
911 927 cs = fmd_adm_serdlist_1((char *)name, &rsl, ap->adm_clnt);
912 928 } while (fmd_adm_retry(ap, cs, &retries));
913 929
914 930 if (cs != RPC_SUCCESS)
915 931 return (fmd_adm_set_errno(ap, EPROTO));
916 932
917 933 if (rsl.rsl_err != 0 || rsl.rsl_len == 0) {
918 934 xdr_free(xdr_fmd_rpc_serdlist, (char *)&rsl);
919 935 return (fmd_adm_set_svcerr(ap, rsl.rsl_err));
920 936 }
921 937
922 938 if ((serds = malloc(sizeof (char *) * rsl.rsl_cnt)) == NULL) {
923 939 xdr_free(xdr_fmd_rpc_serdlist, (char *)&rsl);
924 940 return (fmd_adm_set_errno(ap, EAGAIN));
925 941 }
926 942
927 943 p = rsl.rsl_buf.rsl_buf_val;
928 944
929 945 for (i = 0; i < rsl.rsl_cnt; i++, p += strlen(p) + 1)
930 946 serds[i] = p;
931 947
932 948 qsort(serds, rsl.rsl_cnt, sizeof (char *), fmd_adm_serd_cmp);
933 949
934 950 for (i = 0; i < rsl.rsl_cnt; i++) {
935 951 bzero(&rsi, sizeof (rsi));
936 952
937 953 retries = 0;
938 954 do {
939 955 cs = fmd_adm_serdinfo_1((char *)name, serds[i], &rsi,
940 956 ap->adm_clnt);
941 957 } while (fmd_adm_retry(ap, cs, &retries));
942 958
943 959 if (cs != RPC_SUCCESS) {
944 960 free(serds);
945 961 xdr_free(xdr_fmd_rpc_serdlist, (char *)&rsl);
946 962 return (fmd_adm_set_errno(ap, EPROTO));
947 963 }
948 964
949 965 if (rsi.rsi_err != 0 && rsi.rsi_err != FMD_ADM_ERR_SERDSRCH) {
950 966 free(serds);
951 967 xdr_free(xdr_fmd_rpc_serdinfo, (char *)&rsi);
952 968 xdr_free(xdr_fmd_rpc_serdlist, (char *)&rsl);
953 969 return (fmd_adm_set_svcerr(ap, rsi.rsi_err));
954 970 }
955 971
956 972 if (rsi.rsi_err == FMD_ADM_ERR_SERDSRCH) {
957 973 xdr_free(xdr_fmd_rpc_serdinfo, (char *)&rsi);
958 974 continue;
959 975 }
960 976
961 977 bzero(&asi, sizeof (asi));
962 978
963 979 asi.asi_name = rsi.rsi_name;
964 980 asi.asi_delta = rsi.rsi_delta;
965 981 asi.asi_n = rsi.rsi_n;
966 982 asi.asi_t = rsi.rsi_t;
967 983 asi.asi_count = rsi.rsi_count;
968 984 asi.asi_flags = 0;
969 985
970 986 if (rsi.rsi_fired)
971 987 asi.asi_flags |= FMD_ADM_SERD_FIRED;
972 988
973 989 rv = func(&asi, arg);
974 990
975 991 xdr_free(xdr_fmd_rpc_serdinfo, (char *)&rsi);
976 992
977 993 if (rv != 0)
978 994 break;
979 995 }
980 996
981 997 free(serds);
982 998 xdr_free(xdr_fmd_rpc_serdlist, (char *)&rsl);
983 999 return (0);
984 1000 }
985 1001
986 1002 int
987 1003 fmd_adm_serd_reset(fmd_adm_t *ap, const char *mod, const char *name)
988 1004 {
989 1005 char *s1 = (char *)mod, *s2 = (char *)name;
990 1006 int err;
991 1007 enum clnt_stat cs;
992 1008 uint_t retries = 0;
993 1009
994 1010 if (mod == NULL || name == NULL || strchr(mod, '/') != NULL)
995 1011 return (fmd_adm_set_errno(ap, EINVAL));
996 1012
997 1013 do {
998 1014 cs = fmd_adm_serdreset_1(s1, s2, &err, ap->adm_clnt);
999 1015 } while (fmd_adm_retry(ap, cs, &retries));
1000 1016
1001 1017 if (cs != RPC_SUCCESS)
1002 1018 return (fmd_adm_set_errno(ap, EPROTO));
1003 1019
1004 1020 return (fmd_adm_set_svcerr(ap, err));
1005 1021 }
1006 1022
1007 1023 int
1008 1024 fmd_adm_xprt_iter(fmd_adm_t *ap, fmd_adm_xprt_f *func, void *arg)
1009 1025 {
1010 1026 struct fmd_rpc_xprtlist rxl;
1011 1027 uint_t i;
1012 1028 enum clnt_stat cs;
1013 1029 uint_t retries = 0;
1014 1030
1015 1031 bzero(&rxl, sizeof (rxl)); /* tell xdr to allocate memory for us */
1016 1032
1017 1033 do {
1018 1034 cs = fmd_adm_xprtlist_1(&rxl, ap->adm_clnt);
1019 1035 } while (fmd_adm_retry(ap, cs, &retries));
1020 1036
1021 1037 if (cs != RPC_SUCCESS)
1022 1038 return (fmd_adm_set_errno(ap, EPROTO));
1023 1039
1024 1040 if (rxl.rxl_err != 0) {
1025 1041 xdr_free(xdr_fmd_rpc_xprtlist, (char *)&rxl);
1026 1042 return (fmd_adm_set_svcerr(ap, rxl.rxl_err));
1027 1043 }
1028 1044
1029 1045 for (i = 0; i < rxl.rxl_len; i++)
1030 1046 func(rxl.rxl_buf.rxl_buf_val[i], arg);
1031 1047
1032 1048 xdr_free(xdr_fmd_rpc_xprtlist, (char *)&rxl);
1033 1049 return (0);
1034 1050 }
1035 1051
1036 1052 int
1037 1053 fmd_adm_xprt_stats(fmd_adm_t *ap, id_t id, fmd_adm_stats_t *sp)
1038 1054 {
1039 1055 struct fmd_rpc_modstat rms;
1040 1056 enum clnt_stat cs;
1041 1057 uint_t retries = 0;
1042 1058
1043 1059 if (sp == NULL)
1044 1060 return (fmd_adm_set_errno(ap, EINVAL));
1045 1061
1046 1062 bzero(&rms, sizeof (rms)); /* tell xdr to allocate memory for us */
1047 1063
1048 1064 do {
1049 1065 cs = fmd_adm_xprtstat_1(id, &rms, ap->adm_clnt);
1050 1066 } while (fmd_adm_retry(ap, cs, &retries));
1051 1067
1052 1068 if (cs != RPC_SUCCESS)
1053 1069 return (fmd_adm_set_errno(ap, EPROTO));
1054 1070
1055 1071 if (rms.rms_err != 0) {
1056 1072 xdr_free(xdr_fmd_rpc_modstat, (char *)&rms);
1057 1073 return (fmd_adm_set_svcerr(ap, rms.rms_err));
1058 1074 }
1059 1075
1060 1076 sp->ams_buf = rms.rms_buf.rms_buf_val;
1061 1077 sp->ams_len = rms.rms_buf.rms_buf_len;
1062 1078
1063 1079 return (0);
1064 1080 }
1065 1081
1066 1082 int
1067 1083 fmd_adm_log_rotate(fmd_adm_t *ap, const char *log)
1068 1084 {
1069 1085 int err;
1070 1086 enum clnt_stat cs;
1071 1087 uint_t retries = 0;
1072 1088
1073 1089 if (log == NULL)
1074 1090 return (fmd_adm_set_errno(ap, EINVAL));
1075 1091
1076 1092 do {
1077 1093 cs = fmd_adm_logrotate_1((char *)log, &err, ap->adm_clnt);
1078 1094 } while (fmd_adm_retry(ap, cs, &retries));
1079 1095
1080 1096 if (cs != RPC_SUCCESS)
1081 1097 return (fmd_adm_set_errno(ap, EPROTO));
1082 1098
1083 1099 return (fmd_adm_set_svcerr(ap, err));
1084 1100 }
1085 1101
1086 1102 /*
1087 1103 * Custom XDR routine for our API structure fmd_stat_t. This function must
1088 1104 * match the definition of fmd_stat_t in <fm/fmd_api.h> and must also match
1089 1105 * the corresponding routine in usr/src/cmd/fm/fmd/common/fmd_rpc_adm.c.
1090 1106 */
1091 1107 bool_t
|
↓ open down ↓ |
206 lines elided |
↑ open up ↑ |
1092 1108 xdr_fmd_stat(XDR *xp, fmd_stat_t *sp)
1093 1109 {
1094 1110 bool_t rv = TRUE;
1095 1111
1096 1112 rv &= xdr_opaque(xp, sp->fmds_name, sizeof (sp->fmds_name));
1097 1113 rv &= xdr_u_int(xp, &sp->fmds_type);
1098 1114 rv &= xdr_opaque(xp, sp->fmds_desc, sizeof (sp->fmds_desc));
1099 1115
1100 1116 switch (sp->fmds_type) {
1101 1117 case FMD_TYPE_BOOL:
1102 - rv &= xdr_int(xp, &sp->fmds_value.bool);
1118 + rv &= xdr_int(xp, &sp->fmds_value.b);
1103 1119 break;
1104 1120 case FMD_TYPE_INT32:
1105 1121 rv &= xdr_int32_t(xp, &sp->fmds_value.i32);
1106 1122 break;
1107 1123 case FMD_TYPE_UINT32:
1108 1124 rv &= xdr_uint32_t(xp, &sp->fmds_value.ui32);
1109 1125 break;
1110 1126 case FMD_TYPE_INT64:
1111 1127 rv &= xdr_int64_t(xp, &sp->fmds_value.i64);
1112 1128 break;
1113 1129 case FMD_TYPE_UINT64:
1114 1130 case FMD_TYPE_TIME:
1115 1131 case FMD_TYPE_SIZE:
1116 1132 rv &= xdr_uint64_t(xp, &sp->fmds_value.ui64);
1117 1133 break;
1118 1134 case FMD_TYPE_STRING:
1119 1135 rv &= xdr_string(xp, &sp->fmds_value.str, ~0);
1120 1136 break;
1121 1137 }
1122 1138
1123 1139 return (rv);
1124 1140 }
|
↓ open down ↓ |
12 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX