Update.
[glibc.git] / db2 / progs / db_checkpoint / db_checkpoint.c
blobb2a692bba9063c4be27e5f6578c5aab21e765386
1 /*-
2 * See the file LICENSE for redistribution information.
4 * Copyright (c) 1996, 1997
5 * Sleepycat Software. All rights reserved.
6 */
8 #include "config.h"
10 #ifndef lint
11 static const char copyright[] =
12 "@(#) Copyright (c) 1997\n\
13 Sleepycat Software Inc. All rights reserved.\n";
14 static const char sccsid[] = "@(#)db_checkpoint.c 10.12 (Sleepycat) 9/4/97";
15 #endif
17 #ifndef NO_SYSTEM_INCLUDES
18 #include <sys/types.h>
20 #include <errno.h>
21 #include <limits.h>
22 #include <signal.h>
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <string.h>
26 #include <time.h>
27 #include <unistd.h>
28 #endif
30 #include "db_int.h"
31 #include "shqueue.h"
32 #include "db_page.h"
33 #include "log.h"
34 #include "btree.h"
35 #include "hash.h"
36 #include "clib_ext.h"
37 #include "common_ext.h"
39 char *check __P((DB_ENV *, long, long));
40 int checkpoint __P((DB_ENV *, char *, int));
41 DB_ENV *db_init __P((char *));
42 int logpid __P((char *, int));
43 int main __P((int, char *[]));
44 void onint __P((int));
45 void siginit __P((void));
46 void usage __P((void));
48 int interrupted;
49 time_t now; /* Checkpoint time. */
50 const char
51 *progname = "db_checkpoint"; /* Program name. */
53 int
54 main(argc, argv)
55 int argc;
56 char *argv[];
58 extern char *optarg;
59 extern int optind;
60 DB_ENV *dbenv;
61 time_t now;
62 long kbytes, minutes, seconds;
63 int ch, eval, verbose;
64 char *home, *logfile;
66 home = logfile = NULL;
67 kbytes = minutes = 0;
68 verbose = 0;
69 while ((ch = getopt(argc, argv, "h:k:L:p:v")) != EOF)
70 switch (ch) {
71 case 'h':
72 home = optarg;
73 break;
74 case 'k':
75 get_long(optarg, 1, LONG_MAX, &kbytes);
76 break;
77 case 'L':
78 logfile = optarg;
79 break;
80 case 'p':
81 get_long(optarg, 1, LONG_MAX, &minutes);
82 break;
83 case 'v':
84 verbose = 1;
85 break;
86 case '?':
87 default:
88 usage();
90 argc -= optind;
91 argv += optind;
93 if (argc != 0)
94 usage();
96 if (kbytes == 0 && minutes == 0) {
97 warnx("at least one of -k and -p must be specified");
98 usage();
101 /* Initialize the environment. */
102 dbenv = db_init(home);
104 if (logfile != NULL && logpid(logfile, 1)) {
105 (void)db_appexit(dbenv);
106 return (1);
110 * If we have only a time delay, then we'll sleep the right amount
111 * to wake up when a checkpoint is necessary. If we have a "kbytes"
112 * field set, then we'll check every 30 seconds.
114 eval = 0;
115 seconds = kbytes != 0 ? 30 : minutes * 60;
116 while (!interrupted) {
117 (void)__db_sleep(seconds, 0);
119 if (verbose) {
120 (void)time(&now);
121 printf("checkpoint: %s", ctime(&now));
123 errno = txn_checkpoint(dbenv->tx_info, kbytes, minutes);
125 while (errno == DB_INCOMPLETE) {
126 if (verbose)
127 __db_err(dbenv,
128 "checkpoint did not finish, retrying");
129 (void)__db_sleep(2, 0);
130 errno = txn_checkpoint(dbenv->tx_info, 0, 0);
133 if (errno != 0) {
134 eval = 1;
135 __db_err(dbenv, "checkpoint: %s", strerror(errno));
136 break;
140 if (logfile != NULL && logpid(logfile, 0))
141 eval = 1;
143 if (interrupted) {
144 (void)signal(interrupted, SIG_DFL);
145 (void)raise(interrupted);
146 /* NOTREACHED */
149 return (db_appexit(dbenv) || eval ? 1 : 0);
153 * db_init --
154 * Initialize the environment.
156 DB_ENV *
157 db_init(home)
158 char *home;
160 DB_ENV *dbenv;
162 if ((dbenv = (DB_ENV *)calloc(sizeof(DB_ENV), 1)) == NULL) {
163 errno = ENOMEM;
164 err(1, NULL);
166 dbenv->db_errfile = stderr;
167 dbenv->db_errpfx = progname;
169 if ((errno = db_appinit(home, NULL, dbenv,
170 DB_INIT_LOG | DB_INIT_TXN | DB_INIT_MPOOL | DB_USE_ENVIRON)) != 0)
171 err(1, "db_appinit");
173 if (memp_register(dbenv->mp_info,
174 DB_FTYPE_BTREE, __bam_pgin, __bam_pgout) ||
175 memp_register(dbenv->mp_info,
176 DB_FTYPE_HASH, __ham_pgin, __ham_pgout)) {
177 (void)db_appexit(dbenv);
178 errx(1,
179 "db_appinit: failed to register access method functions");
182 siginit();
184 return (dbenv);
188 * logpid --
189 * Log that we're running.
192 logpid(fname, is_open)
193 char *fname;
194 int is_open;
196 FILE *fp;
197 time_t now;
199 if (is_open) {
200 if ((fp = fopen(fname, "w")) == NULL) {
201 warn("%s", fname);
202 return (1);
204 (void)time(&now);
205 fprintf(fp,
206 "%s: %lu %s", progname, (u_long)getpid(), ctime(&now));
207 fclose(fp);
208 } else
209 (void)remove(fname);
210 return (0);
214 * siginit --
215 * Initialize the set of signals for which we want to clean up.
216 * Generally, we try not to leave the shared regions locked if
217 * we can.
219 void
220 siginit()
222 #ifdef SIGHUP
223 (void)signal(SIGHUP, onint);
224 #endif
225 (void)signal(SIGINT, onint);
226 #ifdef SIGKILL
227 (void)signal(SIGKILL, onint);
228 #endif
229 (void)signal(SIGTERM, onint);
233 * oninit --
234 * Interrupt signal handler.
236 void
237 onint(signo)
238 int signo;
240 if ((interrupted = signo) == 0)
241 interrupted = SIGINT;
244 void
245 usage()
247 (void)fprintf(stderr,
248 "usage: db_checkpoint [-v] [-h home] [-k kbytes] [-L file] [-p min]\n");
249 exit(1);