1 /* Copyright (C) 2014 InfiniDB, Inc.
2
3 This program is free software; you can redistribute it and/or
4 modify it under the terms of the GNU General Public License
5 as published by the Free Software Foundation; version 2 of
6 the License.
7
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
12
13 You should have received a copy of the GNU General Public License
14 along with this program; if not, write to the Free Software
15 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
16 MA 02110-1301, USA. */
17
18 /*
19 * $Id: editem.cpp 2336 2013-06-25 19:11:36Z rdempsey $
20 */
21
22
23 #include <iostream>
24 #include <vector>
25 #include <algorithm>
26 #include <cassert>
27 #include <stdexcept>
28 #include <sstream>
29 #include <string>
30 #include <unistd.h>
31 using namespace std;
32
33 #include "blocksize.h"
34 #include "calpontsystemcatalog.h"
35 #include "objectidmanager.h"
36 using namespace execplan;
37
38 #include "dbrm.h"
39 using namespace BRM;
40
41 #include "configcpp.h"
42 using namespace config;
43
44 #include "dataconvert.h"
45 using namespace dataconvert;
46
47 #include "liboamcpp.h"
48
49 #undef REALLY_DANGEROUS
50
51 #define CHECK(cmd) { int rc = (cmd);\
52 if ((rc) != 0)\
53 { cerr << "Error in DBRM call " #cmd "; returnCode: " << rc << endl;\
54 return 1; } }
55
56 namespace
57 {
58
59 OID_t MaxOID;
60
61 DBRM* emp = 0;
62
63 string pname;
64
65 bool tflg = false;
66 bool sflg = false;
67 bool aflg = false;
68 bool fflg = false;
69 bool vflg = false;
70 bool mflg = false;
71 bool uflg = false;
72
73 struct SortExtentsByPartitionFirst
74 {
operator ()__anona7a1cb0e0111::SortExtentsByPartitionFirst75 bool operator() (const EMEntry& entry1, const EMEntry& entry2)
76 {
77 if ( (entry1.partitionNum < entry2.partitionNum) ||
78 ((entry1.partitionNum == entry2.partitionNum) &&
79 (entry1.dbRoot < entry2.dbRoot)) ||
80 ((entry1.partitionNum == entry2.partitionNum) &&
81 (entry1.dbRoot == entry2.dbRoot) &&
82 (entry1.segmentNum < entry2.segmentNum)) ||
83 ((entry1.partitionNum == entry2.partitionNum) &&
84 (entry1.dbRoot == entry2.dbRoot) &&
85 (entry1.segmentNum == entry2.segmentNum) &&
86 (entry1.blockOffset < entry2.blockOffset)) )
87 return true;
88 else
89 return false;
90 }
91 };
92
93 struct SortExtentsByDBRootFirst
94 {
operator ()__anona7a1cb0e0111::SortExtentsByDBRootFirst95 bool operator() (const EMEntry& entry1, const EMEntry& entry2)
96 {
97 if ( (entry1.dbRoot < entry2.dbRoot) ||
98 ((entry1.dbRoot == entry2.dbRoot) &&
99 (entry1.partitionNum < entry2.partitionNum)) ||
100 ((entry1.dbRoot == entry2.dbRoot) &&
101 (entry1.partitionNum == entry2.partitionNum) &&
102 (entry1.segmentNum < entry2.segmentNum)) ||
103 ((entry1.dbRoot == entry2.dbRoot) &&
104 (entry1.partitionNum == entry2.partitionNum) &&
105 (entry1.segmentNum == entry2.segmentNum) &&
106 (entry1.blockOffset < entry2.blockOffset)) )
107 return true;
108 else
109 return false;
110 }
111 };
112
113 //------------------------------------------------------------------------------
114 // Describes program usage to the user
115 //------------------------------------------------------------------------------
usage(const string & pname)116 void usage(const string& pname)
117 {
118 cout << "usage: " << pname <<
119 " [-tsahvm] [-di]|[-o oid -S opt]|[-c oid]|[-x]|[-e oid]|[-r oid]|"
120 "[-w oid]|[-l]|[-b lbid][-C][-p dbr]" << endl <<
121 " examins/modifies the extent map." << endl <<
122 " -h \tdisplay this help text" << endl <<
123 " -o oid \tdisplay extent map for oid" << endl <<
124 " -S opt \tSort order for -o (1-partition, dbroot, seg#, fbo;" << endl <<
125 " \t 2-dbroot, partition, seg#, fbo;" << endl <<
126 " \t default is unsorted)" << endl <<
127 " -d \tdump the entire extent map" << endl <<
128 " -c oid \tclear the min/max vals for oid" << endl <<
129 " -C \tclear all min/max vals" << endl <<
130 " -t \tdisplay min/max values as dates" << endl <<
131 " -s \tdisplay min/max values as timestamps" << endl <<
132 " -a \tdisplay min/max values as char strings" << endl <<
133 " -u \tdisplay min/max values as unsigned integers" << endl <<
134 " -x \tcreate/extend one or more oids" << endl <<
135 " -e oid \tdelete oid" << endl <<
136 " -r oid \trollback or delete extents" << endl <<
137 " -v \tdisplay verbose output" << endl <<
138 " -w oid \tedit HWM for an oid" << endl <<
139 " -l \tdump the free list" << endl <<
140 " -b lbid\tdisplay info about lbid" << endl <<
141 " -i \tformat the output for import (implies -dm)" << endl <<
142 " -m \tdisplay actual min/max values" << endl <<
143 " -p dbr \tdelete all extents on dbroot dbr" << endl;
144 }
145
146 //------------------------------------------------------------------------------
147 // Converts a non-dictionary char column to a string
148 //------------------------------------------------------------------------------
charcolToString(int64_t v)149 const string charcolToString(int64_t v)
150 {
151 ostringstream oss;
152 char c;
153
154 for (int i = 0; i < 8; i++)
155 {
156 c = v & 0xff;
157 oss << c;
158 v >>= 8;
159 }
160
161 return oss.str();
162 }
163
164 //------------------------------------------------------------------------------
165 // Formats an integer to it's date, datetime, or char equivalent
166 //------------------------------------------------------------------------------
fmt(int64_t v)167 const string fmt(int64_t v)
168 {
169 ostringstream oss;
170
171 if (tflg)
172 {
173 oss << DataConvert::dateToString(v);
174 }
175 else if (sflg)
176 {
177 oss << DataConvert::datetimeToString(v);
178 }
179 else if (aflg)
180 {
181 oss << charcolToString(v);
182 }
183 else if (mflg)
184 {
185 oss << v;
186 }
187 else if (uflg)
188 {
189 if (static_cast<uint64_t>(v) > numeric_limits<uint64_t>::max() - 2)
190 oss << "notset";
191 else
192 oss << static_cast<uint64_t>(v);
193 }
194 else
195 {
196 if (v == numeric_limits<int64_t>::max() ||
197 v <= (numeric_limits<int64_t>::min() + 2))
198 oss << "notset";
199 else
200 oss << v;
201 }
202
203 return oss.str();
204 }
205
206 //------------------------------------------------------------------------------
207 // Check to see if the latest read operation from stdin was successful.
208 // Primarily used to validate the case where we have prompted the user for
209 // more than 1 parameter. Ex: we are validating that the user correctly
210 // formatted the input to enter 3 values separated by spaces (1 2 3) in-
211 // stead of accidentally separating with commas (1,2,3).
212 //------------------------------------------------------------------------------
213 //@bug 4914: Validate that correct number of input parameters is given
isInputValid()214 bool isInputValid()
215 {
216 if (cin.good())
217 return true;
218
219 cin.clear();
220 cin.ignore( numeric_limits<std::streamsize>::max(), '\n');
221 cout << endl << "Invalid input; try again, be sure to enter spaces "
222 "between input parameters." << endl << endl;
223
224 return false;
225 }
226
227 //------------------------------------------------------------------------------
228 // Dump all the extents for the specified OID
229 //------------------------------------------------------------------------------
dumpone(OID_t oid,unsigned int sortOrder)230 int dumpone(OID_t oid, unsigned int sortOrder)
231 {
232 std::vector<struct EMEntry> entries;
233 std::vector<struct EMEntry>::iterator iter;
234 std::vector<struct EMEntry>::iterator end;
235 int64_t max;
236 int64_t min;
237 int32_t seqNum;
238 bool header;
239 bool needtrailer = false;
240 unsigned extentRows = emp->getExtentRows();
241 unsigned colWidth = 0;
242
243 CHECK(emp->getExtents(oid, entries, false, false, true));
244
245 if (entries.size() > 0)
246 {
247 if (sortOrder == 1)
248 {
249 SortExtentsByPartitionFirst sorter;
250 std::sort( entries.begin(), entries.end(), sorter );
251 }
252 else if (sortOrder == 2)
253 {
254 SortExtentsByDBRootFirst sorter;
255 std::sort( entries.begin(), entries.end(), sorter );
256 }
257
258 header = false;
259 iter = entries.begin();
260 end = entries.end();
261
262 while (iter != end)
263 {
264 uint32_t lbidRangeSize = iter->range.size * 1024;
265 max = iter->partition.cprange.hi_val;
266 min = iter->partition.cprange.lo_val;
267 seqNum = iter->partition.cprange.sequenceNum;
268 int state = iter->partition.cprange.isValid;
269
270 if (!header)
271 {
272 if ( iter->colWid > 0 )
273 {
274 cout << "Col OID = " << oid << ", NumExtents = " <<
275 entries.size() << ", width = " << iter->colWid << endl;
276 colWidth = iter->colWid;
277 }
278 else
279 {
280 cout << "Dct OID = " << oid << endl;
281 colWidth = DICT_COL_WIDTH;
282 }
283
284 header = true;
285 }
286
287 if (vflg)
288 cout << oid << ' ';
289
290 cout << iter->range.start << " - " <<
291 (iter->range.start + lbidRangeSize - 1) <<
292 " (" << lbidRangeSize << ") min: " << fmt(min) <<
293 ", max: " << fmt(max) << ", seqNum: " << seqNum << ", state: ";
294
295 switch (state)
296 {
297 case 0:
298 cout << "invalid";
299 break;
300
301 case 1:
302 cout << "updating";
303 break;
304
305 case 2:
306 cout << "valid";
307 break;
308
309 default:
310 cout << "unknown";
311 break;
312 }
313
314 cout << ", fbo: " << iter->blockOffset;
315 cout << ", DBRoot: " << iter->dbRoot <<
316 ", part#: " << iter->partitionNum <<
317 ", seg#: " << iter->segmentNum;
318 cout << ", HWM: " << iter->HWM;
319
320 switch (iter->status)
321 {
322 case EXTENTAVAILABLE:
323 cout << "; status: avail";
324 break;
325
326 case EXTENTUNAVAILABLE:
327 cout << "; status: unavail";
328 break;
329
330 case EXTENTOUTOFSERVICE:
331 cout << "; status: outOfSrv";
332 break;
333
334 default:
335 cout << "; status: unknown";
336 break;
337 }
338
339 cout << endl;
340
341 //Complain loudly if there's a mis-match
342 if (lbidRangeSize != (extentRows * colWidth / BLOCK_SIZE))
343 {
344 cout << endl;
345 throw logic_error(
346 "Extent Map entries do match config file setting!");
347 }
348
349 needtrailer = true;
350 ++iter;
351 }
352
353 if (needtrailer) cout << endl;
354 }
355
356 return 0;
357 }
358
359 //------------------------------------------------------------------------------
360 // Dumps all the extents in the extent map
361 //------------------------------------------------------------------------------
dumpall()362 int dumpall()
363 {
364 for (OID_t oid = 0; oid <= MaxOID; oid++)
365 {
366 dumpone(oid, 0 /* no sorting */);
367 }
368
369 return 0;
370 }
371
372 //------------------------------------------------------------------------------
373 // Deletes all the extents in the extent map
374 //------------------------------------------------------------------------------
zapit()375 int zapit()
376 {
377 #ifdef REALLY_DANGEROUS
378 LBIDRange_v range;
379
380 for (OID_t oid = 0; oid <= MaxOID; oid++)
381 {
382 CHECK(emp->lookup(oid, range));
383
384 if (range.size() > 0)
385 {
386 CHECK(emp->deleteOID(oid));
387 CHECK(emp->confirmChanges());
388 }
389 }
390
391 #else
392 cerr << "Sorry, I'm not going to do that." << endl;
393 #endif
394 return 0;
395 }
396
397 //------------------------------------------------------------------------------
398 // Clears Casual Partition min/max for all the extents in the extent map
399 //------------------------------------------------------------------------------
clearAllCPData()400 int clearAllCPData()
401 {
402 BRM::LBIDRange_v ranges;
403 int oid, err;
404
405 for (oid = 0; oid < MaxOID; oid++)
406 {
407 err = emp->lookup(oid, ranges);
408
409 if (err == 0 && ranges.size() > 0)
410 {
411 BRM::CPInfo cpInfo;
412 BRM::CPInfoList_t vCpInfo;
413 cpInfo.max = numeric_limits<int64_t>::min();
414 cpInfo.min = numeric_limits<int64_t>::max();
415 cpInfo.seqNum = -1;
416
417 for (uint32_t i = 0; i < ranges.size(); i++)
418 {
419 BRM::LBIDRange r = ranges.at(i);
420 cpInfo.firstLbid = r.start;
421 vCpInfo.push_back(cpInfo);
422 }
423
424 CHECK(emp->setExtentsMaxMin(vCpInfo));
425 }
426 }
427
428 return 0;
429 }
430
431 //------------------------------------------------------------------------------
432 // Clears Casual Partition min/max for the specified OID
433 //------------------------------------------------------------------------------
clearmm(OID_t oid)434 int clearmm(OID_t oid)
435 {
436
437 BRM::LBIDRange_v ranges;
438 CHECK(emp->lookup(oid, ranges));
439 BRM::LBIDRange_v::size_type rcount = ranges.size();
440
441 // @bug 2280. Changed to use the batch interface to clear the CP info to make the clear option faster.
442 BRM::CPInfo cpInfo;
443 BRM::CPInfoList_t vCpInfo;
444 cpInfo.max = numeric_limits<int64_t>::min();
445 cpInfo.min = numeric_limits<int64_t>::max();
446 cpInfo.seqNum = -1;
447
448 for (unsigned i = 0; i < rcount; i++)
449 {
450 BRM::LBIDRange r = ranges.at(i);
451 cpInfo.firstLbid = r.start;
452 vCpInfo.push_back(cpInfo);
453 }
454
455 CHECK(emp->setExtentsMaxMin(vCpInfo));
456
457 return 0;
458 }
459
460 //------------------------------------------------------------------------------
461 // Create/add extents to dictionary OID, or a list of column OIDs.
462 //------------------------------------------------------------------------------
extendOids()463 int extendOids( )
464 {
465 uint16_t dbRoot;
466 uint32_t partNum;
467 uint16_t segNum;
468 OID_t oid;
469 uint32_t colWidth;
470 char DictStoreOIDFlag;
471
472 vector<CreateStripeColumnExtentsArgIn> cols;
473
474 cout << "Are you extending a dictionary store oid (y/n)? ";
475 cin >> DictStoreOIDFlag;
476
477 if ((DictStoreOIDFlag == 'y') || (DictStoreOIDFlag == 'Y'))
478 {
479 LBID_t lbid;
480 int allocd;
481
482 cout << "Enter OID, DBRoot, and Partition#, and Segment# "
483 "(separated by spaces): ";
484
485 while (1)
486 {
487 cin >> oid >> dbRoot >> partNum >> segNum;
488
489 if (isInputValid())
490 break;
491 }
492
493 CHECK(emp->createDictStoreExtent ( oid, dbRoot, partNum, segNum,
494 lbid, allocd));
495
496 if (vflg)
497 {
498 cout << oid << " created/extended w/ " << allocd << " blocks; "
499 "beginning LBID: " << lbid <<
500 "; DBRoot: " << dbRoot <<
501 "; Part#: " << partNum <<
502 "; Seg#: " << segNum << endl;
503 }
504 }
505 else
506 {
507 while (1)
508 {
509 bool bFinished = false;
510
511 while (1)
512 {
513 cout << "Enter OID and column width (separated by spaces); "
514 "0 OID represents end of list: ";
515 cin >> oid >> colWidth;
516
517 if (oid == 0)
518 {
519 bFinished = true;
520 break;
521 }
522
523 if (isInputValid())
524 break;
525 }
526
527 if (bFinished)
528 break;
529
530 CreateStripeColumnExtentsArgIn colArg;
531 colArg.oid = oid;
532 colArg.width = colWidth;
533
534 if (uflg)
535 {
536 colArg.colDataType = execplan::CalpontSystemCatalog::UBIGINT;
537 }
538 else
539 {
540 colArg.colDataType = execplan::CalpontSystemCatalog::BIGINT;
541 }
542
543 cols.push_back( colArg );
544 }
545
546 vector<CreateStripeColumnExtentsArgOut> newExtents;
547
548 while (1)
549 {
550 cout << "Enter DBRoot and partition# (partition "
551 "only used for empty DBRoot): ";
552 cin >> dbRoot >> partNum;
553
554 if (isInputValid())
555 break;
556 }
557
558 CHECK(emp->createStripeColumnExtents(cols, dbRoot, partNum,
559 segNum, newExtents));
560
561 cout << "Extents created in partition " << partNum <<
562 ", segment " << segNum << endl;
563
564 if (vflg)
565 {
566 for (unsigned k = 0; k < newExtents.size(); k++)
567 {
568 cout << "Column OID-" << cols[k].oid <<
569 "; LBID-" << newExtents[k].startLbid <<
570 "; nblks-" << newExtents[k].allocSize <<
571 "; fbo-" << newExtents[k].startBlkOffset << endl;
572 }
573 }
574 }
575
576 return 0;
577 }
578
579 //------------------------------------------------------------------------------
580 // Rollback (delete) all extents for the specified OID, that follow the
581 // designated extent
582 //------------------------------------------------------------------------------
rollbackExtents(OID_t oid)583 int rollbackExtents(OID_t oid)
584 {
585 char DictStoreOIDFlag;
586 uint32_t partNum;
587 uint16_t dbRoot;
588 uint16_t segNum;
589 HWM_t hwm;
590
591 cout << "Are you rolling back extents for a dictionary store oid (y/n)? ";
592 cin >> DictStoreOIDFlag;
593
594 if ((DictStoreOIDFlag == 'y') || (DictStoreOIDFlag == 'Y'))
595 {
596 unsigned int hwmCount = 0;
597 vector<uint16_t> segNums;
598 vector<HWM_t> hwms;
599
600 while (1)
601 {
602 cout << "Enter DBRoot#, part#, and the number of HWMs to be entered "
603 "(separated by spaces): ";
604 cin >> dbRoot >> partNum >> hwmCount;
605
606 if (isInputValid())
607 break;
608 }
609
610 for (unsigned int k = 0; k < hwmCount; k++)
611 {
612 while (1)
613 {
614 cout << "Enter seg# and HWM for that segment file " <<
615 "(separated by spaces): ";
616 cin >> segNum >> hwm;
617
618 if (isInputValid())
619 break;
620 }
621
622 hwms.push_back(hwm);
623 segNums.push_back(segNum);
624 }
625
626 CHECK(emp->rollbackDictStoreExtents_DBroot( oid, dbRoot, partNum,
627 segNums, hwms ));
628 }
629 else
630 {
631 while (1)
632 {
633 cout << "Enter DBRoot#, part#, seg#, and HWM for the last extent "
634 "on that DBRoot (separated by spaces): ";
635 cin >> dbRoot >> partNum >> segNum >> hwm;
636
637 if (isInputValid())
638 break;
639 }
640
641 CHECK(emp->rollbackColumnExtents_DBroot( oid, false,
642 dbRoot, partNum, segNum, hwm ));
643 }
644
645 return 0;
646 }
647
648 //------------------------------------------------------------------------------
649 // Delete the specified OID from the extent map
650 //------------------------------------------------------------------------------
deleteOid(OID_t oid)651 int deleteOid(OID_t oid)
652 {
653 if (!fflg)
654 {
655 cout << "WARNING! This operation cannot be undone. Enter 'yes' to continue: ";
656 string resp;
657 cin >> resp;
658
659 if (resp.empty())
660 return 1;
661
662 string::const_iterator p = resp.begin();
663
664 if (*p != 'y' && *p != 'Y')
665 return 1;
666 }
667
668 cout << "Deleting extent map info for " << oid << endl;
669
670 CHECK(emp->deleteOID(oid));
671
672 return 0;
673 }
674
675 //------------------------------------------------------------------------------
676 // Update the local HWM for the specified OID and segment file
677 //------------------------------------------------------------------------------
editHWM(OID_t oid)678 int editHWM(OID_t oid)
679 {
680 HWM_t oldHWM;
681 HWM_t newHWM;
682 uint32_t partNum = 0;
683 uint16_t segNum = 0;
684
685 while (1)
686 {
687 cout << "Enter Partition#, and Segment# (separated by spaces): ";
688 cin >> partNum >> segNum;
689
690 if (isInputValid())
691 break;
692 }
693
694 int extState;
695 CHECK(emp->getLocalHWM(oid, partNum, segNum, oldHWM, extState));
696
697 cout << "HWM for partition " << partNum << " and segment " << segNum <<
698 " is currently " << oldHWM <<
699 ". Enter new value: ";
700 cin >> newHWM;
701
702 CHECK(emp->setLocalHWM(oid, partNum, segNum, newHWM));
703
704 return 0;
705 }
706
707 //------------------------------------------------------------------------------
708 // Dump the free list information
709 //------------------------------------------------------------------------------
dumpFL()710 int dumpFL()
711 {
712 vector<InlineLBIDRange> v = emp->getEMFreeListEntries();
713
714 vector<InlineLBIDRange>::iterator iter = v.begin();
715 vector<InlineLBIDRange>::iterator end = v.end();
716
717 while (iter != end)
718 {
719 if (iter->size || vflg)
720 cout << iter->start << '\t' << iter->size << endl;
721
722 ++iter;
723 }
724
725 return 0;
726 }
727
728 //------------------------------------------------------------------------------
729 // Dump information about the specified LBID
730 //------------------------------------------------------------------------------
dumpLBID(LBID_t lbid)731 int dumpLBID(LBID_t lbid)
732 {
733 uint16_t ver = 0;
734 BRM::OID_t oid;
735 uint16_t dbroot;
736 uint32_t partNum;
737 uint16_t segNum;
738 uint32_t fbo;
739 int rc;
740 rc = emp->lookupLocal(lbid, ver, false, oid, dbroot, partNum, segNum, fbo);
741 idbassert(rc == 0);
742 cout << "LBID " << lbid << " is part of OID " << oid <<
743 "; DbRoot " << dbroot <<
744 "; partition# " << partNum <<
745 "; segment# " << segNum <<
746 "; at FBO " << fbo << endl;
747 return 0;
748 }
749
750 //------------------------------------------------------------------------------
751 // Delete all the extents for the specified DBRoot
752 //------------------------------------------------------------------------------
deleteAllOnDBRoot(uint16_t dbroot)753 int deleteAllOnDBRoot(uint16_t dbroot)
754 {
755 int rc;
756 rc = emp->deleteDBRoot(dbroot);
757 idbassert(rc == 0);
758 return 0;
759 }
760
761 }
762
763 //------------------------------------------------------------------------------
764 // main entry point into this program
765 //------------------------------------------------------------------------------
main(int argc,char ** argv)766 int main(int argc, char** argv)
767 {
768 int c;
769 pname = argv[0];
770 bool dflg = false;
771 int zflg = 0;
772 bool cflg = false;
773 bool Cflg = false;
774 OID_t oid = 0;
775 bool oflg = false;
776 bool xflg = false;
777 bool eflg = false;
778 bool rflg = false;
779 bool wflg = false;
780 bool lflg = false;
781 bool bflg = false;
782 bool iflg = false;
783 LBID_t lbid = 0;
784 bool pflg = false;
785 uint16_t dbroot = 0;
786 unsigned int sortOrder = 0; // value of 0 means no sorting
787
788 opterr = 0;
789
790 while ((c = getopt(argc, argv, "dzCc:o:tsxue:r:fvhw:lb:aimp:S:")) != EOF)
791 switch (c)
792 {
793 case 'd':
794 dflg = true;
795 break;
796
797 case 'z':
798 zflg++;
799 break;
800
801 case 'C':
802 Cflg = true;
803 break;
804
805 case 'c':
806 cflg = true;
807 oid = (OID_t)strtoul(optarg, 0, 0);
808 break;
809
810 case 'o':
811 oflg = true;
812 oid = (OID_t)strtoul(optarg, 0, 0);
813 break;
814
815 case 't':
816 tflg = true;
817 break;
818
819 case 'u':
820 uflg = true;
821 break;
822
823 case 's':
824 sflg = true;
825 break;
826
827 case 'x':
828 xflg = true;
829 break;
830
831 case 'e':
832 eflg = true;
833 oid = (OID_t)strtoul(optarg, 0, 0);
834 break;
835
836 case 'r':
837 rflg = true;
838 oid = (OID_t)strtoul(optarg, 0, 0);
839 break;
840
841 case 'f':
842 fflg = true;
843 break;
844
845 case 'v':
846 vflg = true;
847 break;
848
849 case 'w':
850 wflg = true;
851 oid = (OID_t)strtoul(optarg, 0, 0);
852 break;
853
854 case 'l':
855 lflg = true;
856 break;
857
858 case 'b':
859 bflg = true;
860 lbid = (LBID_t)strtoull(optarg, 0, 0);
861 break;
862
863 case 'a':
864 aflg = true;
865 break;
866
867 case 'i':
868 iflg = true;
869 break;
870
871 case 'm':
872 mflg = true;
873 break;
874
875 case 'p':
876 pflg = true;
877 dbroot = (uint16_t)strtoul(optarg, 0, 0);
878 break;
879
880 case 'S':
881 sortOrder = strtoul(optarg, 0, 0);
882 break;
883
884 case 'h':
885 case '?':
886 default:
887 usage(pname);
888 return (c == 'h' ? 0 : 1);
889 break;
890 }
891
892 (void)Config::makeConfig();
893
894 //IF this is UM in a multi-node system, there may not (won't) be an OID bitmap file, so move on...
895 oam::oamModuleInfo_t modInfo;
896 oam::Oam oam;
897 string localModuleType("pm");
898
899 try
900 {
901 modInfo = oam.getModuleInfo();
902 localModuleType = modInfo.get<1>();
903 }
904 catch (...)
905 {
906 }
907
908 emp = new DBRM();
909
910 if (!emp->isDBRMReady())
911 {
912 cerr << endl << "Error! The DBRM is currently not responding!" << endl
913 << "editem can't continue" << endl << endl;
914 return 1;
915 }
916
917 MaxOID = -1;
918
919 if (localModuleType != "um")
920 {
921 ObjectIDManager oidm;
922 MaxOID = oidm.size();
923 }
924
925 if (emp->isReadWrite() != ERR_OK)
926 {
927 cerr << endl << "Warning! The DBRM is currently in Read-Only mode!" << endl
928 << "Updates will not propagate!" << endl << endl;
929 }
930
931 if (iflg)
932 {
933 dflg = mflg = true;
934 ExtentMap em;
935 cout << em;
936 return 0;
937 }
938
939 if ((int)dflg + (int)cflg + (int)oflg + (int)xflg + (int)eflg + (int)wflg +
940 (int)lflg + (int)bflg + (int)Cflg + (int)rflg + (int)pflg > 1)
941 {
942 cerr << "Only one of d/c/o/x/e/w/l/b/r/C/p can be specified." << endl;
943 usage(pname);
944 return 1;
945 }
946
947 if ((int)sflg + (int)tflg + (int)aflg + (int)uflg > 1)
948 {
949 cerr << "Only one of s/t/a/u can be specified." << endl;
950 usage(pname);
951 return 1;
952 }
953
954 if (MaxOID < 0 && ((int)dflg + (int)Cflg + zflg) > 0)
955 {
956 cerr << "Can't use d/C flag on module type " << localModuleType << endl;
957 usage(pname);
958 return 1;
959 }
960
961 if (pflg)
962 return deleteAllOnDBRoot(dbroot);
963
964 if (oflg)
965 return dumpone(oid, sortOrder);
966
967 if (dflg)
968 return dumpall();
969
970 if (zflg >= 2)
971 return zapit();
972 else if (zflg)
973 {
974 cerr << "Not enough z's to zap extent map." << endl;
975 return 1;
976 }
977
978 if (Cflg)
979 return clearAllCPData();
980
981 if (cflg)
982 return clearmm(oid);
983
984 if (xflg)
985 return extendOids();
986
987 if (eflg)
988 return deleteOid(oid);
989
990 if (wflg)
991 return editHWM(oid);
992
993 if (rflg)
994 return rollbackExtents(oid);
995
996 if (lflg)
997 return dumpFL();
998
999 if (bflg)
1000 return dumpLBID(lbid);
1001
1002 usage(pname);
1003
1004 return 0;
1005 }
1006 // vim:ts=4 sw=4:
1007
1008