00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include <eyedbconfig.h>
00025
00026 #include <stdlib.h>
00027 #include <stdarg.h>
00028 #include <fcntl.h>
00029 #include <string.h>
00030 #include <signal.h>
00031 #include <unistd.h>
00032 #include <errno.h>
00033 #include <sys/types.h>
00034 #include <sys/stat.h>
00035 #include <sys/mman.h>
00036 #include <pthread.h>
00037
00038 #include <eyedblib/machtypes.h>
00039 #include <eyedblib/filelib.h>
00040 #include <eyedblib/butils.h>
00041 #include <transaction.h>
00042 #include <eyedbsm_p.h>
00043 #include <hashtable.h>
00044 #include <lock.h>
00045 #include <eyedblib/iassert.h>
00046 #include <kern.h>
00047 #include <kern_p.h>
00048
00049 using namespace eyedbsm;
00050
00051 #define PROG "eyedbsmtool"
00052
00053 static const TransactionParams params_X = {
00054 TransactionOn,
00055 DatabaseW,
00056 RecoveryFull,
00057 0,
00058 0,
00059 1
00060 };
00061
00062 #define sm_CHECK(S, MSG) (statusPrint(S, MSG) ? 1 : 0)
00063
00064 #define BEGIN(s) \
00065 s = transactionBegin(dbh, (const TransactionParams *)0); \
00066 if (s) return sm_CHECK(s, "transaction begin")
00067
00068 #define BEGIN_X(s) \
00069 s = transactionBegin(dbh, ¶ms_X); \
00070 if (s) {if (s->err == LOCK_TIMEOUT) fprintf(stderr, "cannot acquire exclusive access on database %s\n", argv[0]); return 1; return sm_CHECK(s, "transaction begin"); }
00071
00072 #define END(s, msg) \
00073 if (getenv("_ABORT_") || s) transactionAbort(dbh); \
00074 else transactionCommit(dbh); \
00075 return sm_CHECK(s, msg)
00076
00077 #define OPEN(DBFILE, MODE) \
00078 if (sm_CHECK(dbOpen(DBFILE, MODE, 0, 0, 0, &dbh), \
00079 "database open")) \
00080 return 1
00081
00082 #define sm_OPEN(DBFILE, MODE) \
00083 if (sm_CHECK(ESM_dbOpen(DBFILE, MODE, 0, 0, 0, 0, 0, 0, &sm_dbh), \
00084 "database open")) \
00085 return 1; \
00086 DbHeader _dbh_(DBSADDR(sm_dbh)); \
00087 sm_h = &_dbh_
00088
00089 #define sm_SHMH_INIT(DBFILE, WRITE) \
00090 if (shmh_init(DBFILE, WRITE)) { \
00091 fprintf(stderr,"cannot open database file '%s'\n", DBFILE); \
00092 return 1; \
00093 }
00094
00095 #define sm_XL(x) (((x) == LockX) ? "X" : ((x) == LockS ? "S" : "SX"))
00096 #define sm_LOCK() sm_locked = 1; MUTEX_LOCK_VOID(sm_mutex, MAXCLS)
00097 #define sm_UNLOCK() MUTEX_UNLOCK(sm_mutex, MAXCLS); sm_locked = 0
00098
00099 static DbHandle *sm_dbh;
00100 static DbHandle *dbh;
00101 static DbShmHeader *sm_shmh;
00102 static DbHeader *sm_h;
00103 static XMHandle *sm_xmh;
00104 static int sm_fdshm;
00105 static int unsigned sm_shmsize;
00106 static const char *sm_shmfile;
00107 static Mutex *sm_mutex;
00108 static int sm_locked;
00109
00110 static unsigned int
00111 shmsize_get(int shmfd)
00112 {
00113 struct stat stat;
00114
00115 if (fstat(shmfd, &stat) < 0)
00116 return 0;
00117
00118 return stat.st_size;
00119 }
00120
00121 static int
00122 shmh_init(const char *dbfile, Boolean write)
00123 {
00124 int fddb;
00125 caddr_t shm_addr;
00126 Status status;
00127
00128 if ((fddb = open(dbfile, write ? O_RDWR : O_RDONLY)) < 0)
00129 return 1;
00130
00131 close(fddb);
00132
00133 sm_shmfile = shmfileGet(dbfile);
00134
00135 if ((sm_fdshm = open(shmfileGet(dbfile), write ? O_RDWR : O_RDONLY)) < 0)
00136 return 1;
00137
00138 sm_shmsize = shmsize_get(sm_fdshm);
00139
00140 shm_addr = (caddr_t)mmap(0, sm_shmsize, PROT_READ|(write ? PROT_WRITE : 0),
00141 MAP_SHARED, sm_fdshm, 0);
00142
00143 if (shm_addr == MAP_FAILED)
00144 {
00145 fprintf(stderr, PROG ": cannot map file '%s' for %s.\n", sm_shmfile,
00146 (write ? "reading" : "writing"));
00147 return 1;
00148 }
00149
00150 sm_shmh = (DbShmHeader *)shm_addr;
00151 sm_xmh = XMOpen(shm_addr + SHM_HEADSIZE, 0);
00152
00153
00154 return 0;
00155 }
00156
00157 #define M_DATABASE 0x01000
00158 #define M_DATAFILE 0x02000
00159 #define M_DATASPACE 0x04000
00160 #define M_SHMEM 0x08000
00161 #define M_MUTEX 0x10000
00162 #define M_TRANSACTION 0x20000
00163 #define M_OID 0x40000
00164
00165 enum mAction {
00166 mDatabaseCreate = 1,
00167 mDatabaseDelete,
00168 mDatabaseMove,
00169 mDatabaseCopy,
00170 mDatabaseSetobjmax,
00171 mDatabaseDisplay,
00172 mDatafileCreate,
00173 mDatafileMove,
00174 mDatafileResize,
00175 mDatafileDelete,
00176 mDatafileDefragment,
00177 mDatafileDisplay,
00178 mDatafileRename,
00179 mDataspaceCreate,
00180 mDataspaceUpdate,
00181 mDataspaceDelete,
00182 mDataspaceRename,
00183 mDataspaceDisplay,
00184 mDataspaceSetDefault,
00185 mDataspaceGetDefault,
00186 mDataspaceGetCurDat,
00187 mDataspaceSetCurDat,
00188 mShmemResize,
00189 mShmemDspmap,
00190 mShmemDspsize,
00191 mShmemCheck,
00192 mShmemCleanup,
00193 mMutexUnlock,
00194 mMutexReset,
00195 mMutexDisplay,
00196 mTransactionDisplay,
00197 mTransactionDspoidlock,
00198 mTransactionDsphead,
00199 mTransactionAbrtInact,
00200 mOidMoveDat,
00201 mOidMoveDsp,
00202 mOidDspList,
00203 mOidDspCount,
00204 mOidGetCurLastNx,
00205 mOidSetLastNx,
00206 mOidSetCurNx,
00207 mOidSyncCurLastNx,
00208 mOidDspLoca,
00209 mOidDspLocaStats
00210 };
00211
00212 static const char *prog;
00213
00214 static int
00215 usage(unsigned int mode = 0)
00216 {
00217 if (!mode || mode == mDatabaseCreate || (mode & M_DATABASE))
00218 fprintf(stderr, "%s database create DBFILE DBID OBJMAX {DATAFILE NAME MAXSIZE_KB linkmap|SIZESLOT phy|log}...\n", prog);
00219
00220 if (!mode || mode == mDatabaseDelete || (mode & M_DATABASE))
00221 fprintf(stderr, "%s database delete DBFILE\n", prog);
00222
00223 if (!mode || mode == mDatabaseMove || (mode & M_DATABASE))
00224 fprintf(stderr, "%s database move DBFILE NEW_DBFILE NEW_DATAFILES...\n", prog);
00225
00226 if (!mode || mode == mDatabaseCopy || (mode & M_DATABASE))
00227 fprintf(stderr, "%s database copy DBFILE NEW_DBFILE NEW_DATAFILES...\n", prog);
00228
00229 if (!mode || mode == mDatabaseSetobjmax || (mode & M_DATABASE))
00230 fprintf(stderr, "%s database set:objmax DBFILE NEW_OBJMAX\n", prog);
00231
00232 if (!mode || mode == mDatabaseDisplay || (mode & M_DATABASE))
00233 fprintf(stderr, "%s database display DBFILE\n", prog);
00234
00235 if (!mode)
00236 fprintf(stderr, "\n");
00237
00238 if (!mode || mode == mDatafileCreate || (mode & M_DATAFILE))
00239 fprintf(stderr, "%s datafile create DBFILE FILE NAME SIZE_KB linkmap|SIZESLOT log|phy\n", prog);
00240
00241 if (!mode || mode == mDatafileMove || (mode & M_DATAFILE))
00242 fprintf(stderr, "%s datafile move DBFILE DATAFILE NEW_DATAFILE\n", prog);
00243
00244 if (!mode || mode == mDatafileResize || (mode & M_DATAFILE))
00245 fprintf(stderr, "%s datafile resize DBFILE DATAFILE NEW_SIZE_KB\n", prog);
00246
00247 if (!mode || mode == mDatafileDelete || (mode & M_DATAFILE))
00248 fprintf(stderr, "%s datafile delete DBFILE DATAFILE\n", prog);
00249
00250 if (!mode || mode == mDatafileDefragment || (mode & M_DATAFILE))
00251 fprintf(stderr, "%s datafile defragment DBFILE DATAFILE\n", prog);
00252
00253 if (!mode || mode == mDatafileDisplay || (mode & M_DATAFILE))
00254 fprintf(stderr, "%s datafile display DBFILE [DATAFILES...]\n", prog);
00255
00256 if (!mode || mode == mDatafileRename || (mode & M_DATAFILE))
00257 fprintf(stderr, "%s datafile rename DBFILE DATAFILE NAME\n", prog);
00258
00259 if (!mode)
00260 fprintf(stderr, "\n");
00261
00262 if (!mode || mode == mDataspaceCreate || (mode & M_DATASPACE))
00263 fprintf(stderr, "%s dataspace create DBFILE DATASPACE DATAFILES...\n", prog);
00264
00265 if (!mode || mode == mDataspaceUpdate || (mode & M_DATASPACE))
00266 fprintf(stderr, "%s dataspace update DBFILE DATASPACE DATAFILES...\n", prog);
00267
00268 if (!mode || mode == mDataspaceDelete || (mode & M_DATASPACE))
00269 fprintf(stderr, "%s dataspace delete DBFILE DATASPACE\n", prog);
00270
00271 if (!mode || mode == mDataspaceRename || (mode & M_DATASPACE))
00272 fprintf(stderr, "%s dataspace rename DBFILE DATASPACE NEW_DATASPACE\n", prog);
00273
00274 if (!mode || mode == mDataspaceDisplay || (mode & M_DATASPACE))
00275 fprintf(stderr, "%s dataspace display DBFILE [DATASPACES...]\n", prog);
00276
00277 if (!mode || mode == mDataspaceSetDefault || (mode & M_DATASPACE))
00278 fprintf(stderr, "%s dataspace set:default DBFILE DATASPACE\n", prog);
00279
00280 if (!mode || mode == mDataspaceGetDefault || (mode & M_DATASPACE))
00281 fprintf(stderr, "%s dataspace get:default DBFILE\n", prog);
00282
00283 if (!mode || mode == mDataspaceSetCurDat || (mode & M_DATASPACE))
00284 fprintf(stderr, "%s dataspace set:curdat DBFILE DATASPACE CURDAT\n", prog);
00285
00286 if (!mode || mode == mDataspaceGetCurDat || (mode & M_DATASPACE))
00287 fprintf(stderr, "%s dataspace get:curdat DBFILE DATASPACE\n", prog);
00288
00289 if (!mode)
00290 fprintf(stderr, "\n");
00291
00292 if (!mode || mode == mShmemResize || (mode & M_SHMEM))
00293 fprintf(stderr, "%s shmem resize DBFILE NEW_SIZE_KB\n", prog);
00294
00295 if (!mode || mode == mShmemDspmap || (mode & M_SHMEM))
00296 fprintf(stderr, "%s shmem display:map DBFILE\n", prog);
00297
00298 if (!mode || mode == mShmemDspsize || (mode & M_SHMEM))
00299 fprintf(stderr, "%s shmem display:size DBFILE\n", prog);
00300
00301 if (!mode || mode == mShmemCheck || (mode & M_SHMEM))
00302 fprintf(stderr, "%s shmem check DBFILE\n", prog);
00303
00304 if (!mode || mode == mShmemCleanup || (mode & M_SHMEM))
00305 fprintf(stderr, "%s shmem cleanup DBFILE\n", prog);
00306
00307 if (!mode)
00308 fprintf(stderr, "\n");
00309
00310 if (!mode || mode == mMutexUnlock || (mode & M_MUTEX))
00311 fprintf(stderr, "%s mutex unlock DBFILE\n", prog);
00312
00313 if (!mode || mode == mMutexReset || (mode & M_MUTEX))
00314 fprintf(stderr, "%s mutex reset DBFILE\n", prog);
00315
00316 if (!mode || mode == mMutexDisplay || (mode & M_MUTEX))
00317 fprintf(stderr, "%s mutex display DBFILE\n", prog);
00318
00319 if (!mode)
00320 fprintf(stderr, "\n");
00321
00322 if (!mode || mode == mTransactionDisplay || (mode & M_TRANSACTION))
00323 fprintf(stderr, "%s transaction display [SERVER_PID] DBFILE\n", prog);
00324
00325 if (!mode || mode == mTransactionDspoidlock || (mode & M_TRANSACTION))
00326 fprintf(stderr, "%s transaction display:lockedoids DBFILE\n", prog);
00327
00328 if (!mode || mode == mTransactionDsphead || (mode & M_TRANSACTION))
00329 fprintf(stderr, "%s transaction display:header [SERVER_PID] DBFILE\n", prog);
00330
00331 if (!mode || mode == mTransactionAbrtInact || (mode & M_TRANSACTION))
00332 fprintf(stderr, "%s transaction abort:inactive DBFILE\n", prog);
00333
00334 if (!mode)
00335 fprintf(stderr, "\n");
00336
00337 if (!mode || mode == mOidMoveDat || (mode & M_OID))
00338 fprintf(stderr, "%s oid move:datafile DBFILE FROM_DATAFILE TO_DATAFILE\n", prog);
00339
00340 if (!mode || mode == mOidMoveDsp || (mode & M_OID))
00341 fprintf(stderr, "%s oid move:dataspace DBFILE FROM_DATASPACE TO_DATASPACE\n", prog);
00342
00343 if (!mode || mode == mOidDspList || (mode & M_OID))
00344 fprintf(stderr, "%s oid display:list DBFILE [DATAFILE]\n", prog);
00345
00346 if (!mode || mode == mOidDspCount || (mode & M_OID))
00347 fprintf(stderr, "%s oid display:count DBFILE [DATAFILE]\n", prog);
00348
00349 if (!mode || mode == mOidGetCurLastNx || (mode & M_OID))
00350 fprintf(stderr, "%s oid get:curlastnx DBFILE\n", prog);
00351
00352 if (!mode || mode == mOidSetLastNx || (mode & M_OID))
00353 fprintf(stderr, "%s oid set:lastnx DBFILE LASTNX\n", prog);
00354
00355 if (!mode || mode == mOidSetCurNx || (mode & M_OID))
00356 fprintf(stderr, "%s oid set:curnx DBFILE CURNX\n", prog);
00357
00358 if (!mode || mode == mOidSyncCurLastNx || (mode & M_OID))
00359 fprintf(stderr, "%s oid sync:curlastnx DBFILE\n", prog);
00360
00361 if (!mode || mode == mOidDspLoca || (mode & M_OID))
00362 fprintf(stderr, "%s oid display:loca DBFILE [DATAFILE]\n", prog);
00363
00364 if (!mode || mode == mOidDspLoca || (mode & M_OID))
00365 fprintf(stderr, "%s oid display:locastats DBFILE [DATAFILE]\n", prog);
00366
00367 return 1;
00368 }
00369
00370 static int
00371 databacreate_realize(int argc, char *argv[])
00372 {
00373 if (argc < 4 || ((argc - 3) % 5))
00374 return usage(mDatabaseCreate);
00375
00376 DbCreateDescription dbc;
00377
00378 char *dbfile = argv[0];
00379 dbc.ndat = 0;
00380 dbc.dbid = atoi(argv[1]);
00381 dbc.nbobjs = atoi(argv[2]);
00382
00383 for (int i = 3; i < argc; i += 5)
00384 {
00385 strcpy(dbc.dat[dbc.ndat].file, argv[i]);
00386 strcpy(dbc.dat[dbc.ndat].name, argv[i+1]);
00387 dbc.dat[dbc.ndat].maxsize = atoi(argv[i+2]);
00388 if (!strcmp(argv[i+3], "linkmap"))
00389 dbc.dat[dbc.ndat].mtype = LinkmapType;
00390 else
00391 {
00392 dbc.dat[dbc.ndat].mtype = BitmapType;
00393 dbc.dat[dbc.ndat].sizeslot = atoi(argv[i+3]);
00394 }
00395 if (!strcmp(argv[i+4], "log"))
00396 dbc.dat[dbc.ndat].dtype = LogicalOidType;
00397 else if (!strcmp(argv[i+4], "phy"))
00398 dbc.dat[dbc.ndat].dtype = PhysicalOidType;
00399 else
00400 return usage(mDatabaseCreate);
00401 dbc.ndat++;
00402 }
00403
00404 return sm_CHECK(dbCreate(dbfile, 205015, &dbc, 0, 0), "database create");
00405 }
00406
00407 static int
00408 databadelete_realize(int argc, char *argv[])
00409 {
00410 if (argc != 1)
00411 return usage(mDatabaseDelete);
00412 return sm_CHECK(dbDelete(argv[0]), "database delete");
00413 }
00414
00415 static int
00416 databamove_copy_realize(int argc, char *argv[], Boolean move)
00417 {
00418 if (argc < 3)
00419 return usage(move ? mDatabaseMove : mDatabaseCopy);
00420
00421 DbMoveDescription dbc;
00422 DbCreateDescription *dcr = &dbc.dcr;
00423
00424 char *dbfile = argv[0];
00425 strcpy(dbc.dbfile, argv[1]);
00426 dcr->ndat = 0;
00427
00428 for (int i = 2; i < argc; i++)
00429 {
00430 strcpy(dcr->dat[dcr->ndat].file, argv[i]);
00431 dcr->ndat++;
00432 }
00433
00434 return sm_CHECK((move ? dbMove(dbfile, &dbc) : dbCopy(dbfile, &dbc)),
00435 (move ? "database move" : "database copy"));
00436 }
00437
00438 static int
00439 databasetobjmax_realize(int argc, char *argv[])
00440 {
00441 if (argc != 2)
00442 return usage(mDatabaseSetobjmax);
00443
00444 sm_OPEN(argv[0], VOLRW);
00445 return sm_CHECK(objectNumberSet(sm_dbh, atoi(argv[1])), "database setobjmax");
00446 }
00447
00448 static int
00449 sm_get_refcount()
00450 {
00451 return sm_shmh->trs_hdr.tr_cnt;
00452 }
00453
00454 static int
00455 shmem_check_realize(int argc, char *argv[])
00456 {
00457 if (argc != 1)
00458 return usage(mShmemCheck);
00459
00460 sm_SHMH_INIT(argv[0], True);
00461
00462 if (!mutexLock(sm_mutex, 0))
00463 {
00464 printf("Database shmem %s is in a coherent state\n", argv[0]);
00465 mutexUnlock(sm_mutex, 0);
00466 return 0;
00467 }
00468
00469 printf("Database shmem %s is in an incoherent state. You must perform:\n"
00470 "eyedbsmtool shmem cleanup %s\n", argv[0], argv[0]);
00471 return 1;
00472 }
00473
00474 static int
00475 shmem_cleanup_realize(int argc, char *argv[])
00476 {
00477 if (argc != 1)
00478 return usage(mShmemCleanup);
00479
00480 int cnt = 0;
00481
00482 printf("\nDo you really want to cleanup the shmem for the "
00483 "database '%s'? ", argv[0]);
00484
00485 for (;;)
00486 {
00487 char s[128];
00488 fgets(s, sizeof s, stdin);
00489 s[strlen(s)-1] = 0;
00490 if (!strcasecmp(s, "y") || !strcasecmp(s, "yes"))
00491 {
00492 Status status = dbCleanup(argv[0]);
00493 if (status){
00494 statusPrint(status, "");
00495 return 1;
00496 }
00497 break;
00498 }
00499 else if (!strcasecmp(s, "n") || !strcasecmp(s, "no"))
00500 {
00501 printf("\nOperation aborted by user request.\n");
00502 break;
00503 }
00504 else
00505 printf("Please, answer `y[es]' or `n[o]'? ");
00506 }
00507
00508 return 0;
00509 }
00510
00511 #define OFFSET(T, X) (unsigned long)(&((T *)0)->X)
00512
00513
00514 #define DSPSIZEOF(T) printf("#define " #T "_SIZE %d\n", sizeof(T))
00515 #define DSPOFFSET(T, X) printf("#define " #T "_" #X "_OFF %d\n", OFFSET(T, X))
00516
00517 static void
00518 display_structs()
00519 {
00520 #if 0
00521 DSPSIZEOF(DatafileDesc);
00522 DSPSIZEOF(DataspaceDesc);
00523 DSPSIZEOF(DbHeader);
00524 DSPSIZEOF(MapHeader);
00525 DSPSIZEOF(BitmapHeader);
00526 DSPSIZEOF(LinkmapHeader);
00527 DSPSIZEOF(MapStat);
00528
00529 DSPOFFSET(MapStat, u);
00530 #endif
00531
00532 #if 0
00533 DSPSIZEOF(MapHeader);
00534 DSPSIZEOF(DatafileDesc);
00535 DSPSIZEOF(DataspaceDesc);
00536 DSPSIZEOF(DbHeader);
00537 DSPSIZEOF(DbRootEntry);
00538
00539 printf("\n");
00540
00541 DSPOFFSET(MapHeader, mtype);
00542 DSPOFFSET(MapHeader, sizeslot);
00543 DSPOFFSET(MapHeader, pow2);
00544 DSPOFFSET(MapHeader, nslots);
00545
00546 DSPOFFSET(MapHeader, nbobjs);
00547 DSPOFFSET(MapHeader, mstat);
00548 DSPOFFSET(MapHeader, mstat.mtype);
00549
00550 DSPOFFSET(MapHeader, u.bmh);
00551
00552 DSPOFFSET(MapHeader, u.bmh.slot_cur);
00553 DSPOFFSET(MapHeader, u.bmh.slot_lastbusy);
00554 DSPOFFSET(MapHeader, u.bmh.retry);
00555
00556 DSPOFFSET(MapHeader, mstat.u.bmstat);
00557 DSPOFFSET(MapHeader, mstat.u.bmstat.obj_count);
00558 DSPOFFSET(MapHeader, mstat.u.bmstat.busy_slots);
00559 DSPOFFSET(MapHeader, mstat.u.bmstat.busy_size);
00560 DSPOFFSET(MapHeader, mstat.u.bmstat.hole_size);
00561
00562 DSPOFFSET(MapHeader, mstat.u.lmstat);
00563 DSPOFFSET(MapHeader, mstat.u.lmstat.nfreecells);
00564
00565 DSPOFFSET(MapHeader, u.lmh);
00566 DSPOFFSET(MapHeader, u.lmh.firstcell);
00567
00568 printf("\n");
00569
00570 DSPOFFSET(DatafileDesc, file);
00571 DSPOFFSET(DatafileDesc, name);
00572 DSPOFFSET(DatafileDesc, __maxsize);
00573 DSPOFFSET(DatafileDesc, mp);
00574 DSPOFFSET(DatafileDesc, __lastslot);
00575 DSPOFFSET(DatafileDesc, __dspid);
00576
00577 printf("\n");
00578
00579 DSPOFFSET(DataspaceDesc, name);
00580 DSPOFFSET(DataspaceDesc, __cur);
00581 DSPOFFSET(DataspaceDesc, __ndat);
00582 DSPOFFSET(DataspaceDesc, __datid);
00583
00584 printf("\n");
00585
00586 DSPOFFSET(DbRootEntry, key);
00587 DSPOFFSET(DbRootEntry, data);
00588
00589 printf("\n");
00590
00591 DSPOFFSET(DbHeader, __magic);
00592 DSPOFFSET(DbHeader, __dbid);
00593 DSPOFFSET(DbHeader, state);
00594 DSPOFFSET(DbHeader, __guest_uid);
00595 DSPOFFSET(DbHeader, __prot_uid_oid);
00596 DSPOFFSET(DbHeader, __prot_list_oid);
00597 DSPOFFSET(DbHeader, __prot_lock_oid);
00598 DSPOFFSET(DbHeader, shmfile);
00599 DSPOFFSET(DbHeader, __nbobjs);
00600 DSPOFFSET(DbHeader, __ndat);
00601 DSPOFFSET(DbHeader, dat);
00602 DSPOFFSET(DbHeader, __ndsp);
00603 DSPOFFSET(DbHeader, dsp);
00604 DSPOFFSET(DbHeader, __def_dspid);
00605 DSPOFFSET(DbHeader, vre);
00606 DSPOFFSET(DbHeader, __lastidxbusy);
00607 DSPOFFSET(DbHeader, __curidxbusy);
00608 DSPOFFSET(DbHeader, __lastidxblkalloc);
00609 DSPOFFSET(DbHeader, __lastnsblkalloc);
00610 #endif
00611
00612 #if 0
00613 DSPSIZEOF(HIdx::_Idx);
00614 DSPOFFSET(HIdx::_Idx, key_count);
00615 DSPOFFSET(HIdx::_Idx, dspid);
00616 DSPOFFSET(HIdx::_Idx, keytype);
00617 DSPOFFSET(HIdx::_Idx, keysz);
00618 DSPOFFSET(HIdx::_Idx, datasz);
00619
00620 DSPSIZEOF(MutexP);
00621
00622 DSPOFFSET(MutexP, u.key);
00623 DSPOFFSET(MutexP, xid);
00624 DSPOFFSET(MutexP, wait_cnt);
00625 DSPOFFSET(MutexP, pcond);
00626
00627 DSPSIZEOF(DbShmHeader);
00628 DSPOFFSET(DbShmHeader, version);
00629 DSPOFFSET(DbShmHeader, xid);
00630 DSPOFFSET(DbShmHeader, hostid);
00631 DSPOFFSET(DbShmHeader, arch);
00632 DSPOFFSET(DbShmHeader, lock);
00633 DSPOFFSET(DbShmHeader, trs_hdr);
00634 DSPOFFSET(DbShmHeader, mtx);
00635 DSPOFFSET(DbShmHeader, stat);
00636 #endif
00637 }
00638
00639 static int
00640 databadisplay_realize(int argc, char *argv[])
00641 {
00642 if (argc != 1)
00643 return usage(mDatabaseDisplay);
00644
00645 sm_OPEN(argv[0], VOLREAD);
00646 sm_SHMH_INIT(argv[0], False);
00647
00648 printf(" Database ID #%d\n", sm_dbh->vd->dbid);
00649 printf(" Version %d\n", x2h_u32(sm_shmh->version));
00650 printf(" Max Object Count %d\n", x2h_u32(sm_h->__nbobjs()));
00651 printf(" Datafile Count %d\n", x2h_u32(sm_h->__ndat()));
00652 printf(" Reference Count %d\n", sm_get_refcount());
00653 if (sm_shmh->hostid || *sm_shmh->hostname)
00654 printf(" Host Owner \"%s\", Host ID %p\n",
00655 sm_shmh->hostname, x2h_u32(sm_shmh->hostid));
00656
00657 printf("\n");
00658 printf(" Total Access Number %d\n", x2h_u32(sm_shmh->stat.total_db_access_cnt));
00659 printf(" Current Access Number %d\n", x2h_u32(sm_shmh->stat.current_db_access_cnt));
00660 printf(" Transaction Started %d\n", x2h_u32(sm_shmh->stat.tr_begin_cnt));
00661 printf(" Transaction Committed %d\n", x2h_u32(sm_shmh->stat.tr_commit_cnt));
00662 printf(" Transaction Aborted %d\n", x2h_u32(sm_shmh->stat.tr_abort_cnt));
00663
00664 return 0;
00665 }
00666
00667 static int
00668 databarealize(int argc, char *argv[])
00669 {
00670 const char *action = argv[0];
00671
00672 if (!action)
00673 return usage(M_DATABASE);
00674
00675 if (!strcmp(action, "create"))
00676 return databacreate_realize(argc-1, &argv[1]);
00677
00678 if (!strcmp(action, "delete"))
00679 return databadelete_realize(argc-1, &argv[1]);
00680
00681 if (!strcmp(action, "move"))
00682 return databamove_copy_realize(argc-1, &argv[1], True);
00683
00684 if (!strcmp(action, "copy"))
00685 return databamove_copy_realize(argc-1, &argv[1], False);
00686
00687 if (!strcmp(action, "set:objmax"))
00688 return databasetobjmax_realize(argc-1, &argv[1]);
00689
00690 if (!strcmp(action, "display"))
00691 return databadisplay_realize(argc-1, &argv[1]);
00692
00693 return usage(M_DATABASE);
00694 }
00695
00696 static int
00697 datafile_create_realize(int argc, char *argv[])
00698 {
00699 if (argc != 6)
00700 return usage(mDatafileCreate);
00701
00702 DatType dtype;
00703
00704 if (!strcmp(argv[5], "log"))
00705 dtype = LogicalOidType;
00706 else if (!strcmp(argv[5], "phy"))
00707 dtype = PhysicalOidType;
00708 else
00709 return usage(mDatafileCreate);
00710
00711 Status s;
00712 OPEN(argv[0], VOLRW);
00713 BEGIN_X(s);
00714
00715 MapType mtype;
00716 unsigned int sizeslot;
00717 if (!strcmp(argv[4], "linkmap"))
00718 mtype = LinkmapType;
00719 else
00720 {
00721 mtype = BitmapType;
00722 sizeslot = atoi(argv[4]);
00723 }
00724
00725 s = datCreate(dbh, argv[1], argv[2], atoi(argv[3]), mtype,
00726 sizeslot, dtype, 0, 0);
00727 END(s, "datafile create");
00728 }
00729
00730 static int
00731 datafile_resize_realize(int argc, char *argv[])
00732 {
00733 if (argc != 3)
00734 return usage(mDatafileResize);
00735
00736 Status s;
00737 OPEN(argv[0], VOLRW);
00738 BEGIN_X(s);
00739 s = datResize(dbh, argv[1], atoi(argv[2]));
00740 END(s, "datafile resize");
00741 }
00742
00743 static int
00744 datafile_move_realize(int argc, char *argv[])
00745 {
00746 if (argc != 3)
00747 return usage(mDatafileMove);
00748
00749 Status s;
00750 OPEN(argv[0], VOLRW);
00751 BEGIN_X(s);
00752
00753 s = datMove(dbh, argv[1], argv[2]);
00754 END(s, "datafile move");
00755 }
00756
00757 static int
00758 datafile_delete_realize(int argc, char *argv[])
00759 {
00760 if (argc != 2)
00761 return usage(mDatafileDelete);
00762
00763 Status s;
00764 OPEN(argv[0], VOLRW);
00765 BEGIN_X(s);
00766
00767 s = datDelete(dbh, argv[1]);
00768 END(s, "datafile delete");
00769 }
00770
00771 static int
00772 datafile_defragment_realize(int argc, char *argv[])
00773 {
00774 if (argc != 2)
00775 return usage(mDatafileDefragment);
00776
00777 Status s;
00778 OPEN(argv[0], VOLRW);
00779 BEGIN_X(s);
00780
00781 s = datDefragment(dbh, argv[1], 0, 0);
00782 END(s, "datafile defragment");
00783 }
00784
00785 static int
00786 datafile_rename_realize(int argc, char *argv[])
00787 {
00788 if (argc != 3)
00789 return usage(mDatafileRename);
00790
00791 Status s;
00792 OPEN(argv[0], VOLRW);
00793 BEGIN_X(s);
00794
00795 s = datRename(dbh, argv[1], argv[2]);
00796 END(s, "datafile rename");
00797 }
00798
00799 static short
00800 datafile_get(const char *dat)
00801 {
00802 int ndat = x2h_u32(sm_h->__ndat());
00803 for (int i = 0; i < ndat; i++)
00804 if (!strcmp(dat, sm_h->dat(i).file()))
00805 return i;
00806
00807 return -1;
00808 }
00809
00810 static void
00811 datafile_display_fragmentation(short datid)
00812 {
00813 DatafileDesc dat = sm_h->dat(datid);
00814 MapHeader *xmp = dat.mp();
00815 x2h_prologue(xmp, mp);
00816 char *mapaddr = sm_dbh->vd->dmp_addr[datid];
00817 char *s, *start, *end;
00818 int nfrags, nbusy, ns;
00819
00820 start = mapaddr;
00821 end = mapaddr + (mp->u_bmh_slot_lastbusy() / 8);
00822 nfrags = 0;
00823 ns = 0;
00824
00825 for (s = start; s <= end; s++)
00826 {
00827 char v = *s;
00828 int b;
00829
00830 for (b = 7; b >= 0; b--, ns++)
00831 {
00832 if (!(v & (1 << b)))
00833 nfrags++;
00834
00835 if (ns >= mp->u_bmh_slot_lastbusy())
00836 break;
00837 }
00838 }
00839
00840 if (nfrags > mp->u_bmh_slot_lastbusy())
00841 nfrags = mp->u_bmh_slot_lastbusy();
00842
00843 printf(" Fragmentation %d/%d slots [%2.2f%%]\n",
00844 nfrags, mp->u_bmh_slot_lastbusy(),
00845 (mp->u_bmh_slot_lastbusy() ?
00846 (double)(100.*nfrags)/mp->u_bmh_slot_lastbusy() : 0));
00847 }
00848
00849 static void
00850 display_size(unsigned long long sz)
00851 {
00852 printf("%lldb", sz);
00853 sz /= ONE_K;
00854 if (sz)
00855 {
00856 printf(", %lldKb", sz);
00857 sz /= ONE_K;
00858 if (sz)
00859 {
00860 printf(", ~%lldMb", sz);
00861 sz /= ONE_K;
00862 if (sz)
00863 printf(", ~%lldGb", sz);
00864 }
00865 }
00866 printf("\n");
00867 }
00868
00869 static void
00870 datafile_display_info(short datid, DatafileDesc *dfd)
00871 {
00872 MapHeader *xmp = dfd->mp();
00873 x2h_prologue(xmp, mp);
00874
00875 printf(" Datafile #%d\n", datid);
00876 if (!*dfd->file())
00877 {
00878 printf(" <empty slot>\n");
00879 return;
00880 }
00881
00882 unsigned long Ksz;
00883 printf(" File %s\n", dfd->file());
00884 printf(" Name %s\n",
00885 (*dfd->name() ? dfd->name() : "<unnamed>"));
00886 if (getDatType(sm_h, datid) == LogicalOidType)
00887 printf(" Oid Type Logical\n");
00888 else
00889 printf(" Oid Type Physical\n");
00890
00891 short dspid = getDataspace(sm_h, datid);
00892 if (dspid != DefaultDspid)
00893 printf(" Dataspace %s\n", sm_h->dsp(dspid).name());
00894 printf(" Maximum Size ");
00895 display_size((unsigned long long)x2h_u32(dfd->__maxsize())*ONE_K);
00896 if (mp->mtype() == BitmapType)
00897 {
00898 printf(" Bitmap Allocator\n");
00899 printf(" Max Slots %u\n", mp->nslots());
00900 printf(" Slot Size %u\n\n", mp->sizeslot());
00901 }
00902 else
00903 printf(" Linkmap Allocator\n\n");
00904
00905 printf(" Object Number %d\n", mp->mstat_u_bmstat_obj_count());
00906 printf(" Total Object Size ");
00907 display_size(mp->mstat_u_bmstat_busy_size());
00908
00909 printf(" Average Object Size ");
00910 display_size(mp->mstat_u_bmstat_obj_count() ?
00911 mp->mstat_u_bmstat_busy_size()/mp->mstat_u_bmstat_obj_count() : 0);
00912
00913 printf("\n");
00914 printf(" Busy Slots %d\n", mp->mstat_u_bmstat_busy_slots());
00915 printf(" Last Busy Slot %u\n", mp->u_bmh_slot_lastbusy());
00916 printf(" Last Volume Slot %u\n", x2h_u32(dfd->__lastslot()));
00917 printf(" Busy Slot Size ");
00918 display_size((unsigned long long)mp->mstat_u_bmstat_busy_slots() * mp->sizeslot());
00919
00920 printf(" Total File Size ");
00921 display_size((unsigned long long)mp->u_bmh_slot_lastbusy() * mp->sizeslot());
00922
00923 printf(" Current Slot Pointer %u\n", mp->u_bmh_slot_cur());
00924 printf(" Defragmentable Size ");
00925 display_size((unsigned long long)(mp->u_bmh_slot_lastbusy()+1 - mp->mstat_u_bmstat_busy_slots()) * mp->sizeslot());
00926
00927 printf(" DMP Up Slot %u\n", x2h_u32(sm_h->__lastnsblkalloc(datid)*BITS_PER_BYTE));
00928 printf(" DMP Allocated Size ");
00929 display_size(x2h_u32(sm_h->__lastnsblkalloc(datid)));
00930 printf(" Used %2.2f%%\n",
00931 ((double)mp->mstat_u_bmstat_busy_slots()/(double)mp->nslots())*100.);
00932 }
00933
00934 static int
00935 datafile_display_realize(int argc, char *argv[])
00936 {
00937 if (argc < 1)
00938 return usage(mDatabaseDisplay);
00939
00940 sm_OPEN(argv[0], VOLREAD);
00941 sm_SHMH_INIT(argv[0], False);
00942
00943 int datid_cnt = argc-1;
00944 int i;
00945 char **dats;
00946 short *datids;
00947 dats = (datid_cnt ? new char*[datid_cnt] : 0);
00948 datids = (datid_cnt ? new short[datid_cnt] : 0);
00949
00950 for (i = 0; i < datid_cnt; i++)
00951 dats[i] = argv[i+1];
00952
00953 if (!datid_cnt) {
00954 unsigned int ndat = x2h_u32(sm_h->__ndat());
00955 printf(" Database %s contains %d Data File%s\n\n", sm_dbh->dbfile, ndat, (ndat > 1 ? "s" : ""));
00956 }
00957
00958 for (i = 0; i < datid_cnt; i++)
00959 if (sm_CHECK(ESM_datCheck(sm_dbh, dats[i], &datids[i], 0),
00960 "unknown datafile"))
00961 return 1;
00962
00963 if (!datid_cnt)
00964 {
00965 unsigned int ndat = x2h_u32(sm_h->__ndat());
00966 for (i = 0; i < ndat; i++)
00967 {
00968 if (i) printf("\n");
00969 DatafileDesc d = sm_h->dat(i);
00970 datafile_display_info(i, &d);
00971 }
00972 return 0;
00973 }
00974
00975 for (i = 0; i < datid_cnt; i++)
00976 {
00977 if (i) printf("\n");
00978 DatafileDesc d = sm_h->dat(datids[i]);
00979 datafile_display_info(datids[i], &d);
00980 }
00981
00982 return 0;
00983 }
00984
00985 static int
00986 datafile_realize(int argc, char *argv[])
00987 {
00988 const char *action = argv[0];
00989
00990 if (!action)
00991 return usage(M_DATAFILE);
00992
00993 if (!strcmp(action, "create"))
00994 return datafile_create_realize(argc-1, &argv[1]);
00995
00996 if (!strcmp(action, "resize"))
00997 return datafile_resize_realize(argc-1, &argv[1]);
00998
00999 if (!strcmp(action, "move"))
01000 return datafile_move_realize(argc-1, &argv[1]);
01001
01002 if (!strcmp(action, "delete"))
01003 return datafile_delete_realize(argc-1, &argv[1]);
01004
01005 if (!strcmp(action, "defragment"))
01006 return datafile_defragment_realize(argc-1, &argv[1]);
01007
01008 if (!strcmp(action, "display"))
01009 return datafile_display_realize(argc-1, &argv[1]);
01010
01011 if (!strcmp(action, "rename"))
01012 return datafile_rename_realize(argc-1, &argv[1]);
01013
01014 return usage(M_DATAFILE);
01015 }
01016
01017 static int
01018 dataspace_create_realize(int argc, char *argv[])
01019 {
01020 if (argc < 3)
01021 return usage(mDataspaceCreate);
01022
01023 Status s;
01024 OPEN(argv[0], VOLRW);
01025 BEGIN_X(s);
01026 s = dspCreate(dbh, argv[1], (const char **)&argv[2], argc-2);
01027 END(s, "dataspace create");
01028 }
01029
01030 static int
01031 dataspace_update_realize(int argc, char *argv[])
01032 {
01033 if (argc < 3)
01034 return usage(mDataspaceUpdate);
01035
01036 Status s;
01037 OPEN(argv[0], VOLRW);
01038 BEGIN_X(s);
01039
01040 s = dspUpdate(dbh, argv[1], (const char **)&argv[2], argc-2, 0, DefaultDspid);
01041 END(s, "dataspace update");
01042 }
01043
01044 static int
01045 dataspace_delete_realize(int argc, char *argv[])
01046 {
01047 if (argc != 2)
01048 return usage(mDataspaceDelete);
01049
01050 Status s;
01051 OPEN(argv[0], VOLRW);
01052 BEGIN_X(s);
01053
01054 s = dspDelete(dbh, argv[1]);
01055 END(s, "dataspace delete");
01056 }
01057
01058 static int
01059 dataspace_rename_realize(int argc, char *argv[])
01060 {
01061 if (argc != 3)
01062 return usage(mDataspaceRename);
01063
01064 Status s;
01065 OPEN(argv[0], VOLRW);
01066 BEGIN_X(s);
01067 s = dspRename(dbh, argv[1], argv[2]);
01068 END(s, "dataspace rename");
01069 }
01070
01071 static int
01072 dataspace_display_info(short dspid, DataspaceDesc *dsp)
01073 {
01074 if (!*dsp->name())
01075 return 0;
01076
01077 printf(" Dataspace #%d\n", dspid);
01078 printf(" Name %s\n", dsp->name());
01079 printf(" Current datafile #%d\n", x2h_16(dsp->__datid(x2h_32(dsp->__cur()))));
01080 unsigned int ndat = x2h_u32(dsp->__ndat());
01081 for (int i = 0; i < ndat; i++) {
01082 printf(" Datafile #%d\n", x2h_16(dsp->__datid(i)));
01083 DatafileDesc _dat = sm_h->dat(x2h_16(dsp->__datid(i)));
01084 DatafileDesc *dat = &_dat;
01085 MapHeader *xmp = dat->mp();
01086 x2h_prologue(xmp, mp);
01087 if (*dat->name())
01088 printf(" Name %s\n", dat->name());
01089 printf(" File %s\n", dat->file());
01090 if (getDatType(sm_h, x2h_16(dsp->__datid(i))) == LogicalOidType)
01091 printf(" Oid Type Logical\n");
01092 else
01093 printf(" Oid Type Physical\n");
01094 printf(" Maxsize %d\n", x2h_u32(dat->__maxsize()));
01095 printf(" Used %2.2f%%\n",
01096 ((double)mp->mstat_u_bmstat_busy_slots()/(double)mp->nslots())*100.);
01097 }
01098
01099 return 1;
01100 }
01101
01102 static int
01103 dataspace_display_realize(int argc, char *argv[])
01104 {
01105 if (argc < 1)
01106 return usage(mDataspaceDisplay);
01107
01108 sm_OPEN(argv[0], VOLREAD);
01109 sm_SHMH_INIT(argv[0], False);
01110
01111 int dspid_cnt = argc-1;
01112 int i;
01113 char **dsps;
01114 short *dspids;
01115 dsps = (dspid_cnt ? new char*[dspid_cnt] : 0);
01116 dspids = (dspid_cnt ? new short[dspid_cnt] : 0);
01117
01118 for (i = 0; i < dspid_cnt; i++)
01119 dsps[i] = argv[i+1];
01120
01121 if (!dspid_cnt) {
01122 unsigned int ndsp = x2h_u32(sm_h->__ndsp());
01123 printf(" Database %s contains %d Dataspace%s\n\n", sm_dbh->dbfile, ndsp, (ndsp > 1 ? "s" : ""));
01124 }
01125
01126 for (i = 0; i < dspid_cnt; i++)
01127 if (sm_CHECK(ESM_dspGet(sm_dbh, dsps[i], &dspids[i]),
01128 "unknown dataspace"))
01129 return 1;
01130
01131 int n = 0;
01132 if (!dspid_cnt)
01133 {
01134 unsigned int ndsp = x2h_u32(sm_h->__ndsp());
01135 for (i = 0, n = 0; i < ndsp; i++)
01136 {
01137 if (n) printf("\n");
01138 DataspaceDesc d = sm_h->dsp(i);
01139 n += dataspace_display_info(i, &d);
01140 }
01141 return 0;
01142 }
01143
01144 for (i = 0; i < dspid_cnt; i++)
01145 {
01146 if (n) printf("\n");
01147 DataspaceDesc d = sm_h->dsp(dspids[i]);
01148 n += dataspace_display_info(dspids[i], &d);
01149 }
01150
01151 return 0;
01152 }
01153
01154 static int
01155 dataspace_setdefault_realize(int argc, char *argv[])
01156 {
01157 if (argc != 2)
01158 return usage(mDataspaceSetDefault);
01159
01160 Status s;
01161 OPEN(argv[0], VOLRW);
01162 BEGIN_X(s);
01163
01164 s = dspSetDefault(dbh, argv[1]);
01165 END(s, "dataspace setdefault");
01166 }
01167
01168 static int
01169 dataspace_getdefault_realize(int argc, char *argv[])
01170 {
01171 if (argc != 1)
01172 return usage(mDataspaceGetDefault);
01173
01174 OPEN(argv[0], VOLREAD);
01175
01176 short dspid;
01177 int r = sm_CHECK(dspGetDefault(dbh, &dspid), "dataspace getdefault");
01178 if (r) return r;
01179
01180 printf("Dataspace default:\n");
01181 printf(" Dspid #%d\n", dspid);
01182
01183 return 0;
01184 }
01185
01186 static int
01187 dataspace_setcurdat_realize(int argc, char *argv[])
01188 {
01189 if (argc != 3)
01190 return usage(mDataspaceSetCurDat);
01191
01192 Status s;
01193 OPEN(argv[0], VOLRW);
01194 BEGIN_X(s);
01195
01196 s = dspSetCurDat(dbh, argv[1], argv[2]);
01197 END(s, "dataspace setcurdat");
01198 }
01199
01200 static int
01201 dataspace_getcurdat_realize(int argc, char *argv[])
01202 {
01203 if (argc != 2)
01204 return usage(mDataspaceGetCurDat);
01205
01206 OPEN(argv[0], VOLREAD);
01207
01208 short cur;
01209 int r = sm_CHECK(dspGetCurDat(dbh, argv[1], &cur),
01210 "dataspace getcurdat");
01211 if (r) return r;
01212
01213 printf("Current Datafile is #%d\n", cur);
01214
01215 return 0;
01216 }
01217
01218 static int
01219 dataspace_realize(int argc, char *argv[])
01220 {
01221 const char *action = argv[0];
01222
01223 if (!action)
01224 return usage(M_DATASPACE);
01225
01226 if (!strcmp(action, "create"))
01227 return dataspace_create_realize(argc-1, &argv[1]);
01228
01229 if (!strcmp(action, "update"))
01230 return dataspace_update_realize(argc-1, &argv[1]);
01231
01232 if (!strcmp(action, "delete"))
01233 return dataspace_delete_realize(argc-1, &argv[1]);
01234
01235 if (!strcmp(action, "rename"))
01236 return dataspace_rename_realize(argc-1, &argv[1]);
01237
01238 if (!strcmp(action, "display"))
01239 return dataspace_display_realize(argc-1, &argv[1]);
01240
01241 if (!strcmp(action, "set:default"))
01242 return dataspace_setdefault_realize(argc-1, &argv[1]);
01243
01244 if (!strcmp(action, "get:default"))
01245 return dataspace_getdefault_realize(argc-1, &argv[1]);
01246
01247 if (!strcmp(action, "set:curdat"))
01248 return dataspace_setcurdat_realize(argc-1, &argv[1]);
01249
01250 if (!strcmp(action, "get:curdat"))
01251 return dataspace_getcurdat_realize(argc-1, &argv[1]);
01252
01253 return usage(M_DATASPACE);
01254 }
01255
01256 #define MINSHMSIZE 0x400000U
01257
01258
01259
01260
01261 #undef HAVE_WIDE_MEMORY_MAPPED
01262
01263 #ifdef HAVE_WIDE_MEMORY_MAPPED
01264 #define MAXSHMSIZE 0x120000000U
01265 #else
01266 #define MAXSHMSIZE 0x40000000U
01267 #endif
01268
01269 static int
01270 activetrans_get()
01271 {
01272 TransHeader *trshd = &sm_shmh->trs_hdr;
01273 Transaction *trs = (Transaction *)XM_ADDR(sm_xmh, trshd->first_trs);
01274 int cnt = 0;
01275
01276 while (trs)
01277 {
01278 if (ESM_isTransactionActive(trs))
01279 cnt++;
01280 trs = (Transaction *)XM_ADDR(sm_xmh, trs->next);
01281 }
01282
01283 return cnt;
01284 }
01285
01286 static int
01287 shmem_resize_realize(int argc, char *argv[])
01288 {
01289 if (argc != 2)
01290 return usage(mShmemResize);
01291
01292 sm_OPEN(argv[0], VOLRW);
01293 sm_SHMH_INIT(argv[0], True);
01294
01295 unsigned int newshmsize = (unsigned int)atoi(argv[1])*ONE_K;
01296
01297 DbShmHeader dbhshm;
01298 int r = 1;
01299
01300 #ifndef NO_FILE_LOCK
01301 if (!filelockX(sm_dbh->vd->shmfd))
01302 {
01303 fprintf(stderr, "shmem file '%s' is in use\n", sm_shmfile);
01304 return 1;
01305 }
01306 #endif
01307
01308 if (newshmsize < MINSHMSIZE)
01309 fprintf(stderr, "size %d is too small (minimum is %d bytes)\n",
01310 newshmsize, MINSHMSIZE);
01311 else if (newshmsize > MAXSHMSIZE)
01312 fprintf(stderr, "size %d too large (maximum is %d bytes)\n",
01313 newshmsize, MAXSHMSIZE);
01314 else if (read(sm_fdshm, &dbhshm, sizeof(dbhshm)) < 0)
01315 fprintf(stderr, "cannot read shmfile '%s'\n", sm_shmfile);
01316 else if (dbhshm.magic != MAGIC)
01317 fprintf(stderr, "shmfile '%s' is not a valid EyeDB shmfile\n",
01318 sm_shmfile);
01319 else if (sm_get_refcount())
01320 {
01321
01322 int cnt = activetrans_get();
01323 printf("shmfile '%s' is currenly in use: "
01324 "ref. count %d", sm_shmfile, sm_get_refcount());
01325 if (cnt)
01326 printf(", %d active transaction%s",
01327 cnt, (cnt > 1 ? "s" : ""));
01328 printf("\n");
01329 }
01330 else if (ftruncate(sm_fdshm, newshmsize))
01331 fprintf(stderr, "ftruncate(\"%s\", %u) returns: '%s'\n",
01332 sm_shmfile, newshmsize, strerror(errno));
01333 else
01334 r = 0;
01335
01336 if (!r) {
01337 munmap((caddr_t)sm_shmh, sm_shmsize);
01338 sm_shmsize = newshmsize;
01339 sm_SHMH_INIT(argv[0], True);
01340 ESM_transInit(sm_dbh->vd, (char *)sm_shmh, newshmsize);
01341 }
01342
01343 ut_file_unlock(sm_fdshm);
01344 return r;
01345 }
01346
01347 static int
01348 shm_dspmap_realize(int argc, char *argv[])
01349 {
01350 if (argc != 1)
01351 return usage(mShmemDspmap);
01352
01353 sm_SHMH_INIT(argv[0], True);
01354 XMCheckMemory(sm_xmh);
01355 return 0;
01356 }
01357
01358 static int
01359 shm_dspsize_realize(int argc, char *argv[])
01360 {
01361 if (argc != 1)
01362 return usage(mShmemDspsize);
01363
01364 sm_SHMH_INIT(argv[0], False);
01365 printf("Shm Size %u bytes [~ %uM]\n", sm_shmsize, sm_shmsize/(1024*1024));
01366
01367 return 0;
01368 }
01369
01370 static int
01371 shmem_realize(int argc, char *argv[])
01372 {
01373 const char *action = argv[0];
01374
01375 if (!action)
01376 return usage(M_SHMEM);
01377
01378 if (!strcmp(action, "resize"))
01379 return shmem_resize_realize(argc-1, &argv[1]);
01380
01381 if (!strcmp(action, "display:map"))
01382 return shm_dspmap_realize(argc-1, &argv[1]);
01383
01384 if (!strcmp(action, "display:size"))
01385 return shm_dspsize_realize(argc-1, &argv[1]);
01386
01387 if (!strcmp(action, "check"))
01388 return shmem_check_realize(argc-1, &argv[1]);
01389
01390 if (!strcmp(action, "cleanup"))
01391 return shmem_cleanup_realize(argc-1, &argv[1]);
01392
01393 return usage(M_SHMEM);
01394 }
01395
01396 static int
01397 mutex_display_realize(int argc, char *argv[])
01398 {
01399 if (argc != 1)
01400 return usage(mMutexDisplay);
01401
01402 sm_SHMH_INIT(argv[0], True);
01403
01404 int lockX;
01405
01406 DbLock *dblocks[] = {&sm_shmh->dblock_W, &sm_shmh->dblock_RW,
01407 &sm_shmh->dblock_Wtrans};
01408 for (unsigned int i = 0; i < sizeof(dblocks)/sizeof(dblocks[0]); i++) {
01409 DbLock *dblock = dblocks[i];
01410 printf(" Mutex %s ", dblock->mp.mtname);
01411 if (dblock->mp.xid || dblock->S || dblock->X) {
01412 printf("Locked ");
01413 if (dblock->mp.xid)
01414 printf("by Server Pid %d ", dblock->mp.xid);
01415 printf("[S=%d, X=%d]\n", dblock->S, dblock->X);
01416 }
01417 else
01418 printf("not Locked\n");
01419 }
01420
01421 MutexP *mt = sm_shmh->mtx.mp;
01422 for (unsigned i = 0; i < MTX_CNT; i++, mt++)
01423 {
01424 #ifdef HAVE_SEMAPHORE_POLICY_SYSV_IPC
01425 printf(" Mutex %-4s ", mt->mtname);
01426 #else
01427 int r = pthread_mutex_trylock(&mt->u.mp);
01428
01429 printf(" Mutex %-4s [POSIX mutex ", mt->mtname);
01430 if (!r)
01431 {
01432 printf("not locked] ");
01433 pthread_mutex_unlock(&mt->u.mp);
01434 }
01435 else
01436 printf("LOCKED] ");
01437 #endif
01438 printf("[eyedbsm mutex ");
01439 if (mt->locked)
01440 printf("LOCKED");
01441 else
01442 printf("not locked");
01443 if (mt->xid)
01444 printf(" by Server Pid = %d", mt->xid);
01445 printf("]\n");
01446 }
01447
01448 return 0;
01449 }
01450
01451 static void
01452 unlock_mutex_realize(int which, const char *mtname)
01453 {
01454
01455
01456
01457
01458
01459
01460
01461
01462
01463
01464
01465
01466
01467 }
01468
01469 static int
01470 mutex_unlock_realize(int argc, char *argv[])
01471 {
01472 if (argc != 1)
01473 return usage(mMutexUnlock);
01474
01475 sm_SHMH_INIT(argv[0], True);
01476
01477 unlock_mutex_realize(MAP, "map");
01478 unlock_mutex_realize(TRS, "trs");
01479 unlock_mutex_realize(NX, "nx");
01480 unlock_mutex_realize(SLT, "slt");
01481 unlock_mutex_realize(LSL, "lsl");
01482
01483 return 0;
01484 }
01485
01486 static int
01487 mutex_reset_realize(int argc, char *argv[])
01488 {
01489 if (argc != 1)
01490 return usage(mMutexReset);
01491
01492 sm_SHMH_INIT(argv[0], True);
01493
01494 DbMutexesInit(0, sm_shmh);
01495
01496 return 0;
01497 }
01498
01499 static int
01500 mutex_realize(int argc, char *argv[])
01501 {
01502 const char *action = argv[0];
01503
01504 if (!action)
01505 return usage(M_MUTEX);
01506
01507 if (!strcmp(action, "display"))
01508 return mutex_display_realize(argc-1, &argv[1]);
01509
01510 if (!strcmp(action, "unlock"))
01511 return mutex_unlock_realize(argc-1, &argv[1]);
01512
01513 if (!strcmp(action, "reset"))
01514 return mutex_reset_realize(argc-1, &argv[1]);
01515
01516 return usage(M_MUTEX);
01517 }
01518
01519 static int
01520 transowner_display(XMHandle *xmh, PObject *po)
01521 {
01522 TransOwner *trs_own;
01523 printf("{owners=#%u [%s]", po->trs_own.trs_off, sm_XL(po->trs_own.trs_lock));
01524
01525 trs_own = (TransOwner *)XM_ADDR(xmh, po->trs_own.next);
01526
01527 while (trs_own)
01528 {
01529 printf(", %u [%s]", trs_own->trs_off, sm_XL(trs_own->trs_lock));
01530 trs_own = (TransOwner *)XM_ADDR(xmh, trs_own->next);
01531 }
01532
01533 printf("}\n");
01534 return 0;
01535 }
01536
01537 static void
01538 one_transaction_display(XMHandle *xmh, TransHeader *trshd,
01539 Transaction *trs, Boolean all)
01540 {
01541 HashTable *obj_ht;
01542 HashTable *trs_ht;
01543 int i, count;
01544 XMOffset *tro_poff;
01545 int cnt = 0;
01546
01547 if (trs->trs_state == TransCOMMITING)
01548 {
01549 printf(" COMMITING...\n");
01550 return;
01551 }
01552
01553 if (trs->trs_state == TransABORTING)
01554 {
01555 printf(" ABORTING...\n");
01556 return;
01557 }
01558
01559 if (trs->trs_state != TransACTIVE)
01560 {
01561 printf(" STATE %d...\n", trs->trs_state);
01562 return;
01563 }
01564
01565 obj_ht = (HashTable *)XM_ADDR(xmh, trshd->obj_ht);
01566
01567 trs_ht = (HashTable *)XM_ADDR(xmh, trs->ht_off);
01568
01569 count = trs_ht->mask + 1;
01570
01571 if (!all)
01572 {
01573 printf("\n");
01574 return;
01575 }
01576
01577 printf(" <<<\n");
01578 for (i = 0, tro_poff = &trs_ht->offs[0]; i < count; i++, tro_poff++)
01579 if (*tro_poff)
01580 {
01581 TRObject *tro = (TRObject *)XM_ADDR(xmh, *tro_poff);
01582 while (tro)
01583 {
01584 PObject *po = (PObject *)XM_ADDR(xmh, tro->po_off);
01585 printf(" %-20s ", getOidString(&po->oid));
01586
01587 if (trs->trobj_wait == *tro_poff)
01588 {
01589 printf("WAITING for lock %s ", sm_XL(trs->lock_wait));
01590 cnt--;
01591 }
01592 else if (tro->lockX)
01593 printf("lock X ");
01594 else if (tro->lockS)
01595 printf("lock S ");
01596 else if (tro->lockP)
01597 printf("lock P ");
01598
01599 printf("[X=%d, S=%d, P=%d] ", tro->lockX, tro->lockS,
01600 tro->lockP);
01601 #ifndef EYEDB_USE_DATA_VMEM
01602 if (tro->data) {
01603 void *data = XM_ADDR(xmh, tro->data);
01604 printf("[datasz=%d, mapped=%s] ", objDataSize(data),
01605 objDataAll(data) ? "whole" : "partial");
01606
01607 }
01608 #endif
01609 transowner_display(xmh, po);
01610 tro = (TRObject *)XM_ADDR(xmh, tro->next);
01611 cnt++;
01612 }
01613 }
01614
01615 if (cnt != trs->obj_cnt)
01616 printf(" incoherency locked objects count %d vs. %d\n",
01617 cnt, trs->obj_cnt);
01618 printf(" >>>\n\n");
01619 }
01620
01621 static void
01622 transaction_display_realize(int server_pid, Boolean all)
01623 {
01624 TransHeader *trshd;
01625 Transaction *trs;
01626 XMOffset trs_x[256];
01627 int cnt;
01628
01629 trshd = &sm_shmh->trs_hdr;
01630
01631 trs = (Transaction *)XM_ADDR(sm_xmh, trshd->first_trs);
01632
01633 cnt = 0;
01634
01635
01636
01637
01638
01639
01640
01641
01642 #define SEC_PER_MIN 60
01643 #define MIN_PER_HOUR 60
01644 #define SEC_PER_HOUR (SEC_PER_MIN * MIN_PER_HOUR)
01645 #define USEC_PER_SECOND 1000000
01646 #define USEC_PER_MS 1000
01647 while (trs)
01648 {
01649 if (!server_pid || trs->xid == server_pid)
01650 {
01651 printf(" Transaction #%d\n", cnt);
01652 printf(" Server Pid %d\n", trs->xid);
01653 printf(" Object Count %d\n", trs->obj_cnt);
01654 printf(" Deleted Object Count %d\n", trs->del_obj_cnt);
01655 printf(" Hash Table Entries %u\n", ((HashTable *)XM_ADDR(sm_xmh, trs->ht_off))->mask+1);
01656 printf(" Created on %s\n", eyedblib::setbuftime(trs->create_time));
01657 printf(" Last Access on %s\n", eyedblib::setbuftime(trs->access_time));
01658 unsigned long duration = trs->access_time - trs->create_time;
01659 unsigned int h = duration / (SEC_PER_HOUR * USEC_PER_SECOND);
01660
01661 unsigned int m = (duration - h * SEC_PER_HOUR * USEC_PER_SECOND) / (long)(SEC_PER_MIN * USEC_PER_SECOND);
01662 unsigned int s = (duration - h * SEC_PER_HOUR * USEC_PER_SECOND - m * SEC_PER_MIN * USEC_PER_SECOND) / USEC_PER_SECOND;
01663 unsigned int ms = (duration - h * SEC_PER_HOUR * USEC_PER_SECOND - m * SEC_PER_MIN * USEC_PER_SECOND - s * USEC_PER_SECOND) / USEC_PER_MS;
01664 unsigned int us = (duration - h * SEC_PER_HOUR * USEC_PER_SECOND - m * SEC_PER_MIN * USEC_PER_SECOND - s * USEC_PER_SECOND - ms * USEC_PER_MS);
01665
01666 printf(" Duration %02u:%02u:%02u %03u.%03ums\n", h, m, s, ms, us);
01667 printf(" State %s\n",
01668 (ESM_isTransactionActive(trs) ? "ACTIVE" : "INACTIVE"));
01669 one_transaction_display(sm_xmh, trshd, trs, all);
01670 cnt++;
01671 }
01672 trs = (Transaction *)XM_ADDR(sm_xmh, trs->next);
01673 }
01674
01675
01676
01677
01678
01679
01680
01681
01682 if (!cnt)
01683 {
01684 if (server_pid)
01685 printf("No Current Transaction for Server Pid %d.\n",
01686 server_pid);
01687 else
01688 printf("No Current Transactions.\n");
01689 }
01690 }
01691
01692 static int
01693 transaction_abrtinact_realize(int argc, char *argv[], Boolean all)
01694 {
01695 if (argc != 1)
01696 return usage(mTransactionAbrtInact);
01697
01698 trace_garb_trs = True;
01699 OPEN(argv[0], VOLRW);
01700 return 0;
01701 }
01702
01703 static int
01704 transaction_display_realize(int argc, char *argv[], Boolean all)
01705 {
01706 if (argc != 1 && argc != 2)
01707 return usage(all ? mTransactionDisplay : mTransactionDsphead);
01708
01709 sm_SHMH_INIT(argv[0], True);
01710 transaction_display_realize((argc == 2 ? atoi(argv[1]) : 0), all);
01711 return 0;
01712 }
01713
01714 static void
01715 item_print(TransOwner *trs_own)
01716 {
01717 Transaction *trs = (Transaction *)XM_ADDR(sm_xmh, trs_own->trs_off);
01718 printf("[xid=%d, lock=%s]", trs->xid, sm_XL(trs_own->trs_lock));
01719 }
01720
01721 static int
01722 transaction_dspoidlock_realize(int argc, char *argv[])
01723 {
01724 int i, n;
01725 HashTable *obj_ht;
01726 TransOwner *trs_own;
01727
01728 sm_SHMH_INIT(argv[0], True);
01729
01730 obj_ht = (HashTable *)XM_ADDR(sm_xmh, sm_shmh->trs_hdr.obj_ht);
01731
01732 for (i = 0, n = 0; i < obj_ht->mask+1; i++)
01733 {
01734 XMOffset po_off = obj_ht->offs[i];
01735
01736 while (po_off)
01737 {
01738 PObject *po = (PObject *)XM_ADDR(sm_xmh, po_off);
01739
01740 printf("#%d %s, ", n, getOidString(&po->oid));
01741 n++;
01742 printf("lockS=%d, lockX=%d, lockSX=%d, ", po->lockS, po->lockX,
01743 po->lockSX);
01744 printf("state=");
01745 if (po->state = Active)
01746 printf("Active");
01747 else if (po->state = Deleted)
01748 printf("Deleted");
01749 else if (po->state = Zombie)
01750 printf("Zombie");
01751 if (po->wait_cnt)
01752 printf(", wait count=%d", po->wait_cnt);
01753 printf(", transaction count=%d {", po->trs_cnt);
01754
01755 item_print(&po->trs_own);
01756 trs_own = (TransOwner *)XM_ADDR(sm_xmh, po->trs_own.next);
01757
01758 while (trs_own)
01759 {
01760 printf(", ");
01761 item_print(trs_own);
01762 trs_own = (TransOwner *)XM_ADDR(sm_xmh, trs_own->next);
01763 }
01764
01765 printf("}\n");
01766 po_off = po->next;
01767 }
01768 }
01769
01770 return 0;
01771 }
01772
01773 static int
01774 transaction_realize(int argc, char *argv[])
01775 {
01776 const char *action = argv[0];
01777
01778 if (!action)
01779 return usage(M_TRANSACTION);
01780
01781 if (!strcmp(action, "display"))
01782 return transaction_display_realize(argc-1, &argv[1], True);
01783
01784 if (!strcmp(action, "display:header"))
01785 return transaction_display_realize(argc-1, &argv[1], False);
01786
01787 if (!strcmp(action, "display:lockedoids"))
01788 return transaction_dspoidlock_realize(argc-1, &argv[1]);
01789
01790 if (!strcmp(action, "abort:inactive"))
01791 return transaction_abrtinact_realize(argc-1, &argv[1], False);
01792
01793 return usage(M_TRANSACTION);
01794 }
01795
01796 struct PageStats {
01797 unsigned long long totalsize;
01798 unsigned long long totalsize_align;
01799 unsigned int totaldatpages_max;
01800 unsigned int totalomppages_max;
01801 unsigned int totaldmppages_max;
01802
01803 unsigned int totaldatpages_cnt;
01804 char *totaldatpages;
01805
01806 unsigned int totaldmppages_cnt;
01807 char *totaldmppages;
01808
01809 unsigned int totalomppages_cnt;
01810 char *totalomppages;
01811
01812 unsigned int oid_cnt;
01813 unsigned short datid;
01814
01815 PageStats() {
01816 totalsize = 0;
01817 totalsize_align = 0;
01818
01819 totaldatpages_max = 0;
01820 totalomppages_max = 0;
01821 totaldmppages_max = 0;
01822
01823 totaldatpages = (char *)0;
01824 totalomppages = (char *)0;
01825 totaldmppages = (char *)0;
01826
01827 totaldatpages_cnt = 0;
01828 totalomppages_cnt = 0;
01829 totaldmppages_cnt = 0;
01830
01831 oid_cnt = 0;
01832 datid = (unsigned short)-1;
01833 }
01834
01835 void setDatid(short _datid) {
01836 this->datid = _datid;
01837 DatafileDesc _dfd = sm_h->dat(datid);
01838 DatafileDesc *dfd = &_dfd;
01839 MapHeader *xmp = dfd->mp();
01840 x2h_prologue(xmp, mp);
01841
01842 totaldatpages_max = (x2h_u32(dfd->__maxsize())*ONE_K>>pgsize_pow2)+1;
01843 totaldatpages = (char *)m_calloc(totaldatpages_max, 1);
01844
01845 totalomppages_max = (x2h_u32(sm_h->__nbobjs())*OIDLOCSIZE>>pgsize_pow2)+1;
01846 totalomppages = (char *)m_calloc(totalomppages_max, 1);
01847
01848 totaldmppages_max = (((x2h_u32(dfd->__maxsize())*ONE_K)/(mp->sizeslot()*8))>>pgsize_pow2)+1;
01849 totaldmppages = (char *)m_calloc(totaldmppages_max, 1);
01850 }
01851
01852 void set(const ObjectLocation &objloc) {
01853 if (!objloc.is_valid)
01854 return;
01855 unsigned int size = objloc.size + sizeof(ObjectHeader);
01856 NS ns = SZ2NS(size, sm_h->dat(datid).mp());
01857 totalsize += size;
01858 totalsize_align += ns * sm_h->dat(datid).mp()->sizeslot();
01859
01860 assert(objloc.dat_start_pagenum < totaldatpages_max);
01861 if (!totaldatpages[objloc.dat_start_pagenum])
01862 {
01863 totaldatpages[objloc.dat_start_pagenum] = 1;
01864 totaldatpages_cnt++;
01865 }
01866
01867 assert(objloc.dat_end_pagenum < totaldatpages_max);
01868 if (!totaldatpages[objloc.dat_end_pagenum])
01869 {
01870 totaldatpages[objloc.dat_end_pagenum] = 1;
01871 totaldatpages_cnt++;
01872 }
01873
01874 assert(objloc.omp_start_pagenum < totalomppages_max);
01875 if (!totalomppages[objloc.omp_start_pagenum])
01876 {
01877 totalomppages[objloc.omp_start_pagenum] = 1;
01878 totalomppages_cnt++;
01879 }
01880
01881 assert(objloc.omp_end_pagenum < totalomppages_max);
01882 if (!totalomppages[objloc.omp_end_pagenum])
01883 {
01884 totalomppages[objloc.omp_end_pagenum] = 1;
01885 totalomppages_cnt++;
01886 }
01887
01888 assert(objloc.dmp_start_pagenum < totaldmppages_max);
01889 if (!totaldmppages[objloc.dmp_start_pagenum])
01890 {
01891 totaldmppages[objloc.dmp_start_pagenum] = 1;
01892 totaldmppages_cnt++;
01893 }
01894
01895 assert(objloc.dmp_end_pagenum < totaldmppages_max);
01896 if (!totaldmppages[objloc.dmp_end_pagenum])
01897 {
01898 totaldmppages[objloc.dmp_end_pagenum] = 1;
01899 totaldmppages_cnt++;
01900 }
01901 oid_cnt++;
01902 }
01903 };
01904
01905 static int
01906 lastnx_action_realize(int argc, char *argv[], mAction action)
01907 {
01908 if ((action == mOidSetLastNx && argc != 2) ||
01909 (action == mOidSetCurNx && argc != 2) ||
01910 (action == mOidSyncCurLastNx && argc != 1) ||
01911 (action == mOidGetCurLastNx && argc != 1))
01912 return usage(action);
01913
01914 sm_OPEN(argv[0], (action == mOidGetCurLastNx ? VOLREAD : VOLRW));
01915 sm_SHMH_INIT(argv[0], True);
01916
01917 if (action == mOidGetCurLastNx) {
01918 printf("current nx: %u\n", x2h_u32(sm_h->__curidxbusy()));
01919 printf("last nx: %u\n", x2h_u32(sm_h->__lastidxbusy()));
01920 printf("last nx blkalloc: %u\n", x2h_u32(sm_h->__lastidxblkalloc()));
01921 return 0;
01922 }
01923
01924 if (action == mOidSyncCurLastNx) {
01925 sm_h->__curidxbusy() = sm_h->__lastidxbusy();
01926 return 0;
01927 }
01928
01929 unsigned int idxbusy = atoi(argv[1]);
01930 if (idxbusy <= 0)
01931 return usage(action);
01932
01933 if (action == mOidSetCurNx) {
01934 sm_h->__curidxbusy() = h2x_u32(idxbusy);
01935 return 0;
01936 }
01937
01938 if (x2h_u32(sm_h->__lastidxbusy()) != idxbusy) {
01939 if (x2h_u32(sm_h->__lastidxbusy()) > idxbusy)
01940 printf("\n** YOU ASK TO DECREASE lastnx PARAMETER: OPERATION STRICTLY NOT RECOMMENDED **\n");
01941 printf("\nDo you really want to change lastnx from %u to %u in "
01942 "database '%s'? ", x2h_u32(sm_h->__lastidxbusy()), idxbusy, argv[0]);
01943 for (;;)
01944 {
01945 char s[128];
01946 fgets(s, sizeof s, stdin);
01947 s[strlen(s)-1] = 0;
01948 if (!strcasecmp(s, "y") || !strcasecmp(s, "yes"))
01949 {
01950 sm_h->__lastidxbusy() = h2x_u32(idxbusy);
01951 break;
01952 }
01953 else if (!strcasecmp(s, "n") || !strcasecmp(s, "no"))
01954 {
01955 printf("\nOperation aborted by user request.\n");
01956 break;
01957 }
01958 else
01959 printf("Please, answer `y[es]' or `n[o]'? ");
01960 }
01961 }
01962
01963 return 0;
01964 }
01965
01966 Boolean
01967 is_in_dsp(short datid, short datids[], int ndatids)
01968 {
01969 for (int i = 0; i < ndatids; i++)
01970 if (datids[i] == datid)
01971 return True;
01972
01973 return False;
01974 }
01975
01976 static int
01977 oid_move_realize(int argc, char *argv[], mAction action)
01978 {
01979 if (argc != 3)
01980 return usage(action);
01981
01982 OPEN(argv[0], VOLRW);
01983 short from_datid, to_datid;
01984 short from_dspid, to_dspid;
01985 short datids[MAX_DAT_PER_DSP];
01986 unsigned int ndatids;
01987 if (action == mOidMoveDat) {
01988 if (sm_CHECK(datCheck(dbh, argv[1], &from_datid, 0), "datafile"))
01989 return 1;
01990
01991 if (sm_CHECK(datCheck(dbh, argv[2], &to_datid, 0), "datafile"))
01992 return 1;
01993 from_dspid = to_dspid = -1;
01994 }
01995 else {
01996 if (sm_CHECK(dspCheck(dbh, argv[1], &from_dspid, datids, &ndatids), "dataspace"))
01997 return 1;
01998
01999 if (sm_CHECK(dspCheck(dbh, argv[2], &to_dspid, 0, 0), "dataspace"))
02000 return 1;
02001 from_datid = to_datid = -1;
02002 }
02003
02004 Boolean found;
02005 Oid oid;
02006 int oid_cnt = 0;
02007 int oid_moved = 0;
02008 int oid_invalid = 0;
02009
02010 Status s;
02011 BEGIN(s);
02012
02013 if (sm_CHECK(firstOidDatGet(dbh, from_datid, &oid, &found), "first oid get"))
02014 return 1;
02015
02016 while (found) {
02017 ObjectLocation objloc;
02018 if (sm_CHECK(objectLocationGet(dbh, &oid, &objloc),
02019 "object location"))
02020 return 1;
02021
02022 if (from_datid >= 0) {
02023 assert(objloc.datid == from_datid);
02024 if (objloc.datid == from_datid) {
02025 if (sm_CHECK(objectMoveDat(dbh, &oid, to_datid),
02026 "moving oid"))
02027 return 1;
02028 oid_moved++;
02029 }
02030 }
02031 else if (is_in_dsp(objloc.datid, datids, ndatids)) {
02032 if (sm_CHECK(objectMoveDsp(dbh, &oid, to_dspid),
02033 "moving oid"))
02034 return 1;
02035 oid_moved++;
02036 }
02037
02038 oid_cnt++;
02039
02040 Oid newoid;
02041 if (sm_CHECK(nextOidDatGet(dbh, from_datid, &oid, &newoid, &found), "next oid get"))
02042 return 1;
02043 oid = newoid;
02044 }
02045
02046 printf("%d/%d oid%s moved\n", oid_moved, oid_cnt, (oid_moved != 1 ? "s" : ""));
02047
02048 END(s, "oid move");
02049 return 0;
02050 }
02051
02052 static int
02053 get_def_rawdata_hash_key(const void *key, unsigned int len)
02054 {
02055 int x = 0;
02056 unsigned char *k = (unsigned char *)(key)+len-1;
02057
02058 for (int i = 0; i < len; i++)
02059 x += *k-- << (i*8);
02060
02061 return x;
02062 }
02063
02064 static int test_hash = getenv("ESM_TEST_HASH") ? atoi(getenv("ESM_TEST_HASH")) : 0;
02065 static int *hash_keys;
02066
02067 #define IDEAL(SZ) ((SZ) ? ((((SZ)-1)>>pgsize_pow2)+1) : 0)
02068
02069 static int
02070 oid_action_realize(int argc, char *argv[], mAction action)
02071 {
02072 if (action == mOidMoveDat || action == mOidMoveDsp)
02073 return oid_move_realize(argc, argv, action);
02074
02075 if (argc != 1 && argc != 2)
02076 return usage(action);
02077
02078 if (test_hash) {
02079 hash_keys = new int[test_hash+1];
02080 memset(hash_keys, 0, sizeof(int)*(test_hash+1));
02081 }
02082
02083 sm_OPEN(argv[0], (action == mOidMoveDat ? VOLRW : VOLREAD));
02084 sm_SHMH_INIT(argv[0], True);
02085
02086 Boolean found;
02087 Oid oid;
02088 short from_datid, to_datid;
02089 if (action == mOidMoveDat) {
02090 if (sm_CHECK(ESM_datCheck(sm_dbh, argv[1], &from_datid, 0), "datafile"))
02091 return 1;
02092 if (sm_CHECK(ESM_datCheck(sm_dbh, argv[2], &to_datid, 0), "datafile"))
02093 return 1;
02094 }
02095 else if (argc == 2) {
02096 if (sm_CHECK(ESM_datCheck(sm_dbh, argv[1], &from_datid, 0), "datafile"))
02097 return 1;
02098 }
02099 else
02100 from_datid = -1;
02101
02102 unsigned int oid_cnt = 0;
02103 unsigned int oid_log_cnt = 0;
02104 unsigned int oid_phy_cnt = 0;
02105 unsigned int oid_moved = 0;
02106 unsigned int oid_invalid = 0;
02107
02108 PageStats *page_stats;
02109
02110 if (action == mOidDspLocaStats)
02111 {
02112 unsigned int ndat = x2h_u32(sm_h->__ndat());
02113 page_stats = new PageStats[ndat];
02114 for (int i = 0; i < ndat; i++)
02115 page_stats[i].setDatid(i);
02116 }
02117
02118 short s_datid, e_datid;
02119 if (from_datid >= 0) {
02120 s_datid = from_datid;
02121 e_datid = from_datid+1;
02122 }
02123 else {
02124 s_datid = 0;
02125 e_datid = x2h_u32(sm_h->__ndat());
02126 }
02127
02128 for (int datid = s_datid; datid < e_datid; datid++) {
02129 if (!isDatValid(sm_dbh, datid))
02130 continue;
02131
02132 if (sm_CHECK(ESM_firstOidDatGet(sm_dbh, datid, &oid, &found), "first oid get"))
02133 return 1;
02134
02135 while (found)
02136 {
02137
02138
02139
02140
02141
02142
02143 ObjectLocation objloc = {0};
02144 if (action != mOidDspCount) {
02145 if (sm_CHECK(ESM_objectLocationGet(sm_dbh, &oid, &objloc),
02146 "object location"))
02147 return 1;
02148 }
02149
02150 if (action == mOidMoveDat)
02151 {
02152 if (objloc.datid == from_datid) {
02153 if (sm_CHECK(ESM_objectMoveDatDsp(sm_dbh, &oid, to_datid, -1,
02154 False, OPDefault),
02155 "moving oid"))
02156 return 1;
02157 oid_moved++;
02158 }
02159 oid_cnt++;
02160 }
02161 else if (from_datid < 0 || objloc.datid == from_datid)
02162 {
02163 if (action == mOidDspLoca) {
02164 printf("%s: %s%s datid #%d, slots [%u, %u], size %u, "
02165 "dat pages [%u. %u], omp pages [%u, %u], "
02166 "dmp pages [%u, %u]\n",
02167 getOidString(&oid),
02168 (objloc.is_valid ? "" : "*invalid* "),
02169 (isPhy(sm_dbh, &oid) ? "physical" : "logical"),
02170 objloc.datid,
02171 objloc.slot_start_num, objloc.slot_end_num, objloc.size,
02172 objloc.dat_start_pagenum, objloc.dat_end_pagenum,
02173 objloc.omp_start_pagenum,
02174 objloc.omp_end_pagenum,
02175 objloc.dmp_start_pagenum,
02176 objloc.dmp_end_pagenum);
02177 oid_cnt++;
02178 }
02179 else if (action == mOidDspLocaStats)
02180 page_stats[objloc.datid].set(objloc);
02181 else if (action == mOidDspList)
02182 {
02183 if (test_hash) {
02184 hash_keys[get_def_rawdata_hash_key(&oid, sizeof(oid)) & test_hash]++;
02185 }
02186 else {
02187 unsigned int size;
02188 if (sm_CHECK(ESM_objectSizeGet(sm_dbh, &size, DefaultLock,
02189 &oid, OPDefault),
02190 "size get"))
02191 return 1;
02192 printf("%s [size=%d]\n", getOidString(&oid), size);
02193 }
02194 oid_cnt++;
02195 }
02196 else if (action == mOidDspCount) {
02197 oid_cnt++;
02198 if (isPhy(sm_dbh, &oid))
02199 oid_phy_cnt++;
02200 else
02201 oid_log_cnt++;
02202 }
02203 }
02204
02205 Oid newoid;
02206 if (sm_CHECK(ESM_nextOidDatGet(sm_dbh, datid, &oid, &newoid, &found), "next oid get"))
02207 return 1;
02208 oid = newoid;
02209 }
02210 }
02211
02212 if (action == mOidDspLocaStats) {
02213 unsigned int ndat = x2h_u32(sm_h->__ndat());
02214 for (int i = 0; i < ndat; i++)
02215 if (from_datid < 0 || i == from_datid)
02216 {
02217 printf("Datafile #%d\n", i);
02218 printf(" Object Count %d\n", page_stats[i].oid_cnt);
02219 printf(" Size ");
02220 display_size(page_stats[i].totalsize);
02221 printf(" Slot Size ");
02222 display_size(page_stats[i].totalsize_align);
02223 printf(" DAT Page Count %d",
02224 page_stats[i].totaldatpages_cnt);
02225 printf(" (Ideal Page Count %lld, ",
02226 IDEAL(page_stats[i].totalsize));
02227 printf("Ideal Slot Based Page Count %lld)\n",
02228 IDEAL(page_stats[i].totalsize_align));
02229
02230 printf(" OMP Page Count %d",
02231 page_stats[i].totalomppages_cnt);
02232 printf(" (Ideal Page Count %d)\n",
02233 page_stats[i].oid_cnt ?
02234 ((page_stats[i].oid_cnt*OIDLOCSIZE)>>pgsize_pow2)+1 : 0);
02235
02236
02237
02238
02239 printf(" DMP Page Count %d",
02240 page_stats[i].totaldmppages_cnt);
02241 printf(" (Ideal Page Count %lld)\n",
02242 (page_stats[i].totalsize_align ?
02243 ((((page_stats[i].totalsize_align-1)/(sm_h->dat(i).mp()->sizeslot()*8))>>pgsize_pow2)+1) : 0));
02244 printf("\n");
02245 }
02246 }
02247 else if (action == mOidMoveDat)
02248 printf("%d oid%s moved\n", oid_moved, (oid_moved != 1 ? "s" : ""));
02249 else if (test_hash) {
02250
02251
02252 for (int i = 0; i <= test_hash; i++)
02253 printf("%d %d\n", i, hash_keys[i]);
02254 }
02255 else
02256 printf("%u OID%s found [%u log/%u phy]\n", oid_cnt,
02257 (oid_cnt != 1 ? "s" : ""), oid_log_cnt, oid_phy_cnt);
02258 return 0;
02259 }
02260
02261 static int
02262 oid_realize(int argc, char *argv[])
02263 {
02264 const char *action = argv[0];
02265
02266 if (!action)
02267 return usage(M_OID);
02268
02269 if (!strcmp(action, "move:datafile"))
02270 return oid_action_realize(argc-1, &argv[1], mOidMoveDat);
02271
02272 if (!strcmp(action, "move:dataspace"))
02273 return oid_action_realize(argc-1, &argv[1], mOidMoveDsp);
02274
02275 if (!strcmp(action, "display:list"))
02276 return oid_action_realize(argc-1, &argv[1], mOidDspList);
02277
02278 if (!strcmp(action, "display:count"))
02279 return oid_action_realize(argc-1, &argv[1], mOidDspCount);
02280
02281 if (!strcmp(action, "get:curlastnx"))
02282 return lastnx_action_realize(argc-1, &argv[1], mOidGetCurLastNx);
02283
02284 if (!strcmp(action, "set:lastnx"))
02285 return lastnx_action_realize(argc-1, &argv[1], mOidSetLastNx);
02286
02287 if (!strcmp(action, "set:curnx"))
02288 return lastnx_action_realize(argc-1, &argv[1], mOidSetCurNx);
02289
02290 if (!strcmp(action, "sync:curlastnx"))
02291 return lastnx_action_realize(argc-1, &argv[1], mOidSyncCurLastNx);
02292
02293 if (!strcmp(action, "display:loca"))
02294 return oid_action_realize(argc-1, &argv[1], mOidDspLoca);
02295
02296 if (!strcmp(action, "display:locastats"))
02297 return oid_action_realize(argc-1, &argv[1], mOidDspLocaStats);
02298
02299 return usage(M_OID);
02300 }
02301
02302 int
02303 main(int argc, char *argv[])
02304 {
02305 if (sm_CHECK(init(), "se init"))
02306 return 1;
02307
02308
02309 if (getenv("EYEDBSM_DISPLAY_STRUCTS")) {
02310 display_structs();
02311 return 0;
02312 }
02313
02314 prog = argv[0];
02315
02316 const char *major = argv[1];
02317
02318 if (!major)
02319 return usage();
02320
02321 if (!strcmp(major, "database"))
02322 return databarealize(argc-2, &argv[2]);
02323
02324 if (!strcmp(major, "datafile"))
02325 return datafile_realize(argc-2, &argv[2]);
02326
02327 if (!strcmp(major, "dataspace"))
02328 return dataspace_realize(argc-2, &argv[2]);
02329
02330 if (!strcmp(major, "shmem"))
02331 return shmem_realize(argc-2, &argv[2]);
02332
02333 if (!strcmp(major, "mutex"))
02334 return mutex_realize(argc-2, &argv[2]);
02335
02336 if (!strcmp(major, "transaction"))
02337 return transaction_realize(argc-2, &argv[2]);
02338
02339 if (!strcmp(major, "oid"))
02340 return oid_realize(argc-2, &argv[2]);
02341
02342 return usage();
02343 }
02344
02345