#include <afsconfig.h>
#include <afs/param.h>
-RCSID
- ("$Header$");
#include <sys/types.h>
#include <ctype.h>
#include <stdio.h>
#include <errno.h>
+#include <string.h>
#ifdef AFS_NT40_ENV
#include <fcntl.h>
#else
#include <netinet/in.h>
#include <unistd.h>
#endif
-#ifdef HAVE_STRING_H
-#include <string.h>
-#else
-#ifdef HAVE_STRINGS_H
-#include <strings.h>
-#endif
-#endif
#include <sys/stat.h>
+#ifdef AFS_PTHREAD_ENV
+#include <assert.h>
+#else /* AFS_PTHREAD_ENV */
#include <afs/assert.h>
+#endif /* AFS_PTHREAD_ENV */
#include <rx/xdr.h>
#include <rx/rx.h>
#include <afs/afsint.h>
#include <afs/volume.h>
#include <afs/partition.h>
#include "dump.h"
+#include <afs/daemon_com.h>
#include <afs/fssync.h>
#include <afs/acl.h>
+#include <afs/com_err.h>
+#include <afs/vol_prototypes.h>
#include "volser.h"
#include "volint.h"
+#include "dumpstuff.h"
+
+#ifndef AFS_NT40_ENV
+#ifdef O_LARGEFILE
+#define afs_stat stat64
+#define afs_fstat fstat64
+#else /* !O_LARGEFILE */
+#define afs_stat stat
+#define afs_fstat fstat
+#endif /* !O_LARGEFILE */
+#endif /* !AFS_NT40_ENV */
/*@printflike@*/ extern void Log(const char *format, ...);
extern int DoLogging;
-/* This iod stuff is a silly little package to emulate the old qi_in stuff, which
- emulated the stdio stuff. There is a big assumption here, that the
- rx_Read will never be called directly, by a routine like readFile, when
- there is an old character that was pushed back with iod_ungetc. This
- is really bletchy, and is here for compatibility only. Eventually,
- we should define a volume format that doesn't require
- the pushing back of characters (i.e. characters should not double both
- as an end marker and a begin marker) */
-struct iod {
- struct rx_call *call; /* call to which to write, might be an array */
- int device; /* dump device ID for volume */
- int parentId; /* dump parent ID for volume */
- struct DiskPartition *dumpPartition; /* Dump partition. */
- struct rx_call **calls; /* array of pointers to calls */
- int ncalls; /* how many calls/codes in array */
- int *codes; /* one return code for each call */
- char haveOldChar; /* state for pushing back a character */
- char oldChar;
-};
-
/* Forward Declarations */
static int DumpDumpHeader(register struct iod *iodp, register Volume * vp,
static int ReadVnodes(register struct iod *iodp, Volume * vp, int incremental,
afs_int32 * Lbuf, afs_int32 s1, afs_int32 * Sbuf,
afs_int32 s2, afs_int32 delo);
-static bit32 volser_WriteFile(int vn, struct iod *iodp, FdHandle_t * handleP,
- Error * status);
+static afs_fsize_t volser_WriteFile(int vn, struct iod *iodp,
+ FdHandle_t * handleP, int tag,
+ Error * status);
static int SizeDumpDumpHeader(register struct iod *iodp, register Volume * vp,
afs_int32 fromtime,
int volid, int vnodeNumber, int dumpEverything,
register struct volintSize *size);
+#define MAX_SECTIONS 3
+#define MIN_TLV_TAG 5
+#define MAX_TLV_TAG 0x60
+#define MAX_STANDARD_TAG 0x7a
+static afs_uint32 oldtags[MAX_SECTIONS][16];
+int oldtagsInited = 0;
+
+static void
+RegisterTag(afs_int32 section, unsigned char tag)
+{
+ afs_uint32 off = tag >> 5;
+ afs_uint32 mask = 1 << (tag & 0x1f);
+ oldtags[section][off] |= mask;
+}
+
+static void
+initNonStandardTags(void)
+{
+ RegisterTag(0, 'n'); /* volume name */
+ RegisterTag(0, 't'); /* fromtime, V_backupDate */
+ RegisterTag(1, 'A'); /* V_accessDate */
+ RegisterTag(1, 'C'); /* V_creationDate */
+ RegisterTag(1, 'D'); /* V_dayUseDate */
+ RegisterTag(1, 'E'); /* V_expirationDate */
+ RegisterTag(1, 'M'); /* nullstring (motd) */
+ RegisterTag(1, 'U'); /* V_updateDate */
+ RegisterTag(1, 'W'); /* V_weekUse */
+ RegisterTag(1, 'Z'); /* V_dayUse */
+ RegisterTag(1, 'O'); /* V_offlineMessage */
+ RegisterTag(1, 'b'); /* V_blessed */
+ RegisterTag(1, 'n'); /* V_name */
+ RegisterTag(1, 's'); /* V_inService */
+ RegisterTag(1, 't'); /* V_type */
+ RegisterTag(2, 'A'); /* VVnodeDiskACL */
+ RegisterTag(2, 'b'); /* modeBits */
+ RegisterTag(2, 'f'); /* small file */
+ RegisterTag(2, 'h'); /* large file */
+ RegisterTag(2, 'l'); /* linkcount */
+ RegisterTag(2, 't'); /* type */
+ oldtagsInited = 1;
+}
+
static void
iod_Init(register struct iod *iodp, register struct rx_call *call)
{
iodp->haveOldChar = 0;
return iodp->oldChar;
}
- if (iod_Read(iodp, &t, 1) == 1)
+ if (iod_Read(iodp, (char *) &t, 1) == 1)
return t;
return EOF;
}
static int
ReadShort(register struct iod *iodp, register unsigned short *sp)
{
- register b1, b0;
+ register int b1, b0;
b1 = iod_getc(iodp);
+ if (b1 == EOF)
+ return 0;
b0 = iod_getc(iodp);
+ if (b0 == EOF)
+ return 0;
*sp = (b1 << 8) | b0;
- return b0 != EOF;
+ return 1;
}
static int
{
afs_uint32 register b3, b2, b1, b0;
b3 = iod_getc(iodp);
+ if (b3 == EOF)
+ return 0;
b2 = iod_getc(iodp);
+ if (b2 == EOF)
+ return 0;
b1 = iod_getc(iodp);
+ if (b1 == EOF)
+ return 0;
b0 = iod_getc(iodp);
+ if (b0 == EOF)
+ return 0;
*lp = (((((b3 << 8) | b2) << 8) | b1) << 8) | b0;
- return b0 != EOF;
+ return 1;
}
static void
ReadString(register struct iod *iodp, register char *to, register int maxa)
{
register int c;
+
+ *to = '\0';
+ if (maxa == 0)
+ return;
+
while (maxa--) {
- if ((*to++ = iod_getc(iodp)) == 0)
+ if ((*to++ = c = iod_getc(iodp)) == 0 || c == EOF)
break;
}
if (to[-1]) {
while ((c = iod_getc(iodp)) && c != EOF);
- to[-1] = 0;
+ to[-1] = '\0';
}
}
*to++ = iod_getc(iodp);
}
+/*
+ * returns 1 on success and 0 otherwise
+ */
+static afs_int32
+ReadStandardTagLen(register struct iod *iodp, unsigned char tag, afs_int32 section,
+ afs_size_t *length)
+{
+ afs_int32 code, i;
+ afs_uint32 off = tag >> 5;
+ afs_uint32 mask = 1 << (tag & 0x1f);
+ unsigned char len, buf[8], *p;
+
+ if (!oldtagsInited)
+ initNonStandardTags();
+
+ if (tag < MIN_TLV_TAG
+ || tag > MAX_STANDARD_TAG
+ || section >= MAX_SECTIONS
+ || (oldtags[section][ off] & mask)) {
+ Log("Trying to use ReadStandardTag with tag 0x%02x for section %d, aborting\n", tag, section);
+ return 0;
+ }
+ if (tag <= MAX_TLV_TAG) {
+ len = iod_getc(iodp);
+ if (len < 128)
+ *length = len;
+ else {
+ len &= 0x7f;
+ if ((code = iod_Read(iodp, (char *)buf, len)) != len)
+ return VOLSERDUMPERROR;
+ *length = 0;
+ p = (unsigned char *)&buf;
+ for (i=0; i<len; i++) {
+ *length = ((*length) << 8) | *p++;
+ }
+ }
+ } else {
+ if (tag < MAX_STANDARD_TAG)
+ *length = 4;
+ }
+ return 1;
+}
+
+static char skipbuf[256];
+
+static afs_int32
+SkipData(register struct iod *iodp, afs_size_t length)
+{
+ while (length > 256) {
+ if (iod_Read(iodp, (char *)&skipbuf, 256) != 256)
+ return 0;
+ length -= 256;
+ }
+ if (iod_Read(iodp, (char *)&skipbuf, length) != length)
+ return 0;
+ return 1;
+}
+
+static char *secname[3] = {"ReadDumpHeader", "ReadVolumeHeader", "ReadVnodes"};
+
+static int
+HandleUnknownTag(struct iod *iodp, int tag, afs_int32 section,
+ afs_int32 critical)
+{
+ afs_size_t taglen = 0;
+ afs_uint32 trash;
+
+ if (critical) {
+ Log("%s: unknown critical tag x%02x, aborting\n",
+ secname[section], tag);
+ return 0;
+ }
+ Log("%s: unknown tag x%02x found, skipping\n", secname[section], tag);
+ if (tag >= 0x06 && tag <= 0x60) {
+ if (!ReadStandardTagLen(iodp, tag, 1, &taglen)) {
+ Log("%s: error reading length field for tag x%02x, aborting\n",
+ secname[section], tag);
+ return 0;
+ }
+ if (!SkipData(iodp, taglen)) {
+ Log("%s: error skipping %llu bytes for tag x%02x, aborting\n",
+ secname[section], taglen, tag);
+ return 0;
+ }
+ return 1;
+ }
+ if (tag >= 0x61 && tag <= 0x7a) {
+ if (!ReadInt32(iodp, &trash)) {
+ Log("%s: error skipping int32 for tag x%02x, aborting\n",
+ secname[section], tag);
+ return 0;
+ }
+ return 1;
+ }
+ if (tag >= 0x7b && tag < 0x80) /* dataless tag */
+ return 1;
+ Log("%s: unknown invalid tag x%02x, aborting\n", secname[section], tag);
+ return 0;
+}
+
static int
ReadVolumeHeader(register struct iod *iodp, VolumeDiskData * vol)
{
- register tag;
+ register int tag;
afs_uint32 trash;
+ afs_int32 critical = 0;
memset(vol, 0, sizeof(*vol));
while ((tag = iod_getc(iodp)) > D_MAX && tag != EOF) {
+ if (critical)
+ critical--;
switch (tag) {
case 'i':
if (!ReadInt32(iodp, &vol->id))
if (!ReadInt32(iodp, (afs_uint32 *) & vol->dayUse))
return VOLSERREAD_DUMPERROR;
break;
+ case 'V':
+ if (!ReadInt32(iodp, (afs_uint32 *) &trash/*volUpdateCounter*/))
+ return VOLSERREAD_DUMPERROR;
+ break;
+ case 0x7e:
+ critical = 2;
+ break;
+ default:
+ if (!HandleUnknownTag(iodp, tag, 1, critical))
+ return VOLSERREAD_DUMPERROR;
}
}
iod_ungetc(iodp, tag);
static int
DumpString(register struct iod *iodp, char tag, register char *s)
{
- register n;
+ register int n;
int code = 0;
code = iod_Write(iodp, &tag, 1);
if (code != 1)
return 0;
}
+static afs_int32
+DumpStandardTag(register struct iod *iodp, char tag, afs_uint32 section)
+{
+ afs_int32 code;
+ afs_uint32 off = tag >> 5;
+ afs_uint32 mask = 1 << (tag & 0x1f);
+
+ if (!oldtagsInited)
+ initNonStandardTags();
+
+ if (tag < MIN_TLV_TAG
+ || tag > MAX_STANDARD_TAG
+ || section >= MAX_SECTIONS
+ || (oldtags[section][ off] & mask)) {
+ Log("Trying to use DumpStandardTag with tag 0x%02x for section %d, aborting\n", tag, section);
+ return VOLSERDUMPERROR;
+ }
+ code = iod_Write(iodp, &tag, 1);
+ return 0;
+}
+
+AFS_UNUSED
+static afs_int32
+DumpStandardTagLen(register struct iod *iodp, char tag, afs_uint32 section,
+ afs_size_t length)
+{
+ char buf[10];
+ char *p;
+ afs_int32 code, len;
+
+ if (tag < MIN_TLV_TAG || tag > MAX_TLV_TAG) {
+ Log("Trying to use DumpStandardTagLen with tag 0x%02x for section %d, aborting\n", tag, section);
+ return VOLSERDUMPERROR;
+ }
+ code = DumpStandardTag(iodp, tag, section);
+ if (code)
+ return code;
+ p = &buf[9];
+ if (length < 128) { /* byte after tag contains length */
+ *p-- = length;
+ len = 1;
+ } else { /* byte after tag contains length of length field | 0x80 */
+ for (len=0; length; length=length >> 8) {
+ *p-- = length;
+ len++;
+ }
+ *p-- = len + 128;
+ len += 1;
+ }
+ p++;
+ code = iod_Write(iodp, p, len);
+ if (code != len)
+ return VOLSERDUMPERROR;
+ return 0;
+}
+
static int
-DumpFile(struct iod *iodp, char tag, int vnode, FdHandle_t * handleP)
+DumpFile(struct iod *iodp, int vnode, FdHandle_t * handleP)
{
- int code = 0, lcode = 0, error = 0;
- afs_int32 pad = 0, offset;
- int n, nbytes, howMany, howBig;
+ int code = 0, error = 0;
+ afs_int32 pad = 0;
+ afs_int32 offset = 0;
+ afs_sfsize_t n, nbytes, howMany, howBig;
+ afs_foff_t lcode = 0;
byte *p;
- struct stat status;
- int size;
+ afs_uint32 hi, lo;
+#ifndef AFS_NT40_ENV
+ struct afs_stat status;
+#endif
+ afs_sfsize_t size;
#ifdef AFS_AIX_ENV
#include <sys/statfs.h>
+#if defined(AFS_AIX52_ENV)
+ struct statfs64 tstatfs;
+#else /* !AFS_AIX52_ENV */
struct statfs tstatfs;
+#endif /* !AFS_AIX52_ENV */
+ int statfs_code;
#endif
#ifdef AFS_NT40_ENV
howMany = 4096;
#else
- fstat(handleP->fd_fd, &status);
+ afs_fstat(handleP->fd_fd, &status);
howBig = status.st_size;
#ifdef AFS_AIX_ENV
/* Unfortunately in AIX valuable fields such as st_blksize are
* gone from the stat structure.
*/
- fstatfs(handleP->fd_fd, &tstatfs);
- howMany = tstatfs.f_bsize;
+#if defined(AFS_AIX52_ENV)
+ statfs_code = fstatfs64(handleP->fd_fd, &tstatfs);
+#else /* !AFS_AIX52_ENV */
+ statfs_code = fstatfs(handleP->fd_fd, &tstatfs);
+#endif /* !AFS_AIX52_ENV */
+ if (statfs_code != 0) {
+ Log("DumpFile: fstatfs returned error code %d on descriptor %d\n", errno, handleP->fd_fd);
+ return VOLSERDUMPERROR;
+ }
+ howMany = (afs_sfsize_t) tstatfs.f_bsize;
#else
howMany = status.st_blksize;
#endif /* AFS_AIX_ENV */
size = FDH_SIZE(handleP);
- code = DumpInt32(iodp, tag, size);
+ SplitInt64(size, hi, lo);
+ if (hi == 0L) {
+ code = DumpInt32(iodp, 'f', lo);
+ } else {
+ code = DumpDouble(iodp, 'h', hi, lo);
+ }
if (code) {
return VOLSERDUMPERROR;
}
- p = (unsigned char *)malloc(howMany);
+ p = (unsigned char *)malloc((size_t)howMany);
if (!p) {
- Log("1 Volser: DumpFile: no memory");
+ Log("1 Volser: DumpFile: not enough memory to allocate %u bytes\n", howMany);
return VOLSERDUMPERROR;
}
howMany = nbytes;
/* Read the data - unless we know we can't */
- n = (lcode ? 0 : FDH_READ(handleP, p, howMany));
+ n = (lcode ? 0 : FDH_READ(handleP, p, (size_t)howMany));
/* If read any good data and we null padded previously, log the
* amount that we had null padded.
/* Record the read error */
if (n < 0) {
n = 0;
- Log("1 Volser: DumpFile: Error %d reading inode %s for vnode %d\n", errno, PrintInode(NULL, handleP->fd_ih->ih_ino), vnode);
+ Log("1 Volser: DumpFile: Error reading inode %s for vnode %d: %s\n", PrintInode(NULL, handleP->fd_ih->ih_ino), vnode, afs_error_message(errno));
} else if (!pad) {
Log("1 Volser: DumpFile: Error reading inode %s for vnode %d\n", PrintInode(NULL, handleP->fd_ih->ih_ino), vnode);
}
/* Now seek over the data we could not get. An error here means we
* can't do the next read.
*/
- lcode = FDH_SEEK(handleP, ((size - nbytes) + howMany), SEEK_SET);
+ lcode = FDH_SEEK(handleP, (size_t)((size - nbytes) + howMany), SEEK_SET);
if (lcode != ((size - nbytes) + howMany)) {
if (lcode < 0) {
- Log("1 Volser: DumpFile: Error %d seeking in inode %s for vnode %d\n", errno, PrintInode(NULL, handleP->fd_ih->ih_ino), vnode);
+ Log("1 Volser: DumpFile: Error seeking in inode %s for vnode %d: %s\n", PrintInode(NULL, handleP->fd_ih->ih_ino), vnode, afs_error_message(errno));
} else {
Log("1 Volser: DumpFile: Error seeking in inode %s for vnode %d\n", PrintInode(NULL, handleP->fd_ih->ih_ino), vnode);
lcode = -1;
}
/* Now write the data out */
- if (iod_Write(iodp, (char *)p, howMany) != howMany)
+ if (iod_Write(iodp, (char *)p, (size_t)howMany) != howMany)
error = VOLSERDUMPERROR;
+#ifndef AFS_PTHREAD_ENV
IOMGR_Poll();
+#endif
}
if (pad) { /* Any padding we hadn't reported yet */
code =
DumpVnode(iodp, vnode, V_id(vp),
bitNumberToVnodeNumber(vnodeIndex, class), flag);
+#ifndef AFS_PTHREAD_ENV
if (!flag)
IOMGR_Poll(); /* if we dont' xfr data, but scan instead, could lose conn */
+#endif
}
STREAM_CLOSE(file);
FDH_CLOSE(fdP);
IH_RELEASE(ihP);
return VOLSERREAD_DUMPERROR;
}
- code = DumpFile(iodp, 'f', vnodeNumber, fdP);
+ code = DumpFile(iodp, vnodeNumber, fdP);
FDH_CLOSE(fdP);
IH_RELEASE(ihP);
}
ProcessIndex(Volume * vp, VnodeClass class, afs_int32 ** Bufp, int *sizep,
int del)
{
- int i, nVnodes, offset, code, index = 0;
+ int i, nVnodes, offset, code;
afs_int32 *Buf;
int cnt = 0;
int size;
if (vnode->type != vNull && VNDISK_GET_INO(vnode)) {
cnt1++;
if (DoLogging) {
- afs_fsize_t vnodeLength;
- Log("RestoreVolume %u Cleanup: Removing old vnode=%u inode=%llu size=%llu\n", V_id(vp), bitNumberToVnodeNumber(i, class), (afs_uintmax_t) VNDISK_GET_INO(vnode), (afs_uintmax_t) vnodeLength);
+ Log("RestoreVolume %u Cleanup: Removing old vnode=%u inode=%llu size=unknown\n",
+ V_id(vp), bitNumberToVnodeNumber(i, class),
+ (afs_uintmax_t) VNDISK_GET_INO(vnode));
}
IH_DEC(V_linkHandle(vp), VNDISK_GET_INO(vnode),
V_parentId(vp));
(size <=
vcp->diskSize ? 0 : size - vcp->diskSize) >> vcp->logSize;
if (nVnodes > 0) {
+ if (DoLogging) {
+ Log("RestoreVolume ProcessIndex: Set up %d inodes for volume %d\n",
+ nVnodes, V_id(vp));
+ }
Buf = (afs_int32 *) malloc(nVnodes * sizeof(afs_int32));
- if (Buf == NULL)
- return 1;
- memset((char *)Buf, 0, nVnodes * sizeof(afs_int32));
+ if (Buf == NULL) {
+ STREAM_CLOSE(afile);
+ FDH_CLOSE(fdP);
+ return -1;
+ }
+ memset(Buf, 0, nVnodes * sizeof(afs_int32));
STREAM_SEEK(afile, offset = vcp->diskSize, 0);
while (1) {
code = STREAM_READ(vnode, vcp->diskSize, 1, afile);
}
offset += vcp->diskSize;
}
+ if (DoLogging) {
+ Log("RestoreVolume ProcessIndex: found %d inodes\n", cnt);
+ }
*Bufp = Buf;
*sizep = nVnodes;
}
register Volume *vp;
struct iod iod;
register struct iod *iodp = &iod;
- afs_int32 *b1 = 0, *b2 = 0;
+ afs_int32 *b1 = NULL, *b2 = NULL;
int s1 = 0, s2 = 0, delo = 0, tdelo;
int tag;
iod_Init(iodp, call);
vp = avp;
+
if (!ReadDumpHeader(iodp, &header)) {
Log("1 Volser: RestoreVolume: Error reading header file for dump; aborted\n");
return VOLSERREAD_DUMPERROR;
if (ReadVolumeHeader(iodp, &vol) == VOLSERREAD_DUMPERROR)
return VOLSERREAD_DUMPERROR;
- delo = ProcessIndex(vp, vLarge, &b1, &s1, 0);
+ if (!delo)
+ delo = ProcessIndex(vp, vLarge, &b1, &s1, 0);
if (!delo)
delo = ProcessIndex(vp, vSmall, &b2, &s2, 0);
- if (delo) {
- if (b1)
- free((char *)b1);
- if (b2)
- free((char *)b2);
- b1 = b2 = 0;
+ if (delo < 0) {
+ Log("1 Volser: RestoreVolume: ProcessIndex failed; not restored\n");
+ error = VOLSERREAD_DUMPERROR;
+ goto out;
}
strncpy(vol.name, cookie->name, VOLSER_OLDMAXVOLNAME);
vol.cloneId = cookie->clone;
vol.parentId = cookie->parent;
-
tdelo = delo;
while (1) {
if (ReadVnodes(iodp, vp, 0, b1, s1, b2, s2, tdelo)) {
tag = iod_getc(iodp);
if (tag != D_VOLUMEHEADER)
break;
+
if (ReadVolumeHeader(iodp, &vol) == VOLSERREAD_DUMPERROR) {
error = VOLSERREAD_DUMPERROR;
goto out;
}
- tdelo = -1;
}
if (tag != D_DUMPEND || !ReadInt32(iodp, &endMagic)
|| endMagic != DUMPENDMAGIC) {
}
if (!delo) {
- ProcessIndex(vp, vLarge, &b1, &s1, 1);
- ProcessIndex(vp, vSmall, &b2, &s2, 1);
+ delo = ProcessIndex(vp, vLarge, &b1, &s1, 1);
+ if (!delo)
+ delo = ProcessIndex(vp, vSmall, &b2, &s2, 1);
+ if (delo < 0) {
+ error = VOLSERREAD_DUMPERROR;
+ goto clean;
+ }
}
clean:
{
afs_int32 vnodeNumber;
char buf[SIZEOF_LARGEDISKVNODE];
- register tag;
+ register int tag;
struct VnodeDiskObject *vnode = (struct VnodeDiskObject *)buf;
struct VnodeDiskObject oldvnode;
int idx;
IHandle_t *tmpH;
FdHandle_t *fdP;
Inode nearInode;
+ afs_int32 critical = 0;
tag = iod_getc(iodp);
V_pref(vp, nearInode);
if (!ReadInt32(iodp, (afs_uint32 *) & vnodeNumber))
break;
- ReadInt32(iodp, &vnode->uniquifier);
+ if (!ReadInt32(iodp, &vnode->uniquifier))
+ return VOLSERREAD_DUMPERROR;
+
+ if (DoLogging) {
+ Log("ReadVnodes: setup %d/%d\n", vnodeNumber, vnode->uniquifier);
+ }
while ((tag = iod_getc(iodp)) > D_MAX && tag != EOF) {
haveStuff = 1;
+ if (critical)
+ critical--;
switch (tag) {
case 't':
vnode->type = (VnodeType) iod_getc(iodp);
case 'l':
{
unsigned short tlc;
- ReadShort(iodp, &tlc);
+ if (!ReadShort(iodp, &tlc))
+ return VOLSERREAD_DUMPERROR;
vnode->linkCount = (signed int)tlc;
}
break;
case 'v':
- ReadInt32(iodp, &vnode->dataVersion);
+ if (!ReadInt32(iodp, &vnode->dataVersion))
+ return VOLSERREAD_DUMPERROR;
break;
case 'm':
- ReadInt32(iodp, &vnode->unixModifyTime);
+ if (!ReadInt32(iodp, &vnode->unixModifyTime))
+ return VOLSERREAD_DUMPERROR;
break;
case 's':
- ReadInt32(iodp, &vnode->serverModifyTime);
+ if (!ReadInt32(iodp, &vnode->serverModifyTime))
+ return VOLSERREAD_DUMPERROR;
break;
case 'a':
- ReadInt32(iodp, &vnode->author);
+ if (!ReadInt32(iodp, &vnode->author))
+ return VOLSERREAD_DUMPERROR;
break;
case 'o':
- ReadInt32(iodp, &vnode->owner);
+ if (!ReadInt32(iodp, &vnode->owner))
+ return VOLSERREAD_DUMPERROR;
break;
case 'g':
- ReadInt32(iodp, (afs_uint32 *) & vnode->group);
+ if (!ReadInt32(iodp, (afs_uint32 *) & vnode->group))
+ return VOLSERREAD_DUMPERROR;
break;
case 'b':{
unsigned short modeBits;
- ReadShort(iodp, &modeBits);
+ if (!ReadShort(iodp, &modeBits))
+ return VOLSERREAD_DUMPERROR;
vnode->modeBits = (unsigned int)modeBits;
break;
}
case 'p':
- ReadInt32(iodp, &vnode->parent);
+ if (!ReadInt32(iodp, &vnode->parent))
+ return VOLSERREAD_DUMPERROR;
break;
case 'A':
ReadByteString(iodp, (byte *) VVnodeDiskACL(vnode),
VAclDiskSize(vnode));
acl_NtohACL(VVnodeDiskACL(vnode));
break;
+ case 'h':
case 'f':{
Inode ino;
Error error;
V_parentId(vp), vnodeNumber,
vnode->uniquifier, vnode->dataVersion);
if (!VALID_INO(ino)) {
- perror("unable to allocate inode");
- Log("1 Volser: ReadVnodes: Restore aborted\n");
+ Log("1 Volser: ReadVnodes: IH_CREATE: %s - restore aborted\n",
+ afs_error_message(errno));
return VOLSERREAD_DUMPERROR;
}
nearInode = ino;
IH_INIT(tmpH, vp->device, V_parentId(vp), ino);
fdP = IH_OPEN(tmpH);
if (fdP == NULL) {
+ Log("1 Volser: ReadVnodes: IH_OPEN: %s - restore aborted\n",
+ afs_error_message(errno));
IH_RELEASE(tmpH);
return VOLSERREAD_DUMPERROR;
}
vnodeLength =
- volser_WriteFile(vnodeNumber, iodp, fdP, &error);
+ volser_WriteFile(vnodeNumber, iodp, fdP, tag, &error);
VNDISK_SET_LEN(vnode, vnodeLength);
FDH_REALLYCLOSE(fdP);
IH_RELEASE(tmpH);
}
break;
}
+ case 0x7e:
+ critical = 2;
+ break;
+ default:
+ if (!HandleUnknownTag(iodp, tag, 2, critical))
+ return VOLSERREAD_DUMPERROR;
}
}
if (haveStuff) {
FdHandle_t *fdP = IH_OPEN(vp->vnodeIndex[class].handle);
if (fdP == NULL) {
- Log("1 Volser: ReadVnodes: Error opening vnode index; restore aborted\n");
+ Log("1 Volser: ReadVnodes: Error opening vnode index: %s; restore aborted\n",
+ afs_error_message(errno));
return VOLSERREAD_DUMPERROR;
}
if (FDH_SEEK(fdP, vnodeIndexOffset(vcp, vnodeNumber), SEEK_SET) <
0) {
- Log("1 Volser: ReadVnodes: Error seeking into vnode index; restore aborted\n");
+ Log("1 Volser: ReadVnodes: Error seeking into vnode index: %s; restore aborted\n",
+ afs_error_message(errno));
FDH_REALLYCLOSE(fdP);
return VOLSERREAD_DUMPERROR;
}
vnode->vnodeMagic = vcp->magic;
if (FDH_SEEK(fdP, vnodeIndexOffset(vcp, vnodeNumber), SEEK_SET) <
0) {
- Log("1 Volser: ReadVnodes: Error seeking into vnode index; restore aborted\n");
+ Log("1 Volser: ReadVnodes: Error seeking into vnode index: %s; restore aborted\n",
+ afs_error_message(errno));
FDH_REALLYCLOSE(fdP);
return VOLSERREAD_DUMPERROR;
}
if (FDH_WRITE(fdP, vnode, vcp->diskSize) != vcp->diskSize) {
- Log("1 Volser: ReadVnodes: Error writing vnode index; restore aborted\n");
+ Log("1 Volser: ReadVnodes: Error writing vnode index: %s; restore aborted\n",
+ afs_error_message(errno));
FDH_REALLYCLOSE(fdP);
return VOLSERREAD_DUMPERROR;
}
}
iod_ungetc(iodp, tag);
-
return 0;
}
* needing to read an ungetc'd character, since the ReadInt32 will have read
* it instead.
*/
-static bit32
-volser_WriteFile(int vn, struct iod *iodp, FdHandle_t * handleP,
+static afs_fsize_t
+volser_WriteFile(int vn, struct iod *iodp, FdHandle_t * handleP, int tag,
Error * status)
{
afs_int32 code;
- afs_uint32 filesize;
- bit32 written = 0;
+ afs_sfsize_t lcode;
+ afs_fsize_t filesize;
+ afs_fsize_t written = 0;
register afs_uint32 size = 8192;
- register afs_uint32 nbytes;
+ register afs_fsize_t nbytes;
unsigned char *p;
*status = 0;
+#ifdef AFS_64BIT_ENV
+ {
+ afs_uint32 filesize_high = 0L, filesize_low = 0L;
+ if (tag == 'h') {
+ if (!ReadInt32(iodp, &filesize_high)) {
+ *status = 1;
+ return 0;
+ }
+ }
+ if (!ReadInt32(iodp, &filesize_low)) {
+ *status = 1;
+ return 0;
+ }
+ FillInt64(filesize, filesize_high, filesize_low);
+ }
+#else /* !AFS_64BIT_ENV */
if (!ReadInt32(iodp, &filesize)) {
*status = 1;
return (0);
}
+#endif /* !AFS_64BIT_ENV */
p = (unsigned char *)malloc(size);
if (p == NULL) {
*status = 2;
if (nbytes < size)
size = nbytes;
- if ((code = iod_Read(iodp, p, size)) != size) {
- Log("1 Volser: WriteFile: Error reading dump file %d size=%llu nbytes=%u (%d of %u); restore aborted\n", vn, (afs_uintmax_t) filesize, nbytes, code, size);
+ if ((code = iod_Read(iodp, (char *) p, size)) != size) {
+ Log("1 Volser: WriteFile: Error reading dump file %d size=%llu nbytes=%u (%d of %u): %s; restore aborted\n", vn, (afs_uintmax_t) filesize, nbytes, code, size, afs_error_message(errno));
*status = 3;
break;
}
- code = FDH_WRITE(handleP, p, size);
- if (code > 0)
- written += code;
- if (code != size) {
- Log("1 Volser: WriteFile: Error creating file in volume; restore aborted\n");
+ lcode = FDH_WRITE(handleP, p, size);
+ if (lcode > 0)
+ written += lcode;
+ if (lcode != size) {
+ Log("1 Volser: WriteFile: Error writing (%d,%u) bytes to vnode %d: %s; restore aborted\n", (int)(lcode>>32), (int)(lcode & 0xffffffff), vn, afs_error_message(errno));
*status = 4;
break;
}
static int
ReadDumpHeader(register struct iod *iodp, struct DumpHeader *hp)
{
- register tag;
+ register int tag;
afs_uint32 beginMagic;
+ afs_int32 critical = 0;
if (iod_getc(iodp) != D_DUMPHEADER || !ReadInt32(iodp, &beginMagic)
|| !ReadInt32(iodp, (afs_uint32 *) & hp->version)
|| beginMagic != DUMPBEGINMAGIC)
while ((tag = iod_getc(iodp)) > D_MAX) {
unsigned short arrayLength;
register int i;
+ if (critical)
+ critical--;
switch (tag) {
case 'v':
if (!ReadInt32(iodp, &hp->volumeId))
|| !ReadInt32(iodp, (afs_uint32 *) & hp->dumpTimes[i].to))
return 0;
break;
+ case 0x7e:
+ critical = 2;
+ break;
+ default:
+ if (!HandleUnknownTag(iodp, tag, 0, critical))
+ return VOLSERREAD_DUMPERROR;
}
}
if (!hp->volumeId || !hp->nDumpTimes) {
{
int code = 0;
static char nullString[1] = ""; /*The ``contents'' of motd */
+ afs_uint64 addvar;
/* if (!code) code = DumpTag(iodp, D_VOLUMEHEADER); */
- v_size->dump_size += 1;
+ FillInt64(addvar,0, 1);
+ AddUInt64(v_size->dump_size, addvar, &v_size->dump_size);
/* if (!code) {code = DumpInt32(iodp, 'i',V_id(vp));} */
- v_size->dump_size += 5;
+ FillInt64(addvar,0, 5);
+ AddUInt64(v_size->dump_size, addvar, &v_size->dump_size);
/* if (!code) code = DumpInt32(iodp, 'v',V_stamp(vp).version); */
- v_size->dump_size += 5;
+ FillInt64(addvar,0, 5);
+ AddUInt64(v_size->dump_size, addvar, &v_size->dump_size);
/* if (!code) code = DumpString(iodp, 'n',V_name(vp)); */
- v_size->dump_size += (2 + strlen(V_name(vp)));
+ FillInt64(addvar,0, (2 + strlen(V_name(vp))));
+ AddUInt64(v_size->dump_size, addvar, &v_size->dump_size);
/* if (!code) code = DumpBool(iodp, 's',V_inService(vp)); */
- v_size->dump_size += 2;
+ FillInt64(addvar,0, 2);
+ AddUInt64(v_size->dump_size, addvar, &v_size->dump_size);
/* if (!code) code = DumpBool(iodp, 'b',V_blessed(vp)); */
- v_size->dump_size += 2;
+ FillInt64(addvar,0, 2);
+ AddUInt64(v_size->dump_size, addvar, &v_size->dump_size);
/* if (!code) code = DumpInt32(iodp, 'u',V_uniquifier(vp)); */
- v_size->dump_size += 5;
+ FillInt64(addvar,0, 5);
+ AddUInt64(v_size->dump_size, addvar, &v_size->dump_size);
/* if (!code) code = DumpByte(iodp, 't',(byte)V_type(vp)); */
- v_size->dump_size += 2;
+ FillInt64(addvar,0, 2);
+ AddUInt64(v_size->dump_size, addvar, &v_size->dump_size);
/* if (!code){ code = DumpInt32(iodp, 'p',V_parentId(vp));} */
- v_size->dump_size += 5;
+ FillInt64(addvar,0, 5);
+ AddUInt64(v_size->dump_size, addvar, &v_size->dump_size);
/* if (!code) code = DumpInt32(iodp, 'c',V_cloneId(vp)); */
- v_size->dump_size += 5;
+ FillInt64(addvar,0, 5);
+ AddUInt64(v_size->dump_size, addvar, &v_size->dump_size);
/* if (!code) code = DumpInt32(iodp, 'q',V_maxquota(vp)); */
- v_size->dump_size += 5;
+ FillInt64(addvar,0, 5);
+ AddUInt64(v_size->dump_size, addvar, &v_size->dump_size);
/* if (!code) code = DumpInt32(iodp, 'm',V_minquota(vp)); */
- v_size->dump_size += 5;
+ FillInt64(addvar,0, 5);
+ AddUInt64(v_size->dump_size, addvar, &v_size->dump_size);
/* if (!code) code = DumpInt32(iodp, 'd',V_diskused(vp)); */
- v_size->dump_size += 5;
+ FillInt64(addvar,0, 5);
+ AddUInt64(v_size->dump_size, addvar, &v_size->dump_size);
/* if (!code) code = DumpInt32(iodp, 'f',V_filecount(vp)); */
- v_size->dump_size += 5;
+ FillInt64(addvar,0, 5);
+ AddUInt64(v_size->dump_size, addvar, &v_size->dump_size);
/* if (!code) code = DumpInt32(iodp, 'a', V_accountNumber(vp)); */
- v_size->dump_size += 5;
+ FillInt64(addvar,0, 5);
+ AddUInt64(v_size->dump_size, addvar, &v_size->dump_size);
/* if (!code) code = DumpInt32(iodp, 'o', V_owner(vp)); */
- v_size->dump_size += 5;
+ FillInt64(addvar,0, 5);
+ AddUInt64(v_size->dump_size, addvar, &v_size->dump_size);
/* if (!code) code = DumpInt32(iodp, 'C',V_creationDate(vp)); /\* Rw volume creation date *\/ */
- v_size->dump_size += 5;
+ FillInt64(addvar,0, 5);
+ AddUInt64(v_size->dump_size, addvar, &v_size->dump_size);
/* if (!code) code = DumpInt32(iodp, 'A',V_accessDate(vp)); */
- v_size->dump_size += 5;
+ FillInt64(addvar,0, 5);
+ AddUInt64(v_size->dump_size, addvar, &v_size->dump_size);
/* if (!code) code = DumpInt32(iodp, 'U',V_updateDate(vp)); */
- v_size->dump_size += 5;
+ FillInt64(addvar,0, 5);
+ AddUInt64(v_size->dump_size, addvar, &v_size->dump_size);
/* if (!code) code = DumpInt32(iodp, 'E',V_expirationDate(vp)); */
- v_size->dump_size += 5;
+ FillInt64(addvar,0, 5);
+ AddUInt64(v_size->dump_size, addvar, &v_size->dump_size);
/* if (!code) code = DumpInt32(iodp, 'B',V_backupDate(vp)); /\* Rw volume backup clone date *\/ */
- v_size->dump_size += 5;
+ FillInt64(addvar,0, 5);
+ AddUInt64(v_size->dump_size, addvar, &v_size->dump_size);
/* if (!code) code = DumpString(iodp, 'O',V_offlineMessage(vp)); */
- v_size->dump_size += (2 + strlen(V_offlineMessage(vp)));
+ FillInt64(addvar,0, (2 + strlen(V_offlineMessage(vp))));
+ AddUInt64(v_size->dump_size, addvar, &v_size->dump_size);
/* /\* */
/* * We do NOT dump the detailed volume statistics residing in the old */
/* * motd field, since we cannot tell from the info in a dump whether */
/* * just as if that was what the motd contained. */
/* *\/ */
/* if (!code) code = DumpString(iodp, 'M', nullString); */
- v_size->dump_size += (2 + strlen(nullString));
+ FillInt64(addvar,0, (2 + strlen(nullString)));
+ AddUInt64(v_size->dump_size, addvar, &v_size->dump_size);
/* if (!code) code = DumpArrayInt32(iodp, 'W', (afs_uint32 *)V_weekUse(vp), sizeof(V_weekUse(vp))/sizeof(V_weekUse(vp)[0])); */
- v_size->dump_size +=
- (3 + 4 * (sizeof(V_weekUse(vp)) / sizeof(V_weekUse(vp)[0])));
+ FillInt64(addvar,0, (3 + 4 * (sizeof(V_weekUse(vp)) / sizeof(V_weekUse(vp)[0]))));
+ AddUInt64(v_size->dump_size, addvar, &v_size->dump_size);
/* if (!code) code = DumpInt32(iodp, 'D', V_dayUseDate(vp)); */
- v_size->dump_size += 5;
+ FillInt64(addvar,0, 5);
+ AddUInt64(v_size->dump_size, addvar, &v_size->dump_size);
/* if (!code) code = DumpInt32(iodp, 'Z', V_dayUse(vp)); */
- v_size->dump_size += 5;
+ FillInt64(addvar,0, 5);
+ AddUInt64(v_size->dump_size, addvar, &v_size->dump_size);
return code;
}
SizeDumpEnd(register struct iod *iodp, register struct volintSize *v_size)
{
int code = 0;
- v_size->dump_size += 5;
+ afs_uint64 addvar;
+ FillInt64(addvar,0, 5);
+ AddUInt64(v_size->dump_size, addvar, &v_size->dump_size);
return code;
}
afs_int32 fromtime, int dumpAllDirs,
register struct volintSize *v_size)
{
- struct iod iod;
int code = 0;
register struct iod *iodp = (struct iod *)0;
/* iod_Init(iodp, call); */
afs_int32 fromtime, register struct volintSize *v_size)
{
int code = 0;
- int UseLatestReadOnlyClone = 1;
- afs_int32 dumpTimes[2];
+/* int UseLatestReadOnlyClone = 1; */
+/* afs_int32 dumpTimes[2]; */
+ afs_uint64 addvar;
/* iodp->device = vp->device; */
/* iodp->parentId = V_parentId(vp); */
/* iodp->dumpPartition = vp->partition; */
- v_size->dump_size = 0; /* initialize the size */
+ ZeroInt64(v_size->dump_size); /* initialize the size */
/* if (!code) code = DumpDouble(iodp, D_DUMPHEADER, DUMPBEGINMAGIC, DUMPVERSION); */
- v_size->dump_size += 9;
+ FillInt64(addvar,0, 9);
+ AddUInt64(v_size->dump_size, addvar, &v_size->dump_size);
/* if (!code) code = DumpInt32(iodp, 'v', UseLatestReadOnlyClone? V_id(vp): V_parentId(vp)); */
- v_size->dump_size += 5;
+ FillInt64(addvar,0, 5);
+ AddUInt64(v_size->dump_size, addvar, &v_size->dump_size);
/* if (!code) code = DumpString(iodp, 'n',V_name(vp)); */
- v_size->dump_size += (2 + strlen(V_name(vp)));
+ FillInt64(addvar,0, (2 + strlen(V_name(vp))));
+ AddUInt64(v_size->dump_size, addvar, &v_size->dump_size);
/* dumpTimes[0] = fromtime; */
/* dumpTimes[1] = V_backupDate(vp); /\* Until the time the clone was made *\/ */
/* if (!code) code = DumpArrayInt32(iodp, 't', (afs_uint32 *)dumpTimes, 2); */
- v_size->dump_size += (3 + 4 * 2);
+ FillInt64(addvar,0, (3 + 4 * 2));
+ AddUInt64(v_size->dump_size, addvar, &v_size->dump_size);
return code;
}
register struct volintSize *v_size)
{
int code = 0;
+ afs_uint64 addvar;
if (!v || v->type == vNull)
return code;
/* if (!code) code = DumpDouble(iodp, D_VNODE, vnodeNumber, v->uniquifier); */
- v_size->dump_size += 9;
+ FillInt64(addvar,0, 9);
+ AddUInt64(v_size->dump_size, addvar, &v_size->dump_size);
if (!dumpEverything)
return code;
/* if (!code) code = DumpByte(iodp, 't',(byte)v->type); */
- v_size->dump_size += 2;
+ FillInt64(addvar,0, 2);
+ AddUInt64(v_size->dump_size, addvar, &v_size->dump_size);
/* if (!code) code = DumpShort(iodp, 'l', v->linkCount); /\* May not need this *\/ */
- v_size->dump_size += 3;
+ FillInt64(addvar,0, 3);
+ AddUInt64(v_size->dump_size, addvar, &v_size->dump_size);
/* if (!code) code = DumpInt32(iodp, 'v', v->dataVersion); */
- v_size->dump_size += 5;
+ FillInt64(addvar,0, 5);
+ AddUInt64(v_size->dump_size, addvar, &v_size->dump_size);
/* if (!code) code = DumpInt32(iodp, 'm', v->unixModifyTime); */
- v_size->dump_size += 5;
+ FillInt64(addvar,0, 5);
+ AddUInt64(v_size->dump_size, addvar, &v_size->dump_size);
/* if (!code) code = DumpInt32(iodp, 'a', v->author); */
- v_size->dump_size += 5;
+ FillInt64(addvar,0, 5);
+ AddUInt64(v_size->dump_size, addvar, &v_size->dump_size);
/* if (!code) code = DumpInt32(iodp, 'o', v->owner); */
- v_size->dump_size += 5;
+ FillInt64(addvar,0, 5);
+ AddUInt64(v_size->dump_size, addvar, &v_size->dump_size);
/* if (!code && v->group) code = DumpInt32(iodp, 'g', v->group); /\* default group is 0 *\/ */
- if (v->group)
- v_size->dump_size += 5;
+ if (v->group) {
+ FillInt64(addvar,0, 5);
+ AddUInt64(v_size->dump_size, addvar, &v_size->dump_size);
+ }
/* if (!code) code = DumpShort(iodp, 'b', v->modeBits); */
- v_size->dump_size += 3;
+ FillInt64(addvar,0, 3);
+ AddUInt64(v_size->dump_size, addvar, &v_size->dump_size);
/* if (!code) code = DumpInt32(iodp, 'p', v->parent); */
- v_size->dump_size += 5;
+ FillInt64(addvar,0, 5);
+ AddUInt64(v_size->dump_size, addvar, &v_size->dump_size);
/* if (!code) code = DumpInt32(iodp, 's', v->serverModifyTime); */
- v_size->dump_size += 5;
+ FillInt64(addvar,0, 5);
+ AddUInt64(v_size->dump_size, addvar, &v_size->dump_size);
if (v->type == vDirectory) {
/* acl_HtonACL(VVnodeDiskACL(v)); */
/* if (!code) code = DumpByteString(iodp, 'A', (byte *) VVnodeDiskACL(v), VAclDiskSize(v)); */
- v_size->dump_size += 1 + VAclDiskSize(v);
+ FillInt64(addvar,0, (1 + VAclDiskSize(v)));
+ AddUInt64(v_size->dump_size, addvar, &v_size->dump_size);
}
if (VNDISK_GET_INO(v)) {
- v_size->dump_size += (v->length + 5);
+ FillInt64(addvar,0, (v->length + 5));
+ AddUInt64(v_size->dump_size, addvar, &v_size->dump_size);
}
return code;
}