volser-restore-timestamp-cleanup-20040728
authorKris Van Hees <kvanhees@sinenomine.net>
Thu, 29 Jul 2004 04:44:08 +0000 (04:44 +0000)
committerDerrick Brashear <shadow@dementia.org>
Thu, 29 Jul 2004 04:44:08 +0000 (04:44 +0000)
FIXES 5926

This patch solves the problem of how timestamps are handled by during a
'vos restore' by allowing the specification of there the creation and last
updated timestamps are taken from:

        - generate a new one using the current time
        - retain the one in the target volume if there is one
        - restore the timestamp from the dump file

This is needed to allow sequences of restoring incremental dumps on top of
full dump work, and to ensure that a subsequent vos release can do a real
incremental release for the restored incremental dumps.

It also fixes the fact that the vos exa command hides potential problems
with timestamps by refusing to display a last updated timestamp that is
older than the creation timestamp.

src/volser/volprocs.c
src/volser/volser.p.h
src/volser/vos.c
src/volser/vsprocs.c

index b681068..a4276ae 100644 (file)
@@ -1540,6 +1540,10 @@ VolSetInfo(struct rx_call *acid, afs_int32 atrans,
        td->maxquota = astatus->maxquota;
     if (astatus->dayUse != -1)
        td->dayUse = astatus->dayUse;
+    if (astatus->creationDate != -1)
+       td->creationDate = astatus->creationDate;
+    if (astatus->updateDate != -1)
+       td->updateDate = astatus->updateDate;
     VUpdateVolume(&error, tv);
     tt->rxCallPtr = (struct rx_call *)0;
     if (TRELE(tt))
index 091b523..c55ab06 100644 (file)
@@ -157,12 +157,18 @@ struct partList {         /*used by the backup system */
 
 /* Values for the UV_RestoreVolume flags parameter */
 /* Also used for UV_CopyVolume and UV_CloneVolume */
-#define RV_FULLRST 0x1
-#define RV_OFFLINE 0x2
-#define RV_RDONLY  0x10000
-#define RV_CPINCR  0x20000
-#define RV_NOVLDB  0x40000
-#define RV_NOCLONE 0x80000
+#define RV_FULLRST     0x00001
+#define RV_OFFLINE     0x00002
+#define RV_CRDUMP      0x00010
+#define RV_CRKEEP      0x00020
+#define RV_CRNEW       0x00040
+#define RV_LUDUMP      0x00100
+#define RV_LUKEEP      0x00200
+#define RV_LUNEW       0x00400
+#define RV_RDONLY      0x10000
+#define RV_CPINCR      0x20000
+#define RV_NOVLDB      0x40000
+#define RV_NOCLONE     0x80000
 
 extern afs_uint32 vsu_GetVolumeID(char *astring, struct ubik_client *acstruct, afs_int32 *errp);
 extern int vsu_ExtractName(char rname[], char name[]);
index fb458a9..5c4d4e2 100644 (file)
@@ -499,12 +499,8 @@ DisplayFormat(pntr, server, part, totalOK, totalNotOK, totalBusy, fast,
                fprintf(STDOUT, "    Last Access %s",
                        ctime((time_t *) & pntr->accessDate));
 #endif
-           if (pntr->updateDate < pntr->creationDate)
-               fprintf(STDOUT, "    Last Update %s",
-                       ctime((time_t *) & pntr->creationDate));
-           else
-               fprintf(STDOUT, "    Last Update %s",
-                       ctime((time_t *) & pntr->updateDate));
+           fprintf(STDOUT, "    Last Update %s",
+                   ctime((time_t *) & pntr->updateDate));
            fprintf(STDOUT,
                    "    %d accesses in the past day (i.e., vnode references)\n",
                    pntr->dayUse);
@@ -656,12 +652,8 @@ XDisplayFormat(a_xInfoP, a_servID, a_partID, a_totalOKP, a_totalNotOKP,
                fprintf(STDOUT, "    Last Access %s",
                        ctime((time_t *) & a_xInfoP->accessDate));
 #endif
-           if (a_xInfoP->updateDate < a_xInfoP->creationDate)
-               fprintf(STDOUT, "    Last Update %s",
-                       ctime((time_t *) & a_xInfoP->creationDate));
-           else
-               fprintf(STDOUT, "    Last Update %s",
-                       ctime((time_t *) & a_xInfoP->updateDate));
+           fprintf(STDOUT, "    Last Update %s",
+                   ctime((time_t *) & a_xInfoP->updateDate));
            fprintf(STDOUT,
                    "    %d accesses in the past day (i.e., vnode references)\n",
                    a_xInfoP->dayUse);
@@ -2575,6 +2567,10 @@ DumpVolume(as)
 #define FULL  2
 #define INC   3
 
+#define TS_DUMP        1
+#define TS_KEEP        2
+#define TS_NEW 3
+
 static
 RestoreVolume(as)
      register struct cmd_syndesc *as;
@@ -2582,6 +2578,7 @@ RestoreVolume(as)
 {
     afs_int32 avolid, aserver, apart, code, vcode, err;
     afs_int32 aoverwrite = ASK;
+    afs_int32 acreation = 0, alastupdate = 0;
     int restoreflags, readonly = 0, offline = 0, voltype = RWVOL;
     char prompt;
     char afilename[NameLen], avolname[VOLSER_MAXVOLNAME + 1], apartName[10];
@@ -2628,6 +2625,40 @@ RestoreVolume(as)
        voltype = ROVOL;
     }
 
+    if (as->parms[8].items) {
+       if ((strcmp(as->parms[8].items->data, "d") == 0)
+           || (strcmp(as->parms[8].items->data, "dump") == 0)) {
+           acreation = TS_DUMP;
+       } else if ((strcmp(as->parms[8].items->data, "k") == 0)
+           || (strcmp(as->parms[8].items->data, "keep") == 0)) {
+           acreation = TS_KEEP;
+       } else if ((strcmp(as->parms[8].items->data, "n") == 0)
+           || (strcmp(as->parms[8].items->data, "new") == 0)) {
+           acreation = TS_NEW;
+       } else {
+           fprintf(STDERR, "vos: %s is not a valid argument to -creation\n",
+                   as->parms[8].items->data);
+           exit(1);
+       }
+    }
+
+    if (as->parms[9].items) {
+       if ((strcmp(as->parms[9].items->data, "d") == 0)
+           || (strcmp(as->parms[9].items->data, "dump") == 0)) {
+           alastupdate = TS_DUMP;
+       } else if ((strcmp(as->parms[9].items->data, "k") == 0)
+           || (strcmp(as->parms[9].items->data, "keep") == 0)) {
+           alastupdate = TS_KEEP;
+       } else if ((strcmp(as->parms[9].items->data, "n") == 0)
+           || (strcmp(as->parms[9].items->data, "new") == 0)) {
+           alastupdate = TS_NEW;
+       } else {
+           fprintf(STDERR, "vos: %s is not a valid argument to -lastupdate\n",
+                   as->parms[9].items->data);
+           exit(1);
+       }
+    }
+
     aserver = GetServer(as->parms[0].items->data);
     if (aserver == 0) {
        fprintf(STDERR, "vos: server '%s' not found in host table\n",
@@ -2779,6 +2810,38 @@ RestoreVolume(as)
        restoreflags |= RV_OFFLINE;
     if (readonly)
        restoreflags |= RV_RDONLY;
+
+    switch (acreation) {
+       case TS_DUMP:
+           restoreflags |= RV_CRDUMP;
+           break;
+       case TS_KEEP:
+           restoreflags |= RV_CRKEEP;
+           break;
+       case TS_NEW:
+           restoreflags |= RV_CRNEW;
+           break;
+       default:
+           if (aoverwrite == FULL)
+               restoreflags |= RV_CRNEW;
+           else
+               restoreflags |= RV_CRKEEP;
+    }
+
+    switch (alastupdate) {
+       case TS_DUMP:
+           restoreflags |= RV_LUDUMP;
+           break;
+       case TS_KEEP:
+           restoreflags |= RV_LUKEEP;
+           break;
+       case TS_NEW:
+           restoreflags |= RV_LUNEW;
+           break;
+       default:
+           restoreflags |= RV_LUKEEP;
+    }
+
     code =
        UV_RestoreVolume(aserver, apart, avolid, avolname, restoreflags,
                         WriteData, afilename);
@@ -5373,6 +5436,10 @@ main(argc, argv)
                "leave restored volume offline");
     cmd_AddParm(ts, "-readonly", CMD_FLAG, CMD_OPTIONAL,
                "make restored volume read-only");
+    cmd_AddParm(ts, "-creation", CMD_SINGLE, CMD_OPTIONAL,
+               "dump | keep | new");
+    cmd_AddParm(ts, "-lastupdate", CMD_SINGLE, CMD_OPTIONAL,
+               "dump | keep | new");
     COMMONPARMS;
 
     ts = cmd_CreateSyntax("unlock", LockReleaseCmd, 0,
index c1d0cca..5f49945 100644 (file)
@@ -4040,6 +4040,7 @@ UV_RestoreVolume(afs_int32 toserver, afs_int32 topart, afs_int32 tovolid,
     afs_int32 totid, code, rcode, vcode, terror = 0;
     afs_int32 rxError = 0;
     struct volser_status tstatus;
+    struct volintInfo vinfo;
     char partName[10];
     afs_int32 pvolid;
     afs_int32 temptid;
@@ -4049,7 +4050,8 @@ UV_RestoreVolume(afs_int32 toserver, afs_int32 topart, afs_int32 tovolid,
     int islocked;
     struct restoreCookie cookie;
     int reuseID;
-    afs_int32 newDate, volflag, voltype, volsertype;
+    afs_int32 volflag, voltype, volsertype;
+    afs_int32 oldCreateDate, oldUpdateDate, newCreateDate, newUpdateDate;
     int index, same, errcode;
     char apartName[10];
 
@@ -4129,6 +4131,13 @@ UV_RestoreVolume(afs_int32 toserver, afs_int32 topart, afs_int32 tovolid,
            EGOTO1(refail, code, "Failed to start transaction on %u\n",
                   pvolid);
 
+           code = AFSVolGetStatus(toconn, totid, &tstatus);
+           EGOTO1(refail, code, "Could not get timestamp from volume %u\n",
+                  pvolid);
+
+           oldCreateDate = tstatus.creationDate;
+           oldUpdateDate = tstatus.updateDate;
+
            code =
                AFSVolSetFlags(toconn, totid,
                               VTDeleteOnSalvage | VTOutOfService);
@@ -4150,8 +4159,6 @@ UV_RestoreVolume(afs_int32 toserver, afs_int32 topart, afs_int32 tovolid,
                AFSVolCreateVolume(toconn, topart, tovolname, volsertype, 0,
                                   &pvolid, &totid);
            EGOTO1(refail, code, "Could not create new volume %u\n", pvolid);
-
-           newDate = 0;
        } else {
            code =
                AFSVolTransCreate(toconn, pvolid, topart, ITOffline, &totid);
@@ -4161,9 +4168,15 @@ UV_RestoreVolume(afs_int32 toserver, afs_int32 topart, afs_int32 tovolid,
            code = AFSVolGetStatus(toconn, totid, &tstatus);
            EGOTO1(refail, code, "Could not get timestamp from volume %u\n",
                   pvolid);
-           newDate = tstatus.creationDate;
+
+           oldCreateDate = tstatus.creationDate;
+           oldUpdateDate = tstatus.updateDate;
        }
+    } else {
+       oldCreateDate = 0;
+       oldUpdateDate = 0;
     }
+
     cookie.parent = pvolid;
     cookie.type = voltype;
     cookie.clone = 0;
@@ -4204,12 +4217,35 @@ UV_RestoreVolume(afs_int32 toserver, afs_int32 topart, afs_int32 tovolid,
        error = code;
        goto refail;
     }
-    if (!newDate)
-       newDate = time(0);
-    code = AFSVolSetDate(toconn, totid, newDate);
+
+    if (flags & RV_CRDUMP)
+       newCreateDate = tstatus.creationDate;
+    else if (flags & RV_CRKEEP && oldCreateDate != 0)
+       newCreateDate = oldCreateDate;
+    else
+       newCreateDate = time(0);
+    if (flags & RV_LUDUMP)
+       newUpdateDate = tstatus.updateDate;
+    else if (flags & RV_LUKEEP)
+       newUpdateDate = oldUpdateDate;
+    else
+       newUpdateDate = time(0);
+    code = AFSVolSetDate(toconn,totid, newCreateDate);
     if (code) {
-       fprintf(STDERR, "Could not set the date on %lu\n",
-               (unsigned long)pvolid);
+       fprintf(STDERR, "Could not set the 'creation' date on %u\n", pvolid);
+       error = code;
+       goto refail;
+    }
+
+    memset(&vinfo, 0, sizeof(struct volintInfo));
+    vinfo.dayUse = -1;
+    vinfo.maxquota = -1;
+    vinfo.creationDate = newCreateDate;
+    vinfo.updateDate = newUpdateDate;
+    code = AFSVolSetInfo(toconn, totid, &vinfo);
+    if (code) {
+       fprintf(STDERR, "Could not set the 'last updated' date on %u\n",
+               pvolid);
        error = code;
        goto refail;
     }