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 <afsconfig.h>
15 #include <afs/param.h>
19 #include <afs/ktime.h>
20 #include <afs/budb_client.h>
22 #include <afs/com_err.h>
23 #include <afs/bubasics.h>
26 #include "error_macros.h"
27 #include "bucoord_internal.h"
28 #include "bucoord_prototypes.h"
30 /* code to manage dump schedules
31 * specific to the ubik database implementation
34 extern struct bc_config *bc_globalConfig;
35 extern struct udbHandleS udbHandle;
38 static int ListDumpSchedule(struct bc_dumpSchedule *adump, int alevel);
40 /* ------------------------------------
41 * command level routines
42 * ------------------------------------
48 * parm 0: list of dump names
49 * parm 1: expiration date (list)
53 bc_AddDumpCmd(struct cmd_syndesc *as, void *arock)
55 char *dname; /* dump schedule name */
57 afs_int32 expType, expDate;
61 /* if an expiration date has been specified */
62 if (as->parms[1].items) {
63 code = bc_ParseExpiration(&as->parms[1], &expType, &expDate);
65 printf("Invalid expiration date syntax\n");
69 /* no expiration date specified */
71 expType = BC_NO_EXPDATE;
74 /* lock schedules and check validity */
75 ctPtr = &bc_globalConfig->configText[TB_DUMPSCHEDULE];
77 code = bc_LockText(ctPtr);
81 code = bc_UpdateDumpSchedule();
83 afs_com_err(whoami, code, "; Can't retrieve dump schedule");
87 /* process each dump name using the expiration date computed above */
88 for (ti = as->parms[0].items; ti != 0; ti = ti->next) {
89 /* get next dump name to process */
92 /* validate the name dump name length */
93 if (strlen(dname) >= BU_MAX_DUMP_PATH) {
94 afs_com_err(whoami, 0, "Dump names must be < %d characters",
96 afs_com_err(whoami, 0, "Dump %s not added", dname);
102 bc_CreateDumpSchedule(bc_globalConfig, dname, expDate, expType);
105 afs_com_err(whoami, 0, "Dump already exists");
107 afs_com_err(whoami, 0, "Invalid path name '%s'", dname);
109 afs_com_err(whoami, 0, "Name specification error");
111 afs_com_err(whoami, code, "; Failed to create dump schedule");
115 /* save the new schedule item */
116 code = bc_SaveDumpSchedule();
118 afs_com_err(whoami, code, "Cannot save dump schedule");
119 afs_com_err(whoami, 0,
120 "Changes are temporary - for this session only");
124 afs_com_err(whoami, 0, "Created new dump schedule %s", dname);
128 if (ctPtr->lockHandle)
129 bc_UnlockText(ctPtr);
135 * delete a dump schedule
139 bc_DeleteDumpCmd(struct cmd_syndesc *as, void *arock)
141 /* parm 0 is vol set name
142 * parm 1 is dump schedule name
146 udbClientTextP ctPtr;
148 /* lock schedules and check validity */
149 ctPtr = &bc_globalConfig->configText[TB_DUMPSCHEDULE];
151 code = bc_LockText(ctPtr);
155 code = bc_UpdateDumpSchedule();
157 afs_com_err(whoami, code, "; Can't retrieve dump schedule");
161 dname = as->parms[0].items->data;
163 code = bc_DeleteDumpSchedule(bc_globalConfig, dname);
166 afs_com_err(whoami, 0, "No such dump as %s", dname);
168 afs_com_err(whoami, code, "; Failed to delete dump schedule");
172 code = bc_SaveDumpSchedule();
174 printf("backup: deleted dump schedule %s\n", dname);
176 afs_com_err(whoami, code, "Cannot save dump schedule file");
177 afs_com_err(whoami, 0, "Deletion is temporary - for this session only");
181 if (ctPtr->lockHandle != 0)
182 bc_UnlockText(ctPtr);
187 * Print out the dump schedule tree whose root is adump. Alevel should
188 * be passed in as 0, and is incremented for the recursive calls
190 * adump - ptr to the root node of a dump schedule
195 ListDumpSchedule(struct bc_dumpSchedule *adump, int alevel)
198 struct bc_dumpSchedule *child;
200 /* sanity check for loops */
202 printf("backup: recursing listing dump schedule\n");
206 /* move to appropriate indentation level */
207 for (i = 0; i < alevel; i++)
210 /* name is a pathname style name, determine trailing name and only print
214 printf("/%s ", tailCompPtr(adump->name));
217 /* list expiration time */
218 switch (adump->expType) {
220 /* absolute expiration date. Never expires if date is 0 */
221 if (adump->expDate) {
222 time_t t = adump->expDate;
223 printf("expires at %.24s", cTIME(&t));
229 struct ktime_date kt;
231 /* expiration date relative to the time that the dump is done */
232 LongTo_ktimeRelDate(adump->expDate, &kt);
233 printf(" expires in %s", RelDatetoString(&kt));
241 for (child = adump->firstChild; child; child = child->nextSibling)
242 ListDumpSchedule(child, alevel + 1);
247 /* bc_ListDumpScheduleCmd
248 * list the (internally held) dump schedule tree
254 bc_ListDumpScheduleCmd(struct cmd_syndesc *as, void *arock)
258 struct bc_dumpSchedule *tdump;
260 /* first check to see if schedules must be updated */
261 code = bc_UpdateDumpSchedule();
263 afs_com_err(whoami, code, "; Can't retrieve dump schedule");
267 /* go through entire list, displaying trees for root-level dump
270 for (tdump = bc_globalConfig->dsched; tdump; tdump = tdump->next) {
271 /* if this is a root-level dump, show it and its kids */
273 ListDumpSchedule(tdump, 0);
280 * Set/clear expiration date on existing dump node
282 * parm 0: list of dump names
283 * parm 1: expiration date (list)
287 bc_SetExpCmd(struct cmd_syndesc *as, void *arock)
289 char *dname; /* dump schedule name */
291 struct bc_dumpSchedule *node, *parent;
292 afs_int32 expType, expDate;
293 udbClientTextP ctPtr;
296 /* if an expiration date has been specified */
297 if (as->parms[1].items) {
298 code = bc_ParseExpiration(&as->parms[1], &expType, &expDate);
300 printf("Invalid expiration date syntax\n");
304 /* no expiration date specified */
306 expType = BC_NO_EXPDATE;
309 /* lock schedules and check validity */
310 ctPtr = &bc_globalConfig->configText[TB_DUMPSCHEDULE];
312 code = bc_LockText(ctPtr);
316 code = bc_UpdateDumpSchedule();
318 afs_com_err(whoami, code, "; Can't retrieve dump schedule");
322 /* process each dump name using the expiration date computed above */
323 for (ti = as->parms[0].items; ti != 0; ti = ti->next) {
324 /* get next dump name to process */
327 /* validate the name dump name length */
328 if (strlen(dname) >= BU_MAX_DUMP_PATH) {
330 afs_com_err(whoami, 0, "Dump names must be < %d characters",
332 afs_com_err(whoami, 0, "Dump %s not added", dname);
336 code = FindDump(bc_globalConfig, dname, &parent, &node);
338 afs_com_err(whoami, 0, "Dump level %s not found", dname);
342 node->expDate = expDate;
343 node->expType = expType;
346 code = bc_SaveDumpSchedule();
348 afs_com_err(whoami, code, "Cannot save dump schedule");
349 afs_com_err(whoami, 0,
350 "Expiration changes effective for this session only");
354 if (ctPtr->lockHandle)
355 bc_UnlockText(ctPtr);
361 /* ------------------------------------
362 * general dump schedule handling routines
363 * ------------------------------------
367 bc_ParseDumpSchedule(void)
370 char dsname[256], period[64];
373 udbClientTextP ctPtr;
374 struct bc_dumpSchedule *tds;
375 struct bc_dumpSchedule **ppds, *pds;
376 afs_int32 expDate, expType;
380 /* initialize locally used variables */
381 ctPtr = &bc_globalConfig->configText[TB_DUMPSCHEDULE];
382 stream = ctPtr->textStream;
384 if (ctPtr->textSize == 0) /* nothing defined yet */
388 return (BC_INTERNALERROR);
392 /* check the magic number and version */
393 tp = fgets(tbuffer, sizeof(tbuffer), stream);
395 /* can't read first line - error */
396 return (BC_INTERNALERROR);
398 afs_int32 dsmagic, dsversion;
400 /* read the first line, and then check magic # and version */
402 code = sscanf(tbuffer, "%d %d", &dsmagic, &dsversion);
404 || (dsmagic != BC_SCHEDULE_MAGIC)
405 || (dsversion != BC_SCHEDULE_VERSION)
407 /* invalid or unexpected header - error */
408 afs_com_err(whoami, 0, "Unable to understand dump schedule file");
409 return (BC_INTERNALERROR);
414 /* read all of the lines out */
415 tp = fgets(tbuffer, sizeof(tbuffer), stream);
417 break; /* hit eof? */
419 sscanf(tbuffer, "%s %s %d %d", dsname, period, &expDate,
422 afs_com_err(whoami, 0,
423 "Syntax error in dump schedule file, line is: %s",
425 return (BC_INTERNALERROR);
428 (struct bc_dumpSchedule *)malloc(sizeof(struct bc_dumpSchedule));
429 memset(tds, 0, sizeof(*tds));
431 tds->next = (struct bc_dumpSchedule *)0;
432 tds->name = strdup(dsname);
434 tds->expDate = expDate;
435 tds->expType = expType;
437 /* find the end of the schedule list, and append the new item to it */
438 ppds = &bc_globalConfig->dsched;
450 bc_SaveDumpSchedule(void)
452 struct bc_dumpSchedule *tdump;
453 udbClientTextP ctPtr;
456 extern struct bc_config *bc_globalConfig;
458 /* setup the right ptr */
459 ctPtr = &bc_globalConfig->configText[TB_DUMPSCHEDULE];
462 if (ctPtr->lockHandle == 0)
463 return (BC_INTERNALERROR);
465 /* truncate the file */
466 code = ftruncate(fileno(ctPtr->textStream), 0);
470 rewind(ctPtr->textStream);
472 /* write the new information */
473 fprintf(ctPtr->textStream, "%d %d\n", BC_SCHEDULE_MAGIC,
474 BC_SCHEDULE_VERSION);
476 for (tdump = bc_globalConfig->dsched; tdump; tdump = tdump->next) {
477 fprintf(ctPtr->textStream, "%s %s %d %d\n", tdump->name, "any",
478 tdump->expDate, tdump->expType);
481 if (ferror(ctPtr->textStream))
482 return (BC_INTERNALERROR);
484 fflush(ctPtr->textStream); /* debug */
487 code = bcdb_SaveTextFile(ctPtr);
491 /* increment local version number */
492 ctPtr->textVersion++;
494 /* update locally stored file size */
495 ctPtr->textSize = filesize(ctPtr->textStream);
501 /* ------------------------------------
502 * misc. support routines - specific to dump schedules
503 * ------------------------------------
507 bc_UpdateDumpSchedule(void)
509 struct bc_dumpSchedule *dumpPtr, *nextDumpPtr;
510 struct udbHandleS *uhptr = &udbHandle;
511 udbClientTextP ctPtr;
515 /* lock schedules and check validity */
516 ctPtr = &bc_globalConfig->configText[TB_DUMPSCHEDULE];
518 code = bc_CheckTextVersion(ctPtr);
519 if (code != BC_VERSIONMISMATCH) {
520 ERROR(code); /* Version matches or some other error */
523 /* Must update the dump schedules */
524 /* If we are not already locked, then lock it now */
525 if (!ctPtr->lockHandle) {
526 code = bc_LockText(ctPtr);
532 if (ctPtr->textVersion != -1) {
533 printf("backup: obsolete dump schedule - updating\n");
535 /* clear all old schedule information */
536 dumpPtr = bc_globalConfig->dsched;
538 nextDumpPtr = dumpPtr->next;
540 dumpPtr = nextDumpPtr;
542 bc_globalConfig->dsched = 0;;
545 /* open a temp file to store the config text received from buserver *
546 * The open file stream is stored in ctPtr->textStream */
548 bc_openTextFile(ctPtr,
550 tmpTextFileNames[TB_DUMPSCHEDULE][0]);
553 /* now get a fresh set of information from the database */
554 code = bcdb_GetTextFile(ctPtr);
558 /* fetch the version number */
560 ubik_BUDB_GetTextVersion(uhptr->uh_client, 0, ctPtr->textType,
561 &ctPtr->textVersion);
566 code = bc_ParseDumpSchedule();
570 /* rebuild the tree */
571 code = bc_ProcessDumpSchedule(bc_globalConfig);
576 if (lock && ctPtr->lockHandle)
577 bc_UnlockText(ctPtr);