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>
17 #include <afsconfig.h>
18 #include <afs/param.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"
37 #include "bucoord_internal.h"
38 #include "bucoord_prototypes.h"
40 /* code to manage dump schedules
41 * specific to the ubik database implementation
44 extern struct bc_config *bc_globalConfig;
45 extern struct udbHandleS udbHandle;
48 static int ListDumpSchedule(struct bc_dumpSchedule *adump, int alevel);
50 /* ------------------------------------
51 * command level routines
52 * ------------------------------------
58 * parm 0: list of dump names
59 * parm 1: expiration date (list)
63 bc_AddDumpCmd(struct cmd_syndesc *as, void *arock)
65 char *dname; /* dump schedule name */
67 afs_int32 expType, expDate;
71 /* if an expiration date has been specified */
72 if (as->parms[1].items) {
73 code = bc_ParseExpiration(&as->parms[1], &expType, &expDate);
75 printf("Invalid expiration date syntax\n");
79 /* no expiration date specified */
81 expType = BC_NO_EXPDATE;
84 /* lock schedules and check validity */
85 ctPtr = &bc_globalConfig->configText[TB_DUMPSCHEDULE];
87 code = bc_LockText(ctPtr);
91 code = bc_UpdateDumpSchedule();
93 afs_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) {
99 /* get next dump name to process */
102 /* validate the name dump name length */
103 if (strlen(dname) >= BU_MAX_DUMP_PATH) {
104 afs_com_err(whoami, 0, "Dump names must be < %d characters",
106 afs_com_err(whoami, 0, "Dump %s not added", dname);
112 bc_CreateDumpSchedule(bc_globalConfig, dname, expDate, expType);
115 afs_com_err(whoami, 0, "Dump already exists");
117 afs_com_err(whoami, 0, "Invalid path name '%s'", dname);
119 afs_com_err(whoami, 0, "Name specification error");
121 afs_com_err(whoami, code, "; Failed to create dump schedule");
125 /* save the new schedule item */
126 code = bc_SaveDumpSchedule();
128 afs_com_err(whoami, code, "Cannot save dump schedule");
129 afs_com_err(whoami, 0,
130 "Changes are temporary - for this session only");
134 afs_com_err(whoami, 0, "Created new dump schedule %s", dname);
138 if (ctPtr->lockHandle)
139 bc_UnlockText(ctPtr);
145 * delete a dump schedule
149 bc_DeleteDumpCmd(struct cmd_syndesc *as, void *arock)
151 /* parm 0 is vol set name
152 * parm 1 is dump schedule name
156 udbClientTextP ctPtr;
158 /* lock schedules and check validity */
159 ctPtr = &bc_globalConfig->configText[TB_DUMPSCHEDULE];
161 code = bc_LockText(ctPtr);
165 code = bc_UpdateDumpSchedule();
167 afs_com_err(whoami, code, "; Can't retrieve dump schedule");
171 dname = as->parms[0].items->data;
173 code = bc_DeleteDumpSchedule(bc_globalConfig, dname);
176 afs_com_err(whoami, 0, "No such dump as %s", dname);
178 afs_com_err(whoami, code, "; Failed to delete dump schedule");
182 code = bc_SaveDumpSchedule();
184 printf("backup: deleted dump schedule %s\n", dname);
186 afs_com_err(whoami, code, "Cannot save dump schedule file");
187 afs_com_err(whoami, 0, "Deletion is temporary - for this session only");
191 if (ctPtr->lockHandle != 0)
192 bc_UnlockText(ctPtr);
197 * Print out the dump schedule tree whose root is adump. Alevel should
198 * be passed in as 0, and is incremented for the recursive calls
200 * adump - ptr to the root node of a dump schedule
205 ListDumpSchedule(struct bc_dumpSchedule *adump, int alevel)
208 struct bc_dumpSchedule *child;
210 /* sanity check for loops */
212 printf("backup: recursing listing dump schedule\n");
216 /* move to appropriate indentation level */
217 for (i = 0; i < alevel; i++)
220 /* name is a pathname style name, determine trailing name and only print
224 printf("/%s ", tailCompPtr(adump->name));
227 /* list expiration time */
228 switch (adump->expType) {
230 /* absolute expiration date. Never expires if date is 0 */
231 if (adump->expDate) {
232 time_t t = adump->expDate;
233 printf("expires at %.24s", cTIME(&t));
239 struct ktime_date kt;
241 /* expiration date relative to the time that the dump is done */
242 LongTo_ktimeRelDate(adump->expDate, &kt);
243 printf(" expires in %s", RelDatetoString(&kt));
251 for (child = adump->firstChild; child; child = child->nextSibling)
252 ListDumpSchedule(child, alevel + 1);
257 /* bc_ListDumpScheduleCmd
258 * list the (internally held) dump schedule tree
264 bc_ListDumpScheduleCmd(struct cmd_syndesc *as, void *arock)
268 struct bc_dumpSchedule *tdump;
270 /* first check to see if schedules must be updated */
271 code = bc_UpdateDumpSchedule();
273 afs_com_err(whoami, code, "; Can't retrieve dump schedule");
277 /* go through entire list, displaying trees for root-level dump
280 for (tdump = bc_globalConfig->dsched; tdump; tdump = tdump->next) {
281 /* if this is a root-level dump, show it and its kids */
283 ListDumpSchedule(tdump, 0);
290 * Set/clear expiration date on existing dump node
292 * parm 0: list of dump names
293 * parm 1: expiration date (list)
297 bc_SetExpCmd(struct cmd_syndesc *as, void *arock)
299 char *dname; /* dump schedule name */
301 struct bc_dumpSchedule *node, *parent;
302 afs_int32 expType, expDate;
303 udbClientTextP ctPtr;
306 /* if an expiration date has been specified */
307 if (as->parms[1].items) {
308 code = bc_ParseExpiration(&as->parms[1], &expType, &expDate);
310 printf("Invalid expiration date syntax\n");
314 /* no expiration date specified */
316 expType = BC_NO_EXPDATE;
319 /* lock schedules and check validity */
320 ctPtr = &bc_globalConfig->configText[TB_DUMPSCHEDULE];
322 code = bc_LockText(ctPtr);
326 code = bc_UpdateDumpSchedule();
328 afs_com_err(whoami, code, "; Can't retrieve dump schedule");
332 /* process each dump name using the expiration date computed above */
333 for (ti = as->parms[0].items; ti != 0; ti = ti->next) {
334 /* get next dump name to process */
337 /* validate the name dump name length */
338 if (strlen(dname) >= BU_MAX_DUMP_PATH) {
340 afs_com_err(whoami, 0, "Dump names must be < %d characters",
342 afs_com_err(whoami, 0, "Dump %s not added", dname);
346 code = FindDump(bc_globalConfig, dname, &parent, &node);
348 afs_com_err(whoami, 0, "Dump level %s not found", dname);
352 node->expDate = expDate;
353 node->expType = expType;
356 code = bc_SaveDumpSchedule();
358 afs_com_err(whoami, code, "Cannot save dump schedule");
359 afs_com_err(whoami, 0,
360 "Expiration changes effective for this session only");
364 if (ctPtr->lockHandle)
365 bc_UnlockText(ctPtr);
371 /* ------------------------------------
372 * general dump schedule handling routines
373 * ------------------------------------
377 bc_ParseDumpSchedule(void)
380 char dsname[256], period[64];
383 udbClientTextP ctPtr;
384 struct bc_dumpSchedule *tds;
385 struct bc_dumpSchedule **ppds, *pds;
386 afs_int32 expDate, expType;
390 /* initialize locally used variables */
391 ctPtr = &bc_globalConfig->configText[TB_DUMPSCHEDULE];
392 stream = ctPtr->textStream;
394 if (ctPtr->textSize == 0) /* nothing defined yet */
398 return (BC_INTERNALERROR);
402 /* check the magic number and version */
403 tp = fgets(tbuffer, sizeof(tbuffer), stream);
405 /* can't read first line - error */
406 return (BC_INTERNALERROR);
408 afs_int32 dsmagic, dsversion;
410 /* read the first line, and then check magic # and version */
412 code = sscanf(tbuffer, "%d %d", &dsmagic, &dsversion);
414 || (dsmagic != BC_SCHEDULE_MAGIC)
415 || (dsversion != BC_SCHEDULE_VERSION)
417 /* invalid or unexpected header - error */
418 afs_com_err(whoami, 0, "Unable to understand dump schedule file");
419 return (BC_INTERNALERROR);
424 /* read all of the lines out */
425 tp = fgets(tbuffer, sizeof(tbuffer), stream);
427 break; /* hit eof? */
429 sscanf(tbuffer, "%s %s %d %d", dsname, period, &expDate,
432 afs_com_err(whoami, 0,
433 "Syntax error in dump schedule file, line is: %s",
435 return (BC_INTERNALERROR);
438 (struct bc_dumpSchedule *)malloc(sizeof(struct bc_dumpSchedule));
439 memset(tds, 0, sizeof(*tds));
441 tds->next = (struct bc_dumpSchedule *)0;
442 tds->name = (char *)malloc(strlen(dsname) + 1);
443 strcpy(tds->name, dsname);
445 tds->expDate = expDate;
446 tds->expType = expType;
448 /* find the end of the schedule list, and append the new item to it */
449 ppds = &bc_globalConfig->dsched;
461 bc_SaveDumpSchedule(void)
463 struct bc_dumpSchedule *tdump;
464 udbClientTextP ctPtr;
467 extern struct bc_config *bc_globalConfig;
469 /* setup the right ptr */
470 ctPtr = &bc_globalConfig->configText[TB_DUMPSCHEDULE];
473 if (ctPtr->lockHandle == 0)
474 return (BC_INTERNALERROR);
476 /* truncate the file */
477 code = ftruncate(fileno(ctPtr->textStream), 0);
481 rewind(ctPtr->textStream);
483 /* write the new information */
484 fprintf(ctPtr->textStream, "%d %d\n", BC_SCHEDULE_MAGIC,
485 BC_SCHEDULE_VERSION);
487 for (tdump = bc_globalConfig->dsched; tdump; tdump = tdump->next) {
488 fprintf(ctPtr->textStream, "%s %s %d %d\n", tdump->name, "any",
489 tdump->expDate, tdump->expType);
492 if (ferror(ctPtr->textStream))
493 return (BC_INTERNALERROR);
495 fflush(ctPtr->textStream); /* debug */
498 code = bcdb_SaveTextFile(ctPtr);
502 /* increment local version number */
503 ctPtr->textVersion++;
505 /* update locally stored file size */
506 ctPtr->textSize = filesize(ctPtr->textStream);
512 /* ------------------------------------
513 * misc. support routines - specific to dump schedules
514 * ------------------------------------
518 bc_UpdateDumpSchedule(void)
520 struct bc_dumpSchedule *dumpPtr, *nextDumpPtr;
521 struct udbHandleS *uhptr = &udbHandle;
522 udbClientTextP ctPtr;
526 /* lock schedules and check validity */
527 ctPtr = &bc_globalConfig->configText[TB_DUMPSCHEDULE];
529 code = bc_CheckTextVersion(ctPtr);
530 if (code != BC_VERSIONMISMATCH) {
531 ERROR(code); /* Version matches or some other error */
534 /* Must update the dump schedules */
535 /* If we are not already locked, then lock it now */
536 if (!ctPtr->lockHandle) {
537 code = bc_LockText(ctPtr);
543 if (ctPtr->textVersion != -1) {
544 printf("backup: obsolete dump schedule - updating\n");
546 /* clear all old schedule information */
547 dumpPtr = bc_globalConfig->dsched;
549 nextDumpPtr = dumpPtr->next;
551 dumpPtr = nextDumpPtr;
553 bc_globalConfig->dsched = 0;;
556 /* open a temp file to store the config text received from buserver *
557 * The open file stream is stored in ctPtr->textStream */
559 bc_openTextFile(ctPtr,
561 tmpTextFileNames[TB_DUMPSCHEDULE][0]);
564 /* now get a fresh set of information from the database */
565 code = bcdb_GetTextFile(ctPtr);
569 /* fetch the version number */
571 ubik_BUDB_GetTextVersion(uhptr->uh_client, 0, ctPtr->textType,
572 &ctPtr->textVersion);
577 code = bc_ParseDumpSchedule();
581 /* rebuild the tree */
582 code = bc_ProcessDumpSchedule(bc_globalConfig);
587 if (lock && ctPtr->lockHandle)
588 bc_UnlockText(ctPtr);