Print this page
OS-279 #pragma D option zone= does not work on installed, halted zones
OS-208 DTrace needs to use zone_did to match zone-limited enablings
INTRO-118 enabling USDT probes in zones should be more scalable
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/lib/libdtrace/common/dt_options.c
+++ new/usr/src/lib/libdtrace/common/dt_options.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 /*
23 23 * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
24 24 * Use is subject to license terms.
25 25 */
26 26
27 27 /*
28 28 * Copyright (c) 2013, Joyent, Inc. All rights reserved.
29 29 * Copyright (c) 2012 by Delphix. All rights reserved.
30 30 */
31 31
32 32 #include <sys/resource.h>
33 33 #include <sys/mman.h>
↓ open down ↓ |
33 lines elided |
↑ open up ↑ |
34 34 #include <sys/types.h>
35 35
36 36 #include <strings.h>
37 37 #include <signal.h>
38 38 #include <stdlib.h>
39 39 #include <unistd.h>
40 40 #include <limits.h>
41 41 #include <alloca.h>
42 42 #include <errno.h>
43 43 #include <fcntl.h>
44 +#include <zone.h>
45 +#include <libzonecfg.h>
44 46
45 47 #include <dt_impl.h>
46 48 #include <dt_string.h>
47 49
48 50 static int
49 51 dt_opt_agg(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
50 52 {
51 53 dt_aggregate_t *agp = &dtp->dt_aggregate;
52 54
53 55 if (arg != NULL)
54 56 return (dt_set_errno(dtp, EDT_BADOPTVAL));
55 57
56 58 agp->dtat_flags |= option;
57 59 return (0);
58 60 }
59 61
60 62 /*ARGSUSED*/
61 63 static int
62 64 dt_opt_amin(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
63 65 {
64 66 char str[DTRACE_ATTR2STR_MAX];
65 67 dtrace_attribute_t attr;
66 68
67 69 if (arg == NULL || dtrace_str2attr(arg, &attr) == -1)
68 70 return (dt_set_errno(dtp, EDT_BADOPTVAL));
69 71
70 72 dt_dprintf("set compiler attribute minimum to %s\n",
71 73 dtrace_attr2str(attr, str, sizeof (str)));
72 74
73 75 if (dtp->dt_pcb != NULL) {
74 76 dtp->dt_pcb->pcb_cflags |= DTRACE_C_EATTR;
75 77 dtp->dt_pcb->pcb_amin = attr;
76 78 } else {
77 79 dtp->dt_cflags |= DTRACE_C_EATTR;
78 80 dtp->dt_amin = attr;
79 81 }
80 82
81 83 return (0);
82 84 }
83 85
84 86 static void
85 87 dt_coredump(void)
86 88 {
87 89 const char msg[] = "libdtrace DEBUG: [ forcing coredump ]\n";
88 90
89 91 struct sigaction act;
90 92 struct rlimit lim;
91 93
92 94 (void) write(STDERR_FILENO, msg, sizeof (msg) - 1);
93 95
94 96 act.sa_handler = SIG_DFL;
95 97 act.sa_flags = 0;
96 98
97 99 (void) sigemptyset(&act.sa_mask);
98 100 (void) sigaction(SIGABRT, &act, NULL);
99 101
100 102 lim.rlim_cur = RLIM_INFINITY;
101 103 lim.rlim_max = RLIM_INFINITY;
102 104
103 105 (void) setrlimit(RLIMIT_CORE, &lim);
104 106 abort();
105 107 }
106 108
107 109 /*ARGSUSED*/
108 110 static int
109 111 dt_opt_core(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
110 112 {
111 113 static int enabled = 0;
112 114
113 115 if (arg != NULL)
114 116 return (dt_set_errno(dtp, EDT_BADOPTVAL));
115 117
116 118 if (enabled++ || atexit(dt_coredump) == 0)
117 119 return (0);
118 120
119 121 return (dt_set_errno(dtp, errno));
120 122 }
121 123
122 124 /*ARGSUSED*/
123 125 static int
124 126 dt_opt_cpp_hdrs(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
125 127 {
126 128 if (arg != NULL)
127 129 return (dt_set_errno(dtp, EDT_BADOPTVAL));
128 130
129 131 if (dtp->dt_pcb != NULL)
130 132 return (dt_set_errno(dtp, EDT_BADOPTCTX));
131 133
132 134 if (dt_cpp_add_arg(dtp, "-H") == NULL)
133 135 return (dt_set_errno(dtp, EDT_NOMEM));
134 136
135 137 return (0);
136 138 }
137 139
138 140 /*ARGSUSED*/
139 141 static int
140 142 dt_opt_cpp_path(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
141 143 {
142 144 char *cpp;
143 145
144 146 if (arg == NULL)
145 147 return (dt_set_errno(dtp, EDT_BADOPTVAL));
146 148
147 149 if (dtp->dt_pcb != NULL)
148 150 return (dt_set_errno(dtp, EDT_BADOPTCTX));
149 151
150 152 if ((cpp = strdup(arg)) == NULL)
151 153 return (dt_set_errno(dtp, EDT_NOMEM));
152 154
153 155 dtp->dt_cpp_argv[0] = (char *)strbasename(cpp);
154 156 free(dtp->dt_cpp_path);
155 157 dtp->dt_cpp_path = cpp;
156 158
157 159 return (0);
158 160 }
159 161
160 162 static int
161 163 dt_opt_cpp_opts(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
162 164 {
163 165 char *buf;
164 166 size_t len;
165 167 const char *opt = (const char *)option;
166 168
167 169 if (opt == NULL || arg == NULL)
168 170 return (dt_set_errno(dtp, EDT_BADOPTVAL));
169 171
170 172 if (dtp->dt_pcb != NULL)
171 173 return (dt_set_errno(dtp, EDT_BADOPTCTX));
172 174
173 175 len = strlen(opt) + strlen(arg) + 1;
174 176 buf = alloca(len);
175 177
176 178 (void) strcpy(buf, opt);
177 179 (void) strcat(buf, arg);
178 180
179 181 if (dt_cpp_add_arg(dtp, buf) == NULL)
180 182 return (dt_set_errno(dtp, EDT_NOMEM));
181 183
182 184 return (0);
183 185 }
184 186
185 187 /*ARGSUSED*/
186 188 static int
187 189 dt_opt_ctypes(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
188 190 {
189 191 int fd;
190 192
191 193 if (arg == NULL)
192 194 return (dt_set_errno(dtp, EDT_BADOPTVAL));
193 195
194 196 if ((fd = open64(arg, O_CREAT | O_WRONLY, 0666)) == -1)
195 197 return (dt_set_errno(dtp, errno));
196 198
197 199 (void) close(dtp->dt_cdefs_fd);
198 200 dtp->dt_cdefs_fd = fd;
199 201 return (0);
200 202 }
201 203
202 204 /*ARGSUSED*/
203 205 static int
204 206 dt_opt_droptags(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
205 207 {
206 208 dtp->dt_droptags = 1;
207 209 return (0);
208 210 }
209 211
210 212 /*ARGSUSED*/
211 213 static int
212 214 dt_opt_dtypes(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
213 215 {
214 216 int fd;
215 217
216 218 if (arg == NULL)
217 219 return (dt_set_errno(dtp, EDT_BADOPTVAL));
218 220
219 221 if ((fd = open64(arg, O_CREAT | O_WRONLY, 0666)) == -1)
220 222 return (dt_set_errno(dtp, errno));
221 223
222 224 (void) close(dtp->dt_ddefs_fd);
223 225 dtp->dt_ddefs_fd = fd;
224 226 return (0);
225 227 }
226 228
227 229 /*ARGSUSED*/
228 230 static int
229 231 dt_opt_debug(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
230 232 {
231 233 if (arg != NULL)
232 234 return (dt_set_errno(dtp, EDT_BADOPTVAL));
233 235
234 236 _dtrace_debug = 1;
235 237 return (0);
236 238 }
237 239
238 240 /*ARGSUSED*/
239 241 static int
240 242 dt_opt_iregs(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
241 243 {
242 244 int n;
243 245
244 246 if (arg == NULL || (n = atoi(arg)) <= 0)
245 247 return (dt_set_errno(dtp, EDT_BADOPTVAL));
246 248
247 249 dtp->dt_conf.dtc_difintregs = n;
248 250 return (0);
249 251 }
250 252
251 253 /*ARGSUSED*/
252 254 static int
253 255 dt_opt_lazyload(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
254 256 {
255 257 dtp->dt_lazyload = 1;
256 258
257 259 return (0);
258 260 }
259 261
260 262 /*ARGSUSED*/
261 263 static int
262 264 dt_opt_ld_path(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
263 265 {
264 266 char *ld;
265 267
266 268 if (arg == NULL)
267 269 return (dt_set_errno(dtp, EDT_BADOPTVAL));
268 270
269 271 if (dtp->dt_pcb != NULL)
270 272 return (dt_set_errno(dtp, EDT_BADOPTCTX));
271 273
272 274 if ((ld = strdup(arg)) == NULL)
273 275 return (dt_set_errno(dtp, EDT_NOMEM));
274 276
275 277 free(dtp->dt_ld_path);
276 278 dtp->dt_ld_path = ld;
277 279
278 280 return (0);
279 281 }
280 282
281 283 /*ARGSUSED*/
282 284 static int
283 285 dt_opt_libdir(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
284 286 {
285 287 dt_dirpath_t *dp;
286 288
287 289 if (arg == NULL)
288 290 return (dt_set_errno(dtp, EDT_BADOPTVAL));
289 291
290 292 if ((dp = malloc(sizeof (dt_dirpath_t))) == NULL ||
291 293 (dp->dir_path = strdup(arg)) == NULL) {
292 294 free(dp);
293 295 return (dt_set_errno(dtp, EDT_NOMEM));
294 296 }
295 297
296 298 dt_list_append(&dtp->dt_lib_path, dp);
297 299 return (0);
298 300 }
299 301
300 302 /*ARGSUSED*/
301 303 static int
302 304 dt_opt_linkmode(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
303 305 {
304 306 if (arg == NULL)
305 307 return (dt_set_errno(dtp, EDT_BADOPTVAL));
306 308
307 309 if (strcmp(arg, "kernel") == 0)
308 310 dtp->dt_linkmode = DT_LINK_KERNEL;
309 311 else if (strcmp(arg, "primary") == 0)
310 312 dtp->dt_linkmode = DT_LINK_PRIMARY;
311 313 else if (strcmp(arg, "dynamic") == 0)
312 314 dtp->dt_linkmode = DT_LINK_DYNAMIC;
313 315 else if (strcmp(arg, "static") == 0)
314 316 dtp->dt_linkmode = DT_LINK_STATIC;
315 317 else
316 318 return (dt_set_errno(dtp, EDT_BADOPTVAL));
317 319
318 320 return (0);
319 321 }
320 322
321 323 /*ARGSUSED*/
322 324 static int
323 325 dt_opt_linktype(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
324 326 {
325 327 if (arg == NULL)
326 328 return (dt_set_errno(dtp, EDT_BADOPTVAL));
327 329
328 330 if (strcasecmp(arg, "elf") == 0)
329 331 dtp->dt_linktype = DT_LTYP_ELF;
330 332 else if (strcasecmp(arg, "dof") == 0)
331 333 dtp->dt_linktype = DT_LTYP_DOF;
332 334 else
333 335 return (dt_set_errno(dtp, EDT_BADOPTVAL));
334 336
335 337 return (0);
336 338 }
337 339
338 340 /*ARGSUSED*/
339 341 static int
340 342 dt_opt_encoding(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
341 343 {
342 344 if (arg == NULL)
343 345 return (dt_set_errno(dtp, EDT_BADOPTVAL));
344 346
345 347 if (strcmp(arg, "ascii") == 0)
346 348 dtp->dt_encoding = DT_ENCODING_ASCII;
347 349 else if (strcmp(arg, "utf8") == 0)
348 350 dtp->dt_encoding = DT_ENCODING_UTF8;
349 351 else
350 352 return (dt_set_errno(dtp, EDT_BADOPTVAL));
351 353
352 354 return (0);
353 355 }
354 356
355 357 /*ARGSUSED*/
356 358 static int
357 359 dt_opt_evaltime(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
358 360 {
359 361 if (arg == NULL)
360 362 return (dt_set_errno(dtp, EDT_BADOPTVAL));
361 363
362 364 if (strcmp(arg, "exec") == 0)
363 365 dtp->dt_prcmode = DT_PROC_STOP_CREATE;
364 366 else if (strcmp(arg, "preinit") == 0)
365 367 dtp->dt_prcmode = DT_PROC_STOP_PREINIT;
366 368 else if (strcmp(arg, "postinit") == 0)
367 369 dtp->dt_prcmode = DT_PROC_STOP_POSTINIT;
368 370 else if (strcmp(arg, "main") == 0)
369 371 dtp->dt_prcmode = DT_PROC_STOP_MAIN;
370 372 else
371 373 return (dt_set_errno(dtp, EDT_BADOPTVAL));
372 374
373 375 return (0);
374 376 }
375 377
376 378 /*ARGSUSED*/
377 379 static int
378 380 dt_opt_pgmax(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
379 381 {
380 382 int n;
381 383
382 384 if (arg == NULL || (n = atoi(arg)) < 0)
383 385 return (dt_set_errno(dtp, EDT_BADOPTVAL));
384 386
385 387 dtp->dt_procs->dph_lrulim = n;
386 388 return (0);
387 389 }
388 390
389 391 static int
390 392 dt_opt_setenv(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
391 393 {
392 394 char **p;
393 395 char *var;
394 396 int i;
395 397
396 398 /*
397 399 * We can't effectively set environment variables from #pragma lines
398 400 * since the processes have already been spawned.
399 401 */
400 402 if (dtp->dt_pcb != NULL)
401 403 return (dt_set_errno(dtp, EDT_BADOPTCTX));
402 404
403 405 if (arg == NULL)
404 406 return (dt_set_errno(dtp, EDT_BADOPTVAL));
405 407
406 408 if (!option && strchr(arg, '=') != NULL)
407 409 return (dt_set_errno(dtp, EDT_BADOPTVAL));
408 410
409 411 for (i = 1, p = dtp->dt_proc_env; *p != NULL; i++, p++)
410 412 continue;
411 413
412 414 for (p = dtp->dt_proc_env; *p != NULL; p++) {
413 415 var = strchr(*p, '=');
414 416 if (var == NULL)
415 417 var = *p + strlen(*p);
416 418 if (strncmp(*p, arg, var - *p) == 0) {
417 419 dt_free(dtp, *p);
418 420 *p = dtp->dt_proc_env[i - 1];
419 421 dtp->dt_proc_env[i - 1] = NULL;
420 422 i--;
421 423 }
422 424 }
423 425
424 426 if (option) {
425 427 if ((var = strdup(arg)) == NULL)
426 428 return (dt_set_errno(dtp, EDT_NOMEM));
427 429
428 430 if ((p = dt_alloc(dtp, sizeof (char *) * (i + 1))) == NULL) {
429 431 dt_free(dtp, var);
430 432 return (dt_set_errno(dtp, EDT_NOMEM));
431 433 }
432 434
433 435 bcopy(dtp->dt_proc_env, p, sizeof (char *) * i);
434 436 dt_free(dtp, dtp->dt_proc_env);
435 437 dtp->dt_proc_env = p;
436 438
437 439 dtp->dt_proc_env[i - 1] = var;
438 440 dtp->dt_proc_env[i] = NULL;
439 441 }
440 442
441 443 return (0);
442 444 }
443 445
444 446 /*ARGSUSED*/
445 447 static int
446 448 dt_opt_stdc(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
447 449 {
448 450 if (arg == NULL)
449 451 return (dt_set_errno(dtp, EDT_BADOPTVAL));
450 452
451 453 if (dtp->dt_pcb != NULL)
452 454 return (dt_set_errno(dtp, EDT_BADOPTCTX));
453 455
454 456 if (strcmp(arg, "a") == 0)
455 457 dtp->dt_stdcmode = DT_STDC_XA;
456 458 else if (strcmp(arg, "c") == 0)
457 459 dtp->dt_stdcmode = DT_STDC_XC;
458 460 else if (strcmp(arg, "s") == 0)
459 461 dtp->dt_stdcmode = DT_STDC_XS;
460 462 else if (strcmp(arg, "t") == 0)
461 463 dtp->dt_stdcmode = DT_STDC_XT;
462 464 else
463 465 return (dt_set_errno(dtp, EDT_BADOPTVAL));
464 466
465 467 return (0);
466 468 }
467 469
468 470 /*ARGSUSED*/
469 471 static int
470 472 dt_opt_syslibdir(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
471 473 {
472 474 dt_dirpath_t *dp = dt_list_next(&dtp->dt_lib_path);
473 475 char *path;
474 476
475 477 if (arg == NULL)
476 478 return (dt_set_errno(dtp, EDT_BADOPTVAL));
477 479
478 480 if ((path = strdup(arg)) == NULL)
479 481 return (dt_set_errno(dtp, EDT_NOMEM));
480 482
481 483 free(dp->dir_path);
482 484 dp->dir_path = path;
483 485
484 486 return (0);
485 487 }
486 488
487 489 /*ARGSUSED*/
488 490 static int
489 491 dt_opt_tree(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
490 492 {
491 493 int m;
492 494
493 495 if (arg == NULL || (m = atoi(arg)) <= 0)
494 496 return (dt_set_errno(dtp, EDT_BADOPTVAL));
495 497
496 498 dtp->dt_treedump = m;
497 499 return (0);
498 500 }
499 501
500 502 /*ARGSUSED*/
501 503 static int
502 504 dt_opt_tregs(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
503 505 {
504 506 int n;
505 507
506 508 if (arg == NULL || (n = atoi(arg)) <= 0)
507 509 return (dt_set_errno(dtp, EDT_BADOPTVAL));
508 510
509 511 dtp->dt_conf.dtc_diftupregs = n;
510 512 return (0);
511 513 }
512 514
513 515 /*ARGSUSED*/
514 516 static int
515 517 dt_opt_xlate(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
516 518 {
517 519 if (arg == NULL)
518 520 return (dt_set_errno(dtp, EDT_BADOPTVAL));
519 521
520 522 if (strcmp(arg, "dynamic") == 0)
521 523 dtp->dt_xlatemode = DT_XL_DYNAMIC;
522 524 else if (strcmp(arg, "static") == 0)
523 525 dtp->dt_xlatemode = DT_XL_STATIC;
524 526 else
525 527 return (dt_set_errno(dtp, EDT_BADOPTVAL));
526 528
527 529 return (0);
528 530 }
529 531
530 532 /*ARGSUSED*/
531 533 static int
532 534 dt_opt_cflags(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
533 535 {
534 536 if (arg != NULL)
535 537 return (dt_set_errno(dtp, EDT_BADOPTVAL));
536 538
537 539 if (dtp->dt_pcb != NULL)
538 540 dtp->dt_pcb->pcb_cflags |= option;
539 541 else
540 542 dtp->dt_cflags |= option;
541 543
542 544 return (0);
543 545 }
544 546
545 547 static int
546 548 dt_opt_dflags(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
547 549 {
548 550 if (arg != NULL)
549 551 return (dt_set_errno(dtp, EDT_BADOPTVAL));
550 552
551 553 dtp->dt_dflags |= option;
552 554 return (0);
553 555 }
554 556
555 557 static int
556 558 dt_opt_invcflags(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
557 559 {
558 560 if (arg != NULL)
559 561 return (dt_set_errno(dtp, EDT_BADOPTVAL));
560 562
561 563 if (dtp->dt_pcb != NULL)
562 564 dtp->dt_pcb->pcb_cflags &= ~option;
563 565 else
564 566 dtp->dt_cflags &= ~option;
565 567
566 568 return (0);
567 569 }
568 570
569 571 /*ARGSUSED*/
570 572 static int
571 573 dt_opt_version(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
572 574 {
573 575 dt_version_t v;
574 576
575 577 if (arg == NULL)
576 578 return (dt_set_errno(dtp, EDT_BADOPTVAL));
577 579
578 580 if (dt_version_str2num(arg, &v) == -1)
579 581 return (dt_set_errno(dtp, EDT_VERSINVAL));
580 582
581 583 if (!dt_version_defined(v))
582 584 return (dt_set_errno(dtp, EDT_VERSUNDEF));
583 585
584 586 return (dt_reduce(dtp, v));
585 587 }
586 588
587 589 static int
588 590 dt_opt_runtime(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
589 591 {
590 592 char *end;
591 593 dtrace_optval_t val = 0;
592 594 int i;
593 595
594 596 const struct {
595 597 char *positive;
596 598 char *negative;
597 599 } couples[] = {
598 600 { "yes", "no" },
599 601 { "enable", "disable" },
600 602 { "enabled", "disabled" },
601 603 { "true", "false" },
602 604 { "on", "off" },
603 605 { "set", "unset" },
604 606 { NULL }
605 607 };
606 608
607 609 if (arg != NULL) {
608 610 if (arg[0] == '\0') {
609 611 val = DTRACEOPT_UNSET;
610 612 goto out;
611 613 }
612 614
613 615 for (i = 0; couples[i].positive != NULL; i++) {
614 616 if (strcasecmp(couples[i].positive, arg) == 0) {
615 617 val = 1;
616 618 goto out;
617 619 }
618 620
619 621 if (strcasecmp(couples[i].negative, arg) == 0) {
620 622 val = DTRACEOPT_UNSET;
621 623 goto out;
622 624 }
623 625 }
624 626
625 627 errno = 0;
626 628 val = strtoull(arg, &end, 0);
627 629
628 630 if (*end != '\0' || errno != 0 || val < 0)
629 631 return (dt_set_errno(dtp, EDT_BADOPTVAL));
630 632 }
631 633
632 634 out:
633 635 dtp->dt_options[option] = val;
634 636 return (0);
635 637 }
636 638
637 639 static int
638 640 dt_optval_parse(const char *arg, dtrace_optval_t *rval)
639 641 {
640 642 dtrace_optval_t mul = 1;
641 643 size_t len;
642 644 char *end;
643 645
644 646 len = strlen(arg);
645 647 errno = 0;
646 648
647 649 switch (arg[len - 1]) {
648 650 case 't':
649 651 case 'T':
650 652 mul *= 1024;
651 653 /*FALLTHRU*/
652 654 case 'g':
653 655 case 'G':
654 656 mul *= 1024;
655 657 /*FALLTHRU*/
656 658 case 'm':
657 659 case 'M':
658 660 mul *= 1024;
659 661 /*FALLTHRU*/
660 662 case 'k':
661 663 case 'K':
662 664 mul *= 1024;
663 665 /*FALLTHRU*/
664 666 default:
665 667 break;
666 668 }
667 669
668 670 errno = 0;
669 671 *rval = strtoull(arg, &end, 0) * mul;
670 672
671 673 if ((mul > 1 && end != &arg[len - 1]) || (mul == 1 && *end != '\0') ||
672 674 *rval < 0 || errno != 0)
673 675 return (-1);
674 676
675 677 return (0);
676 678 }
677 679
678 680 static int
679 681 dt_opt_size(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
680 682 {
681 683 dtrace_optval_t val = 0;
682 684
683 685 if (arg != NULL && dt_optval_parse(arg, &val) != 0)
684 686 return (dt_set_errno(dtp, EDT_BADOPTVAL));
685 687
686 688 dtp->dt_options[option] = val;
687 689 return (0);
688 690 }
689 691
690 692 static int
691 693 dt_opt_rate(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
692 694 {
693 695 char *end;
694 696 int i;
695 697 dtrace_optval_t mul = 1, val = 0;
696 698
697 699 const struct {
698 700 char *name;
699 701 hrtime_t mul;
700 702 } suffix[] = {
701 703 { "ns", NANOSEC / NANOSEC },
702 704 { "nsec", NANOSEC / NANOSEC },
703 705 { "us", NANOSEC / MICROSEC },
704 706 { "usec", NANOSEC / MICROSEC },
705 707 { "ms", NANOSEC / MILLISEC },
706 708 { "msec", NANOSEC / MILLISEC },
707 709 { "s", NANOSEC / SEC },
708 710 { "sec", NANOSEC / SEC },
709 711 { "m", NANOSEC * (hrtime_t)60 },
710 712 { "min", NANOSEC * (hrtime_t)60 },
711 713 { "h", NANOSEC * (hrtime_t)60 * (hrtime_t)60 },
712 714 { "hour", NANOSEC * (hrtime_t)60 * (hrtime_t)60 },
713 715 { "d", NANOSEC * (hrtime_t)(24 * 60 * 60) },
714 716 { "day", NANOSEC * (hrtime_t)(24 * 60 * 60) },
715 717 { "hz", 0 },
716 718 { NULL }
717 719 };
718 720
719 721 if (arg != NULL) {
720 722 errno = 0;
721 723 val = strtoull(arg, &end, 0);
722 724
723 725 for (i = 0; suffix[i].name != NULL; i++) {
724 726 if (strcasecmp(suffix[i].name, end) == 0) {
725 727 mul = suffix[i].mul;
726 728 break;
727 729 }
728 730 }
729 731
730 732 if (suffix[i].name == NULL && *end != '\0' || val < 0)
731 733 return (dt_set_errno(dtp, EDT_BADOPTVAL));
732 734
733 735 if (mul == 0) {
734 736 /*
735 737 * The rate has been specified in frequency-per-second.
736 738 */
737 739 if (val != 0)
738 740 val = NANOSEC / val;
739 741 } else {
740 742 val *= mul;
741 743 }
742 744 }
743 745
744 746 dtp->dt_options[option] = val;
745 747 return (0);
746 748 }
747 749
748 750 /*
749 751 * When setting the strsize option, set the option in the dt_options array
750 752 * using dt_opt_size() as usual, and then update the definition of the CTF
751 753 * type for the D intrinsic "string" to be an array of the corresponding size.
752 754 * If any errors occur, reset dt_options[option] to its previous value.
753 755 */
754 756 static int
755 757 dt_opt_strsize(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
756 758 {
757 759 dtrace_optval_t val = dtp->dt_options[option];
758 760 ctf_file_t *fp = DT_STR_CTFP(dtp);
759 761 ctf_id_t type = ctf_type_resolve(fp, DT_STR_TYPE(dtp));
760 762 ctf_arinfo_t r;
761 763
762 764 if (dt_opt_size(dtp, arg, option) != 0)
763 765 return (-1); /* dt_errno is set for us */
764 766
765 767 if (dtp->dt_options[option] > UINT_MAX) {
766 768 dtp->dt_options[option] = val;
767 769 return (dt_set_errno(dtp, EOVERFLOW));
768 770 }
769 771
770 772 if (ctf_array_info(fp, type, &r) == CTF_ERR) {
771 773 dtp->dt_options[option] = val;
772 774 dtp->dt_ctferr = ctf_errno(fp);
773 775 return (dt_set_errno(dtp, EDT_CTF));
774 776 }
775 777
776 778 r.ctr_nelems = (uint_t)dtp->dt_options[option];
777 779
778 780 if (ctf_set_array(fp, type, &r) == CTF_ERR ||
779 781 ctf_update(fp) == CTF_ERR) {
780 782 dtp->dt_options[option] = val;
781 783 dtp->dt_ctferr = ctf_errno(fp);
782 784 return (dt_set_errno(dtp, EDT_CTF));
783 785 }
784 786
785 787 return (0);
786 788 }
787 789
788 790 static const struct {
789 791 const char *dtbp_name;
790 792 int dtbp_policy;
791 793 } _dtrace_bufpolicies[] = {
792 794 { "ring", DTRACEOPT_BUFPOLICY_RING },
793 795 { "fill", DTRACEOPT_BUFPOLICY_FILL },
794 796 { "switch", DTRACEOPT_BUFPOLICY_SWITCH },
795 797 { NULL, 0 }
796 798 };
797 799
798 800 /*ARGSUSED*/
799 801 static int
800 802 dt_opt_bufpolicy(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
801 803 {
802 804 dtrace_optval_t policy = DTRACEOPT_UNSET;
803 805 int i;
804 806
805 807 if (arg == NULL)
806 808 return (dt_set_errno(dtp, EDT_BADOPTVAL));
807 809
808 810 for (i = 0; _dtrace_bufpolicies[i].dtbp_name != NULL; i++) {
809 811 if (strcmp(_dtrace_bufpolicies[i].dtbp_name, arg) == 0) {
810 812 policy = _dtrace_bufpolicies[i].dtbp_policy;
811 813 break;
812 814 }
813 815 }
814 816
815 817 if (policy == DTRACEOPT_UNSET)
816 818 return (dt_set_errno(dtp, EDT_BADOPTVAL));
817 819
818 820 dtp->dt_options[DTRACEOPT_BUFPOLICY] = policy;
819 821
820 822 return (0);
821 823 }
822 824
823 825 static const struct {
824 826 const char *dtbr_name;
825 827 int dtbr_policy;
826 828 } _dtrace_bufresize[] = {
827 829 { "auto", DTRACEOPT_BUFRESIZE_AUTO },
828 830 { "manual", DTRACEOPT_BUFRESIZE_MANUAL },
829 831 { NULL, 0 }
830 832 };
831 833
832 834 /*ARGSUSED*/
833 835 static int
834 836 dt_opt_bufresize(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
835 837 {
836 838 dtrace_optval_t policy = DTRACEOPT_UNSET;
837 839 int i;
838 840
839 841 if (arg == NULL)
840 842 return (dt_set_errno(dtp, EDT_BADOPTVAL));
841 843
842 844 for (i = 0; _dtrace_bufresize[i].dtbr_name != NULL; i++) {
843 845 if (strcmp(_dtrace_bufresize[i].dtbr_name, arg) == 0) {
844 846 policy = _dtrace_bufresize[i].dtbr_policy;
845 847 break;
846 848 }
↓ open down ↓ |
793 lines elided |
↑ open up ↑ |
847 849 }
848 850
849 851 if (policy == DTRACEOPT_UNSET)
850 852 return (dt_set_errno(dtp, EDT_BADOPTVAL));
851 853
852 854 dtp->dt_options[DTRACEOPT_BUFRESIZE] = policy;
853 855
854 856 return (0);
855 857 }
856 858
859 +/*ARGSUSED*/
860 +static int
861 +dt_opt_zone(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
862 +{
863 + zoneid_t z, did;
864 +
865 + if (arg == NULL)
866 + return (dt_set_errno(dtp, EDT_BADOPTVAL));
867 +
868 + /*
869 + * If the specified zone is currently running, we'll query the kernel
870 + * for its debugger ID. If it doesn't appear to be running, we'll look
871 + * for it for among all installed zones (thereby allowing a zdefs
872 + * enabling against a halted zone).
873 + */
874 + if ((z = getzoneidbyname(arg)) != -1) {
875 + if (zone_getattr(z, ZONE_ATTR_DID, &did, sizeof (did)) < 0)
876 + return (dt_set_errno(dtp, EDT_BADOPTVAL));
877 + } else {
878 + zone_dochandle_t handle;
879 +
880 + if ((handle = zonecfg_init_handle()) == NULL)
881 + return (dt_set_errno(dtp, errno));
882 +
883 + if (zonecfg_get_handle(arg, handle) != Z_OK) {
884 + zonecfg_fini_handle(handle);
885 + return (dt_set_errno(dtp, EDT_BADOPTVAL));
886 + }
887 +
888 + did = zonecfg_get_did(handle);
889 + zonecfg_fini_handle(handle);
890 + }
891 +
892 + dtp->dt_options[DTRACEOPT_ZONE] = did;
893 +
894 + return (0);
895 +}
896 +
857 897 int
858 898 dt_options_load(dtrace_hdl_t *dtp)
859 899 {
860 900 dof_hdr_t hdr, *dof;
861 901 dof_sec_t *sec;
862 902 size_t offs;
863 903 int i;
864 904
865 905 /*
866 906 * To load the option values, we need to ask the kernel to provide its
867 907 * DOF, which we'll sift through to look for OPTDESC sections.
868 908 */
869 909 bzero(&hdr, sizeof (dof_hdr_t));
870 910 hdr.dofh_loadsz = sizeof (dof_hdr_t);
871 911
872 912 if (dt_ioctl(dtp, DTRACEIOC_DOFGET, &hdr) == -1)
873 913 return (dt_set_errno(dtp, errno));
874 914
875 915 if (hdr.dofh_loadsz < sizeof (dof_hdr_t))
876 916 return (dt_set_errno(dtp, EINVAL));
877 917
878 918 dof = calloc(1, hdr.dofh_loadsz);
879 919 if (dof == NULL)
880 920 return (dt_set_errno(dtp, errno));
881 921
882 922 dof->dofh_loadsz = hdr.dofh_loadsz;
883 923
884 924 for (i = 0; i < DTRACEOPT_MAX; i++)
885 925 dtp->dt_options[i] = DTRACEOPT_UNSET;
886 926
887 927 if (dt_ioctl(dtp, DTRACEIOC_DOFGET, dof) == -1) {
888 928 free(dof);
889 929 return (dt_set_errno(dtp, errno));
890 930 }
891 931
892 932 for (i = 0; i < dof->dofh_secnum; i++) {
893 933 sec = (dof_sec_t *)(uintptr_t)((uintptr_t)dof +
894 934 dof->dofh_secoff + i * dof->dofh_secsize);
895 935
896 936 if (sec->dofs_type != DOF_SECT_OPTDESC)
897 937 continue;
898 938
899 939 break;
900 940 }
901 941
902 942 for (offs = 0; offs < sec->dofs_size; offs += sec->dofs_entsize) {
903 943 dof_optdesc_t *opt = (dof_optdesc_t *)(uintptr_t)
904 944 ((uintptr_t)dof + sec->dofs_offset + offs);
905 945
906 946 if (opt->dofo_strtab != DOF_SECIDX_NONE)
907 947 continue;
908 948
909 949 if (opt->dofo_option >= DTRACEOPT_MAX)
910 950 continue;
911 951
912 952 dtp->dt_options[opt->dofo_option] = opt->dofo_value;
913 953 }
914 954
915 955 free(dof);
916 956 return (0);
917 957 }
918 958
919 959 typedef struct dt_option {
920 960 const char *o_name;
921 961 int (*o_func)(dtrace_hdl_t *, const char *, uintptr_t);
922 962 uintptr_t o_option;
923 963 } dt_option_t;
924 964
925 965 /*
926 966 * Compile-time options.
927 967 */
928 968 static const dt_option_t _dtrace_ctoptions[] = {
929 969 { "aggpercpu", dt_opt_agg, DTRACE_A_PERCPU },
930 970 { "amin", dt_opt_amin },
931 971 { "argref", dt_opt_cflags, DTRACE_C_ARGREF },
932 972 { "core", dt_opt_core },
933 973 { "cpp", dt_opt_cflags, DTRACE_C_CPP },
934 974 { "cpphdrs", dt_opt_cpp_hdrs },
935 975 { "cpppath", dt_opt_cpp_path },
936 976 { "ctypes", dt_opt_ctypes },
937 977 { "defaultargs", dt_opt_cflags, DTRACE_C_DEFARG },
938 978 { "dtypes", dt_opt_dtypes },
939 979 { "debug", dt_opt_debug },
940 980 { "define", dt_opt_cpp_opts, (uintptr_t)"-D" },
941 981 { "droptags", dt_opt_droptags },
942 982 { "empty", dt_opt_cflags, DTRACE_C_EMPTY },
943 983 { "encoding", dt_opt_encoding },
944 984 { "errtags", dt_opt_cflags, DTRACE_C_ETAGS },
945 985 { "evaltime", dt_opt_evaltime },
946 986 { "incdir", dt_opt_cpp_opts, (uintptr_t)"-I" },
947 987 { "iregs", dt_opt_iregs },
948 988 { "kdefs", dt_opt_invcflags, DTRACE_C_KNODEF },
949 989 { "knodefs", dt_opt_cflags, DTRACE_C_KNODEF },
950 990 { "late", dt_opt_xlate },
951 991 { "lazyload", dt_opt_lazyload },
952 992 { "ldpath", dt_opt_ld_path },
953 993 { "libdir", dt_opt_libdir },
954 994 { "linkmode", dt_opt_linkmode },
955 995 { "linktype", dt_opt_linktype },
956 996 { "nolibs", dt_opt_cflags, DTRACE_C_NOLIBS },
957 997 { "pgmax", dt_opt_pgmax },
958 998 { "pspec", dt_opt_cflags, DTRACE_C_PSPEC },
959 999 { "setenv", dt_opt_setenv, 1 },
960 1000 { "stdc", dt_opt_stdc },
961 1001 { "strip", dt_opt_dflags, DTRACE_D_STRIP },
962 1002 { "syslibdir", dt_opt_syslibdir },
963 1003 { "tree", dt_opt_tree },
964 1004 { "tregs", dt_opt_tregs },
965 1005 { "udefs", dt_opt_invcflags, DTRACE_C_UNODEF },
966 1006 { "undef", dt_opt_cpp_opts, (uintptr_t)"-U" },
967 1007 { "unodefs", dt_opt_cflags, DTRACE_C_UNODEF },
968 1008 { "unsetenv", dt_opt_setenv, 0 },
969 1009 { "verbose", dt_opt_cflags, DTRACE_C_DIFV },
970 1010 { "version", dt_opt_version },
971 1011 { "zdefs", dt_opt_cflags, DTRACE_C_ZDEFS },
972 1012 { NULL }
973 1013 };
974 1014
975 1015 /*
976 1016 * Run-time options.
977 1017 */
978 1018 static const dt_option_t _dtrace_rtoptions[] = {
979 1019 { "aggsize", dt_opt_size, DTRACEOPT_AGGSIZE },
980 1020 { "bufsize", dt_opt_size, DTRACEOPT_BUFSIZE },
981 1021 { "bufpolicy", dt_opt_bufpolicy, DTRACEOPT_BUFPOLICY },
982 1022 { "bufresize", dt_opt_bufresize, DTRACEOPT_BUFRESIZE },
983 1023 { "cleanrate", dt_opt_rate, DTRACEOPT_CLEANRATE },
984 1024 { "cpu", dt_opt_runtime, DTRACEOPT_CPU },
985 1025 { "destructive", dt_opt_runtime, DTRACEOPT_DESTRUCTIVE },
986 1026 { "dynvarsize", dt_opt_size, DTRACEOPT_DYNVARSIZE },
↓ open down ↓ |
120 lines elided |
↑ open up ↑ |
987 1027 { "grabanon", dt_opt_runtime, DTRACEOPT_GRABANON },
988 1028 { "jstackframes", dt_opt_runtime, DTRACEOPT_JSTACKFRAMES },
989 1029 { "jstackstrsize", dt_opt_size, DTRACEOPT_JSTACKSTRSIZE },
990 1030 { "nspec", dt_opt_runtime, DTRACEOPT_NSPEC },
991 1031 { "specsize", dt_opt_size, DTRACEOPT_SPECSIZE },
992 1032 { "stackframes", dt_opt_runtime, DTRACEOPT_STACKFRAMES },
993 1033 { "statusrate", dt_opt_rate, DTRACEOPT_STATUSRATE },
994 1034 { "strsize", dt_opt_strsize, DTRACEOPT_STRSIZE },
995 1035 { "ustackframes", dt_opt_runtime, DTRACEOPT_USTACKFRAMES },
996 1036 { "temporal", dt_opt_runtime, DTRACEOPT_TEMPORAL },
1037 + { "zone", dt_opt_zone, DTRACEOPT_ZONE },
997 1038 { NULL }
998 1039 };
999 1040
1000 1041 /*
1001 1042 * Dynamic run-time options.
1002 1043 */
1003 1044 static const dt_option_t _dtrace_drtoptions[] = {
1004 1045 { "agghist", dt_opt_runtime, DTRACEOPT_AGGHIST },
1005 1046 { "aggpack", dt_opt_runtime, DTRACEOPT_AGGPACK },
1006 1047 { "aggrate", dt_opt_rate, DTRACEOPT_AGGRATE },
1007 1048 { "aggsortkey", dt_opt_runtime, DTRACEOPT_AGGSORTKEY },
1008 1049 { "aggsortkeypos", dt_opt_runtime, DTRACEOPT_AGGSORTKEYPOS },
1009 1050 { "aggsortpos", dt_opt_runtime, DTRACEOPT_AGGSORTPOS },
1010 1051 { "aggsortrev", dt_opt_runtime, DTRACEOPT_AGGSORTREV },
1011 1052 { "aggzoom", dt_opt_runtime, DTRACEOPT_AGGZOOM },
1012 1053 { "flowindent", dt_opt_runtime, DTRACEOPT_FLOWINDENT },
1013 1054 { "quiet", dt_opt_runtime, DTRACEOPT_QUIET },
1014 1055 { "rawbytes", dt_opt_runtime, DTRACEOPT_RAWBYTES },
1015 1056 { "stackindent", dt_opt_runtime, DTRACEOPT_STACKINDENT },
1016 1057 { "switchrate", dt_opt_rate, DTRACEOPT_SWITCHRATE },
1017 1058 { NULL }
1018 1059 };
1019 1060
1020 1061 int
1021 1062 dtrace_getopt(dtrace_hdl_t *dtp, const char *opt, dtrace_optval_t *val)
1022 1063 {
1023 1064 const dt_option_t *op;
1024 1065
1025 1066 if (opt == NULL)
1026 1067 return (dt_set_errno(dtp, EINVAL));
1027 1068
1028 1069 /*
1029 1070 * We only need to search the run-time options -- it's not legal
1030 1071 * to get the values of compile-time options.
1031 1072 */
1032 1073 for (op = _dtrace_rtoptions; op->o_name != NULL; op++) {
1033 1074 if (strcmp(op->o_name, opt) == 0) {
1034 1075 *val = dtp->dt_options[op->o_option];
1035 1076 return (0);
1036 1077 }
1037 1078 }
1038 1079
1039 1080 for (op = _dtrace_drtoptions; op->o_name != NULL; op++) {
1040 1081 if (strcmp(op->o_name, opt) == 0) {
1041 1082 *val = dtp->dt_options[op->o_option];
1042 1083 return (0);
1043 1084 }
1044 1085 }
1045 1086
1046 1087 return (dt_set_errno(dtp, EDT_BADOPTNAME));
1047 1088 }
1048 1089
1049 1090 int
1050 1091 dtrace_setopt(dtrace_hdl_t *dtp, const char *opt, const char *val)
1051 1092 {
1052 1093 const dt_option_t *op;
1053 1094
1054 1095 if (opt == NULL)
1055 1096 return (dt_set_errno(dtp, EINVAL));
1056 1097
1057 1098 for (op = _dtrace_ctoptions; op->o_name != NULL; op++) {
1058 1099 if (strcmp(op->o_name, opt) == 0)
1059 1100 return (op->o_func(dtp, val, op->o_option));
1060 1101 }
1061 1102
1062 1103 for (op = _dtrace_drtoptions; op->o_name != NULL; op++) {
1063 1104 if (strcmp(op->o_name, opt) == 0)
1064 1105 return (op->o_func(dtp, val, op->o_option));
1065 1106 }
1066 1107
1067 1108 for (op = _dtrace_rtoptions; op->o_name != NULL; op++) {
1068 1109 if (strcmp(op->o_name, opt) == 0) {
1069 1110 /*
1070 1111 * Only dynamic run-time options may be set while
1071 1112 * tracing is active.
1072 1113 */
1073 1114 if (dtp->dt_active)
1074 1115 return (dt_set_errno(dtp, EDT_ACTIVE));
1075 1116
1076 1117 return (op->o_func(dtp, val, op->o_option));
1077 1118 }
1078 1119 }
1079 1120
1080 1121 return (dt_set_errno(dtp, EDT_BADOPTNAME));
1081 1122 }
↓ open down ↓ |
75 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX