volser: update log formatting in dump and restore
[openafs.git] / src / volser / vol-dump.c
index 4dff10b..554ecf0 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Copyright 2000, International Business Machines Corporation and others.
  * All Rights Reserved.
- * 
+ *
  * This software has been released under the terms of the IBM Public
  * License.  For details, see the LICENSE file in the top-level source
  * directory or online at http://www.openafs.org/dl/license10.html
@@ -11,7 +11,7 @@
    System:             VICE-TWO
    Module:             vol-dump.c
    Institution:        The Information Technology Center, Carnegie-Mellon University
-   
+
    */
 
 #include <afsconfig.h>
 # pragma GCC diagnostic warning "-Wformat"
 #endif
 
+#include <roken.h>
+
 #include <ctype.h>
-#include <errno.h>
-#include <sys/stat.h>
-#include <stdio.h>
-#include <string.h>
-#ifdef AFS_NT40_ENV
-#include <fcntl.h>
-#include <time.h>
-#include <io.h>
-#else
-#include <sys/param.h>
-#include <sys/file.h>
-#include <sys/time.h>
-#endif
-#include <afs/cmd.h>
 
+#include <afs/cmd.h>
 #include <rx/xdr.h>
+#include <rx/rx_queue.h>
 #include <afs/afsint.h>
 #include <afs/nfs.h>
 #include <afs/errors.h>
 #include <afs/dir.h>
 #include <afs/com_err.h>
 
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h>
-#endif
-
-#ifdef HAVE_FCNTL_H
-#include <fcntl.h>
-#endif
-
-#ifdef _AIX
-#include <time.h>
-#endif
-
-#include <dirent.h>
-
 #include "volser.h"
 #include "volint.h"
 #include "dump.h"
 
-#define putint32(p, v)  *p++ = v>>24, *p++ = v>>16, *p++ = v>>8, *p++ = v
-#define putshort(p, v) *p++ = v>>8, *p++ = v
-
-#ifdef O_LARGEFILE
-#define afs_stat       stat64
-#define afs_fstat      fstat64
-#define afs_open       open64
-#else /* !O_LARGEFILE */
-#define afs_stat       stat
-#define afs_fstat      fstat
-#define afs_open       open
-#endif /* !O_LARGEFILE */
+#define afs_putint32(p, v)  *p++ = v>>24, *p++ = v>>16, *p++ = v>>8, *p++ = v
+#define afs_putshort(p, v) *p++ = v>>8, *p++ = v
 
 int VolumeChanged;             /* needed by physio - leave alone */
 int verbose = 0;
 
 /* Forward Declarations */
-void HandleVolume(struct DiskPartition64 *partP, char *name, char *filename, int fromtime);
-Volume *AttachVolume(struct DiskPartition64 *dp, char *volname,
-                    register struct VolumeHeader *header);
+static void HandleVolume(struct DiskPartition64 *partP, char *name,
+                        char *filename, int fromtime);
+static Volume *AttachVolume(struct DiskPartition64 *dp, char *volname,
+                           struct VolumeHeader *header);
 static void DoMyVolDump(Volume * vp, struct DiskPartition64 *dp,
                        char *dumpfile, int fromtime);
 
