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>
17 #include <afsconfig.h>
25 #include <sys/socket.h>
26 #include <netinet/in.h>
30 #include <afs/ktime.h>
31 #include <afs/budb_client.h>
33 #include <afs/com_err.h>
34 #include <afs/bubasics.h>
36 #include "error_macros.h"
38 /* code to manage dump schedules
39 * specific to the ubik database implementation
42 afs_int32 bc_UpdateDumpSchedule();
43 extern struct bc_config *bc_globalConfig;
44 extern struct udbHandleS udbHandle;
48 /* ------------------------------------
49 * command level routines
50 * ------------------------------------
56 * parm 0: list of dump names
57 * parm 1: expiration date (list)
60 afs_int32 bc_AddDumpCmd(as, arock)
61 struct cmd_syndesc *as;
63 register char *dname; /* dump schedule name */
64 char *dateString; /* expiration date */
65 register afs_int32 code;
66 afs_int32 expType, expDate;
67 register struct cmd_item *ti, *expItem;
70 afs_int32 bc_ParseExpiration();
72 /* if an expiration date has been specified */
73 if (as->parms[1].items)
75 code = bc_ParseExpiration(&as->parms[1], &expType, &expDate);
78 printf("Invalid expiration date syntax\n");
84 /* no expiration date specified */
86 expType = BC_NO_EXPDATE;
89 /* lock schedules and check validity */
90 ctPtr = &bc_globalConfig->configText[TB_DUMPSCHEDULE];
92 code = bc_LockText(ctPtr);
93 if (code) ERROR(code);
95 code = bc_UpdateDumpSchedule();
97 com_err(whoami, code, "; Can't retrieve dump schedule");
101 /* process each dump name using the expiration date computed above */
102 for( ti=as->parms[0].items; ti != 0; ti = ti->next )
104 /* get next dump name to process */
107 /* validate the name dump name length */
108 if ( strlen(dname) >= BU_MAX_DUMP_PATH )
110 com_err(whoami, 0, "Dump names must be < %d characters", BU_MAX_DUMP_PATH);
111 com_err(whoami, 0, "Dump %s not added", dname);
116 code = bc_CreateDumpSchedule(bc_globalConfig, dname, expDate, expType);
120 com_err(whoami,0,"Dump already exists");
123 com_err(whoami,0,"Invalid path name '%s'", dname);
126 com_err(whoami, 0, "Name specification error");
128 com_err(whoami,code,"; Failed to create dump schedule");
132 /* save the new schedule item */
133 code = bc_SaveDumpSchedule();
136 com_err(whoami, code, "Cannot save dump schedule");
137 com_err(whoami,0,"Changes are temporary - for this session only");
141 com_err(whoami,0,"Created new dump schedule %s", dname);
145 if (ctPtr->lockHandle) bc_UnlockText(ctPtr);
151 * delete a dump schedule
154 afs_int32 bc_DeleteDumpCmd(as, arock)
155 struct cmd_syndesc *as;
157 /* parm 0 is vol set name
158 * parm 1 is dump schedule name
160 register char *dname;
161 register afs_int32 code;
162 udbClientTextP ctPtr;
164 /* lock schedules and check validity */
165 ctPtr = &bc_globalConfig->configText[TB_DUMPSCHEDULE];
167 code = bc_LockText(ctPtr);
171 code = bc_UpdateDumpSchedule();
173 com_err(whoami, code, "; Can't retrieve dump schedule");
177 dname = as->parms[0].items->data;
179 code = bc_DeleteDumpSchedule(bc_globalConfig, dname);
183 com_err(whoami,0,"No such dump as %s", dname);
185 com_err(whoami,code,"; Failed to delete dump schedule");
189 code = bc_SaveDumpSchedule();
191 printf("backup: deleted dump schedule %s\n", dname);
194 com_err(whoami, code, "Cannot save dump schedule file");
195 com_err(whoami,0,"Deletion is temporary - for this session only");
199 if ( ctPtr->lockHandle != 0 )
200 bc_UnlockText(ctPtr);
206 /* bc_ListDumpScheduleCmd
207 * list the (internally held) dump schedule tree
212 afs_int32 bc_ListDumpScheduleCmd(as, arock)
213 struct cmd_syndesc *as;
218 register struct bc_dumpSchedule *tdump;
220 /* first check to see if schedules must be updated */
221 code = bc_UpdateDumpSchedule();
223 com_err(whoami, code, "; Can't retrieve dump schedule");
227 /* go through entire list, displaying trees for root-level dump
230 for(tdump = bc_globalConfig->dsched; tdump; tdump=tdump->next)
232 /* if this is a root-level dump, show it and its kids */
234 ListDumpSchedule(tdump, 0);
241 * Set/clear expiration date on existing dump node
243 * parm 0: list of dump names
244 * parm 1: expiration date (list)
247 afs_int32 bc_SetExpCmd(as, arock)
248 struct cmd_syndesc *as;
251 register char *dname; /* dump schedule name */
252 register struct cmd_item *ti;
253 struct bc_dumpSchedule *node, *parent;
254 afs_int32 expType, expDate;
255 udbClientTextP ctPtr;
256 register afs_int32 code;
258 afs_int32 bc_ParseExpiration();
260 /* if an expiration date has been specified */
261 if (as->parms[1].items)
263 code = bc_ParseExpiration(&as->parms[1], &expType, &expDate);
266 printf("Invalid expiration date syntax\n");
272 /* no expiration date specified */
274 expType = BC_NO_EXPDATE;
277 /* lock schedules and check validity */
278 ctPtr = &bc_globalConfig->configText[TB_DUMPSCHEDULE];
280 code = bc_LockText(ctPtr);
281 if (code) ERROR(code);
283 code = bc_UpdateDumpSchedule();
285 com_err(whoami, code, "; Can't retrieve dump schedule");
289 /* process each dump name using the expiration date computed above */
290 for( ti = as->parms[0].items; ti != 0; ti = ti->next)
292 /* get next dump name to process */
295 /* validate the name dump name length */
296 if ( strlen(dname) >= BU_MAX_DUMP_PATH )
299 com_err(whoami, 0, "Dump names must be < %d characters", BU_MAX_DUMP_PATH);
300 com_err(whoami, 0, "Dump %s not added", dname);
304 code = FindDump(bc_globalConfig, dname, &parent, &node);
307 com_err(whoami, 0, "Dump level %s not found", dname);
311 node->expDate = expDate;
312 node->expType = expType;
315 code = bc_SaveDumpSchedule();
318 com_err(whoami, code, "Cannot save dump schedule");
319 com_err(whoami,0,"Expiration changes effective for this session only");
323 if (ctPtr->lockHandle) bc_UnlockText(ctPtr);
329 /* ------------------------------------
330 * general dump schedule handling routines
331 * ------------------------------------
334 bc_ParseDumpSchedule()
337 char dsname[256], period[64];
340 udbClientTextP ctPtr;
341 register struct bc_dumpSchedule *tds;
342 struct bc_dumpSchedule **ppds, *pds;
343 afs_int32 expDate, expType;
345 register FILE *stream;
347 /* initialize locally used variables */
348 ctPtr = &bc_globalConfig->configText[TB_DUMPSCHEDULE];
349 stream = ctPtr->textStream;
351 if ( ctPtr->textSize == 0 ) /* nothing defined yet */
354 if ( stream == NULL )
355 return(BC_INTERNALERROR);
359 /* check the magic number and version */
360 tp = fgets(tbuffer, sizeof(tbuffer), stream);
362 /* can't read first line - error */
363 return(BC_INTERNALERROR);
366 afs_int32 dsmagic, dsversion;
368 /* read the first line, and then check magic # and version */
370 code = sscanf(tbuffer, "%d %d", &dsmagic, &dsversion);
372 || (dsmagic != BC_SCHEDULE_MAGIC)
373 || (dsversion != BC_SCHEDULE_VERSION)
376 /* invalid or unexpected header - error */
377 com_err(whoami, 0, "Unable to understand dump schedule file");
378 return(BC_INTERNALERROR);
384 /* read all of the lines out */
385 tp = fgets(tbuffer, sizeof(tbuffer), stream);
387 break; /* hit eof? */
388 code = sscanf(tbuffer, "%s %s %d %d", dsname, period,
392 com_err(whoami,0,"Syntax error in dump schedule file, line is: %s",
394 return (BC_INTERNALERROR);
396 tds = (struct bc_dumpSchedule *)malloc(sizeof(struct bc_dumpSchedule));
397 bzero(tds, sizeof(*tds));
399 tds->next = (struct bc_dumpSchedule *) 0;
400 tds->name = (char *) malloc(strlen(dsname)+1);
401 strcpy(tds->name, dsname);
403 tds->expDate = expDate;
404 tds->expType = expType;
406 /* find the end of the schedule list, and append the new item to it */
407 ppds = &bc_globalConfig->dsched;
420 bc_SaveDumpSchedule()
422 struct bc_dumpSchedule *tdump;
423 udbClientTextP ctPtr;
426 extern struct bc_config *bc_globalConfig;
427 extern afs_int32 filesize();
429 /* setup the right ptr */
430 ctPtr = &bc_globalConfig->configText[TB_DUMPSCHEDULE];
433 if ( ctPtr->lockHandle == 0 )
434 return(BC_INTERNALERROR);
436 /* truncate the file */
437 code = ftruncate(fileno(ctPtr->textStream), 0);
441 rewind(ctPtr->textStream);
443 /* write the new information */
444 fprintf(ctPtr->textStream, "%d %d\n",
445 BC_SCHEDULE_MAGIC, BC_SCHEDULE_VERSION);
447 for(tdump = bc_globalConfig->dsched; tdump; tdump = tdump->next)
449 fprintf(ctPtr->textStream, "%s %s %d %d\n",tdump->name, "any",
450 tdump->expDate, tdump->expType);
453 if (ferror(ctPtr->textStream))
454 return(BC_INTERNALERROR);
456 fflush(ctPtr->textStream); /* debug */
459 code = bcdb_SaveTextFile(ctPtr);
463 /* increment local version number */
464 ctPtr->textVersion++;
466 /* update locally stored file size */
467 ctPtr->textSize = filesize(ctPtr->textStream);
473 /* ------------------------------------
474 * misc. support routines - specific to dump schedules
475 * ------------------------------------
478 afs_int32 bc_UpdateDumpSchedule()
480 struct bc_dumpSchedule *dumpPtr, *nextDumpPtr;
481 struct udbHandleS *uhptr = &udbHandle;
482 udbClientTextP ctPtr;
486 /* lock schedules and check validity */
487 ctPtr = &bc_globalConfig->configText[TB_DUMPSCHEDULE];
489 code = bc_CheckTextVersion(ctPtr);
490 if ( code != BC_VERSIONMISMATCH )
492 ERROR(code); /* Version matches or some other error */
495 /* Must update the dump schedules */
496 /* If we are not already locked, then lock it now */
497 if ( !ctPtr->lockHandle )
499 code = bc_LockText(ctPtr);
505 if (ctPtr->textVersion != -1)
507 printf("backup: obsolete dump schedule - updating\n");
509 /* clear all old schedule information */
510 dumpPtr = bc_globalConfig->dsched;
513 nextDumpPtr = dumpPtr->next;
515 dumpPtr = nextDumpPtr;
517 bc_globalConfig->dsched = 0;;
520 /* open a temp file to store the config text received from buserver *
521 * The open file stream is stored in ctPtr->textStream */
522 code = bc_openTextFile(ctPtr, &bc_globalConfig->tmpTextFileNames[TB_DUMPSCHEDULE][0]);
525 /* now get a fresh set of information from the database */
526 code = bcdb_GetTextFile(ctPtr);
530 /* fetch the version number */
531 code = ubik_Call(BUDB_GetTextVersion, uhptr->uh_client, 0,
532 ctPtr->textType, &ctPtr->textVersion);
537 code = bc_ParseDumpSchedule();
541 /* rebuild the tree */
542 code = bc_ProcessDumpSchedule(bc_globalConfig);
547 if ( lock && ctPtr->lockHandle )
548 bc_UnlockText(ctPtr);
553 * Print out the dump schedule tree whose root is adump. Alevel should
554 * be passed in as 0, and is incremented for the recursive calls
556 * adump - ptr to the root node of a dump schedule
560 static ListDumpSchedule(adump, alevel)
562 register struct bc_dumpSchedule *adump; {
564 register struct bc_dumpSchedule *child;
568 /* sanity check for loops */
570 printf("backup: recursing listing dump schedule\n");
574 /* move to appropriate indentation level */
575 for(i=0; i<alevel; i++)
578 /* name is a pathname style name, determine trailing name and only print
582 printf("/%s ", tailCompPtr(adump->name));
585 /* list expiration time */
586 switch ( adump->expType )
589 /* absolute expiration date. Never expires if date is 0 */
590 if ( adump->expDate )
592 printf("expires at %.24s", cTIME(&adump->expDate));
598 struct ktime_date kt;
600 /* expiration date relative to the time that the dump is done */
601 LongTo_ktimeRelDate(adump->expDate, &kt);
602 printf(" expires in %s", RelDatetoString(&kt));
610 for(child = adump->firstChild; child; child = child->nextSibling)
611 ListDumpSchedule(child, alevel+1);