static bit32 volser_WriteFile(int vn, struct iod *iodp, FdHandle_t *handleP,
Error *status);
+static int SizeDumpDumpHeader(register struct iod *iodp, register Volume *vp,
+ afs_int32 fromtime, register struct volintSize *size);
+static int SizeDumpPartial(register struct iod *iodp, register Volume *vp,
+ afs_int32 fromtime, int dumpAllDirs,
+ register struct volintSize *size);
+static int SizeDumpVnodeIndex(register struct iod *iodp, Volume *vp,
+ VnodeClass class, afs_int32 fromtime, int forcedump,
+ register struct volintSize *size);
+static int SizeDumpVnode(register struct iod *iodp, struct VnodeDiskObject *v,
+ int volid, int vnodeNumber, int dumpEverything,
+ register struct volintSize *size);
static void iod_Init(register struct iod *iodp, register struct rx_call *call)
{
iod_ungetc(iodp, tag);
return 1;
}
+
+
+/* ----- Below are the calls that calculate dump size ----- */
+
+static int SizeDumpVolumeHeader(register struct iod *iodp, register Volume *vp, register struct volintSize *v_size)
+{
+ int code = 0;
+ static char nullString[1] = ""; /*The ``contents'' of motd*/
+
+/* if (!code) code = DumpTag(iodp, D_VOLUMEHEADER); */
+ v_size->dump_size += 1;
+/* if (!code) {code = DumpInt32(iodp, 'i',V_id(vp));} */
+ v_size->dump_size += 5;
+/* if (!code) code = DumpInt32(iodp, 'v',V_stamp(vp).version); */
+ v_size->dump_size += 5;
+/* if (!code) code = DumpString(iodp, 'n',V_name(vp)); */
+ v_size->dump_size += (2 + strlen(V_name(vp)));
+/* if (!code) code = DumpBool(iodp, 's',V_inService(vp)); */
+ v_size->dump_size += 2;
+/* if (!code) code = DumpBool(iodp, 'b',V_blessed(vp)); */
+ v_size->dump_size += 2;
+/* if (!code) code = DumpInt32(iodp, 'u',V_uniquifier(vp)); */
+ v_size->dump_size += 5;
+/* if (!code) code = DumpByte(iodp, 't',(byte)V_type(vp)); */
+ v_size->dump_size += 2;
+/* if (!code){ code = DumpInt32(iodp, 'p',V_parentId(vp));} */
+ v_size->dump_size += 5;
+/* if (!code) code = DumpInt32(iodp, 'c',V_cloneId(vp)); */
+ v_size->dump_size += 5;
+/* if (!code) code = DumpInt32(iodp, 'q',V_maxquota(vp)); */
+ v_size->dump_size += 5;
+/* if (!code) code = DumpInt32(iodp, 'm',V_minquota(vp)); */
+ v_size->dump_size += 5;
+/* if (!code) code = DumpInt32(iodp, 'd',V_diskused(vp)); */
+ v_size->dump_size += 5;
+/* if (!code) code = DumpInt32(iodp, 'f',V_filecount(vp)); */
+ v_size->dump_size += 5;
+/* if (!code) code = DumpInt32(iodp, 'a', V_accountNumber(vp)); */
+ v_size->dump_size += 5;
+/* if (!code) code = DumpInt32(iodp, 'o', V_owner(vp)); */
+ v_size->dump_size += 5;
+/* if (!code) code = DumpInt32(iodp, 'C',V_creationDate(vp)); /\* Rw volume creation date *\/ */
+ v_size->dump_size += 5;
+/* if (!code) code = DumpInt32(iodp, 'A',V_accessDate(vp)); */
+ v_size->dump_size += 5;
+/* if (!code) code = DumpInt32(iodp, 'U',V_updateDate(vp)); */
+ v_size->dump_size += 5;
+/* if (!code) code = DumpInt32(iodp, 'E',V_expirationDate(vp)); */
+ v_size->dump_size += 5;
+/* if (!code) code = DumpInt32(iodp, 'B',V_backupDate(vp)); /\* Rw volume backup clone date *\/ */
+ v_size->dump_size += 5;
+/* if (!code) code = DumpString(iodp, 'O',V_offlineMessage(vp)); */
+ v_size->dump_size += (2 + strlen(V_offlineMessage(vp)));
+/* /\* */
+/* * 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 */
+/* * statistics data has been put there. Instead, we dump a null string, */
+/* * just as if that was what the motd contained. */
+/* *\/ */
+/* if (!code) code = DumpString(iodp, 'M', nullString); */
+ v_size->dump_size += (2 + strlen(nullString));
+/* 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])));
+/* if (!code) code = DumpInt32(iodp, 'D', V_dayUseDate(vp)); */
+ v_size->dump_size += 5;
+/* if (!code) code = DumpInt32(iodp, 'Z', V_dayUse(vp)); */
+ v_size->dump_size += 5;
+ return code;
+}
+
+static int SizeDumpEnd(register struct iod *iodp, register struct volintSize *v_size)
+{
+ int code = 0;
+ v_size->dump_size += 5;
+ return code;
+}
+
+int SizeDumpVolume(register struct rx_call *call, register Volume *vp, 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);
+
+ if (!code) code = SizeDumpDumpHeader(iodp, vp, fromtime, v_size);
+ if (!code) code = SizeDumpPartial(iodp, vp, fromtime, dumpAllDirs, v_size);
+ if (!code) code = SizeDumpEnd(iodp, v_size);
+
+ return code;
+}
+
+static int SizeDumpDumpHeader(register struct iod *iodp, register Volume *vp, afs_int32 fromtime,
+ register struct volintSize *v_size)
+{
+ int code = 0;
+ int UseLatestReadOnlyClone = 1;
+ afs_int32 dumpTimes[2];
+// iodp->device = vp->device;
+// iodp->parentId = V_parentId(vp);
+// iodp->dumpPartition = vp->partition;
+
+ v_size->dump_size = 0; /* initialize the size */
+/* if (!code) code = DumpDouble(iodp, D_DUMPHEADER, DUMPBEGINMAGIC, DUMPVERSION); */
+ v_size->dump_size += 9;
+/* if (!code) code = DumpInt32(iodp, 'v', UseLatestReadOnlyClone? V_id(vp): V_parentId(vp)); */
+ v_size->dump_size += 5;
+/* if (!code) code = DumpString(iodp, 'n',V_name(vp)); */
+ v_size->dump_size += (2 + strlen(V_name(vp)));
+/* 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);
+ return code;
+}
+
+static int SizeDumpVnode(register struct iod *iodp, struct VnodeDiskObject *v, int volid, int vnodeNumber, int dumpEverything,
+ register struct volintSize *v_size)
+{
+ int code = 0;
+
+ if (!v || v->type == vNull)
+ return code;
+/* if (!code) code = DumpDouble(iodp, D_VNODE, vnodeNumber, v->uniquifier); */
+ v_size->dump_size += 9;
+ if (!dumpEverything)
+ return code;
+/* if (!code) code = DumpByte(iodp, 't',(byte)v->type); */
+ v_size->dump_size += 2;
+/* if (!code) code = DumpShort(iodp, 'l', v->linkCount); /\* May not need this *\/ */
+ v_size->dump_size += 3;
+/* if (!code) code = DumpInt32(iodp, 'v', v->dataVersion); */
+ v_size->dump_size += 5;
+/* if (!code) code = DumpInt32(iodp, 'm', v->unixModifyTime); */
+ v_size->dump_size += 5;
+/* if (!code) code = DumpInt32(iodp, 'a', v->author); */
+ v_size->dump_size += 5;
+/* if (!code) code = DumpInt32(iodp, 'o', v->owner); */
+ v_size->dump_size += 5;
+/* if (!code && v->group) code = DumpInt32(iodp, 'g', v->group); /\* default group is 0 *\/ */
+ if(v->group) v_size->dump_size += 5;
+/* if (!code) code = DumpShort(iodp, 'b', v->modeBits); */
+ v_size->dump_size += 3;
+/* if (!code) code = DumpInt32(iodp, 'p', v->parent); */
+ v_size->dump_size += 5;
+/* if (!code) code = DumpInt32(iodp, 's', v->serverModifyTime); */
+ v_size->dump_size += 5;
+ 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);
+ }
+
+ if (VNDISK_GET_INO(v)) {
+ v_size->dump_size += (v->length + 5);
+ }
+ return code;
+}
+
+/* A partial dump (no dump header) */
+static int SizeDumpPartial(register struct iod *iodp, register Volume *vp, afs_int32 fromtime, int dumpAllDirs,
+ register struct volintSize *v_size)
+{
+ int code = 0;
+ if (!code) code = SizeDumpVolumeHeader(iodp, vp, v_size);
+ if (!code) code = SizeDumpVnodeIndex(iodp, vp, vLarge, fromtime, dumpAllDirs, v_size);
+ if (!code) code = SizeDumpVnodeIndex(iodp, vp, vSmall, fromtime, 0, v_size);
+ return code;
+}
+
+static int SizeDumpVnodeIndex(register struct iod *iodp, Volume *vp, VnodeClass class, afs_int32 fromtime,
+ int forcedump, register struct volintSize *v_size)
+{
+ register int code = 0;
+ register struct VnodeClassInfo *vcp = &VnodeClassInfo[class];
+ char buf[SIZEOF_LARGEDISKVNODE];
+ struct VnodeDiskObject *vnode = (struct VnodeDiskObject *) buf;
+ StreamHandle_t *file;
+ FdHandle_t *fdP;
+ int size;
+ int flag;
+ register int vnodeIndex, nVnodes;
+
+ fdP = IH_OPEN(vp->vnodeIndex[class].handle);
+ assert(fdP != NULL);
+ file = FDH_FDOPEN(fdP, "r+");
+ assert(file != NULL);
+ size = OS_SIZE(fdP->fd_fd);
+ assert(size != -1);
+ nVnodes = (size / vcp->diskSize) - 1;
+ if (nVnodes > 0) {
+ assert((nVnodes+1)*vcp->diskSize == size);
+ assert(STREAM_SEEK(file, vcp->diskSize, 0) == 0);
+ }
+ else nVnodes = 0;
+ for (vnodeIndex = 0; nVnodes && STREAM_READ(vnode, vcp->diskSize, 1, file) == 1 && !code;
+ nVnodes--, vnodeIndex++) {
+ flag = forcedump || (vnode->serverModifyTime >= fromtime);
+ /* Note: the >= test is very important since some old volumes may not have
+ a serverModifyTime. For an epoch dump, this results in 0>=0 test, which
+ does dump the file! */
+ if (!code) code = SizeDumpVnode(iodp, vnode, V_id(vp), bitNumberToVnodeNumber(vnodeIndex, class), flag, v_size);
+ }
+ STREAM_CLOSE(file);
+ FDH_CLOSE(fdP);
+ return code;
+}
+
return code;
}
+static Sizes(as)
+register struct cmd_syndesc *as;
+{
+ afs_int32 avolid, aserver, apart,voltype,fromdate=0,code, err, i;
+ struct nvldbentry entry;
+ volintSize vol_size;
+
+ rx_SetRxDeadTime(60 * 10);
+ for (i = 0; i<MAXSERVERS; i++) {
+ struct rx_connection *rxConn = ubik_GetRPCConn(cstruct,i);
+ if (rxConn == 0) break;
+ rx_SetConnDeadTime(rxConn, rx_connDeadTime);
+ if (rxConn->service) rxConn->service->connDeadTime = rx_connDeadTime;
+ }
+
+ avolid = vsu_GetVolumeID(as->parms[0].items->data, cstruct, &err);
+ if (avolid == 0) {
+ if (err) PrintError("", err);
+ else fprintf(STDERR, "vos: can't find volume '%s'\n", as->parms[0].items->data);
+ return ENOENT;
+ }
+
+ if (as->parms[1].items || as->parms[2].items) {
+ if (!as->parms[1].items || !as->parms[2].items) {
+ fprintf(STDERR, "Must specify both -server and -partition options\n");
+ return -1;
+ }
+ aserver = GetServer(as->parms[2].items->data);
+ if (aserver == 0) {
+ fprintf(STDERR, "Invalid server name\n");
+ return -1;
+ }
+ apart = volutil_GetPartitionID(as->parms[1].items->data);
+ if (apart < 0) {
+ fprintf(STDERR, "Invalid partition name\n");
+ return -1;
+ }
+ } else {
+ code = GetVolumeInfo(avolid, &aserver, &apart, &voltype, &entry);
+ if (code) return code;
+ }
+
+ fromdate = 0;
+
+ if (as->parms[4].items && strcmp(as->parms[4].items->data,"0")) {
+ code = ktime_DateToInt32(as->parms[4].items->data, &fromdate);
+ if (code) {
+ fprintf(STDERR,"vos: failed to parse date '%s' (error=%d))\n",
+ as->parms[1].items->data, code);
+ return code;
+ }
+ }
+
+ fprintf(STDOUT, "Volume: %s\n", as->parms[0].items->data);
+
+ if(as->parms[3].items) /* do the dump estimate */
+ {
+ vol_size.dump_size = 0;
+ code = UV_GetSize(avolid, aserver, apart, fromdate, &vol_size);
+ if (code) {
+ PrintDiagnostics("size", code);
+ return code;
+ }
+ /* presumably the size info is now gathered in pntr */
+ /* now we display it */
+
+ fprintf(STDOUT,"dump_size: %llu\n", vol_size.dump_size);
+ }
+
+ /* Display info */
+
+ return 0;
+}
+
PrintDiagnostics(astring, acode)
char *astring;
afs_int32 acode;
cmd_AddParm(ts, "-force", CMD_FLAG, CMD_OPTIONAL, "don't ask");
COMMONPARMS;
+ ts = cmd_CreateSyntax("size", Sizes, 0, "obtain various sizes of the volume.");
+ cmd_AddParm(ts, "-id", CMD_SINGLE, 0, "volume name or ID");
+ cmd_AddParm(ts, "-partition", CMD_SINGLE, CMD_OPTIONAL, "partition name");
+ cmd_AddParm(ts, "-server", CMD_SINGLE, CMD_OPTIONAL, "machine name");
+ cmd_AddParm(ts, "-dump", CMD_FLAG, CMD_OPTIONAL, "Obtain the size of the dump");
+ cmd_AddParm(ts, "-time", CMD_SINGLE, CMD_OPTIONAL, "dump from time");
+ COMMONPARMS;
+
code = cmd_Dispatch(argc, argv);
if (rxInitDone) {
/* Shut down the ubik_client and rx connections */