|
|
1.1 ! root 1: /* ! 2: ** Copyright (c) 1983 Relational Technology Inc. ! 3: ** ! 4: ** IIDR.H - structures for the INGRES lock driver ! 5: ** ! 6: ** Description: ! 7: ** Defines the constants and the structures used by the lock device. ! 8: */ ! 9: ! 10: /* The request codes to the lock device. */ ! 11: ! 12: /* These are opcodes used by the lock driver when it is called as ! 13: ** a minor device. ! 14: */ ! 15: # define KN_O_LOCK 1 ! 16: # define KN_O_UNLOCK 2 ! 17: # define KN_O_CONVERT 3 ! 18: # define KN_O_RELEASE 4 ! 19: # define KN_O_UNIQ 5 ! 20: # define KN_O_DBCONSIST 6 ! 21: ! 22: /* These are codes used by the lock driver when it is called as ! 23: ** a major device. ! 24: */ ! 25: # define KN_O_USERSLOT 1 ! 26: # define KN_O_PRINT_STRUCTURES 2 ! 27: # define KN_O_DEBUGLEVEL 3 ! 28: # define KN_O_RESET_LOCKDRIVER 4 ! 29: ! 30: /* ! 31: ** Ioctl's have the command encoded in the lower word, ! 32: ** and the size of any in or out parameters in the upper ! 33: ** word. The high 2 bits of the upper word are used ! 34: ** to encode the in/out status of the parameter; for now ! 35: ** we restrict parameters to at most 128 bytes. ! 36: ** ! 37: ** For some reason bit 29 is always set. ! 38: ** ! 39: ** The high two bits (31 and 30) mean: ! 40: ** 00 (2) - Void - no parameters ! 41: ** 10 (a) - In parameter ! 42: ** 01 (6) - Out parameter ! 43: ** 11 (e) - in/out parameter ! 44: */ ! 45: ! 46: /* Command qualification for OS, currently unused by INGRES */ ! 47: # define KN_QUAL ('i' << 8) ! 48: ! 49: /* bits to shift for parameter type */ ! 50: # define KN_P_TSHIFT 28 ! 51: ! 52: /* descriptions of parameters */ ! 53: # define KN_P_VOID (0x2 << KN_P_TSHIFT) ! 54: # define KN_P_OUT (0x6 << KN_P_TSHIFT) ! 55: # define KN_P_IN (0xa << KN_P_TSHIFT) ! 56: # define KN_P_INOUT (0xe << KN_P_TSHIFT) ! 57: ! 58: /* bits to shift parameter size */ ! 59: # define KN_P_SSHIFT 16 ! 60: ! 61: /* size of minor device parameters, in sizoef quantities */ ! 62: # define KN_SZ_LOCK (sizeof(LOCK_KEY) << KN_P_SSHIFT) ! 63: # define KN_SZ_UNLOCK (sizeof(short) << KN_P_SSHIFT) ! 64: # define KN_SZ_CONVERT (sizeof(short) << KN_P_SSHIFT) ! 65: # define KN_SZ_RELEASE 0 ! 66: # define KN_SZ_UNIQ (2 * sizeof(int) << KN_P_SSHIFT) ! 67: # define KN_SZ_DBCONSIST (sizeof(int) << KN_P_SSHIFT) ! 68: ! 69: /* size of major device parameters, in sizeof() quantities */ ! 70: # define KN_SZ_USERSLOT (sizeof(int) << KN_P_SSHIFT) ! 71: # define KN_SZ_PRINT_STRUCTURES (sizeof(int) << KN_P_SSHIFT) ! 72: # define KN_SZ_DEBUGLEVEL (sizeof(int) << KN_P_SSHIFT) ! 73: # define KN_SZ_RESET_LOCKDRIVER 0 ! 74: ! 75: # define KN_R_LOCK (KN_QUAL | KN_P_IN | KN_O_LOCK | KN_SZ_LOCK) ! 76: # define KN_R_UNLOCK (KN_QUAL | KN_P_IN | KN_O_UNLOCK | KN_SZ_UNLOCK) ! 77: # define KN_R_CONVERT (KN_QUAL | KN_P_IN | KN_O_CONVERT | KN_SZ_CONVERT) ! 78: # define KN_R_RELEASE (KN_QUAL | KN_P_VOID | KN_O_RELEASE | KN_SZ_RELEASE) ! 79: # define KN_R_UNIQ (KN_QUAL | KN_P_OUT | KN_O_UNIQ | KN_SZ_UNIQ) ! 80: # define KN_R_DBCONSIST (KN_QUAL | KN_P_IN | KN_O_DBCONSIST | KN_SZ_DBCONSIST) ! 81: ! 82: /* These are opcodes to be used when connected to the major device */ ! 83: # define KN_R_USERSLOT (KN_QUAL | KN_P_OUT | KN_SZ_USERSLOT | KN_O_USERSLOT) ! 84: # define KN_R_PRINT_STRUCTURES (KN_QUAL | KN_P_IN | KN_SZ_PRINT_STRUCTURES | KN_O_PRINT_STRUCTURES) ! 85: # define KN_R_DEBUGLEVEL (KN_QUAL | KN_P_IN | KN_SZ_DEBUGLEVEL | KN_O_DEBUGLEVEL) ! 86: # define KN_R_RESET_LOCKDRIVER (KN_QUAL | KN_P_VOID | KN_SZ_RESET_LOCKDRIVER | KN_O_RESET_LOCKDRIVER) ! 87: ! 88: /* ! 89: ** These are the parameters to be passed in "addr" on a ! 90: ** KN_R_PRINT_STRUCTURES call. ! 91: */ ! 92: # define KN_P_USERS 1 ! 93: # define KN_P_LKB 2 ! 94: # define KN_P_HASH 3 ! 95: # define KN_P_STAT 4 ! 96: # define KN_P_RSB 5 ! 97: ! 98: /* The lock modes that the device supports */ ! 99: ! 100: # define KN_M_NL 0 ! 101: # define KN_M_CR 1 ! 102: # define KN_M_CW 2 ! 103: # define KN_M_PR 3 ! 104: # define KN_M_PW 4 ! 105: # define KN_M_EX 5 ! 106: ! 107: /* Possible extra return values from the lock device */ ! 108: ! 109: # define EDEADLOCK 60 ! 110: # define ECHILDREN 61 ! 111: # define ELOCKID 62 ! 112: # define ENOTQUEUED 63 ! 113: # define ERESOURCE 64 ! 114: # define EBUG 65 ! 115: # define ECONSIST 66 /* Couldn't grant lock - data base has gone ! 116: ** inconsistent ! 117: */ ! 118: # define EFLAG_SAME 67 /* Call to KN_R_CONSIST resulted in state ! 119: ** remaining the same. ! 120: */ ! 121: # define ELOCKMODE_INVALID 68 ! 122: # define EOPCODE_INVALID 69 ! 123: # define EWAIT_INTR 70 ! 124: # define EPANIC 71 /* lock driver is in a panic ! 125: ** state. Rather than crashing ! 126: ** the machine, disallow all ! 127: ** ioctl requests by minor de- ! 128: ** vices. ! 129: */ ! 130: ! 131: /* Types of locks that the lock driver knows about */ ! 132: # define LCK_DATABASE 0x4949 /* 'II' */ ! 133: ! 134: /* The structure used by the user to pass lock key information to the lock device. */ ! 135: ! 136: typedef struct ! 137: { ! 138: short lk_parent; /* parentid when setting a lock */ ! 139: unsigned short lk_type; /* the type of lock */ ! 140: long lk_key; /* the key when setting a lock */ ! 141: short lk_installation; /* installation constant */ ! 142: } LOCK_KEY; ! 143: ! 144: /* Collect performance numbers about the lock device in this structure. */ ! 145: ! 146: typedef struct ! 147: { ! 148: long ii_locks; /* number of lock requests */ ! 149: long ii_unlocks; /* number of unlocks requests */ ! 150: long ii_converts; /* number of conversion requests */ ! 151: long ii_lockwaits; /* number of lock requests that waited */ ! 152: long ii_waitconverts; /* number of convert requests that waited */ ! 153: long ii_deadconverts; /* number of conversion deadlocks */ ! 154: long ii_deadsearchs; /* number of deadlock searches performed */ ! 155: long ii_deadlocks; /* number of resource deadlocks found */ ! 156: } STAT; ! 157: ! 158: /* ! 159: ** CMD ! 160: ** ! 161: ** This structure really wants to be a bitfield, but this format ! 162: ** does not work on different architectures. On machines with ! 163: ** BYTE_SWAP the structure needs to defined differently than on ! 164: ** a VAX. ! 165: ** ! 166: ** Finally on the Pyramid BITFIELDS are not pushed and popped as ! 167: ** if they were ints. Since ioctl expects the cmd argument to be ! 168: ** an int we must define CMD as an int and use bit-masking, and ! 169: ** shifting to get the values out. ! 170: ** ! 171: ** The format of a request code to the lock device. ! 172: ** ! 173: ** typedef struct ! 174: ** { ! 175: ** unsigned cmd_opcode:3; ** function code ! 176: ** ! 177: ** unsigned cmd_lock_mode:3; ** lock mode ! 178: ** ! 179: ** unsigned cmd_no_queue:1; ** don't wait modifier ! 180: ** ! 181: ** unsigned cmd_ignore_econsist:1; ** modifier tells lock driver ! 182: ** ** to ignore the fact that the ! 183: ** ** data base may be ! 184: ** ** inconsistent ! 185: ** ** ! 186: ** } CMD; ! 187: ** ! 188: ** ! 189: ** bits of the command: ! 190: ** bits 0-2: opcode. ! 191: ** bits 3-5: lock_mode. ! 192: ** bit 6 : wait/nowait modifier ! 193: ** bit 7 : ignore consistent database modifyer ! 194: ** bits 8-15: qualifier to operating system. ! 195: ** this is usually a single character. ! 196: ** we use 'i', which is not used currently ! 197: ** for anything. ! 198: ** bits 16-23:size of the parameter being passed through ! 199: ** "addr" the third argument of the ioctl call. ! 200: ** bits 24-28: ? ! 201: ** bits 29-31: used to encode whether the parameter is ! 202: ** in, out, in/out, or not used. (see above ! 203: ** for description.) ! 204: */ ! 205: # define CMD_OPCODE(cmd) (0x00000007 & (cmd)) ! 206: # define CMD_LOCK_MODE(cmd) (0x00000007 & ((cmd) >> 3)) ! 207: # define CMD_NO_QUEUE(cmd) (0x00000001 & ((cmd) >> 6)) ! 208: # define CMD_IGNORE_ECONSIST(cmd) (0x00000001 & ((cmd) >> 7)) ! 209: ! 210: ! 211: # ifndef QUE_DEF ! 212: # define QUE_DEF 1 ! 213: typedef struct _QUEUE QUEUE; ! 214: ! 215: struct _QUEUE ! 216: { ! 217: QUEUE *q_next; ! 218: QUEUE *q_prev; ! 219: }; ! 220: ! 221: # endif QUE_DEF ! 222: ! 223: QUEUE *remque_30(); ! 224: QUEUE *insque_30(); ! 225: ! 226: typedef struct _LKB LKB; ! 227: typedef struct _RSB RSB; ! 228: ! 229: /* ! 230: ** A Resource Block. ! 231: ** An RSB is allocated for each unique key that is locked. ! 232: ** It contains information about that states of locks queued against this resource. ! 233: */ ! 234: ! 235: struct _RSB ! 236: { ! 237: QUEUE rsb_next; /* next of hash chain */ ! 238: QUEUE rsb_wait_lkb; /* queue of waiting locks */ ! 239: QUEUE rsb_grant_lkb; /* queue of granted locks followed by conversion requests */ ! 240: RSB *rsb_parent; /* parent resource */ ! 241: LKB *rsb_deadlock_next; /* used to save next on recursion in deadlock tree */ ! 242: LKB *rsb_deadlock_curr; /* used to save curr on recursion in deadlock tree */ ! 243: int rsb_pad; /* for future use */ ! 244: union ! 245: { ! 246: LOCK_KEY rsb_lk; /* used to save lock from user */ ! 247: struct ! 248: { ! 249: unsigned char rsb_xgrant_mode; /* granted mode of locked */ ! 250: unsigned char rsb_xconvert_mode; /* effective convert mode */ ! 251: short rsb_xtype; /* first part of the key */ ! 252: long rsb_xrkey; /* second part of the key */ ! 253: short rsb_xrinstallation; /* installation key */ ! 254: } rsb_actual; ! 255: } rsb_key; ! 256: }; ! 257: ! 258: # define rsb_grant_mode rsb_key.rsb_actual.rsb_xgrant_mode ! 259: # define rsb_convert_mode rsb_key.rsb_actual.rsb_xconvert_mode ! 260: # define rsb_depth rsb_key.rsb_actual.rsb_xdepth ! 261: # define rsb_type rsb_key.rsb_actual.rsb_xtype ! 262: # define rsb_rkey rsb_key.rsb_actual.rsb_xrkey ! 263: # define rsb_rinstallation rsb_key.rsb_actual.rsb_xrinstallation ! 264: ! 265: /* ! 266: ** The User structure. ! 267: ** Contains information about processes that currently have the lock device open. ! 268: ** Used to store information that can't be put in the 'u' struct. ! 269: */ ! 270: ! 271: typedef struct ! 272: { ! 273: short usr_minor_dev_number; /* This will be the minor ! 274: ** device number of the driver ! 275: ** that the user is connected ! 276: ** to. ! 277: ** In the case of the major ! 278: ** device this number will be ! 279: ** 0. This number will not ! 280: ** be unique for users con- ! 281: ** nected to the major device. ! 282: ** All opcodes implemented for ! 283: ** the major device should not ! 284: ** need this number to be unique ! 285: ** (ie. they should not need ! 286: ** context saved between calls). ! 287: */ ! 288: ! 289: char usr_state; /* miscellaneous status info */ ! 290: ! 291: char usr_visited; /* noded visited marked for ! 292: ** deadlock search ! 293: */ ! 294: ! 295: char usr_inconsistent_flag; /* This is the flag twiddled by ! 296: ** the user by using ! 297: ** KN_R_CONSIST. If this flag ! 298: ** is set when the user exits ! 299: ** then the database is ! 300: ** inconsistent. ! 301: */ ! 302: ! 303: char usr_db_inconsistent; /* if this flag is set then the ! 304: ** the database is inconsistent ! 305: */ ! 306: ! 307: char usr_made_db_inconsistent; /* if this flag is set then ! 308: ** this user was the one that ! 309: ** made the db inconsistent. ! 310: */ ! 311: ! 312: char usr_not_used; /* keep structure 16 byte ! 313: ** alligned. ! 314: */ ! 315: ! 316: RSB *usr_db_resource; /* This is a pointer to the ! 317: ** database lock held by the ! 318: ** user. This is the only case ! 319: ** where the lockdriver "knows" ! 320: ** about types of locks. ! 321: */ ! 322: ! 323: LKB *usr_wait; /* lock that we are waiting ! 324: ** on ! 325: */ ! 326: ! 327: } USR; ! 328: ! 329: # define USR_NULLSTATE 00 ! 330: # define USR_WAIT 01 ! 331: # define USR_VISITED 01 ! 332: # define USR_NOTVISITED 00 ! 333: ! 334: /* used for usr_made_db_inconsistent */ ! 335: # define USR_USR_INCONSISTENT 01 ! 336: ! 337: /* used for usr_db_inconsistent */ ! 338: # define USR_DB_INCONSISTENT 01 ! 339: ! 340: /* ! 341: ** The Lock Block. ! 342: ** Contains information about a given processes lock request against a resource. ! 343: */ ! 344: ! 345: struct _LKB ! 346: { ! 347: QUEUE lkb_next; /* next LBK of the same type */ ! 348: LKB *lkb_parent; /* parent lock block */ ! 349: RSB *lkb_rsb; /* associated resource block */ ! 350: USR *lkb_usr; /* owning process */ ! 351: unsigned char lkb_grant_mode; /* granted mode */ ! 352: unsigned char lkb_request_mode; /* requested lock mode */ ! 353: unsigned char lkb_state; /* current lock state */ ! 354: unsigned char lkb_children; /* number of child locks */ ! 355: }; ! 356: ! 357: # define LKB_FREE 0 ! 358: # define LKB_GRANT 1 ! 359: # define LKB_CONVERT 2 ! 360: # define LKB_WAIT 3 ! 361: # define LKB_E_WAIT_ECONSIST 4 /* lock wait was aborted due to the db going inconsistent */ ! 362: # define LKB_E_CONVERT_ECONSIST 5 /* lock wait on a convert was aborted due to the db going ! 363: ** inconsistent. ! 364: */ ! 365: ! 366: /* The following macro is used because SV lock drivers set errno by ! 367: ** setting u.u_error, while 4.2 lock drivers do it by returning a value. ! 368: */ ! 369: #define BSD 1 /* Power6/32 is a bsd site */ ! 370: # ifdef BSD ! 371: # define SET_ERRNO(a) ! 372: # endif BSD ! 373: ! 374: # ifdef WECO ! 375: # define SET_ERRNO(a) set_errno(a) ! 376: # endif WECO ! 377: ! 378: /* UPRINTF ! 379: ** On BSD systems uprintf prints to the user's terminal. This feature ! 380: ** is not availiable to SV systems so we use printf instead. ! 381: */ ! 382: # ifdef BSD ! 383: # define UPRINTF uprintf ! 384: # endif BSD ! 385: ! 386: # ifdef WECO ! 387: # define UPRINTF printf ! 388: # endif WECO
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.