2 * Copyright 2000, International Business Machines Corporation and others.
5 * This software has been released under the terms of the IBM Public
6 * License. For details, see the LICENSE file in the top-level source
7 * directory or online at http://www.openafs.org/dl/license10.html
14 #include <sys/types.h>
16 #include <afsconfig.h>
17 #include <afs/param.h>
26 #include <sys/socket.h>
27 #include <netinet/in.h>
31 #include <afs/ktime.h>
32 #include <afs/budb_client.h>
34 #include <afs/com_err.h>
35 #include <afs/bubasics.h>
37 #include "error_macros.h"
39 /* code to manage dump schedules
40 * specific to the ubik database implementation
43 afs_int32 bc_UpdateDumpSchedule();
44 extern struct bc_config *bc_globalConfig;
45 extern struct udbHandleS udbHandle;
49 /* ------------------------------------
50 * command level routines
51 * ------------------------------------
57 * parm 0: list of dump names
58 * parm 1: expiration date (list)
62 bc_AddDumpCmd(as, arock)
63 struct cmd_syndesc *as;
66 register char *dname; /* dump schedule name */
67 register afs_int32 code;
68 afs_int32 expType, expDate;
69 register struct cmd_item *ti;
72 afs_int32 bc_ParseExpiration();
74 /* if an expiration date has been specified */
75 if (as->parms[1].items) {
76 code = bc_ParseExpiration(&as->parms[1], &expType, &expDate);
78 printf("Invalid expiration date syntax\n");
82 /* no expiration date specified */
84 expType = BC_NO_EXPDATE;
87 /* lock schedules and check validity */
88 ctPtr = &bc_globalConfig->configText[TB_DUMPSCHEDULE];
90 code = bc_LockText(ctPtr);
94 code = bc_UpdateDumpSchedule();
96 com_err(whoami, code, "; Can't retrieve dump schedule");
100 /* process each dump name using the expiration date computed above */
101 for (ti = as->parms[0].items; ti != 0; ti = ti->next) {
102 /* get next dump name to process */
105 /* validate the name dump name length */
106 if (strlen(dname) >= BU_MAX_DUMP_PATH) {
107 com_err(whoami, 0, "Dump names must be < %d characters",
109 com_err(whoami, 0, "Dump %s not added", dname);
115 bc_CreateDumpSchedule(bc_globalConfig, dname, expDate, expType);
118 com_err(whoami, 0, "Dump already exists");
120 com_err(whoami, 0, "Invalid path name '%s'", dname);
122 com_err(whoami, 0, "Name specification error");
124 com_err(whoami, code, "; Failed to create dump schedule");
128 /* save the new schedule item */
129 code = bc_SaveDumpSchedule();
131 com_err(whoami, code, "Cannot save dump schedule");
133 "Changes are temporary - for this session only");
137 com_err(whoami, 0, "Created new dump schedule %s", dname);
141 if (ctPtr->lockHandle)
142 bc_UnlockText(ctPtr);
148 * delete a dump schedule
152 bc_DeleteDumpCmd(as, arock)
153 struct cmd_syndesc *as;
156 /* parm 0 is vol set name
157 * parm 1 is dump schedule name
159 register char *dname;
160 register afs_int32 code;
161 udbClientTextP ctPtr;
163 /* lock schedules and check validity */
164 ctPtr = &bc_globalConfig->configText[TB_DUMPSCHEDULE];
166 code = bc_LockText(ctPtr);
170 code = bc_UpdateDumpSchedule();
172 com_err(whoami, code, "; Can't retrieve dump schedule");
176 dname = as->parms[0].items->data;
178 code = bc_DeleteDumpSchedule(bc_globalConfig, dname);
181 com_err(whoami, 0, "No such dump as %s", dname);
183 com_err(whoami, code, "; Failed to delete dump schedule");
187 code = bc_SaveDumpSchedule();
189 printf("backup: deleted dump schedule %s\n", dname);
191 com_err(whoami, code, "Cannot save dump schedule file");
192 com_err(whoami, 0, "Deletion is temporary - for this session only");
196 if (ctPtr->lockHandle != 0)
197 bc_UnlockText(ctPtr);
202 * Print out the dump schedule tree whose root is adump. Alevel should
203 * be passed in as 0, and is incremented for the recursive calls
205 * adump - ptr to the root node of a dump schedule
210 ListDumpSchedule(register struct bc_dumpSchedule *adump, int alevel)
213 register struct bc_dumpSchedule *child;
217 /* sanity check for loops */
219 printf("backup: recursing listing dump schedule\n");
223 /* move to appropriate indentation level */
224 for (i = 0; i < alevel; i++)
227 /* name is a pathname style name, determine trailing name and only print
231 printf("/%s ", tailCompPtr(adump->name));
234 /* list expiration time */
235 switch (adump->expType) {
237 /* absolute expiration date. Never expires if date is 0 */
238 if (adump->expDate) {
239 time_t t = adump->expDate;
240 printf("expires at %.24s", cTIME(&t));
246 struct ktime_date kt;
248 /* expiration date relative to the time that the dump is done */
249 LongTo_ktimeRelDate(adump->expDate, &kt);
250 printf(" expires in %s", RelDatetoString(&kt));
258 for (child = adump->firstChild; child; child = child->nextSibling)
259 ListDumpSchedule(child, alevel + 1);
264 /* bc_ListDumpScheduleCmd
265 * list the (internally held) dump schedule tree
271 bc_ListDumpScheduleCmd(struct cmd_syndesc *as, char *arock)
275 register struct bc_dumpSchedule *tdump;
277 /* first check to see if schedules must be updated */
278 code = bc_UpdateDumpSchedule();
280 com_err(whoami, code, "; Can't retrieve dump schedule");
284 /* go through entire list, displaying trees for root-level dump
287 for (tdump = bc_globalConfig->dsched; tdump; tdump = tdump->next) {
288 /* if this is a root-level dump, show it and its kids */
290 ListDumpSchedule(tdump, 0);
297 * Set/clear expiration date on existing dump node
299 * parm 0: list of dump names
300 * parm 1: expiration date (list)
304 bc_SetExpCmd(as, arock)
305 struct cmd_syndesc *as;
308 register char *dname; /* dump schedule name */
309 register struct cmd_item *ti;
310 struct bc_dumpSchedule *node, *parent;
311 afs_int32 expType, expDate;
312 udbClientTextP ctPtr;
313 register afs_int32 code;
315 afs_int32 bc_ParseExpiration();
317 /* if an expiration date has been specified */
318 if (as->parms[1].items) {
319 code = bc_ParseExpiration(&as->parms[1], &expType, &expDate);
321 printf("Invalid expiration date syntax\n");
325 /* no expiration date specified */
327 expType = BC_NO_EXPDATE;
330 /* lock schedules and check validity */
331 ctPtr = &bc_globalConfig->configText[TB_DUMPSCHEDULE];
333 code = bc_LockText(ctPtr);
337 code = bc_UpdateDumpSchedule();
339 com_err(whoami, code, "; Can't retrieve dump schedule");
343 /* process each dump name using the expiration date computed above */
344 for (ti = as->parms[0].items; ti != 0; ti = ti->next) {
345 /* get next dump name to process */
348 /* validate the name dump name length */
349 if (strlen(dname) >= BU_MAX_DUMP_PATH) {
351 com_err(whoami, 0, "Dump names must be < %d characters",
353 com_err(whoami, 0, "Dump %s not added", dname);
357 code = FindDump(bc_globalConfig, dname, &parent, &node);
359 com_err(whoami, 0, "Dump level %s not found", dname);
363 node->expDate = expDate;
364 node->expType = expType;
367 code = bc_SaveDumpSchedule();
369 com_err(whoami, code, "Cannot save dump schedule");
371 "Expiration changes effective for this session only");
375 if (ctPtr->lockHandle)
376 bc_UnlockText(ctPtr);
382 /* ------------------------------------
383 * general dump schedule handling routines
384 * ------------------------------------
387 bc_ParseDumpSchedule()
390 char dsname[256], period[64];
393 udbClientTextP ctPtr;
394 register struct bc_dumpSchedule *tds;
395 struct bc_dumpSchedule **ppds, *pds;
396 afs_int32 expDate, expType;
398 register FILE *stream;
400 /* initialize locally used variables */
401 ctPtr = &bc_globalConfig->configText[TB_DUMPSCHEDULE];
402 stream = ctPtr->textStream;
404 if (ctPtr->textSize == 0) /* nothing defined yet */
408 return (BC_INTERNALERROR);
412 /* check the magic number and version */
413 tp = fgets(tbuffer, sizeof(tbuffer), stream);
415 /* can't read first line - error */
416 return (BC_INTERNALERROR);
418 afs_int32 dsmagic, dsversion;
420 /* read the first line, and then check magic # and version */
422 code = sscanf(tbuffer, "%d %d", &dsmagic, &dsversion);
424 || (dsmagic != BC_SCHEDULE_MAGIC)
425 || (dsversion != BC_SCHEDULE_VERSION)
427 /* invalid or unexpected header - error */
428 com_err(whoami, 0, "Unable to understand dump schedule file");
429 return (BC_INTERNALERROR);
434 /* read all of the lines out */
435 tp = fgets(tbuffer, sizeof(tbuffer), stream);
437 break; /* hit eof? */
439 sscanf(tbuffer, "%s %s %d %d", dsname, period, &expDate,
443 "Syntax error in dump schedule file, line is: %s",
445 return (BC_INTERNALERROR);
448 (struct bc_dumpSchedule *)malloc(sizeof(struct bc_dumpSchedule));
449 memset(tds, 0, sizeof(*tds));
451 tds->next = (struct bc_dumpSchedule *)0;
452 tds->name = (char *)malloc(strlen(dsname) + 1);
453 strcpy(tds->name, dsname);
455 tds->expDate = expDate;
456 tds->expType = expType;
458 /* find the end of the schedule list, and append the new item to it */
459 ppds = &bc_globalConfig->dsched;
471 bc_SaveDumpSchedule()
473 struct bc_dumpSchedule *tdump;
474 udbClientTextP ctPtr;
477 extern struct bc_config *bc_globalConfig;
478 extern afs_int32 filesize();
480 /* setup the right ptr */
481 ctPtr = &bc_globalConfig->configText[TB_DUMPSCHEDULE];
484 if (ctPtr->lockHandle == 0)
485 return (BC_INTERNALERROR);
487 /* truncate the file */
488 code = ftruncate(fileno(ctPtr->textStream), 0);
492 rewind(ctPtr->textStream);
494 /* write the new information */
495 fprintf(ctPtr->textStream, "%d %d\n", BC_SCHEDULE_MAGIC,
496 BC_SCHEDULE_VERSION);
498 for (tdump = bc_globalConfig->dsched; tdump; tdump = tdump->next) {
499 fprintf(ctPtr->textStream, "%s %s %d %d\n", tdump->name, "any",
500 tdump->expDate, tdump->expType);
503 if (ferror(ctPtr->textStream))
504 return (BC_INTERNALERROR);
506 fflush(ctPtr->textStream); /* debug */
509 code = bcdb_SaveTextFile(ctPtr);
513 /* increment local version number */
514 ctPtr->textVersion++;
516 /* update locally stored file size */
517 ctPtr->textSize = filesize(ctPtr->textStream);
523 /* ------------------------------------
524 * misc. support routines - specific to dump schedules
525 * ------------------------------------
529 bc_UpdateDumpSchedule()
531 struct bc_dumpSchedule *dumpPtr, *nextDumpPtr;
532 struct udbHandleS *uhptr = &udbHandle;
533 udbClientTextP ctPtr;
537 /* lock schedules and check validity */
538 ctPtr = &bc_globalConfig->configText[TB_DUMPSCHEDULE];
540 code = bc_CheckTextVersion(ctPtr);
541 if (code != BC_VERSIONMISMATCH) {
542 ERROR(code); /* Version matches or some other error */
545 /* Must update the dump schedules */
546 /* If we are not already locked, then lock it now */
547 if (!ctPtr->lockHandle) {
548 code = bc_LockText(ctPtr);
554 if (ctPtr->textVersion != -1) {
555 printf("backup: obsolete dump schedule - updating\n");
557 /* clear all old schedule information */
558 dumpPtr = bc_globalConfig->dsched;
560 nextDumpPtr = dumpPtr->next;
562 dumpPtr = nextDumpPtr;
564 bc_globalConfig->dsched = 0;;
567 /* open a temp file to store the config text received from buserver *
568 * The open file stream is stored in ctPtr->textStream */
570 bc_openTextFile(ctPtr,
572 tmpTextFileNames[TB_DUMPSCHEDULE][0]);
575 /* now get a fresh set of information from the database */
576 code = bcdb_GetTextFile(ctPtr);
580 /* fetch the version number */
582 ubik_BUDB_GetTextVersion(uhptr->uh_client, 0, ctPtr->textType,
583 &ctPtr->textVersion);
588 code = bc_ParseDumpSchedule();
592 /* rebuild the tree */
593 code = bc_ProcessDumpSchedule(bc_globalConfig);
598 if (lock && ctPtr->lockHandle)
599 bc_UnlockText(ctPtr);