1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
7 * with the License.
8 *
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
13 *
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
19 *
20 * CDDL HEADER END
21 */
22 /*
23 * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
25 */
26
27 #pragma ident "%Z%%M% %I% %E% SMI"
28
29 /*
30 * Just in case we're not in a build environment, make sure that
31 * TEXT_DOMAIN gets set to something.
32 */
33 #if !defined(TEXT_DOMAIN)
34 #define TEXT_DOMAIN "SYS_TEST"
35 #endif
36
37 /*
38 * setup utility
39 */
40
41 #include "meta_set_prv.h"
42 #include <sys/resource.h>
43 #include <syslog.h>
44
45
46 /* globals */
47 char *myname = "";
48 FILE *metalogfp = NULL;
49 int metasyslog = 0;
50 uint_t verbosity = 0;
51 hrtime_t start_time = 0;
52 sigset_t allsigs;
53
54 /* locals */
55 static int rb_signal_handling = FALSE;
56 static int rb_signal_caught = FALSE;
57 static int rb_signal_which = 0;
58 static size_t metansig = 0;
59 static struct sigaction *metahandlers = NULL;
60 #ifdef _DEBUG_MALLOC_INC
61 static ulong_t malloc_histid_begin;
62 static ulong_t malloc_histid_end;
63 static ulong_t malloc_inuse_begin;
64 static ulong_t malloc_inuse_end;
65 #endif /* _DEBUG_MALLOC_INC */
66
67 /* forwards */
68 static void md_catcher(int sig);
69
70 /*
71 * push/pop signal handlers
72 */
73 static int
md_pushsig(unsigned sig,void (* handler)(int sig),md_error_t * ep)74 md_pushsig(
75 unsigned sig,
76 void (*handler)(int sig),
77 md_error_t *ep
78 )
79 {
80 struct sigaction newhandler;
81
82 /* expand vector as neccessary */
83 if (sig >= metansig) {
84 if (metahandlers == NULL) {
85 metahandlers = Zalloc(
86 (sig + 1) * sizeof (metahandlers[0]));
87 } else {
88 metahandlers = Realloc(metahandlers,
89 ((sig + 1) * sizeof (metahandlers[0])));
90 (void) memset(&metahandlers[metansig], 0,
91 ((sig - metansig) * sizeof (metahandlers[0])));
92 }
93 metansig = sig;
94 }
95
96 /* We need to have a seperate stack to handle rollback properly */
97 newhandler.sa_flags = 0;
98 if (sigfillset(&newhandler.sa_mask) < 0)
99 return (mdsyserror(ep, errno,
100 "sigfillset(&newhandler.sa_mask)"));
101 newhandler.sa_handler = handler;
102
103 /* push handler */
104 if (sigaction(sig, &newhandler, &metahandlers[sig]) < 0)
105 return (mdsyserror(ep, errno, "sigaction(&newhandler)"));
106
107 /* return success */
108 return (0);
109 }
110
111 static int
md_popsig(unsigned sig,md_error_t * ep)112 md_popsig(
113 unsigned sig,
114 md_error_t *ep
115 )
116 {
117 /* can't pop what isn't pushed */
118 assert(sig <= metansig);
119 assert(metahandlers[sig].sa_handler != md_catcher);
120
121 /* pop handler */
122 if (sigaction(sig, &metahandlers[sig], NULL) < 0)
123 return (mdsyserror(ep, errno, "sigaction(&metahandlers)"));
124
125 /* return success */
126 return (0);
127 }
128
129 char *
meta_lock_name(set_t setno)130 meta_lock_name(
131 set_t setno
132 )
133 {
134 char lockname[30];
135
136 if (setno == MD_LOCAL_SET)
137 return (strdup(METALOCK));
138
139 (void) snprintf(lockname, sizeof (lockname), "%s.%ld", METALOCK, setno);
140 return (strdup(lockname));
141 }
142
143 #define META_LOCK_FD(sp) ((sp)->lockfd)
144 #define META_LOCK_NAME(sp) (meta_lock_name((sp)->setno))
145
146 /*
147 * open lock
148 */
149 static int
meta_lock_open(mdsetname_t * sp,md_error_t * ep)150 meta_lock_open(
151 mdsetname_t *sp,
152 md_error_t *ep
153 )
154 {
155 int lockfd = META_LOCK_FD(sp);
156 char *lockname = META_LOCK_NAME(sp);
157
158 /* check for already open */
159 if (lockfd >= 0)
160 goto success;
161 assert(lockfd == MD_NO_LOCK);
162
163 /* open and/or create lock file */
164 if ((lockfd = open(lockname, O_WRONLY, 0)) < 0) {
165 if (errno == EROFS) {
166 lockfd = MD_NO_LOCK;
167 goto success;
168 }
169 if (errno != ENOENT) {
170 (void) mdsyserror(ep, errno, lockname);
171 goto failure;
172 }
173 if ((lockfd = open(lockname, (O_WRONLY|O_CREAT),
174 0644)) < 0) {
175 (void) mdsyserror(ep, errno, lockname);
176 goto failure;
177 }
178 if (fchmod(lockfd, 0644) != 0) {
179 (void) mdsyserror(ep, errno, lockname);
180 goto failure;
181 }
182 }
183
184 /* return success */
185 success:
186 if (lockname != NULL)
187 free(lockname);
188 META_LOCK_FD(sp) = lockfd;
189 return (0);
190
191 /* flag failure */
192 failure:
193 if (lockname != NULL)
194 free(lockname);
195 if (lockfd >= 0)
196 (void) close(lockfd);
197 return (-1);
198 }
199
200 static int
meta_lock_close(mdsetname_t * sp,md_error_t * ep)201 meta_lock_close(
202 mdsetname_t *sp,
203 md_error_t *ep
204 )
205 {
206 int retval = 0;
207
208 if (close(META_LOCK_FD(sp)) != 0) {
209 if (ep != NULL) {
210 char *lockname = META_LOCK_NAME(sp);
211 (void) mdsyserror(ep, errno, lockname);
212 if (lockname != NULL)
213 free(lockname);
214 }
215
216 retval = -1;
217 }
218 META_LOCK_FD(sp) = MD_NO_LOCK;
219 return (retval);
220 }
221
222 /*
223 * unlock
224 */
225 int
meta_unlock(mdsetname_t * sp,md_error_t * ep)226 meta_unlock(
227 mdsetname_t *sp,
228 md_error_t *ep
229 )
230 {
231 int lockfd = META_LOCK_FD(sp);
232
233 /* ignore read-only filesystem */
234 if (lockfd == MD_NO_LOCK)
235 return (0);
236
237 assert(lockfd >= 0);
238
239 /* unlock and discard */
240 if (lockf(lockfd, F_ULOCK, 0) != 0) {
241 (void) mdsyserror(ep, errno, METALOCK);
242 (void) meta_lock_close(sp, NULL);
243 return (-1);
244 }
245 return (meta_lock_close(sp, ep));
246 }
247
248 /*
249 * lock
250 */
251 int
meta_lock(mdsetname_t * sp,int print_status,md_error_t * ep)252 meta_lock(
253 mdsetname_t *sp,
254 int print_status,
255 md_error_t *ep
256 )
257 {
258 int lockfd;
259 char *lockname = NULL;
260
261 /* open lock file */
262 if (meta_lock_open(sp, ep) != 0) {
263 assert(META_LOCK_FD(sp) == MD_NO_LOCK);
264 goto failure;
265 }
266
267 /* ignore read-only filesystem */
268 if ((lockfd = META_LOCK_FD(sp)) == MD_NO_LOCK)
269 goto success;
270 assert(lockfd >= 0);
271
272 lockname = META_LOCK_NAME(sp);
273
274 /* grab lock */
275 if (lockf(lockfd, F_TLOCK, 0) != 0) {
276 if ((errno != EACCES) && (errno != EAGAIN)) {
277 (void) mdsyserror(ep, errno, lockname);
278 goto failure;
279 }
280 if (print_status)
281 (void) fprintf(stderr, dgettext(TEXT_DOMAIN,
282 "%s: waiting on %s\n"),
283 myname, lockname);
284 if (lockf(lockfd, F_LOCK, 0) != 0) {
285 (void) mdsyserror(ep, errno, lockname);
286 goto failure;
287 }
288 }
289
290 /* return success */
291 success:
292 if (lockname != NULL)
293 free(lockname);
294 return (0);
295
296 /* flag failure */
297 failure:
298 if (lockname != NULL)
299 free(lockname);
300 if (lockfd >= 0)
301 (void) meta_lock_close(sp, ep);
302 return (-1);
303 }
304
305 int
meta_lock_nowait(mdsetname_t * sp,md_error_t * ep)306 meta_lock_nowait(
307 mdsetname_t *sp,
308 md_error_t *ep
309 )
310 {
311 int lockfd;
312 char *lockname = NULL;
313
314 /* open lock file */
315 if (meta_lock_open(sp, ep) != 0) {
316 assert(META_LOCK_FD(sp) == MD_NO_LOCK);
317 goto failure;
318 }
319
320 /* ignore read-only filesystem */
321 if ((lockfd = META_LOCK_FD(sp)) == MD_NO_LOCK)
322 goto success;
323 assert(lockfd >= 0);
324
325 lockname = META_LOCK_NAME(sp);
326
327 /* grab lock */
328 if (lockf(lockfd, F_TLOCK, 0) != 0) {
329 if ((errno != EACCES) && (errno != EAGAIN)) {
330 (void) mdsyserror(ep, errno, lockname);
331 goto failure;
332 }
333 (void) mdsyserror(ep, EAGAIN, lockname);
334 goto failure;
335 }
336
337 /* return success */
338 success:
339 if (lockname != NULL)
340 free(lockname);
341 return (0);
342
343 /* flag failure */
344 failure:
345 if (lockname != NULL)
346 free(lockname);
347 if (lockfd >= 0)
348 (void) meta_lock_close(sp, ep);
349 return (-1);
350 }
351
352 /*
353 * lock status
354 */
355 int
meta_lock_status(mdsetname_t * sp,md_error_t * ep)356 meta_lock_status(
357 mdsetname_t *sp,
358 md_error_t *ep
359 )
360 {
361 int lockfd;
362
363 /* open lock file */
364 if (meta_lock_open(sp, ep) != 0) {
365 assert(META_LOCK_FD(sp) == MD_NO_LOCK);
366 return (-1);
367 }
368
369 lockfd = META_LOCK_FD(sp);
370 /* ignore read-only filesystem */
371 if (lockfd == MD_NO_LOCK)
372 return (0);
373 assert(lockfd >= 0);
374
375 /* test lock */
376 if (lockf(lockfd, F_TEST, 0) != 0) {
377 char *lockname = META_LOCK_NAME(sp);
378 (void) mdsyserror(ep, errno, lockname);
379 if (lockname != NULL)
380 free(lockname);
381 return (-1);
382 }
383
384 return (0);
385 }
386
387 /*
388 * setup for syslog daemon output
389 */
390 static void
md_syslog(char * name)391 md_syslog(
392 char *name /* name of program */
393 )
394 {
395 if ((name == NULL) || (*name == '\0'))
396 name = "md";
397 openlog(name, LOG_CONS, LOG_DAEMON);
398 metasyslog = 1;
399 }
400
401 /*
402 * daemonize: put in background
403 */
404 int
md_daemonize(mdsetname_t * sp,md_error_t * ep)405 md_daemonize(
406 mdsetname_t *sp,
407 md_error_t *ep
408 )
409 {
410 char *p;
411 struct rlimit rlim;
412 pid_t pid;
413 int i;
414
415 /* debug */
416 if (((p = getenv("MD_DEBUG")) != NULL) &&
417 (strstr(p, "NODAEMON") != NULL)) {
418 return (0); /* do nothing */
419 }
420
421 /* get number of file descriptors */
422 if (getrlimit(RLIMIT_NOFILE, &rlim) != 0) {
423 return (mdsyserror(ep, errno, "getrlimit(RLIMIT_NOFILE)"));
424 }
425
426 /* fork and kill parent */
427 if ((pid = fork()) == -1)
428 return (mdsyserror(ep, errno, "fork"));
429 else if (pid != 0)
430 return (pid);
431
432 /*
433 * We need to close the admin device and reset the specialfd to force
434 * the child process to reopen it, since we are going to close all
435 * descriptors from 3 up to RLIMIT_NOFILE in the child.
436 */
437 if (close_admin(ep) != 0)
438 return (-1);
439
440 /* close RPC connections */
441 metarpccloseall();
442
443 /* drop lock */
444 if (meta_unlock(sp, ep) != 0)
445 return (-1);
446
447 if (rlim.rlim_cur != RLIM_INFINITY) {
448 /*
449 * close all but stdout, stderr, and metalogfp
450 */
451
452 for (i = 0; (i < rlim.rlim_cur); ++i) {
453 if ((i == fileno(stdout)) ||
454 (i == fileno(stderr)) ||
455 ((metalogfp != NULL) &&
456 (i == fileno(metalogfp)))) {
457 continue;
458 }
459 (void) close(i);
460 }
461 }
462
463 /* put in own process group */
464 if (setsid() == -1)
465 return (mdsyserror(ep, errno, "setsid"));
466
467 /* setup syslog */
468 md_syslog(myname);
469
470 /* return success */
471 return (0);
472 }
473
474 /*
475 * flush and sync fp
476 */
477 static void
flushfp(FILE * fp)478 flushfp(
479 FILE *fp
480 )
481 {
482 (void) fflush(fp);
483 (void) fsync(fileno(fp));
484 }
485
486 /*
487 * reset and exit utility
488 */
489 void
md_exit(mdsetname_t * sp,int eval)490 md_exit(
491 mdsetname_t *sp,
492 int eval
493 )
494 {
495 md_error_t status = mdnullerror;
496 md_error_t *ep = &status;
497
498
499 /* close RPC connections */
500 metarpccloseall();
501
502 if (sp != NULL) {
503 if (meta_unlock(sp, ep) != 0) {
504 mde_perror(ep, "");
505 mdclrerror(ep);
506 if (eval == 0)
507 eval = 1;
508 }
509 }
510
511 /* flush name caches */
512 #ifdef DEBUG
513 metaflushnames(1);
514 #endif /* DEBUG */
515
516 /* log exit */
517 if (metalogfp != NULL) {
518 md_logpfx(metalogfp);
519 (void) fprintf(metalogfp, dgettext(TEXT_DOMAIN,
520 "exiting with %d\n"), eval);
521 flushfp(metalogfp);
522 (void) fclose(metalogfp);
523 metalogfp = NULL;
524 }
525 if ((metasyslog) && (eval != 0)) {
526 syslog(LOG_ERR, dgettext(TEXT_DOMAIN,
527 "exiting with %d\n"), eval);
528 closelog();
529 metasyslog = 0;
530 }
531
532 /* check arena, print malloc usage */
533 #ifdef _DEBUG_MALLOC_INC
534 (void) malloc_chain_check(1);
535 {
536 char *p;
537
538 if (((p = getenv("MD_DEBUG")) != NULL) &&
539 (strstr(p, "MALLOC") != NULL)) {
540 malloc_inuse_end = malloc_inuse(&malloc_histid_end);
541 (void) fprintf(stderr, "%s: end malloc_inuse %lu\n",
542 myname, malloc_inuse_end);
543 if (malloc_inuse_end != malloc_inuse_begin) {
544 malloc_list(fileno(stderr),
545 malloc_histid_begin, malloc_histid_end);
546 }
547 }
548 }
549 #endif /* _DEBUG_MALLOC_INC */
550
551 /* exit with value */
552 exit(eval);
553 }
554
555 /*
556 * signal catcher
557 */
558 static void
md_catcher(int sig)559 md_catcher(
560 int sig
561 )
562 {
563 char buf[128];
564 char *msg;
565 md_error_t status = mdnullerror;
566 md_error_t *ep = &status;
567 struct sigaction defhandler;
568
569 /* log signal */
570 if ((msg = strsignal(sig)) == NULL) {
571 (void) snprintf(buf, sizeof (buf),
572 dgettext(TEXT_DOMAIN, "unknown signal %d"), sig);
573 msg = buf;
574 }
575 md_eprintf("%s\n", msg);
576
577 /*
578 * In roll_back crtical section handling, the first instance of a user
579 * generated signal is caught, a flag is set to allow preemption at a
580 * "convenient" point and md_catcher returns. If the user continues
581 * generate the signal, the second instance will invoke the default
582 * handler and exit.
583 */
584 if (rb_signal_handling == TRUE) {
585 if (sig != SIGABRT && sig != SIGBUS && sig != SIGSEGV) {
586 if (rb_signal_caught == FALSE) {
587 rb_signal_caught = TRUE;
588 rb_signal_which = sig;
589 return;
590 }
591 }
592 }
593
594 /* let default handler do it's thing */
595 if (md_popsig(sig, ep) != 0) {
596 mde_perror(ep, "");
597 mdclrerror(ep);
598 defhandler.sa_flags = 0;
599 if (sigfillset(&defhandler.sa_mask) < 0) {
600 (void) mdsyserror(ep, errno,
601 "sigfillset(&defhandler.sa_mask)");
602 mde_perror(ep, "");
603 md_exit(NULL, 1);
604 }
605 defhandler.sa_handler = SIG_DFL;
606 if (sigaction(sig, &defhandler, NULL) < 0) {
607 (void) mdsyserror(ep, errno, "sigaction(&defhandler)");
608 mde_perror(ep, "");
609 md_exit(NULL, 1);
610 }
611 }
612
613 md_post_sig(sig);
614 }
615
616 void
md_post_sig(int sig)617 md_post_sig(int sig)
618 {
619 if (kill(getpid(), sig) != 0) {
620 md_perror("kill(getpid())");
621 md_exit(NULL, -sig);
622 }
623 }
624
625 int
md_got_sig(void)626 md_got_sig(void)
627 {
628 return (rb_signal_caught);
629 }
630
631 int
md_which_sig(void)632 md_which_sig(void)
633 {
634 return (rb_signal_which);
635 }
636
637 void
md_rb_sig_handling_on(void)638 md_rb_sig_handling_on(void)
639 {
640 rb_signal_handling = TRUE;
641 }
642
643 void
md_rb_sig_handling_off(int sig_seen,int sig)644 md_rb_sig_handling_off(int sig_seen, int sig)
645 {
646 rb_signal_handling = FALSE;
647 rb_signal_caught = FALSE;
648 rb_signal_which = 0;
649 if (sig_seen)
650 md_post_sig(sig);
651 }
652
653 /*
654 * setup metaclust variables
655 */
656 void
setup_mc_log(uint_t level)657 setup_mc_log(
658 uint_t level
659 )
660 {
661 /* initialise externals */
662 verbosity = level;
663 start_time = gethrtime();
664 }
665
666 /*
667 * initilize utility
668 */
669 int
md_init(int argc,char * argv[],int dosyslog,int doadmin,md_error_t * ep)670 md_init(
671 int argc,
672 char *argv[],
673 int dosyslog,
674 int doadmin,
675 md_error_t *ep
676 )
677 {
678 int ret = 0;
679
680 /* initialize everything but the signals */
681 if ((ret = md_init_nosig(argc, argv, dosyslog,
682 doadmin, ep)) != 0)
683 return (ret);
684
685
686 if (sigfillset(&allsigs) < 0)
687 return (mdsyserror(ep, errno, "sigfillset(&allsigs)"));
688
689 /* catch common signals */
690 if ((md_pushsig(SIGHUP, md_catcher, ep) != 0) ||
691 (md_pushsig(SIGINT, md_catcher, ep) != 0) ||
692 (md_pushsig(SIGQUIT, md_catcher, ep) != 0) ||
693 (md_pushsig(SIGABRT, md_catcher, ep) != 0) ||
694 (md_pushsig(SIGBUS, md_catcher, ep) != 0) ||
695 (md_pushsig(SIGSEGV, md_catcher, ep) != 0) ||
696 (md_pushsig(SIGPIPE, md_catcher, ep) != 0) ||
697 (md_pushsig(SIGTERM, md_catcher, ep) != 0)) {
698 return (-1);
699 }
700
701 /* return success */
702 return (0);
703 }
704
705
706 /*
707 * initilize utility without setting up sighandlers
708 * setting up signal handlers in libmeta can affect others
709 * programs that link with libmeta but have their own handlers
710 */
711 int
md_init_nosig(int argc,char * argv[],int dosyslog,int doadmin,md_error_t * ep)712 md_init_nosig(
713 int argc,
714 char *argv[],
715 int dosyslog,
716 int doadmin,
717 md_error_t *ep
718 )
719 {
720 /* setup myname */
721 if ((myname = strrchr(argv[0], '/')) != NULL)
722 ++myname;
723 else
724 myname = argv[0];
725
726 #if !defined(TEXT_DOMAIN)
727 #define TEXT_DOMAIN "SYS_TEST"
728 #endif
729
730 /* print malloc usage */
731 #ifdef _DEBUG_MALLOC_INC
732 {
733 char *p;
734
735 if (((p = getenv("MD_DEBUG")) != NULL) &&
736 (strstr(p, "MALLOC") != NULL)) {
737 malloc_inuse_begin =
738 malloc_inuse(&malloc_histid_begin);
739 (void) fprintf(stderr, "%s: begin malloc_inuse %lu\n",
740 myname, malloc_inuse_begin);
741 }
742 }
743 #endif /* _DEBUG_MALLOC_INC */
744
745 /* open syslog */
746 if (dosyslog)
747 md_syslog(myname);
748
749 /* log command */
750 if (getenv(METALOGENV) != NULL) {
751 if ((metalogfp = fopen(METALOG, "a")) != NULL) {
752 int i;
753
754 (void) fchmod(fileno(metalogfp), 0664);
755 md_logpfx(metalogfp);
756 for (i = 1; (i < argc); ++i)
757 (void) fprintf(metalogfp, " %s", argv[i]);
758 (void) fprintf(metalogfp, "\n");
759 flushfp(metalogfp);
760 }
761 }
762
763 /* make sure we can open the admin device before we do anything else */
764 if (doadmin)
765 if (open_admin(ep) < 0)
766 return (-1);
767
768 /* flush name caches */
769 metaflushnames(1);
770
771 /* return success */
772 return (0);
773 }
774
775 /*
776 * (re)initilize daemon
777 */
778 int
md_init_daemon(char * name,md_error_t * ep)779 md_init_daemon(
780 char *name,
781 md_error_t *ep
782 )
783 {
784 static int already = 0;
785 int dosyslog = 1;
786 int doadmin = 1;
787
788 /* setup */
789 if (! already) {
790 if (md_init(1, &name, dosyslog, doadmin, ep) != 0)
791 return (-1);
792 already = 1;
793 }
794
795 /* return success */
796 return (0);
797 }
798
799 /*
800 * Roll back functions for handling sync and async cleanup.
801 */
802
803 int
procsigs(int block,sigset_t * oldsigs,md_error_t * ep)804 procsigs(int block, sigset_t *oldsigs, md_error_t *ep)
805 {
806 if (block == TRUE) {
807 if (sigprocmask(SIG_BLOCK, &allsigs, oldsigs) < 0) {
808 (void) mdsyserror(ep, errno, "sigprocmask(SIG_BLOCK)");
809 return (-1);
810 }
811 } else {
812 if (sigprocmask(SIG_SETMASK, oldsigs, NULL) < 0) {
813 (void) mdsyserror(ep, errno,
814 "sigprocmask(SIG_SETMASK)");
815 return (-1);
816 }
817 }
818 return (0);
819 }
820
821 #ifdef DEBUG
822 int
rb_test(int rbt_sel_tpt,char * rbt_sel_tag,md_error_t * ep)823 rb_test(
824 int rbt_sel_tpt,
825 char *rbt_sel_tag,
826 md_error_t *ep
827 )
828 {
829 char *rbt_env_tpt = getenv("META_RBT_TPT");
830 char *rbt_env_tag = getenv("META_RBT_TAG");
831 int sig = 0;
832 int rbt_int_tpt;
833 int rbt_tag_match = 1;
834 sigset_t curmask;
835 md_error_t xep = mdnullerror;
836
837 if (rbt_env_tpt) {
838 rbt_int_tpt = atoi(rbt_env_tpt);
839 if (rbt_int_tpt < 0) {
840 sig = 1;
841 rbt_int_tpt = -1 * rbt_int_tpt;
842 }
843
844 assert(rbt_sel_tpt != 0);
845
846 if (rbt_int_tpt == 0)
847 return (0);
848
849 if (rbt_env_tag && rbt_sel_tag)
850 if (strcmp(rbt_env_tag, rbt_sel_tag) != 0)
851 rbt_tag_match = 0;
852
853 if (rbt_int_tpt == rbt_sel_tpt && rbt_tag_match) {
854 md_eprintf(
855 "******************** RB_TEST(%s, %d, sig=%s)\n",
856 rbt_sel_tag, rbt_sel_tpt,
857 (sig != 0) ? "True" : "False");
858 if (sig) {
859 md_eprintf("********** sigsuspend()\n");
860 if (sigprocmask(NULL, NULL, &curmask) < 0) {
861 (void) mdsyserror(&xep, errno, NULL);
862 mde_perror(&xep, "sigprocmask(GET)");
863 md_exit(NULL, 1);
864 }
865
866 if (sigsuspend(&curmask) < 0) {
867 (void) mdsyserror(&xep, errno, NULL);
868 mde_perror(&xep,
869 "sigsuspend(&curmask)");
870 md_exit(NULL, 1);
871 }
872
873 if (md_got_sig())
874 return (-1);
875 }
876 (void) mderror(ep, MDE_TESTERROR,
877 "********** rb_test()");
878 md_eprintf("******************** rollback\n");
879 return (-1);
880 }
881 }
882 return (0);
883 }
884 #else
885 /* ARGSUSED */
886 int
rb_test(int rbt_sel_tpt,char * rbt_sel_tag,md_error_t * ep)887 rb_test(
888 int rbt_sel_tpt,
889 char *rbt_sel_tag,
890 md_error_t *ep
891 )
892 {
893 (void) mderror(ep, MDE_TESTERROR, "******** rb_test:Not supported\n");
894 return (-1);
895
896 }
897 #endif /* DEBUG */
898