source: trunk/third/moira/dbck/dbck.pc @ 24319

Revision 24319, 4.6 KB checked in by broder, 14 years ago (diff)
New Moira snapshot from SVN.
Line 
1/* $Id: dbck.pc 3956 2010-01-05 20:56:56Z zacheiss $
2 *
3 * Moira database consistency checker
4 *
5 * (c) Copyright 1988-1998 by the Massachusetts Institute of Technology.
6 * For copying and distribution information, please see the file
7 * <mit-copyright.h>.
8 */
9
10#include <mit-copyright.h>
11#include <moira.h>
12#include "dbck.h"
13
14#include <signal.h>
15#include <stdio.h>
16#include <stdlib.h>
17
18EXEC SQL INCLUDE sqlca;
19EXEC SQL INCLUDE sqlda;
20
21RCSID("$HeadURL: svn+ssh://svn.mit.edu/moira/trunk/moira/dbck/dbck.pc $ $Id: dbck.pc 3956 2010-01-05 20:56:56Z zacheiss $");
22
23int debug = 0;
24int mode = MODE_ASK;
25int fast = 0;
26int warn = 1;
27int abort_p = 0;
28struct hash *users, *machines, *clusters, *lists, *filesys, *nfsphys;
29struct hash *strings, *members, *subnets, *string_dups, *printservers;
30struct hash *containers;
31EXEC SQL BEGIN DECLARE SECTION;
32int dcmenable;
33EXEC SQL END DECLARE SECTION;
34struct save_queue *modtables;
35SQLDA *mr_sqlda;
36
37void interrupt(int signal);
38extern SQLDA *sqlald(int, int, int);
39extern void sqlglm(char *, unsigned int *, unsigned int *);
40
41int main(int argc, char **argv)
42{
43  char **arg = argv;
44  EXEC SQL BEGIN DECLARE SECTION;
45  char *database;
46  EXEC SQL END DECLARE SECTION;
47  struct sigaction sa;
48
49  database = "moira";
50  setvbuf(stdout, NULL, _IOLBF, BUFSIZ);
51
52  while (++arg - argv < argc)
53    {
54      if (**arg == '-')
55        {
56          switch ((*arg)[1])
57            {
58            case 'd':
59              debug = atoi((*arg)[2] ? *arg + 2 : *++arg);
60              break;
61            case 'n':
62              mode = MODE_NO;
63              break;
64            case 'y':
65              mode = MODE_YES;
66              break;
67            case 'p':
68              mode = MODE_PREEN;
69              break;
70            case 'a':
71              mode = MODE_ASK;
72              break;
73            case 'f':
74              fast++;
75              break;
76            case 'w':
77              warn = 0;
78              break;
79            default:
80              printf("Usage: %s [-d level] [-n] [-y] [-p] [-a] [-f] [-w] [database]\n",
81                     argv[0]);
82              exit(1);
83            }
84        }
85      else
86        database = *arg;
87    }
88  if (fast)
89    printf("Doing fast version (skipping some checks)\n");
90  if (mode == MODE_NO)
91    printf("Will NOT modify the database\n");
92  else if (mode == MODE_PREEN)
93    printf("Will fix simple things without asking\n");
94  else if (mode == MODE_YES)
95    printf("Will fix everything without asking\n");
96  if (debug)
97    printf("Debug level is %d\n", debug);
98
99  sa.sa_handler = interrupt;
100  sa.sa_flags = 0;
101  sigemptyset(&sa.sa_mask);
102  sigaction(SIGHUP, &sa, NULL);
103  sigaction(SIGQUIT, &sa, NULL);
104  sigaction(SIGINT, &sa, NULL);
105
106  modtables = sq_create();
107  mr_sqlda = sqlald(1, 255, 0);
108
109  EXEC SQL WHENEVER SQLERROR DO dbmserr();
110  printf("Opening database %s...", database);
111  fflush(stdout);
112  EXEC SQL CONNECT :database IDENTIFIED BY :database;
113  printf("done\n");
114  if (mode != MODE_NO)
115    {
116      EXEC SQL SELECT value INTO :dcmenable FROM numvalues
117        WHERE name = 'dcm_enable';
118      dprintf("DCM disabled (was %d)\n", dcmenable);
119      EXEC SQL UPDATE numvalues SET value = 0 WHERE name = 'dcm_enable';
120    }
121
122  /* Begin transaction here. */
123
124  phase1();
125  EXEC SQL COMMIT WORK;
126  phase2();
127  EXEC SQL COMMIT WORK;
128  phase3();
129  EXEC SQL COMMIT WORK;
130  phase4();
131  EXEC SQL COMMIT WORK;
132
133  if (mode != MODE_NO)
134    cleanup();
135  printf("Done.\n");
136  exit(0);
137}
138
139void dbmserr(void)
140{
141  EXEC SQL BEGIN DECLARE SECTION;
142  char buf[256];
143  EXEC SQL END DECLARE SECTION;
144  int bufsize = 256, msglength = 0;
145
146  if (sqlca.sqlcode == 1403)
147    return;
148  printf("A DBMS error occurred, code %ld\n", sqlca.sqlcode);
149  sqlglm(buf, &bufsize, &msglength);
150  buf[msglength] = '\0';
151  printf("%s\n", buf);
152  printf("Aborting...\n");
153  if (!abort_p)
154    {
155      abort_p++;
156      EXEC SQL ROLLBACK WORK;
157    }
158  exit(1);
159}
160
161
162void interrupt(int signal)
163{
164  printf("Signal caught\n");
165  if (prompt("Save database changes"))
166    {
167      EXEC SQL COMMIT WORK;
168      cleanup();
169      exit(0);
170    }
171  printf("Aborting transaction\n");
172  if (!abort_p)
173    {
174      abort_p++;
175      EXEC SQL ROLLBACK WORK;
176    }
177
178  EXEC SQL UPDATE numvalues SET value = :dcmenable
179    WHERE name = 'dcm_enable';
180
181  exit(0);
182}
183
184
185void modified(char *table)
186{
187  sq_save_unique_string(modtables, table);
188}
189
190void cleanup(void)
191{
192  EXEC SQL BEGIN DECLARE SECTION;
193  char *tab;
194  EXEC SQL END DECLARE SECTION;
195
196  while (sq_get_data(modtables, &tab))
197    {
198      EXEC SQL UPDATE tblstats SET modtime = SYSDATE
199        WHERE table_name = :tab;
200    }
201  EXEC SQL UPDATE numvalues SET value = :dcmenable
202    WHERE name = 'dcm_enable';
203}
204
205
206void out_of_mem(char *msg)
207{
208  fprintf(stderr, "Out of memory while %s\n", msg);
209  if (prompt("Save database changes"))
210    {
211      EXEC SQL COMMIT WORK;
212      cleanup();
213      exit(1);
214    }
215  printf("Aborting transaction\n");
216  EXEC SQL ROLLBACK WORK;
217  exit(1);
218}
Note: See TracBrowser for help on using the repository browser.