static void GetFileInfo(FD_t fd, int *size, char **ctime, char **mtime, char **atime) { #ifdef AFS_NT40_ENV BY_HANDLE_FILE_INFORMATION fi; if (!GetFileInformationByHandle(fd, &fi)) { printf("GetFileInformationByHandle failed, exiting\n"); exit(1); } *size = (int)fi.nFileSizeLow; *ctime = "N/A"; *mtime = NT_date(&fi.ftLastWriteTime); *atime = NT_date(&fi.ftLastAccessTime); #else struct afs_stat status; if (afs_fstat(fd, &status) == -1) { printf("fstat failed %d\n", errno); exit(1); } *size = (int)status.st_size; *ctime = date(status.st_ctime); *mtime = date(status.st_mtime); *atime = date(status.st_atime); #endif }
afs_sfsize_t ih_size(int fd) { struct afs_stat status; if (afs_fstat(fd, &status) < 0) return -1; return status.st_size; }
static int fs_stateLoadDump(struct fs_dump_state * state) { afs_uint64 z; int fd, ret = 0; struct afs_stat status; afs_int32 now = FT_ApproxTime(); ZeroInt64(z); if ((fd = afs_open(state->fn, O_RDWR)) == -1 || (afs_fstat(fd, &status) == -1)) { ViceLog(0, ("fs_stateLoadDump: failed to load state dump file '%s'\n", state->fn)); ret = 1; goto done; } state->fd = fd; state->mode = FS_STATE_LOAD_MODE; state->file_len = status.st_size; #ifdef FS_STATE_USE_MMAP if (fs_stateMapFile(state)) { ViceLog(0, ("fs_stateLoadDump: failed to memory map state dump file '%s'\n", state->fn)); ret = 1; goto done; } #endif if (fs_stateReadHeader(state, &z, state->hdr, sizeof(struct fs_state_header))) { ViceLog(0, ("fs_stateLoadDump: failed to read header from dump file '%s'\n", state->fn)); ret = 1; goto done; } /* check the validity of the header */ if (fs_stateCheckHeader(state->hdr)) { ViceLog(1, ("fs_stateLoadDump: header failed validity checks; not restoring '%s'\n", state->fn)); ret = 1; goto done; } if ((state->hdr->timestamp + HOST_STATE_VALID_WINDOW) >= now) { state->flags.do_host_restore = 1; } else { ViceLog(0, ("fs_stateLoadDump: warning: dump is too old for host and callback restore; skipping those steps\n")); } done: return ret; }
static int fs_stateCreateDump(struct fs_dump_state * state) { int fd, ret = 0; char savedump[MAXPATHLEN]; struct afs_stat status; afs_snprintf(savedump, sizeof(savedump), "%s.old", state->fn); if (afs_stat(state->fn, &status) == 0) { renamefile(state->fn, savedump); } if (((fd = afs_open(state->fn, O_RDWR | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR)) == -1) || (afs_fstat(fd, &status) == -1)) { ViceLog(0, ("fs_stateCreateDump: failed to create state dump file '%s'\n", state->fn)); ret = 1; goto done; } state->fd = fd; state->mode = FS_STATE_DUMP_MODE; memset(state->hdr, 0, sizeof(struct fs_state_header)); fs_stateIncEOF(state, sizeof(struct fs_state_header)); #ifdef FS_STATE_USE_MMAP if (fs_stateSizeFile(state)) { ViceLog(0, ("fs_stateCreateDump: failed to resize state dump file '%s'\n", state->fn)); ret = 1; goto done; } if (fs_stateMapFile(state)) { ViceLog(0, ("fs_stateCreateDump: failed to memory map state dump file '%s'\n", state->fn)); ret = 1; goto done; } #endif ret = fs_stateInvalidateDump(state); done: return ret; }
afs_sfsize_t ih_size(FD_t fd) { #ifdef AFS_NT40_ENV LARGE_INTEGER size; if (!GetFileSizeEx(fd, &size)) return -1; return size.QuadPart; #else struct afs_stat_st status; if (afs_fstat(fd, &status) < 0) return -1; return status.st_size; #endif }
void HandleVolume(struct DiskPartition64 *dp, char *name, char *filename, int fromtime) { struct VolumeHeader header; struct VolumeDiskHeader diskHeader; struct afs_stat status, stat; register int fd; Volume *vp; IHandle_t *ih; char headerName[1024]; afs_int32 n; (void)afs_snprintf(headerName, sizeof headerName, "%s/%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); close(fd); exit(1); } n = read(fd, &diskHeader, sizeof(diskHeader)); if (n != sizeof(diskHeader) || diskHeader.stamp.magic != VOLUMEHEADERMAGIC) { fprintf(stderr, "Error reading volume header %s\n", name); exit(1); } if (diskHeader.stamp.version != VOLUMEHEADERVERSION) { fprintf(stderr, "Volume %s, version number is incorrect; volume needs salvage\n", name); exit(1); } DiskToVolumeHeader(&header, &diskHeader); close(fd); vp = AttachVolume(dp, name, &header); if (!vp) { fprintf(stderr, "Error attaching volume header %s\n", name); exit(1); } DoMyVolDump(vp, dp, filename, fromtime); }
static int openFile(char * path) { int ret = 0; struct afs_stat status; dump_fd = afs_open(path, O_RDWR); if (dump_fd == -1) { fprintf(stderr, "dump file '%s' failed to open\n", path); ret = 1; goto done; } printf("opened dump file '%s'\n", path); if (afs_fstat(dump_fd, &status) == -1) { fprintf(stderr, "failed to stat file\n"); ret = 1; goto done; } map_len = status.st_size; map = afs_mmap(NULL, map_len, PROT_READ, MAP_SHARED, dump_fd, 0); if (map == MAP_FAILED) { fprintf(stderr, "failed to mmap file\n"); ret = 1; goto done; } printf("mapped %lu bytes at %"AFS_PTR_FMT"\n", (unsigned long)map_len, map); done: if (ret) { if (map) { munmap(map, map_len); map = NULL; } if (dump_fd != -1) { close(dump_fd); dump_fd = -1; } } return ret; }
void HandleVolume(struct DiskPartition64 *dp, char *name) { struct VolumeHeader header; struct VolumeDiskHeader diskHeader; struct afs_stat status, stat; int fd; Volume *vp; IHandle_t *ih; char headerName[1024]; if (online) { printf("volinfo: -online not supported\n"); exit(1); } else { afs_int32 n; (void)afs_snprintf(headerName, sizeof headerName, "%s/%s", VPartitionPath(dp), name); if ((fd = afs_open(headerName, O_RDONLY)) == -1 || afs_fstat(fd, &status) == -1) { printf("Volinfo: Cannot read volume header %s\n", name); close(fd); exit(1); } n = read(fd, &diskHeader, sizeof(diskHeader)); if (n != sizeof(diskHeader) || diskHeader.stamp.magic != VOLUMEHEADERMAGIC) { printf("Volinfo: Error reading volume header %s\n", name); exit(1); } if (diskHeader.stamp.version != VOLUMEHEADERVERSION) { printf ("Volinfo: Volume %s, version number is incorrect; volume needs salvage\n", name); exit(1); } DiskToVolumeHeader(&header, &diskHeader); if (dheader) { FdHandle_t *fdP; afs_sfsize_t size = 0; afs_sfsize_t code; if (afs_fstat(fd, &stat) == -1) { perror("stat"); exit(1); } if (!dsizeOnly && !saveinodes) { size = stat.st_size; printf("Volume header (size = %d):\n", (int)size); printf("\tstamp\t= 0x%x\n", header.stamp.version); printf("\tVolId\t= %u\n", header.id); } IH_INIT(ih, dp->device, header.parent, header.volumeInfo); fdP = IH_OPEN(ih); if (fdP == NULL) { perror("opening volume info"); exit(1); } code = FDH_SIZE(fdP); if (code == -1) { perror("fstat"); exit(1); } FDH_REALLYCLOSE(fdP); IH_RELEASE(ih); size += code; if (!dsizeOnly && !saveinodes) { printf("\tparent\t= %u\n", header.parent); printf("\tInfo inode\t= %s (size = %d)\n", PrintInode(NULL, header.volumeInfo), (int)code); } IH_INIT(ih, dp->device, header.parent, header.smallVnodeIndex); fdP = IH_OPEN(ih); if (fdP == NULL) { perror("opening small vnode index"); exit(1); } code = FDH_SIZE(fdP); if (code == -1) { perror("fstat"); exit(1); } FDH_REALLYCLOSE(fdP); IH_RELEASE(ih); size += code; if (!dsizeOnly && !saveinodes) { printf("\tSmall inode\t= %s (size = %d)\n", PrintInode(NULL, header.smallVnodeIndex), (int)code); } IH_INIT(ih, dp->device, header.parent, header.largeVnodeIndex); fdP = IH_OPEN(ih); if (fdP == NULL) { perror("opening large vnode index"); exit(1); } code = FDH_SIZE(fdP); if (code == -1) { perror("fstat"); exit(1); } FDH_REALLYCLOSE(fdP); IH_RELEASE(ih); size += code; if (!dsizeOnly && !saveinodes) { printf("\tLarge inode\t= %s (size = %d)\n", PrintInode(NULL, header.largeVnodeIndex), (int)code); #ifndef AFS_NT40_ENV printf("Total aux volume size = %d\n\n", (int)size); #endif } #ifdef AFS_NAMEI_ENV IH_INIT(ih, dp->device, header.parent, header.linkTable); fdP = IH_OPEN(ih); if (fdP == NULL) { perror("opening link table index"); exit(1); } code = FDH_SIZE(fdP); if (code == -1) { perror("fstat"); exit(1); } FDH_REALLYCLOSE(fdP); IH_RELEASE(ih); size += code; if (!dsizeOnly && !saveinodes) { printf("\tLink inode\t= %s (size = %d)\n", PrintInode(NULL, header.linkTable), (int)code); printf("Total aux volume size = %d\n\n", (int)size); } #endif Vauxsize = size; Vauxsize_k = size / 1024; } close(fd); vp = AttachVolume(dp, name, &header); if (!vp) { printf("Volinfo: Error attaching volume header %s\n", name); return; } } PrintHeader(vp); if (DumpVnodes) { if (!dsizeOnly && !saveinodes) printf("\nLarge vnodes (directories)\n"); PrintVnodes(vp, vLarge); if (!dsizeOnly && !saveinodes) { printf("\nSmall vnodes(files, symbolic links)\n"); fflush(stdout); } if (saveinodes) printf("Saving all volume files to current directory ...\n"); PrintVnodes(vp, vSmall); } if (dsizeOnly) { totvolsize = Vauxsize_k + Vvnodesize_k; if (saveinodes) printf ("Volume-Id\t Volsize Auxsize Inodesize AVolsize SizeDiff (VolName)\n"); printf("%u\t%9d%9d%10d%10d%9d\t%24s\n", V_id(vp), Vdiskused, Vauxsize_k, Vvnodesize_k, totvolsize, totvolsize - Vdiskused, V_name(vp)); } free(vp->header); free(vp); }
static int 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; byte *p; #ifndef AFS_NT40_ENV struct afs_stat status; #endif afs_sfsize_t size, tmpsize; #ifdef AFS_AIX_ENV #include <sys/statfs.h> struct statfs tstatfs; #endif if (verbose) fprintf(stderr, "dumping file for vnode %d\n", vnode); #ifdef AFS_NT40_ENV howBig = _filelength(handleP->fd_fd); howMany = 4096; #else 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; #else howMany = status.st_blksize; #endif /* AFS_AIX_ENV */ #endif /* AFS_NT40_ENV */ size = FDH_SIZE(handleP); if (verbose) fprintf(stderr, " howBig = %u, howMany = %u, fdh size = %u\n", howBig, howMany, 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); } } #else /* !AFS_LARGEFILE_ENV */ code = DumpInt32(dumpfd, 'f', size); #endif /* !AFS_LARGEFILE_ENV */ if (code) { return VOLSERDUMPERROR; } p = (unsigned char *)malloc(howMany); if (!p) { fprintf(stderr, "out of memory!\n"); return VOLSERDUMPERROR; } /* loop through whole file, while we still have bytes left, and no errors, in chunks of howMany bytes */ for (nbytes = size; (nbytes && !failed_write); nbytes -= howMany) { if (nbytes < howMany) howMany = nbytes; /* Read the data - unless we know we can't */ n = (failed_seek ? 0 : FDH_READ(handleP, p, howMany)); /* 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); pad = 0; } /* If didn't read enough data, null padd the rest of the buffer. This * can happen if, for instance, the media has some bad spots. We don't * want to quit the dump, so we start null padding. */ if (n < howMany) { if (verbose) fprintf(stderr, " read %u instead of %u bytes.\n", n, 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), vnode); } else if (!pad) { fprintf(stderr, "Error reading inode %s for vnode %d\n", PrintInode(NULL, handleP->fd_ih->ih_ino), vnode); } /* Pad the rest of the buffer with zeros. Remember offset we started * padding. Keep total tally of padding. */ memset(p + n, 0, howMany - n); if (!pad) offset = (howBig - nbytes) + n; pad += (howMany - n); /* 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; } } /* Now write the data out */ if (write(dumpfd, (char *)p, howMany) != howMany) failed_write = VOLSERDUMPERROR; } if (pad) { /* Any padding we hadn't reported yet */ fprintf(stderr, "Null padding file: %d bytes at offset %u\n", pad, offset); } free(p); return failed_write; }