#include <roken.h>
-#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 <sys/param.h>
-#include <sys/file.h>
-#include <sys/uio.h>
-#include <netinet/in.h>
-#include <unistd.h>
-#endif
-#include <sys/stat.h>
-#include <afs/afs_assert.h>
-#include <rx/xdr.h>
+
+#include <afs/opr.h>
#include <rx/rx.h>
+#include <rx/rx_queue.h>
#include <afs/afsint.h>
#include <afs/nfs.h>
#include <afs/errors.h>
#include <afs/vnode.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 "dump.h"
#include "volser.h"
#include "volint.h"
#include "dumpstuff.h"
/*@printflike@*/ extern void Log(const char *format, ...);
extern int DoLogging;
+extern int DoPreserveVolumeStats;
/* Forward Declarations */
struct volintSize *size);
#define MAX_SECTIONS 3
-#define MIN_TLV_TAG 5
+
+/* The TLV range must start above D_MAX */
+#define MIN_TLV_TAG 21
#define MAX_TLV_TAG 0x60
#define MAX_STANDARD_TAG 0x7a
static afs_uint32 oldtags[MAX_SECTIONS][16];
int code, i;
int one_success = 0;
- osi_Assert((iodp->call && iodp->ncalls == 1 && !iodp->calls)
+ opr_Assert((iodp->call && iodp->ncalls == 1 && !iodp->calls)
|| (!iodp->call && iodp->ncalls >= 1 && iodp->calls));
if (iodp->call) {
afs_int32 code, i;
afs_uint32 off = tag >> 5;
afs_uint32 mask = 1 << (tag & 0x1f);
- unsigned char len, buf[8], *p;
+ int len;
+ unsigned char buf[8], *p;
if (!oldtagsInited)
initNonStandardTags();
}
if (tag <= MAX_TLV_TAG) {
len = iod_getc(iodp);
- if (len < 128)
+ if (len == EOF)
+ return VOLSERDUMPERROR;
+ else if (len < 128)
*length = len;
else {
len &= 0x7f;
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
#include <sys/statfs.h>
#if defined(AFS_AIX52_ENV)
#endif
#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
#endif /* AFS_NT40_ENV */
- size = FDH_SIZE(handleP);
- SplitInt64(size, hi, lo);
+ SplitInt64(howBig, hi, lo);
if (hi == 0L) {
code = DumpInt32(iodp, 'f', lo);
} else {
return VOLSERDUMPERROR;
}
- for (nbytes = size; (nbytes && !error); nbytes -= howMany) {
+ for (nbytes = howBig; (nbytes && !error); nbytes -= howMany) {
if (nbytes < howMany)
howMany = nbytes;
/* Now seek over the data we could not get. An error here means we
* can't do the next read.
*/
- howFar = (size_t)((size - nbytes) + howMany);
+ howFar = (size_t)((howBig - nbytes) + howMany);
}
/* Now write the data out */
int vnodeIndex;
fdP = IH_OPEN(vp->vnodeIndex[class].handle);
- osi_Assert(fdP != NULL);
+ opr_Assert(fdP != NULL);
file = FDH_FDOPEN(fdP, "r+");
- osi_Assert(file != NULL);
+ opr_Assert(file != NULL);
size = OS_SIZE(fdP->fd_fd);
- osi_Assert(size != -1);
+ opr_Assert(size != -1);
nVnodes = (size / vcp->diskSize) - 1;
if (nVnodes > 0) {
- osi_Assert((nVnodes + 1) * vcp->diskSize == size);
- osi_Assert(STREAM_ASEEK(file, vcp->diskSize) == 0);
+ opr_Assert((nVnodes + 1) * vcp->diskSize == size);
+ opr_Assert(STREAM_ASEEK(file, vcp->diskSize) == 0);
} else
nVnodes = 0;
for (vnodeIndex = 0;
VAclDiskSize(v));
}
if (VNDISK_GET_INO(v)) {
+ afs_sfsize_t indexlen, disklen;
IH_INIT(ihP, iodp->device, iodp->parentId, VNDISK_GET_INO(v));
fdP = IH_OPEN(ihP);
if (fdP == NULL) {
IH_RELEASE(ihP);
return VOLSERREAD_DUMPERROR;
}
+ VNDISK_GET_LEN(indexlen, v);
+ disklen = FDH_SIZE(fdP);
+ if (indexlen != disklen) {
+ FDH_REALLYCLOSE(fdP);
+ IH_RELEASE(ihP);
+ Log("DumpVnode: volume %lu vnode %lu has inconsistent length "
+ "(index %lu disk %lu); aborting dump\n",
+ (unsigned long)volid, (unsigned long)vnodeNumber,
+ (unsigned long)indexlen, (unsigned long)disklen);
+ return VOLSERREAD_DUMPERROR;
+ }
code = DumpFile(iodp, vnodeNumber, fdP);
FDH_CLOSE(fdP);
IH_RELEASE(ihP);
OS_SYNC(afile->str_fd);
} else {
size = OS_SIZE(fdP->fd_fd);
- osi_Assert(size != -1);
+ opr_Assert(size != -1);
nVnodes =
(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 = malloc(nVnodes * sizeof(afs_foff_t));
+ Buf = calloc(nVnodes, sizeof(afs_foff_t));
if (Buf == NULL) {
STREAM_CLOSE(afile);
FDH_CLOSE(fdP);
return -1;
}
- memset(Buf, 0, nVnodes * sizeof(afs_foff_t));
STREAM_ASEEK(afile, offset = vcp->diskSize);
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;
}
afs_foff_t *b1 = NULL, *b2 = NULL;
int s1 = 0, s2 = 0, delo = 0, tdelo;
int tag;
+ VolumeDiskData saved_header;
iod_Init(iodp, call);
vp = avp;
+ if (DoPreserveVolumeStats) {
+ CopyVolumeStats(&V_disk(vp), &saved_header);
+ }
+
if (!ReadDumpHeader(iodp, &header)) {
Log("1 Volser: RestoreVolume: Error reading header file for dump; aborted\n");
return VOLSERREAD_DUMPERROR;
vol.cloneId = cookie->clone;
vol.parentId = cookie->parent;
+ V_needsSalvaged(vp) = 0;
+
tdelo = delo;
while (1) {
if (ReadVnodes(iodp, vp, 0, b1, s1, b2, s2, tdelo)) {
}
clean:
- ClearVolumeStats(&vol);
+ if (DoPreserveVolumeStats) {
+ CopyVolumeStats(&saved_header, &vol);
+ } else {
+ ClearVolumeStats(&vol);
+ }
+ if (V_needsSalvaged(vp)) {
+ /* needsSalvaged may have been set while we tried to write volume data.
+ * prevent it from getting overwritten. */
+ vol.needsSalvaged = V_needsSalvaged(vp);
+ }
CopyVolumeHeader(&vol, &V_disk(vp));
V_destroyMe(vp) = 0;
VUpdateVolume(&vupdate, vp);
out:
/* Free the malloced space above */
if (b1)
- free((char *)b1);
+ free(b1);
if (b2)
- free((char *)b2);
+ free(b2);
return error;
}
struct VnodeClassInfo *vcp;
IHandle_t *tmpH;
FdHandle_t *fdP;
- Inode nearInode;
+ Inode nearInode AFS_UNUSED;
afs_int32 critical = 0;
tag = iod_getc(iodp);
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)
}
saw_f = 1;
- ino =
- IH_CREATE(V_linkHandle(vp), V_device(vp),
+ tmpH =
+ IH_CREATE_INIT(V_linkHandle(vp), V_device(vp),
VPartitionPath(V_partition(vp)), nearInode,
V_parentId(vp), vnodeNumber,
vnode->uniquifier, vnode->dataVersion);
- if (!VALID_INO(ino)) {
+ if (!tmpH) {
Log("1 Volser: ReadVnodes: IH_CREATE: %s - restore aborted\n",
afs_error_message(errno));
+ V_needsSalvaged(vp) = 1;
return VOLSERREAD_DUMPERROR;
}
+ ino = tmpH->ih_ino;
nearInode = ino;
VNDISK_SET_INO(vnode, 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);
+ V_needsSalvaged(vp) = 1;
return VOLSERREAD_DUMPERROR;
}
vnodeLength =
Log("1 Volser: ReadVnodes: IDEC inode %llu\n",
(afs_uintmax_t) ino);
IH_DEC(V_linkHandle(vp), ino, V_parentId(vp));
+ V_needsSalvaged(vp) = 1;
return VOLSERREAD_DUMPERROR;
}
break;
if (fdP == NULL) {
Log("1 Volser: ReadVnodes: Error opening vnode index: %s; restore aborted\n",
afs_error_message(errno));
+ V_needsSalvaged(vp) = 1;
return VOLSERREAD_DUMPERROR;
}
if (FDH_PREAD(fdP, &oldvnode, sizeof(oldvnode), vnodeIndexOffset(vcp, vnodeNumber)) ==
Log("1 Volser: ReadVnodes: Error writing vnode index: %s; restore aborted\n",
afs_error_message(errno));
FDH_REALLYCLOSE(fdP);
+ V_needsSalvaged(vp) = 1;
return VOLSERREAD_DUMPERROR;
}
FDH_CLOSE(fdP);
}
FillInt64(filesize, filesize_high, filesize_low);
}
- p = (unsigned char *)malloc(size);
+ p = malloc(size);
if (p == NULL) {
*status = 2;
return (0);
}
if (VNDISK_GET_INO(v)) {
- FillInt64(addvar,0, (v->length + 5));
+ VNDISK_GET_LEN(addvar, v);
+ if (v->vn_length_hi)
+ addvar += 9;
+ else
+ addvar += 5;
AddUInt64(v_size->dump_size, addvar, &v_size->dump_size);
}
return code;
int vnodeIndex;
fdP = IH_OPEN(vp->vnodeIndex[class].handle);
- osi_Assert(fdP != NULL);
+ opr_Assert(fdP != NULL);
file = FDH_FDOPEN(fdP, "r+");
- osi_Assert(file != NULL);
+ opr_Assert(file != NULL);
size = OS_SIZE(fdP->fd_fd);
- osi_Assert(size != -1);
+ opr_Assert(size != -1);
nVnodes = (size / vcp->diskSize) - 1;
if (nVnodes > 0) {
- osi_Assert((nVnodes + 1) * vcp->diskSize == size);
- osi_Assert(STREAM_ASEEK(file, vcp->diskSize) == 0);
+ opr_Assert((nVnodes + 1) * vcp->diskSize == size);
+ opr_Assert(STREAM_ASEEK(file, vcp->diskSize) == 0);
} else
nVnodes = 0;
for (vnodeIndex = 0;