@@ -106,7 +69,7 @@ static void DoMyVolDump(Volume * vp, struct DiskPartition64 *dp,
 char name[VMAXPATHLEN];
 
 
-int
+static int
 ReadHdr1(IHandle_t * ih, char *to, int size, u_int magic, u_int version)
 {
     int code;
@@ -119,11 +82,11 @@ ReadHdr1(IHandle_t * ih, char *to, int size, u_int magic, u_int version)
 }
 
 
-Volume *
+static Volume *
 AttachVolume(struct DiskPartition64 * dp, char *volname,
-            register struct VolumeHeader * header)
+            struct VolumeHeader * header)
 {
-    register Volume *vp;
+    Volume *vp;
     afs_int32 ec = 0;
 
     vp = (Volume *) calloc(1, sizeof(Volume));
@@ -141,7 +104,7 @@ AttachVolume(struct DiskPartition64 * dp, char *volname,
     vp->shuttingDown = 0;
     vp->goingOffline = 0;
     vp->nUsers = 1;
-    vp->header = (struct volHeader *)calloc(1, sizeof(*vp->header));
+    vp->header = calloc(1, sizeof(*vp->header));
     ec = ReadHdr1(V_diskDataHandle(vp), (char *)&V_disk(vp),
                  sizeof(V_disk(vp)), VOLUMEINFOMAGIC, VOLUMEINFOVERSION);
     if (!ec) {
@@ -170,7 +133,7 @@ AttachVolume(struct DiskPartition64 * dp, char *volname,
 static int
 handleit(struct cmd_syndesc *as, void *arock)
 {
-    register struct cmd_item *ti;
+    struct cmd_item *ti;
     int err = 0;
     afs_uint32 volumeId = 0;
     char *partName = 0;
@@ -243,25 +206,25 @@ handleit(struct cmd_syndesc *as, void *arock)
        exit(1);
     }
 
-    (void)afs_snprintf(name1, sizeof name1, VFORMAT, (unsigned long)volumeId);
+    snprintf(name1, sizeof name1, VFORMAT, (unsigned long)volumeId);
     HandleVolume(partP, name1, fileName, fromtime);
     return 0;
 }
 
-void
+static void
 HandleVolume(struct DiskPartition64 *dp, char *name, char *filename, int fromtime)
 {
     struct VolumeHeader header;
     struct VolumeDiskHeader diskHeader;
     struct afs_stat status;
-    register int fd;
+    int fd;
     Volume *vp;
     char headerName[1024];
 
     afs_int32 n;
 
-    (void)afs_snprintf(headerName, sizeof headerName, "%s/%s",
-                      VPartitionPath(dp), name);
+    snprintf(headerName, sizeof headerName, "%s" OS_DIRSEP "%s",
+            VPartitionPath(dp), name);
     if ((fd = afs_open(headerName, O_RDONLY)) == -1
        || afs_fstat(fd, &status) == -1) {
        fprintf(stderr, "Cannot read volume header %s\n", name);
@@ -291,18 +254,25 @@ HandleVolume(struct DiskPartition64 *dp, char *name, char *filename, int fromtim
     }
 
     DoMyVolDump(vp, dp, filename, fromtime);
+
+    free(vp);
 }
 
 
 int
 main(int argc, char **argv)
 {
-    register struct cmd_syndesc *ts;
+    struct cmd_syndesc *ts;
     afs_int32 code;
+    VolumePackageOptions opts;
 
-    VInitVolumePackage(volumeUtility, 5, 5, DONT_CONNECT_FS, 0);
+    VOptDefaults(volumeUtility, &opts);
+    if (VInitVolumePackage2(volumeUtility, &opts)) {
+       fprintf(stderr, "errors encountered initializing volume package, but "
+                       "trying to continue anyway\n");
+    }
 
-    ts = cmd_CreateSyntax(NULL, handleit, NULL,
+    ts = cmd_CreateSyntax(NULL, handleit, NULL, 0,
                          "Dump a volume to a 'vos dump' format file without using volserver");
     cmd_AddParm(ts, "-part", CMD_LIST, CMD_OPTIONAL, "AFS partition name");
     cmd_AddParm(ts, "-volumeid", CMD_LIST, CMD_OPTIONAL, "Volume id");
@@ -318,34 +288,34 @@ main(int argc, char **argv)
 
 
 static int
-DumpDouble(int dumpfd, char tag, register afs_uint32 value1,
-          register afs_uint32 value2)
+DumpDouble(int dumpfd, char tag, afs_uint32 value1,
+          afs_uint32 value2)
 {
     int res;
     char tbuffer[9];
-    register byte *p = (unsigned char *)tbuffer;
+    byte *p = (unsigned char *)tbuffer;
     *p++ = tag;
-    putint32(p, value1);
-    putint32(p, value2);
+    afs_putint32(p, value1);
+    afs_putint32(p, value2);
 
     res = write(dumpfd, tbuffer, 9);
     return ((res == 9) ? 0 : VOLSERDUMPERROR);
 }
 
 static int
-DumpInt32(int dumpfd, char tag, register afs_uint32 value)
+DumpInt32(int dumpfd, char tag, afs_uint32 value)
 {
     char tbuffer[5];
-    register byte *p = (unsigned char *)tbuffer;
+    byte *p = (unsigned char *)tbuffer;
     *p++ = tag;
-    putint32(p, value);
+    afs_putint32(p, value);
     return ((write(dumpfd, tbuffer, 5) == 5) ? 0 : VOLSERDUMPERROR);
 }
 
 static int
-DumpString(int dumpfd, char tag, register char *s)
+DumpString(int dumpfd, char tag, char *s)
 {
-    register int n;
+    int n;
     int code = 0;
     code = write(dumpfd, &tag, 1);
     if (code != 1)
@@ -359,15 +329,15 @@ DumpString(int dumpfd, char tag, register char *s)
 
 
 static int
-DumpArrayInt32(int dumpfd, char tag, register afs_uint32 * array,
-              register int nelem)
+DumpArrayInt32(int dumpfd, char tag, afs_uint32 * array,
+              int nelem)
 {
     char tbuffer[4];
-    register afs_uint32 v;
+    afs_uint32 v;
     int code = 0;
-    register byte *p = (unsigned char *)tbuffer;
+    byte *p = (unsigned char *)tbuffer;
     *p++ = tag;
-    putshort(p, nelem);
+    afs_putshort(p, nelem);
     code = write(dumpfd, tbuffer, 3);
     if (code != 3)
        return VOLSERDUMPERROR;
@@ -375,7 +345,7 @@ DumpArrayInt32(int dumpfd, char tag, register afs_uint32 * array,
        p = (unsigned char *)tbuffer;
        v = *array++;           /*this was register */
 
-       putint32(p, v);
+       afs_putint32(p, v);
        code = write(dumpfd, tbuffer, 4);
        if (code != 4)
            return VOLSERDUMPERROR;
@@ -387,7 +357,7 @@ DumpArrayInt32(int dumpfd, char tag, register afs_uint32 * array,
 
 
 static int
-DumpDumpHeader(int dumpfd, register Volume * vp, afs_int32 fromtime)
+DumpDumpHeader(int dumpfd, Volume * vp, afs_int32 fromtime)
 {
     int code = 0;
     afs_int32 dumpTimes[2];
@@ -405,7 +375,21 @@ DumpDumpHeader(int dumpfd, register Volume * vp, afs_int32 fromtime)
        code = DumpString(dumpfd, 'n', V_name(vp));
 
     dumpTimes[0] = fromtime;
-    dumpTimes[1] = V_backupDate(vp);   /* Until the time the clone was made */
+    switch (V_type(vp)) {
+    case readwriteVolume:
+       dumpTimes[1] = V_updateDate(vp);        /* until last update */
+       break;
+    case readonlyVolume:
+       dumpTimes[1] = V_creationDate(vp);      /* until clone was updated */
+       break;
+    case backupVolume:
+       /* until backup was made */
+       dumpTimes[1] = V_backupDate(vp) != 0 ? V_backupDate(vp) :
+                                              V_creationDate(vp);
+       break;
+    default:
+       code = EINVAL;
+    }
     if (!code)
        code = DumpArrayInt32(dumpfd, 't', (afs_uint32 *) dumpTimes, 2);
 
@@ -423,14 +407,14 @@ static int
 DumpByte(int dumpfd, char tag, byte value)
 {
     char tbuffer[2];
-    register byte *p = (unsigned char *)tbuffer;
+    byte *p = (unsigned char *)tbuffer;
     *p++ = tag;
     *p = value;
     return ((write(dumpfd, tbuffer, 2) == 2) ? 0 : VOLSERDUMPERROR);
 }
 
 static int
-DumpTag(int dumpfd, register int tag)
+DumpTag(int dumpfd, int tag)
 {
     char p;
 
@@ -443,7 +427,7 @@ static int
 DumpBool(int dumpfd, char tag, unsigned int value)
 {
     char tbuffer[2];
-    register byte *p = (unsigned char *)tbuffer;
+    byte *p = (unsigned char *)tbuffer;
     *p++ = tag;
     *p = value;
     return ((write(dumpfd, tbuffer, 2) == 2) ? 0 : VOLSERDUMPERROR);
@@ -452,7 +436,7 @@ DumpBool(int dumpfd, char tag, unsigned int value)
 
 
 static int
-DumpVolumeHeader(int dumpfd, register Volume * vp)
+DumpVolumeHeader(int dumpfd, Volume * vp)
 {
     int code = 0;
 
@@ -527,7 +511,7 @@ static int
 DumpShort(int dumpfd, char tag, unsigned int value)
 {
     char tbuffer[3];
-    register byte *p = (unsigned char *)tbuffer;
+    byte *p = (unsigned char *)tbuffer;
     *p++ = tag;
     *p++ = value >> 8;
     *p = value;
@@ -535,7 +519,7 @@ DumpShort(int dumpfd, char tag, unsigned int value)
 }
 
 static int
-DumpByteString(int dumpfd, char tag, register byte * bs, register int nbytes)
+DumpByteString(int dumpfd, char tag, byte * bs, int nbytes)
 {
     int code = 0;
 
@@ -554,11 +538,18 @@ DumpFile(int dumpfd, int vnode, FdHandle_t * handleP,  struct VnodeDiskObject *v
 {
     int code = 0, failed_seek = 0, failed_write = 0;
     afs_int32 pad = 0;
-    afs_int32 offset = 0;
-    afs_sfsize_t n, nbytes, howMany, howBig;
+    afs_foff_t offset = 0;
+    afs_sfsize_t nbytes, howBig;
+    ssize_t n;
+    size_t howMany;
+    afs_foff_t howFar = 0;
     byte *p;
+    afs_uint32 hi, lo;
+    afs_ino_str_t stmp;
 #ifndef AFS_NT40_ENV
     struct afs_stat status;
+#else
+    LARGE_INTEGER fileSize;
 #endif
     afs_sfsize_t size;
 #ifdef AFS_AIX_ENV
@@ -570,7 +561,11 @@ DumpFile(int dumpfd, int vnode, FdHandle_t * handleP,  struct VnodeDiskObject *v
        fprintf(stderr, "dumping file for vnode %d\n", vnode);
 
 #ifdef AFS_NT40_ENV
-    howBig = _filelength(handleP->fd_fd);
+    if (!GetFileSizeEx(handleP->fd_fd, &fileSize)) {
+        Log("DumpFile: GetFileSizeEx returned error code %d on descriptor %d\n", GetLastError(), handleP->fd_fd);
+           return VOLSERDUMPERROR;
+    }
+    howBig = fileSize.QuadPart;
     howMany = 4096;
 
 #else
@@ -578,7 +573,7 @@ DumpFile(int dumpfd, int vnode, FdHandle_t * handleP,  struct VnodeDiskObject *v
     howBig = status.st_size;
 
 #ifdef AFS_AIX_ENV
-    /* Unfortunately in AIX valuable fields such as st_blksize are 
+    /* Unfortunately in AIX valuable fields such as st_blksize are
      * gone from the stat structure.
      */
     fstatfs(handleP->fd_fd, &tstatfs);
@@ -596,24 +591,18 @@ DumpFile(int dumpfd, int vnode, FdHandle_t * handleP,  struct VnodeDiskObject *v
                (unsigned int) howBig, (unsigned int) howMany,
                (unsigned int) size);
 
-#ifdef AFS_LARGEFILE_ENV
-    {
-       afs_uint32 hi, lo;
-       SplitInt64(size, hi, lo);
-       if (hi == 0L) {
-           code = DumpInt32(dumpfd, 'f', lo);
-       } else {
-           code = DumpDouble(dumpfd, 'h', hi, lo);
-       }
+    SplitInt64(size, hi, lo);
+    if (hi == 0L) {
+       code = DumpInt32(dumpfd, 'f', lo);
+    } else {
+       code = DumpDouble(dumpfd, 'h', hi, lo);
     }
-#else /* !AFS_LARGEFILE_ENV */
-    code = DumpInt32(dumpfd, 'f', size);
-#endif /* !AFS_LARGEFILE_ENV */
+
     if (code) {
        return VOLSERDUMPERROR;
     }
 
-    p = (unsigned char *)malloc(howMany);
+    p = malloc(howMany);
     if (!p) {
        fprintf(stderr, "out of memory!\n");
        return VOLSERDUMPERROR;
@@ -625,14 +614,15 @@ DumpFile(int dumpfd, int vnode, FdHandle_t * handleP,  struct VnodeDiskObject *v
            howMany = nbytes;
 
        /* Read the data - unless we know we can't */
-       n = (failed_seek ? 0 : FDH_READ(handleP, p, howMany));
+       n = (failed_seek ? 0 : FDH_PREAD(handleP, p, howMany, howFar));
+       howFar += n;
 
        /* If read any good data and we null padded previously, log the
         * amount that we had null padded.
         */
        if ((n > 0) && pad) {
-           fprintf(stderr, "Null padding file %d bytes at offset %u\n", pad,
-                   offset);
+           fprintf(stderr, "Null padding file %d bytes at offset %lld\n", pad,
+                   (long long)offset);
            pad = 0;
        }
 
@@ -642,20 +632,20 @@ DumpFile(int dumpfd, int vnode, FdHandle_t * handleP,  struct VnodeDiskObject *v
         */
        if (n < howMany) {
 
-               if (verbose) fprintf(stderr, "  read %u instead of %u bytes.\n", n, howMany);
+               if (verbose) fprintf(stderr, "  read %u instead of %u bytes.\n", (unsigned)n, (unsigned)howMany);
 
            /* Record the read error */
            if (n < 0) {
                n = 0;
                fprintf(stderr, "Error %d reading inode %s for vnode %d\n",
-                       errno, PrintInode(NULL, handleP->fd_ih->ih_ino),
+                       errno, PrintInode(stmp, handleP->fd_ih->ih_ino),
                        vnode);
            } else if (!pad) {
                fprintf(stderr, "Error reading inode %s for vnode %d\n",
-                       PrintInode(NULL, handleP->fd_ih->ih_ino), vnode);
+                       PrintInode(stmp, handleP->fd_ih->ih_ino), vnode);
            }
 
-           /* Pad the rest of the buffer with zeros. Remember offset we started 
+           /* Pad the rest of the buffer with zeros. Remember offset we started
             * padding. Keep total tally of padding.
             */
            memset(p + n, 0, howMany - n);
@@ -666,22 +656,7 @@ DumpFile(int dumpfd, int vnode, FdHandle_t * handleP,  struct VnodeDiskObject *v
            /* Now seek over the data we could not get. An error here means we
             * can't do the next read.
             */
-           failed_seek = FDH_SEEK(handleP, ((size - nbytes) + howMany), SEEK_SET);
-           if (failed_seek != ((size - nbytes) + howMany)) {
-               if (failed_seek < 0) {
-                   fprintf(stderr,
-                           "Error %d seeking in inode %s for vnode %d\n",
-                           errno, PrintInode(NULL, handleP->fd_ih->ih_ino),
-                           vnode);
-               } else {
-                   fprintf(stderr,
-                           "Error seeking in inode %s for vnode %d\n",
-                           PrintInode(NULL, handleP->fd_ih->ih_ino), vnode);
-                   failed_seek = -1;
-               }
-           } else {
-               failed_seek = 0;
-           }
+           howFar = ((size - nbytes) + howMany);
        }
 
        /* Now write the data out */
@@ -690,8 +665,8 @@ DumpFile(int dumpfd, int vnode, FdHandle_t * handleP,  struct VnodeDiskObject *v
     }
 
     if (pad) {                 /* Any padding we hadn't reported yet */
-       fprintf(stderr, "Null padding file: %d bytes at offset %u\n", pad,
-               offset);
+       fprintf(stderr, "Null padding file: %d bytes at offset %lld\n", pad,
+               (long long)offset);
     }
 
     free(p);
@@ -700,12 +675,13 @@ DumpFile(int dumpfd, int vnode, FdHandle_t * handleP,  struct VnodeDiskObject *v
 
 
 static int
-DumpVnode(int dumpfd, struct VnodeDiskObject *v, int volid, int vnodeNumber,
+DumpVnode(int dumpfd, struct VnodeDiskObject *v, VolumeId volid, int vnodeNumber,
          int dumpEverything, struct Volume *vp)
 {
     int code = 0;
     IHandle_t *ihP;
     FdHandle_t *fdP;
+    afs_ino_str_t stmp;
 
     if (verbose)
        fprintf(stderr, "dumping vnode %d\n", vnodeNumber);
@@ -749,15 +725,16 @@ DumpVnode(int dumpfd, struct VnodeDiskObject *v, int volid, int vnodeNumber,
        fdP = IH_OPEN(ihP);
        if (fdP == NULL) {
            fprintf(stderr,
-                   "Unable to open inode %s for vnode %u (volume %i); not dumped, error %d\n",
-                   PrintInode(NULL, VNDISK_GET_INO(v)), vnodeNumber, volid,
-                   errno);
+                   "Unable to open inode %s for vnode %u "
+                   "(volume %"AFS_VOLID_FMT"); not dumped, error %d\n",
+                   PrintInode(stmp, VNDISK_GET_INO(v)), vnodeNumber,
+                   afs_printable_VolumeId_lu(volid), errno);
        }
        else
        {
                if (verbose)
                    fprintf(stderr, "about to dump inode %s for vnode %u\n",
-                           PrintInode(NULL, VNDISK_GET_INO(v)), vnodeNumber);
+                           PrintInode(stmp, VNDISK_GET_INO(v)), vnodeNumber);
                code = DumpFile(dumpfd, vnodeNumber, fdP, v);
                FDH_CLOSE(fdP);
        }
@@ -774,16 +751,16 @@ static int
 DumpVnodeIndex(int dumpfd, Volume * vp, VnodeClass class, afs_int32 fromtime,
               int forcedump)
 {
-    register int code = 0;
-    register struct VnodeClassInfo *vcp = &VnodeClassInfo[class];
+    int code = 0;
+    struct VnodeClassInfo *vcp = &VnodeClassInfo[class];
     char buf[SIZEOF_LARGEDISKVNODE];
     struct VnodeDiskObject *vnode = (struct VnodeDiskObject *)buf;
     StreamHandle_t *file;
     FdHandle_t *fdP;
-    int size;
+    afs_sfsize_t size;
     int flag;
-    int offset = 0;
-    register int vnodeIndex, nVnodes = 0;
+    afs_foff_t offset = 0;
+    int vnodeIndex, nVnodes = 0;
 
     fdP = IH_OPEN(vp->vnodeIndex[class].handle);
     file = FDH_FDOPEN(fdP, "r+");
@@ -791,7 +768,7 @@ DumpVnodeIndex(int dumpfd, Volume * vp, VnodeClass class, afs_int32 fromtime,
     nVnodes = (size / vcp->diskSize) - 1;
 
     if (nVnodes > 0) {
-       STREAM_SEEK(file, vcp->diskSize, 0);
+       STREAM_ASEEK(file, vcp->diskSize);
     } else
        nVnodes = 0;
     for (vnodeIndex = 0;
@@ -802,9 +779,9 @@ DumpVnodeIndex(int dumpfd, Volume * vp, VnodeClass class, afs_int32 fromtime,
         * a serverModifyTime.  For an epoch dump, this results in 0>=0 test, which
         * does dump the file! */
        if (verbose)
-           fprintf(stderr, "about to dump %s vnode %u (vnode offset = %u)\n",
+           fprintf(stderr, "about to dump %s vnode %u (vnode offset = %lld)\n",
                        class == vSmall ? "vSmall" : "vLarge",
-                   bitNumberToVnodeNumber(vnodeIndex, class), offset);
+                   bitNumberToVnodeNumber(vnodeIndex, class), (long long)offset);
        if (!code)
            code =
                DumpVnode(dumpfd, vnode, V_id(vp),
@@ -820,7 +797,7 @@ DumpVnodeIndex(int dumpfd, Volume * vp, VnodeClass class, afs_int32 fromtime,
 
 /* A partial dump (no dump header) */
 static int
-DumpPartial(int dumpfd, register Volume * vp, afs_int32 fromtime,
+DumpPartial(int dumpfd, Volume * vp, afs_int32 fromtime,
            int dumpAllDirs)
 {
     int code = 0;