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 <afs/param.h>
21 #include <sys/socket.h>
22 #include <netinet/in.h>
26 #include <afs/ktime.h>
27 #include <afs/budb_client.h>
29 #include <afs/com_err.h>
30 #include <afs/bubasics.h>
32 #include "error_macros.h"
34 /* code to manage dump schedules
35 * specific to the ubik database implementation
38 afs_int32 bc_UpdateDumpSchedule();
39 extern struct bc_config *bc_globalConfig;
40 extern struct udbHandleS udbHandle;
44 /* ------------------------------------
45 * command level routines
46 * ------------------------------------
52 * parm 0: list of dump names
53 * parm 1: expiration date (list)
56 afs_int32 bc_AddDumpCmd(as, arock)
57 struct cmd_syndesc *as;
59 register char *dname; /* dump schedule name */
60 char *dateString; /* expiration date */
61 register afs_int32 code;
62 afs_int32 expType, expDate;
63 register struct cmd_item *ti, *expItem;
66 afs_int32 bc_ParseExpiration();
68 /* if an expiration date has been specified */
69 if (as->parms[1].items)
71 code = bc_ParseExpiration(&as->parms[1], &expType, &expDate);
74 printf("Invalid expiration date syntax\n");
80 /* no expiration date specified */
82 expType = BC_NO_EXPDATE;
85 /* lock schedules and check validity */
86 ctPtr = &bc_globalConfig->configText[TB_DUMPSCHEDULE];
88 code = bc_LockText(ctPtr);
89 if (code) ERROR(code);
91 code = bc_UpdateDumpSchedule();
93 com_err(whoami, code, "; Can't retrieve dump schedule");
97 /* process each dump name using the expiration date computed above */
98 for( ti=as->parms[0].items; ti != 0; ti = ti->next )
100 /* get next dump name to process */
103 /* validate the name dump name length */
104 if ( strlen(dname) >= BU_MAX_DUMP_PATH )
106 com_err(whoami, 0, "Dump names must be < %d characters", BU_MAX_DUMP_PATH);
107 com_err(whoami, 0, "Dump %s not added", dname);
112 code = bc_CreateDumpSchedule(bc_globalConfig, dname, expDate, expType);
116 com_err(whoami,0,"Dump already exists");
119 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();
132 com_err(whoami, code, "Cannot save dump schedule");
133 com_err(whoami,0,"Changes are temporary - for this session only");
137 com_err(whoami,0,"Created new dump schedule %s", dname);
141 if (ctPtr->lockHandle) bc_UnlockText(ctPtr);
147 * delete a dump schedule
150 afs_int32 bc_DeleteDumpCmd(as, arock)
151 struct cmd_syndesc *as;
153 /* parm 0 is vol set name
154 * parm 1 is dump schedule name
156 register char *dname;
157 register afs_int32 code;
158 udbClientTextP ctPtr;
160 /* lock schedules and check validity */
161 ctPtr = &bc_globalConfig->configText[TB_DUMPSCHEDULE];
163 code = bc_LockText(ctPtr);
167 code = bc_UpdateDumpSchedule();
169 com_err(whoami, code, "; Can't retrieve dump schedule");
173 dname = as->parms[0].items->data;
175 code = bc_DeleteDumpSchedule(bc_globalConfig, dname);
179 com_err(whoami,0,"No such dump as %s", dname);
181 com_err(whoami,code,"; Failed to delete dump schedule");
185 code = bc_SaveDumpSchedule();
187 printf("backup: deleted dump schedule %s\n", dname);
190 com_err(whoami, code, "Cannot save dump schedule file");
191 com_err(whoami,0,"Deletion is temporary - for this session only");
195 if ( ctPtr->lockHandle != 0 )
196 bc_UnlockText(ctPtr);
202 /* bc_ListDumpScheduleCmd
203 * list the (internally held) dump schedule tree
208 afs_int32 bc_ListDumpScheduleCmd(as, arock)
209 struct cmd_syndesc *as;
214 register struct bc_dumpSchedule *tdump;
216 /* first check to see if schedules must be updated */
217 code = bc_UpdateDumpSchedule();
219 com_err(whoami, code, "; Can't retrieve dump schedule");
223 /* go through entire list, displaying trees for root-level dump
226 for(tdump = bc_globalConfig->dsched; tdump; tdump=tdump->next)
228 /* if this is a root-level dump, show it and its kids */
230 ListDumpSchedule(tdump, 0);
237 * Set/clear expiration date on existing dump node
239 * parm 0: list of dump names
240 * parm 1: expiration date (list)
243 afs_int32 bc_SetExpCmd(as, arock)
244 struct cmd_syndesc *as;
247 register char *dname; /* dump schedule name */
248 register struct cmd_item *ti;
249 struct bc_dumpSchedule *node, *parent;
250 afs_int32 expType, expDate;
251 udbClientTextP ctPtr;
252 register afs_int32 code;
254 afs_int32 bc_ParseExpiration();
256 /* if an expiration date has been specified */
257 if (as->parms[1].items)
259 code = bc_ParseExpiration(&as->parms[1], &expType, &expDate);
262 printf("Invalid expiration date syntax\n");
268 /* no expiration date specified */
270 expType = BC_NO_EXPDATE;
273 /* lock schedules and check validity */
274 ctPtr = &bc_globalConfig->configText[TB_DUMPSCHEDULE];
276 code = bc_LockText(ctPtr);
277 if (code) ERROR(code);
279 code = bc_UpdateDumpSchedule();
281 com_err(whoami, code, "; Can't retrieve dump schedule");
285 /* process each dump name using the expiration date computed above */
286 for( ti = as->parms[0].items; ti != 0; ti = ti->next)
288 /* get next dump name to process */
291 /* validate the name dump name length */
292 if ( strlen(dname) >= BU_MAX_DUMP_PATH )
295 com_err(whoami, 0, "Dump names must be < %d characters", BU_MAX_DUMP_PATH);
296 com_err(whoami, 0, "Dump %s not added", dname);
300 code = FindDump(bc_globalConfig, dname, &parent, &node);
303 com_err(whoami, 0, "Dump level %s not found", dname);
307 node->expDate = expDate;
308 node->expType = expType;
311 code = bc_SaveDumpSchedule();
314 com_err(whoami, code, "Cannot save dump schedule");
315 com_err(whoami,0,"Expiration changes effective for this session only");
319 if (ctPtr->lockHandle) bc_UnlockText(ctPtr);
325 /* ------------------------------------
326 * general dump schedule handling routines
327 * ------------------------------------
330 bc_ParseDumpSchedule()
333 char dsname[256], period[64];
336 udbClientTextP ctPtr;
337 register struct bc_dumpSchedule *tds;
338 struct bc_dumpSchedule **ppds, *pds;
339 afs_int32 expDate, expType;
341 register FILE *stream;
343 /* initialize locally used variables */
344 ctPtr = &bc_globalConfig->configText[TB_DUMPSCHEDULE];
345 stream = ctPtr->textStream;
347 if ( ctPtr->textSize == 0 ) /* nothing defined yet */
350 if ( stream == NULL )
351 return(BC_INTERNALERROR);
355 /* check the magic number and version */
356 tp = fgets(tbuffer, sizeof(tbuffer), stream);
358 /* can't read first line - error */
359 return(BC_INTERNALERROR);
362 afs_int32 dsmagic, dsversion;
364 /* read the first line, and then check magic # and version */
366 code = sscanf(tbuffer, "%d %d", &dsmagic, &dsversion);
368 || (dsmagic != BC_SCHEDULE_MAGIC)
369 || (dsversion != BC_SCHEDULE_VERSION)
372 /* invalid or unexpected header - error */
373 com_err(whoami, 0, "Unable to understand dump schedule file");
374 return(BC_INTERNALERROR);
380 /* read all of the lines out */
381 tp = fgets(tbuffer, sizeof(tbuffer), stream);
383 break; /* hit eof? */
384 code = sscanf(tbuffer, "%s %s %d %d", dsname, period,
388 com_err(whoami,0,"Syntax error in dump schedule file, line is: %s",
390 return (BC_INTERNALERROR);
392 tds = (struct bc_dumpSchedule *)malloc(sizeof(struct bc_dumpSchedule));
393 bzero(tds, sizeof(*tds));
395 tds->next = (struct bc_dumpSchedule *) 0;
396 tds->name = (char *) malloc(strlen(dsname)+1);
397 strcpy(tds->name, dsname);
399 tds->expDate = expDate;
400 tds->expType = expType;
402 /* find the end of the schedule list, and append the new item to it */
403 ppds = &bc_globalConfig->dsched;
416 bc_SaveDumpSchedule()
418 struct bc_dumpSchedule *tdump;
419 udbClientTextP ctPtr;
422 extern struct bc_config *bc_globalConfig;
423 extern afs_int32 filesize();
425 /* setup the right ptr */
426 ctPtr = &bc_globalConfig->configText[TB_DUMPSCHEDULE];
429 if ( ctPtr->lockHandle == 0 )
430 return(BC_INTERNALERROR);
432 /* truncate the file */
433 code = ftruncate(fileno(ctPtr->textStream), 0);
437 rewind(ctPtr->textStream);
439 /* write the new information */
440 fprintf(ctPtr->textStream, "%d %d\n",
441 BC_SCHEDULE_MAGIC, BC_SCHEDULE_VERSION);
443 for(tdump = bc_globalConfig->dsched; tdump; tdump = tdump->next)
445 fprintf(ctPtr->textStream, "%s %s %d %d\n",tdump->name, "any",
446 tdump->expDate, tdump->expType);
449 if (ferror(ctPtr->textStream))
450 return(BC_INTERNALERROR);
452 fflush(ctPtr->textStream); /* debug */
455 code = bcdb_SaveTextFile(ctPtr);
459 /* increment local version number */
460 ctPtr->textVersion++;
462 /* update locally stored file size */
463 ctPtr->textSize = filesize(ctPtr->textStream);
469 /* ------------------------------------
470 * misc. support routines - specific to dump schedules
471 * ------------------------------------
474 afs_int32 bc_UpdateDumpSchedule()
476 struct bc_dumpSchedule *dumpPtr, *nextDumpPtr;
477 struct udbHandleS *uhptr = &udbHandle;
478 udbClientTextP ctPtr;
482 /* lock schedules and check validity */
483 ctPtr = &bc_globalConfig->configText[TB_DUMPSCHEDULE];
485 code = bc_CheckTextVersion(ctPtr);
486 if ( code != BC_VERSIONMISMATCH )
488 ERROR(code); /* Version matches or some other error */
491 /* Must update the dump schedules */
492 /* If we are not already locked, then lock it now */
493 if ( !ctPtr->lockHandle )
495 code = bc_LockText(ctPtr);
501 if (ctPtr->textVersion != -1)
503 printf("backup: obsolete dump schedule - updating\n");
505 /* clear all old schedule information */
506 dumpPtr = bc_globalConfig->dsched;
509 nextDumpPtr = dumpPtr->next;
511 dumpPtr = nextDumpPtr;
513 bc_globalConfig->dsched = 0;;
516 /* open a temp file to store the config text received from buserver *
517 * The open file stream is stored in ctPtr->textStream */
518 code = bc_openTextFile(ctPtr, &bc_globalConfig->tmpTextFileNames[TB_DUMPSCHEDULE][0]);
521 /* now get a fresh set of information from the database */
522 code = bcdb_GetTextFile(ctPtr);
526 /* fetch the version number */
527 code = ubik_Call(BUDB_GetTextVersion, uhptr->uh_client, 0,
528 ctPtr->textType, &ctPtr->textVersion);
533 code = bc_ParseDumpSchedule();
537 /* rebuild the tree */
538 code = bc_ProcessDumpSchedule(bc_globalConfig);
543 if ( lock && ctPtr->lockHandle )
544 bc_UnlockText(ctPtr);
549 * Print out the dump schedule tree whose root is adump. Alevel should
550 * be passed in as 0, and is incremented for the recursive calls
552 * adump - ptr to the root node of a dump schedule
556 static ListDumpSchedule(adump, alevel)
558 register struct bc_dumpSchedule *adump; {
560 register struct bc_dumpSchedule *child;
564 /* sanity check for loops */
566 printf("backup: recursing listing dump schedule\n");
570 /* move to appropriate indentation level */
571 for(i=0; i<alevel; i++)
574 /* name is a pathname style name, determine trailing name and only print
578 printf("/%s ", tailCompPtr(adump->name));
581 /* list expiration time */
582 switch ( adump->expType )
585 /* absolute expiration date. Never expires if date is 0 */
586 if ( adump->expDate )
588 printf("expires at %.24s", cTIME(&adump->expDate));
594 struct ktime_date kt;
596 /* expiration date relative to the time that the dump is done */
597 LongTo_ktimeRelDate(adump->expDate, &kt);
598 printf(" expires in %s", RelDatetoString(&kt));
606 for(child = adump->firstChild; child; child = child->nextSibling)
607 ListDumpSchedule(child, alevel+1);