10Sstevel@tonic-gate /* 20Sstevel@tonic-gate * CDDL HEADER START 30Sstevel@tonic-gate * 40Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*9694SScott.Rotondo@Sun.COM * Common Development and Distribution License (the "License"). 6*9694SScott.Rotondo@Sun.COM * You may not use this file except in compliance with the License. 70Sstevel@tonic-gate * 80Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 90Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 100Sstevel@tonic-gate * See the License for the specific language governing permissions 110Sstevel@tonic-gate * and limitations under the License. 120Sstevel@tonic-gate * 130Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 140Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 150Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 160Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 170Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 180Sstevel@tonic-gate * 190Sstevel@tonic-gate * CDDL HEADER END 200Sstevel@tonic-gate */ 210Sstevel@tonic-gate /* 220Sstevel@tonic-gate * db_headers.h 230Sstevel@tonic-gate * 24*9694SScott.Rotondo@Sun.COM * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 25702Sth160488 * Use is subject to license terms. 260Sstevel@tonic-gate */ 270Sstevel@tonic-gate 280Sstevel@tonic-gate #ifndef _DB_HEADERS_H 290Sstevel@tonic-gate #define _DB_HEADERS_H 300Sstevel@tonic-gate 310Sstevel@tonic-gate #include <rpc/rpc.h> 320Sstevel@tonic-gate #include <syslog.h> 330Sstevel@tonic-gate #include <stdlib.h> 340Sstevel@tonic-gate #include <setjmp.h> 350Sstevel@tonic-gate 36*9694SScott.Rotondo@Sun.COM #ifdef __cplusplus 37*9694SScott.Rotondo@Sun.COM extern "C" { 38*9694SScott.Rotondo@Sun.COM #endif 39*9694SScott.Rotondo@Sun.COM 400Sstevel@tonic-gate extern int verbose; 41*9694SScott.Rotondo@Sun.COM 42*9694SScott.Rotondo@Sun.COM #ifdef __cplusplus 43*9694SScott.Rotondo@Sun.COM } 44*9694SScott.Rotondo@Sun.COM #endif 45*9694SScott.Rotondo@Sun.COM 460Sstevel@tonic-gate extern jmp_buf dbenv; 470Sstevel@tonic-gate 480Sstevel@tonic-gate #define FATAL(msg, fcode) \ 490Sstevel@tonic-gate { \ 500Sstevel@tonic-gate syslog(LOG_ERR, "ERROR: %s", (msg)); \ 510Sstevel@tonic-gate __nisdb_get_tsd()->fatalcode = (int)(fcode); \ 520Sstevel@tonic-gate __nisdb_get_tsd()->fatalmsg = msg; \ 530Sstevel@tonic-gate return; \ 540Sstevel@tonic-gate } 550Sstevel@tonic-gate #define FATAL3(msg, fcode, retval) \ 560Sstevel@tonic-gate { \ 570Sstevel@tonic-gate syslog(LOG_ERR, "ERROR: %s", (msg)); \ 580Sstevel@tonic-gate __nisdb_get_tsd()->fatalcode = (int)(fcode); \ 590Sstevel@tonic-gate __nisdb_get_tsd()->fatalmsg = msg; \ 600Sstevel@tonic-gate return (retval); \ 610Sstevel@tonic-gate } 620Sstevel@tonic-gate 630Sstevel@tonic-gate #ifdef NISDB_MT_DEBUG 640Sstevel@tonic-gate #define LOCKVAL(lockcall, msg, lockcode) \ 650Sstevel@tonic-gate { \ 660Sstevel@tonic-gate lockcode = lockcall(); \ 670Sstevel@tonic-gate if (lockcode != 0) { \ 680Sstevel@tonic-gate __nisdb_get_tsd()->fatalcode = lockcode; \ 690Sstevel@tonic-gate __nisdb_get_tsd()->fatalmsg = msg; \ 700Sstevel@tonic-gate abort(); \ 710Sstevel@tonic-gate } \ 720Sstevel@tonic-gate } 730Sstevel@tonic-gate #else 740Sstevel@tonic-gate #define LOCKVAL(lockcall, msg, lockcode) \ 750Sstevel@tonic-gate { \ 760Sstevel@tonic-gate lockcode = lockcall(); \ 770Sstevel@tonic-gate if (lockcode != 0) { \ 780Sstevel@tonic-gate __nisdb_get_tsd()->fatalcode = lockcode; \ 790Sstevel@tonic-gate __nisdb_get_tsd()->fatalmsg = msg; \ 800Sstevel@tonic-gate } \ 810Sstevel@tonic-gate } 820Sstevel@tonic-gate #endif /* NISDB_MT_DEBUG */ 830Sstevel@tonic-gate 840Sstevel@tonic-gate #define LOCKV(lockcall, msg) \ 850Sstevel@tonic-gate { \ 860Sstevel@tonic-gate int lockcode; \ 870Sstevel@tonic-gate LOCKVAL(lockcall, msg, lockcode); \ 880Sstevel@tonic-gate if (lockcode != 0) \ 890Sstevel@tonic-gate return; \ 900Sstevel@tonic-gate } 910Sstevel@tonic-gate #define LOCK(lockcall, retval, msg) \ 920Sstevel@tonic-gate { \ 930Sstevel@tonic-gate int lockcode; \ 940Sstevel@tonic-gate LOCKVAL(lockcall, msg, lockcode); \ 950Sstevel@tonic-gate if (lockcode != 0) \ 960Sstevel@tonic-gate return (retval); \ 970Sstevel@tonic-gate } 980Sstevel@tonic-gate 990Sstevel@tonic-gate /* Read lock/unlock 'this', return 'retval' is unsuccessful, and save 'msg' */ 1000Sstevel@tonic-gate #define READLOCK(this, retval, msg) \ 1010Sstevel@tonic-gate LOCK(this->acqnonexcl, retval, msg) 1020Sstevel@tonic-gate #define READUNLOCK(this, retval, msg) \ 1030Sstevel@tonic-gate LOCK(this->relnonexcl, retval, msg) 1040Sstevel@tonic-gate 1050Sstevel@tonic-gate /* Ditto, but return without a value (i.e., a "void" function */ 1060Sstevel@tonic-gate #define READLOCKV(this, msg) \ 1070Sstevel@tonic-gate LOCKV(this->acqnonexcl, msg) 1080Sstevel@tonic-gate #define READUNLOCKV(this, msg) \ 1090Sstevel@tonic-gate LOCKV(this->relnonexcl, msg) 1100Sstevel@tonic-gate 1110Sstevel@tonic-gate /* As READLOCK/READUNLOCK, but set rescode instead of returning on failure */ 1120Sstevel@tonic-gate #define READLOCKNR(this, rescode, msg) \ 1130Sstevel@tonic-gate LOCKVAL(this->acqnonexcl, msg, rescode) 1140Sstevel@tonic-gate #define READUNLOCKNR(this, rescode, msg) \ 1150Sstevel@tonic-gate LOCKVAL(this->relnonexcl, msg, rescode) 1160Sstevel@tonic-gate 1170Sstevel@tonic-gate /* As READLOCK/READUNLOCK, but use a write lock */ 1180Sstevel@tonic-gate #define WRITELOCK(this, retval, msg) \ 1190Sstevel@tonic-gate LOCK(this->acqexcl, retval, msg) 1200Sstevel@tonic-gate #define WRITEUNLOCK(this, retval, msg) \ 1210Sstevel@tonic-gate LOCK(this->relexcl, retval, msg) 1220Sstevel@tonic-gate 1230Sstevel@tonic-gate /* Non-blocking write lock */ 1240Sstevel@tonic-gate #define TRYWRITELOCK(this, rescode, msg) \ 1250Sstevel@tonic-gate LOCKVAL(this->tryacqexcl, msg, rescode) 1260Sstevel@tonic-gate 1270Sstevel@tonic-gate /* Ditto, but return without a value */ 1280Sstevel@tonic-gate #define WRITELOCKV(this, msg) \ 1290Sstevel@tonic-gate LOCKV(this->acqexcl, msg) 1300Sstevel@tonic-gate #define WRITEUNLOCKV(this, msg) \ 1310Sstevel@tonic-gate LOCKV(this->relexcl, msg) 1320Sstevel@tonic-gate 1330Sstevel@tonic-gate /* As WRITELOCK/WRITEUNLOCK, but set rescode instead of returning on failure */ 1340Sstevel@tonic-gate #define WRITELOCKNR(this, rescode, msg) \ 1350Sstevel@tonic-gate LOCKVAL(this->acqexcl, msg, rescode) 1360Sstevel@tonic-gate #define WRITEUNLOCKNR(this, rescode, msg) \ 1370Sstevel@tonic-gate LOCKVAL(this->relexcl, msg, rescode) 1380Sstevel@tonic-gate 1390Sstevel@tonic-gate /* Apply a second write lock when already holding another write lock */ 1400Sstevel@tonic-gate #define WRITELOCK2(this, retval, msg, that) \ 1410Sstevel@tonic-gate if (this != 0) { \ 1420Sstevel@tonic-gate int lockcode1, lockcode2; \ 1430Sstevel@tonic-gate WRITELOCKNR(this, lockcode2, msg); \ 1440Sstevel@tonic-gate if (lockcode2 != 0) { \ 1450Sstevel@tonic-gate if (that != 0) { \ 1460Sstevel@tonic-gate WRITEUNLOCKNR(that, lockcode1, msg); \ 1470Sstevel@tonic-gate } \ 1480Sstevel@tonic-gate return (retval); \ 1490Sstevel@tonic-gate } \ 1500Sstevel@tonic-gate } 1510Sstevel@tonic-gate /* Release two write locks */ 1520Sstevel@tonic-gate #define WRITEUNLOCK2(this, that, retval1, retval2, msg1, msg2) \ 1530Sstevel@tonic-gate { \ 1540Sstevel@tonic-gate int lockcode1 = 0, lockcode2 = 0; \ 1550Sstevel@tonic-gate if (this != 0) { \ 1560Sstevel@tonic-gate WRITEUNLOCKNR(this, lockcode1, msg1); \ 1570Sstevel@tonic-gate } \ 1580Sstevel@tonic-gate if (that != 0) { \ 1590Sstevel@tonic-gate WRITEUNLOCKNR(that, lockcode2, msg2); \ 1600Sstevel@tonic-gate } \ 1610Sstevel@tonic-gate if (lockcode2 != 0) { \ 1620Sstevel@tonic-gate return (retval2); \ 1630Sstevel@tonic-gate } else if (lockcode1 != 0) { \ 1640Sstevel@tonic-gate return (retval1); \ 1650Sstevel@tonic-gate } \ 1660Sstevel@tonic-gate } 1670Sstevel@tonic-gate 1680Sstevel@tonic-gate /* Apply a second read lock when already holding another read lock */ 1690Sstevel@tonic-gate #define READLOCK2(this, retval, msg, that) \ 1700Sstevel@tonic-gate if (this != 0) { \ 1710Sstevel@tonic-gate int lockcode1, lockcode2; \ 1720Sstevel@tonic-gate READLOCKNR(this, lockcode2, msg); \ 1730Sstevel@tonic-gate if (lockcode2 != 0) { \ 1740Sstevel@tonic-gate if (that != 0) { \ 1750Sstevel@tonic-gate READUNLOCKNR(that, lockcode1, msg); \ 1760Sstevel@tonic-gate } \ 1770Sstevel@tonic-gate return (retval); \ 1780Sstevel@tonic-gate } \ 1790Sstevel@tonic-gate } 1800Sstevel@tonic-gate /* Release two read locks */ 1810Sstevel@tonic-gate #define READUNLOCK2(this, that, retval1, retval2, msg1, msg2) \ 1820Sstevel@tonic-gate { \ 1830Sstevel@tonic-gate int lockcode1 = 0, lockcode2 = 0; \ 1840Sstevel@tonic-gate if (this != 0) { \ 1850Sstevel@tonic-gate READUNLOCKNR(this, lockcode1, msg1); \ 1860Sstevel@tonic-gate } \ 1870Sstevel@tonic-gate if (that != 0) { \ 1880Sstevel@tonic-gate READUNLOCKNR(that, lockcode2, msg2); \ 1890Sstevel@tonic-gate } \ 1900Sstevel@tonic-gate if (lockcode2 != 0) { \ 1910Sstevel@tonic-gate return (retval2); \ 1920Sstevel@tonic-gate } else if (lockcode1 != 0) { \ 1930Sstevel@tonic-gate return (retval1); \ 1940Sstevel@tonic-gate } \ 1950Sstevel@tonic-gate } 1960Sstevel@tonic-gate 1970Sstevel@tonic-gate #define ASSERTWRITELOCKHELD(lvar, retval, msg) \ 1980Sstevel@tonic-gate { \ 1990Sstevel@tonic-gate int lc; \ 2000Sstevel@tonic-gate if ((lc = __nisdb_assert_wheld(&lvar ## _rwlock)) != 0) { \ 2010Sstevel@tonic-gate __nisdb_get_tsd()->fatalcode = lc; \ 2020Sstevel@tonic-gate __nisdb_get_tsd()->fatalmsg = msg; \ 2030Sstevel@tonic-gate return (retval); \ 2040Sstevel@tonic-gate } \ 2050Sstevel@tonic-gate } 2060Sstevel@tonic-gate 2070Sstevel@tonic-gate #define WARNING(x) { syslog(LOG_ERR, "WARNING: %s", (x)); } 2080Sstevel@tonic-gate 2090Sstevel@tonic-gate #define WARNING_M(x) { syslog(LOG_ERR, "WARNING: %s: %m", (x)); } 2100Sstevel@tonic-gate 2110Sstevel@tonic-gate 2120Sstevel@tonic-gate enum db_status {DB_SUCCESS, DB_NOTFOUND, DB_NOTUNIQUE, 2130Sstevel@tonic-gate DB_BADTABLE, DB_BADQUERY, DB_BADOBJECT, 2140Sstevel@tonic-gate DB_MEMORY_LIMIT, DB_STORAGE_LIMIT, DB_INTERNAL_ERROR, 2150Sstevel@tonic-gate DB_BADDICTIONARY, DB_SYNC_FAILED, DB_LOCK_ERROR}; 2160Sstevel@tonic-gate typedef enum db_status db_status; 2170Sstevel@tonic-gate 2180Sstevel@tonic-gate enum db_action {DB_LOOKUP, DB_REMOVE, DB_ADD, DB_FIRST, DB_NEXT, DB_ALL, 2190Sstevel@tonic-gate DB_RESET_NEXT, DB_ADD_NOLOG, 2200Sstevel@tonic-gate DB_ADD_NOSYNC, DB_REMOVE_NOSYNC }; 2210Sstevel@tonic-gate typedef enum db_action db_action; 2220Sstevel@tonic-gate 223702Sth160488 #endif /* _DB_HEADERS_H */ 224